Unrolling the Codex agent loop

By Michael Bolin, Member of the Technical Staff

Michael Bolin
17 min readintermediate
--
View Original

Overview

This article explains the core agent loop architecture behind OpenAI's Codex CLI, detailing how it orchestrates interactions between users, LLM models, and tools to perform software engineering tasks. It covers prompt construction, the Responses API integration, tool calling mechanics, context window management, prompt caching optimization, and conversation compaction strategies.

What You'll Learn

1

How an AI agent loop orchestrates user input, model inference, and tool calls to perform software tasks

2

How to structure prompts for the OpenAI Responses API with instructions, tools, and input fields

3

Why prompt caching requires exact prefix matching and how to preserve cache hits across conversation turns

4

How context window compaction works to prevent token exhaustion in long agent conversations

5

How Codex CLI supports multiple Responses API endpoints including local, cloud, and custom providers

Prerequisites & Requirements

  • Basic understanding of LLMs, tokens, and how language models generate text
  • Familiarity with REST APIs and JSON payloads
  • Understanding of HTTP request/response patterns and Server-Sent Events (SSE)(optional)
  • Familiarity with OpenAI's Responses API or similar LLM APIs(optional)
  • Experience building or using AI-powered developer tools or coding agents(optional)

Key Questions Answered

What is an agent loop and how does it work in AI coding assistants?
An agent loop is the core logic that orchestrates interaction between the user, the model, and tools. It takes user input, sends it as a prompt to the model for inference, and the model either produces a final response or requests a tool call. If a tool call is requested, the agent executes it, appends the output to the prompt, and re-queries the model. This cycle repeats until the model produces an assistant message, signaling the turn is complete.
How does Codex CLI build the initial prompt for the Responses API?
Codex constructs the prompt using three main Responses API parameters: instructions (model-specific or custom instructions from config), tools (shell tool, plan tool, web search, and MCP server tools), and input (a list containing developer permissions messages, optional developer instructions from config.toml, aggregated user instructions from AGENTS.md files and skills, environment context with cwd and shell, and finally the user's message).
What are the message roles in the OpenAI Responses API prompt and their priority?
The Responses API uses four roles in decreasing order of priority: system (highest weight, controlled by the server), developer (instructions from the API caller), user (end-user input and context), and assistant (model-generated responses). The system message content is controlled by the server, while tools and instructions content are determined by the client. This hierarchy determines how much weight the model gives to each piece of content.
How does prompt caching work in the Codex agent loop?
Prompt caching enables reuse of computation from previous inference calls by matching exact prefixes. Codex ensures each new prompt is an exact prefix extension of the previous one, so only the new tokens need processing. This makes sampling linear rather than quadratic. Cache misses occur when tools change order, the model changes, or sandbox configuration is modified mid-conversation. Codex appends new messages rather than modifying earlier ones to preserve prefix matching.
How does Codex handle context window exhaustion in long conversations?
Codex uses conversation compaction to prevent context window exhaustion. When token usage exceeds the auto_compact_limit threshold, it calls the Responses API's /responses/compact endpoint, which returns a smaller list of items including a special type=compaction item with encrypted_content that preserves the model's understanding of the conversation. This replaces the previous input, freeing up context window space while maintaining conversation continuity.
What tools does Codex CLI provide to the model by default?
Codex provides several tool types: a default shell tool for spawning local processes (with command, workdir, and timeout parameters), a built-in update_plan tool for task planning, the web_search tool provided by the Responses API, and any user-configured MCP server tools defined in ~/.codex/config.toml. Only the shell tool is sandboxed by Codex; MCP tools are responsible for their own guardrails.
How does Codex CLI support Zero Data Retention (ZDR) customers?
Codex keeps all API requests fully stateless by not using the previous_response_id parameter, which would require server-side data storage incompatible with ZDR. Reasoning from prior turns is preserved through encrypted_content fields that can be decrypted server-side using a persisted decryption key, while the actual conversation data is never stored. This was implemented in PRs #642 and #1641.
What causes prompt cache misses in an AI agent loop?
Cache misses in Codex occur when: the available tools change mid-conversation (including MCP servers sending tools/list_changed notifications), the target model changes (which alters model-specific instructions), or sandbox configuration/approval mode/working directory changes modify earlier prompt items. Codex mitigates directory and config changes by appending new messages rather than modifying existing ones, preserving the prefix match needed for caching.

Key Statistics & Figures

Default user instructions size limit
32 KiB
Maximum size for aggregated user instructions from AGENTS.md files collected from project root to current working directory

Technologies & Tools

Some links below are affiliate links. We may earn a commission if you make a purchase.

AI Agent / Developer Tool
Openai Codex CLI
Cross-platform local software agent for producing reliable software changes
API
Openai Responses API
HTTP endpoint for model inference that structures instructions, tools, and input into prompts
Programming Language
Rust
Implementation language for the Codex CLI core (codex-rs)
Protocol
Server-sent Events (sse)
Streaming protocol used by the Responses API to return model inference results incrementally
Protocol
Mcp (model Context Protocol)
Protocol for user-configured tool servers that extend agent capabilities
Local Inference
Ollama
Local model serving compatible with Codex CLI via --oss flag (version 0.13.4+)
Local Inference
Lm Studio
Local model serving compatible with Codex CLI via --oss flag (version 0.3.39+)
API Specification
Openresponses
Open specification for Responses API compatibility that enables custom endpoints
Data Format
JSON
Payload format for Responses API requests and SSE event data
Cloud Provider
Azure
Mentioned as a cloud provider option for hosting the Responses API

Key Actionable Insights

1
Structure your prompts with static content first and variable content last to maximize prompt cache hits. Place instructions, tool definitions, and system messages at the beginning, and put user-specific or changing content at the end. This ensures exact prefix matching works for caching.
The article demonstrates that prompt caching transforms quadratic sampling costs into linear costs. Codex specifically designs its prompt ordering (system → tools → instructions → developer messages → user context → user message) to maximize cache reuse across inference calls.
2
When building an agent loop, ensure new prompts are exact prefix extensions of previous prompts rather than modified versions. Append tool call results and new messages to the end of the input array rather than inserting or modifying items in the middle of the conversation history.
Codex explicitly maintains this prefix property across all conversation turns. When configuration changes occur mid-conversation (like working directory changes), Codex appends new messages with updated information rather than modifying the original messages, specifically to preserve cache hits.
3
Implement automatic conversation compaction to prevent context window exhaustion in long-running agent sessions. Set a token threshold that triggers compaction before hitting the hard context limit, and use the compacted representation as a drop-in replacement for the full conversation history.
Codex evolved from manual /compact commands to automatic compaction using the /responses/compact endpoint when the auto_compact_limit is exceeded. The compacted output includes encrypted_content that preserves the model's latent understanding of the original conversation.
4
Keep your Responses API requests fully stateless by including the complete conversation history in each request rather than relying on server-side state via previous_response_id. This simplifies the architecture, improves reliability, and supports Zero Data Retention configurations.
While this approach means quadratic JSON payload growth, prompt caching makes the actual model sampling cost linear. The trade-off favors statelessness because network traffic cost is dominated by sampling cost, and stateless requests are simpler to debug and operate.
5
When integrating MCP tools into an agent loop, enumerate tools in a consistent order across requests and be cautious about honoring tools/list_changed notifications mid-conversation, as they will cause expensive prompt cache misses.
Codex encountered a bug where MCP tools were listed in inconsistent order, causing cache misses. MCP servers can dynamically change their tool list, and honoring these changes mid-conversation invalidates the entire prompt cache for that session.
6
Design your agent's tool definitions to be modular, separating built-in tools, API-provided tools, and user-configured tools. Only sandbox the tools you control directly; external tools like MCP servers should enforce their own security guardrails.
Codex's sandboxing applies only to its built-in shell tool, not to MCP server tools. This separation of concerns allows flexibility while maintaining security for the tools the agent directly controls.

Common Pitfalls

1
Failing to maintain consistent tool ordering across Responses API requests causes prompt cache misses, which dramatically increases inference costs. This is especially problematic with MCP tools, where servers can enumerate tools in different orders across requests.
Codex encountered this exact bug in their initial MCP support. The fix required ensuring deterministic tool ordering in every request to maintain the exact prefix matching that prompt caching requires.
2
Modifying earlier messages in the conversation input array (such as updating sandbox configuration or working directory) instead of appending new messages breaks prompt cache prefix matching and causes expensive re-computation of the entire prompt.
Codex handles mid-conversation configuration changes by appending new developer or user messages with updated information, preserving the original messages intact so the prefix match is maintained.
3
Honoring MCP tools/list_changed notifications mid-conversation changes the tools parameter, which is part of the prompt prefix. This invalidates the entire prompt cache for that conversation, causing a significant performance regression in long sessions.
The tools list is positioned early in the prompt structure, so any change to it cascades as a cache miss for everything that follows. Agents should carefully weigh whether to honor dynamic tool changes mid-conversation or defer them.
4
Not implementing automatic conversation compaction can lead to context window exhaustion during long agent sessions with many tool calls, causing the agent to fail mid-task when it runs out of token space for both input and output.
The context window includes both input and output tokens, and an agent making hundreds of tool calls in a single turn can easily exhaust it. Codex implements an auto_compact_limit threshold that triggers compaction before hitting the hard limit.

Related Concepts

Llm Prompt Engineering
Token-based Context Windows
Prompt Caching And Prefix Matching
Server-sent Events (sse) Streaming
Tool Use And Function Calling In Llms
Model Context Protocol (mcp)
Zero Data Retention (zdr)
Conversation State Management
Sandboxed Code Execution
Agent Orchestration Patterns
Openai Responses API
Reasoning Models And Chain-of-thought
Stateless API Design