Home » Context Engineering » Context Engineering for Coding Agents

Context Engineering for Coding Agents

A coding agent is only as good as the code in its context window, because it can only edit what it can see. Context engineering for coding agents is the practice of getting the right files, symbols, and project conventions into the window for each step, while keeping the window lean enough to survive a long task. The specific challenges are that codebases are far larger than any window, that the relevant code is scattered across files, and that the agent's window fills fast as it reads and edits, so selection, project memory, and loop management are what separate a coding agent that ships a correct change from one that edits the wrong function.

Coding is where context engineering is both hardest and most visible, because the gap between having the right context and not is stark: an agent shown the function it needs to change makes the change, and an agent that never retrieved that function invents a plausible edit to the wrong place. A codebase is orders of magnitude larger than any context window, so the entire task is deciding which small slice of the repository to put in front of the model for each step. This page covers how to make that decision well, building on the general context engineering principles and the agent patterns, specialized for the realities of code.

Selecting the Right Code Into the Window

The core problem is selection, and code rewards a smarter approach than plain text similarity search. The relevant context for a change is usually the function being modified, the definitions of the types and functions it calls, the callers that depend on it, and the tests that cover it, and these are connected by the structure of the code, not by textual similarity. So the strongest selection uses the codebase's structure: parse it to resolve which symbols a target depends on and which depend on it, and pull those definitions into the window rather than whichever files happen to share vocabulary. Semantic search still helps for the first hop, finding where a concept lives when the agent only has a description, but following the dependency graph from there is what assembles a window that actually contains the code the change touches.

Precision matters more in code than in prose because a coding window fills fast and irrelevant files are expensive. Including an entire large file to use one function of it wastes budget and buries the relevant span, so trimming to the pertinent functions, or including signatures rather than full bodies where the body is not needed, keeps relevance density high. The discipline is the same as general context selection, include the few definitions the change depends on and exclude the rest, but the unit is the symbol and the map is the dependency graph. An agent given the target function plus its direct dependencies and its tests has a lean, complete window, while an agent given ten whole files that mention the feature has a bloated one that is likelier to edit the wrong place.

Key Takeaway

Select code by structure, not just similarity: pull the target symbol, its dependencies, its callers, and its tests by following the codebase's own graph, and trim to the pertinent spans. A lean window of the exact symbols a change touches beats a large window of whole files that merely mention the feature.

Carrying Project Conventions and Rules

Beyond the code itself, a coding agent needs the project's conventions in context to produce a change that fits: the code style, the libraries the project prefers, the patterns it follows, the things it forbids. These are the rules a human contributor learns from a contributing guide and from reading the codebase, and an agent that lacks them writes code that works but does not match, using the wrong HTTP client or inventing a pattern the project already has a convention for. The common mechanism for supplying these is a project rules file that the agent loads into context on every task, which is the role played by files like a repository's agent instructions, and the practice of writing and maintaining these is covered across the AI coding memory pillar.

Project rules belong in the pinned, high-attention part of the window, alongside the system instructions, because they are constraints the agent must respect on every edit rather than reference material it consults occasionally. Keeping them there and keeping them current is a small investment that raises the fit of every change the agent makes. The rules should be curated rather than exhaustive, since a rules file that grows into hundreds of lines of every possible guideline itself consumes budget and dilutes attention, so the best practice is to state the conventions that actually matter and that the agent would otherwise get wrong, and to leave the obvious ones out. This is relevance density applied to rules, the same principle that governs code selection.

Managing the Agent Loop

A coding agent runs a loop, read code, make an edit, run tests, read the results, edit again, and every iteration adds tokens, so the window grows continuously and will hit the limit or succumb to context rot before a long task finishes unless it is managed. The management techniques are the general agent strategies applied to code. The agent compresses by summarizing completed sub-tasks, once a file is edited and its tests pass, the full exploration that got there can collapse to a short note of what changed and why. It writes intermediate state out, keeping a running plan and a record of decisions in a scratchpad rather than re-deriving them from a growing transcript. And it isolates, spawning a focused sub-agent with its own clean window for a distinct sub-task rather than running everything through one bloated context.

Tool results are a particular source of bloat in coding loops and deserve deliberate handling. A test run can produce a large log, a file read can return more than the agent needs, and a search can return many matches, and dumping all of this into the window verbatim fills it fast. The fix is to trim tool output to its essential result before feeding it back, the failing assertion rather than the entire test log, the relevant matches rather than every hit, so the loop can run many iterations without the accumulated tool output crowding out the code. Managing history and tool output under a budget, covered in how to manage conversation history, is what lets a coding agent sustain a task across dozens of steps rather than stalling when its window fills.

Remembering Decisions Across Sessions

The context that a coding agent most often lacks is the memory of earlier work: why a piece of code is structured the way it is, what approach was already tried and rejected, what decision was made about an architecture and for what reason. This knowledge is generated during development and then lost, because it lives in a past session's window that is gone, so the agent rediscovers the same constraints and sometimes reverses a decision that was made deliberately. A memory layer solves this by persisting these decisions and rationales outside any single session and selecting the relevant ones back into the window when the agent works in the same area again, which is the write-and-select strategy applied to a project's accumulated engineering knowledge.

This is where a memory system and a coding agent meet directly. Adaptive Recall stores facts and decisions with confidence scores and returns the ones relevant to the current task, so an agent picking up work on a module can be handed the decisions that were made about it, the approaches that were ruled out, and the conventions that were established, without carrying an entire project history in the window. Over time this turns a coding agent from one that starts fresh every session into one that accumulates knowledge of the codebase the way a long-tenured engineer does, which is the difference between an agent that keeps relearning the project and one that builds on what it already worked out. The persistence layer that makes this possible is covered in memory for AI agents and the coding-specific side in AI coding memory.

A Worked Example: Fixing a Reported Bug

The four disciplines come together in a concrete task. Suppose a coding agent is asked to fix a bug where a discount is applied twice at checkout. A naive agent searches the codebase for the word discount, pulls the ten files that mention it into the window, and starts editing whichever looks plausible, which is how it ends up changing display logic that was never the cause. A context-engineered agent works differently. It selects by structure: it locates the function that computes the order total, then follows the dependency graph to the functions that total calls, finding the two places a discount is subtracted, and it pulls those definitions plus the tests that cover checkout into the window. The window now contains the actual code paths where a double subtraction could happen, not a pile of files that merely mention discounts.

From there the other three disciplines carry the task. The agent has the project rules pinned in context, so its fix uses the codebase's existing money-handling helper rather than inventing raw arithmetic, and it matches the surrounding style without being told. As it works, it manages the loop, running the checkout tests and feeding back only the failing assertion rather than the entire test log, so the window stays lean across the several iterations the fix takes. And when it finishes, it writes to memory the decision it made, that the duplicate discount came from both the cart and the promotion module applying the same code, so a future agent touching either module is handed that context instead of rediscovering it. The same bug fix that a naive agent botches by editing the wrong file, a context-engineered agent lands because the right code, the right rules, a managed loop, and the memory of the decision were all in the window when they were needed.

Key Takeaway

Context engineering for coding agents is four disciplines together: select code by its dependency structure, carry curated project rules in the pinned part of the window, manage the loop by compressing sub-tasks and trimming tool output, and persist decisions to a memory layer so the agent builds on past work instead of relearning the codebase each session.