How Coding Agents Actually Work: Tools, Context, and Loops
A coding agent looks like magic from the outside. You describe a feature, and a few minutes later there is a diff, a test run, and a summary of what changed. Underneath that experience there is no magic, only a loop: a l
A coding agent looks like magic from the outside. You describe a feature, and a few minutes later there is a diff, a test run, and a summary of what changed. Underneath that experience there is no magic, only a loop: a language model reads a task, picks a tool, observes the result, and decides what to do next. Everything interesting about coding agents follows from the details of that loop: which tools are available, what context the model can see, how it plans, and how it checks its own work. Once you understand those pieces, you can predict where agents will succeed, where they will fail, and how to use them well.
The loop is the whole architecture
At its core, an agent is a program wrapped around a language model. The program gives the model a goal, a set of tools, and a transcript of everything that has happened so far. The model produces either a piece of text or a tool call. If it calls a tool, the program runs it and appends the result to the transcript. Then the model is asked again, with the longer transcript. This repeats until the model declares the task done, hits a step limit, or the program stops it for another reason.
That loop explains both the power and the failure modes. The model is not executing code directly and it is not browsing your repository by intuition. It only knows what has been placed in its context or returned by a tool. If a tool result is truncated, the model is working with a partial picture. If the transcript grows too long, older details get summarized or dropped, and the agent can forget a constraint you stated at the start. Every agent design decision is, in some form, a decision about managing that transcript.
A typical loop for a coding task runs through recognisable stages, though the model may revisit them in any order:
- Explore the repository: list files, read the relevant modules, and find existing patterns for the kind of change requested.
- Form a plan: decide which files change, what the new behaviour should be, and how it will be verified.
- Edit code in small steps, running the compiler or tests after each meaningful change.
- Observe failures, read the error output, and fix the cause rather than the symptom.
- Summarise the change for review, including what was tested and what remains uncertain.
Steps 3 and 4 are where agents earn their keep or waste your time. An agent that edits and never runs anything is just autocomplete with confidence. An agent that runs the test suite and reads the failure output is doing something closer to engineering.
Tools are the agent's hands
A language model on its own can only produce text. Tools are what let it act. The standard toolset for a coding agent includes file reading, file editing, shell command execution, and search across the codebase. More capable setups add tools for running specific test commands, querying a database schema, fetching documentation, or opening a pull request.
Tool design matters more than most people expect. A read tool returning an entire 2,000 line file floods the context, while a search tool returning ranked snippets finds the right function with a fraction of the tokens. An edit tool applying a precise replacement is far safer than one rewriting whole files, which can silently drop behaviour the model never saw. Good harnesses also sandbox shell execution, since a model running arbitrary commands can delete files or leak secrets, so treat an agent's shell access as scoped, logged, and reversible where possible.
Here is a simplified sketch of the loop in pseudocode, to make the structure concrete:
transcript = [system_prompt, user_task]
for step in range(max_steps):
action = model.generate(transcript)
if action.is_final_answer():
break
result = run_tool(action.tool, action.arguments)
transcript.append(action)
transcript.append(result)
Nothing in that sketch is exotic. The sophistication lives in the system prompt, the tool definitions, and the rules for when to stop. A harness might stop after repeated failures on the same test, ask the user a clarifying question, or require the model to explain its plan before editing. Those guardrails are product decisions, and they are what separate a research demo from a tool you trust on a real codebase.
Context is the scarce resource
Every model has a context window, a limit on how much text it can consider at once. That window holds the system prompt, the task, the tool definitions, and the entire transcript of actions and observations. Repository exploration is therefore a budgeting exercise. Reading every file is impossible on a large codebase, so the agent must choose what to read, and that choice determines the quality of the result.
Agents manage context in a few standard ways. They retrieve files by relevance instead of reading whole directories. They summarise long tool outputs, keeping the error lines and dropping the rest. They compact the transcript when it grows too long, replacing early exploration steps with a summary. And they use persistent memory, such as a project notes file, to carry conventions across sessions without re-reading the whole repository each time.
This is why the way you write code affects how well agents work on it. Small focused modules, clear naming, and tests that document expected behaviour are all context efficient: the agent can find the right file quickly and understand it without reading half the repository. A codebase with duplicated logic, vague names, and behaviour hidden in configuration is expensive for an agent to explore, and the agent will make worse decisions because it literally cannot see enough of the system at once. The old advice to write readable code has gained a new justification: readability is now also agent legibility.
Planning, and why agents sometimes wander
Early agents planned very little: they reacted to each tool result and hoped the task converged. Modern agents often plan explicitly, writing a short plan before editing, breaking the task into steps, and revisiting the plan when a step fails. Planning helps on multi file changes, where the order of edits matters and a single wrong assumption can cascade.
Even with planning, agents wander. The common patterns are worth recognising. One is the rabbit hole: the agent finds a plausible but wrong root cause and keeps patching around it instead of stepping back. Another is scope creep: asked to fix a bug, the agent also refactors neighbouring code, renames things, and upgrades a dependency, producing a diff that is hard to review. A third is the confident wrong fix: the agent changes a test expectation to match its broken implementation, so the suite passes while the behaviour is still wrong. That last one is a review problem as much as an agent problem, and it is why diffs produced by agents deserve the same scrutiny as diffs from any other author, perhaps more.
The practical countermeasures are simple. Keep tasks small and independently verifiable. Require the agent to run the relevant tests and report the output. Review the diff, not just the summary, and check whether tests were weakened rather than fixed. And keep the agent away from tasks where a wrong change is expensive and hard to detect, such as security sensitive code or data migrations, unless a human reviews every line.
Verification is what makes an agent trustworthy
The difference between a demo and a dependable tool is verification. A serious coding agent setup treats the model's output as a draft until something independent checks it: the compiler, the type checker, the test suite, a linter, or a second review pass. The strongest setups run tests in a clean environment, not in the agent's own shell session, so a passing test means something.
This also shapes how you should evaluate agent tools. Do not judge them by the best demo output. Judge them by the failure rate on your codebase, the size and reviewability of the diffs they produce, and how often their summaries match what the diff actually does. A tool that produces a correct change half the time but always shows you exactly what it changed is more useful than a tool that is right slightly more often but hides its work.
Using agents well is not about writing longer prompts. It is about decomposition: breaking work into pieces with clear acceptance criteria, giving the agent a fast feedback loop through tests, and reviewing output critically. The agent amplifies existing engineering habits, good and bad alike.
Coding agents are not a replacement for understanding your system. They are a force multiplier on top of that understanding. The loop is simple, the tools are the hands, context is the budget, and verification is the trust mechanism. Keep those four ideas in mind, and the next time an agent surprises you, whether pleasantly or not, you will usually be able to say exactly which part of the loop produced the surprise.
Originally published by Dev.to AI. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.