拒绝“幻觉”:当 Agent 工具调用失败时,如何设计优雅的 Prompt 容错机制?

大家好,我是你们的老朋友,一名深耕 IT 领域的技术博主。

在构建 AI Agent(智能体)应用时,我们往往最关注模型有多聪明、推理能力有多强。但在生产环境中,**“稳定性”**才是决定用户体验生死的关键。

你是否遇到过这样的场景:
用户问:“今天北京的天气怎么样?”
Agent 调用了天气 API,但因为网络波动超时了,或者 API 返回了空数据
结果,Agent 开始“一本正经地胡说八道”,编造了一个晴朗的天气,或者卡在那里没有任何反应。

这就是典型的 Tool Failure Handling(工具失败处理) 缺失。

今天,我们就来深入探讨:当工具调用超时或返回空值时,如何通过 Prompt 设计,让 Agent 从“瞎猜”转变为“可控地表达不确定性 + 引导用户下一步”?


一、 为什么工具失败处理这么重要?

在 ReAct(Reasoning + Acting)架构中,LLM(大语言模型)是大脑,Tool(工具)是手脚。如果手脚失灵了,大脑不能假装一切正常。

核心目标非常明确:

不是让模型去“猜”结果,而是让 Agent 在工具失败时,仍然能“体面”地与用户交互。

我们需要达成三个效果:

  1. 诚实:明确告知用户当前无法获取信息。
  2. 透明:简单解释原因(是系统忙?还是没数据?)。
  3. 引导:给用户指一条明路(重试?换个问法?还是人工介入?)。

二、 先定义失败:知己知彼

在设计 Prompt 之前,我们必须先对“失败”进行分类。不同的失败类型,对应的处理策略完全不同。

失败类型 典型表现 用户感知 推荐策略
超时 (Timeout) 工具长时间无响应 “怎么还没好?” 建议稍后重试,或缩小查询范围
空结果 (Empty) 返回 []null “是不是搜错了?” 引导检查关键词,或放宽条件
错误 (Error) API 报错、Schema 异常 “系统崩了?” 道歉,记录日志,建议联系管理员

三、 核心设计原则:生产级 Prompt 的三条铁律

原则 1:严禁幻觉(No Hallucination)

这是底线。必须在 System Prompt 中用最强的语气禁止模型在工具失效时编造数据。

如果工具未返回有效结果,绝对禁止基于猜测生成答案。

原则 2:显式声明“不确定”

避免模型为了“讨好”用户而强行回答。要让模型学会说“我不知道”,但这是一种专业的“不知道”。

原则 3:提供“下一步路径”(Actionable Next Steps)

只说“失败了”是糟糕的体验。好的 Agent 会说:“失败了,但你可以试试 A 或 B。”


四、 实战:不同场景的 Prompt 模板

以下是我经过多次调试总结出的通用模板,你可以直接嵌入到你的 System Prompt 中。

1. 全局兜底规则(System Prompt 片段)

【工具调用失败处理协议】
当工具调用返回失败(包括超时、空结果、API错误)时,你必须严格遵守以下规则:
1. **禁止编造**:不得利用训练数据中的旧知识或猜测来填充缺失信息。
2. **状态声明**:明确告知用户当前信息不可用。
3. **原因简述**:用通俗语言解释可能原因(如:系统繁忙、数据不存在)。
4. **行动引导**:提供 1-2 个具体的可操作建议(如:重试、修改查询条件)。
5. **部分可用处理**:如果仅有部分数据返回,需标注“数据不完整”,并仅展示已知部分。

2. 场景化输出示例

场景 A:超时 (Timeout)

用户心理:焦急,想知道还要等多久。

Agent 回复示例:
“抱歉,当前数据查询响应超时,未能及时获取结果。

可能原因:

  • 当前系统负载较高
  • 查询涉及的数据量过大

建议操作:

  • 请稍后再次尝试
  • 尝试缩小查询时间范围或关键词”
场景 B:空结果 (No Data)

用户心理:疑惑,怀疑自己输错了。

Agent 回复示例:
“未在数据库中找到匹配的数据。

