

An AI agent is meant to implement a new feature. But it spends a long time searching the codebase or rewrites functions that already exist. Why does this happen, and what can be done about it?
Christoph Bergen and Robert Bauer explain how to identify architecture problems and which practices help when evolving a system. They also discuss how the harness, meaning the agent’s working environment, can be improved based on completed tasks.
An AI-friendly architecture helps coding agents find existing functionality and implement and test changes within the affected module wherever possible. Defined development workflows help preserve these properties: changes are checked against the architecture, documentation is updated where necessary, and required checks are run automatically. The “Advanced Harness” approach also involves reviewing completed tasks and revising the agent’s instructions, skills and workflows based on these experiences.
This interview has been edited for length and organised by topic.
Christoph: Robert, how do you recognise in practice that an architecture is not AI-friendly?
Robert: The clearest sign is when I give the agent the next feature and it can no longer find its way around the system. It searches the codebase for a long time, does not know which subsystem it should work in, or implements functionality that already exists elsewhere. At some point, the same logic exists several times in the system. Then it can no longer be changed centrally.
Development may continue, but every new task becomes more difficult. For me, that is a very tangible warning sign.
Christoph: Does it make a difference whether the code was written by people or by AI?
Robert: It can happen in both cases. While I was on holiday, I continued working on older private projects and deliberately tested how far I could get by simply giving tasks to the agent while hardly looking at the code myself. After three or four days, I had reached that point: the next feature could no longer be implemented as easily as it could at the beginning.
I was also using lower-cost models. Even so, I was surprised by how quickly duplication and disorder accumulated. For me, it was a good reminder of how important the agent’s structure and guidance are.
Christoph: What helps the agent find its way around more quickly?
Robert: It needs an understandable description of the architecture. What subsystems are there? What are their responsibilities? Which dependencies exist between them? And why were certain architectural decisions made?
Take a new frontend feature. The agent should be able to quickly recognise where it belongs, how that area is structured and how it connects to the backend. Of course, it can infer much of this from the code. But that takes time and context every time.
In practice, we usually solve this by automatically giving the agent links to the descriptions of the architecture components. The agent looks there at the start of a task and gets a brief overview of the system. This allows it to find the relevant folders and components quite quickly for typical tasks. The starting point is then fairly straightforward.
Christoph: We talk a lot about documentation. What does this mean for the structure of the software itself?
Robert: Modules that are separated as clearly as possible help enormously. Ideally, the agent can work on a task with two or three files as context. It then needs to know little about the rest of the system, and the change can be tested within that area.
Clear interfaces are part of this: what goes into a module, what comes out, and which conditions apply? Such boundaries make the work manageable. Of course, not every change can be contained so neatly. But wherever possible, that is exactly what I would work towards.
Further reading: The article “Token Efficiency in AI Coding Assistants: 10 Strategies for Reducing Costs and Context” explores how to reduce unnecessary search and excessive context in coding workflows.
Christoph: Let us assume that the modules are sensibly structured and the architecture is documented. How do we preserve this state as the system evolves?
Robert: We need a defined process for this. We need to establish how a new feature is created and how a bug is fixed. Otherwise, we explain the same basic principles to the agent again for every task.
Whether a team uses Spec-Driven Development, Test-Driven Development or variations of these approaches is secondary to me at first. What matters is that certain steps take place reliably. A codebase can lose its AI-friendly qualities again. If we clean it up once and then continue working without structure, we will eventually face the same problems again.
Christoph: How much process is needed? That can quickly sound like additional effort for every small change.
Robert: It can remain manageable. As a minimum, I would include four steps. First, we compare the task with the architecture and clarify where the change belongs. Then we record a brief plan of the required changes. Next comes the implementation. Finally, we check whether it was actually integrated into the architecture as intended.
The final step also includes checking the documentation. If something has been added or we have made a deliberate exception, it needs to be documented. This keeps the description useful for the next task.
The process needs a clear entry point. For a feature, I call the intended workflow; for a bug fix, I call the corresponding alternative workflow. Initially, this can simply be a prepared prompt. What matters is that I start the workflow deliberately.
Christoph: How binding are such requirements when the agent is expected to follow them itself?
Robert: It is worth making a careful distinction here. If I write in a prompt, “Please run check XYZ after coding,” that is initially an instruction. I am relying on the agent to remember it and implement it correctly.
In a pipeline, I can make the check mandatory. It runs automatically, and if it fails, the process cannot continue at that point. The agent has to resolve the problem. Especially for these kinds of checks, I want to depend as little as possible on whether the agent triggers them itself.
These technically embedded rules help ensure that the development process is actually followed.
Christoph: What else should a review look at?
Robert: At how the change fits into the overall system. A function may look good in isolation. Whether it is in the right module or reimplements something that already exists elsewhere can only be determined with knowledge of the architecture.
That is precisely the part of the review that requires attention. I need to understand how the affected parts relate to one another. Looking at the changed lines of code alone often does not answer these questions.
Background: The article “Harness Engineering: How to Keep AI Coding Agents Controllable in the Project Context” describes the working environment around a coding agent and the interplay of instructions, tools, checks and feedback.
Christoph: You mentioned a third point in our preliminary discussion, “Advanced Harness”, and it takes things one step further. What do you mean by an Advanced Harness?
Robert: I am particularly interested in the system’s self-reflection. We have defined a working process with instructions, skills and checks. There should now be a step that examines whether this process is still appropriate and where we need to improve it.
This is different from checking whether the architecture documentation is still correct. In that case, we simply make sure that code and documentation match. With self-reflection, we look at how the agent works: are its skills up to date? Do the instructions still fit the libraries being used? Are there rules that we have repeatedly had to remind it of in the past?
One example would be a library whose usage has changed. The agent encounters a warning and works out how to deal with it during the task. This insight should then be incorporated into the appropriate skill. Otherwise, it will encounter the same error again next time.
Another example would be new style guidelines that we have defined. If I have to explain again after a few weeks where they are located and that they need to be considered, we have not properly incorporated the experience from the previous task.
Christoph: So that would be an outer loop in the sense of Loop Engineering?
Robert: Exactly. The inner loop handles a specific task and corrects the result based on feedback. The outer loop looks at the way of working across several tasks.
Self-correction and self-optimisation therefore concern two different levels. In one case, we improve the current change. In the other, we adapt the skills, instructions or workflows used to create future changes.
Christoph: How do you approach this in practice today?
Robert: My approach so far is quite simple, and I do not yet apply it consistently everywhere. At the end of a task, the chat already contains a great deal of context: which skills were loaded, which steps the agent carried out and where I had to correct it.
I have another skill review this. It is meant to write a short retrospective: what worked? Where were there difficulties? Did tool calls fail? Did script calls specified in the instructions not work?
This summary is stored separately. If such reviews are created regularly, it is possible to build a broader reflection loop on top of them. We then have concrete experience from the runs that can be used to improve the way of working. That is the direction I want to pursue.
Further reading: “Loop Engineering: How to Build Reliable AI Coding Agents” explains the different feedback loops and distinguishes, among other things, between checking individual results and improving the system across several runs.
Christoph: What role does the selection of additional tools and skills play?
Robert: They should fit the project. This can include support tools, MCP servers or prepared information about the libraries being used.
However, I am not a fan of huge collections of skills. For a library, I prefer a compact core skill that contains the most important guidance and points to further documentation that is easy for agents to read. The agent can then look things up when necessary. After all, a large number of individual skills also need to be maintained and kept up to date.
Christoph: How far can we already rely on ready-made coding environments for this?
Robert: In the tools I have tried, I have seen approaches in this direction. Some retain information across tasks or reflect in the background. But I have not yet been able to rely on them to produce the improvements I need for my project.
I also want more visibility. I want to be able to see which information has been retained and what the system has changed in the way it works. That is an important requirement for me as harness tools continue to develop.
But even with better tools, configuration remains an engineering task that I do not want to leave entirely to AI. I would choose different workflows for a private project than for a client project with particular quality requirements. We still need to define consciously which rules apply, which checks are mandatory and how we want to work with the codebase, and reflect these requirements in the harness.
