All posts
Fundamentals

Why give an agent a computer

Every tool we have built is a function you wrote in advance. The agent can search, read a file, run a query, because you anticipated those needs and coded them.

Code execution is a different idea: instead of a menu of functions, give the agent a Python interpreter and let it write the code it needs. That one change removes three limits at once.

Limit one: the action space is only what you built

A predefined-tool agent can do exactly the things you thought of, and nothing else. Give it read_file and write_file, and the moment a task needs the two combined in a way you did not anticipate, "read these ten files and keep only the lines mentioning errors", the agent is stuck. The capability was never registered.

You cannot anticipate everything. Users ask for things you did not imagine, and new situations arrive constantly. A fixed tool menu is a fixed ceiling on what the agent can attempt.

Code has no such ceiling. If the task can be expressed as a program, the agent can write that program, and the action space becomes everything the language can do.

Limit two: multi-step data work is slow and expensive

Watch a predefined-tool agent analyse ten files. It reads file one, the contents land in the context, it reads file two, more context, and on through all ten, then it analyses. That is eleven tool calls, eleven round trips, and ten file contents now sitting in the window costing tokens on every later call.

Action: read_file("file_1.txt")   Observation: <contents>
Action: read_file("file_2.txt")   Observation: <contents>
... eight more times ...
Action: analyze(...)              Observation: <result>

The same task in code is one execution.

# one code execution, not eleven tool calls
results = []
for path in glob.glob("*.txt"):
    text = open(path).read()
    results.append(count_errors(text))
print(summarise(results))          # only the summary comes back to the model

One round trip does the whole job, and only the summary returns to the context. The ten files never enter the window. On data-heavy work the difference is not marginal; it is the difference between an agent that scales and one that chokes on its own tool results.

Ten tool calls with ten file contents in context, versus one code execution that returns a summary.Ten tool calls with ten file contents in context, versus one code execution that returns a summary.

Limit three: more tools make the agent worse

The obvious fix for a limited action space is to register more tools. That has its own cost, and it compounds.

Every tool's definition sits in the prompt. A hundred tools is a hundred definitions the model reads on every call, which lengthens the prompt, raises the cost, and, worst of all, degrades the model's choices. A model picking from a hundred near-neighbours makes more mistakes than one picking from ten. Piling on tools to widen the action space narrows the model's accuracy.

Code sidesteps the trade entirely. A handful of core tools, one of them "run this Python", gives a wider action space than a hundred registered functions, with a shorter prompt.

What code brings that a tool cannot

Beyond efficiency, code has expressive power a list of tool calls cannot match.

Control flow. A program can branch, loop and decide. "Add the highly-rated products to the cart, but stop when the total passes the budget" is a few lines of code with an if and a running sum. As a sequence of tool calls it is clumsy; as code it is natural.

Composition. Code chains operations: read, filter, transform, aggregate, all in one execution, passing intermediate values that never touch the model's context.

The full library ecosystem. The moment the agent can run Python, it can use pandas to read a spreadsheet, a PDF library to merge documents, the standard library to do a hundred things you never registered as tools.

Predefined toolsCode execution
Action spaceWhat you built in advanceAnything a program can do
Ten-file analysisEleven calls, ten files in contextOne execution, a summary back
Widening capabilityRegister more tools, degrade choicesWrite different code, no new tools
Control flow and compositionAwkward across tool callsNative

A few core tools plus code beats a hundred registered functions, on capability and on cost.A few core tools plus code beats a hundred registered functions, on capability and on cost.

The catch, named up front

Code execution is the most powerful capability in this book, and the most dangerous. Letting a model write and run code means running code you did not write, generated by something that takes direction from untrusted input. That is a real risk, and it argues for running the code somewhere it cannot hurt you, a sandbox, rather than for avoiding code execution. The sandbox is the whole of the next post.

What to take from this

  • Predefined tools bound the agent to what you anticipated. Code execution makes the action space everything a program can do.
  • On multi-step data work, code is one execution that returns a summary, instead of many tool calls that flood the context. It scales where a tool menu chokes.
  • Adding tools to widen capability degrades the model's choices; a few core tools plus code widen it without that cost. The power comes with a risk the next post handles: a sandbox.

The gain is real and so is the danger. The next post is where code execution earns its keep safely, by running in an isolated environment the agent cannot escape.