一个工具描述写得含含糊糊的 AI Agent,在该查订单时却去退了款、参数还填错,把工具用得乱七八糟:一次工具定义不清的深度复盘

给客服 Agent 配了一堆工具,它表现却飘忽不定:问订单到哪了,有时查物流有时查订单、偶尔还调了退款,参数还把订单号填进用户 ID 的位置。换更强的模型也没根治。根因是工具描述写得含糊雷同(refund 只写'订单处理')、参数只写 id: string 没说是订单号还是用户 ID——而大模型完全依据工具的描述和参数 schema(看不到实现)来选工具、填参数,说明书烂它只能连蒙带猜。本文讲透 Agent 如何选工具填参数,给出名字清晰+描述写清做什么/何时用/何时不用+参数说明到位+职责单一+副作用标注+参数校验的正解,梳理工具设计常见坑,最后落到'工具定义是 Agent 关键基础设施、清晰表达是 AI 时代的硬能力、Agent 出错先反求诸己'的认知。

一个工具描述写得含含糊糊的 AI Agent,在该查订单时却去退了款、参数还填错,把工具用得乱七八糟:一次工具定义不清的深度复盘

那个问题是 Agent 上线后行为"飘忽不定"暴露出来的:我们给一个客服 Agent 配了一堆工具——查订单、查物流、申请退款、修改地址……可它的表现极不稳定:用户问"我的订单到哪了",它有时去查物流(对)、有时却去查订单详情(不太对)、偶尔还调用了"申请退款"(完全错!);更离谱的是,它调工具时参数经常填错——把订单号填进了用户 ID 的位置。我一开始怀疑是模型不行,换了更强的模型,好了一点但还是会错。直到我回头仔细看我给这些工具写的描述(description)和参数说明,才恍然大悟,后背发凉:我把工具的描述写得含含糊糊。比如"申请退款"工具,我的描述只写了"处理订单相关请求"——这描述既不说明它具体是干嘛的、也没说什么时候该用它,模型看了根本分不清它和"查订单"的区别,于是乱选;参数也只写了 id: string,没说这个 id 到底是订单号还是用户 ID,模型只能瞎猜,自然填错。问题的根,不在模型"不够聪明",而在我给它的工具"说明书"写得太烂——大模型是完全依据我写的工具描述和参数说明,来决定"用哪个工具、怎么填参数"的;我把说明书写得模糊,它就只能连蒙带猜这篇就把这次"Agent 工具定义不清"的坑,从头到尾复盘一遍。

故障现场:含糊的工具描述和参数说明

问题代码,是一组描述写得含糊、模型无从分辨的工具定义:

# ✗ 出问题的工具定义: 描述含糊、参数说明不清
TOOLS = [
    {
        "name": "get_order",
        "description": "处理订单相关请求",      # ✗ 太含糊! 到底是查订单还是干嘛?
        "parameters": {"id": {"type": "string"}}   # ✗ id是订单号? 用户ID? 没说!
    },
    {
        "name": "refund",
        "description": "订单处理",              # ✗ 和上面的描述几乎一样, 模型分不清!
        "parameters": {"id": {"type": "string"}}   # ✗ 同样没说id是什么
    },
    {
        "name": "get_logistics",
        "description": "物流",                  # ✗ 就俩字, 模型不知道什么时候该用它
        "parameters": {"id": {"type": "string"}}
    },
]

# 结果:
# - 用户问"订单到哪了" → 模型在 get_order/get_logistics/refund 之间【乱选】
#   (描述都含糊雷同, 它分不清哪个对应"查物流");
# - 偶尔选了 refund(退款)→ 灾难!(它以为"订单处理"可能就是用户要的);
# - 参数 id 填错: 把订单号填进本该是用户ID的位置(描述没说清id是什么)。

# 为什么会这样:
# - 大模型决定"用哪个工具、怎么填参数", 【唯一的依据】就是你提供的:
#   工具的 name、description、参数的 schema 和说明;
# - 这些就是模型眼里这个工具的"说明书"——它【看不到工具的代码实现】, 只能靠这份说明书理解;
# - → 说明书写得含糊/雷同/不清, 模型就【无从准确判断和填写】, 只能连蒙带猜 → 乱用工具。

