groundy
agents & frameworks

Code-as-Action Agents Beat GAIA But Require Runtime Sandboxing

Hugging Face's code agent leads GAIA by treating code as the action space. This generalizes reasoning but shifts safety from prompt filtering to runtime containment, where.

11 min···4 sources ↓

Code-as-action agents are climbing general-assistant leaderboards like GAIA, and a June 2026 red-team found they execute embedded unsafe operations 73.61% of the time.3 An agent whose action space is executable code generalizes to browsing, file handling, and multi-step reasoning better than the hand-wired tool graphs most production agents still ship. The price is a containment problem most teams have not solved.

Why does code-as-action generalize beyond coding?

Code-as-action generalizes because a programming language is a universal interface: parsing a file, calling an API, looping over results, branching on intermediate state, and checking the output of step three before attempting step four can all be expressed in one medium, and it happens to be the medium LLMs are trained on most heavily.

GAIA was designed to test exactly this kind of generality. Its tasks reward assistants that can browse the web, manipulate files, and chain reasoning across modalities, the sort of thing a competent human finds easy and a tool-calling agent finds brittle. The intuition behind most agent frameworks was that you close that gap by wiring up tools: a browser tool, a file tool, a calculator tool, each with a JSON schema the model fills in. The code-agent bet is different. Give the model a Python interpreter and let it write the browser calls, the file parsing, and the glue logic itself. Every capability the designer did not anticipate is still reachable, because the model composes it from primitives rather than selecting it from a menu.

The strongest recent evidence that this is a general phenomenon rather than a coding-benchmark artifact comes from outside software engineering entirely. KG2Code1 formulates knowledge-graph question answering as a code generation task, producing what the authors describe as verifiable reasoning traces and executable code. Knowledge-graph QA is about as far from “write a function” as reasoning tasks get: entity linking, relation traversal, multi-hop constraint satisfaction. Yet casting it as code works, and the reason it works is the reason code agents are climbing general-assistant leaderboards. A generated program is both the answer and the audit trail. You can execute it, diff it, and see exactly which intermediate step produced which value. A prose chain-of-thought offers no such handle; you can read it, but you cannot run it.

That verifiability point deserves more weight than it usually gets. When a tool-graph agent fails, you inspect a sequence of tool calls and their arguments. When a code agent fails, you get a stack trace, intermediate variables, and a program you can rerun with modifications. For teams debugging agent behavior in production, the second failure mode is substantially cheaper to diagnose.

Hugging Face’s own tooling investments point the same direction. Its homepage lists Transformers as covering 163,055 models for PyTorch2, alongside smolagents2, a smol library to build great agents in Python. The organization maintaining the ecosystem’s default model hub has decided that agents are worth a dedicated library.

Should you wire tool graphs or let the model write code?

If your task distribution is narrow, stable, and heavily audited, a bespoke tool graph is still the easier system to secure and reason about; if tasks are open-ended, code execution wins on generality.

The honest comparison is not capability versus capability. It is an enumeration problem. A tool graph is a whitelist: the set of things the agent can do is finite, enumerable, and reviewable before deployment. That is a genuine safety property, and for workflows like “triage this ticket against these three internal APIs” it may be all the capability you need. The cost shows up at the edges. Every unanticipated sub-task becomes a feature request. Every new tool means a schema, validation logic, prompt real estate, and another thing the model can call incorrectly. Teams maintaining large tool graphs will recognize the failure mode: the agent has forty tools, uses twelve of them, and confuses two with overlapping descriptions.

Code-as-action inverts the trade. The action space is effectively unbounded, so capability stops being the bottleneck and containment becomes it. The architectural question shifts from “which tools do I wire up” to “how do I sandbox a model that writes and runs its own code.” That is not a rhetorical reframing. It changes which engineers you need (runtime security rather than prompt design), which infrastructure you buy (isolated execution environments rather than API gateways), and which failures you drill for (a model that writes os.remove rather than a model that calls the wrong endpoint).

