想象这样一个早晨:你从网上买了一台漂亮的咖啡机,快递拆开,里面没有说明书。你盯着密密麻麻的按钮,只能凭感觉乱按——结果喷了一身热水。这时你才意识到,那份薄薄的说明书才是机器的灵魂。 AI Agent 也一样。它不像人那样“看着像就会用”,它调用你开发的工具时,唯一的信息来源就是你写给它的那份“说明书”——工具描述。描述里写清楚了:这个工具是干什么的、需要哪些参数、会返回什么结果、怎么调用才正确。描述写得清楚,Agent 一击即中;写得含糊,Agent 就像面对没有说明书的咖啡机,乱猜一气,频频报错。 这篇文章,就带你学会怎么写一份让 Agent“一看就懂、一调就对”的工具描述——一份完美的“AI 版说明书”。
工具描述是 Agent 调用的起点和地基。写好它,你开发的工具才能真正被大模型稳定、准确地使用,是 Agent 应用开发者最核心的基本功之一。
可视化演示
动态演示工具描述的核心机制,通过输入/处理/存储/输出四种模式展示关键概念与交互流程。
本节配有交互动效(进入视口后自动加载,约 3KB)。
工具描述:工具描述 工具描述结构规范与核心要素 参数类型定义与约束规范 核心机制可视化 工具描述整体架构与关键组件
一、描述结构四要素
拿到一份新家电的说明书,你最先翻到的一定是“产品功能”那一章:这台机器到底能干什么,适合什么场景。工具描述的第一段也是同理——先告诉 Agent“这个工具是做什么的、什么时候该用它”。比如“查询指定城市实时天气”,而不是“一个天气工具”,后者就像说明书上只写了“一台机器”四个字。
除了功能说明,一份完整的工具描述还包含另外三个层次:参数定义、返回格式、调用示例。这四件事对应 Agent 调用前的四个疑问:这个工具干嘛的?参数怎么传?结果长什么样?具体怎么调用?在 Function Calling(让大模型学会调用外部工具的机制)中,这些内容被组织成一个 JSON 结构,叫做工具 Schema——相当于把说明书整本压缩成一页纸。
就像说明书少了“注意事项”章节会让你踩坑,工具描述缺了任何一个要素,Agent 都会在某个环节卡壳。四要素齐了,这本“说明书”才算合格。
- 质量分数 Q代表一份工具描述的整体完整度,分数越高,Agent 调用越可靠。
- 功能覆盖度 C工具的用途、适用场景是否写得清楚明确。
- 参数完整度 P参数的类型、必填性、取值范围是否都交代了。
- 返回清晰度 R返回结构、字段含义、错误码是否一目了然。
- 示例丰富度 E是否提供了典型调用示例,让 Agent 有样学样。
- 权重 w每个维度的贡献比例,其中参数和示例通常权重最高。
二、参数定义与约束
说明书翻到“按键说明”那一页,每个按钮旁边都得标清楚:这是干什么用的、怎么按、能不能不按、按到什么程度算合适。参数的写法,就是把每个按钮的说明翻译给 Agent 听。
在工具 Schema 里,每个参数都要声明几点:类型是字符串还是数字,是否必填,取值范围有哪些,默认值是什么。比如“温度单位”这个参数,你写“字符串”还不够——Agent 还是会猜“摄氏度”“华氏度”“K”哪个才对;你要写明它只能取 celsius 或 fahrenheit 二选一。这就是给参数画了一个“圈”,把 Agent 的选择限制在合法区域内。
说明书里每个按键都标注清楚,“这是个旋钮,左转减小、右转加大,只能转到 1-5 档”——Agent 照着操作自然不出错。参数约束越明确,Agent 的“误操作”就越少。
- 合法取值域 D所有允许传入的参数值构成的集合,越界即为非法。
- 参数值 v用户或 Agent 实际传入的某个具体数值。
- 下界 min参数允许的最小值,比如“温度不低于 -50”。
- 上界 max参数允许的最大值,比如“温度不高于 60”。
- 集合约束如果描述里不写范围,Agent 会以为任何值都合法,传一个荒谬的数字进来。
三、返回格式规范
家电说明书通常会有一个“指示灯说明”小表格:绿灯常亮表示正常运行,红灯闪烁表示故障,不同故障还有对应编号。工具描述里的返回格式说明,就是给 Agent 的“指示灯说明”。
Agent 调用工具后拿到返回数据,它需要判断:这次调用到底成功没有?数据里哪个字段是温度、哪个是天气?如果失败了,该如何向用户解释、该不该重试?如果描述里只说“返回查询结果”,Agent 面对一团乱麻,只能瞎猜——就像看说明书找不到“红灯闪两下是什么意思”。所以返回结构要写清楚:成功时返回哪些字段、字段类型是什么、失败时错误码和错误信息长什么样。
就像指示灯“一绿一红”让你一眼知道机器状态,清晰的返回格式让 Agent 拿到结果后能果断决定下一步:解析数据、向用户汇报,还是礼貌地道歉重试。模糊的返回说明,等于把 Agent 扔进一个没有指示灯的机房。
- 返回结果 resp工具每次执行后返回给 Agent 的数据包。
- 成功分支 ok结构固定且字段完整,Agent 可直接解析使用。
- 失败分支 err一旦失败,返回体必须进入错误通道。
- 错误码 code机器可读的数字编号,如 404 表示“城市不存在”。
- 错误信息 message人能看懂的描述,Agent 可以原样转述给用户。
四、调用示例编写
说明书里最受欢迎的永远是“快速上手”那一页:三步带你把咖啡拉花做出来。纯文字描述再准确,也不如一个完整例子让人醍醐灌顶。对 Agent 来说,这个“例子”就是调用示例。
调用示例不是摆设,它相当于一种“模仿学习”素材——学术上叫 few-shot(给模型看几个输入输出对,它就能照着规律举一反三)。比如描述“查询天气工具”时附上一个示例:传入 {"city":"北京"},返回 {"temp":18,"weather":"晴"}。Agent 看了这个例子,就知道了三件事:参数写成什么格式、返回长什么样、字段代表什么含义。示例越贴近真实场景,Agent 学得越快。
图文并茂比通篇理论更让人心安,Agent 也一样。多写几个好例子,胜过在文字描述里反复强调“请一定传对参数”——行动示范比说教管用。
- 成功概率 PAgent 在一次真实调用中做对全部步骤的可能性。
- 条件分支 E工具描述中附带了典型调用示例的情况。
- 条件分支 ∅描述中没有任何示例的“裸奔”情况。
- 不等关系示例对成功率有明显增益,本质是让 Agent 少走猜弯路。
五、常见描述错误
你一定见过这种“翻车说明书”:写着“按任意键继续”,其实只有底部小按钮可用;或者首页印满品牌故事,关键参数却藏在角落里。工具描述里的错误,往往也长这样。
最常见的四种坑,踩中任何一个都会让 Agent 抓狂。第一种是表述模糊——“处理数据”这种话等于没说,处理什么数据、怎么处理、达成什么效果,一概不知,Agent 只能干瞪眼。第二种是参数遗漏——没写类型、没标必填、没给范围,Agent 猜一个传进去,工具当场报错。第三种是过度冗长——把背景故事、实现原理全塞进来,真正关键的信息被淹没,大模型读起来反而抓住了错误重点。第四种是参数幻觉——描述里写的参数,工具后端根本没有实现,Agent 照描述传参,就像说明书承诺“支持语音控制”而机器压根没有麦克风。
一份翻车的说明书会被用户扔进垃圾桶,一份翻车的工具描述则会让 Agent 反复报错、让用户反复重试。写描述时,多问自己一句:“这句话,另一个完全不知情的人能看懂吗?”能,才过关。
- 信息熵 H描述文本带给 Agent 的不确定程度,熵越高越迷茫。
- 概率 pᵢAgent 猜测“描述含义是第 i 种可能”的概率,可能越多越分散。
- 求和符号把所有可能情况的不确定性累加起来。
- 对数项单一可能(p 接近 1)时对数值为 0,熵最小,描述最明确。
六、最佳编写实践
顶级说明书作者有个共同点:他们永远蹲在“第一次用这台机器的人”的视角写,绝不假设读者懂任何背景。给 Agent 写工具描述,请把自己想象成在给一个空白的机器人讲步骤。
基于这个视角,有四条心法值得内化成习惯。第一,站在 Agent 的角度——描述要回答“什么情况下用我”,而不是炫耀“我有多强大”。第二,简明扼要——每句话都有信息量,不写废话,不被冗余淹没重点。第三,持续迭代——工具描述不是一锤子买卖,Agent 在真实场景里调用失误了,就回来打磨措辞,像产品经理迭代文案一样。第四,自动化测试验证——准备一批典型问题,每次改完描述就跑一遍回归,看 Agent 是否都能正确触发工具,用数据说话。
说明书大师不会写完就撒手不管,他会找几个真正的用户试读,看哪里还会按错,然后反复修订。工具描述同样需要“试读”——不过这次的读者是 Agent,而“试读报告”就是那一条条真实调用日志。把描述当成产品来打磨,Agent 才会越用越顺手。
- 平均分数 Score描述质量在测试集上的最终量化结果。
- 测试数量 N准备的真实调用测试用例总数。
- 求和累加逐个统计 N 个用例的通过情况。
- 示性函数 𝕀用例通过时记 1,失败记 0,像考官打勾画叉。
AI 应用场景
场景一:智能客服的订单查询助手
阶段:工具调用与信息检索
解决的问题:传统客服机器人只能回答话术库里的固定问题,遇到“我的快递到哪了”这类需要查实时数据的问题就无能为力。通过一个“查询订单物流”工具,配上清晰的工具描述——参数 order_id(字符串、必填、11 位数字)、返回结构(状态码 + 物流轨迹数组),Agent 就能准确调用查询接口并把结果转述给用户。
具体案例:用户在淘宝式电商平台问“订单 202501011234 到哪了”,Agent 看到工具描述中写明参数必填和格式要求,自动从对话中提取订单号并调用工具,返回“已到本市中转站”,用户无需再打人工客服。
场景二:数据分析助手的 SQL 查询工具
阶段:意图理解与结构化查询生成
解决的问题:业务人员不懂 SQL,又需要从数据库里取数。给 Agent 配一个“表格查询工具”,描述里写清参数 table_name 的可选枚举值(只能查白名单内的几张表)、filters 的 JSON 格式和示例,Agent 就能把自然语言“上个月华东区销售额”翻译成正确的查询参数。
具体案例:数据分析师说“帮我看下 5 月华东区订单总量”,Agent 依据工具描述中枚举约束,锁定 table_name="orders"、filters={"region":"华东","month":5},一次调用成功返回聚合结果,全程不需要人写一行 SQL。
Python 演示
import jsonfrom typing import Any, Dict, List REQUIRED_FIELDS = ["name", "description", "parameters"] def validate_tool_description(schema: Dict[str, Any]) -> List[str]: """检查工具描述是否包含 Agent 调用所需的必要信息.""" errors = [] for field in REQUIRED_FIELDS: if field not in schema: errors.append("缺少必要字段: " + field) if "parameters" not in schema: return errors params_obj = schema["parameters"] if params_obj.get("type") != "object": errors.append("parameters.type 应为 object") props = params_obj.get("properties", {}) required_list = params_obj.get("required", []) for name, meta in props.items(): if "type" not in meta: errors.append("参数 [" + name + "] 缺少 type") if "description" not in meta: errors.append("参数 [" + name + "] 缺少 description") for name in required_list: if name not in props: errors.append("required 中声明了未定义的参数 [" + name + "]") if "examples" not in schema or not isinstance(schema["examples"], list): errors.append("建议提供调用示例 examples, 帮助 Agent 理解用法") return errors def print_report(schema: Dict[str, Any]) -> None: """打印可读的检查报告.""" errors = validate_tool_description(schema) print("工具: " + schema.get("name", "(未命名)")) if errors: for e in errors: print(" [x] " + e) else: print(" [ok] 工具描述合格, Agent 可以放心调用!") GOOD_SCHEMA = { "name": "query_weather", "description": "查询指定城市当前天气状况, 返回温度与天气类型.", "parameters": { "type": "object", "properties": { "city": {"type": "string", "description": "城市名称, 例如: 北京, 上海."}, "unit": { "type": "string", "enum": ["celsius", "fahrenheit"], "description": "温度单位, 默认 celsius." } }, "required": ["city"] }, "examples": [ {"input": {"city": "北京"}, "output": {"temp": 18, "weather": "晴"}} ]} BAD_SCHEMA = { "name": "do_stuff", "description": "处理数据.", "parameters": { "type": "object", "properties": { "stuff": {"description": "要处理的东西"} } }} if __name__ == "__main__": print_report(GOOD_SCHEMA) print_report(BAD_SCHEMA)
REQUIRED_FIELDS = [...]定义工具描述必含的首要字段,相当于说明书不能缺封面。for field in REQUIRED_FIELDS:逐一核对必要字段是否都存在。params_obj.get("type") != "object"参数容器必须是 object 类型,否则 Agent 无法按名取参。if "type" not in meta:每个参数都必须有类型标注,缺失则提示。"type": "string", "enum": [...]用枚举约束把参数“圈”进合法范围。if "examples" not in schema缺少调用示例时给出温和提醒,鼓励提供示范。print_report(GOOD_SCHEMA)用合格样例验证检查器输出 “合格”。print_report(BAD_SCHEMA)用模糊描述样例展示如何揪出问题。
常见误区
误区觉得工具描述要“字多才专业”,把背景故事、实现原理、团队历史全写进去,以为大模型读得越多懂得越多。
正解大模型读描述时会平均分配注意力,冗余信息会稀释关键内容,甚至让 Agent 抓住一个无关细节去执行。好的描述像机场指示牌:字少、信息密度高、指向明确。能一句话说清的,绝不写两段。
为何常见:人们习惯用“篇幅”衡量用心程度,忘了描述的目标读者是追求效率的 AI,而不是逐字品读的人类。
误区认为只要标注了类型,Agent 就能正确传参,比如日期参数写 `string` 就完了。
正解string 只说了“这是字符串”,没说格式。日期到底是 2025-01-01 还是 20250101?枚举值有哪些?范围多大?描述里必须继续写清 format、enum、min、max 等约束,否则 Agent 只能自由发挥,传个牛头不对马嘴的格式回来。
为何常见:人一看“字符串”就自然知道写什么,误以为 Agent 也有这种常识,忽略了它本质是一个逐字读说明书的呆板执行者。
误区觉得只要工具实现了,返回什么交给 Agent 现场发挥就行,不写返回结构也不写错误码。
正解Agent 解析一行不知道结构的 JSON,就像看没有图例的仪表盘——每个数字都认识,但不知道含义。成功时字段是什么类型,失败时错误码和 message 在哪,都必须写清楚,Agent 才能决定继续解析还是转人工。
为何常见:开发者自己熟悉接口返回格式,产生了“别人也懂”的错觉,忘记了 Agent 唯一的了解渠道就是描述文本。
误区认为功能说明和参数定义写全了,调用示例是锦上添花甚至多此一举。
正解示例是给 Agent 的“标准答案示范”,质量再高的文字描述也替代不了。一个真实的输入输出对,同时示范了参数拼接格式、返回体结构和字段用法,等于给 Agent 画了一张完整路线图,成功率显著提升。实践中缺示例的描述,Agent 首次调用往往要试错好几次。
为何常见:人习惯了抽象理解,但机器学习本质上更依赖具体样例,写描述的人容易低估“照葫芦画瓢”的力量。
面试题
Q1. 工具描述在 AI Agent 中扮演什么角色?
- A.让用户界面看起来更美观
- B.帮 Agent 理解工具的使用方法← 正确答案
- C.让程序运行速度变得更快
- D.自动修复代码中各种缺陷
答案:B。工具描述是给 Agent 的“说明书”,核心作用是让 Agent 理解工具的功能、参数和返回格式。界面美观、运行速度、代码修复都和描述无关。Agent 不是靠看界面猜功能的,它只靠描述文本。
Q2. 参数定义中 type 字段负责什么?
- A.声明参数的数据类型例如 string← 正确答案
- B.设置按钮显示时的颜色值
- C.规定页面元素的排列顺序
- D.决定工具返回多少条结果
答案:A。type 声明参数的数据类型,如字符串、整数、布尔值,这是参数约束的第一道“圈”。它不负责界面样式、页面布局或返回数量,那些都由工具自身逻辑决定。
Q3. 调用示例相当于说明书里的什么?
- A.封面上的出版社信息
- B.演示操作步骤的图文教程← 正确答案
- C.售后服务电话的号码
- D.包装箱上的生产日期
答案:B。调用示例好比说明书里的“快速上手”图文教程,给出输入和对应输出,Agent 照着例子就能学会怎么用。出版社信息、售后电话、生产日期都和“教你怎么用”无关。
Q4. 工具描述没有写清返回格式,会导致什么?
- A.Agent 无法解析结果并决定下一步← 正确答案
- B.工具执行速度大幅下降变慢
- C.服务器内存直接溢出崩溃
- D.用户无法登录管理后台
答案:A。返回格式是 Agent 判断成功失败、提取数据的依据。没写清返回结构,Agent 拿到 JSON 也只能干瞪眼。它不影响执行速度,也不会导致内存溢出或登录问题,那些是工具实现层面的事。
Q5. “参数幻觉”指的是哪种现象?
- A.模型想象出根本不存在的参数并传参← 正确答案
- B.参数描述字体太小导致看不清楚
- C.参数默认值为空字符串没有填
- D.参数列表顺序随机变换不固定
答案:A。参数幻觉指描述里写了后端不存在的参数,或描述太模糊让模型脑补出无中生有的参数,传过去后工具直接报错。它和字体、默认值、列表顺序都无关,是描述与实现脱节导致的。
Q6. 以下哪项最符合高质量工具描述的风格?
- A.处理一些用户提交的数据
- B.查询城市实时天气并返回温度← 正确答案
- C.做各种各样有用的事情
- D.功能很多,自行查看文档吧
答案:B。高质量描述要具体到“做什么、输入什么、输出什么”。“查询城市实时天气并返回温度”信息密度高、边界清晰。其余选项笼统含糊,甚至把理解成本推给 Agent,都属于典型反面教材。
Q7. 必填参数漏写在 required 列表中会怎样?
- A.Agent 认为可选取而漏传参数← 正确答案
- B.参数名自动变成大写字母
- C.工具描述无法通过格式校验
- D.参数值会被强制加密存储
答案:A。required 列表是 Agent 判断“哪些参数必须传”的唯一依据。漏写了,Agent 就以为该参数可选,可能不传,工具执行时因缺参报错。它不会改大小写,也不会触发格式校验或加密,那些不在描述语义范围内。
Q8. 迭代工具描述时,最可靠的做法是什么?
- A.每次修改后用真实用例回归验证← 正确答案
- B.让 UI 设计师检查文案是否美观
- C.把描述加密后存进远程数据库
- D.只在发布新版本时简单看一眼
答案:A。描述改的是“文字”,影响的是“调用行为”,所以必须用真实用例去测回归效果。美观审查、加密存储、发布时看一眼都无法验证 Agent 是否真的调用正确,只有跑用例才行。
Q9. 一份完整工具描述应包含哪些部分?
- A.工具功能用途的说明← 正确答案
- B.参数类型与约束的定义← 正确答案
- C.返回数据的结构和错误码← 正确答案
- D.公司内部财务审计报表
答案:ABC。四要素中的功能、参数、返回是必备项,加上调用示例更佳。财务审计报表和 Agent 调用毫无关系,属于把无关内容塞进描述的反面示范。
Q10. 以下哪些属于工具描述的常见编写错误?
- A.功能描述过于笼统模糊← 正确答案
- B.参数缺少类型与取值范围← 正确答案
- C.示例与真实返回结构不一致← 正确答案
- D.描述文件采用 JSON 结构存储
答案:ABC。笼统描述、参数缺约束、示例与真实返回对不上,都会误导 Agent,属于高频错误。用 JSON 承载描述是行业标准做法,是正确的工程实践,不是错误。