Skip to content

The Core Agent Loop Pattern in Coding Agent CLIs

A research article on the single shared design at the heart of Codex, Claude Code, Gemini CLI, and OpenCode — the "agent loop." Research date: Aug 2, 2026. All facts linked to verified primary sources.


TL;DR

Every coding agent CLI — Codex, Claude Code, Gemini CLI, OpenCode — implements the same core pattern: a loop that alternates model inference with tool execution, feeding tool results back into the prompt until the model emits a final message. OpenAI calls it "the agent loop" and states it sits "at the heart of every AI agent"; Anthropic documents it as the "agentic loop" (gather context → take action → verify results); Google's architecture doc describes the identical flow; OpenCode implements it as iterative steps gated by permissions. The loop is the product of convergent engineering, and its academic ancestor is ReAct (https://arxiv.org/abs/2210.03629).

The real craft of an agent CLI is not the loop itself — a basic loop is "a few dozen lines of code" (Simon Willison, https://simonwillison.net/guides/agentic-engineering-patterns/how-coding-agents-work/) — but the harness engineering around it: prompt assembly, context management, caching, exit conditions, and permission/sandbox gates.


Part 1 — The Canonical Loop Pattern

1.1 The six stages

# Stage What happens Who controls it
0 Turn starts User submits a query; conversation history is loaded CLI frontend
1 Prompt assembly System/instructions, tool schemas, memory files, environment context, history, user message are composed into one prompt Harness (not the model)
2 Model inference Prompt is sent to the model API (streamed via SSE); model emits reasoning + optional tool calls + text Model
3 Parse tool calls Each function call (name + arguments) is deserialized and validated against registered tools Harness
4 Execute tools Tools run (shell, file edit, search, web); gated by sandboxing / user approval / permissions Harness + OS + user
5 Append + re-query Tool outputs are appended to the input; prompt grows; re-query the model (new prompt = old prompt + tool results, as an exact prefix) Harness
6 Exit Loop ends when the model emits a final assistant message (no more tool calls), or an exit tool / max-steps / user interrupt fires Model or harness

1.2 Pseudocode

def run_turn(user_input):
    input = assemble_input(system_prompt, tool_schemas, memory_files,
                           environment_context, conversation_history, user_input)
    while True:
        response = model.infer(input)          # stage 2
        if response.is_final_message():
            return response.text               # stage 6 — exit condition
        for call in response.tool_calls:
            result = execute_tool(call, gate=permissions)   # stage 4
            input.append(function_call(call))
            input.append(function_call_output(result))      # stage 5
        if input.exceeds_context_window():
            input = compact(input)             # context management
        if steps_exhausted():
            return summarize_and_stop()        # forced exit

This is the loop OpenAI documents end-to-end in "Unrolling the Codex agent loop" (https://openai.com/index/unrolling-the-codex-agent-loop/): "the agent executes the tool call and appends its output to the original prompt. This output is used to generate a new input that's used to re-query the model... This process repeats until the model stops emitting tool calls and instead produces a message for the user."

1.3 Key terminology (turn / thread / step)

  • Step / iteration: one inference + tool-call cycle inside a turn. A turn can contain "hundreds of tool calls" (OpenAI).
  • Turn: the whole journey from user input to final assistant message. "Each turn always ends with an assistant message... which signals a termination state in the agent loop" (OpenAI).
  • Thread / session: the multi-turn conversation; every new turn re-sends the full accumulated history as part of the prompt.
  • OpenCode's steps: "the maximum number of agentic iterations an agent can perform before being forced to respond with text only" (https://opencode.ai/docs/agents/).

Part 2 — How the Four Major CLIs Implement the Same Loop

2.1 Codex CLI — the most explicit documentation

Source: https://openai.com/index/unrolling-the-codex-agent-loop/ (M. Bolin, Jan 2026), plus the open-source repo https://github.com/openai/codex.

  • Transport: HTTP to the Responses API (SSE stream; events like response.output_item.added, response.output_text.delta, response.completed).
  • Prompt construction (the instructions / tools / input fields):
  • instructions: model-specific base instructions bundled with the CLI (e.g. gpt-5.2-codex_prompt.md in the repo).
  • tools: CLI-provided tools (e.g. shell, update_plan), API-provided tools (e.g. web_search), and user tools via MCP servers (e.g. mcp__weather__get-forecast).
  • input, in order: (1) a developer message describing the sandbox and permission rules — which apply only to Codex's own shell tool, not to MCP tools; (2) optional developer_instructions from config; (3) user instructions aggregated from AGENTS.override.md / AGENTS.md hierarchy (32 KiB cap) and skills metadata; (4) an <environment_context> message with cwd and shell.
  • Loop mechanics: each tool call and its function_call_output are appended to input so the new prompt is an exact prefix of the old one — intentionally, to maximize prompt-cache hits.
  • Statelessness: Codex deliberately does not use previous_response_id, keeping every request stateless and ZDR-compatible (PRs #642, #1641).
  • Compaction: originally manual /compact (summarize via the API and restart with the summary); now automatic via the /responses/compact endpoint when auto_compact_limit is exceeded; a special type=compaction item with encrypted_content preserves the model's latent understanding.

2.2 Claude Code — "gather context, take action, verify results"

Source: https://code.claude.com/docs/en/how-claude-code-works (official docs).

  • The agentic loop: three phases that blend together — gather context (search/read), take action (edit/run), verify results (run tests, check output) — repeated until the task is complete. A question may only need context gathering; a bug fix cycles through all three.
  • Two components: "models that reason and tools that act"; Claude Code itself is the "agentic harness" — "it provides the tools, context management, and execution environment that turn a language model into a capable coding agent."
  • Tool categories (five): file operations, search, execution, web, code intelligence. "Each tool use returns information that feeds back into the loop, informing Claude's next decision."
  • Human in the loop: the user can interrupt at any point (Esc cancels the running tool call; typed corrections are read as soon as the current action completes).
  • Context management: auto-compaction clears older tool outputs first, then summarizes the conversation; persistent rules belong in CLAUDE.md (a "Compact Instructions" section can control what's preserved); /context shows usage; skills load on demand; subagents get a fresh, isolated context and return only a summary.
  • Sessions: every message/tool use is written to JSONL under ~/.claude/projects/; file edits are snapshotted (checkpoints) before changes; sessions can be resumed (--continue / --resume) and forked (--fork-session).
  • Safety gates: four permission modes (Manual, Accept edits, Plan, Auto) cycled with Shift+Tab, plus per-command rules in .claude/settings.json.

2.3 Gemini CLI — approval-gated loop with PTY terminal emulation

Sources: architecture docs https://google-gemini.github.io/gemini-cli/docs/architecture.html · PTY post https://developers.googleblog.com/en/say-hello-to-a-new-level-of-interactivity-in-gemini-cli/ · repo https://github.com/google-gemini/gemini-cli (→ Antigravity CLI).

  • Two packages: packages/cli (frontend: input, history, rendering) and packages/core (backend: prompt construction, tool registration/execution, conversation state management).
  • The interaction flow (per architecture doc): user input → core constructs a prompt (history + tool definitions) → Gemini API → if the API requests a tool: mutating tools (file system or shell) require explicit user approval; read-only tools may proceed without confirmation → execute → "the result is sent back to the Gemini API" → API processes the result and generates the final response → displayed by the CLI.
  • Signature difference: shell commands run inside a PTY (node-pty) with terminal-state serialization, enabling interactive commands (e.g. vim, long-running processes) that a plain subprocess bash tool cannot drive.
  • Loop topology is otherwise identical: prompt → API → tool request → execute → result back → next inference.

2.4 OpenCode — steps, subagents, and permission-gated iterations

Source: https://opencode.ai/docs/agents/ · repo https://github.com/anomalyco/opencode.

  • Loop shape: with no steps limit set, "the agent will continue to iterate until the model chooses to stop or the user interrupts the session." With steps set, the agent is forced to respond with text only when exhausted, receiving "a special system prompt instructing it to respond with a summarization of its work and recommended remaining tasks" — i.e. a harness-enforced exit condition.
  • Agent hierarchy: primary agents (Build — all tools; Plan — read-only) and subagents (General, Explore, Scout) invoked via a Task tool or @mention; subagent runs are child sessions with fresh context.
  • Hidden system agents running inside the loop: a compaction agent (compacts long context into a smaller summary automatically), a title agent, and a summary agent.
  • Permission gates: ask / allow / deny per tool, with glob patterns for fine-grained bash control (e.g. "bash": {"git push": "ask", "grep *": "allow"}) and wildcard tool matching ("mymcp_*": "deny").

2.5 The shared shape — one table

Aspect Codex CLI Claude Code Gemini CLI OpenCode
Loop name "the agent loop" "the agentic loop" core interaction flow agentic iterations / steps
Stages input → prompt → inference → tool call → execute → append → repeat gather context → take action → verify → repeat input → prompt → API → tool request → approve/execute → result back → final prompt → tool calls → execute (gated) → append → repeat
Exit condition assistant message; /responses/compact when full model stops; auto-compaction final response after tool results model stops, or steps limit forces summarization
Safety gate OS sandbox for its own shell tool; approval policy messages permission modes + checkpoints per-tool user approval for mutating tools permission ask/allow/deny + glob rules
Context mgmt auto compaction via /responses/compact, ZDR stateless auto-compaction (clear outputs → summarize) conversation state mgmt; 1M-token window hidden compaction agent
Nested loops subagents via update_plan-style orchestration dispatch_agent subagent tool (fresh context) subagents = child sessions, Task tool
Docs openai.com/index/unrolling-the-codex-agent-loop/ code.claude.com/docs/en/how-claude-code-works google-gemini.github.io/gemini-cli/docs/architecture.html opencode.ai/docs/agents/

Part 3 — The Engineering Around the Loop

The loop is identical; the engineering differs. Four problems dominate every implementation:

3.1 Context window management (the quadratic growth problem)

  • Every inference re-sends the full conversation, so prompt length grows with each tool call — "the agent could decide to make hundreds of tool calls in a single turn, potentially exhausting the context window. For this reason, context window management is one of the agent's many responsibilities" (OpenAI).
  • Compaction strategies evolve from manual to automatic: Codex went from user-invoked /compact to the automatic /responses/compact endpoint (https://openai.com/index/unrolling-the-codex-agent-loop/); Claude Code clears older tool outputs first, then summarizes, and stops auto-compacting with a "thrashing error" if a single huge output refills the window (https://code.claude.com/docs/en/how-claude-code-works); OpenCode delegates compaction to a hidden agent (https://opencode.ai/docs/agents/).
  • Isolation as an alternative to compaction: subagents with fresh context (Claude Code's dispatch_agent, OpenCode's child sessions) keep the main context lean — "their work doesn't bloat your context" (Claude Code docs).

3.2 Prompt caching (making the growing loop affordable)

  • Cache hits require exact prefix matches; "to realize caching benefits, place static content like instructions and examples at the beginning of your prompt, and put variable content at the end" (OpenAI, https://platform.openai.com/docs/guides/prompt-caching).
  • Cache-miss hazards documented by the Codex team: changing the tools list mid-conversation, changing the model, changing sandbox/approval config or cwd. The Codex team even fixed an MCP tool-enumeration ordering bug because it broke caching (https://github.com/openai/codex/pull/2611), and handles mid-conversation config changes by appending new messages instead of editing old ones.
  • Because cache hits make sampling linear instead of quadratic, caching discipline is the single biggest cost lever in the loop (ByteByteGo's analysis: "quadratic prompt growth, caching fragility" — https://blog.bytebytego.com/p/how-openai-codex-works).

3.3 Exit conditions and runaway prevention

  • Model-determined exit: assistant message without tool calls (OpenAI), model "chooses to stop" (OpenCode docs).
  • Harness-enforced exit: OpenCode's steps limit forces a text-only summarization; Claude Code stops auto-compacting after repeated refills to avoid infinite loops (thrashing error); Anthropic's loop taxonomy adds goal-based (/goal) and time-based (/loop, /schedule) loops over the basic turn-based one (https://claude.com/blog/getting-started-with-loops).
  • User interrupt: Esc/Steering input mid-turn is a first-class part of Claude Code's loop ("You're part of this loop too").

3.4 Safety gates inside the loop

The human sits inside the loop at the tool-execution stage, not after it:

  • Gemini: approval required per mutating tool call before execution (architecture doc).
  • Codex: sandbox rules and approval policies are injected as developer-role messages into the prompt — the model is told when to ask; the sandbox itself only wraps Codex's own shell tool.
  • Claude Code: permission modes gate file edits and shell commands; checkpoints make edits reversible.
  • OpenCode: permission matrix (ask/allow/deny) including glob-matched bash commands; plan agent defaults everything to ask.

Part 4 — Variants on the Pattern

  1. Workflow vs. agent (Anthropic, https://www.anthropic.com/research/building-effective-agents): workflows = predetermined code paths orchestrating LLMs; agents = LLMs choosing tools in a loop based on environmental feedback. Coding CLIs are agents.
  2. Loop + memory (Reflexion, https://arxiv.org/abs/2303.11366): the loop gains an explicit reflect-and-store step (episodic memory) — the ancestor of session persistence (Claude Code JSONL sessions, auto-memory, AGENTS.md).
  3. Plan mode as a restricted loop: Claude Code's Plan mode (read-only tools), OpenCode's Plan agent (all edits ask), and Codex's update_plan tool are the same loop with the tool surface restricted — evidence that the loop is orthogonal to the toolset.
  4. Nested loops: subagent loops with fresh context (Claude Code dispatch_agent, OpenCode Task tool child sessions) run inside the outer loop and return only summaries — a hierarchy, not a different loop.

Conclusion

The core agent loop is one pattern, universally implemented: assemble prompt → infer → parse tool calls → execute (gated) → append results → re-query → exit on assistant message. It is documented identically by OpenAI, Anthropic, and Google, descended from ReAct, and — in Simon Willison's words — "LLM + system prompt + tools in a loop… that's most of what it takes to build a coding agent" (https://simonwillison.net/guides/agentic-engineering-patterns/how-coding-agents-work/).

What differentiates coding agent CLIs is not the loop but the harness around it: context compaction, prompt-cache discipline, exit-condition enforcement, subagent isolation, and where the human permission gate sits. As Gergely Orosz concluded after interviewing the Codex team: the agent loop is "something every AI agent uses, not just Codex" (https://newsletter.pragmaticengineer.com/p/how-codex-is-built).


References (all primary/verified)

Official loop documentation - OpenAI — Unrolling the Codex agent loop: https://openai.com/index/unrolling-the-codex-agent-loop/ · Codex repo: https://github.com/openai/codex - Anthropic — How Claude Code works: https://code.claude.com/docs/en/how-claude-code-works · Building effective agents: https://www.anthropic.com/research/building-effective-agents · Getting started with loops: https://claude.com/blog/getting-started-with-loops - Google — Gemini CLI architecture: https://google-gemini.github.io/gemini-cli/docs/architecture.html · PTY interactivity: https://developers.googleblog.com/en/say-hello-to-a-new-level-of-interactivity-in-gemini-cli/ · Gemini CLI repo: https://github.com/google-gemini/gemini-cli - OpenCode — Agents docs: https://opencode.ai/docs/agents/ · repo: https://github.com/anomalyco/opencode - OpenAI — A Practical Guide to Building Agents (the loop is "central"): https://cdn.openai.com/business-guides-and-resources/a-practical-guide-to-building-agents.pdf

Academic ancestors - ReAct: https://arxiv.org/abs/2210.03629 · Reflexion: https://arxiv.org/abs/2303.11366

Analyses - Simon Willison — How coding agents work: https://simonwillison.net/guides/agentic-engineering-patterns/how-coding-agents-work/ · Designing agentic loops: https://simonwillison.net/2025/Sep/30/designing-agentic-loops/ - Gergely Orosz (Pragmatic Engineer) — How Codex is built: https://newsletter.pragmaticengineer.com/p/how-codex-is-built - ByteByteGo — How OpenAI Codex works: https://blog.bytebytego.com/p/how-openai-codex-works - OpenAI prompt caching docs: https://platform.openai.com/docs/guides/prompt-caching