Coding Agent Architecture: Agent Harness and Six Core Modules
Intelligent coding agents are more than large language models. This article explains the three layers of base models, reasoning-enhanced models, and the agent control plane; why the surrounding system matters as much as the model; the observe–inspect–choose–act loop; and the six core modules of an Agent Harness: planning, tools, context, memory, policy, and observability. It also covers practical patterns for repository navigation, patch-based editing, sandboxed execution, stable prompts, and common implementation pitfalls.
In software engineering, the large model itself is important, but the system around it often determines task quality: tool orchestration, context management, session memory, and the control loop. This explains why the same type of model may perform modestly in a general chat interface yet can reliably navigate repositories, modify code, and execute commands in a coding agent built for real codebases. This article starts with conceptual layers and then moves into six practical building blocks, showing how an Agent Harness turns a “model that can write code” into an “engineering assistant that can get work done.”
Three Layers: Base Model, Reasoning Enhancement, and Agent Control Plane
A large language model is essentially a next-token prediction engine. It is good at generating coherent text within a given context. A reasoning-enhanced model is still a language model, but through training or prompting strategies it spends more compute on intermediate reasoning, validation, and candidate search. This costs more, but it can be more stable for complex decisions. An agent sits at a higher control layer: it decides what to inspect next, which tools to call, how to update state, and when to stop.
An imperfect but intuitive analogy is that the base model is an engine, a reasoning-enhanced model is a more powerful but more fuel-hungry engine, and the Agent Harness is the complete vehicle system that installs the engine and adds instruments, brakes, and navigation. When people discuss whether a model “can write code,” they often conflate model capability, reasoning behavior, and a productized agent. From an engineering perspective, these must be separated: the model generates, while the Harness makes generation observable, constrainable, and iterable.
Why the Surrounding System Matters as Much as the Model
Real software tasks are rarely single-turn question answering. An agent needs to locate files in a repository, understand dependencies, propose patches, run tests, and revise based on failure logs. Without stable tool interfaces, a controlled context window, and cross-turn memory, even a strong model can get lost in noise. Intelligent coding agents productize these capabilities: they wrap the model at the application layer to form a Harness for coding tasks, maintaining continuity across long sessions.
The core difference is that coding work depends not only on model choice but also on how codebase context is injected, the granularity of tool design, prompt cache stability, memory strategy, and session lifecycle management. The value of the Harness is that it turns these engineering problems from “assembling prompts ad hoc every time” into a reusable runtime.
Minimal Loop: Observe → Inspect → Choose → Act
Regardless of implementation complexity, most intelligent coding agents can be abstracted as an iterative loop. Observe collects the current task state and user goal. Inspect reads evidence such as the repository, logs, and test results. Choose decides the next tool or whether to finish. Act actually modifies files or executes commands. The loop continues until the goal is reached or a stopping condition is met.
The point of this loop is to turn “one-shot generation” into an “error-correcting process.” Model output is no longer directly equal to the final artifact; it is an intermediate step constrained by tool results. Failures can be fed back into context, and successes can be retained as memory, making the system more reliable on real engineering tasks.
Six Building Blocks of a Complete Harness
1. Goal and Task Planning
An agent needs to break a vague request into verifiable subgoals: locate the entry point, modify the interface, add tests, and run the build. The plan does not need to be perfect on the first attempt, but it should be updateable. A better approach is to maintain an explicit task list and revise it each turn based on new evidence, rather than packing all steps into one extremely long prompt.
2. Tool Layer
Tools are the boundary between the model and the real world. Common categories include read-only retrieval (list directories, search symbols, read file snippets), writes (patch-level edits rather than full-file overwrites), execution (builds, tests, scripts), and environment queries (dependencies, configuration). Design principles are least privilege, structured results, and readable failure information. Tool returns should include exit codes and key log summaries, avoiding dumping massive raw output directly into context.
3. Context Management
The window is limited, so budgeting is necessary. Effective strategies include extracting file snippets by relevance, using retrieval instead of pasting the entire repository, keeping repeated system prompts as a stable prefix to support caching, and compressing tool results into structured summaries. Context is not “the more the better”; what matters is whether the evidence needed for the current decision is complete and whether noise is controlled.
4. Memory and Session Continuity
Short-term memory is the current workspace state: opened files, pending changes, and recent test failures. Long-term memory is cross-session project conventions, common commands, and known pitfalls. Implementation can use simple key-value storage or tiered summaries: compress decisions and conclusions at the end of a session, then load project-level memory before task-level state on the next task, avoiding exploring the repository from scratch every time.
5. Policy and Stopping Conditions
An agent must know when to stop: tests pass, the user confirms, a step or cost limit is reached, or repeated failures produce no new information. Policy also includes risk control: dangerous commands require confirmation, write operations should produce a diff before being applied, and production environments should be read-only. Stopping conditions written into the Harness are more reliable than expecting the model to “end on its own.”
6. Observability and Human-AI Collaboration
An engineering agent is not a fully automatic black box. It should show the current plan, tool calls, and key diffs, and allow humans to insert constraints or roll back. Logs should support review: which step selected the wrong tool, and which piece of context misled the decision. Observability is both a debugging mechanism and a foundation for trust.
Practical Points for Software Engineering Tasks
Repository navigation should prioritize structured retrieval: narrow the scope by symbols, path patterns, and test naming conventions, then read a small number of files closely. Code editing should be patch-oriented: provide a unified diff or line-range replacement to reduce the chance of unintended changes. Command execution should be sandboxed: limit the working directory, timeout, network, and permissions; truncate output and extract failed assertions.
Prompt design should be stable. The system layer describes the tool protocol and safety boundaries and should change as little as possible to support caching; the task layer injects only the current goal and evidence. Reasoning-enhanced models are suitable for complex planning and comparing alternatives, while simple retrieval and formatting edits can use lighter calls to control latency and cost. The Harness scheduling strategy can choose different reasoning depths by step type.
Common Pitfalls in Implementation
Treating an agent as a “chat box that talks better” and ignoring how tool results constrain generation leads to hallucinated changes. Appending context indefinitely pushes key evidence out of the window. Tools that are too coarse (execute an arbitrary script at once) or too fine (one call per character) can make the loop unstable. Without stopping conditions, the agent can spin and waste resources. Without human review, erroneous patches may be merged directly. The correct approach is an interruptible loop, rollbackable changes, and traceable evidence.
Conclusion
The capability of an intelligent coding agent is the product of the model and the Harness. The observe–inspect–choose–act loop, together with the six modules of planning, tools, context, memory, policy, and observability, upgrades coding from one-shot generation to a sustainable engineering process. With this layering understood, evaluating or building an agent should consider both model reasoning quality and surrounding system design, rather than comparing only one-off answers in a chat interface. For developers, making these modules into a composable runtime is how to achieve stable, auditable, and collaborative intelligent assistance on repository-level tasks.
