学习笔记 | 11 月 1 日 · 工具调用的三种翻车方式
- 2026-11-07 01:12:53
每一步 95 分,十步之后还剩多少
今天补一句不太乐观的话:循环会把每一步的失败率乘起来。
单步正确率 95%,走 10 步,全程不出错的概率是 0.95¹⁰ ≈ 60%。单步 90%,10 步只剩 35%。
所以 Agent 的体验断崖,往往不是模型突然变笨,而是任务变长了。
工程重心也就不是「让它更聪明」,而是两件事:让每一步更不容易错,错了还救得回来。
今天拆三种最常见的翻车,以及对应的三道防线。
选错工具:描述写得太像
症状:用户问「我的订单到哪了」,它去查了订单详情,没查物流;用户问退款政策,它直接调了「发起退款」。
原因通常很朴素:两个工具的描述高度重叠。
search_orders 查询订单相关信息search_logistics 查询订单相关的物流信息
第二个描述里的「订单相关」,把第一个的语义也覆盖了。模型只能猜。
修法不是加提示词,是改描述——把「什么时候不要用」写进去:
search_logistics用途:查快递轨迹、签收状态、预计送达。不要用于:订单金额、商品明细、退款进度,那些用 get_order。前置条件:需要 order_id 或 11 位手机号。
加一句「不要用于」,比加十句「请正确选择工具」有用。
工具的 description 是路由表,不是说明书封面。
参数幻觉:编一个不存在的 id
症状:它给出的订单号是 ORD-20231031-001,看起来无比正确,但库里根本没有这条。
原因:模型是在「什么看起来合理」的分布里采样,不是在「什么真实存在」的集合里检索。这两件事长得很像,结果完全不同。
三个高频位置:
id 类:订单号、用户 id、文件路径 枚举类: canceled与cancelled、已支付与支付成功
- 时间类:2 月 30 日、不存在的时区偏移
对策有三条,从便宜到贵:
枚举写进 schema,不要写进描述。 描述是给人看的,schema 是给校验器看的。 需要真实值就先检索。把「填 id」拆成「先搜、再选」,别让模型凭空生成。 校验失败时,把合法集合喂回去。不说「参数错误」,而是「status 只能是 paid / shipped / refunded,你给的是 canceled」。
第三条收益最高,因为它把一次错误变成了一次可用的反馈。
连环调用:一步错,步步错
三种表现:
重试风暴:同一个接口失败,它换个参数再试,连试八次,烧掉一半预算。 目标漂移:为了查 A 先查 B,B 又要查 C,回来时已经忘了原本要干什么。 假完成:数据没拿到,但报告写得很完整——最危险的一种,因为看不出来。
一个真实会遇到的场景,查「上个月退款的订单」:
search_orders(month=9月) → 3 条get_refund(ORD-...-001) → 404search_orders(9月, refunded) → 1 条get_refund(ORD-...-017) → ok
第 2 步的 404 不是错误,是信息——「这条没退款」。当异常抛出去,流程就断了;当信息用,它正好修正了第 3 步的查询条件。
对策是给循环装三个硬约束:
错误预算:同一个工具连续失败两次,强制换策略或停下来问。 每步断言:规定「这一步的成功长什么样」,比如结果里必须出现 order_id,否则判定失败。允许说不知道:把「无法完成」设计成一个合法输出,并规定它的格式。
最后一条反直觉,但最重要:不给模型一个体面的退出口,它就会编一个体面的答案。
三道防线:schema、运行时、提示词
第一道,schema——在它开口之前就把可能性收窄:
refund_order(order_id: string, 必填格式 ^ORD-8位数字-3位数字reason: enum[质量问题, 七天无理由, 发错货]amount: number, 大于 0.01禁止额外字段)
四件事:类型、枚举、必填、禁止多余字段。「禁止额外字段」(additionalProperties: false)最常被忘,但它正是挡住「模型自创参数」的那道门。
第二道,运行时——校验不过就回喂,不要直接抛错:
参数校验失败field: reason你给的值:不喜欢合法值:质量问题 / 七天无理由 / 发错货请从中选一个;都不匹配就问用户
第三道,提示词——只写规则,不写情绪。真正有用的通常就三句:
不确定时先问,不要假设。 拿不到数据就说拿不到,不要用推测填空。 同一步骤失败两次,换方法或停止。
写「请你仔细、认真地选择工具」几乎没用;写「什么情况下不要用这个工具」,立刻见效。
给周报 Agent 加三道保险
接着昨天那个周报 Agent,加三处:
读文件加白名单:只允许读 materials/下的.md和.txt,路径里出现..直接拒绝。写之前先校验结构:输出必须正好三段,每段至少一条,每条不超过 40 字,不满足就重写一次。 交付前自检:先回答三个问题——有没有素材里没有的事实?有没有把进行中写成已完成?有没有超字数?三个都过了再输出。
三处加起来不到 30 行代码,但能把「偶尔好用」变成「每天能用」。
上线前我会过一遍这五个问题:
工具描述里,写了「什么时候不要用」吗? 枚举值是在 schema 里,还是在描述里? 需要真实 id 的地方,是不是让它先检索? 同一工具连续失败,会不会自动停? 「做不到」有没有一个明确的输出格式?
五个都能答上来,这个 Agent 才算能交付。
今日三句话
单步 95 分,十步只剩 60 分——长任务是被失败率乘垮的。 三种翻车:选错工具(描述太像)、参数幻觉(编不存在的 id)、连环调用(一步错步步错)。 三道防线:schema 收窄可能性、运行时回喂错误、提示词给一个体面的退出口。
明日预告:多轮任务的状态管理——中断了怎么续、跨天跑了三天怎么不丢进度。