One caveat on benchmark fidelity before anyone rewrites their agent stack on the strength of a leaderboard. GAIA measures general-assistant competence on a fixed question set, and like every public benchmark with static answers, it is exposed to contamination: tasks and solutions circulate, and training corpora absorb them. A code agent that tops GAIA has demonstrated real generality, but a single leaderboard position is weak evidence about performance on your workload, which has different tools, different latency budgets, and different blast radii. Treat any leaderboard result as a signal about where the architecture frontier is moving, not as an evaluation of your use case.

What does the safety tax actually cost?

The safety tax is the difference between filtering prompts and containing programs: when the model’s output is executable code, every defense that used to live at the prompt layer has to be rebuilt at the runtime layer, and runtime containment is harder, more expensive, and less mature.

With a tool graph, the trust boundary is convenient. Inputs get filtered, arguments get validated against schemas, and the worst case is usually a wrong-but-well-formed API call. Prompt injection is still a problem, but the injected instruction can only reach the tools you wired up. The blast radius is bounded by your whitelist.

With code-as-action, the model’s output channel is Turing-complete. A successful injection is no longer “convince the agent to call the delete tool”; it is “convince the agent to write and run a program,” and that program can read the filesystem, open network connections, exfiltrate whatever credentials the environment holds, and do it all inside what looks like an innocuous refactoring task. Defense has to happen where the code runs: filesystem isolation, network egress control, secrets kept out of the environment entirely, resource limits, and ideally a sandbox spun up per invocation. Each of those is a solved problem in isolation. Composing them into a fast, cheap, always-on execution layer for agent workloads is an operations program, not a library import, and it is now on the critical path of every agent rollout that adopts this pattern.

This is also where the economics move. Sandboxed execution adds latency and compute per agent step, and code agents tend to take more steps than tool-graph agents because they explore by running things. Teams budgeting an agent rollout on tool-graph cost assumptions will underestimate both.

What do the red-team exploitability numbers actually mean?

They mean that when unsafe operations are hidden inside ordinary engineering work, current coding agents execute them more often than not, and packaging the payload as code is more effective than packaging it as prose.

The numbers come from Execution-Grounded Security Testing for Coding Agents in Software Engineering Pipelines3, a June 2026 red-team framework worth reading carefully because of how it defines its metric. “Verified unsafe execution” is not a judge model’s opinion about whether an agent’s output looks dangerous. The framework embeds a target unsafe operation into a routine software-engineering workload, lets the agent do its job, and then checks at runtime whether the unsafe operation actually executed. The cover tasks are the blandest work in the pipeline: unit testing, regression testing, crash reproduction, validation. Nothing about the surrounding context signals an attack, which is precisely the point, because that is what real injection looks like.

Under that metric, coding agents reached 73.61% verified unsafe execution on code carriers and 53.93% on text carriers.3 Two conclusions follow. First, the absolute numbers are bad: a majority of embedded unsafe operations ran, on both carriers, in a setting where the correct behavior was to notice and refuse. Second, the roughly twenty-point gap between code and text carriers says the code channel itself is the stronger attack surface. Agents trained to helpfully execute code will helpfully execute code. A payload that arrives as a program to run meets less resistance than the same payload phrased as an instruction to follow, because running programs is the agent’s entire job.

For anyone shipping code-as-action, this is the finding that should set the production bar. Prompt-level filtering does not reach these failures, because the unsafe behavior is not in the prompt; it is synthesized by the model at execution time, from context that looked like a normal task. The defense has to observe and constrain what runs, not what is said.

Is there any defense layer that actually works?

Yes, but the working defenses operate on execution and provenance rather than prompts, which is another way of saying the whole verification stack is migrating to the same layer the attacks live on.

ProvenanceGuard4, evaluated on 281 medical-domain MCP-agent traces, attacks a different but adjacent problem: whether an agent’s claims are faithful to the sources it actually retrieved. Its mechanism is source-aware factuality verification, checking claims against provenance rather than against general plausibility. The reported numbers are solid for a hard domain: block F1 of 0.802 and source accuracy of 0.858 over 260 source-eligible claims on a 40-trace held-out split.4 More striking is the adversarial result: in 50 controlled clinical conflation probes, where attributions were deliberately swapped between sources, the system detected every injected swap with no retained wrong attribution.

