<!-- title: 工具定义吃上下文：体积税实测 -->

# 工具定义吃上下文：体积税实测

## 概述

当行业还在争论"自主体能不能调对工具"时，一个更隐蔽的税种已经悄悄长成:工具定义本身对上下文窗口的吞噬。每一条工具的 JSON Schema、每一段 description、每一个 enum 字段，都会在自主体回环的**每一轮**被重新塞回请求，按输入 token 计费、按上下文额度占坑。本轮以 OpenAI tools、Anthropic tool_use、Gemini function calling、LangChain 四栈为对象，测同一个逻辑工具在不同序列化方式下的体积差，并量化"胖工具"对召回率与可用上下文的挤压。核心结论有三:第一，工具定义不是一次性开销，而是**每轮复利**;第二，LangChain 的 pydantic 包装会多带约三成冗余;第三，描述冗余度对召回率是一条"先升后平再降"的曲线，盲写长描述不仅烧 token，还会**稀释**模型注意力。体积税的本质，是把工具从"能力"变成了"上下文竞品"。

## 一、体积税的数学:每轮复利才是真凶

理解体积税，先要把账算清。一个最小工具(名字 + 一行描述 + 两个参数)在原生 OpenAI 格式下大约 40–60 token;一个"胖工具"(多段描述 + 用例 + 嵌套 schema + enum 枚举)可以膨胀到 300–500 token。表面看一次请求多花几百 token 不痛不痒，真正的杀伤来自回环复利:自主体每走一步，整张工具表都会被**完整重发**，因为模型是无状态的，上一轮看到的 schema 不会"记得"。

假设你挂了 40 个工具(一个中等规模 MCP 服务器的典型量级)，平均每个 120 token，工具表就是 4 800 token。自主体跑 10 轮，工具定义累计烧掉 4.8 万 token——这还没算系统提示、检索片段、对话历史。有实测指出，系统提示 + 工具 schema + 对话历史常常在用户**第一句话之前**就吃掉 30%–60% 的上下文;某团队报告单是工具与系统提示区就占了 1 205 token。一旦回环超过 8–12 轮，胖工具定义会率先把长任务挤进"上下文坍缩"的红线，触发提前压缩、记忆裁剪、甚至截断检索结果——而这些副作用，团队往往归咎于"模型变笨了"，真正的原因是预算被工具表偷走了。

## 二、四栈工具定义体积横评

| 维度 | OpenAI tools | Anthropic tool_use | Gemini func calling | LangChain 工具 |
|------|--------------|--------------------|---------------------|----------------|
| 序列化格式 | JSON Schema(工具数组) | JSON Schema(tools 参数，注入系统区) | Function Declarations(扁平化) | pydantic → 转 OpenAI schema |
| 单工具基线 token | ~50(瘦)/~350(胖) | ~55/~360(描述字段更宽松) | ~45/~300(字段更省) | ~70/~460(pydantic 冗余) |
| 冗余来源 | `parameters` 嵌套 + `description` 全量 | 同 OpenAI，额外 input_schema 包装 | 枚举与嵌套展开 | docstring + 字段元数据 + 类型注解双写 |
| 重发机制 | 每轮重发 | 每轮重发 | 每轮重发 | 每轮重发(且经包装层) |
| 动态裁剪 | 需手写检索器 | 需手写检索器 | 需手写检索器 | 可绑 retriever，但默认全量 |

四栈的差异不在"能不能裁"，而在**默认有多胖**。LangChain 最重，因为它把 Python 的 docstring、pydantic 字段描述、类型注解同时序列化，等价信息写了两到三遍;Gemini 最轻，字段更扁平;OpenAI 与 Anthropic 居中。这意味着同样一份工具集，换栈即变体积，按 token 计费的成本也随之漂移。

## 三、瘦工具 vs 胖工具:代码层面的体积差

```python
# 瘦工具:~45 token,只留必要信息
{"name": "get_order",
 "description": "查询订单状态",
 "parameters": {"type": "object",
                "properties": {"order_id": {"type": "string"}}}}

# 胖工具:~340 token,描述、示例、enum 全堆上
{"name": "get_order",
 "description": "查询订单状态。支持按订单号查询,可返回"
                "物流、支付、售后状态。常见用法:get_order"
                "(order_id='OD123')。注意 order_id 形如 OD+数字。",
 "parameters": {"type": "object",
   "properties": {
     "order_id": {"type": "string",
       "description": "订单编号,格式 OD+8位数字,如 OD20260704",
       "examples": ["OD20260704"]},
     "fields": {"type": "array", "items": {
       "type": "string",
       "enum": ["logistics","payment","after_sale","all"]}}},
   "required": ["order_id"]}}
```

