高频追问:Agent 里 LLM 可能反复生成同一个 tool_call,工具也可能超时/报错——重复调用和连续失败在"哪一层"被拦住?答案要分两层:模型层去重 + 平台层熔断。
💡 答案要点
先定位问题(两层失败/重复):
模型层:LLM 生成 tool_call 时可能重复调用同一个工具(参数相同)
平台层:工具本身超时、报错、依赖的服务挂了
→ 两个层面都要治理,缺一不可第一层:模型层去重(防重复调用)
- 相同工具 + 相同参数在短时间内只执行一次,后续调用直接返回缓存结果;
- 工具调用结果回填上下文,让 LLM 看到"已经调用过",减少重复生成;
- 关键:去重键要包含参数 hash + 会话 id,避免跨会话误命中。
第二层:平台层熔断(防连续失败)
超时(每次调用设 timeout,如 5s)
→ 重试(指数退避,上限 N 次,如 3 次)
→ 熔断(连续失败 N 次后熔断该工具,直接走降级路径)
→ 恢复(半开状态探测,成功后逐步恢复)幂等设计(工具侧最重要):
- 工具接口设计成幂等:同一个 request_id 重复提交,结果一致、不产生副作用;
- Go 侧落地:request_id 查重 + 数据库唯一约束(如唯一索引 on request_id);
- 这样即使去重失败导致重复调用,业务数据也不会错。
错误返回协议(让 LLM 能判断):
- 工具错误要结构化返回:错误码 + 可恢复标记(RETRYABLE / NON_RETRYABLE);
- 可恢复错误 → LLM 可以重试或换参数;不可恢复 → 直接降级/转人工,别让模型瞎试。
审计: 每次调用记录 agent_id、tool_name、参数摘要、结果、耗时、是否重试/熔断,供复盘和成本归因。
状态机(熔断器):
CLOSED(正常)→ 连续失败 ≥ N → OPEN(熔断,直接降级)
OPEN → 冷却期后 → HALF_OPEN(放少量探测请求)
HALF_OPEN → 成功 → CLOSED(恢复);失败 → OPEN(继续熔断)面试话术:
"工具调用治理我分两层:模型层去重——相同参数短时间只执行一次,结果回填上下文,防 LLM 重复生成 tool_call;平台层熔断——超时、指数退避重试、连续失败熔断、半开恢复,熔断后走降级路径。工具本身必须幂等,request_id 加唯一约束,这样即使去重失效,重复调用也不产生副作用。错误返回带 RETRYABLE 标记,让模型知道能不能重试。每次调用全量审计,出问题能复盘。"