Agent 的错误提示设计:Agent 执行失败了,怎么把技术错误翻译成用户能懂的话

你让 Agent 帮你查今天的股市行情。它在对话框里安静了五秒,然后拉出一行红色小字:TypeError: Cannot read properties of undefined (reading "close")。你盯着这行字,心脏开始打鼓:是我操作不对?是 App 崩了?还是我被攻击了?

AI technology illustration

都不是。这只是一个很普通的错误——Agent 调行情接口时,后端返回的数据少了一个字段。这句话从技术上说,跟你没有半毛钱关系。但问题是,Agent 犯的错,为什么要你来猜?

Agent 的链条太长,每一步都可能塌

你可能觉得,Agent 不是号称超级智能吗?处理一个“查行情”的任务,怎么会错得这么滑稽?答案藏在 Agent 的工作方式里。

一个典型的执行循环长这样:

  1. 意图理解——把“查行情”变成结构化的任务指令。
  2. 工具规划——决定调用行情接口,还是资讯频道。
  3. 参数生成——为工具调用生成 JSON 参数,比如 {"symbol": "AAPL"}。
  4. 工具执行——发出 HTTP 请求,等待响应。
  5. 结果整合——把返回的 close: 12.5 翻译成“今天收盘 12 块 5”。

这五步每一步都可能出问题。意图理解偏了,它可能把你的“查行情”理解成“查持仓”;工具规划错了,它可能调了天气接口;参数生成格式不对,后端直接报 validation error;工具执行撞上了上游 503;结果整合时,它甚至能把“涨”说成“跌”。

传统软件的错误是确定性的,数据库连不上就是连不上。Agent 的错误是概率性的、分布式的,而且常常以“假性成功”收场——你以为它做完了,其实它做错了。这种情况下,用户看到裸错误是必然的。

为什么市面上的 Agent 错误提示,还在把用户当程序员

打开你的 Agent 产品,遇到失败时你看到的往往是:

openai: connection error
retry after 5.2s
request id: 0x7f3a9c2e1b00
Traceback (most recent call last):
File "/app/agent.py", line 42, in tool_call
result = requests.post(...)

这种提示在大厂产品里极度常见。为什么?因为写错误提示没有 KPI。工程师把异常 catch 住,能打日志就算负责,谁有时间研究用户的语言?

更严重的后果是心理层面的。心理学研究发现,当错误信息里充满用户看不懂的术语时,用户倾向于把失败归因于自己能力不足。一个普通用户看到 rate_limit_exceeded,第一反应不是“服务忙”,而是“我是不是问太多了”。这种归因误差会直接摧毁他对 Agent 的信任。

我最早以为“透明”就是展示细节,直到阿姨问我:它是不是在骂我

我自己也犯过这个错。最初做 Agent 产品时,我信奉一个原则:错误提示要透明。把底层异常展示出来,用户就知道发生了什么,这难道不是最诚实的做法吗?

直到我做用户访谈。一位阿姨盯着屏幕上的 connection timeout,认认真真地问我:“它是不是在骂我?”

那一刻我才想通:透明不是把技术细节摊开,透明是让用户知道发生了什么、跟他有什么关系、他下一步能做什么。三点缺一,用户就会把错误归因于自己。

把技术错误翻译成人话:一个四步流程

后来我给自己定了一个流程,每个技术错误在面向用户之前,都要走四步:

  1. 判定错误类别:是可重试的临时错误(超时、限流),还是不可重试的确定性错误(参数错、没权限)?
  2. 定位用户当前目标:用户此刻想要什么?错误发生在他的哪一步?
  3. 选择叙述视角:不用“接口调失败了”,而用“你要的信息我没拿到”。
  4. 给出最小可行的下一步:不是“请稍后再试”,而是“等一分钟再问”或“换个文件名”。

这四步的产物是一张映射表。给你看一组实例:

