Applied Agents
Coding agents
How Claude Code and friends work
This is probably the agent you already use every day: Claude Code, Cursor, Codex, Devin. Under the hood it is nothing exotic - a model in a loop, running tools over your repo. What makes coding the breakout application is not a special model. It is that code has a property most tasks lack: outcomes are verifiable. A test passes or it does not. That single fact turns a code generator into a self-correcting agent.
A coding agent is a model in a loop over a repo
Strip away the UI and a coding agent is, in Simon Willison's phrase, "an LLM + a system prompt + tools, run in a loop."[1] The model emits a tool call; a executes it against the real world (the filesystem, the shell, git), captures the result, and calls the model again. The loop stops when the model returns no tool call (it thinks the task is done) or a step or cost safeguard trips. You have seen this machinery already: it is the agent loop, wired to real tools, with reflection baked into every turn. "A simple tool loop is a few dozen lines of code - a good loop (recovery, context management, permissions, caching) is where the engineering lives."[1]
Claude Code's docs describe the loop as three blended phases that repeat until the work is verifiably done. A question about your codebase might only need the first; a bug fix cycles through all three, over and over.[2]
| Phase | What happens |
|---|---|
| 1 - Gather context | Search files, read code, inspect git state, fetch docs. Pull only what this step needs into the context window. |
| 2 - Take action | Edit files, run shell commands, run builds and tests, use git. Every action changes the world and produces new output. |
| 3 - Verify results | Run the tests, re-read the diff, check type errors. Each result feeds back and informs the next decision. |
Crucially, the human stays in the loop. You can interrupt (Esc), or type a correction that the model reads after the current action finishes: a live steering signal, not a fire-and-forget batch job.[2]
The loop, as a cycle
Here is the beating heart of every coding agent. The branch at run tests is the whole point: green exits the loop, red routes to reflect / fix and the cycle continues.
Tap a node to see what it does.
Why coding is the breakout application: verification
Every other applied-agent domain - clicking around a GUI, drafting an email - struggles because success is fuzzy and expensive to check. Code is the exception. The generation-verification loop closes cheaply and automatically: generating a fix is hard, but checking it is a compiler pass, a type-checker, a test suite, each a fast, objective, machine-runnable verdict. That asymmetry is what lets the agent grade its own work and iterate without a human in the middle of every step.
This makes the single highest-leverage practice obvious: give the agent something to verify against. Provide the failing test, the expected output, the target screenshot. Anthropic's own harness guidance goes further: verify end-to-end (drive the real app), not just unit tests, because agents will otherwise mark a feature "done" that does not actually work for a user.[3]
Tests aren't just correctness - they're the agent's feedback signal
Context gathering: agentic search, not RAG
Before it can act, the agent has to find the relevant code in a repo it has never seen. There are two philosophies, and this is one of the most instructive design forks in the whole field.
Agentic search - Claude Code, SWE-agent, Devin
grep / glob / file-reads) at runtime and refines iteratively, exactly how you explore an unfamiliar repo. Claude Code's team started with a local vector DB (RAG) and dropped it: agentic search consistently won.[4] Why it wins: precision (grep is exact matches, no fuzzy false positives), freshness (nothing to drift while you edit), simplicity (nothing to build or maintain), and privacy (no code leaves the machine to be embedded).[5]Semantic indexing - Cursor
middleware/session.ts even if the word "auth" never appears. Cursor reports semantic plus grep is ~12.5% more accurate than grep alone, and the gap widens most on 1,000-plus file codebases.[7]This is not "good versus bad": both are shipping products. It is a real tradeoff - precision, freshness, and privacy versus conceptual recall on large repos. It is the same RAG-versus-tool-use tension from the retrieval module, now decided for code specifically.
The harness and the ACI: the interface drives performance
Here is the counter-intuitive lesson. The Princeton SWE-agent paper found that the interface you give the model matters as much as the model itself. A human-oriented UI (the raw Linux shell) is a bad fit for a language model. Wrap the same GPT-4 Turbo in a purpose-built and SWE-bench performance jumped from ~3.8% to 12.5%, roughly 10.7 points over a plain-shell baseline.[8] Same model. Better interface.
The harness is that interface plus the machinery around it - Claude Code is "the agentic harness around Claude: it provides the tools, context management, and execution environment."[2] SWE-agent distilled four ACI design principles worth memorizing:
- Actions should be simple and easy for a model to understand.
- Actions should be compact, accomplishing a lot in few steps.
- Feedback should be informative but concise, never flooding the context window.
- Guardrails mitigate error propagation and speed up recovery.
Those are not slogans, they are concrete components. Compare what a human tool exposes versus what SWE-agent's ACI exposes:
| Concern | Raw shell (human UI) | ACI (built for the model) |
|---|---|---|
| Search | grep dumps every hit, can blow context | Results capped at 50, a summarized count if more[9] |
| View a file | cat the whole file into context | Fixed 100-line window with line numbers (beat 30-line and whole-file in ablation)[9] |
| Edit | Any edit applies, even broken syntax | Single edit runs a linter first and refuses invalid edits, showing the error[9] |
| History | Every past command stays verbatim | Observations older than the last 5 turns collapse[9] |
The lint-guarded editor is the sharpest example of principle 4: it stops the agent from ever seeing a broken file, a whole class of downstream errors prevented at the interface. A real harness adds more on top: context management (auto-compact older tool outputs, then summarize, which is why durable rules belong in CLAUDE.md, not chat, since compaction can drop early messages), permissions (ask before edits or commands with irreversible side effects), checkpoints (snapshot each file before editing so you can rewind), and subagents with fresh isolated context that return only a summary.[2] One more quiet economic driver: harnesses never mutate earlier turns, so the prompt prefix stays cache-hittable, cutting the token bill of a long session dramatically.[1]
Watch it run: fixing a failing test
Prompt: "The checkout flow is broken for users with expired cards. Code is in src/payments/. Write a failing test, then fix it." Here is the trace, phases tagged. Notice that running the test again is the entire difference between an agent and a code generator.
$ pytest -k checkout # (1) gather - reproduce it
FAILED test_checkout_expired_card
AttributeError: 'NoneType' has no attribute 'refresh'
$ grep -rn "refresh" src/payments/ # (1) agentic search, no index
token.py:42 def refresh(self): ...
checkout.py:88 token = self.get_token(); token.refresh()
$ sed -n '60,120p' src/payments/checkout.py # (1) read a 100-line window
-> get_token() returns None when the card is expired
# (2) edit - guard the None (harness snapshots the file + lints the patch first)
checkout.py:88 if token is None: raise ExpiredCardError(...)
$ pytest -k checkout # (3) verify - run it again
PASSED
# tests are green -> the model returns no tool call -> the loop stops.Three phases, recurring: context (the reproduce, search, and read), action (the edit), verify (the re-run). Had the test still failed, the last output would feed reflect / fix and the cycle would spin again. Devin runs exactly this loop autonomously end-to-end - sandboxed shell plus editor plus browser, long-horizon planning, iterating until tests pass - then opens a pull request for human review.[10]
How to prompt your daily coding agent well
- Give it a verifier. A failing test or expected output is worth more than three paragraphs of description.
- Separate research from implementation. Ask it to explore and propose a plan before it edits; two-phase beats jumping straight to code.
- Be specific, then delegate. Name files, constraints, and patterns, then trust it to choose which files to read. Precise first prompts often land first try.[1]
- Put durable rules in
CLAUDE.mdor config, not the chat; compaction drops early conversation.[2]
SWE-bench, and a reality check
is why we can even talk about progress: it hands an agent a real GitHub issue and grades it by whether its patch makes the repo's hidden tests pass. SWE-agent posted 12.5% in mid-2024; Verified leaders now sit in the 70 to 90%-plus range.[11] Genuinely fast progress, but do not read the headline number as "solved."
SWE-bench Verified overstates real-world capability
The frontier framing is telling: the discipline is shifting from prompting agents to designing the loops that run them - worktrees, skills, sub-agents, external state, and start-of-session verification that survives across many context windows. "Loop engineering," not prompt engineering, is where reliability now comes from.[12]
Check yourself
Match each coding-agent building block to what it is.
exact-match, always-current code lookup at runtime
an interface built for the model, not a human
the reward signal read inside the loop
tools, context management, permissions, and caching
Why is coding the breakout application for autonomous agents?
What does agentic search do instead of RAG, and the four reasons Claude Code chose it?
What is the counter-bet? Try to state it, then check.
Lock it in
- A coding agent is a model in a loop: gather context, take action, verify - repeating until tests are green (no tool call) or a safeguard trips. The human can steer at any point.
- Verification is the breakout property. Code is cheaply, automatically checkable; tests are the in-loop feedback signal that turns a generator into a self-corrector. Always give the agent something to verify against.
- Agentic search beats RAG for code: grep/glob at runtime wins on precision, freshness, simplicity, and privacy. Cursor's indexing is the counter-bet that pays off on 1,000-plus file, conceptual queries.
- The ACI matters as much as the model. Capped search, a 100-line file window, and a lint-guarded editor lifted GPT-4 Turbo from ~3.8% to 12.5% on SWE-bench. Design the interface, not just the prompt.
- Read benchmarks skeptically: SWE-bench Verified (70 to 90%-plus) saturates and overstates; SWE-bench Pro is far lower (80.9% to 45.9%). Ask which one.
Primary source
Simon Willison, How coding agents workThe clearest first-principles walk-through of "an LLM + a system prompt + tools in a loop," why a good loop is the real engineering, and how prompt caching quietly powers long sessions. Pair it with the Claude Code "How it works" docs for the concrete harness.
Sources
- 1.Simon Willison, How coding agents work
- 2.Claude Code, How Claude Code works
- 3.Anthropic, Effective harnesses for long-running agents
- 4.Vadim Kravcenko, Why Claude Code does not index your codebase
- 5.MindStudio, Is RAG dead? What AI agents use instead
- 6.Cursor Docs, Agent search tools
- 7.Morph, Codebase indexing
- 8.Yang et al., SWE-agent: Agent-Computer Interfaces (arXiv 2405.15793)
- 9.SWE-agent paper (Hugging Face Papers)
- 10.Cognition, Introducing Devin
- 11.CodeAnt, SWE-bench scores explained
- 12.Simon Willison, Agentic engineering patterns