Let the model write the workflow.
CodeAct is a way for an AI agent to take action by writing a short program. That program calls only the tools you approve, combines their results with ordinary code, and returns an answer through the ADK-Rust runtime.
cart = call_tool("fetch_cart", args) subtotal = sum(item["price"] * item["qty"] for item in cart["items"]) rate = call_tool("tax_rate", region) total = subtotal * (1 + rate)
Start here
What is a CodeAct agent?
A CodeAct agent is an AI agent that writes executable code to decide how several approved tools should work together. Your application runs that code in a controlled interpreter and remains responsible for every external action.
Traditional tool calling
The model chooses one action at a time.
- 01Ask the model which tool to call.
- 02Run that tool and send its result back to the model.
- 03Ask the model what to do next, then repeat.
CodeAct
The model writes the complete procedure.
- 01Ask the model for a short program using the available tools.
- 02Run the program and pause only when it reaches a real tool.
- 03Resume with the tool result until the program returns its answer.
A simple analogy
Traditional tool calling is like asking a colleague to press one calculator button, report the screen, and wait for the next instruction. CodeAct is like giving that colleague permission to write a small spreadsheet formula: the allowed inputs stay the same, but the calculation can contain variables, conditions, loops, and several steps.
Eight words you will see on this page
Model
The LLM that writes the script.
Agent
The component that turns a goal into actions and results.
Tool
An approved Rust function that reaches business data or systems.
Script
The short program written for the current agent turn.
Runtime
The interpreter that executes and pauses the script.
Observation
A result or error returned to the model for another turn.
Checkpoint
A saved paused program that can continue later.
Final result
The typed answer returned to your application.
Where the idea came from
CodeAct began as a research question about an agent's action language.
Most early tool-using agents represented an action as natural language or a JSON object containing a tool name and arguments. Researchers Xingyao Wang, Yangyi Chen, Lifan Yuan, Yizhe Zhang, Yunzhu Li, Hao Peng, and Heng Ji asked whether executable Python would be a more expressive action format.
Their paper, “Executable Code Actions Elicit Better LLM Agents”, was released in February 2024 and appeared at ICML 2024. It evaluated 17 language models on API-Bank and the paper's M³ToolEval benchmark. The authors reported that code actions achieved success rates up to 20% higher than the text and JSON action formats tested.
The paper also introduced CodeActInstruct, a dataset of 7,000 multi-turn interactions, and CodeActAgent models fine-tuned to execute code, observe results, revise failed programs, and continue the conversation. These are research results on the paper's tasks; they do not mean code actions are automatically better for every product.
Why would I use CodeAct?
CodeAct
CodeAct is compelling when the agent must combine tools with computation. It gives the model a familiar language for expressing logic while your application retains the tool and runtime boundaries.
Compose several tools
A script can call several approved tools and pass one result directly into the next step.
Use real control flow
Loops, conditions, variables, sorting, filtering, and arithmetic are expressed directly in code.
Reduce model round trips
Work that would require several tool-selection turns can sometimes be expressed in one generated script.
Keep intermediate data local
The runtime can filter or aggregate large tool results before deciding what belongs in the model transcript.
Correct executable mistakes
A syntax error, exception, or failed assertion can become an observation the model uses to revise the next script.
Inspect the action
Developers can read the generated program, tool calls, outputs, and checkpoints as an execution trail.
Trade-offs
When should I avoid it?
One simple action
A normal LlmAgent tool call is easier when the request maps cleanly to one business operation.
Weak code generation
A model that struggles to write valid code may need more correction turns than structured tool calling.
No safe runtime
Generated code needs an interpreter with explicit access and resource limits. Never pass it to unrestricted eval or exec.
Full software development
Use CodingAgent when the goal is editing repositories, running shell commands, or operating a development workspace.
Implementations in the ecosystem
The CodeAct concept now appears in several agent systems.
They share the idea of code as an action format, but differ in language support, tool exposure, sandboxing, state, and intended workload.
CodeAct
Original research
Python actions, CodeActInstruct, fine-tuned research models, and a containerized execution engine.
Learn more ↗OpenHands
Software agents
Its CodeActAgent can converse, execute Python, and run shell commands for software-development work.
Learn more ↗smolagents
Hugging Face
CodeAgent uses Python actions with loops and conditions and supports several sandbox executors.
Learn more ↗Pydantic AI
Code Mode
Wraps an agent's tools in a code interface and uses Monty as a controlled Python runtime.
Learn more ↗ADK-Rust
Rust-native runtime
Adds the CodeAct loop to typed agents, tools, sessions, events, approvals, callbacks, and transfers.
Learn more ↗How ADK-Rust implements CodeAct
CodeAct works inside the ADK-Rust runtime.
CodeActAgent is an agent type alongside LlmAgent. You give it a model, a CodeRuntime, and Rust tools. You then run it through the same Runner, session, event, callback, authorization, and output systems used by other ADK-Rust agents.
1. Model
Choose any ADK-Rust model provider capable of producing reliable code.
2. CodeRuntime
Use the Monty-backed Python runtime or implement the language-agnostic CodeRuntime trait.
3. Rust tools
Register typed tools. The script can reach only the tools supplied for that invocation.
4. Runner
Run the agent with a user and session, then consume normal typed ADK-Rust events.
5. Session
Persist checkpoints when approval or a long-running tool pauses the program.
6. Controls
Apply confirmation, retries, timeouts, callbacks, guardrails, and validated outputs.
Fastest working start
Run the checked-in example first.
It uses a deterministic model, a real Monty Python interpreter, two Rust tools, an in-memory session, and the ADK-Rust Runner. No model API key is required.
The Monty adapter is currently an experimental Git dependency and requires Rust 1.95+, so the example carries its own toolchain file.
git clone https://github.com/zavora-ai/adk-rust.git
cd adk-rust/examples/codeact_monty_agent
# This example selects Rust 1.95 automatically.
cargo run=== ADK-Rust CodeAct × Monty (Python) example ===
[cart_assistant]
{
"lines": 3,
"region": "CA",
"subtotal": 132.0,
"tax_rate": 0.0725,
"total": 141.57,
"user": "u-42"
}
Done.Architecture
The script runs inside the agent system.
The model proposes executable logic. The CodeRuntime controls how that logic advances. ADK-Rust owns every external action, durable checkpoint, and event that the application sees.
Model
Writes a script using the runtime briefing and the tools available for this invocation.
CodeRuntime
Runs the script step by step and exposes calls, completion, stdout, and script errors.
ADK-Rust host
Executes tools with authorization and context, persists state, and streams the final result.
Source-backed execution walkthrough
Case study: price a shopping cart in one CodeAct turn.
This follows the deterministic CodeAct × Monty example in the ADK-Rust repository. Select each boundary to see which part of the system is working and what becomes visible to the next part.
Runner
The request enters ADK-Rust
The Runner attaches the user, session, invocation context, callbacks, and available tools before the CodeAct agent begins.
Visible signal
What's the total for cart u-42, including CA tax?
Choose the right agent shape
CodeAct has a specific job.
Use it when a model can express the work more clearly as a program. ADK-Rust also provides agent shapes for conversational tool use and full software-development environments.
LlmAgent
Choose and call tools conversationally.
Best for: Questions, dialogue, isolated business actions, and natural handoffs.
model → tool → model
CodeActAgent
Compose tools and logic in one executable plan.
Best for: Analysis, data transformation, batch work, calculations, and conditional flows.
model → script ↔ tools → result
CodingAgent
Work inside a software-development harness.
Best for: Repository editing, shell commands, builds, tests, patches, and coding-agent protocols.
agent ↔ workspace + shell
Monty runtime
Give generated code a clear operating boundary.
ADK-Rust's current Python adapter runs Monty in-process. The host decides what the script can read, write, know, and consume before execution begins.
Monty is still experimental. It is currently a pinned Git dependency and requires Rust 1.95+. The adapter lives in its own crate until Monty is available on crates.io.
Default sandbox
No filesystem access and an empty environment. Network and subprocess operations have no Monty surface.
Explicit mounts
Map selected host directories to virtual paths and choose read-only or read-write access for each one.
Resource limits
Set a time cap and memory cap for every advance. Serialized continuations retain those limits when resumed.
One tool form
Scripts call call_tool(name, args). Exact named arguments survive serialization and bind centrally in ADK-Rust.
Controlled environment
Expose only the environment values the task needs. Host process secrets are never inherited automatically.
Visible failures
Syntax errors and exceptions return to the model as fixable script feedback; host runtime failures stop the run.
Durable execution
A paused program can become durable agent state.
Confirmation-gated and long-running tools may need the request to end before the answer exists. CodeAct snapshots the paused interpreter, its transcript, and pending call into the session so another invocation can continue from the same line of code.
Save before
Persist the continuation before an external tool is allowed to run.
Resolve
Execute, approve, reject, or wait for the pending tool result.
Save after
Persist the returned value so recovery does not repeat a completed call.
Resume
Load the checkpoint and continue the same script from its call boundary.
Developer responsibility: a crash after an external side effect but before the save-after checkpoint may cause that tool to run again. Give non-idempotent tools an idempotency key or another duplicate-action guard.
Implementation
Four pieces define the complete agent.
Choose a model, supply a CodeRuntime, register the tools the script may call, and run the agent through the normal ADK-Rust Runner.
use std::sync::Arc;
use adk_agent::codeact::CodeActAgent;
use adk_codeact_monty::MontyRuntime;
let runtime = MontyRuntime::builder()
.environ_var("CART_USER", "u-42")
.environ_var("TAX_REGION", "CA")
.system_clock(true)
.build();
let agent = CodeActAgent::builder()
.name("cart_assistant")
.model(model)
.runtime(Arc::new(runtime))
.instruction("Price the cart by writing Python.")
.tool(Arc::new(fetch_cart))
.tool(Arc::new(tax_rate))
.output_key("priced_cart")
.build()?;Build with CodeAct
Turn a multi-step tool conversation into one readable program.
Start with the deterministic example, inspect every pause and resume, then connect the model and tools your product already uses.