工具调用是"黑盒里最多暗门"的一段
模型回答错了,你还能看输入输出;工具调用错了,问题可能藏在参数、时序、权限、幂等里。
所以要专门为它做可观测:日志要结构化、失败要能回放、重试要有边界。
一、日志:每次调用记这 10 项
- 请求 id(串起同一任务的多次调用);
- 工具名与版本;
- 参数(脱敏后的原文);
- 参数来源(模型生成 / 规则补全 / 用户输入);
- 校验结果(通过 / 哪条规则不过);
- 权限判定(允许 / 拒绝 / 需要确认);
- 耗时(分:排队、执行、返回);
- 结果摘要(成功/失败 + 关键字段,不要整包);
- 是否重试、第几次;
- 副作用是否落库(以及幂等键)。
关键是 4 与 10:前者决定"是模型的错还是规则的错",后者决定"能不能安全重试"。
二、回放:把失败变成可复现的用例
- 保存足够复现的输入(脱敏后的参数 + 当时的工具版本 + 相关上下文片段);
- 提供离线回放命令:同一输入重跑该工具(对只读工具可直接跑;写操作要打到沙箱);
- 回放结果与线上结果对比,判断是"工具偶发"还是"逻辑错"。
没有回放能力,工具出错只能靠猜。
三、重试:三条边界
- 只重试幂等的(读、查询、幂等写);非幂等操作要先确认再用补偿;
- 区分可重试错误(超时、5xx、限流)与不可重试错误(参数错、权限拒绝);
- 限制次数与总时长(例如 2 次 / 10 秒),并把"已经重试过"写进日志。
同时要防重试放大:重试会让并发与成本翻倍,必须纳入容量与预算(见容量规划那篇)。
四、该报警的四个指标
- 工具失败率(分工具、分错误类型);
- 参数校验拒绝率(升高通常意味着模型输出漂移或提示词改了);
- 重试率与重试后成功占比(后者低说明重试没意义);
- 写操作被拒绝/待确认的比例(权限与安全策略是否过紧或过松)。
五、最小落地顺序
- 先把上面 10 项日志补齐(半天,收益最大);
- 加只读工具的离线回放;
- 给写操作加幂等键与"意图→执行→确认"两阶段;
- 最后加指标与告警。