跳到主要内容

上游数据质量是你 AI Agent 的真实瓶颈

· 阅读需 11 分钟
Tian Pan
Software Engineer

一个团队花了三个月时间为他们的知识智能体(knowledge agent)调优提示词。他们尝试了 GPT-4,接着是 Claude,然后是一个微调模型。他们重写了六次系统提示词,还聘请了一名提示词工程师。智能体却一直在产生幻觉——语气自信、表达流利,但内容是错的。真正的问题最后被发现是向量库中存放了一份 2023 年的 Confluence 导出文件,以及一份充满矛盾、随意的 Slack 归档讨论,两者都在讨论同一话题。模型只是在履行它的职责:综合处理给定的信息。而这些信息本身就是垃圾。

超过 60% 的生产环境 AI 项目失败可以追溯到数据质量、上下文问题或治理失败,而非模型限制。然而,当智能体表现异常时,人们的第一反应几乎总是修改提示词。第二反应是切换模型。第三可能是增加一个重排序器(reranker)。而喂给整个流水线的上游数据库,在浪费了数月工作时间之前,很少会出现在排错清单上。

为什么模型总是替罪羊

LLM 是概率性的,它们的失败看起来很像推理错误。当一个客服智能体引用了两个季度前的价格政策时,这感觉像是在产生幻觉。当一个文档助手混淆了两个名称相似的不同产品时,这看起来像是一个上下文窗口问题。当一个提取智能体在 15% 的情况下对必填字段返回空值(null)时,这读起来像是模型不一致。

这些诊断通常是错误的。价格政策的失败是因为向量库中存在同一文档的三个版本,且没有时间戳元数据。混淆是因为去年两个产品合并了,但描述字段从未进行协调。空值提取是因为 15% 的源记录本身就有缺失值,而这些缺失值从未在任何监控仪表盘中体现。

模型正在忠实地综合其输入。输入才是问题所在。

这很重要,因为补救路径完全不同。如果是模型的错,你会调优提示词、增加示例或升级模型。如果是数据的错,你需要刷新验证、去重、模式强制执行(schema enforcement)以及完整性监控——这些都不是更好的模型能带给你的。

看起来像模型错误的失败模式

空值传播(Null propagation)。 源数据库中某产品类别字段有 15% 的空值。智能体检索记录,遇到空值后,要么编造一个听起来合理的类别名称,要么悄悄丢弃这些记录。评估(eval)通常两者都抓不住:编造的值能通过格式检查,而丢失的记录不会作为错误显现。只有当下游报表显示出无法解释的缺口时,你才会发现问题。

带有冲突状态的重复记录。 在一个订单管理系统中,一个客户出现在三条记录中——一条来自旧系统导入,一条来自自助服务注册,一条由支持人员创建。负责汇总客户历史记录的智能体综合了这三条信息,产生了一个充满矛盾的概况。模型并没有困惑;它只是拿到了相互矛盾的源材料。

检索语料库中的陈旧文档。 一个 RAG 系统对文档进行索引。源文档更新了,但索引刷新每晚运行且只抓取新文件,而不处理对现有文件的编辑。支持工单开始反映去年的功能。添加元数据新鲜度过滤器也无济于事,因为索引中的文件没有可靠的最后修改字段。

训练与推理时的模式漂移(Schema drift)。 一个智能体是基于 status 为包含四个值的枚举类型的数据库模式构建的。一次迁移增加了一个第五个值,且回填(backfill)只完成了一部分——这意味着 40% 的近期记录有新值,而 60% 仍是旧值。智能体从未被更新以理解新值,从而悄无声息地错误分类了 40% 的近期项目。

跨数据源的字段定义不一致。 “收入”(revenue)一词出现在四个不同的表中,在每个表中的含义都略有不同——一个是毛利,一个是净利,一个不含退款,一个是已收与已确认收入。一个被要求报告“收入”的分析智能体,会选择在语义搜索中检索排名最高的那个源。至于哪一个是最高,取决于最近有哪些文档在与查询类似的上下文中谈论了收入。

15% 的坏记录如何转化为智能体行为

这里的计算是残酷的,因为智能体会跨步骤复合错误。对于单步提取任务,15% 的坏数据率会产生 15% 的错误率。但在一个五步的智能体工作流中,如果每一步都独立接触到这些坏记录,其失败率可能会让习惯于考虑单个模型准确性的团队感到惊讶。

失败模式还取决于错误的类型。缺失字段导致的下游行为不同于格式错误的值,后者又不同于矛盾的值。缺失字段通常会产生优雅但错误的输出——智能体用一个合理的答案填补空白。格式错误的值可能会导致模式验证失败,这至少是可见的。矛盾的值是最难处理的:智能体选择其中一个版本,通常没有任何信号表明存在冲突。

可见性问题由于 LLM 很少说“我不知道”或“这些数据不一致”而变得更加严重。无论输入质量如何,它们都会产生流利、自信的输出。人类分析师看到冲突的数据会标记冲突。而智能体会生成一个综合结果,然后继续执行。

