Direct Tool Calls vs Programmatic Tool Calling
Should your agent call its tools directly, or write a script that calls them?
The model makes every tool call itself and reads each full result before deciding what to do next.
Docs for Direct Tool CallsThe model writes a script that calls the tools, and it only sees what the script prints.
Docs for Programmatic Tool CallingWhen the model used scripts to triage 50 issues, it read half as many tokens as with parallel calls, and the run cost $0.24 instead of $0.45. For a small bug fix it didn't write a script at all, so the cost was the same. I'd still check every item got done, because in 1 of 5 runs a script got a field name wrong, only fetched the first page, and the model labelled those 25 as if that was all.
Same task, three ways
Each block is one request to the model, and the taller it is, the more the model read in that request.
- model requests
- 103
- tool calls
- 102
- tokens read
- 4.3M
- time
- 118 s
- cost
- $1.24
- model requests
- 10
- tool calls
- 102
- tokens read
- 300k
- time
- 54 s
- cost
- $0.45
- model requests
- 10
- tool calls
- 171
- tokens read
- 149k
- time
- 35 s
- cost
- $0.24
In 1 of the 5 runs, it only got 25 of the 50 right.
That's 103 requests one call at a time, 10 with parallel calls and 10 with the script.
All runs used Claude Opus 5.5 at high effort, and each lane replays the run closest to the median of the 5 runs we recorded.
Side by side
| Criterion | Direct Tool Calls | Programmatic Tool Calling |
|---|---|---|
| Model requests, 50 issues | 103 one call at a time, 10 with parallel calls | 10 |
| Tokens read, 50 issues | 4.3M one call at a time, 300k with parallel calls | 149k |
| Cost, 50 issues | $1.24 one call at a time, $0.45 with parallel calls | $0.24 |
| Time, 50 issues | 118 s one call at a time, 54 s with parallel calls | 35 s |
| Runs that labelled all 50 | 10 of 10 | 4 of 5, and one stopped at 25 |
| Fixing a failing test | 5 to 7 requests, $0.05 to $0.06 | 5 requests and $0.06, without writing a script |
| What the model reads | Every tool result in full | Only what the script prints |
When to pick which
- Each step depends on what the last one returned
- The job only takes a handful of tool calls
- You want to see every call as it happens
- You've got nowhere safe to run code the model writes
- The same call runs over dozens of items
- Tool results are big and you only need part of each one
- You can check the script got through every item
- You already have a sandbox set up for running scripts
How we tested
- Task
- We ran three tasks against mock tools with known answers. The model triaged 50 issues, found the 5 files (out of 53) that read environment variables, and fixed a failing unit test. We ran each task 5 times per approach, one call at a time, with parallel calls, and with a script runner that calls the same tools.
- Evidence
- 45 recorded runs with prompt caching on, each scored against the task's answer key. Costs use Claude Opus 5.5 list prices on 4 Nov 2026.
- With
- Claude Opus 5.5, effort high, A small harness of our own on the Claude Messages API, Scripts in a QuickJS sandbox, output capped at 10,000 characters
Updates
Published.