Practical AI for Developers Today

by

There is a lot of speculation about what AI will do to software engineering in the years ahead. This post is not about that. It is about the things we can do with AI right now, on the work that is already on our plates. None of these require new infrastructure or a change in how a team is organized. They are available today, and they pay for themselves almost immediately.

Working with legacy code

In Working Effectively with Legacy Code, Michael Feathers defines legacy code as code without tests. By that definition, most organizations have a great deal of it. Tests get cut under delivery pressure, and years later a team is asked to modernize a system that nobody fully understands.

The usual obstacle to fixing this is time. For a small section of code, the tests can be many times longer than the code itself, and writing them is tedious enough that the work keeps getting deferred. An AI assistant changes the economics. You can capture real inputs and outputs, ask the assistant to generate a test suite around them, and review the result for correctness. What used to be a week of low-energy work becomes an hour of focused review. Once the tests are in place, you can refactor with confidence.

The same assistant helps you understand the code in the first place. When you open a function that makes no sense, possibly one you wrote yourself months ago, you can ask the assistant to explain it, connect it to the ticket history, and propose a clearer version. This is a conversation you can have immediately, without waiting on a colleague who is in a meeting. Save the human review for the cases where you genuinely want a second opinion.

Reading stack traces

Most of the languages we use in practice — Java, TypeScript, JavaScript — report failures as long, repetitive stack traces. On a JVM with a framework like Spring Boot, a single failure can produce a cascade of nested causes. Finding the line that actually matters is a skill, and even experienced engineers regularly spend time looking in the wrong place.

This is something AI is genuinely good at. Paste the trace in, and the assistant will locate the relevant frame, explain what went wrong, and often propose a fix. The practical takeaway is simple: stop reading stack traces line by line. Feed them to the assistant first, then read the explanation and decide what to do. And when you fix the underlying issue, add a test for it so the failure cannot return quietly.

Training junior developers

The two uses above are about speed. This one is about growth, and it may be the most valuable of the three over time.

Junior developers learn fastest when they can explore a topic at their own pace, ask follow-up questions without feeling they are imposing, and get answers grounded in the code in front of them. A senior engineer can provide all of that, but only in limited amounts — their time is the scarcest resource on the team. An AI assistant fills the
gap between those sessions. A junior developer can ask why a pattern is used here, what a piece of syntax means, or how a part of the system fits together, and follow the
thread as far as their curiosity takes them.

Used well, this raises the quality of the questions that eventually reach a senior engineer. Instead of “what does this do?”, the conversation becomes “I think this does X for reason Y — is that right, and is it the approach we want?” The senior engineer spends their time on judgment and context rather than on definitions, and the junior developer arrives already having done the legwork.

A few things make this work in practice:

  • Encourage exploration, not just answers. The goal is for the junior developer to understand the reasoning, not to paste in generated code they cannot explain.
  • Keep the human in the loop for judgment. AI is excellent at explaining how something works. Deciding whether it is the right thing to do is still a
    conversation worth having with a person.
  • Review what gets produced. The same care we apply to AI-generated tests and fixes applies here. Trust, but verify.

Where this leaves us

None of these uses are speculative. Generating tests for legacy code, parsing stack traces, and supporting junior developers as they learn are all things a team can start
doing today, with tools that are already available. The return is immediate: less time spent on tedious work, faster diagnosis of failures, and engineers who grow more
quickly. The teams that benefit most are not the ones waiting for the next breakthrough. They are the ones putting today’s tools to work on today’s problems.