# 关键: Agent靠"工具的描述和参数说明"来决定用哪个工具、怎么填参数; 描述含糊/参数不清,
#       模型就会选错工具、填错参数——这不是模型笨, 是你给的"工具说明书"太烂。

第一次意识到是"我写的说明书太烂"时,我又懊恼又恍然:"我一直怪模型选错工具,原来是我没把工具讲清楚,它怎么可能选对?"这个坑最容易被归错因的地方在于:当 Agent 表现不好时,我们第一反应总是"模型不够强",于是想着换更贵的模型、调 prompt;却常常忽略了一个更根本的原因:我们给模型的"工具定义/信息"本身就是模糊、错误、或不足的。模型再聪明,也只能基于你给它的信息做判断;信息(工具说明书)烂,再强的模型也救不回来下面就来拆解,工具定义对 Agent 有多关键、该怎么写好。

第一件事:搞懂 Agent 是怎么"选工具、填参数"的

我认真梳理了 Agent 调用工具的机制,才彻底理解工具定义为什么这么关键。

Agent 怎么决定"用哪个工具、怎么填参数"?

【核心: 模型只能看到工具的"描述+参数schema"(看不到实现); 它完全依据这份"说明书"来选工具、填参数】

1. Agent调用工具的流程:
   - 你把所有工具的 name + description + 参数schema, 一起告诉模型;
   - 模型根据【当前任务】和【这些工具说明书】, 判断"该用哪个工具、参数填什么";
   - 它输出一个"工具调用"(工具名 + 参数); 你的代码再去真正执行这个工具。

2. 关键: 模型【只能看到说明书, 看不到工具的代码实现】:
   - 它不知道 get_order 内部到底查了什么, 它【只知道你写的那句description】;
   - → 你的 description 和参数说明, 就是模型理解这个工具的【全部信息来源】;
   - → 说明书的质量, 直接决定模型能不能选对、填对。

3. 说明书烂会导致:
   - 描述含糊("处理订单") → 模型不知道这工具具体干嘛、什么时候用;
   - 多个工具描述雷同 → 模型分不清它们的区别, 乱选;
   - 参数说明不清(id没说是啥) → 模型不知道填什么、填错;
   - 缺少"何时使用"的指引 → 模型在多个工具间犹豫、选错。

4. 类比: Agent就像一个【新来的、很聪明但对你业务一无所知的实习生】;
   - 你给他一堆工具(API), 他全靠你写的"工具使用手册"来决定用哪个、怎么用;
   - 手册写得清楚(每个工具干嘛、何时用、参数啥意思、给例子)→ 他用得又快又对;
   - 手册写得含糊雷同 → 再聪明的实习生也会用错——不是他笨, 是手册没讲清。

5. 推论: 工具定义(描述+参数schema)是Agent能力的【关键基础设施】;
   - 它和prompt一样, 是你"指挥"模型的核心手段; 值得像写API文档一样认真写。

一句话: Agent只能依据工具的"描述+参数说明"(看不到实现)来选工具、填参数; 说明书含糊/雷同/不清,
   模型就会选错填错(不是模型笨, 是说明书烂); 工具定义是Agent的关键基础设施, 要认真写清。

