拒绝“幻觉”:当 Agent 工具调用失败时,如何设计优雅的 Prompt 容错机制?
拒绝“幻觉”:当 Agent 工具调用失败时,如何设计优雅的 Prompt 容错机制?
大家好,我是你们的老朋友,一名深耕 IT 领域的技术博主。
在构建 AI Agent(智能体)应用时,我们往往最关注模型有多聪明、推理能力有多强。但在生产环境中,**“稳定性”**才是决定用户体验生死的关键。
你是否遇到过这样的场景:
用户问:“今天北京的天气怎么样?”
Agent 调用了天气 API,但因为网络波动超时了,或者 API 返回了空数据。
结果,Agent 开始“一本正经地胡说八道”,编造了一个晴朗的天气,或者卡在那里没有任何反应。
这就是典型的 Tool Failure Handling(工具失败处理) 缺失。
今天,我们就来深入探讨:当工具调用超时或返回空值时,如何通过 Prompt 设计,让 Agent 从“瞎猜”转变为“可控地表达不确定性 + 引导用户下一步”?
一、 为什么工具失败处理这么重要?
在 ReAct(Reasoning + Acting)架构中,LLM(大语言模型)是大脑,Tool(工具)是手脚。如果手脚失灵了,大脑不能假装一切正常。
核心目标非常明确:
不是让模型去“猜”结果,而是让 Agent 在工具失败时,仍然能“体面”地与用户交互。
我们需要达成三个效果:
- 诚实:明确告知用户当前无法获取信息。
- 透明:简单解释原因(是系统忙?还是没数据?)。
- 引导:给用户指一条明路(重试?换个问法?还是人工介入?)。
二、 先定义失败:知己知彼
在设计 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. 架构流程图
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 指令:
如果工具不可用,且用户问题属于通用常识,你可以基于训练数据提供参考信息,但必须在开头声明: “⚠️ 注意:当前无法获取实时数据,以下信息仅供参考,可能与实际情况有出入。”
六、 避坑指南与最佳实践
-
不要在 Prompt 里写“如果失败就重试”:
LLM 无法直接发起网络重试。重试逻辑应该写在代码层(Wrapper 层),LLM 只需要知道“重试后依然失败”的结果。 -
区分“没数据”和“出错了”:
对用户来说,这两者体验截然不同。“没数据”可能是用户搜错了,“出错了”是平台的问题。Prompt 中要区分这两种语气。 -
保持语气一致:
即使是报错,也要保持品牌设定的语气(幽默、严肃或亲切)。不要在报错时突然变成冰冷的机器码。 -
日志记录是关键:
当 Agent 触发“失败处理 Prompt”时,务必在后端记录日志。这些日志是你优化 API 稳定性和调整 Prompt 的宝贵数据。
七、 总结
在构建高可用的 AI Agent 时,工具失败处理不是边缘功能,而是核心体验的一部分。
我们要做的不是让模型去“补全”缺失的答案,而是通过 Prompt + 工程结构 的双重约束,实现:
- 控制不确定性:不让模型胡编乱造。
- 引导用户行为:让用户知道接下来该做什么。
记住这句话:
优秀的 Agent 不仅知道如何回答问题,更知道在无法回答时,如何优雅地帮助用户。
希望这篇博客能为你的 Agent 开发带来一些启发。如果你在实施过程中遇到具体问题,欢迎在评论区交流!
参考资料
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐

所有评论(0)