跳到主要内容

隐形的交接:为什么生产环境中的 AI 故障集中在组件边界上

· 阅读需 10 分钟
Tian Pan
Software Engineer

当你的 AI 功能输出错误答案时,第一个问题总是:“是模型的问题吗?”大多数工程师会进行模型评估,运行几个测试提示词,并得出模型看起来没问题的结论。他们通常是对的。模型没问题。故障发生在其他地方——在你的组件相互通信的那些无形接缝处。

这一结论的证据是一致的。对生产环境 RAG 部署的分析显示,73% 的故障是检索故障,而不是生成故障。在多智能体系统中,最常见的故障模式是消息顺序冲突、状态同步间隙和 schema 不匹配——这些都不会出现在任何单组件健康检查中。GPT-4 在处理复杂的提取任务时,产生无效响应的比例接近 12%,这不是因为模型坏了,而是因为模型与下游解析器之间的输出格式契约从未被强制执行。

模型背了锅,边界才是元凶。

扼杀生产系统的三个交接面

每个 AI 流水线都有一组关键的交接面——即一个组件的输出成为下一个组件输入的点。在大多数架构中,有三个交接面主导了故障场景。

工具输出与提示词对接。 当智能体调用工具时,工具返回数据。这些数据被反馈到下一次 LLM 调用中。如果数据轻微格式错误——缺失字段、非预期的类型,或者技术上存在但语义错误的数值——模型通常不会拒绝它。它会继续运行,并基于错误的前提进行自信的推理。系统记录 HTTP 200,延迟看起来正常,响应读起来也很流畅。没有错误产生。只是出现了一个三个迭代周期(sprints)都没人发现的错误答案。

这里的故障模式不是崩溃,而是基于损坏的上下文生成的听起来很有道理的输出。这类静默失败(Silent failures)最难调试,因为每个组件都报告运行健康。

检索到的上下文与生成器对接。 在检索增强系统中,检索器选取 chunk 传递给模型。模型根据这些 chunk 进行生成。这个交接在描述上很简单,但在实践中却很残酷。固定大小的分块(chunking)会在任意边界切断句子、表格和函数。语义搜索无法将“我该如何取消订阅?”与标题为“账户终止政策”的文档匹配。模型接收到十个最近邻结果,即使其中只有两个是相关的,这用噪声稀释了信号。

结果就是模型对每个查询都给出平庸的答案——不是因为它不能推理,而是因为它在根据错误的输入进行推理。检索器在工作,生成器也在工作,但它们之间的接缝出问题了。

结构化输出与下游解析器对接。 你要求模型返回一个 JSON 对象。它返回了 JSON——除了那 12% 的请求,它可能将 JSON 包装在句子中(”没问题!这是你要的数据:{...}”),或者遗漏了必填字段,或者将数值序列化为字符串。你的解析器会对这 12% 的请求抛出异常,静默地吞掉错误的请求,或者——最糟糕的情况——强制转换类型并将语义无效的数据进一步传播到下游。

在解析器输出作为另一个提示词或工具调用的流水线中,这个交接面变得呈指数级危险。一次糟糕的解析会污染随后的每一个步骤。

为什么标准监控无法察觉边界问题

这些故障之所以持续存在,是因为标准监控是以组件为中心的。你对模型调用进行埋点,追踪延迟和错误率,观察 GPU 显存。你对检索器进行埋点,追踪查询时间和命中率。你对工具进行埋点,追踪执行时间和退出码。

每个组件看起来都很健康。每个组件确实都很健康。但系统坏了。

运行健康(Operationally healthy)与行为可靠(Behaviorally reliable)是不同的属性,大多数监控技术栈无法区分它们。一个成功返回十个无关 chunk 的检索器在运行上是健康的。一个在模型期望字符串的地方返回带有 null 值的 JSON 对象的工具在运行上也是健康的。一个在 800ms 内完成并基于损坏上下文生成流畅段落的 LLM 调用在运行上同样是健康的。

故障存在于组件之间的关系中,而不是任何一个组件内部。标准的可观测性工具对组件进行监测,但不监测关系。

还有一个次要问题:交接故障往往是降低质量而非触发错误。崩溃会显示在你的错误率中。而错误的答案则表现为用户流失、支持工单,或者三周后经理发来的一条 Slack 消息。反馈循环很长,信号很弱,且根本原因难以察觉。

梳理你的交接面

加载中…
References:Let's stay in touch and Follow me for more thoughts and updates