上一篇讲了野行 Y 的循环。循环里,模型每一轮都在做同一个决定:下一步调哪个工具。这篇就讲工具。

一个 Agent 有多大本事,说到底看它手里有哪些工具。模型再聪明,它能对真实世界做的每一件事,都得穿过工具这道门。搜一个地方、算一段路、查一班航班、把行程提交出去,这些模型自己都干不了,它只能决定调哪个工具,让工具去做。所以设计一个专用 Agent,工具怎么定义,直接框定了它的能力上限。

先看野行 Y 里一个工具长什么样,小到有点朴素:一个名字(模型看到的),一段描述(什么时候、怎么用它),一组参数(模型要填什么),一个真正干活、返回一段文字的函数。就这四样。

tools.py 开头有句注释我挺喜欢:循环不关心一个工具底下是个本地 Python 函数、一次联网抓取、一个命令行子进程,还是一个远程服务。对循环来说,它们全长一个样:名字、描述、参数、返回。循环只做一件事,把工具清单交给模型,模型挑一个、填好参数,循环执行、把返回塞回上下文。

这个设计的好处是,能力可以一直往上加,循环一行都不用改。这是从 Claude Code 那儿学来的最值钱的一个抽象:工具是能力的最小单位,也是唯一单位。

那问题就来了:一个专业领域的 Agent,到底该有哪些工具?

这是做专用 Agent 最核心的一步,我觉得也是最容易被跳过的一步。工程师的本能是先搭架构,可这里第一件事,得先回答另一个问题:把「排一趟自驾」这件模糊的事,拆成哪几个说得清、做得到的动作。

Claude Code 把「写代码」拆成了读文件、改文件、跑命令、搜代码这几个动作,凑一起就是写代码的全部原子操作。那「排一趟自驾」拆开是什么?野行 Y 拆出来是这么一组:搜目的地、核实路况、估驾时、选车、查真实机酒、跟用户确认、提交行程。

这组动作,是走一遍真实的用户旅程摸出来的。一个人要自驾川西,真实要经历的是:先定个大方向,上网查查这条线靠不靠谱、什么季节去、有没有封路,掰着指头算每天开多久、住哪,琢磨开什么车,订机票酒店,出发。这中间每一个「他要做的判断」,就是一个候选工具。把这条旅程摊开,工具集自己就浮出来了。

这也是通用 Agent 给不了的东西。通用大模型不知道「自驾得先算驾时、防止一天开太远」,因为它没走过这条领域旅程,没把「算驾时」认成一个必须有的动作。它有个博学的脑子,可缺这套领域动作的手脚。你做专用 Agent 的价值,一大半就在于把这套手脚设计出来、装上去。

工具拆得多了,我发现一件让人安心的事:它们翻来覆去就落在五种模式上。搜索、估算、推荐、核实、选择。认得这五种,设计任何新工具都有章可循。

搜索,比如从目的地库里按地貌筛候选。它干的是从你自己攒的一个库里,挑出一组带结构化属性的候选。要点是返回属性、别返回散文:给模型「稻城亚丁,海拔 4700,独特度 9」,比给它「稻城亚丁是个很美的地方」有用一百倍,因为模型要拿这些属性接着比较和筛选。

估算,比如算一段路的里程和驾时。它的实现朴素得可爱:两点直线距离,乘一个 1.35 的绕路系数,再除以每小时 55 公里的山路时速。这不精确,它返回里自己都老实标着「仅供每日可行性粗判」。可它够用了,因为它的用途是让模型判断「这天是不是排太赶」,一天估出来要开十一个小时,模型就知道该拆成两天。这个判断,一个粗估就够,用不着去接一个精确路由 API。估算类工具最容易过度设计,一上来就想接地图算精确路线,其实精度匹配用途就行,真正精确的里程留到最后出报告再补。

推荐,比如按路况、人数、预算、偏好选车。这是五种里最重的一种,因为它内部藏着真领域知识。野行 Y 的选车工具,底下是一个 193 款车的自建车型库,它把「川藏318 高原 烂路涉水」翻译成一个越野需求分,再叠加人数、预算、出行性质(带老人就回避颠簸的硬派越野),算出推荐和理由。要点是输出必须带理由:「推荐赛那,因为七座够坐、带老人不颠」,理由让推荐可信、也让用户敢照着做。

核实,比如查一个垭口十月封不封路。搜索是从我的库里挑,核实是去外面的世界确认。它专门对付一件事:防止模型编造。模型脑子里「觉得」某个景点存在、某条路能过,可它会记错、会过时、会幻觉。核实工具逼它把「觉得」变成「查过」。这类工具的描述里我写死了一句「查了不写等于没查」,查到的结论必须落进行程、让用户看得到。

选择,比如把真实航班原样摆给用户挑。有些决定不该 Agent 替用户做,选哪班航班、住哪家酒店。这类工具查出真实候选,原样交给用户拍板。它有条铁律:模型全程不许碰关键数据。航班号、价格从查到落地一直待在代码里,模型只负责发起查询和透传展示。因为一旦让它经手价格,它就可能顺手改一个、编一个。

还有个细节想单独说一句,关于工具的描述。一开始我把所有规则都堆在一个巨大的 system prompt 里,搜索要怎样、查了要写进哪、一批点要并行别一个个查,写着写着涨到七十行,又贵又没人愿意碰,而且每一轮对话都得把这七十行重新喂给模型。后来我把这些规则下沉进了各个工具自己的描述里,system prompt 瘦到二十几行。关于 web_search 的规则,只有模型在盘算要不要调 web_search 时才需要看到,写在工具描述里,它选这个工具那一刻规则就在眼前,就近、省钱、还内聚。一个好工具是自文档化的,模型不用读一篇手册才会用它,看名字、描述、参数就够了。

说回来。工具是 Agent 的手脚。把一个专业领域拆成一张动作词典,再认着搜索、估算、推荐、核实、选择这五种模式,把每个工具设计好,这个 Agent 能干什么、干得多专业,基本就定了。

而每个工具查回来、算出来的东西,最后都要塞进模型的上下文,好让它做下一步判断。可上下文是有限的,塞多了它又贵又慢、还会变糊涂。下一篇,讲怎么经营这块上下文:放什么、不放什么、太长了怎么压。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