这套机制,是整个坑的根。Agent 调用工具的流程:你把所有工具的 name+description+参数 schema 告诉模型,模型根据当前任务和这些说明书判断"用哪个工具、参数填什么",输出工具调用、你的代码再执行。关键是:模型只能看到说明书、看不到工具的代码实现——它不知道工具内部干了什么,你的 description 和参数说明就是模型理解这个工具的全部信息来源,说明书质量直接决定模型能不能选对填对。说明书烂会导致:描述含糊(不知干嘛/何时用)、多工具描述雷同(分不清乱选)、参数说明不清(不知填啥填错)、缺"何时使用"指引(犹豫选错)就像Agent 是个聪明但对你业务一无所知的新实习生,全靠你写的"工具使用手册"决定用哪个怎么用;手册清楚就用得又快又对、含糊雷同再聪明也会用错——不是他笨是手册没讲清推论:工具定义是 Agent 能力的关键基础设施,和 prompt 一样是你指挥模型的核心手段,值得像写 API 文档一样认真写一句话:Agent 只能依据工具的"描述+参数说明"(看不到实现)来选工具、填参数;说明书含糊/雷同/不清,模型就会选错填错(不是模型笨,是说明书烂);工具定义是 Agent 的关键基础设施,要认真写清。

第二件事:正解——把工具描述和参数说明写清楚,职责单一,加校验

搞懂了原理,正解就清晰了:工具描述写清"做什么、何时用、何时不用",参数 schema 写清每个参数的含义/格式/示例,工具职责单一、名字清晰,并对参数做运行时校验兜底

# ✓ 正解: 清晰、单一职责、参数说明到位的工具定义
TOOLS = [
    {
        "name": "query_order_detail",                # ★ 名字清晰: 查订单详情
        "description":
            "根据订单号查询【订单的详细信息】(商品、金额、下单时间、订单状态)。"
            "当用户询问订单内容、金额、状态时使用。"
            "【注意】这不查物流(用query_logistics)、也不退款(用apply_refund)。",  # 何时用+何时不用
        "parameters": {
            "type": "object",
            "properties": {
                "order_no": {                        # ★ 参数名明确: order_no 而非含糊的id
                    "type": "string",
                    "description": "订单号, 形如 'ORD20260602001'(不是用户ID, 不是商品ID)",  # 说清含义+格式+反例
                }
            },
            "required": ["order_no"],
        },
    },
    {
        "name": "query_logistics",
        "description": "根据订单号查询【物流配送进度】(发货、运输、签收状态)。"
                       "当用户问'我的东西到哪了/什么时候到/有没有发货'时使用。",  # 明确的触发场景
        "parameters": { "type": "object", "properties": {
            "order_no": {"type": "string", "description": "订单号, 形如 'ORD20260602001'"}
        }, "required": ["order_no"]},
    },
    {
        "name": "apply_refund",
        "description": "为指定订单【发起退款申请】(这是个【有副作用的写操作】, 会真的发起退款)。"
                       "【仅当】用户【明确要求退款/退货】时才使用; 用户只是查询时【绝不要】调用它。",  # 强调副作用+严格触发条件
        "parameters": { "type": "object", "properties": {
            "order_no": {"type": "string", "description": "要退款的订单号"},
            "reason": {"type": "string", "description": "退款原因"},
        }, "required": ["order_no", "reason"]},
    },
]
# → 描述说清"做什么+何时用+何时别用"、参数名明确含义清晰带示例、有副作用的工具特别强调;
#   模型据此就能准确地选对工具、填对参数。
# ====== 写好工具定义的几条要点 ======

# 1. 名字清晰、有动词: query_order_detail 比 get_order 好, 一看就知道干嘛(动词+对象)。

# 2. 描述写清三件事: "这工具【做什么】" + "【什么时候】该用它" + "【什么时候不该】用(和别的工具的区别)"。

# 3. 工具职责单一: 一个工具只干一件事; 别一个工具又查又改(模型难判断、也危险)。

# 4. 参数说明到位: 每个参数写清【含义、格式、示例】, 甚至反例("不是用户ID"); 名字别用含糊的id。

# 5. 用严格的参数schema: 类型、必填、枚举值、范围都约束上(JSON Schema), 减少模型乱填的空间。

# 6. 有副作用的工具特别标注: 明确"这是写操作/会产生真实影响", 并写清严格的触发条件; 高危的加人工确认。

# 7. 运行时校验兜底: 别完全信模型填的参数, 执行工具前再做一层参数校验(同对待外部输入)。

# 8. 工具别太多: 工具一多, 模型选择困难、易混淆; 按需精简, 或分组/分层。

