为什么 AI 应用开发要先设计失败状态
AI 应用的失败不只是一条报错,还包括低置信度、超时、格式异常和无法引用。先设计失败状态,才能决定重试、降级、人工接管和用户提示。
先说结论。
AI 应用开发应该在成功页面之前,先画出失败状态。因为模型返回了内容,不代表任务完成;内容可能无法解析、缺少依据、置信不足、超过时限,或者不具备执行下一步的权限。
如果产品只设计“生成中”和“生成完成”,所有不确定性都会被压成一个看似正常的答案。真正可靠的系统,要让失败可见、可恢复、可追踪。
模型成功返回也可能是业务失败
传统接口常用状态码判断成功与否。AI 任务多了一层语义判断:HTTP 请求成功,但摘要漏掉关键日期;JSON 格式正确,但字段值与原文冲突;检索得到结果,但来源不属于当前用户权限。
因此至少要区分技术成功、格式成功、证据充分和业务可用。四层不能用一个绿色对勾代替。
例如合同信息提取接口返回了完整 JSON,但“续约日期”来自附件里的旧版本。解析成功,业务上却不能直接写入系统。
先把五类失败状态命名
第一类是硬错误,包括网络失败、鉴权失败和服务不可用。第二类是超时,任务仍可能在后台继续。第三类是格式异常,输出不能进入下游字段。
第四类是低置信或证据不足,系统无法确认答案可靠。第五类是业务拒绝,例如用户无权查询、内容触发合规规则、动作超过自动执行范围。
命名的价值是让每类失败有不同处理方式。硬错误可能重试,权限拒绝不能重试,低置信应转人工,超时则要避免用户重复提交造成双写。
失败状态决定界面怎么说
“生成失败,请重试”通常信息不足。用户需要知道任务是否已保存、是否会自动继续、重复操作是否安全,以及有没有替代路径。
好的提示不泄露内部堆栈,但应说明下一步。例如:“文档已保存,当前无法提取日期;你可以手动填写,系统不会自动写回。”这比统一弹窗更能保护流程。
对于高风险动作,界面还要显示证据和确认点。系统可以建议客户回复,但在人工点击发送之前,不应把“建议已生成”表现成“任务已完成”。
为每一种失败规定恢复动作
可以建立一张状态表:
| 状态 | 自动动作 | 人工动作 | 必须记录 | | --- | --- | --- | --- | | 服务超时 | 有上限地重试 | 查看任务队列 | 请求标识、耗时 | | 格式异常 | 尝试安全解析或降级 | 修正字段 | 原输出、解析错误 | | 证据不足 | 停止自动写回 | 补充资料或确认 | 检索来源、缺失项 | | 权限拒绝 | 不重试 | 申请授权 | 用户、资源、策略版本 | | 高风险建议 | 保留草稿 | 审批后执行 | 审批人、最终内容 |
恢复动作要幂等。重试不能重复创建工单、重复扣费或重复发消息。
具体场景:知识库没有找到可靠答案
客服知识库收到“这个特殊订单能否退款”。检索只找到通用规则,没有订单类型对应条款。系统不应拼出一个肯定答案。
合理状态是“依据不足”:展示找到的通用规则,标明缺少特殊订单条款,把问题转入待确认队列,并保存用户原问法。知识管理员补文档后,这条问题还能进入回归测试。
这里的失败不是坏结果,而是知识库运营的输入。
常见失败原因是只测正常样本
开发阶段常用短文档、标准问题和稳定网络做演示。上线后才遇到空文件、扫描件、混合语言、重复点击、模型限流和权限变化。
另一个误区是无限重试。没有重试上限、退避和幂等键,短暂故障会放大成成本和数据一致性问题。
还有一种失败是静默降级。系统换了模型或缩短上下文,却没有记录,团队看到质量下降时找不到原因。
边界:一次性低风险工具可以简化
内部头脑风暴、临时改写或无持久化的个人工具,不必搭完整状态机。失败后重新输入,后果也很有限。
但只要结果会写数据库、发给外部、影响权限、生成正式记录或触发付款,就必须把失败状态当成产品功能,而不是日志里的异常分支。
上线前做一次失败演练
主动断开模型服务、返回非法格式、撤销用户权限、制造超时并提交重复请求。逐项检查用户看到了什么、系统保存了什么、谁收到通知、恢复后是否重复执行。
AI 应用的可靠性,不是保证永远不失败,而是失败发生时,系统仍然知道自己在哪里,用户也知道下一步该做什么。
最后还要检查责任边界:产品定义用户提示和替代路径,工程团队保证状态、幂等与日志,业务负责人决定哪些低置信结果可以人工接受。三方如果只约定“异常时联系管理员”,失败状态仍没有真正被设计。把每个状态放进验收用例,并保存一次演练证据,才算从文档进入系统。
发生了什么、真正变化与后续观察信号
发生了什么:模型超时、非法格式和权限变化开始进入真实使用链路。真正变化是失败从一条技术报错变成了用户可理解、团队可分派的业务状态。后续观察信号有三项:
- 信号一:同类失败是否总能进入同一状态。
- 信号二:用户重试是否造成重复写入。
- 信号三:人工接管后是否能从失败点继续,而不是从头重做。
任一信号长期无法回答,说明状态设计仍停留在界面文案。
反例是一次性、只读且低风险的内部脚本,可以只保留简单错误提示。下一步把最近一次线上异常映射到状态表,若找不到对应状态,就补状态、恢复动作和责任人,而不是只补一条捕获异常的代码。
我的判断是,失败状态是否合格,应由恢复路径和责任归属验证,而不是由错误文案是否友好验证。
还要区分“可以重试”和“必须重新确认”。查询超时通常可安全重试,发送邮件超时却可能已在外部成功;盲目重试会造成重复动作。写操作需要幂等键与外部回执,输入变化后旧审批也应失效。
// comments
0 threads登录 后可留言、回复。
- 还没有留言,来做第一个。