真正有效的四种模式

源头数据契约 (Data contracts)

数据契约是一份关于数据集内容的正式协议:包括必填字段及其类型、每个字段可接受的空值率(null rates)、取值范围和枚举约束、最大允许的陈旧度以及语义定义。在数据进入任何供给 LLM 的管道之前,需要在摄取时对契约进行检查。

关键在于将空值率视为一等公民指标(first-class metrics),而非偶然属性。像 customer_segment workshop 这样的字段如果有 5% 的空值是业务问题;30% 的空值则是数据问题;而达到 80% 的空值则意味着该字段在实质意义上并不存在,下游系统应当停止将其视为可靠信号。契约使这些阈值变得明确且强制化。

带有熔断机制的时效性监控

过时的数据对智能体(Agent)来说尤为危险,因为它会产生带有误导性自信的、针对特定时期的错误答案。智能体幻觉出一个不存在的功能固然糟糕,但智能体引用一个 18 个月前已被废弃的真实功能则更糟,因为它的语气听起来极具权威性。

时效性监控会跟踪数据资产的最后更新时间,并将其与预期的节奏进行对比。对 AI 管道的一个有用补充是熔断器(circuit breaker):当数据源超过其最大陈旧阈值时,依赖该数据源的检索工作流将暂停或重定向到备选方案,而不是默默地提供退化的数据。这需要了解哪些智能体工作流依赖哪些数据源——事实证明,这本身就是一项值得进行的练习。

将去重作为一个持续的过程

大多数去重工作只在迁移时进行一次,然后就停止了。记录会不断从导入、集成和用户创建的条目中累积重复项。对于智能体来说,重复项尤其成问题,因为语义搜索会返回某个概念的所有实例,智能体必须对这些实例进行合成。如果这些实例发生冲突,合成结果将是随机的。

将去重视为一个持续监控的环节——跟踪实体冲突率、针对新记录运行定期去重检查、在重复率超过阈值时发出警报——可以防止索引在数月的生产使用中陷入混乱状态。

从数据开始的根因分诊 (Root-cause triage)

当智能体产生错误的输出时,大多数团队的默认调试流程是:检查提示词(prompt)、检查检索到的上下文、检查模型输出。上游数据源往往是最后才被检查的,甚至根本不查。

在实践中,反转这个顺序会更快。第一个诊断问题应该是:针对此查询的正确答案,是否真实存在于源数据中且准确无误?如果源数据本身就是错的,那么智能体在给定输入的情况下已经正确完成了任务,再怎么优化提示词也无法解决底层问题。

这听起来显而易见,但需要工具化支撑:能够将特定的智能体输出追溯到贡献该输出的具体记录,并直接检查这些记录。如果没有这种可追溯性,团队只能靠猜。

根因测试 (The Root-Cause Test)

一个简单的启发式方法:选取 20 个智能体输出错误的案例。针对每个案例,调取所使用的源记录。询问如果一位人类分析师拿到这些完全相同的记录,是否能给出正确答案,还是这些记录本身就不充分、错误或自相矛盾。

如果人类也会出错,那么问题在于上游的数据质量。如果人类能答对但智能体答错了,那么问题出在检索或生成管道的某个环节。

在实践中,运行此测试的团队会发现第一类问题(数据问题)占主导地位。具体比例因领域和数据成熟度而异,但很少低于失败案例的一半,通常甚至更高。

在进行任何提示词迭代周期之前,都值得运行此测试。它能防止这样一种模式:即数月的提示词工程仅产生微小的收益,因为真正的瓶颈在于需要清理的数据库,而不是需要更好指令的模型。

现在就应增加的工具化设施

如果你正在生产环境中运行 AI 智能体且尚未建立以下机制,那么在进行其他工作之前,这些都值得优先添加:

  • 字段级空值率跟踪:针对所有用作智能体输入的字段。当空值率超过定义阈值时发出警报。
  • 文档时效性元数据:在所有检索语料库中记录。包括索引创建日期、源文件最后修改日期以及自动更新的陈旧度标志。
  • 实体冲突监控:统计解析为同一规范标识符的不同实体的数量。当此增长速度快于底层实体总数增长时,发出警报。
  • 源记录可追溯性:能够将智能体输出映射回贡献它的具体源记录。这对于任何有意义的故障分诊都是必需的。
  • 时效性熔断器:当数据依赖超过其最大陈旧阈值时,自动暂停工作流。

这些工作都不光鲜亮丽。它们不会出现在基准测试分数或模型卡中。但在生产环境的 AI 系统中,它们往往决定了一个智能体是足够可靠以至于可以推广,还是永远处于因一个客服工单就被关停的边缘。

底层模型很重要。提示词质量很重要。检索架构也很重要。但如果你有 15% 的源记录存在格式错误或字段缺失,那么构建在该数据之上的所有内容的上限就是 85% —— 无论你使用哪种模型或如何调优提示词。

References:Let's stay in touch and Follow me for more thoughts and updates