# 核心: 工具定义是Agent的"工具使用手册"——名字清晰、描述写清"做什么+何时用+何时不用"、参数说明到位带示例、
#   职责单一、严格schema、副作用标注、运行时校验兜底; 把它当API文档一样认真写, 别让模型连蒙带猜。

修复的核心,是"把工具说明书写得让模型一看就懂、不用猜"正解要点:名字清晰带动词(query_order_detail 比 get_order 好)、描述写清三件事(做什么+何时用+何时不该用)、工具职责单一(别又查又改)、参数说明到位(含义/格式/示例/反例,别用含糊的 id)、用严格 schema(类型/必填/枚举约束)、有副作用的特别标注(强调写操作+严格触发条件+高危人工确认)、运行时校验兜底(别完全信模型填的参数)、工具别太多(选择困难)。归根结底:工具定义是 Agent 的"工具使用手册"——名字清晰、描述写清"做什么+何时用+何时不用"、参数说明到位带示例、职责单一、严格 schema、副作用标注、运行时校验兜底;把它当 API 文档一样认真写,别让模型连蒙带猜。

第三件事:AI Agent 工具设计的其他常见坑

排查后我把 Agent 工具设计相关的其他常见坑也系统梳理了一遍。

AI Agent 工具设计的其他常见坑

# 1. 工具描述含糊/雷同(本文): 模型选错工具。→ 描述写清做什么+何时用+区别。

# 2. 参数说明不清: 模型填错参数。→ 参数写清含义/格式/示例, 名字明确, 严格schema。

# 3. 工具职责不单一: 一个工具又查又改, 模型难判断、且危险。→ 单一职责, 拆开。

# 4. 工具太多: 几十个工具模型选择困难、易混。→ 精简/分组/按场景动态提供子集。

# 5. 有副作用的工具没标注没确认: 模型可能误调退款/删除等。→ 标注副作用+严格触发+人工确认。

# 6. 完全信任模型填的参数: 不校验直接执行。→ 执行前做参数校验(当外部输入对待)。

# 7. 工具返回结果不友好: 返回一大坨原始数据, 模型难理解/塞爆context。→ 返回结构化、精炼的结果。

# 8. 工具失败没反馈: 工具执行失败没把错误信息返给模型, 它不知道该重试还是换法。→ 返回清晰的错误。

# 共同根源: 把Agent的能力寄托在"模型够聪明"上, 却忽视了"模型是基于你给的工具信息来行动的";
#   工具的定义、描述、参数、返回, 是模型行动的依据——这些信息的质量, 直接决定Agent的表现。

# 核心: 工具定义当API文档认真写(名字/描述/参数/示例/何时用); 职责单一、精简、严格schema、
#   副作用标注+确认、参数校验、返回精炼且带错误反馈; 给模型清晰的信息, 它才能做对的行动。

排查让我把 Agent 工具设计的其他坑也梳理清了。一、工具描述含糊/雷同(本文)。二、参数说明不清三、工具职责不单一四、工具太多(选择困难,分组/动态提供)。五、有副作用的工具没标注没确认六、完全信任模型填的参数(执行前校验)。七、工具返回不友好(返回精炼结构化)。八、工具失败没反馈(返回清晰错误)。它们的共同根源是:把 Agent 的能力寄托在"模型够聪明"上,却忽视了"模型是基于你给的工具信息来行动的";工具的定义、描述、参数、返回是模型行动的依据,这些信息的质量直接决定 Agent 的表现核心是:工具定义当 API 文档认真写;职责单一、精简、严格 schema、副作用标注+确认、参数校验、返回精炼且带错误反馈;给模型清晰的信息,它才能做对的行动下面这张图,是这次工具定义不清坑的成因与解法:

第四件事:好工具定义的检查清单速查表

这次踩坑后,我把"一个好的 Agent 工具定义该满足什么"整理成一张清单表。