No single paper is a moat, and 50 probes is a small adversarial sample. But the direction matters. The verification systems showing real traction in mid-2026 are the ones grounded in what the agent did and what it touched: which sources it read, which operations it ran. That is the same philosophy as execution-grounded security testing, applied to factuality instead of safety. For builders, the pattern across both papers is the actual takeaway: instrumentation at the runtime layer is not optional overhead, it is the only layer where current defenses demonstrably work.

When should you ship code-as-action, and what do you sandbox first?

Ship code-as-action where runtime containment is already solved; everywhere else, treat the architecture as a reason to start building the sandbox, not as a deployment green light.

In practice that ordering looks like this. First, filesystem isolation, so a generated program cannot read or write outside a scratch volume. Second, network egress control, defaulting to deny, because exfiltration is the failure that turns an annoying incident into a reportable one. Third, secrets hygiene: nothing in the execution environment that the agent does not strictly need for the current task, on the assumption that anything present can be reached by generated code. Fourth, resource limits on CPU, memory, and wall time, both for cost and to bound runaway loops. Only after those four does monitoring and provenance tooling of the ProvenanceGuard type become the right next investment, since it presumes you can already observe execution cleanly.

The workloads where this math works today share a profile: high task diversity, tolerable latency, and an environment that is cheap to isolate. CI automation, data pipeline scaffolding, migration scripting, eval harnesses. The workloads where it does not are the ones with live production credentials, tight latency budgets, or irreversible actions reachable from the runtime. For those, a narrow tool graph with an enumerable action space remains the defensible architecture, whatever the leaderboard says.

What does the evidence actually establish?

The sourcing supports a mechanism argument and a security argument, both independent of any single leaderboard. What the sources do establish: code-formulated reasoning generalizes well beyond coding tasks, per KG2Code1; code agents fail execution-grounded security tests at rates of 73.61% and 53.93% depending on the attack carrier, per the red-team framework3; provenance-grounded verification can catch attribution attacks that surface-level checks miss, per ProvenanceGuard4; and Hugging Face ships a dedicated agent library, per its own pages2. The practical verdict: the builder’s question has moved from “which tools do I wire up” to “how do I sandbox a model that writes and runs its own code,” and the answer to the second question determines whether you get to exploit the first. Code-as-action is the generality winner. Runtime containment is the gating cost. Ship the pattern only where the sandbox is real, instrument execution the way the June red-team work3 demonstrates you must, and do not let a benchmark result substitute for a threat model.

Frequently Asked Questions

How does KG2Code’s approach to knowledge-graph QA differ from standard tool-calling agents?

KG2Code treats knowledge-graph question answering as a code generation task rather than a sequence of tool invocations. This produces verifiable reasoning traces and executable code, allowing the system to diff outputs and inspect intermediate variable values. Standard tool-calling agents rely on opaque JSON arguments, which makes debugging multi-hop constraint satisfaction significantly harder.

What specific runtime controls are required to mitigate the 73.61% unsafe execution rate?

Mitigating that risk requires filesystem isolation to prevent reads outside a scratch volume, network egress control defaulting to deny, and strict secrets hygiene. Teams must also enforce resource limits on CPU, memory, and wall time to bound runaway loops. These controls shift the security model from prompt filtering to runtime containment.

How does ProvenanceGuard’s adversarial performance compare to standard factuality checks?

ProvenanceGuard achieved a block F1 of 0.802 and source accuracy of 0.858 on a held-out split of medical-domain traces. In adversarial clinical conflation probes, it detected every injected attribution swap with zero retained wrong attributions. This outperforms standard checks that rely on general plausibility rather than source-grounded verification.

Why is code-as-action more vulnerable to prompt injection than text-based instructions?

The Execution-Grounded Security Testing framework found a twenty-point gap between code carriers (73.61%) and text carriers (53.93%). Agents trained to helpfully execute code meet program payloads with less resistance than prose instructions. Running programs is the agent’s core function, so the model does not flag code execution as inherently suspicious.

sources · 4 cited

  1. Hugging Face – The AI community building the future.huggingface.covendoraccessed 2026-07-28