codeAgent 系列 第 4 篇,每天一个真实技术点,全部附源码。
仓库:https://github.com/Harvil1/codeAgent

一个被严重低估的成本大头
聊 Agent 成本,大家先想到历史消息。但还有一块常被忽略:工具的 schema。
模型不会"天生"知道怎么调你的工具——每个工具的名称、描述、参数 JSON Schema,都要放在每次请求的 tools 字段里发过去。30 个工具轻松吃掉两三千 token,而且每一轮都重发、每一轮都计费,还让模型在一堆不相关的工具里分心。
解法:餐厅套餐
我的做法在 toolsets.py,文件开头就把比方打好了:
"""(文件头注释)
像餐厅菜单:不把全部菜一次端上桌,而是按场景配成几套"套餐"(工具集),
每次只上一套。
为什么不全部端上来?因为每份工具说明书(schema)都要随每次请求发给
LLM、都花 token,可见性必须有人为控制。位于工具体系的可见性层,
被 model_tools.get_tool_definitions 调用。
"""
# 核心工具集:agent 默认装备,全部对 LLM 可见(浏览器不进 core,
# 需要时走 MCP 接外部服务——"能力放边缘"的设计原则)
_CORE_TOOLS = [
# —— 文件与命令 ——
"terminal", # 跑 shell 命令
"read_file", # 读文件
...
]
套餐登记表是一个普通字典,一眼看懂:
# 所有"套餐"的登记表:名字 → {描述, 包含哪些工具, 还捎带哪些别的套餐}
TOOLSETS: Dict[str, dict] = {
"core": {
"description": "核心工具集 - agent 默认装备",
"tools": _CORE_TOOLS,
"includes": [],
},
"minimal": {
"description": "最小工具集(适合子代理)",
"tools": ["terminal", "read_file"],
},
"bg": {
"description": "后台任务管理",
"tools": ["bg_start", "bg_status", "bg_result", "bg_list", "bg_stop"],
},
"team": {
"description": "Team 多 agent 协作",
"tools": ["team_send", "team_inbox", "team_members", ...],
},
...
}
三个值得抄的细节:
1. 子代理给 minimal。派出去干活的分身只带 terminal + read_file——它不需要全副武装,少给工具既省钱又防越权。
2. MCP 是"动态菜单":
# MCP = 接外部工具服务器的协议。这个套餐是"动态菜单":
# 固定清单为空,实际工具在连接服务器后现场登记(名字带 mcp__ 前缀,
# 服务器断线时对应工具自动隐身)
"mcp": {
"description": "MCP 外部服务器工具(动态发现,通过 check_fn 门控)",
"tools": [],
},
外部工具服务器连上时现场登记、断线自动隐身——工具清单跟着现实状态走,不是写死的。
3. 侦察兵有专用只读套餐。Explore 子代理(只看不改的分身)的套餐里全是 read_file / search_files / web_fetch 这类只读工具,从可见性层面就杜绝了它改东西的可能——比"提醒它别改"可靠一百倍。
效果量级
工具从 30 个砍到 10 个,schema 开销立减约三分之二;更重要的是小工具集显著降低模型"选错工具"的概率——省钱和提准是一枚硬币的两面。
小结
- 工具 schema 是每轮重发的隐性成本,几十个工具就是几千 token
- 套餐化:默认 core、子代理 minimal、场景包 bg/team、MCP 动态登记
- 可见性裁剪 = 成本优化 + 权限收窄 + 准确率提升,一石三鸟
下一篇:并行工具调用回喂的坑——Anthropic 凭什么把我拒了 400(附消息转换源码)。
仓库在这,注释全中文,欢迎 Star ⭐:https://github.com/Harvil1/codeAgent
标签:Agent Function Calling 成本优化 Python