How to Build Real Software With an AI Coding Agent Like Codex
A high reasoning coding agent can build almost anything if you plan first, work in small steps, and stay in charge. Here is the workflow that actually ships, with a real business example.

The most valuable shift in AI-assisted software development is not speed. It is what happens when you stop asking the model what to do and start telling it what the result must look like. Almost every team that struggles with AI coding agents is struggling with the leadership problem, not the technology problem.
Madhuranjan Kumar has watched this play out across dozens of build sessions: the same model, the same task, producing dramatically different outcomes depending solely on how the person directing it frames the goal. The model that returns a sprawling, overengineered first draft when asked "how should I build this?" returns a clean, working prototype when told "here is what I need this to do, and here is what success looks like." The difference is not in the model. It is in who is in charge.
The Engineer That Never Pushes Back, And Why That Is the Real Danger
An AI coding agent is a tireless senior engineer with one dangerous characteristic: it almost never pushes back. It does not tell you the feature you are asking for is unnecessary. It does not question whether the tool you are building actually solves the problem you have. It does not say this is overengineered, let me propose a simpler version. It builds what you describe, thoroughly and fast, whether or not what you described is what you actually need.
This is a capability that turns into a liability when the person directing the model has not thought clearly about the goal. A coding agent given a vague description of what to build will build something. It will be coherent, internally consistent, and often technically impressive. It will also frequently miss the actual need, because the model cannot infer the business context, the user experience constraints, or the operational realities that would have shaped a human engineer's clarifying questions.
The agent's willingness to execute without pushback means the entire responsibility for the quality of the direction falls on the person commissioning the build. In a traditional software development relationship, a developer pushes back, asks questions, challenges assumptions, and sometimes refuses to build something they believe is the wrong approach. That friction is valuable. It catches bad ideas before they become working code that still does the wrong thing. A coding agent provides almost none of that friction. You get what you asked for, and if you asked for the wrong thing, you get a working implementation of the wrong thing delivered with complete confidence.
This is not a criticism of the tools. It is a description of how to lead them correctly. The developer who used to push back is gone from this workflow, and the intellectual responsibility that person carried has transferred entirely to you. The speed advantage of AI-assisted development comes packaged with this leadership requirement, and teams that try to use the speed without accepting the leadership requirement usually produce technically impressive software that solves problems slightly adjacent to the ones they actually have.
The corrective is to front-load the thinking that used to happen in the back-and-forth with a developer. Before you direct the agent toward any implementation, write out what the result must look like from the perspective of the person who will use it. Describe the user's journey through the tool. Describe what happens in the failure cases. Describe what you want to be true about the output that you cannot live without. That description is your direction, and your direction is the only pushback the agent will ever receive.
There is a second dimension to this leadership requirement that becomes visible in longer build sessions. A coding agent set to high reasoning effort can think for several minutes on a hard problem and produce a solution that is genuinely impressive. But that reasoning, applied to a poorly framed goal, is impressive effort spent in the wrong direction. High reasoning effort amplifies both good direction and bad direction equally. The highest-performing use of an agent's reasoning capacity is a precisely framed goal, because the agent's thinking then elaborates on the right problem rather than elaborating on an approximation of it.
The instruction to write the simplest version possible is part of the same principle. Models tend to overengineer. They add abstraction layers that are not needed yet, implement configuration options for use cases that do not exist, and build infrastructure for scale that the current workload does not require. Asking explicitly for the fewest lines of code that accomplish the goal produces cleaner work, because the instruction forces the model to prioritize the actual requirement over its instinct to make the system general and extensible before it has proven it works at all. A small working tool that does exactly one thing is more valuable than a large, configurable system that almost works at three things.

