Authors:
Imran Sheik Mohamed, AI Solutions Architect, Data Center Group, Intel
Mikolaj Zyczynski, AI Software Architect, Data Center Group, Intel
Jakub Maksymczuk, AI Software Engineer, Data Center Group, Intel
How to build agents that do more work in runtime, not in your token budget.
As Agentic AI is increasingly adopted in enterprises, and because agentic models require far more tokens per task than standard models, token costs are eating into IT budget allocations. Every LLM call in an agentic system carries a heavy context payload: system prompts, tool definitions, memory, and middleware all compete for space in the context window before the user's actual question even arrives.
The landscape of AI agents is shifting from simple "ask-and-receive" interactions toward complex, multi-step reasoning. Traditionally, we’ve relied on Direct Tool Calling, where an agent triggers a single tool, waits for the response, processes it, and then decides on the next move.
Tool calls with Agentic systems have been groundbreaking by enabling dynamic interaction with external systems, orchestrating multi-step workflows, and extending LLM capabilities beyond static text generation to real-world actions such as API calls, database queries, and tool integrations. This allows agents to reason, plan, and execute tasks autonomously, making them highly flexible and well-suited for complex problem-solving across domains. Tool calls are also sequential, relying on the LLM to validate and provide directions for subsequent actions (tool calls or other actions). This also introduces complexity and takes a long time to resolve the problem reported to the agent.
Imagine you've launched an Agentic AI assistant for your retail store. It's in production. Real customers are using it. And then someone types:
"Do you have the 'Midnight Runner' sneakers in stock?"
Simple question. But watch what happens under the hood. Your agent runs on an MCP-powered tool stack: inventory lookup, product search, order management, customer accounts, pricing, promotions, and returns. Add a couple more MCPs for web interactions, ticketing, and internal APIs, and before the customer's question even reaches the model, you're already carrying dozens of tools and thousands of tokens of tool definitions in context. The agent hasn't said a word yet.
Now it calls the MCP tool to list all the products. Back comes a massive JSON blob, every product, price, SKU, and internal code, all dumped into the context window so the model can scan through and find one pair of shoes.
This is the direct tool call method agents have been using so far.
But what if there was a better way to do the same thing, faster and with fewer tokens? There has been an alternative methodology floating around to wrap these tools in a script and run them programmatically to speed things up.
Anthropic described this architectural pattern in their blog on code execution with MCP, and later shipped it as a product feature called Programmatic Tool Calling, which was an extension of the previous work with CodeAct and SmolAgents. In their benchmarks, this approach reduced average token usage from 43,588 to 27,297 tokens, a 37% reduction on complex research tasks, by keeping intermediate results in the execution environment instead of passing them through the model's context window.
Picture1.png
Figure 1: Flowchart showing differences between Direct Tool Call and Agentic Code Execution
Now, when using the Agentic Code Execution approach with the same query, the agent generates a script that calls the same tool to list the product, filters the list for "Midnight Runner" in memory, grabs the specific identifier, and immediately chains it with another call to get the details.
The result? The LLM context never sees the other 499 products. This "need-to-know" data flow ensures that insignificant or sensitive details are never exposed to the context or the end user, helping narrow data exposure in the prompt path and the prompt focus.
The Architecture: Chaining vs. Chatting
In a standard setup, an agent acts like a relay runner, constantly passing the baton back and forth between the tool and the context window. In Agentic Code Execution, the agent acts more like a developer. Instead of calling one tool at a time, it generates a Python script that chains multiple actions together.
Key Differences:
- Direct Approach: The raw output of every tool (no matter how bloated) is dumped back into the LLM context.
- Code Execution with MCP Approach: The agent uses Python features-loops, filters, and logic-to process data locally within the execution environment. Only the "significant" results are printed and returned to the context.
How we tested this.
We wanted to validate this approach against industry-standard benchmarks, so we compared results with open-source models on τ²-bench for the retail domain to see if the approach offered any measurable benefits.
The models we ended up testing were instruction-tuned versions of Qwen3-Coder-30B-A3B-Instruct and Gemma4-26B-A4B-it. This was hosted on an Intel® Xeon® 6767P processor using vLLM (v0.20.0). The serving framework includes optimizations specific to Intel® Advanced Matrix Extensions (Intel® AMX) for both model families as part of the upstream enablement work, and they are also available out of the box in the public Docker container, without any additional configuration.
Under the Hood: How a Turn Actually Flows
So, what does an Agentic Code Execution turn look like in practice? In our setup, built with Flowise for orchestration and MCP servers over SSE for tool access, the flow is split across three cooperating layers: an orchestrator, a Python execution sandbox (powered by utcp_code_mode or pydantic-monty as pluggable engines), and a domain tools server, each with a specific job.
The Orchestrator
The orchestrator owns the conversation loop, the system prompt, and the connection to the LLM. From its perspective, the agent has exactly one tool: execute_python. It doesn't see find_user, get_order_details, list_products, or any of the other 20-odd domain tools - those are deliberately hidden one layer down. The LLM is told, via a dynamically generated API reference, that these actions exist and are callable as method_name() from inside a Python script. That single indirection is what unlocks everything else.
The Sandbox Server: Where the Generated Code Actually Runs
When the model produces a Python snippet, Flowise ships it over MCP to the sandbox server. This is a key control layer in the pattern.
Letting an LLM write code that runs on your infrastructure is, on its face, terrifying. If you just exec() model-generated strings, you've built a remote-code-execution vulnerability and called it an agent. The sandbox is what turns it from a liability into a feature:
- RestrictedPython compilation. Code is compiled with RestrictedPython before execution, which blocks dangerous syntax (attribute mangling, uncontrolled iteration, raw subscript access) and forces every read/write through guarded primitives (getiter, getitem, write, inplacevar).
- A stripped-down globals table. The execution context doesn't start from builtins; it starts from RestrictedPython.safe_globals and is then handed a hand-picked set of primitives (len, range, sorted, map, filter, etc.). There's no open, no eval, no exec, no file I/O.
- A whitelisted import. Only json, math, datetime, time, re, typing, collections, and itertools can be imported. Anything else -os, subprocess, socket, requests -raises ImportError at import time.
- Per-request, stateless execution. Each execute_python call spins up a fresh sandbox instance. Variables don't carry across turns, so a malicious or confused prior turn can't poison later ones.
- Hard timeouts. Every execution runs inside a thread with a bounded timeout, so a runaway loop can't wedge the server.
The net effect: the model can write whatever Python code it wants, but the scope of execution is capped at "manipulate local variables and call the tools we explicitly exposed."
The Bridge to the Tools Server
Inside the sandbox, the actions object isn't magic; it's a proxy. For every domain tool advertised by the tools server, the sandbox dynamically builds a Python function that, when called, opens an MCP session over SSE and forwards the call. Two details matter here:
- Session-scoped isolation. Every tool call is tagged with an mcp-session-id header, which the tools server uses to route into a per-session copy of the domain database. Designed to isolate per-session state in our test setup, important both for privacy and for results reproducibility.
- Automatic tool discovery. The sandbox polls the tools server every 10 seconds, re-discovers its tool list, and regenerates the execute_python description that the LLM sees. Swap the domain from retail to airline, and the agent's available "API" updates without a restart.
So when the model writes list_all_products() inside its script, the call travels: sandbox → MCP client → tools server → per-session SQLite copy of the retail DB → back up the same chain. The raw JSON response is executed in the sandbox's Python runtime, not in the LLM's context.
The Return Trip
Here's where the token savings come from. The sandbox collects only what the script explicitly exposes with print(), via a shared PrintCollector wired into RestrictedPython's print hook, plus any structured error. That captured output is what gets returned to Flowise and appended to the conversation.
Everything else: the 500-product catalog the script filtered through, the intermediate dicts, the loop counters, the full order records it pulled just to grab a single status field -stays inside the sandbox and is garbage-collected when the call returns. The LLM sees a clean, curated summary; the heavy data never crosses the context boundary.
That's the whole trick, and it's why the numbers in the table above look the way they do: the agent still has full access to the data, but the context window only sees the answer.
The Results
Moving the heavy lifting into a generated script doesn’t just make the code cleaner; it also reduces token utilization and end-to-end task execution latency. Our tests showed a marked decrease in the number of turns between the user and the agent and a decrease in the number of tools called per conversation.
Picture2.png
| Model | Metric | Direct Tools (Baseline) | Agentic Code Execution | Observed Benefit |
| Qwen3-Coder-30B-A3B-Instruct | Tokens Generated | 154,254 | 115,172 | -25% |
Average Task Completion Time | 67.717 | 60.201 | -10% | |
| Gemma-4-26B-A4B-it | Tokens Generated | 108,645 | 75,344 | -30% |
| Average Task Completion Time | 256.119 | 187.089 | -27% |
Table 1: Results are scenario-specific and may vary by model, workload, deployment, and environment.
For Gemma-4 in this setup, end-to-end latency was 27% lower. Based on the data above, reducing the "chatty" nature of tool interactions results in lower token usage and lower end-to-end latency.
So, when would you use this new innovative approach?
Agentic Code Execution raises a deeper architectural question that every agent builder should consider: Should the LLM be doing ad hoc data processing at all?
In many cases, the answer is no. If a task can be scripted, tested, and verified once, put it in a skills library. Let the agent invoke a known, reliable script rather than generating new code from scratch each time. If data processing belongs on the server side, give the agent a clean endpoint that returns the result rather than having it orchestrate dozens of individual data fetches.
Agentic Code Execution is most valuable when the task is genuinely dynamic, when the logic can't be known in advance, or when you're operating at a scale that makes sequential tool calls infeasible.
The Takeaway
This new approach isn't a clever trick; it's a shift in where the work happens. Instead of the LLM being both the planner and the data processor, it goes back to doing what it's actually good at: deciding what needs to happen, then writing a few lines of code to make it happen. The heavy lifting: filtering, joining, and looping, moves into a runtime that reduces overall task execution times and utilizes fewer tokens.
It's not the right answer for every agent. If your task is well-defined and repeated, put it in a skills library and call it directly. If your data flow belongs on the server, expose a clean endpoint and skip the orchestration. But when the work is genuinely dynamic, when you can't know the call graph in advance, letting the model write the glue code is the practical option for dynamic workflows.
The bigger point: agents don't have to be chatty to be capable. They can be designed to reduce unnecessary data exposure in context, lean by construction, and still do everything the direct-call version does. They just stop the LLM from reading every row of the database to find one pair of sneakers.
This approach is already available as the Blueprint: Agentic Code Execution in the Intel AI Software Catalog.
Note: This blog reports approach-level workflow observations in a specific application setup and does not constitute CPU/GPU/SoC performance or Intel-versus-competitor performance claims.
References:
- https://fortune.com/2026/05/26/uber-coo-ai-spending-tokens-claude-code/
- CodeAct: Wang, X., Chen, Y., Yuan, L., Zhang, Y., Li, Y., Peng, H., & Ji, H. (2024). Executable Code Actions Elicit Better LLM Agents. Proceedings of the 41st International Conference on Machine Learning (ICML), in Proceedings of Machine Learning Research, 235: 50208-50232.
- Code Execution with MCP: https://www.anthropic.com/engineering/code-execution-with-mcp
- https://www.anthropic.com/engineering/advanced-tool-use
- SmolAgents: Roucher, A., Villanova del Moral, A., Wolf, T., von Werra, L., & Kaunismäki, E. (2025). smolagents: A smol library to build great agentic systems [Computer software]. GitHub. https://github.com/huggingface/smolagents
- https://github.com/sierra-research/tau2-bench
- https://docs.vllm.ai/en/latest/getting_started/installation/cpu/#set-up-using-docker
- https://github.com/universal-tool-calling-protocol/code-mode
- https://github.com/pydantic/monty
- https://aiswcatalog.intel.com/blueprints
Notices and Disclaimers
Performance varies by use, configuration, and other factors. Learn more on the Performance Index site.
Performance results are based on testing as of the dates shown in configurations and may not reflect all publicly available updates. See backup for configuration details. No product or component can be absolutely secure.
Your costs and results may vary.
Intel technologies may require enabled hardware, software, or service activation.
© Intel Corporation. Intel, the Intel logo, and other Intel marks are trademarks of Intel Corporation or its subsidiaries. Other names and brands may be claimed as the property of others.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.