要素 反例 正例
名字 get_order(含糊) query_order_detail(动词+对象)
描述-做什么 "处理订单" "查订单的商品/金额/状态"
描述-何时用 没写 "用户问订单内容时用"
描述-何时不用 没写 "不查物流/不退款"
参数含义 id: string order_no: 订单号 形如 ORD...
副作用标注 没标 "写操作, 仅用户明确要求退款时用"

这张清单把好工具定义的标准钉清了。核心是:一个好的工具定义,要让模型"无需猜测"就能准确判断"这个工具是不是我现在要用的、参数该填什么"——名字一看就懂、描述讲清做什么+何时用+何时不用、参数写明含义和格式、有副作用的特别标注;核心是把"模型需要知道才能正确使用"的信息,全部、清晰地提供给它它给我的最大启发是:"给 AI 写工具定义",本质和"给人写清晰的接口文档/操作说明"是一回事——都是要站在使用者的角度,把'用对它所需的一切信息'清晰、无歧义地表达出来;"清晰的沟通/表达"这个能力,在 AI 时代不仅没贬值,反而更值钱了——因为你现在不仅要把事讲清楚给,还要讲清楚给AI(prompt、工具描述、规则),而 AI 对"表达是否清晰"极其敏感这让我重新认识了一项"软技能"的硬价值:在 AI Agent 时代,"把意图、规则、信息清晰准确地表达出来"的能力,成了一项核心的工程能力——无论是写 prompt、定义工具、还是设计 Agent 的行为约束,本质都是"用清晰的语言去精确地指挥 AI";"清晰表达 = 让 AI(和人)准确理解你的意图",而模糊的表达,会让再强的 AI 也偏离你的本意——"会清晰地表达",是驾驭 AI 的一项关键功夫把工具定义当清晰的接口文档来写、重视 AI 时代清晰表达的硬价值——是这个坑带给我的认知。

第五件事:别把 Agent 的问题都归咎于"模型不够强"

这次最该反思的,是我一开始就把锅甩给了模型。我把"Agent 表现不好的常见原因"整理成表。

表现不好的原因 占比感受 解法方向
工具定义不清(本文) 很常见 写清描述/参数
prompt写得不好 很常见 优化prompt
给的上下文/信息不足或太杂 常见 上下文工程
没有合适的工具可用 常见 补工具
流程/约束设计不当 常见 改编排/护栏
模型本身能力不够 较少是根因 换更强模型

这张表道出了一个常见的归因误区。核心是:当 Agent 表现不好时,"模型能力不够"往往不是最主要的原因;更常见的根因是我们这边的"工程"没做好——工具定义不清、prompt 不好、上下文不当、缺工具、流程设计差;这些"我们能控制、能优化"的因素,贡献了大部分的 Agent 问题它给我的深刻启发是:面对 AI 系统表现不佳,有一种"甩锅给模型"的诱惑("是模型不行")——这很省事(反正不是我的错),但常常是错的、且让你错过了真正能改进的地方;因为模型是"给定的"(你换不换得起更强的另说),而"怎么用好这个模型"(工具、prompt、上下文、流程)才是你真正能掌控、能下功夫的地方;"把 Agent 的表现,更多地看成'我有没有把模型用好'的问题,而非'模型够不够强'的问题"这给了我一种更有建设性的归因习惯:系统出问题时,先反求诸己——检查"我提供给它的信息、配置、约束、流程"是不是有问题,而不是急着把责任推给"不可控的外部因素"(模型、框架、运气)——因为"自己能改的部分",才是改进的真正杠杆;"遇到问题先找自己能控制的原因",不仅更可能找到真因,也让你始终握着"能让事情变好"的主动权别轻易把 Agent 问题归咎于模型、先反求诸己检查自己能控制的工程因素——是这个坑带给我的归因认知。

第六件事:给 Agent 定义一个工具时,我现在的检查习惯

现在每当我给 Agent 定义一个工具,我都会按这张图把它过一遍:

