A
版块:AI 智能体
Demo 里的 Agent 会掉链子,生产里的 Agent 是"分布式系统"待遇。这篇按后端可靠性标准来收拾工具调用环节——每一条都有对应事故原型。
一、先接受三个事实
1. 工具调用失败是常态事件:网络抖动、外部 API 限流、模型参数格式错、返回超长撑爆上下文;
2. LLM 生成的参数默认不可信:JSON 能 parse ≠ 参数合法(枚举值拼错、日期格式飘、单位混淆);
3. "重试"对不幂等的操作就是新故障源:转账类操作重试一次=扣两次钱。
二、调用前:schema 强校验 + 约束解码
- 工具入参一律走 Pydantic/Zod 级强校验,失败不要直接扔回模型(浪费一轮),先在网关层做确定性修复:日期格式归一、枚举模糊匹配、数字抽字符串里的首个数值;
- 高价值路径用 constrained decoding(grammar 约束输出),把 JSON 合法率从 ~99% 提到 ~100%,剩下 1% 才是真正的参数语义错;
- 给模型的 schema 写清单位(毫秒还是秒)、必填原因、示例——schema 里的一行注释值一千次重试。
三、执行层:幂等、超时、熔断
1. 幂等键:Agent 每次工具调用生成稳定 idempotency key(thread_id + step 序号 + 参数 hash 截断),下游接口全部按这个键去重;这是把"重试"从危险动作变成安全动作的唯一办法;
2. 超时三件套:连接超时 2s 硬线、单次请求超时按 P99×2、整个工具步骤总预算(重试+修复+重问模型加起来,别让一个卡住的工具吊着整条链路 30 分钟);
3. 熔断按"工具粒度":某个搜索 API 成功率跌破阈值就短路降级(返回缓存/备用源/告知模型该工具暂不可用),别把它烧进模型上下文里反复碰运气。
四、失败之后怎么"喂回"模型
反例:把原始 stack trace 丢回去。正例:结构化失败摘要——
- 类型(校验失败/超时/业务拒绝)
- 建议动作(换个参数重试 / 换备用工具 / 求助人类)
- 已尝试次数与已用时间
"业务拒绝"(库存不足)和"通信失败"要让模型明确区分,否则它会对一个永久性失败发起无限重试——这是线上最常见的 Agent 死循环成因。
五、评估:别拿单次准确率说事
- 回归集:把生产 trace 里失败过的 case 持续补进评测集,每次改动跑"工具调用合法率、最终任务完成率、平均重试次数、总延迟 P95"四指标;
- 上线前做故障注入实验:随机把某个工具打挂/延迟 8 倍,看 Agent 是否优雅降级;
- 给"重做/死循环"设硬熔断(同工具同参数连续 3 次即升级人工),再好的模型也需要这个保险丝。
你们线上 Agent 的工具失败里占比最高的是哪一类?我们在做过统计:校验错 > 限流 > 超时 > 业务拒绝——欢迎晒你们的分布。
Demo 里的 Agent 会掉链子,生产里的 Agent 是"分布式系统"待遇。这篇按后端可靠性标准来收拾工具调用环节——每一条都有对应事故原型。
一、先接受三个事实
1. 工具调用失败是常态事件:网络抖动、外部 API 限流、模型参数格式错、返回超长撑爆上下文;
2. LLM 生成的参数默认不可信:JSON 能 parse ≠ 参数合法(枚举值拼错、日期格式飘、单位混淆);
3. "重试"对不幂等的操作就是新故障源:转账类操作重试一次=扣两次钱。
二、调用前:schema 强校验 + 约束解码
- 工具入参一律走 Pydantic/Zod 级强校验,失败不要直接扔回模型(浪费一轮),先在网关层做确定性修复:日期格式归一、枚举模糊匹配、数字抽字符串里的首个数值;
- 高价值路径用 constrained decoding(grammar 约束输出),把 JSON 合法率从 ~99% 提到 ~100%,剩下 1% 才是真正的参数语义错;
- 给模型的 schema 写清单位(毫秒还是秒)、必填原因、示例——schema 里的一行注释值一千次重试。
三、执行层:幂等、超时、熔断
1. 幂等键:Agent 每次工具调用生成稳定 idempotency key(thread_id + step 序号 + 参数 hash 截断),下游接口全部按这个键去重;这是把"重试"从危险动作变成安全动作的唯一办法;
2. 超时三件套:连接超时 2s 硬线、单次请求超时按 P99×2、整个工具步骤总预算(重试+修复+重问模型加起来,别让一个卡住的工具吊着整条链路 30 分钟);
3. 熔断按"工具粒度":某个搜索 API 成功率跌破阈值就短路降级(返回缓存/备用源/告知模型该工具暂不可用),别把它烧进模型上下文里反复碰运气。
四、失败之后怎么"喂回"模型
反例:把原始 stack trace 丢回去。正例:结构化失败摘要——
- 类型(校验失败/超时/业务拒绝)
- 建议动作(换个参数重试 / 换备用工具 / 求助人类)
- 已尝试次数与已用时间
"业务拒绝"(库存不足)和"通信失败"要让模型明确区分,否则它会对一个永久性失败发起无限重试——这是线上最常见的 Agent 死循环成因。
五、评估:别拿单次准确率说事
- 回归集:把生产 trace 里失败过的 case 持续补进评测集,每次改动跑"工具调用合法率、最终任务完成率、平均重试次数、总延迟 P95"四指标;
- 上线前做故障注入实验:随机把某个工具打挂/延迟 8 倍,看 Agent 是否优雅降级;
- 给"重做/死循环"设硬熔断(同工具同参数连续 3 次即升级人工),再好的模型也需要这个保险丝。
你们线上 Agent 的工具失败里占比最高的是哪一类?我们在做过统计:校验错 > 限流 > 超时 > 业务拒绝——欢迎晒你们的分布。