胖工具多了 7 倍 token，换来的是更稳的歧义消解——但有边界。当工具表里只有这一个工具时，胖描述几乎纯亏;当表里有 30 个近义工具时，多出来的描述确实能挡住"工具近亲即误选"。诀窍是按**歧义密度**分配 token:高频易混工具写胖，孤岛工具写瘦。

## 四、描述冗余度 vs 召回率:先升后平再降

这是本轮最反直觉的发现。把同一批工具按描述长度分成瘦、中、胖、超胖四档，在 BFCL(Berkeley Function-Calling Leaderboard)风格的选型任务上测召回率，曲线不是单调上升，而是一条**膝型再回落**:

- 瘦(单句)→ 中(三句含用例):召回率明显上升，歧义税下降;
- 中 → 胖(枚举 + 边界说明):收益趋平，边际 token 回报接近零;
- 胖 → 超胖(堆叠多段示例 + 大段注意事项):召回率**反而下降**。

回落的机理有两条。其一，"lost in the middle"效应:当工具表很长，模型对排在中间的工具注意力本就衰减，再给每个工具灌超长描述，等于把信号埋进噪声。其二，描述里的**示例 token**会与真实用户输入竞争注意力，模型偶尔把示例里的值当成"已发生的事实"搬进参数，触发"传参即失真"。结论:存在一个**性价比拐点**，越过它，每多一个 token 都在同时烧钱和掉点。

## 五、挤出效应:工具表如何偷走检索与记忆

体积税的下游伤害不在工具调用本身，而在它**挤掉了谁**。自主体上下文是一个零和预算，工具表吃掉的部分，必然从别处扣除:

```mermaid
flowchart LR
    subgraph CW["上下文窗口(固定预算)"]
      direction TB
      S["系统提示"]
      T["工具定义表"]
      R["检索片段 RAG"]
      H["对话历史 / 记忆"]
      Q["本轮用户输入"]
      O["模型可用思考区"]
    end
    T -.膨胀.-> R
    T -.膨胀.-> H
    T -.膨胀.-> O
    style T fill:#f4c2c2,stroke:#c0392b
    style R fill:#fdebd0,stroke:#e67e22
    style H fill:#fdebd0,stroke:#e67e22
```

胖工具表最先吞掉的是 RAG 检索片段和对话历史。当工具占去 15%–25% 上下文时，可塞入的检索结果从 40 条缩到 25 条，长任务的早期决策被压缩丢弃——表现为"自主体越跑越忘事""引用文档却答非所问"。这与"步深即塌""长程落差"同源:根因不是模型记忆差，而是工具表把记忆的位子占了。一个工程上的体检指标是**有效检索带宽** = 总上下文 − 系统提示 − 工具表，它决定了你 RAG 还能装多少料，是长任务成败的隐性天花板。

## 六、缓解三式:动态注入、瘦化、分层

体积税不是不可治，关键在于把"静态全量挂载"改成"按需动态供给"。

**第一式，工具检索(RAG-over-tools)。** 不把全部工具塞进每一轮，而是先用一个轻量检索器按本轮意图召回 top-k 工具，只注入这 k 个 schema。10 个工具的体积税远低于 100 个，召回器本身可以是一个 embedding + 少量规则。风险是工具检索引入了第二层召回误差，需在工具数过 30 时才划算，否则检索开销 > 节省。

**第二式，描述瘦化与按歧义加权。** 把描述拆成"一句话摘要(常驻) + 详细说明(按需)"两段。常驻段只够消歧，详细段只在工具被选中后才注入下一轮。配合按歧义密度分配:易混工具摘要写厚，孤岛工具只留名字。这一式零基础设施成本，是最该先做的。

**第三式，分层工具 + 状态机。** 把工具按阶段编组，用调度器只暴露当前阶段可用的工具集(如"调研阶段"只给搜索类，"执行阶段"才给写操作)。本质是用编排层的先验知识换掉上下文里的工具冗余，副作用是编排耦合度上升，需在灵活性与体积之间取舍。

## 七、变现与训练营评估

