跳到主要内容

你的 AI 功能可靠性受限于无人负责的上游 ETL 流水线

· 阅读需 10 分钟
Tian Pan
Software Engineer

AI 功能拥有仪表板。提示词(Prompt)有版本控制。评估套件(Eval suite)有轮值表。然后是一个写于 2022 年的上游定时任务(cron job),由一个在两次重组前就退出了分析部门的团队负责,它生成了构建你的检索索引所需的 CSV 文件。那个定时任务没有 SLA。那个 CSV 没有 Schema 契约。负责它的团队根本不知道它正在为一个 AI 功能提供数据。当它发生变化时——它一定会变——AI 团队将花费三周时间去调试一个完全没有出错的提示词。

你即将追踪的 AI 质量回退几乎从来不是 AI 问题。它是一个穿着 AI 外衣的 ETL 问题。需要落实的规范是两者之间的衔接点——契约、血缘(lineage)、新鲜度信号、成对的轮值——而没有将其正式化的团队,所交付的 AI 功能的可靠性将受限于公司里最不受待见的定时任务。

隐形的依赖

AI 功能是一个流水线。这条流水线的最后 20%——提示词、模型、评估框架(eval harness)——是工程投资集中的地方,也是每次复盘开始的地方。而前 80%——摄取任务、规范化步骤、去重处理、每日快照、从第三个上游系统合并进来的列——是在任何人在会议中提到“Agent”这个词之前就构建好的。它由那些认为自己拥有的是一个面向分析用户的数仓的人负责。他们不知道下游有一个 LLM。

这种不可见性就是故障模式。数据团队像对待 Tableau 后端一样对待他们的流水线:重命名一个列是常规清理,每日运行延迟到隔天运行是可接受的降级,Schema 的“改进”只是在 Slack 的分析频道发个通知。这些沟通都没有传达到 AI 团队,因为 AI 团队从未被注册为消费者。没有任何契约规定嵌入(embedding)流水线依赖于 customer_segment 是字符串而不是整数。没有任何消费者注册表会在下游 RAG 索引读取数据团队的输出时向他们发送告警。

与此同时,AI 团队将上游视为绝对真理。他们的评估是针对过去某个时间点拍摄的数据快照进行的。他们的检索之所以有效,是因为列都在他们预期的位置。他们的微调是在他们假设平稳的分布上训练的。每一个假设都是一份从未签署的契约,而上游团队今天下午就可以随意违反其中的每一项,因为没有人告诉过他们自己曾经达成过任何协议。

被记录为“模型回退”的故障模式

这种模式重复得如此频繁,以至于几乎成了一种典型。AI 团队注意到每周评估中的质量下降了四个百分点。延迟正常,错误率正常,模型版本没变,提示词也没变。他们花了一周时间调整提示词。又花了一周尝试不同的分块(chunking)策略。第三周对检索流水线进行消融实验。最终,有人将一批糟糕的输出追溯到某个特定文档,找到了该文档,查看了它最后一次摄取的时间,发现上游流水线在两周前开始过滤掉某一类记录,原因是进行了一次“无害的清理”,删除了标记为“内部”的记录。而该 AI 功能正依赖于这些记录。

第二种模式:上游流水线开始输出精度不同的列。以前是以毫秒为单位的时间戳,现在变成了秒。检索层原本使用时间戳来解决相关性排名的冲突。突然间,冲突解决变得不可预测,同样的查询在不同的日子返回不同的文档,评估套件开始出现波动。模型没问题。检索没问题。数据差了一个小数点。

第三种:由于缩减成本的计划降低了非关键任务的优先级,上游流水线的运行频率从每小时降到了每天。RAG 索引现在有长达 24 小时的滞后。AI 功能开始用落后一天的数据回答关于“最新”信息的问题。没有任何地方触发告警——流水线运行成功,索引更新成功,模型响应成功——唯一的信号是客户满意度在一个季度内悄然下降。

第四种:上游流水线由于有人更改了数仓列类型,静默地将一个长字符串字段截断为 256 个字符。RAG 索引现在包含的分块(chunk)在每个长文档的后半部分都缺失了。检索仍然返回分块。只是分块是不完整的。模型基于不完整的上下文进行回答。幻觉率上升。团队归咎于模型。

在所有这些案例中,AI 团队的前三个假设都是关于模型的。这些假设没有一个是正确的。第四个假设最终指向了数据。数据几乎总是答案,而几乎从来不是人们首先寻找的地方。

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