一个订单查询工具返回 40 多个字段。代理处理退货请求只需要 5 个。3 次调用后,上下文快满了——78% 被 internal_notes、warehouse_code、supplier_contact 这些代理从来不用的无关字段占据。
在追加到上下文之前过滤工具输出只保留相关字段。任务完成率从 52% 跳到 94%。
数据
500 个代理会话,平均 8 次工具调用:
| 方法 | 每次调用 token | 工具总 token | 剩余上下文 |
|---|---|---|---|
| 完整输出(40+ 字段) | ~2,000 | 16,000(80%) | 4,000 |
| 过滤后(5-8 字段) | ~300 | 2,400(12%) | 17,600 |
过滤每个会话节省 13,600 token——总上下文预算的 68%。代理从耗尽前 4.2 次工具调用变成了 11.8 次。
怎么过滤
编程式字段过滤 — 在把工具输出追加到上下文之前,只提取当前任务需要的字段。退货请求只需要:order_status、order_date、items、total、return_eligible。丢掉其他 35 个以上的字段。
这比模型摘要更可靠,因为摘要可能概括掉精确值(“$127.50” → “退款金额”)。编程式过滤保留精确数据——只移除无关字段。
上下文感知过滤 — 不同任务类型需要同一工具的不同字段。退货需要状态和退货资格。账单需要支付方式和发票。物流需要追踪号和配送中心。在配置中按任务类型定义字段相关性规则——过滤自动适配,不需要改代码。
PostToolUse hook — 在工具输出进入对话上下文之前拦截。Hook 应用过滤规则,只返回相关子集。
“以后可能用得到”的争论
有同事提议保留完整输出,因为”模型可能需要任何字段来回答我们没预料到的后续问题。”
这是用一个确定的问题(4 次调用后上下文耗尽)换一个假设的问题(需要意外的字段)。解决方案:现在激进过滤,以后真需要意外字段时重新调用工具。一次额外的工具调用比在上下文中永久存储 35 个无关字段便宜多了。
什么不管用
更大的上下文窗口。 推迟问题而非解决问题。每次调用 40 多个字段在任何窗口大小下都浪费上下文。
模型生成的摘要。 摘要可能丢失工具输出中的精确值(金额、ID、日期)。编程式过滤以确定性方式保留精确数据。
限制工具调用次数。 限制的是代理的能力。问题在于每次调用的输出大小,不是调用频率。
指望模型忽略无关字段。 上下文中的所有内容都影响模型的注意力。无关字段不会被可靠地忽略——它们稀释了对相关数据的注意力。在插入上下文之前移除它们是唯一可靠的方法。
一句话总结: 在追加到上下文之前过滤工具输出只留相关字段——这释放 68% 的上下文预算,多出 3 倍工具调用空间,任务完成率从 52% 提到 94%。