失败的呈现
坦诚报告失败、部分完成与下一步建议。
一句话理解:Agent 一定会失败,信任取决于失败时的表现:说清做成了什么、没做成什么、为什么、现在的状态是否安全,以及下一步该怎么办;最不可原谅的失败,是假装成功。
一个订单售后处理 Agent 在界面上显示:“✓ 已为您通知客户并创建补偿工单。”第二天客户投诉没有收到任何通知。排查发现,邮件接口当时返回了错误,但 Agent 在最终回复里仍然写了“已通知”。
这类“假成功”比明确的失败危险得多。明确的失败,用户会去补救;假成功,用户会放心地转身离开,直到问题从别处爆发。一旦用户发现过一次,他们就会开始怀疑 Agent 说的每一个“已完成”,之后要么每件事都亲自复查,要么干脆不再使用。
这一课讲失败的呈现。失败的分类见 失败分类,何时停下来找人见 什么时候停下来找人,这里聚焦用户看到的界面与文案。
第一原则:未经验证,不说成功
Agent 的“完成”声明必须建立在验证结果上,而不是建立在“我调用了这个工具”上:
| 动作 | 不可靠的依据 | 可靠的依据 |
|---|---|---|
| 发送邮件通知 | 调用了发送接口 | 接口返回成功,并拿到消息 ID |
| 创建补偿工单 | 调用了创建接口 | 读回工单系统,能查到该工单编号 |
| 修复代码 Bug | 修改了文件 | 相关测试运行通过 |
| 更新网站 meta 标签 | 提交了修改 | 重新抓取页面,确认标签已生效 |
界面上的状态文案要与验证程度严格对应:
- “已发送,消息 ID 8812…” ——已验证
- “已提交发送请求,等待送达回执” ——已执行,未确认结果
- “发送失败:邮件服务返回错误” ——已确认失败
图 1 把验证程度和状态文案对应起来:
验证方法本身见 各类动作的验证方式。产品层面要做的,是 禁止在没有验证结果时使用“已完成”类的文案,并在指令与输出契约中写明这一规则。
结果状态不止成功与失败
把任务结果只分为“成功”和“失败”会迫使 Agent 在模糊情况下二选一,而它往往会倾向于报喜。建议至少区分以下几种:
| 状态 | 含义 | 界面处理 |
|---|---|---|
| 已完成 | 所有目标达成并验证 | 展示产物与验证凭证 |
| 部分完成 | 部分目标达成,部分未达成 | 逐项列出完成与未完成,未完成项给出下一步 |
| 失败,无副作用 | 没有完成,也没有对外部系统产生任何改变 | 说明原因,提供重试或换方式 |
| 失败,有副作用 | 没有完成,但已经执行了部分写操作 | 醒目列出已执行的操作,提供回滚或人工处理入口 |
| 结果未知 | 操作已发出,但无法确认是否生效(例如请求超时) | 明确说“无法确认”,提供查验方式,避免盲目重试造成重复执行 |
| 已停止 | 触达步数、时间或预算上限,或被用户取消 | 说明停在哪一步、已消耗多少,提供继续或调整后重跑 |
“失败,有副作用”和“结果未知”是最需要谨慎处理的两种。例如创建工单的请求超时,直接重试可能会创建两张重复的工单,界面应该先引导查验,而不是一个简单的“重试”按钮。
图 2 给出判定这六种状态的顺序:
一份好的失败报告
以部分完成的订单售后处理为例:
◐ 部分完成:订单 A1024 退款超时处理
目标 查明退款超时原因,通知客户,并为符合条件的订单创建补偿工单
✓ 已完成
· 诊断超时原因:退款审核队列积压,订单滞留 41 小时 [查看证据]
· 客户通知邮件已发送并送达(消息 ID 8812…)
✕ 未完成
· 创建补偿工单
原因:工单系统返回“该订单已存在进行中的补偿工单”,可能已有同事提交过
当前状态:没有创建新工单,系统中无任何改动
建议下一步
[查看已有补偿工单] [仍要创建新工单] [交给人工处理] [标记为无需处理]
这份报告包含五个要素:
- 标题直接给出结果状态,不用“任务结束”这类中性词掩盖。
- 逐项列出完成与未完成,而不是笼统地说“部分步骤失败”。
- 原因用用户能理解的语言说明,并在可能时给出解释(“可能已有同事提交过”)。
- 明确当前状态是否安全:“没有创建新工单,系统中无任何改动”,这是用户最关心却最常被遗漏的信息。
- 给出具体可点击的下一步,而不是“请稍后重试或联系管理员”。
把技术错误翻译成可行动的信息
用户看不懂也不需要看懂原始错误。翻译时要回答“这对我意味着什么、我能做什么”:
| 原始错误 | 糟糕的呈现 | 好的呈现 |
|---|---|---|
HTTP 429 Too Many Requests |
“发生错误:429” | “邮件服务繁忙,已自动排队,预计 5 分钟内发送。无需操作。” |
permission denied: tickets.create |
“权限不足” | “你的账号没有创建补偿工单的权限。可以把这一步转交给有权限的同事。” [转交] |
| 工具返回空数组 | 不提示,继续给出结论 | “未查询到该订单的退款记录,超时原因无法判断。可能是支付系统数据尚未同步。” [1 小时后重查] |
| 达到最大步数 | “任务失败” | “已尝试 30 步仍未找到根因,为避免继续消耗费用已停止。已排除的可能性见下方。” [调整范围后继续] |
| 模型输出不符合格式 | “系统异常” | 内部自动重试;多次失败后:“报告生成失败,诊断数据已保存,可以重新生成报告。” |
注意第三行:工具“成功”返回了空结果,是最容易被忽视的失败。在 Tracing 一课的例子中,正是这种情况导致 Agent 得出了“退款已被撤销”的错误结论。“没有数据”必须作为一种需要说明的情况呈现出来。
失败之后:恢复与学习
好的失败呈现不止于报告,还要让恢复变得容易:
- 从断点继续。已经完成且验证过的步骤不需要重做,用户处理完阻塞点后,Agent 从失败的步骤继续。
- 修改后重试。允许用户调整输入或范围再试,例如“跳过抓取失败的 8 个页面,先出报告”。
- 回滚。对于已经产生副作用的失败,提供回滚入口,或列出需要人工撤销的操作清单,见 不可逆操作。
- 一键反馈。在失败报告上提供“这个结果不对”“原因说明看不懂”等反馈入口,把失败案例送进 持续改进闭环。
图 3 汇总这四条恢复路径:
失败时的语气
- 坦诚直接。 先说结果,再说原因。不要用大段铺垫稀释“没有完成”这个事实。
- 不甩锅,也不过度道歉。 “工单系统返回错误”是事实陈述;连续三句“非常抱歉给您带来不便”只会降低信息密度。
- 不编造原因。 不知道为什么失败时,就说“原因暂不明确”,并给出排查方式,而不是编一个听起来合理的解释。
- 不夸大,也不淡化。 部分完成就说部分完成,不要说成“基本完成”。
常见误区
- “失败会让用户觉得产品不好,要尽量少提。” 恰恰相反,坦诚报告失败是建立长期信任的关键。用户能接受 Agent 做不到,不能接受 Agent 骗他。
- “显示‘出错了,请重试’就够了。” 用户不知道重试是否安全、是否会重复执行、问题是否会自己消失。
- “失败就是失败,没必要区分。” 有副作用与无副作用、结果未知与确认失败,需要完全不同的处理方式。
- “只要最终结论写得谨慎就行。” 失败信息需要结构化呈现:完成项、未完成项、当前状态与下一步,而不是埋在一段措辞谨慎的文字里。
设计要点
- 未经验证,不使用“已完成”类文案;状态文案严格对应验证程度。
- 结果至少区分已完成、部分完成、失败无副作用、失败有副作用、结果未知、已停止。
- 失败报告包含:结果状态、完成项、未完成项及原因、当前状态是否安全、可点击的下一步。
- 把技术错误翻译成“对我意味着什么、我能做什么”。
- 把“工具返回空结果”“数据缺失”作为需要说明的情况,而不是静默忽略。
- 支持从断点继续、修改后重试、回滚和一键反馈。
- 语气坦诚、直接、不编造原因。
练习
为「SEO 诊断 Agent」设计失败呈现(30–45 分钟)。场景:诊断 50 个页面,其中 8 个页面因目标网站限流抓取失败,2 个页面的检测结果超时未返回,其余 40 个正常完成。
- 判断这次任务的结果状态,写出结果标题。
- 写出完整的失败报告,包含完成项、未完成项及原因、当前状态和至少 3 个下一步按钮。
- 为“目标网站限流”和“检测超时”分别写出面向用户的错误说明。
- 设计用户点击“跳过失败页面,先出报告”之后,报告中如何标注这 10 个页面。
延伸阅读
下一步
到这里,你已经掌握了 Agent 从能力、系统、可靠性到交互的全部零件。下一模块「Agent 产品设计」的第一课「找 Job,而不是找 Agent」,会把这些零件整合进完整的产品方法。