可能原因:

  • 该条件下确实无数据
  • 查询关键词可能存在拼写偏差

建议操作:

  • 请检查输入的条件是否正确
  • 尝试使用更宽泛的关键词重新搜索”
场景 C:API 错误 (System Error)

用户心理:担忧,觉得系统坏了。

Agent 回复示例:
“系统在处理请求时发生内部错误,暂时无法提供服务。

我们已记录该异常,技术团队正在排查。

建议操作:

  • 建议您稍后重试
  • 如问题持续,请联系系统管理员”

五、 进阶架构:不只是 Prompt,更是工程体系

在实际的企业级开发中,单纯依靠 Prompt 是不够的。我们需要构建三层防御体系

1. 架构流程图

第三层:Prompt 决策层

第二层:结构化中间件

第一层:工具层防御

调用工具

Retry/Circuit Breaker

Raw Result

标准化结构

Success

Timeout

Empty

Error

读取 Status

Success

Failure

用户提问

Agent Core

Tool Wrapper层

外部 API

状态判断

数据正常

超时信号

空结果信号

错误信号

Prompt 逻辑判断

生成正常回答

生成降级/引导回答

2. 关键组件解析

第一层:Tool Response Wrapper(工具响应包装器)

不要直接把 Raw JSON 扔给 LLM。要在代码层做一个中间件,统一返回格式。

# Python 伪代码示例
class ToolResponse:
    def __init__(self, status, data=None, message="", retryable=False):
        self.status = status  # 'success', 'timeout', 'empty', 'error'
        self.data = data
        self.message = message
        self.retryable = retryable

    def to_dict(self):
        return {
            "status": self.status,
            "data": self.data,
            "message": self.message,
            "retryable": self.retryable
        }
第二层:Agent Decision Layer(决策层)

在 LangChain 或 ReAct 的 Prompt 中,增加对 status 字段的判断逻辑。

【决策逻辑】
请首先检查工具返回的 "status" 字段:
- 如果 status == "success": 基于 data 正常回答。
- 如果 status == "empty": 告诉用户没找到数据,并建议修改查询条件。
- 如果 status == "timeout": 告诉用户系统繁忙,建议稍后重试。
- 如果 status == "error": 告知系统错误,并提供人工客服链接(如果有)。
第三层:Fallback Answer(降级回答)

如果工具彻底不可用,是否允许使用模型自带的知识库?

  • 策略:可以,但必须加“免责声明”。

  • Prompt 指令

    如果工具不可用,且用户问题属于通用常识,你可以基于训练数据提供参考信息,但必须在开头声明:
    “⚠️ 注意:当前无法获取实时数据,以下信息仅供参考,可能与实际情况有出入。”
    

六、 避坑指南与最佳实践

  1. 不要在 Prompt 里写“如果失败就重试”
    LLM 无法直接发起网络重试。重试逻辑应该写在代码层(Wrapper 层),LLM 只需要知道“重试后依然失败”的结果。

  2. 区分“没数据”和“出错了”
    对用户来说,这两者体验截然不同。“没数据”可能是用户搜错了,“出错了”是平台的问题。Prompt 中要区分这两种语气。

  3. 保持语气一致
    即使是报错,也要保持品牌设定的语气(幽默、严肃或亲切)。不要在报错时突然变成冰冷的机器码。

  4. 日志记录是关键
    当 Agent 触发“失败处理 Prompt”时,务必在后端记录日志。这些日志是你优化 API 稳定性和调整 Prompt 的宝贵数据。


七、 总结

在构建高可用的 AI Agent 时,工具失败处理不是边缘功能,而是核心体验的一部分。

我们要做的不是让模型去“补全”缺失的答案,而是通过 Prompt + 工程结构 的双重约束,实现:

  1. 控制不确定性:不让模型胡编乱造。
  2. 引导用户行为:让用户知道接下来该做什么。

记住这句话:

优秀的 Agent 不仅知道如何回答问题,更知道在无法回答时,如何优雅地帮助用户。

希望这篇博客能为你的 Agent 开发带来一些启发。如果你在实施过程中遇到具体问题,欢迎在评论区交流!


参考资料

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