The architectural implication is that the script is the context. Variables persist for the lifetime of the script. The agent does not see anything the script does not print. That is the property that makes the surface useful: it gives the agent a private workspace where intermediate results can be filtered, transformed, or aggregated before a single summary crosses back into the model context.
The child process runs on the agent host, communicating over the socket; there is no separate ingestion engine (https://hermes-agent.nousresearch.com/docs/user-guide/features/code-execution). The hermes_tools stub exposes a documented subset of tools: web_search, web_extract, read_file, write_file, search_files, patch, and terminal (foreground only). Tools outside that subset cannot be called from inside the script.
When execute_code wins and when it loses
The published heuristic for when to use execute_code is three or more tool calls with processing logic between them, bulk data filtering, conditional branching, or loops over results (https://hermes-agent.nousresearch.com/docs/user-guide/features/code-execution). The common thread is that intermediate tool results are noise from the model's perspective. They are inputs to a computation the agent would do anyway, and the model only needs the computation's output.
| Use execute_code | Stay in multi-turn tool use |
|---|
| Looping over search results to extract or filter | A single tool call with a deterministic result |
| Bulk refactor across many files with per-file decisions | Each tool call needs to be steered by the next user-visible turn |
| Piping web search to web extract to summary | The intermediate result is the answer the user is waiting for |
| Filtering thousands of rows to the few that matter | Tool results are inherently conversational and should appear in the transcript |
| Multi-source aggregation that needs typed structures | The user is debugging the agent's reasoning and needs to see each step |
The losing column is important. There are workflows where the user genuinely benefits from seeing each tool call and its result in the transcript — for trust, for debugging, for auditability. Forcing those workflows into execute_code hides useful signal and removes the operator's window into what the agent actually did. The right design is to use the surface for what it is good at and leave the conversational workflows conversational.
A migration pattern from multi-turn to single-turn
The migration from a multi-turn tool loop to an execute_code script follows a recognizable pattern. First, identify the tool calls that would have happened and the processing between them. Second, write the script so that each tool call is a function call and each processing step is a Python expression. Third, collect the final summary in a single print statement. Fourth, let the script decide what the next model turn should see.
A worked example: the published documentation shows a data processing pipeline that searches for configuration files matching a pattern, reads each one, and returns a structured summary with file paths and previews (https://hermes-agent.nousresearch.com/docs/user-guide/features/code-execution). In a multi-turn implementation, each search and each read would have returned to the model; in the execute_code implementation, the loop stays in the script and only the final summary crosses the boundary.
The same pattern applies to a multi-step web research workflow: search, extract each result page, filter for content, summarize (https://hermes-agent.nousresearch.com/docs/user-guide/features/code-execution). Each step is a function call in the script, and the model sees only the final structured summary. The cost shape shifts from "every intermediate result is in the model's context" to "only the final summary is in the model's context," which is the entire point of the surface.
What you give up by collapsing turns
The collapse is not free. Three trade-offs are worth naming explicitly. First, the operator loses the step-by-step transcript. If something goes wrong inside the script, the model sees only the failure message, not the intermediate state that produced it. Second, the script becomes a single point of debugging, which means errors in the script's logic are harder to attribute than errors in a multi-turn conversation. Third, the agent cannot reason about intermediate results in the same way; it sees what the script chose to print, not the raw tool outputs.
The architectural mitigation for all three is to print enough. A good script prints structured summaries that include counts, decision thresholds, and named intermediate aggregates, so that a reader can reconstruct the reasoning from the printed output alone. The pattern is similar to logging in a long-running service: the script is the service, the print is the log, and the model is the operator who has to debug from the log alone.
A second mitigation is to keep the script small enough to reason about. The execute_code surface is most powerful when each script is a focused transformation with a clear input, a clear output, and a short computation in between. Long scripts that try to do everything in one shot produce the exact failure mode the surface is meant to prevent: a context window flooded with intermediate state.
The documented tool surface inside scripts is web_search, web_extract, read_file, write_file, search_files, patch, and terminal (foreground only) (https://hermes-agent.nousresearch.com/docs/user-guide/features/code-execution). The terminal call is foreground only, which means long-running commands inside a script block the script for the duration. Background processes from a script are not supported by the documented surface.
The implication for builders is that scripts are well-suited to short, deterministic terminal work (run a test, run a linter, parse the output) and not well-suited to long-running processes (a dev server, a watcher, a daemon). For the latter, the right pattern is to use the subagent delegation or cron surfaces, not execute_code (https://hermes-agent.nousresearch.com/docs/user-guide/features/delegation, https://hermes-agent.nousresearch.com/docs/user-guide/features/cron).
The hermes_tools stub is generated per script invocation and is the bridge back into the agent's tool surface (https://hermes-agent.nousresearch.com/docs/user-guide/features/code-execution). The stub pattern is what keeps the script portable across tool surface changes: the script imports a stable interface, and the bridge handles the RPC and the agent-side execution.
Implementation metrics and review thresholds
Three numbers tell you whether an execute_code implementation is paying its way. They are easy to compute after a few runs and they are the early signal that a workflow is a good candidate for the surface or that an existing implementation should be reconsidered.
| Metric | Threshold worth watching | Why it matters |
|---|
| Tool calls collapsed per script invocation | More than 3 | Below this threshold, the multi-turn surface is simpler and the savings do not justify the script |
| Intermediate results kept out of the model context | All filtered, aggregated, or summarized before print | The surface is only a win if the model never sees the intermediate state |
| Failure attribution from a single print block | The script logs each decision threshold and aggregate count | A script that does not print enough makes the next debug session harder than a multi-turn conversation would have been |
A reference workflow rewritten end to end
A useful reference workflow is "find all Python files using a deprecated API and rewrite them in place." In a multi-turn implementation, the agent would search, read each file, propose a rewrite, write it, and verify; each step would return to the model. In the execute_code implementation, the script searches, filters, rewrites each file via the patch tool, and prints a single structured summary with the count of files fixed and the count of files skipped (https://hermes-agent.nousresearch.com/docs/user-guide/features/code-execution).
The same pattern rewrites end-to-end test suites, bulk documentation cleanup, structured data extraction from a list of URLs, and any other workflow where the structure of the computation matters more than the structure of the conversation. The discriminating question is always the same: would the model benefit from seeing each tool call in the transcript, or would the model benefit from seeing only the final aggregated result?
FAQ
The documented surface is web_search, web_extract, read_file, write_file, search_files, patch, and terminal (foreground only) (https://hermes-agent.nousresearch.com/docs/user-guide/features/code-execution). Other tools are not available from inside the script.
Can I run a long-running process inside an execute_code script?
The documented terminal call is foreground only (https://hermes-agent.nousresearch.com/docs/user-guide/features/code-execution). Long-running processes belong in subagent delegation or cron, not execute_code.
How does execute_code differ from subagent delegation?
execute_code collapses multiple tool calls into a single LLM turn in the parent's context (https://hermes-agent.nousresearch.com/docs/user-guide/features/code-execution). Subagent delegation starts a fresh conversation with isolated context and returns a summary (https://hermes-agent.nousresearch.com/docs/user-guide/features/delegation).
The execution test
An execute_code script is well-designed when (a) the model sees only the summary it needs to act on next, (b) every intermediate decision the script made is reconstructable from the printed output, (c) the script stays small enough to reason about, and (d) the workflow would have been three or more multi-turn tool calls without it. The surface is built to make each of those properties achievable; the builder's job is to use it for what it is good at and leave conversational workflows conversational. Each implementation is also a tradeoff between context compression and debugging transparency, and a good implementation names the tradeoff in the implementation review rather than letting one side win by default. The limitations of the foreground-only terminal call are the right counterweight for the RPC design, and the right implementation uses subagent delegation or cron when the work crosses the boundary.
An execute_code review most teams skip is the one where they print enough that the next debug session can reconstruct every decision from the source of the printed output alone. That print discipline is the implementation tradeoff that separates a script worth keeping from one worth rewriting, and the surface is at its best when the model never has to ask for intermediate state it never saw.