乐于分享
好东西不私藏

AI Skill#12:Agent工具设计——让Agent调用又准又稳

AI Skill#12:Agent工具设计——让Agent调用又准又稳

上一篇聊了AI Agent——让AI自己拆任务、自己干活、不用你盯着。

但你真上手搭过一个Agent的话,大概率会发现一件事:

Agent翻车,十有八九不是模型不行,是工具烂。

就像你给米其林大厨配了一把生锈菜刀和一口漏底的锅。Agent手里的工具接口设计得稀碎,再聪明的模型也调不明白。

今天聊怎么把工具做得让Agent一调就对。

Agent用工具和人用工具,完全是两回事

你搜东西的时候会自己琢磨关键词、判断结果靠不靠谱、搜不到了换个词。这些全靠经验和直觉。

Agent没这个。它决定”用哪个工具””参数填什么”,靠的完全是你写的工具说明——name、description、parameters那几行字。

工具名字模棱两可?选错。参数说明有歧义?填错。返回格式不统一?解析崩了,后面全跟着崩。

人能容忍含糊,Agent不行。核心原则就一句:对机器友好,把歧义全干掉。

四条黄金法则

法则一:名字用”动词+宾语”,一看就知道干嘛

❌ 模糊命名
✅ 清晰命名
为什么更好
data_process search_customer_by_name
明确是搜索,对象是客户,条件是姓名
handle_order create_new_order
到底是创建、删除还是查询?说清楚
file_op upload_file_to_s3
操作+对象+目的地,一目了然
send send_email_to_user
发什么?给谁?全交代了

公式:动作 + 对象 + 限定条件

法则二:参数要有类型、示例和边界

“传一个日期”不够。什么格式?能不能空?范围多大?你不说,Agent就瞎猜。

错误示范:

{"date": "日期"}

正确写法:

{  "date": {    "type": "string",    "description": "查询日期,格式YYYY-MM-DD",    "required": true,    "example": "2026-04-21"  }}

五要素尽量写全:

  • type
     — string / number / boolean / array / object
  • required
     — 必填还是可选
  • format
     — 日期格式、枚举值、正则
  • example
     — 至少给一个具体例子
  • default
     — 可选参数的默认值

Agent读不懂你的潜台词,得全摆在明面上。

法则三:返回值必须结构化JSON

千万别返回一段话让Agent自己”读理解”:

"查询成功!客户张三,手机号13800138000,最近下单4月15日,金额299元。"

改成:

{  "status": "success",  "data": {    "name": "张三",    "phone": "13800138000",    "last_order": {"date": "2026-04-15", "amount": 299}  }}

错误也一样——别返回模糊的”操作失败”,给结构化错误码:

{  "status": "error",  "error_code": "NOT_FOUND",  "message": "未找到名为'李四'的客户"}

Agent看到 status: error 就知道该换方案了,不会傻傻重试。

法则四:一个工具只干一件事

见过那种”瑞士军刀”工具吗?一个 manage_user,传 action=create 就创建,传 delete 就删除,传 query 就查询。

对人还行,对Agent认知负担太重了——得先搞清四种模式的差别,再根据模式传不同参数。

直接拆:

工具
职责
create_user
创建新用户
delete_user
删除指定用户
update_user
更新用户信息
get_user
查询用户信息

每个工具参数独立、返回格式独立。Agent按需选,不用做二次判断。

实战:设计一套”客户营销”工具链

任务:”查一下上海VIP客户里最近30天没下单的,给他们发优惠券。”

Agent需要依次调三个工具:

工具1:search_customers — 按条件筛客户

{  "city": {"type": "string", "example": "上海"},  "level": {"type": "string", "enum": ["normal", "vip", "svip"]},  "inactive_days": {"type": "number", "example": 30}}

返回客户ID列表。

工具2:create_coupon_batch — 批量建优惠券

{  "customer_ids": {"type": "array", "items": "string"},  "coupon_type": {"type": "string", "enum": ["discount_10", "discount_20", "free_shipping"]},  "expire_days": {"type": "number", "default": 7}}

工具3:send_coupon_notification — 发短信通知

{  "customer_ids": {"type": "array", "items": "string"},  "message_template": {"type": "string", "default": "您有一张新优惠券待领取"}}

几个设计要点:三个工具各管各的,不是一个大而全的 handle_promotion。优惠券类型用枚举值,不让Agent自由发挥。有效期给了默认值,不传也能跑。工具1返回的ID直接喂给2和3,数据流一条线串下来。

常见翻车场景

翻车表现
根本原因
怎么救
选错工具
名字/描述太模糊
名称”动词+宾语”,描述写清适用和不适用场景
参数填错
格式没说清
加type、enum、example
死循环调用
错误信息不明确
返回结构化error_code
结果解析失败
返回格式不统一
所有工具统一JSON + status/data结构
调用顺序乱
依赖关系没说明
描述里写”需先调XX获取ID”

小练习

找一个你工作中常用的操作——查库存、查订单、发通知都行。按今天的四条法则写一个工具定义:

  1. 起一个”动词+宾语”的名称
  2. 每个参数写清type、description、example
  3. 定义好返回值的JSON结构
  4. 想想调用失败时错误信息怎么返回

写完发给ChatGPT或Claude,让它模拟调用一遍。如果它填错参数或理解偏了,说明你的定义还有歧义——继续改,这个过程本身就是最好的练习。

下一篇预告

下一篇聊 Agent记忆系统——Agent没有记忆,每次对话从零开始,跨对话全忘光。怎么给它装一个持久化的”大脑”?下篇拆。

关注「AI引路者」,每天用大白话帮你搞懂 AI。看完就能用。

📦 回复「AI模板」获取 30 个实用 Prompt 模板,直接复制就能用!