原始技术错误 用户触发场景 翻译后的提示
429 rate_limit_exceeded 用户连续问了好几个问题 你问得太密了,我有点喘不过气。等一分钟再继续。
context_length_exceeded 对话历史太长 咱们聊得太久,我已经记不住开头了。建议开个新会话。
tool call failed: file not found 让 Agent 读取某个文件 这个文件我没找到,要不要确认一下路径?
API timeout 让 Agent 处理很重的任务 任务太重,我超时了。可以试着拆成几个小步骤。

注意,同一个技术错误在不同场景下翻译完全不同。比如“429”,如果用户正在回复一条重要的邮件,你可以说“服务繁忙,先点保存草稿,一分钟后再继续”;如果用户只是闲聊,一句“等会儿再试”就够了。这就是为什么不能做一个全局的“错误码词典”——提示必须结合上下文。

比裸错误更阴险的,是模型假装成功

以上讨论的都是程序能捕获的异常。Agent 还有一个独特的问题:模型会把失败包装成成功。

工具调用返回了一个空列表,模型不知道那是“查询无结果”还是“接口报错”,它可能顺着你的预期编一句:“查到了!今日收盘 12.50 美元。”你以为它完成了任务,实际上它什么都没查到。这种错误没有堆栈,没有错误码,你连“翻译”的机会都没有。

解决办法分两层。第一层是提示词强约束,我一般在系统提示里写死一条规则:

当你调用工具失败时,必须这样回应:
- 明确说“刚才的查询没成功”
- 不要假装拿到了数据
- 告诉用户你尝试过什么

但模型天生爱讨好,偶尔还是会越界。所以第二层是工程保障:在 Agent 循环里加一个“错误嗅探器”。一旦工具调用返回错误码,就跳过模型,直接向用户展示预设的降级文案。这样即使模型想撒谎,也没有机会开口。

还有人尝试用另一个模型来翻译错误提示。这个思路很诱人,但要小心:翻译模型也会幻觉。它可能把 “503” 翻译成“你的账号被冻结了”,然后用户开始跟客服吵架。安全做法是,给翻译模型输入三样东西:原始错误码、当前会话摘要、用户可能的意图列表。缺一样,翻译就变成编故事。

你可能会问的三件事

所有错误都要提示用户吗?

不是。只有打断用户目标的错误才需要提示。日志上报失败、后台缓存重建失败,这种错误用户知道了只会徒增焦虑。提示也是成本,提示越多,用户越不信任。

重试按钮永远安全吗?

不安全。限流、网络抖动可以重试;但参数错误、无权限这类确定性错误,重试一万次也没用。重试按钮必须在“错误可恢复性”为真时才出现。

能不能让 Agent 不犯错,从源头省掉错误提示?

不可能。只要 Agent 依赖外部工具和生成模型,错误就是系统固有属性。你能做的是让错误不打扰用户——自动重试、提前降级、或者在错误发生前主动问“文档太长,我只读前 20 页可以吗?”

错误提示的终点,是让错误变成设计过的体验

我最理想的产品状态,是用户根本感知不到 Agent 出过错:任务重了自动拆解、接口超时自动换源、遇到不熟悉的领域先问再答。错误提示只是最后一道安全网。

但现实很骨感:大部分 Agent 产品还在第一版,错误处理是最不被重视的环节。如果你正在做 Agent,请把错误提示当作核心功能来设计。它决定了用户遇到困难时,是觉得“Agent 真笨”,还是觉得“Agent 在帮我”。同样是失败,这两种体验的留存差距,往往比功能本身的差距更大。

下次你在代码里写 catch (e) { show(e.message) } 的时候,请想起那位阿姨。你写下的不是异常处理,是用户和 Agent 之间最后一点体面。

原创文章,作者:guanweilu,如若转载,请注明出处:https://guanweilu.cn/article/1128.html

赞 (0)
上一篇 2026年9月24日 上午1:12
下一篇 2026年9月24日

相关推荐