1980 字
10 分钟
Agent 声称调用了工具,但实际没有解决问题

一、问题分析#

Agent 声称已经调用工具,或者告诉用户任务已完成,但实际上可能存在三种情况:

  1. 工具没有执行:模型只输出“已完成”,没有产生真实的工具调用。
  2. 工具执行失败:已经调用工具,但参数错误、权限不足、接口超时或服务异常。
  3. 工具执行成功,但任务没有完成:工具返回成功,但没有达到用户要求的业务结果。

解决思路:不能直接相信 Agent 的自然语言回复,而要根据真实执行记录、工具返回结果和业务验收结果判断任务是否完成。

二、整体工程方案#

用户提出任务
↓
Agent 生成结构化 Tool Call
↓
检查是否产生真实工具调用
├── 没有 Tool Call
│ ↓
│ 不允许判定成功
│ 要求继续执行或返回未完成
│
└── 存在 Tool Call
↓
Tool Executor 执行工具
↓
记录真实执行结果
↓
根据结果分类处理
├── 参数错误 → 修正参数后重试
├── 临时错误 → 有限次退避重试
├── 超时未知 → 查询业务状态
└── 执行成功 → 业务结果验收
↓
验收通过才算任务完成

三、具体工程实现#

1. 工具调用:使用现成框架管理执行#

可以参考 LangGraph 的 ToolNode 和 tools_condition。

  • Agent 负责生成结构化工具调用请求。
  • ToolNode 根据工具名称找到对应实现并执行。
  • tools_condition 根据模型消息中是否存在 Tool Call 进行路由。
  • 工具执行结果返回给模型,让 Agent 根据结果继续处理。

注意:模型输出“我已经调用工具”只是普通文本,不代表真的发生了工具调用。

如果没有产生 Tool Call,系统不能将任务标记为成功;如果有 Tool Call,还需要确认执行器确实运行并返回了结果。

参考:

2. 执行记录:确认工具是否真的执行#

后端可以建立 agent_tool_execution 表,记录:

字段作用
task_id所属 Agent 任务
tool_call_id本次工具调用的唯一标识
tool_name工具名称
arguments工具调用参数
status执行状态
result工具真实返回结果
error_code错误类型
duration_ms执行耗时

执行器在调用前创建记录,执行后更新状态。

可以使用以下状态:

  • PENDING:等待执行
  • RUNNING:正在执行
  • SUCCEEDED:工具执行成功
  • FAILED:明确执行失败
  • UNKNOWN:结果暂时无法确认

通过执行记录和运行轨迹,可以区分模型没有发起调用、执行器没有正常运行,以及外部 API 执行失败等问题。

参考:

3. 错误恢复:将真实错误反馈给 Agent#

不能所有错误都采用同一种重试方式,需要根据错误类型分类处理。

错误情况处理方式
参数错误将具体错误反馈给 Agent,修正参数后重试
临时限流或服务异常由执行器按照退避策略有限次重试
权限不足停止重试,提示用户授权
工具返回业务失败分析错误原因,决定是否更换工具或调整方案
请求超时,结果未知先查询业务状态,避免重复执行
超过最大重试次数停止自动纠错,返回明确失败原因

重试时需要设置最大次数和整体执行时限,避免 Agent 无限循环。

对于创建工单、创建待办、扣费等有副作用的操作,还需要使用幂等键、业务唯一标识或结果查询,避免重复执行。

4. 业务验收:工具成功不等于任务完成#

例如,用户要求创建一条飞书待办。

不能只检查创建接口是否返回成功,还可以根据返回的 todo_id 查询实际记录,并检查:

  • 待办是否真实存在。
  • 标题和负责人是否符合要求。
  • 是否满足用户提出的其他业务条件。

建议区分两个状态:

  • tool_status:工具执行是否成功。
  • task_status:用户要求的任务是否完成。

例如:

tool_status = SUCCEEDED
task_status = VERIFYING

验收通过后:

tool_status = SUCCEEDED
task_status = SUCCEEDED

如果工具执行成功,但业务验收失败,则不能把任务标记为完成。

注意:只有外部系统支持查询或提供足够的结果证据时,才能验证实际业务状态;不能声称完成了无法执行的检查。

四、完整故障处理示例#

场景:用户要求 Agent 创建飞书待办,但 Agent 直接回复“创建成功”。

情况一:没有真实工具调用#

  1. 模型只返回普通文本,没有 Tool Call。
  2. 后端发现没有对应的工具执行记录。
  3. 不允许任务进入 SUCCEEDED。
  4. 系统要求 Agent 继续执行,或向用户明确说明任务尚未完成。
  5. 如果达到执行上限,则停止并报告失败。

情况二:工具执行失败#

  1. Agent 调用 create_todo。
  2. 后端执行器实际调用飞书 API。
  3. 飞书返回 INVALID_ASSIGNEE,说明负责人 ID 无效。
  4. 执行器记录失败状态,并将错误反馈给 Agent。
  5. Agent 查询合法的负责人 ID,再重新调用创建工具。
  6. 重试次数受限制,最终结果仍由后端验收。

情况三:工具超时#

  1. 后端发起创建请求。
  2. 请求超时,无法确定飞书是否已经创建待办。
  3. 将执行状态标记为 UNKNOWN,而不是直接认定失败。
  4. 根据业务唯一标识或查询接口确认是否已创建。
  5. 确认未创建后再决定是否重试,避免重复创建。

五、面试口播#

如果遇到 Agent 声称调用了工具,但实际没有解决问题,我会先区分三种情况:工具没有真正执行、工具执行失败,以及工具执行成功但业务任务没有完成。

首先,在执行链路上,我会使用 LangGraph 的 ToolNode 这类工具执行机制,将模型生成的结构化 Tool Call 交给后端执行,而不是直接相信模型输出的成功话术。

其次,我会通过工具执行日志和运行轨迹,记录调用参数、执行状态和返回结果。如果没有真实的执行记录,就不能认定工具调用成功;如果执行失败,就将具体错误反馈给 Agent,让它修正参数或更换工具,并限制重试次数。

最后,我会增加业务结果校验。例如创建飞书待办,不仅检查 API 是否返回成功,还可以根据待办 ID 查询记录是否真实存在。

对于超时场景,还需要先确认外部操作是否已经成功,避免盲目重试造成重复执行。

这样就形成了从工具调用、执行监控、错误纠正到业务验收的完整闭环。核心是由后端掌握工具执行和任务成功状态的判定权,而不是依赖 Agent 自己声称任务已经完成。

六、核心记忆点#

  1. 工具调用:使用结构化 Tool Call 和执行节点,不能依赖普通文本。
  2. 执行监控:通过执行记录和 Tracing 还原真实调用过程。
  3. 错误纠正:将错误反馈给 Agent,分类处理并限制重试。
  4. 业务验收:工具执行成功不代表任务完成。
  5. 异常安全:超时结果未知时先查状态,防止重复执行。

一句话总结:现成框架负责工具调度和执行观测,自定义逻辑负责错误恢复与业务验收。

Agent 声称调用了工具,但实际没有解决问题
https://blog.xqcherry.top/posts/interview/ai-engineering/agent-tool-call-verification/
作者
xqcherry
发布于
2026-10-23
许可协议
CC BY-NC-SA 4.0