ConceptAgents & Tool Use
CodeAct
At a glance
Agents that act by writing executable code instead of emitting one JSON tool call at a time.
- Who this is for
- Engineers and technical readers learning the terms used in AI systems.
- Topics
- Agents & Tool Use
- Concept
CodeAct, named by Xingyao Wang and colleagues in a 2024 ICML paper, flips the standard agent contract. Instead of the model emitting one structured tool call per turn and waiting for the result, the model writes a block of executable code, usually Python, and the runtime executes the whole block as a single action. The agent still loops, observes, and corrects like any ReAct-style agent; what changes is the unit of action. One generated program can call five tools, branch on intermediate results, retry failures, and return only the final answer, where a JSON-calling agent would need five model round trips to do the same work.
Code as the action space#
A conventional tool-calling agent has a fixed menu: the tools you defined, called one at a time, with arguments shaped by a JSON schema. CodeAct replaces that menu with a programming language. Tools become functions the generated code can call, but the model also gets everything the language gives away for free: variables to hold intermediate results, loops to repeat work, conditionals to branch, libraries like pandas to crunch data that never needs to enter the model's context.
The original paper tested this across 17 LLMs and found code actions outperformed JSON and text action formats by up to 20% in success rate on tool-composition benchmarks. The intuition behind the number is simple: models have seen billions of lines of real Python in training and comparatively little of your bespoke JSON dialect, and real code naturally expresses "do A, feed it to B, then C" in one breath. The team turned the idea into CodeActAgent, the lineage that became OpenHands (formerly OpenDevin), one of the most-used open coding agents.
Why one code block beats many round trips#
Count the costs of a chained task under each contract. Say the job is "compute Q3 net revenue and file a report": fetch orders, fetch refunds, subtract, write the report. With JSON tool calls that is three or four model round trips, each one a full inference pass costing seconds of latency, and every raw result, potentially thousands of rows, gets pasted into the context so the model can decide the next step. With CodeAct the model writes one script: two fetches into variables, a subtraction, one report call. One inference pass, and the row data never touches the context.
Three things come free once the action is a program. Composition: chaining tools is just passing variables, no extra turns. Loops: "check budget compliance for 20 employees" is a for loop in one action, not 20 round trips; Anthropic's docs use exactly this example for programmatic tool calling. Error handling: the code can catch an exception, retry with backoff, or fall back to a second data source without waking the model. The interpreter's traceback is also a far richer observation than "tool returned error," which is why the CodeAct paper found agents self-debug effectively from stack traces.
The context savings are the headline in production. Anthropic's "code execution with MCP" post works one Salesforce-plus-transcript example from 150,000 tokens of tool definitions and intermediate results down to about 2,000 tokens, a 98.7% reduction, by letting the agent import MCP servers as code APIs and keep intermediate data in the execution environment. Their measured benchmark numbers for programmatic tool calling are more modest and more honest: about 11% accuracy improvement on agentic search suites with 24% fewer input tokens.
The sandbox is a hard requirement#
A JSON tool call can only do what the tool allows. Generated code can do anything the interpreter can, which is the entire point and the entire risk. An agent that writes rm -rf or exfiltrates an environment variable is not a hypothetical; it is the default failure mode of running model-generated code with real permissions, and prompt injection means an attacker can author that code through your agent.
So sandboxed execution is not a hardening step you add later, it is part of the pattern's definition. The standard stack in 2026: an isolated container or microVM per session (Docker, gVisor, Firecracker), no credentials inside beyond scoped tokens for the tools you intend to expose, an egress allowlist so code can reach your APIs and nothing else, and CPU, memory, and wall-clock limits so a runaway loop dies quietly. Hosted offerings like Anthropic's code execution tool, E2B, and Modal exist mostly so teams do not have to rebuild this isolation themselves. If you cannot articulate where the generated code runs and what it can reach, you are not ready to ship a CodeAct agent.
Where it shows up today#
The lineage runs from research to default practice in about two years. Open Interpreter (2023, roughly 64k GitHub stars) put the "LLM writes code, your machine runs it" loop on developer laptops before the pattern had a name. The CodeAct paper (February 2024) formalized it and seeded OpenHands. Manus, the agent product that went viral in March 2025, is built on CodeAct: its executor writes Python in an isolated Linux sandbox rather than emitting tool calls, and it popularized the architecture for general-purpose autonomous agents.
Providers then absorbed it. Anthropic ships a server-side code execution tool with container reuse and, since the 2026 version, programmatic tool calling, where your declared tools become functions the sandboxed code can call directly. OpenAI's code interpreter and Google's Gemini code execution cover the same ground. The November 2025 "code execution with MCP" post pushed the idea furthest: present entire MCP servers as importable code modules so the agent discovers tools by reading the filesystem instead of holding every definition in context. Smolagents from Hugging Face made code actions its default agent type. The pattern stopped being exotic; it is now a checkbox in the API.
When JSON calls are still the right answer#
CodeAct is not a strict upgrade. For a single tool call per turn, code adds tokens and an interpreter hop for zero benefit. JSON calls are easier to validate (schemas, allowlists), easier to audit (one typed action per log line), and safer by construction since there is no interpreter to escape. Strict approval workflows, like "human reviews every write action," map cleanly onto discrete tool calls and awkwardly onto a 40-line script that mixes reads and writes. And plan-and-execute systems that want a reviewable step list before anything runs often prefer discrete actions for exactly that legibility.
The crossover point is chaining. One or two independent calls per turn: stay with JSON. Pipelines, fan-outs over lists, or large intermediate results that the model only needs in aggregate: code actions win on cost, latency, and reliability at once.
Practical takeaways#
Treat the action space as a design decision, not a default. Reach for CodeAct when tasks chain tools, loop over collections, or move data the model should summarize rather than read. Budget the sandbox first; isolation, scoped credentials, and egress control are the price of admission. Keep discrete tool calls for single actions and approval-gated writes. And if you are on a frontier API, try the provider's native version (code execution plus programmatic tool calling) before building your own interpreter loop, because the vendors have already paid the isolation tax for you.