Skip to content

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]

PhaseWhat happens
1 - Gather contextSearch files, read code, inspect git state, fetch docs. Pull only what this step needs into the context window.
2 - Take actionEdit files, run shell commands, run builds and tests, use git. Every action changes the world and produces new output.
3 - Verify resultsRun the tests, re-read the diff, check type errors. Each result feeds back and informs the next decision.
Claude Code's three blended phases. A codebase question may only need phase one; a bug fix cycles through all three repeatedly.

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.

The coding-agent loop. Gather context, plan, edit, run tests, reflect and fix, then back to gathering. Tests passing is the only clean exit; the model signals it by returning no tool call. A human can interrupt at any point to steer.

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.

Generate: propose an edit
Verify: run the tests
Green? branch on the result
The generation-verification loop. Tests are the verifier: pass stops the loop, fail sends the error back to be read and edited again. An agent that can check its own output self-corrects; one that cannot just hallucinates success in confident prose.

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

In a workflow, tests catch your mistakes at the end. In an agent, the test suite is the reward signal inside the loop: it is what the model reads after each edit to decide whether to stop or keep going. No verifier means no self-correction means back to being a fancy autocomplete. This is also why coding is the cleanest domain for agentic RL: pass/fail is a ready-made, hard-to-hack reward.

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

No pre-built index. The model runs (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

The opposite bet: chunk the repo with tree-sitter, embed the chunks, store them in a vector DB (Turbopuffer), and keep them fresh with incremental Merkle-tree sync.[6] Why it can win: conceptual recall. "Where do we handle auth?" can surface 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:

  1. Actions should be simple and easy for a model to understand.
  2. Actions should be compact, accomplishing a lot in few steps.
  3. Feedback should be informative but concise, never flooding the context window.
  4. 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:

ConcernRaw shell (human UI)ACI (built for the model)
Searchgrep dumps every hit, can blow contextResults capped at 50, a summarized count if more[9]
View a filecat the whole file into contextFixed 100-line window with line numbers (beat 30-line and whole-file in ablation)[9]
EditAny edit applies, even broken syntaxSingle edit runs a linter first and refuses invalid edits, showing the error[9]
HistoryEvery past command stays verbatimObservations older than the last 5 turns collapse[9]
The ACI is the same underlying shell, reshaped for a model: capped search, a fixed file window, a lint-guarded editor, and collapsed history.

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.
Terminal - one bug-fix cycle: gather, edit, verify

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.md or 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

Verified is a human-filtered, "solvable, fair-test" subset, and it is saturating. On the harder, contamination-controlled SWE-bench Pro (unseen tasks, standardized scaffolding), the same models drop sharply: Opus 4.5 scores 80.9% Verified but 45.9% Pro.[11] When you read a leaderboard, ask which SWE-bench, and remember Verified issues can be partially leaked into training. Real repos are messier than any benchmark.

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.

drop here

exact-match, always-current code lookup at runtime

drop here

an interface built for the model, not a human

drop here

the reward signal read inside the loop

drop here

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 work

The 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. 1.Simon Willison, How coding agents work
  2. 2.Claude Code, How Claude Code works
  3. 3.Anthropic, Effective harnesses for long-running agents
  4. 4.Vadim Kravcenko, Why Claude Code does not index your codebase
  5. 5.MindStudio, Is RAG dead? What AI agents use instead
  6. 6.Cursor Docs, Agent search tools
  7. 7.Morph, Codebase indexing
  8. 8.Yang et al., SWE-agent: Agent-Computer Interfaces (arXiv 2405.15793)
  9. 9.SWE-agent paper (Hugging Face Papers)
  10. 10.Cognition, Introducing Devin
  11. 11.CodeAnt, SWE-bench scores explained
  12. 12.Simon Willison, Agentic engineering patterns