这张图的精髓,是"名字清晰、描述讲清三件事、参数到位、副作用标注、校验兜底"定义工具依次确认:名字一看就懂、描述讲清做什么+何时用+何时不用、参数含义格式示例齐全且严格 schema、有副作用就标注+严格触发+高危人工确认、执行前参数校验兜底这套习惯,让我从"随手写个工具描述"变成了"把工具定义当接口文档认真写"——核心始终是:工具定义是 Agent 的说明书,要写清让模型不用猜,职责单一、副作用标注、参数校验。

我立下的几条规矩

这场"工具定义不清、Agent 乱用工具"的事故,换来了我做 Agent 时,刻进骨子里的几条铁律:

  1. 模型靠工具的描述和参数说明来选工具、填参数。它看不到工具实现。
  2. 工具名字清晰、带动词。query_order_detail 比 get_order 好。
  3. 描述讲清三件事:做什么、何时用、何时不用。尤其和相似工具的区别。
  4. 参数写清含义/格式/示例,用严格 schema。别用含糊的 id。
  5. 工具职责单一,有副作用的特别标注+严格触发+高危人工确认。
  6. 执行前对模型填的参数做校验。当外部输入对待,别完全信。
  7. Agent 表现不好先反求诸己。多半是工具/prompt/上下文,别轻易怪模型。

写在最后

回头看,这场由"工具描述写得含糊"引发的、Agent 乱用工具的事故,真正教给我的,远不止"工具定义要写清楚"这一个技巧。它让我对"当一个'智能体'表现不好时,问题常常不在它'',而在我没把'意图和信息'清楚地传达给它",有了一次刻骨的体会。我栽跟头,根源在于我把'沟通失败'误判成了'能力不足'。Agent 用错工具,我的第一反应是"这模型怎么这么笨"——我归咎于它的能力。可真相是:它一点都不笨,它只是没能从我含糊的工具说明书里,正确地理解我的意图;这不是"它理解能力差",而是"我表达得太差"——是一次'沟通'的失败,而非'能力'的失败就像我给一个聪明的实习生一份烂手册,他做错了,错的是手册、不是他的智商这让我领悟到一个在 AI 时代愈发重要的认知:当我们指挥一个"有理解能力的智能体"(无论是 AI 还是人)时,它的产出质量,极大程度上取决于我们"输入"给它的意图和信息的清晰度——"垃圾进,垃圾出(garbage in, garbage out)":你给的指令、信息、上下文越模糊,它的产出越可能跑偏;不是它不想做对,而是它无法从模糊的输入里,还原出你想要的那个清晰的意图;"很多'它没做对'的问题,根子是'我没说清'"这给了我一种与智能体协作的根本自觉:想让 AI(或任何协作者)做对事,首先要逼自己把"要它做什么、怎么判断、有什么约束"想清楚、表达清楚——"清晰的意图"是"正确的产出"的前提;模糊的指挥,只会得到模糊的结果,然后你还误以为是对方能力不行;"把表达清楚、把信息给足,当成自己的责任",而不是指望对方去猜、再回过头怪对方猜错——这是高效协作(无论和人还是和 AI)的根本认清 Agent 用错工具常是"我没说清"而非"它笨"、把清晰表达意图当成自己的责任——这,是我用一次工具定义不清的事故,换来的、关于 AI Agent、也关于如何与一切智能体高效协作的、最朴素也最深刻的领悟。如果这篇复盘,能让你下次给 Agent 加工具时,把描述和参数当一份认真的说明书来写,那我对着那个乱用工具的 Agent 排查的这段时间,就值了。

—— 别看了 · 2026
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理 邮箱1846861578@qq.com。
技术教程

一个用联合类型加 switch 处理多种形状的函数,在我新增了一种类型后悄悄漏掉了它、TS 却一声不吭,直到线上才暴露:一次 TypeScript 穷尽检查缺失的深度复盘

2026-6-2 18:25:33

技术教程

一段用浅拷贝复制配置模板的 Python 代码,我改了副本里的一个嵌套列表,结果把原始模板和其他所有副本一起改了:一次浅拷贝陷阱的深度复盘

2026-6-2 18:35:38

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索