
我以前写 Agent 工具说明有个很朴素的习惯:能想到的情况都塞进去。
“搜索帖子”不只负责搜索,还可以浏览、检查草稿、为编辑做准备;“读取帖子”也能查询作者、检查媒体、准备更新;“修改帖子”当然又要提到正文、封面、搜索结果和发布。每段单独看都很负责,六个工具放在一起,像六个人同时说“这事我也能帮一点”。
线上偶尔选错工具时,我还会继续补说明。结果字越来越多,边界越来越薄。
这次我没有直接拿一个大模型跑几十遍,因为那样很容易把采样波动、模型版本和提示词改动混在一起。我先做了一个笨得多、但完全可复现的路由代理:把用户提示和每个工具说明切成中文字符、连续汉字二元组与英文 token,计算词面重叠分数,分最高的工具胜出。
它当然不是 LLM,也不能代表真实 function calling 的准确率。它只回答一个小问题:当工具说明大量重复“搜索、读取、修改、正文、媒体、发布”这些词时,单靠描述提供的区分信息会变成什么样。
测试集冻结了 24 条提示,六个工具各 4 条:
post_id 读取一篇;media_id;我没有在跑完后删题,也把每条预测和第二名一起写进了 results.json。
第一版六段说明合计 543 个字符。它们总爱顺便提到别的工具负责的阶段,例如搜索工具说“可为后续修改或发布准备候选”,修改工具又说“可以保存搜索或评论之后的新内容”。在词面选择器里,24 题只对了 12 题。
第二版总共 182 个字符,少了 66.5%。我主要做了三件事:
post_id”;同一批题重新跑,答对 23 条,只剩“给我列出讨论 RAG 的几篇内容”被评论工具抢走。原始长说明错 12 次,短说明错 1 次。

这个差距不能外推成“真实 Agent 准确率提高 45.8 个百分点”。选择器只认词面,恰好会放大描述重叠的问题;真实模型能理解语义,也可能从对话上下文修正。但它至少证明了一件值得继续查的事:长说明并不自动携带更多有效路由信息,很多字只是在多个工具之间复制噪声。
精简最容易走到另一个极端:把说明写成“搜索帖子”“更新帖子”四个字,让所有限制都靠模型猜。我这次保留了会改变调用决定的内容。
比如读取和修改都必须有 post_id;新建草稿明确不碰已有帖子;上传工具返回的是 media_id,并不直接修改封面。至于“上传图片后可以继续编辑文章”“搜索结果可用于发布准备”,这些是真的,却不属于当前工具的选择边界。我把它们移到 Agent 的流程说明或工具返回值里,而不是在每个工具描述里重复。
我现在判断一句话是否该留,会问:删掉它以后,模型会不会因此选择另一个工具、漏填一个必需参数,或做出不可逆动作?如果都不会,它大概率只是背景介绍。
短说明剩下的那次错误没有继续靠塞关键词修。提示是“给我列出讨论 RAG 的几篇内容”,正确答案是搜索帖子,选择器却因为“讨论”二字偏向评论列表。
真实系统里可以在搜索说明中再补“多篇内容”,也可以让路由先识别对象是帖子还是评论。但对这个小实验,我更愿意把它留下。24/24 很好看,却会让人误以为这套二元组打分真的能做代理路由。23/24 更接近它的用途:用最低成本找出说明之间明显的词汇污染,再把候选版本交给真实模型评测。
只改描述还不够。若工具名分别叫 find_content、get_content 和 query_content,模型第一眼看到的区分仍很小;如果三个 schema 又都塞进一组可选的 id、query、content,短说明也救不了含糊的参数面。我后来把名字统一改成“动词加对象”,并让读取、更新只接收明确的 post_id,搜索则接收 query 与可选筛选条件。
错误信息同样属于工具边界。读取工具收到不存在的编号时,返回“帖子不存在”和原编号;更新工具缺少正文时,明确指出缺哪个字段。若只抛一个通用失败,Agent 往往会换工具重试,把一次参数错误演成连续误调用。精简描述省下来的字,不该用含混的 schema 和错误返回再补回去。
真正接模型测试时,我还会把“选对工具”和“把任务做完”分开计数。第一步选对、参数填错,和第一步选错但随后自行修正,是两种完全不同的失败。除了准确率,还要记录无效调用次数、修复轮数和是否触发写操作。这样才能知道短说明带来的改善究竟发生在路由、填参,还是只让流程看上去更短。
下一步如果接到生产 Agent,我会固定模型版本、温度、系统提示和完整工具 schema,至少重复跑多轮,再观察工具选择、参数正确率和最终任务成功率。这里的结果只是一轮前置消融,不是模型评测。
不过它已经帮我改掉一个习惯。工具说明无需写成产品说明书,把所有可能性写全也不等于负责。它更像岔路口的路牌:此刻最重要的是让人看清该走哪条路,也看清哪些路与眼前的事无关。

文章问答
她会先读这篇文章,再安静地回答你的问题。可以继续追问。
加载中…
登录后参与讨论