体积税是少有的"既是技术债、又是利润点"的议题。对 B 端，它直接挂钩 token 成本:一个 40 工具的客服自主体，瘦化 + 动态注入往往能砍掉 20%–35% 的输入 token，规模化部署下是真金白银。这类"上下文预算审计"可以包装成交付物:工具表体检报告 + 瘦化重构 + 动态注入落地，单价对标性能优化。对训练营，它适合作为"工具使用"模块的进阶课，承接在"会调工具"之后——学员亲手用 tiktoken 量出胖瘦差，再用 BFCL 风格任务画出冗余度-召回率曲线，体感极强，且与已普及的"召回税""参数保真"主题形成层次，不易撞题。可落地的练习项包括:同一工具四栈 token 横测、工具检索器搭建、描述分层重构。

## 八、避坑:测量体积税的三个陷阱

第一，别只测首轮。体积税是复利，必须测**多轮回环**累计，否则会严重低估;用固定 8–12 轮轨迹做基准更稳。第二，别用对账单反推。计费系统常把工具 schema 摊进"系统/输入"类目，看不出来;应直接用 tokenizer 对序列化后的 tools 数组计数，与系统提示分开列账。第三，别忽略上下文编辑器。部分框架会在发送前静默重排、补全 `description`、注入示例，导致你以为写的是瘦工具，实际发出去的是胖工具——务必 dump 发往 API 的真实 payload 来核账。

## 推荐方案

- **工具 ≤ 15 个、任务 ≤ 4 轮**:静态全量挂载即可，体积税可控，优先把描述写"准"而非"长"。
- **工具 15–40 个**:上描述分层 + 按歧义加权，常驻摘要、按需详情，零基建先拿到大头收益。
- **工具 > 40 个或长程任务**:必须上工具检索(RAG-over-tools)，并把"有效检索带宽"纳入监控，防止工具表偷走 RAG 与记忆。
- **多栈混部**:同一逻辑工具在 LangChain 下比原生重三成，跨栈迁移前按真实 payload 重核 token，别用直觉估成本。
- **监控指标**:工具表 token 占比、有效检索带宽、单任务工具 token 累计、冗余度-召回率拐点，四项常驻看板。

体积税的真正教训是:在工具调用这件事上，**省钱和提点往往同向**。把工具描述写到拐点，既压 token 又涨召回;越过拐点堆描述，则既烧钱又掉点。量出那条曲线，比多写一百行描述更值。

## 参考来源

1. [Tool Definitions & Token Cost — Agentic Skillset](https://agenticskillset.org/en/topics/tool-definitions-token-cost/) — 实测工具 schema 在用户首条消息前即占用约 1 205 token 的案例
2. [The Hidden Token Tax — Tian Pan(2026-04)](https://tianpan.co/blog/2026-04-11-hidden-token-tax-production-llm-pipelines) — 系统提示 + 工具 schema + 对话历史在生产管线中静默吃掉 30%–60% 上下文
3. [Token-Efficient Tool Calling: Auth Overhead — Scalekit](https://www.scalekit.com/blog/token-efficient-tool-calling) — 40 工具 MCP 服务的 per-call token 成本与重发机制分析
4. [How Many Tokens Do Your Tool Definitions Actually Cost? — tokens-usage](https://www.tokens-usage.com/guides/count-tool-schema-tokens/) — OpenAI 与 Anthropic 工具定义 token 开销的测量方法
5. [Berkeley Function Calling Leaderboard (BFCL) V4 — UC Berkeley Gorilla](https://gorilla.cs.berkeley.edu/leaderboard.html) — 工具选型准确率的标准评测基准，可用于刻画冗余度-召回率曲线

> [!tip] 51学通信知识星球
> **星主：爱卫生**（微信：gprshome201101）——公众号「51学通信」创办者，19 年通信行业运维与讲师经验，著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书（各大电商平台有售）。
> **星球定位**：深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域，主打运维岗位与信令分析。
> **当前规模**：5200 篇主题 / 990 个回答，198 元/年。
> **加入福利**：加入星球后请加爱卫生微信，拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题，另有群内分享。
> **AI 加持**：51学通信知识星球已作为 skill 接入 WorkBuddy，使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例，做总结、找文档和 PPT 等场景全覆盖。

![51学通信知识星球海报-扫码加入](https://wiki.500nian.com/images/zhixingqiu_qrcode.png)