Planning Is the Skill That Survives Every Model Update
Every few months, a new model arrives that is meaningfully better than the one before it. Prompting techniques that worked well on one model need adjustment on the next. Context window sizes change. Reasoning capabilities shift. The specific ways a model interprets ambiguous instructions evolve. In that environment, almost every tactical skill you develop for working with a specific model has a shelf life.
Planning does not. The skill of translating a business need into a clear, staged build plan, written down before any code is written, is the one capability that transfers across every model update, every new harness, and every shift in the underlying technology.
The planning step works as follows. Before the agent writes a single line of code, have it read your goal statement and produce a short plan, typically six steps covering the major stages of the build, and save that plan to a markdown file in the project. The markdown file matters for a specific reason: the plan needs to outlive the chat session. A reasoning chain that lives only in a conversation window disappears when the session resets or the context window fills. A markdown file is a project artifact that can be referenced, revised, and shared.
Then build one step at a time. Complete a stage, test it, and confirm it is working before moving to the next. The temptation with a fast coding agent is to describe the entire system and let it run. That temptation is worth resisting every time. Large one-shot builds produce cascading errors because the model makes assumptions in early stages that create incompatibilities in later stages, and by the time the incompatibility surfaces, a significant amount of work is tangled up in it. A step-by-step build catches each assumption before it creates downstream problems, and each completed step is a stable foundation rather than a dependency that might be fragile.
For a photography studio building a client gallery and proofing tool, the plan looks like this: step one, set up the gallery with the ability to upload and display a set of images under a unique client identifier. Step two, generate a private link for each client that gives them access to their gallery only. Step three, add favorite and approve buttons on each image. Step four, store the client's selections in a simple data structure tied to their client identifier. Step five, build a summary view that shows the studio owner which clients have approved their gallery and what their selections were. Step six, send an automatic notification to the photographer when a client submits their approval.
Six steps, one at a time, tested after each. That is a complete proofing tool, built from a six-line plan.
The plan also serves as the documentation. When the studio owner returns to the tool six months later and wants to add a feature, the plan tells them what was built and why it was structured the way it was. A chat history from the build session serves the same purpose poorly: it includes the wrong turns, the retries, and the exploratory prompts alongside the actual decisions, and separating one from the other takes more time than reading a short, clean plan. Good plans are the reason software stays understandable as it grows, not the reason it gets built faster. Speed is the byproduct. Clarity is the point.
This planning habit also changes what you can hand off. A plan saved in a markdown file is something another person can pick up, or something a future agent session can read as context without re-deriving the structure from the code itself. It converts the build from a one-time event into a traceable, extensible project. That quality, traceability and extensibility, is what separates software that grows with a business from software that has to be replaced when the requirements change.

Two Agents Together Catch What One Never Will
A coding agent reviewing its own code has a structural limitation that no amount of reasoning depth overcomes. It produced the code from a specific set of assumptions, with a specific framing of the problem, and a specific understanding of what the code needs to do. When it reviews the same code, it brings the same assumptions and the same framing to the review. The bugs it is most likely to miss are the ones that follow from those assumptions, because the assumptions feel correct to the model that holds them.
A second agent, reading the same code with no knowledge of how it was produced, brings a different set of priors to the review. It does not know which parts of the implementation were considered carefully and which were handled quickly. It reads each piece of code at the same level of attention and with the same skepticism. The bugs it catches are frequently the ones the first agent was most confident about, because the first agent's confidence was itself an artifact of the assumptions the second agent does not share.
In practice, running a second agent over code that a first agent produced catches a different category of issues than the first agent's own self-review. The first agent tends to catch implementation errors: places where the code does not quite do what it was intended to do. The second agent tends to catch design errors: places where the code does exactly what it was intended to do but the intent itself was wrong, or where a missing case at the design level produces unexpected behavior at the edge.
For the photography studio proofing tool, the second agent review surfaces specific gaps that the first agent missed entirely. What happens if a client opens their gallery link and approves their selection, then opens the same link again on a different device? Does the approval register twice? What happens if a client has no images uploaded yet because the photographer is still editing? Does the gallery page show an error or a graceful empty state? What happens if the notification to the photographer fails because the email address is misconfigured? Is there a retry, or does the approval get lost silently?
None of these are bugs in the traditional sense of the first agent's code being wrong. They are gaps in the design that the first agent did not flag because it was focused on implementing the specified behavior rather than exploring the unspecified behavior around the edges. The second agent, reviewing with no prior exposure to the implementation, asks exactly these edge questions because they are what a reviewer with fresh eyes naturally asks.
The same logic applies when a coding agent reviews a pull request. A human reviewer and a model reviewer catch different types of mistakes. Human reviewers are strong on business logic and intent alignment. Model reviewers are thorough on edge case coverage, error handling, and consistency with existing patterns in the codebase. Running both, not one or the other, produces a review that covers both categories. Adding the model review takes about a minute and catches a category of issues that human reviewers regularly miss, particularly in code paths that are not exercised by the obvious test cases.
For the photography studio, the practical business impact of a well-built proofing tool extends beyond the efficiency of the approval process itself. A client who receives a professional, private gallery link on a clean mobile page, marks their favorites with a tap, and approves with a single button has a meaningfully better experience than a client who emails back and forth with the studio to communicate selections. That experience difference shows up in the language of reviews: clients describe the studio as organized, professional, and easy to work with. Those descriptors drive rebooking and referral at a rate that the quality of the photographs alone does not, because many of the studio's competitors also take good photographs, but not all of them make the post-shoot process feel easy.
A tool that converts the proofing step from a multi-day email thread into a 20-minute client action does not just save the studio time. It changes what the studio's clients say about working with them, which changes how new clients decide to book, which changes the studio's growth trajectory. The software itself takes a day to build and a second agent session to review correctly. The downstream effect on the business compounds across every booking.
The lesson that holds across every build of this type, the photography studio proofing tool and every other internal tool built with two agents, is the same. The model is not the variable that determines whether the software succeeds. The leadership is the variable. Write the goal clearly. Plan before you build. Keep the implementation simple. And bring in a second perspective on everything that will touch real users, because the thing you did not specify is always the thing that matters most to the person using it.
That is exactly what we do at AI DOERS. Book a private 30-minute call with Madhuranjan Kumar and we will map the fastest path to it for your specific business.
Book your call →
