复合幻觉问题:多阶段 AI 流水线如何放大错误
大多数关于幻觉的研究都集中在单次模型调用的输出上。这种框架忽略了一个更可怕的问题:在四阶段的工作流(pipeline)中,如果每个阶段都无条件地信任前一个阶段的输出,会发生什么。第一阶段中一个虚构的事实不仅会持续存在,还会成为后续每一次推理的承重前提。到第四阶段,工作流会给出一个自信且逻辑自洽的答案,但结果却是完全错误的。
这不是一个可以通过更强大的模型来解决的能力问题。这是一个系统架构问题,需要从系统层面进行修复。
大多数关于幻觉的研究都集中在单次模型调用的输出上。这种框架忽略了一个更可怕的问题:在四阶段的工作流(pipeline)中,如果每个阶段都无条件地信任前一个阶段的输出,会发生什么。第一阶段中一个虚构的事实不仅会持续存在,还会成为后续每一次推理的承重前提。到第四阶段,工作流会给出一个自信且逻辑自洽的答案,但结果却是完全错误的。
这不是一个可以通过更强大的模型来解决的能力问题。这是一个系统架构问题,需要从系统层面进行修复。
你的智能体在第三轮对话时明确说过"绝对不要使用 eval()"。到了第三十轮,它调用了 eval()。你的保险处理系统规定"未经有效身份验证,不得批准理赔"。经过十五个压缩周期后,它批准了一笔。这些不是模型失败——是压缩失败。智能体的推理本身没有问题,是摘要中间件把那条唯一关键的约束丢掉了。
上下文压缩如今已成为长时运行智能体系统的标准基础设施。当对话历史增长到超出上下文窗口时,你就会进行压缩——把旧的轮次汇总成摘要,进行修剪、分块或精炼。问题在于,现代摘要器并不是随机破坏信息,而是可预测地沿着特定的断裂线破坏信息,而大多数团队只在生产环境中才发现这些断裂线。
每隔六个月,就会有一款配备更大上下文窗口的模型问世。GPT-4.1 达到了 100 万 Token,Gemini 2.5 紧随其后,达到 200 万,而 Llama 4 如今更是号称支持 1000 万 Token。隐含的承诺是:把所有内容都塞进去,不用再纠结该放什么,让模型自己搞定。
这个承诺在生产环境中站不住脚。一项 2024 年针对 18 个主流 LLM 的研究发现,随着输入长度增加,每一个模型的性能都出现下降——不是某些模型,而是每一个。上下文窗口是天花板,而非地板。把它当作地板来用的团队,正在以痛苦的方式发现这一点。
用户与 AI 助手进行了一个小时的长代码会话。他们建立了规范,分享了代码库上下文,并详细描述了一个多文件重构方案。接着,在第 40 条消息左右,AI 开始给出忽略其“已知”一切的建议。它推荐了一个用户二十分钟前已经拒绝的方案。当被追问时,它显得很困惑。
没有显示任何错误。没有出现任何警告。模型只是静默地丢弃了较早的消息,以为新消息腾出空间——而用户得出的结论是,该 AI 不可靠。
这不是模型失败。这是产品设计失败。
在一个生产环境中的 LLM 功能上线半年后,一名工程师提交了一个 bug:模型在上个季度的某个时间点开始给出错误的输出。没人记得改过提示词(Prompt)。Git blame 显示它为了“提高可读性”被清理过。之前的版本已经找不到了。调试工作只能从零开始。
就在这一刻,团队才发现他们的上下文窗口(context window)从未被真正工程化过——它只是被拼凑出来的。
上下文窗口是你的系统与模型之间的契约。进入其中的每一个标记(token)——系统指令、检索到的文档、对话历史、工具架构、用户查询——都是对一个函数调用的输入,这个调用既费钱又耗时,且会产生非确定性的输出。然而,大多数团队将上下文组合视为实现细节,而非 API 表面。提示词被就地编辑,没有版本控制。各部分通过累加增长。没有人负责布局。变化在无声无息中传播。调试体验比 LLM 时代之前的任何东西都要糟糕,因为至少堆栈跟踪(stack traces)会告诉你什么是改变了的。
你的 AI 功能在测试中运行完美。单轮问答,毫无问题。但在生产环境中,当真实用户进行一场 10 轮调试对话时,它却失败了——不是因为模型出了问题,而是因为你的速率限制器是为一个完全不同的世界设计的。
标准 API 速率限制是专为无状态 REST 调用设计的粗糙工具。每个请求被视为一个独立的、大致等量的消耗单元。对于 CRUD 端点而言,这种模型运行良好,因为每次调用确实具有可比性。但对于多轮对话,这种模型就行不通了——每一个后续轮次的成本都在递增,一次用户交互可能触发数十次内部模型调用,而会话中途被切断造成的损害,远比一次失败的单次查询严重得多。
你的 AI 系统在上午 9 点将一条患者查询路由到了自托管模型。上午 11 点,该模型的 Pod 在部署时重启。请求队列积压,路由器检测到超时,随即回退到你用于通用查询的云端 LLM。请求成功完成,没有告警触发,监控面板一片绿色。而就在这次交互中,受保护的健康信息悄然流向了一个你根本没有签署《业务伙伴协议》的供应商。
这不是假设,而是几乎所有未经专门设计来防范此类问题的 AI 路由栈的默认行为。
你的 LLM API 调用在 P99 分位下于 500 毫秒内完成。但你的用户却在等待 12 秒。这两个数字都是准确的,谁都没有撒谎——它们只是在测量完全不同的东西。两者之间的差距正是大多数 Agent 系统性能无声流失的地方,而且大多数团队从未对其进行过监控(instrumentation)。
问题是结构性的:P99 LLM 延迟是一个应用于多步执行模型的单次调用指标。一个 ReAct Agent 进行五次连续的工具调用、重试一个幻觉化的函数、组装不断增长的上下文并生成 300 个 token 的推理链,这并不是一次 LLM 调用。这是一个分布式工作流,其中 LLM 只是一个节点,而其他每个节点都有其自身的延迟开销。