The first time a coding agent edits ten files, runs the test suite, fixes the failing import, and hands back a clean diff, it feels like the work has moved to a new substrate. The second time it confidently rewrites the wrong abstraction, you realize the model was only the visible part. The real system is the harness around it.
Claude Code, Codex, and Gemini CLI are not just chat boxes with better coding models. They are runtimes. They read files, execute shell commands, call tools, remember instructions, ask for permissions, spawn subagents, and leave behind artifacts. Anthropic describes Claude Code as a tool that reads a codebase, edits files, runs commands, and integrates with development tools.1 OpenAI’s Codex CLI is a local coding agent from OpenAI.2 Google’s Gemini CLI is an open-source terminal agent with file operations, shell commands, web fetch, Google Search grounding, MCP support, checkpointing, and GEMINI.md context files.3 The model matters, but the harness decides what the model is allowed to see, do, remember, delegate, and verify.
The tempting question is “which agent is best?” I think that is the wrong first question. A strong agent in a weak harness becomes an expensive random walk. A merely good model in a disciplined harness can be useful all day.
The productivity gain from AI agents comes less from replacing developers than from turning software work into a supervised, testable, memory-bearing operating loop.
This is the article I wish I had before wiring together Claude, Codex, Gemini, browser automation, memory servers, and project skills. It is not a leaderboard. It is a map of the layers that make agents productive without letting them quietly turn into unsupervised coworkers.
The tool is not the unit
The unit is not Claude, Codex, or Gemini. The unit is a loop: goal, context, model, tool call, observation, patch, verification, and human decision. I wrote a broader field guide on the model-in-a-loop idea already, so I will not repeat that whole map here.4 The new point is more operational: the best agents now expose enough surface area that they should be configured like small developer platforms, not prompted like text generators.
Here is the stack I mean:
The thing to notice is that the model is not at the top. Human intent enters a harness, and the harness mediates every layer before the model acts.
Claude Code exposes that shape most explicitly. Its documentation names CLAUDE.md, auto memory, MCP, skills, hooks, permissions, subagents, background agents, and an Agent SDK.1 Codex exposes a similar center of gravity through AGENTS.md, local execution, IDE and app surfaces, and the Agents SDK when you want to build your own runtime.56 Gemini CLI uses GEMINI.md, built-in terminal tools, MCP servers, Google Search grounding, GitHub Actions, checkpointing, and non-interactive scripting.3 Google ADK then turns the same ideas into an application framework: agents, tools, artifacts, skills, callbacks, sessions, memory, graph workflows, and multi-agent workflows.7
The names differ. The architecture repeats.
That repetition is important because it changes how you should evaluate the tools. A model benchmark tells you something about raw capability. It does not tell you whether the tool remembers your project conventions, whether it can be stopped before git push, whether it can isolate exploratory search from the main context, whether its tools are safe, or whether it leaves a trace you can audit. Those are harness questions.
I would use a simple rule: judge agents by the work surface they give you, not only the answer they generate. The answer is one event. The surface is the system you will use every day.
Context is the first layer
An agent cannot work from your intent alone. It needs local norms: how to run tests, which packages are preferred, what not to touch, how releases are cut, how design decisions were made, and what the reviewer will reject.
That is why context files are winning. Anthropic’s CLAUDE.md is loaded at the start of sessions as persistent project instruction.8 The cross-vendor AGENTS.md describes itself as a predictable place to give coding agents project-specific guidance.5 Gemini CLI has GEMINI.md for custom project context.3 A 2026 exploratory study of agentic coding tool configuration found context files dominating the configuration landscape across Claude Code, GitHub Copilot, Cursor, Gemini, and Codex, with AGENTS.md emerging as the interoperable format.9
This matches my experience. The first productivity jump is rarely “ask better.” It is “stop re-explaining.” Put the test command, architecture constraints, commit rules, design system, and forbidden shortcuts in a file the agent reads every session. The gain is not mystical. It removes repeated setup turns and reduces the chance that the agent burns half the task rediscovering the repo.
But context files are not law. Claude’s docs are blunt on this point: CLAUDE.md and auto memory are context, not enforced configuration, and blocking an action belongs in a hook or permission rule.8 That distinction matters. “Do not edit generated files” in a context file is a request. A permission rule or hook that blocks generated paths is a control.
The context layer should be short enough to survive contact with the window. This is where people overfit. They pour a whole architecture document into the agent’s permanent prompt, then wonder why it ignores the one line that mattered. Good context files behave more like a startup checklist than a textbook:
- Commands: how to build, test, lint, run focused tests, and start the app.
- Boundaries: files the agent should not edit, generated code policy, public-safety rules, secrets policy.
- Local taste: preferred libraries, UI conventions, review standards, naming rules.
- Known traps: the three mistakes the agent has made twice.
The trap is treating context as memory, policy, and evaluation all at once. It is none of those by itself. It is just what the model sees before it starts.
Memory is a governed cache
Memory is where agent work starts to look less like a single conversation and more like an operating system. Claude Code has user-written instructions and auto memory, with auto memory storing learnings like build commands and debugging insights across sessions.8 Google ADK separates Session and State, which track one conversation, from MemoryService, which acts as searchable long-term knowledge across past conversations or sources.10 OpenAI Agents SDK lists sessions as a persistent memory layer for maintaining working context inside an agent loop.6
The useful mental model is not “the agent remembers.” The useful model is memory is a cache with governance.
Like any cache, it can be stale, duplicated, overbroad, poisoned, or scoped wrong. A memory saying “this repo uses npm” is useful until the repo migrates to pnpm. A memory saying “the user prefers no tests for small changes” might be an artifact of one emergency, not a global preference. A memory extracted from a failed run might preserve the wrong lesson. If memory feeds future context without review, it becomes a quiet prompt injection you wrote yourself.
So I split memory into three classes:
- Procedural memory: build commands, deploy commands, test shortcuts, review rituals.
- Preference memory: writing style, interaction style, design taste, default constraints.
- Project memory: architecture facts, known failure modes, integration quirks.
Procedural memory is usually safe and valuable. Preference memory is valuable but should be editable. Project memory is the most dangerous, because it ages. It should cite a source, point to a file, or be easy to invalidate.
The algorithm is retrieval, not recollection. On every turn the harness decides whether memory should enter context at all. If the task is “fix the CSS contrast bug,” the agent needs the design rules and test command, not every deployment story it has ever learned. If the task is “write an article in my style,” it needs the writing skill, the flagship posts, and the no-em-dash rule. More memory is not more intelligence. It is more input to rank.
That is why I like ADK’s split between session state and long-term memory. It forces the question: is this temporary working state, or durable knowledge worth retrieving later?10 The same question belongs in every Claude, Codex, and Gemini setup.
Tools are capability boundaries
The agent becomes consequential at the tool layer. Before tools, it can be wrong in text. After tools, it can change a repository, call an API, create a branch, open a PR, query a database, run a browser, or send a message.
MCP exists because every agent needs this layer. The protocol defines a host-client-server architecture: a host manages isolated client connections, each client talks to one server, and servers expose resources, tools, and prompts.11 Its design goal is composability with security boundaries: servers should be easy to build, narrowly focused, isolated from one another, and unable to see the whole conversation by default.11 Gemini CLI’s MCP docs show the same operational path: discover configured servers, fetch tool definitions, validate schemas, register tools, and wrap execution with confirmation logic, response processing, connection state, and timeouts.12
This layer has two jobs that fight each other.
First, tools should be easy to expose. That is the productivity story. A filesystem tool, a shell tool, a browser tool, a GitHub tool, a database tool, and a deployment tool give the agent enough reach to finish work without asking you to copy and paste every intermediate result.
Second, tools should be hard to misuse. That is the safety story. A tool’s description is model input. A server’s resource can carry untrusted text. A shell command can mutate state. An API token can reach production. The tool layer is where prompt injection stops being amusing and starts being a breach.
Good harnesses use three controls here:
- Narrow tools: expose operations with task-shaped arguments instead of raw admin surfaces.
- Typed schemas: make malformed calls impossible and semantic mistakes visible.
- Policy gates: require approval, sandboxing, or denial based on action, path, command, domain, and environment.
Claude Code’s permission docs are a clean example. Read-only file reads need no approval. Bash commands and file modifications require approval by default. Rules can allow, ask, or deny, with deny evaluated first, and the docs explicitly distinguish instructions from enforcement.13 That is the right separation. A prompt says what the agent should try. A permission layer says what the agent can actually do.
I treat every powerful tool as a loaded capability. The question is not “will the model behave?” The question is “what happens when it does not?”
Harnesses turn autonomy into operations
Once context, memory, tools, and permissions exist, the remaining work is operations. How does the agent run? Where does state live? Can the run resume? What traces are kept? What happens if the agent needs a human? Can the same workflow run from terminal, IDE, CI, and background sessions?
This is where the newer frameworks become useful. OpenAI’s Agents SDK lists a small set of primitives: agents, agents as tools or handoffs, and guardrails. Around those it adds a built-in loop, function tools, MCP tools, sessions, human-in-the-loop, tracing, realtime agents, and sandbox agents with resumable isolated workspaces.6 Google ADK frames the same problem as software development: define agent logic, tools, and orchestration in code, then scale from a single agent into workflows when instruction length, context limits, modularity, or the need to mix deterministic and non-deterministic steps makes one agent too brittle.7
The important word is “deterministic.” A harness is useful because it lets you keep deterministic code where deterministic code belongs.
For example, a coding agent should not decide how to run your entire CI policy from scratch. The harness should know the test command, the linter, the typecheck, the screenshot flow, the accessibility check, and the deployment gate. The agent can decide which focused test to run during exploration, but the acceptance gate should be boring code.
That pattern generalizes:
- Let the model explore, synthesize, and propose.
- Let deterministic tools build, test, diff, lint, scan, format, and deploy.
- Let humans approve irreversible or high-risk state changes.
- Let traces record what happened.
The productivity comes from putting the model in the middle of a loop that can learn, but not making the model the only source of truth. The harness is the adult supervision.
Orchestration is a read/write discipline
Multi-agent orchestration sounds like a management breakthrough and often behaves like a distributed systems bug. Anthropic’s multi-agent research system reported a large internal improvement over a single agent, but also about fifteen times the token use.14 Claude Code’s subagent docs make the practical benefit concrete: subagents preserve context by putting exploration, logs, and file contents in a separate context window, returning only a summary.15 The same page says subagents can have custom prompts, tool access, permissions, models, hooks, skills, and persistent memory.15
That is powerful. It is also enough rope.
My rule is simple: parallelize reads, serialize writes.
The diagram is intentionally conservative. Research, review, log analysis, browser QA, benchmark lookup, and source reading parallelize well. Each worker can be wrong independently, and the lead can compare their outputs. Implementation does not parallelize the same way unless the boundaries are clean. Two agents editing one design system, one API surface, or one migration plan will invent incompatible assumptions. You pay the merge cost in reasoning, not just Git.
A 2026 Claude Code architecture paper describes the core as a simple loop but says most of the system lives around it: permissions, compaction, extensibility, subagents with worktree isolation, and append-oriented session storage.16 That is exactly what orchestration needs. The hard part is not spawning helpers. It is bounding their context, tools, permissions, memory, and write authority.
A2A points at the next level up: agents from different frameworks collaborating without exposing internal state, memory, or tools, using discovery, modality negotiation, and long-running task collaboration.17 MCP connects models to tools. A2A connects agentic applications to each other. The two protocols answer different questions. MCP asks “what can this agent call?” A2A asks “which other agent can this agent coordinate with?”
I would be cautious with both. A standard interface lowers integration cost. It also lowers the cost of adding too many capabilities before you have evaluation. The orchestration layer should grow only after the eval layer can tell you whether the extra agent helped.
Productivity is conditional
The evidence on productivity is not a slogan. It is conditional.
The classic Copilot controlled experiment found that developers with Copilot completed a small JavaScript HTTP server task 55.8% faster than the control group.18 That is real evidence for a certain kind of task: scoped, greenfield, easy to verify, and close to code synthesis.
The METR randomized controlled trial on experienced open-source developers found the opposite in its setting. Sixteen developers working on 246 real issues in large repositories took 19% longer when allowed to use early-2025 AI tools. They expected a 24% speedup and still believed afterward they had been sped up by 20%.19 METR is careful about scope, and so should we be. The study does not prove AI tools are useless. It does show that self-reported speedup can be wrong, and that experienced developers in familiar, high-quality codebases can lose time to prompting, waiting, reviewing, and cleaning up agent output.
The reconciliation is not hard. Agents are best when the task has at least one of these properties:
- Context is expensive for a human to gather: log search, repo archaeology, dependency review, documentation sweep.
- Verification is cheap and objective: tests, typecheck, screenshots, diff review, benchmark, parser output.
- The work is parallelizable: several independent reads can collapse into one synthesis.
- The artifact can be thrown away: prototypes, drafts, migration sketches, test scaffolds.
- The codebase is unfamiliar: the agent can amortize exploration faster than the human can.
They are worst when tacit judgment dominates and verification is slow: subtle product design, security-sensitive flows, performance tuning without a benchmark, large refactors with hidden invariants, or a codebase the human already knows deeply.
So the productivity algorithm is not “use the agent more.” It is:
- Give it the context it would otherwise rediscover.
- Give it tools that produce inspectable artifacts.
- Make verification cheaper than generation.
- Use parallel agents for independent reads.
- Keep one writer for coupled changes.
The loop looks like this:
The key edge is failure feedback. A vague “try again” prompt is low-grade supervision. A failing test name, screenshot, stack trace, or reviewer comment is a reward signal the agent can actually use.
Evaluation is the steering wheel
Benchmarks are useful, but they are not your workflow. SWE-bench, Terminal-Bench, tau-bench, and newer dialogue coding benchmarks measure different slices of agent capability. Terminal-Bench 2.0 reports frontier models and agents below 65% on hard terminal tasks.20 ADK Arena evaluated 51 Python agent frameworks and found no single framework dominated, with generation success and benchmark resolution varying widely.21 That is exactly what I would expect. The harness changes the outcome.
For a team, the important benchmark is local:
- Can the agent fix a real issue from your backlog?
- Can it write a test your reviewer accepts?
- Can it diagnose a production log excerpt without hallucinating the system?
- Can it update docs without drifting from the implementation?
- Can it follow your design system under screenshot review?
- Can it stop when the right answer is “ask a human”?
This local evaluation should be a harness feature, not a spreadsheet. Save traces. Keep accepted and rejected patches. Track which instructions prevented repeated mistakes. Measure review time, not just generation time. Count how often the first patch passes. Count how often the agent changed files outside scope. Count how often a human had to undo work.
The best agent setup I know is not the one that produces the largest diff. It is the one that produces the smallest diff that passes the strongest local check.
The evaluation layer also decides memory. A repeated failure becomes a memory or a context rule only after you understand it. Otherwise you are teaching the agent superstition. “Always use --force” might have fixed one local cache problem. It might also destroy the next deployment. Good memory is postmortem, not residue.
The operating model
If I had to run Claude, Codex, and Gemini as a disciplined engineering system, I would set it up in layers.
First, write the repo contract. Put AGENTS.md, CLAUDE.md, or GEMINI.md in the repo with build commands, test commands, style rules, public-safety rules, and known traps. Keep it short. Link out to longer docs instead of stuffing them into the startup context.
Second, split memory by scope. User preferences belong at user scope. Project facts belong at repo scope. Subagent memories should be narrow. Stale memory should be easy to inspect and delete.
Third, expose tools through the smallest safe interface. Prefer task-shaped MCP tools over raw credentials. Put production actions behind approval. Deny dangerous command families by default. Treat shell access as a privilege, not a convenience.
Fourth, make the default workflow boring:
- Explore read-only.
- Plan with citations to files or docs.
- Implement in one path.
- Run focused checks.
- Run the full relevant check before handoff.
- Summarize changed files, tests, and residual risk.
Fifth, orchestrate by independence. Use Claude subagents, Codex parallel tasks, Gemini scripts, or your own ADK/OpenAI Agents SDK harness when the work can be split into independent reads. Use one writer for shared state. If two agents must coordinate every paragraph or every component boundary, you probably did not decompose the task.
Sixth, use multiple agents as reviewers, not just builders. One agent writes. Another reads the diff against the instructions. A browser harness checks the UI. A security harness checks tool boundaries. A human makes the final call for irreversible actions. This is where agent productivity becomes more than speed. It becomes coverage.
The hard part is cultural. Treat agent output like intern output and you will either micromanage it into uselessness or trust it too much. Treat it like a distributed build system with a probabilistic planner inside, and the controls become obvious.
The agent should have a job. The harness should have a contract. The human should own the merge.
Takeaways
If I compress this into a few rules:
- The harness is the product, not the model. Claude, Codex, and Gemini matter, but the practical difference comes from context, memory, tools, permissions, orchestration, and evaluation around them.
- Context guides, permissions enforce. Put project knowledge in context files, but use permission rules, hooks, sandboxes, and approval gates for actions the agent must not take.
- Memory needs governance. A useful memory layer is scoped, inspectable, retrievable, and easy to invalidate. Otherwise it becomes stale context with authority.
- Parallelize reads and serialize writes. Multi-agent work pays off when agents gather independent evidence. Shared implementation should usually have one writer and several reviewers.
- Measure the loop, not the feeling. Track review time, pass rate, diff scope, rework, and local acceptance checks. The productivity evidence is mixed enough that intuition is not a metric.
That brings the argument back to the first surprising diff. The magic was never that the model edited ten files. The magic was that the system could give it the right files, let it run the right checks, block the wrong actions, remember the useful lesson, and still make a human own the final merge.
Footnotes
-
Anthropic Claude Code docs, “Overview”. The docs describe Claude Code as an agentic coding tool available in terminal, IDE, desktop, and browser surfaces that can read code, edit files, run commands, use MCP, customize with
CLAUDE.md, skills, hooks, and run agent teams. https://code.claude.com/docs/en/overview ↩ ↩2 -
OpenAI
openai/codexrepository. The README describes Codex CLI as a coding agent from OpenAI that runs locally on your computer and links to the Codex docs and app surfaces. https://github.com/openai/codex ↩ -
Google Gemini CLI repository. The README describes Gemini CLI as an open-source terminal agent with built-in Google Search grounding, file operations, shell commands, web fetching, MCP support, checkpointing, custom
GEMINI.mdcontext files, and scripting modes. https://github.com/google-gemini/gemini-cli ↩ ↩2 ↩3 -
I covered the general definition and failure modes in “Putting a Model in a Loop: A Field Guide to Agentic AI.” This essay narrows the frame to harness design for daily use. ↩
-
AGENTS.mdproject README. It definesAGENTS.mdas a simple open format for guiding coding agents, roughly a README for agents that gives predictable project-specific context and instructions. https://github.com/agentsmd/agents.md ↩ ↩2 -
OpenAI Agents SDK documentation. The SDK exposes agents, handoffs, guardrails, a built-in loop, function tools, MCP tool calling, sessions, human-in-the-loop, tracing, realtime agents, and sandbox agents. https://openai.github.io/openai-agents-python/ ↩ ↩2 ↩3
-
Google Agent Development Kit docs, “Agents”. ADK defines an agent as a model with instructions and optional tools, then recommends workflows as complexity grows due to instruction-following, context, modularity, and deterministic plus non-deterministic control needs. https://adk.dev/agents/ ↩ ↩2
-
Anthropic Claude Code docs, “How Claude remembers your project”. The docs distinguish
CLAUDE.mdfiles from auto memory, note both are loaded into sessions, and explain that they guide behavior rather than enforce permissions. https://code.claude.com/docs/en/memory ↩ ↩2 ↩3 -
Galster et al, “Configuring Agentic AI Coding Tools: An Exploratory Study”, arXiv:2602.14690 (2026). The study analyzes configuration mechanisms across Claude Code, GitHub Copilot, Cursor, Gemini, and Codex, finding context files dominant and
AGENTS.mdemerging as an interoperable standard. https://arxiv.org/abs/2602.14690 ↩ -
Google ADK docs, “Memory: Long-Term Knowledge with MemoryService”. ADK separates session state from long-term searchable memory and documents ingestion plus search operations across memory services. https://adk.dev/sessions/memory/ ↩ ↩2
-
Model Context Protocol specification, “Architecture”, version 2025-06-18. MCP uses a host-client-server architecture, JSON-RPC, isolated server sessions, capability negotiation, and security boundaries between servers. https://modelcontextprotocol.io/specification/2025-06-18/architecture ↩ ↩2
-
Gemini CLI docs, “MCP servers with Gemini CLI”. The docs describe discovery across configured MCP servers, tool schema validation, global tool registration, resources, confirmation logic, execution, response processing, timeouts, and transports. https://github.com/google-gemini/gemini-cli/blob/main/docs/tools/mcp-server.md ↩
-
Anthropic Claude Code docs, “Configure permissions”. The docs describe read-only tools, approval for shell and file modifications, allow, ask, and deny rules, rule precedence, and permission modes including plan, auto, and sandbox-sensitive bypass behavior. https://code.claude.com/docs/en/permissions ↩
-
Anthropic, “How we built our multi-agent research system” (2025). Anthropic reports a multi-agent research system outperforming a single agent on its internal evaluation while using far more tokens. https://www.anthropic.com/engineering/multi-agent-research-system ↩
-
Anthropic Claude Code docs, “Create custom subagents”. The docs describe subagents as separate context windows with custom prompts, tool access, permissions, model choice, hooks, skills, and optional persistent memory, useful for preserving main-context space and specializing behavior. https://code.claude.com/docs/en/sub-agents ↩ ↩2
-
Liu et al, “Dive into Claude Code: The Design Space of Today’s and Future AI Agent Systems”, arXiv:2604.14228 (2026). The paper analyzes Claude Code architecture and identifies the simple loop plus surrounding systems such as permissions, compaction, extensibility, subagents, worktree isolation, and session storage. https://arxiv.org/abs/2604.14228 ↩
-
A2A project README. Agent2Agent is an open protocol for communication between opaque agentic applications, with capability discovery, modality negotiation, long-running collaboration, and no need to expose internal state, memory, or tools. https://github.com/a2aproject/A2A ↩
-
Peng et al, “The Impact of AI on Developer Productivity: Evidence from GitHub Copilot”, arXiv:2302.06590 (2023). In a controlled JavaScript HTTP-server task, the Copilot group completed work 55.8% faster than the control group. https://arxiv.org/abs/2302.06590 ↩
-
Becker, Rush, Barnes, and Rein, “Measuring the Impact of Early-2025 AI on Experienced Open-Source Developer Productivity” (METR, 2025). The RCT found experienced open-source developers took 19% longer with early-2025 AI tools in that setting, despite expecting and perceiving speedups. https://metr.org/blog/2025-07-10-early-2025-ai-experienced-os-dev-study/ ↩
-
Merrill et al, “Terminal-Bench: Benchmarking Agents on Hard, Realistic Tasks in Command Line Interfaces”, arXiv:2601.11868 (2026). Terminal-Bench 2.0 contains hard terminal tasks with tests and reports frontier agents below 65% on the benchmark. https://arxiv.org/abs/2601.11868 ↩
-
Huang et al, “ADK Arena: Evaluating Agent Development Kits via LLM-as-a-Developer”, arXiv:2606.05548 (2026). The study evaluates 51 Python ADK frameworks and finds large variation in generation effort and benchmark performance, with no single framework dominating. https://arxiv.org/abs/2606.05548 ↩