AI 智能體每步重傳工具清單,重複描述成本佔帳單 32%
Your AI agent re-reads its tool list on every step — that's 32% of the bill
作者估算,AI 智能體每步 API 請求都會重傳工具清單;18 個工具、10 步的示例中,工具描述佔輸入 token 36%,並佔執行成本 32%。
You give your agent a toolbox: read a file, run the tests, search the web. The model picks a tool, your code runs it, the result goes back, the model picks the next one. It feels like the model knows its tools. It doesn't. It forgets them after every reply, and you pay to remind it.
I counted what that reminder costs on a realistic toolbox. Short version: about a third of the bill.
How the model "knows" its tools
A few words first. A token is roughly ¾ of a word; APIs bill per million of them, one price for input (what you send) and a higher one for output (what the model writes). Tool calling is the API feature where you describe functions and the model replies with "call read_file with these arguments" instead of plain text. Each function is described with a JSON Schema — a JSON object listing the name, a description and the parameters with their types.
Here is one of them, exactly as an OpenAI-compatible API expects it:
{"type": "function", "function": {
"name": "edit_file",
"description": "Replace an exact string in a file with a new string. The old string must appear exactly once in the file unless replace_all is true. Preserve indentation exactly.",
"parameters": {"type": "object", "properties": {
"path": {"type": "string", "description": "Path to the file to edit."},
"old_string": {"type": "string", "description": "Exact text to find. Must be unique in the file."},
"new_string": {"type": "string", "description": "Text to replace it with."},
"replace_all": {"type": "boolean", "description": "Replace every occurrence instead of requiring a unique match."}},
"required": ["path", "old_string", "new_string"]}}}
The API is stateless: nothing is remembered between requests. So the whole tools array travels inside the input of every request, next to the system prompt and the history. An agent loop — the model calls a tool, gets the result, decides the next move — is one request per step. Ten steps, ten copies of the toolbox.
I counted a real-looking toolbox
I wrote 18 tools of the kind every coding agent ships with: read_file, write_file, edit_file, list_directory, search_code, find_files, run_shell, run_tests, three git tools, web_search, fetch_url, http_request, query_database, create_issue, send_message, ask_user. Descriptions are ordinary, one or two sentences each. Then I counted them with tiktoken and o200k_base, the tokenizer behind current GPT models:
import json, tiktoken # pip install tiktoken
enc = tiktoken.get_encoding("o200k_base")
tools = json.load(open("tools.json")) # your "tools" array
total = len(enc.encode(json.dumps(tools)))
print(f"{len(tools)} tools = {total} tokens per request")
for t in tools:
n = len(enc.encode(json.dumps(t)))
print(f" {t['function']['name']:<16} {n}")
Result: 2,388 tokens, 133 per tool on average. The smallest, git_status with no parameters, is 54. The biggest, search_code with five parameters, is 193. That's for one request — before the user has typed a word.
Ten steps, ten copies
Now a modest agent run: a 500-token system prompt, a 200-token task, 10 steps, each step adding about 780 tokens of history (a tool call plus its result) and producing 150 output tokens. Prices are GPT-5.6's official ones on 15.10.2026: $2.00 per million input, $12.00 per million output.
| Toolbox | Tool tokens per run | Share of input | Cost per run | Schemas per month* |
|---|---|---|---|---|
| All 18 tools | 23,880 | 36% | $0.150 | $1,433 |
| 6 tools the task needs | 9,380 | 18% | $0.121 | $563 |
| No tools (baseline) | 0 | 0% | $0.102 | $0 |
*1,000 runs a day, 30 days, input price only.
With the full toolbox, the schemas are $0.048 of a $0.150 run — 32% of the bill. Per request, they weigh more than three times the system prompt and the task combined. And it's not a one-off: at 1,000 runs a day that's 716 million tokens a month spent re-describing send_message to a model fixing a typo.
What to do about it
Ship the agent only the tools the job needs. A coding fix doesn't need create_issue, send_message or query_database. Cutting to six relevant tools dropped the schema cost from $1,433 to $563 a month — $870 saved without touching a prompt.
Second, trim the descriptions. I kept every tool but cut each description to its first sentence and removed per-parameter descriptions: 2,388 → 1,545 tokens, −35%. Test that the model still picks the right tool afterwards; descriptions are how it decides.
Third, run the script above on your own tools array. It takes a minute and turns "it's just some JSON" into a number.
The price per token is the other multiplier. We resell GPT-5.6 at $1.70 per million input against the official $2.00, so the same 716M tokens of schemas cost $1,218 instead of $1,433. That's 15% off a waste you shouldn't be paying for at all — trimming the toolbox comes first.
What this doesn't solve
My count is approximate. Providers don't send your JSON to the model verbatim: they rewrite it into an internal format and add their own instructions, so the real figure is a bit different and differs per vendor — check usage.prompt_tokens on a real call with and without tools. Prompt caching changes the money a lot: the tool list sits at the start of every request, which is exactly what caching discounts, so with caching on, the 32% shrinks. I can't show how much on our traffic — our usage records don't split cached tokens out yet. And swapping toolboxes per step breaks that cache, so "send fewer tools" and "cache them" pull against each other.
Count your tools before you count anything else. They're the part of the prompt you wrote once and pay for forever.
來源:DEV Community · dev.to