Previous article: How AI Will Change Software Development Work
Why I Do Not Let AI Agents Drive Alone
I wrote in the previous articles that AI agent coding is powerful, but not naturally safe. I still think that is the right starting point.
In practice, AI agents do not output especially clean code by default. They are very strong at the fine-grained parts of implementation. They are also strong at repeating similar work without getting bored, and that alone has enormous value. But if I simply hand over everything and wait for a complete result, I think the project will eventually break.
The reason is not only that the models make mistakes. My current view is that they are structurally unable to fully hold the whole design intent of a long-lived system in the same way a human owner does. But they can approximate that state for a while. They can sometimes do it impressively. But understanding the whole architecture, retaining the meaning of each boundary, and designing new behavior while respecting that intent still does not seem to be what these systems fundamentally do.
Maybe some of this improves as available resources expand. Maybe some of it improves more than I expect. But unless there is some real paradigm shift, I suspect the core limitation does not change very much. That is why my main concern is not how to make AI code faster. It is how to make AI coding safer.
I Start With ChatGPT, Not With Coding
In my recent development style, I usually start by explaining the business domain and the thing I want to build to ChatGPT. That is where I begin to solidify the specification.
Why ChatGPT first? My impression is that it handles long conversational history better than most coding agents such as Codex or Copilot. I do not present that as a proven fact. It may simply be my own impression. I treat it as a workflow-level observation, not as a benchmark comparison between products. Still, in actual use, ChatGPT often feels better at pulling together earlier discussions, older context, and even information that seems to have carried over from other conversations.
That matters more than it may sound. In the earlier article, I wrote about problems such as ignoring the intended framework structure or slipping into implementation that violates the architectural boundary I wanted. Those problems seemed to happen less often once I stopped starting directly from the coding agent and instead used ChatGPT first to organize the work.
So I now use ChatGPT as the place where I shape the problem before any agent starts touching the repository. That one change alone seems to have reduced a lot of avoidable friction.
Conversation First, Then a Design Document
The conversations I have while clarifying the idea are not disposable. I treat them as accumulated knowledge. Once I feel that enough knowledge has been built up, I let ChatGPT produce the final requirement summary.
At that stage I may also provide documents or other materials, as long as they are safe to send outside. Then I review the generated requirement summary, correct details, tighten the wording, and continue until it feels close enough to the real intent.
The next step is important. I do not ask Codex or Copilot to write code yet. First, I ask for an instruction document for the coding agent. That document is still not code. It is a design document.
This distinction matters a lot to me. If I skip directly from a vague idea to implementation, then I am asking the model to perform design implicitly while coding. That is exactly the kind of situation where AI starts making local decisions that look efficient but drift away from the intended structure.
What I Still Write Myself
Even with this workflow, there are parts I still write myself in principle. The clearest example is the entity classes.
I usually write those on my own. The reason is simple. They are part of the foundation of system design, and if there is a problem there that I do not understand, it can turn into a future bug that becomes very difficult to deal with.
There is another reason as well. Even if AI could write those classes perfectly with no mistakes at all, I still think the trial and error involved in writing them myself has value. That is where I often notice things that are easy to miss if I stay one level too far above the actual structure. I do not want to give that up casually.
So for me, this is not only about reducing AI mistakes. It is also about deciding which parts of development should remain direct contact points between the system and my own thinking.
Design Documents Need To Align Human and Agent Attention
The design document itself often includes diagrams. When needed, I have Codex or Copilot produce documents that include class diagrams, sequence diagrams, and similar materials. I use Mermaid for that.
The point is not decoration. The point is alignment. Those diagrams help both me and the AI agent hold the same mental picture of the feature before coding begins. Because of that, the output has to be readable in a way that suits me, not merely machine-generated.
There is also a cultural background here that I should mention. In Japanese system integrators, design documents are often made in Excel. A common style is to narrow the columns until the cells become almost square and then use the sheet like a layout canvas. I disliked that style from the beginning of my career. I hated it quite a lot, in fact. Even when I was less senior and had less authority, that style always felt to me like a bad way to think and a worse way to communicate.
After I moved into a position where I had more control over how development was done, I generally switched to Word for written documents. For UML and similar drawings, I used dedicated tools, exported the result as images, and pasted them into the document. Outside Japan, I imagine many teams use wikis instead. That is a reasonable choice. But personally, even writing Markdown by hand often felt like a chore, so for a long time my own practical compromise was Word plus drawing tools.
AI Removed Most of the Friction of Documentation
That changed dramatically with AI. The inconvenience of writing Markdown and the inconvenience of producing Mermaid diagrams both became much smaller. On this point, I do not think there is much room for doubt.
Right now, for system development documentation, excluding revisions to old projects that already have a legacy format, I no longer use Word, Excel, or dedicated drawing software at all. AI agents produce Markdown and Mermaid documents quickly and at surprisingly high quality.
This has had a bigger effect on my workflow than I expected. Documentation used to be something I knew was important but still experienced as resistance. Now it is much easier to keep the documents alive while the system is changing. There was also a period when agile became fashionable in Japan, although I am not sure how many teams were actually practicing anything that deserved that name. Some people even argued that agile meant not writing documentation at all. Of course that was never true. But I think the fact that such an idea could sound attractive at all says something real about the way documentation often feels to engineers. It can create enough friction that people become tempted by obviously wrong shortcuts.
That matters because the value of documentation is not just that it exists. Its value depends on whether it stays synchronized with the actual implementation and with the current design intent.
After That, the Main Worker Becomes the Agent
At that stage, the work is still centered on improving the design materials rather than writing code. Usually there are multiple rounds of adjustment. I refine the Markdown. I refine the diagrams. I refine the instruction document until I think the output has reached a practical level of quality.
When it seems complete, I do not trust one model alone. I review it with another model. If I used Codex for one pass, I may ask Copilot to review it. And because GitHub Copilot itself can use multiple models, I sometimes use that flexibility as well when I want another angle on the same material. Since the macOS version of ChatGPT can also work with VS Code, I may ask ChatGPT to review the same material as well. That cross-check raises the quality further.
Only when the design document reaches a level I consider good enough, and the major problems have been resolved or at least reduced to an acceptable level, do I ask the coding agent to implement the feature.
After that comes code review and refactoring. At this point, the number of outright behavioral defects tends to drop significantly. That contributes to speed, of course. But the larger gain may be that I end up with maintained documents that do not substantially drift away from the code. That should be normal in principle, but I doubt that many projects in the world have consistently achieved it in practice.
And when those documents do exist, they are extremely useful. They help when explaining the system to a new member. They help when explaining the system to my future self. They help because they reduce the cost of remembering why the code exists in the shape it has.
What I Deliberately Do Not Put Into the Design Document
Even in this workflow, the design document is not meant to describe everything. I generally do not describe details such as how every method should be split. Sometimes a sequence view naturally implies part of that structure, but even then the goal is to express the broad shape of the implementation, not to prescribe every local method boundary.
That may be one reason a certain type of annoyance still appears so often. Even though I explicitly prohibit it in AGENTS.md, I still frequently get those private methods that do not represent real abstraction and merely move logic sideways. The code becomes more fragmented without becoming more meaningful.
So I do not think documents alone solve this. They reduce the risk a great deal. They do not remove the need for review.
Safer Does Not Mean Slow
Even with all of these precautions, I think the risky part of AI-driven development decreases quite a lot. Of course, I do not believe this produces the kind of speed improvement claimed by people who say everything can simply be thrown at AI with no trade-offs. My experience is not that extreme.
Even so, the improvement is still more than enough to matter. It is large enough that I think any engineer doing serious development should be thinking about how to build a disciplined workflow around these tools.
For me, the point is not maximum raw speed. It is a balance between speed and quality that avoids severe problems. By that standard, the current workflow feels rational.
The Other Half of Safety Is Architecture
Even so, process is only one side of the problem. The other side is architecture.
In some ways, AI-driven development resembles the older Japanese system integrator split I discussed in the previous article, where the System Engineer handled design and the Programmer handled implementation. If I use that old distinction, AI-driven development sometimes feels like a world in which every engineer is expected to behave as a System Engineer.
If that is true, then there may be something worth learning from Japanese system integrator design practices. In my own experience with SES and other system integrators, many of the projects I worked on used object-oriented languages, but not all of them were designed in what I would call a truly object-oriented way. I often worked in smaller teams, or in teams whose headcount looked larger than their actual development capacity, such as twenty people with only five doing real implementation and the rest mainly testing. In those situations, more deliberate OOP design often made sense.
But when I think back to projects that were not like that, I often remember something different. The classes were used more like containers for functions than as carefully meaningful models. And, more importantly, the processing was often split very strictly by screen. Each person owned a screen. Sometimes even an external team was given only the related screens and nothing else.
That approach has an obvious weakness. It makes the whole system harder to understand. It also makes it easier for problematic SQL, deadlock-prone access patterns, or poor performance decisions to be created separately in each screen until the total situation becomes hard to control. In that sense, I do think the more deliberate OOP-oriented designs I used in other projects had real justification. They were not only about elegance. They were also a way to keep those concerns from scattering too freely. But that screen-split approach also has one very large advantage. Changes to one screen are less likely to spread into others.
Narrow Change Surfaces Matter More With AI
That advantage matters more in AI-driven development than it once did. What is frightening about AI agents is not only that they can break the project. If they break it badly and obviously, then the answer is simple. Revert it. If I commit frequently, I can throw away the changes with git.
The more dangerous case is the half-broken state. The system still appears to work. Most of the behavior still looks normal. But somewhere inside it now contains a severe problem that was introduced by a partially correct change.
To reduce the chance of that kind of failure, I think it is better when the impact range of one modification is as narrow as possible. The less an agent has to consider outside the target feature, the lower the risk that it silently damages some distant part of the system.
Why I Think AI May Push Design Away From Huge Client-Side Surfaces
SPA frameworks such as React remain extremely popular. That makes sense. But I also think AI may push some design thinking back toward non-SPA structures.
I do not mean that the Japanese system integrator style of splitting everything mechanically by screen should simply be copied. I do not think that is the answer. The data still benefits from being defined as models. And I suspect AI also works better when it can rely on explicit model structure.
But if both the model layer and the screen layer are organized by feature, and each feature contains only the amount of implementation it actually needs, then the amount an AI agent has to reason about becomes smaller. That lowers the risk to the whole system.
In other words, I think architectures with narrower feature boundaries and smaller change surfaces may become more attractive in the AI era, even if the exact form differs from older Japanese screen-oriented systems.
Why Design Matters Even More Now
So when I think about safe AI-driven development, I do not end up with a conclusion about prompts alone. I end up with a conclusion about engineering.
AI-driven development does not reduce the need for design ability. It increases it. The better the design, the safer and more productive AI becomes. The worse the design, the faster the damage spreads.
That is why I think the quality of design matters even more now than it did before. The tool became stronger. So the cost of weak structure also became stronger.
At the same time, I also suspect that the design most suitable for human development and the design most suitable for AI-assisted development will not always be exactly the same. I do not think I can say with confidence yet what that new optimum looks like. But I do think it is a question worth pursuing seriously.
Next article: Designing Software for AI Code Generation