Things are changing very fast in the world of software engineering. A new suite of tools that run AI agents on the command line—Claude Code, OpenAI Codex, Google Gemini CLI, Cursor CLI, Copilot CLI, OpenCode, and others—have dramatically shifted the playing field for software engineers. These tools have only existed for about six months or less, so this information applies in October 2025 but may become outdated quickly.
When used responsibly, these tools can increase the productive output of senior engineers. But when used irresponsibly, they are technical debt factories that make code bases impossible to maintain and grow. Thus, the top question for senior engineers is how best to use these tools responsibly. I previously discussed this shift toward software architecture in We Are All Software Architects Now.
The best way to use these tools is simply to augment the actions of the human engineer. The human must make all high-level decisions about architecture and must review the full output of the AI agent.
Any output from the AI agent that is not reviewed is likely to contain security bugs, scalability bugs, maintainability bugs, or worse, may not even work at all. This is not negotiable. If you’re not reviewing the code, you’re not using AI responsibly—you’re creating technical debt.
The proper way to use these tools: determine exactly what changes you want to make to the code base, down to the level of files, functions, and code style choices. However, it is most helpful to let the AI actually write some of the code.
When context is filled in correctly, new methods can be created by the AI agent accurately. This is where the productivity gains come from—you’re not typing every character, but you are making every decision about what should be typed.
The key is context. Without proper context, the AI will hallucinate. With proper context, it can generate conventional code patterns correctly. As I described in English is a High Level Programming Language Now, this represents a new level of abstraction where English becomes the interface for expressing programmer intent.
There is a spectrum of possibilities for productive AI use. If your application is highly novel, AI will be of less use, because the statistical predictions of the AI agent will simply be wrong. But most applications are not that novel.
Most applications have a novel core and a large amount of conventional components. All conventional components can be written by AI agents with human review.
An example would be something like an input box with React in your product’s UI. AI can make this input box correctly because it has seen millions of them. If you are not making an innovative new input box, you can simply give the correct context to your AI agent, such as “make an input box following React best practices,” and it will do so.
However, there isn’t really a way to provide the correct context to your AI agent about the core of your application. Whatever that part is will either require hand-coding, or it will require a detailed specification to be filled out by the AI. In this case, the AI isn’t so much writing new code as it is turning pseudocode into working code.
Either way, the attention to detail by the human must be higher when working on the core code of the application. If the rest of your application depends on this, the human should put maximum attention onto this piece.
A way to think about this is that AI tools create additional freedom for the human to put their attention on whatever piece matters most. Perhaps the input box doesn’t matter as much as the database schema. So the human can put their mental focus on the database schema and let the UI components be built by the AI agent.
This is not totally unlike the relationship of senior engineers to junior engineers. Often, the senior engineer takes the part of the system they are uniquely able to handle, and lets junior engineers work on the more peripheral aspects of the system. AI is sort of like a junior engineer in this case.
The difference is that AI is faster and doesn’t get tired, but it also doesn’t learn from mistakes the way a junior engineer does. You must provide all the context every time.
Now we must address the issue of junior engineers using AI tools. In order to use these tools well, the engineer must actually understand and review the code. Junior engineers who produce huge volumes of code that they themselves do not understand are technical debt factories squared.
Because the junior engineer doesn’t exactly know what they want or need, they are unable to give accurate instructions or context to the AI agent. This means the AI agent has unclear instructions and will fill out code that might work on the surface, but does not conform to scalability, security, or maintainability requirements.
One possible solution to this is to maintain your AGENTS.md file and other documentation accurately, also with the aid of AI, so that the correct scalability, maintainability, and security concerns can be plugged into every AI agent. But this is not too helpful if the engineer doesn’t know this information themselves and is not able to assess whether the AI agent has succeeded or not.
Thus, it is the recommendation of the author that junior engineers should not be afraid to program the old-fashioned way whenever they do not fully understand something. It is okay to produce only 100 lines of code instead of 10,000 if those 100 lines are something the engineer understands and are correct, versus 10,000 lines of code that no one understands and has hidden bugs.
In summary, AI tools are extremely helpful and accelerate software development when used responsibly. You must hold the hand of the AI agent and tell it exactly what to do, with all accurate context, and you must review every single line.
Any code you don’t fully review is likely to contain errors, and that should be code that only exists at the periphery of your application, such as one-use scripts or UI components on a page that only one user needs—areas where that code is unlikely to cause harm elsewhere. But by and large, you must still review all code produced by the AI.
However, even so, the great advantage of all this is that the human engineer can put their mind where it matters most, most likely concerning the core aspects of the system. This produces better results than without the aid of AI.
But this only works if the human actually knows what they are doing. If they do not understand the code, the AI will dig itself into a hole it can’t get out of.
Thus, junior engineers should not be afraid to write code by hand. And the same for senior engineers: no one knows everything, and senior engineers must regularly put down the AI tools and code it up by hand to be sure they actually understand the system they are dealing with.
Furthermore, documentation must be kept up to date to provide accurate context to the AI agents. If all these rules are followed, today’s AI CLI tools, such as Claude Code and the rest, are a huge productivity boost to software engineering.
The key insight is this: AI tools are force multipliers, not replacements. They multiply your effectiveness when you know what you’re doing. They multiply your mistakes when you don’t.
Use them to handle the conventional parts of your system so you can focus on the novel parts. Use them to write boilerplate so you can think about architecture. But never stop understanding your own code, and never stop reviewing what the AI produces.
The engineers who thrive in this new era will be those who can effectively direct AI agents while maintaining deep technical understanding. The ones who struggle will be those who let the AI do the thinking for them.
Choose to be in the first group.