CodeAct: Collapsing Tool Calls to Cut Agent Latency
The primary bottleneck in production AI agent systems is not just model inference time. It is the round-trip latency inherent in the tool-calling loop. In a traditional architecture, an agent performing a multi-step task—such as fetching data from an API, transforming it, and then updating a database—must cycle through the LLM multiple times.
Each cycle involves the model emitting a JSON tool call, the orchestrator parsing that JSON, executing the function, returning the result as a string, and the model processing that new context to decide the next move. When a task requires five or six sequential tool calls, the wall-clock time becomes unacceptable for interactive applications.
The CodeAct agent framework offers a different path. By allowing agents to emit executable code rather than discrete tool calls, we can collapse these multiple round-trips into a single execution block. In our benchmarks at AEGIS, this approach consistently cuts latency by 50% or more for complex data-heavy tasks.
The Traditional Tool-Call Tax
To understand the efficiency of CodeAct, we must first look at the overhead of the standard ReAct (Reasoning and Acting) pattern. In a typical tool-calling scenario, the sequence looks like this:
- ·LLM Inference: The model decides to use
get_user_data. - ·Serialization: The model generates a JSON object:
{"tool": "get_user_data", "args": {"id": 123}}. - ·Parsing & Execution: The orchestrator validates the JSON and calls the Python function.
- ·Observation: The function returns a 2KB JSON blob of user data.
- ·Context Injection: The orchestrator appends this result to the prompt.
- ·LLM Inference (Again): The model reads the data and decides to call
calculate_risk_score.
This loop repeats for every single action. The latency accumulates at every step: the token generation for the JSON, the network overhead of multiple API calls to the LLM provider, and the repeated processing of an ever-growing context window. If the model needs to perform a loop—for example, processing ten items in a list—it might require twenty round-trips.
How CodeAct Collapses the Loop
CodeAct (Code Action) treats the agent's action space as a programming environment rather than a menu of predefined functions. Instead of emitting a specific tool name, the agent emits a block of Python code.
The orchestrator takes this code and runs it inside a secure sandbox. The agent has access to a set of pre-installed libraries or even the ability to install new ones. The output of the code—everything sent to stdout and stderr—is captured and returned to the agent as a single observation.
Consider the user data example again. In a CodeAct framework, the agent emits a single block:
import internal_api
user = internal_api.get_user_data(id=123)
risk = calculate_risk_score(user['history'])
internal_api.update_record(id=123, score=risk)
print(f"Updated risk score for user 123 to {risk}")
The orchestrator executes this entire block in one go. The model only needs to perform one inference step to generate the logic, and the orchestrator only makes one round-trip to the LLM. The "latency tax" of serialization and context re-processing is paid once instead of three times.
The Latency Math
The performance gains from CodeAct are non-linear. For a single tool call, CodeAct is actually slightly slower due to the overhead of spinning up a code execution environment. However, as the number of required steps (N) increases, the benefits scale.
If L_inf is the average inference latency and L_exec is the execution time of a tool, a traditional agent's total time is roughly N × (L_inf + L_exec).
With CodeAct, the model generates the entire logic in one inference pass. The total time becomes L_inf(long) + L_exec(total). Since L_inf(long) is significantly less than N × L_inf, especially when using fast streaming models, the time savings are massive. In multi-step data transformations, we have observed wall-clock time dropping from 12 seconds to under 5 seconds.
Sandboxing: The Production Requirement
Allowing an LLM to execute arbitrary Python code is a significant security risk. You cannot run CodeAct on a bare metal server or a shared container without strict isolation. Production-grade CodeAct requires a specialized sandboxing layer.
There are three primary ways to implement this safely:
- ·Micro-VMs (Firecracker): This is the gold standard for isolation. Each agent gets its own lightweight virtual machine that boots in milliseconds. If the agent writes malicious code or attempts a fork bomb, it only crashes its own isolated environment.
- ·Managed Sandboxes (E2B or Modal): Services like E2B provide "Code Interpreter as a Service." They handle the lifecycle of the sandbox, providing a secure environment where the agent can run code, save files, and interact with a filesystem.
- ·Wasm (WebAssembly): For certain languages, running code in a Wasm runtime provides a high degree of isolation with almost zero startup overhead, though it limits the libraries available to the agent.
At AEGIS, we lean toward micro-VM isolation. The ability to give an agent a full Linux environment—where it can run pip install, manipulate local files, and execute complex logic—is what makes CodeAct powerful.
Tradeoffs and Challenges
CodeAct is not a silver bullet. It introduces new complexities that must be managed.
Auditability: In a traditional tool-calling system, every action is a discrete event in your logs. You can see exactly when update_record was called and with what arguments. In CodeAct, that call happens inside a code block. You must implement deep instrumentation within the sandbox to capture these internal calls if you require a granular audit trail.
Error Recovery: If a traditional tool call fails, the model receives a specific error message for that one tool and can retry. If a CodeAct block fails on line 4 of 10, the agent must decide whether to rewrite the whole block, try to fix just the failing part, or roll back the previous three lines of logic. This requires a more sophisticated model capable of debugging its own code.
Model Capability: CodeAct requires a model that is highly proficient in Python. While GPT-4o and Claude 3.5 Sonnet excel at this, smaller or older models often struggle with syntax errors or hallucinated library functions, leading to a high failure rate that negates the latency gains.
When to Use CodeAct vs. Traditional Tools
We recommend a hybrid approach based on the nature of the task.
Use Traditional Tool Calls when:
- ·The operation is deterministic and single-step (e.g., "Post this message to Slack").
- ·You need strict schema validation for every argument.
- ·You are using a smaller, less capable model.
- ·The task requires human-in-the-loop approval for every individual action.
Use CodeAct when:
- ·The task involves complex data manipulation (e.g., "Fetch this CSV, calculate the average of column B, and graph it").
- ·The agent needs to perform loops or conditional logic.
- ·Latency is the primary constraint for a multi-step workflow.
- ·The agent needs to use libraries that don't exist as standalone tools.
The AEGIS OS Approach
AEGIS OS does not force a choice between these two architectures. We use a hybrid execution engine. For high-stakes, deterministic operations like infrastructure changes or financial transactions, our agents use structured tool calls with strict schema enforcement and mandatory approval gates.
However, for the "connective tissue" of a project—data transformation, log analysis, and multi-step research—we deploy CodeAct-style execution. By collapsing these internal reasoning steps into code, we ensure that our fleet remains responsive even as the complexity of the tasks grows.
The goal of an autonomous system is to minimize the time between a human's intent and the system's result. Collapsing the tool-call loop is one of the most effective ways to close that gap.
To see how AEGIS OS orchestrates these agentic workflows in production, visit aegisos.cc.