跳至正文
Starone

AI 工程

为什么大多数 AI 原型走不到生产环境

原型证明的是模型能给出一次好答案。生产环境需要的是一个系统:每一次都给出可接受的答案,成本可预期,面对的还是没有人整理过的数据。两者之间的差距在于工程,而不在于模型质量。

· 阅读约 4 分钟 · Starone 工程团队

一个 AI 原型通常由一段提示词、一个模型 API 和一小批输入组成,而这些输入是搭建者自己挑的。它回答的只有一个问题:模型到底能不能完成这项任务。这个问题值得回答,notebook 也正是回答它的合适场所。

生产环境问的是另一类问题:遇到没人挑选过的输入会怎样,模型变慢或出错时系统如何表现,单次请求的成本是多少,谁有权看到哪些数据,质量下滑时又如何得知。我们的看法是,大多数原型之所以停滞,是因为这些问题从来不在原型的范围之内,而不是模型能力不够。

演示衡量错了对象

评估一个演示的方式,是有人看几条输出,觉得说得过去。这测的是最佳情况。真实流量里有含糊不清的请求、语言不对的输入、扫描质量很差的文档、系统本应拒绝回答的问题,以及数据里根本没有答案的问题。

语言模型的失败是悄无声息的。传统服务答不上来会返回错误;模型答不上来,返回的是一段通顺的文字。如果没有一种度量能把“正确”和“通顺”区分开,团队就没有任何证据说明系统在见过的样例之外表现如何。

没有评估集,就谈不上工程

我们构建的第一个生产制品不是流水线,而是评估集:一组有版本管理的代表性输入,配有期望输出或评分标准,并且包含困难样例和对抗样例。在它出现之前,每一次提示词修改、模型升级或检索调整都只是猜测,回归问题则要靠用户来发现。

评估集应当像其他测试套件一样在持续集成中运行。结构化输出用精确匹配来检查。自由文本可以由第二个模型按评分细则打分,前提是评分模型本身也要与人工判断做抽样比对。评估集从生产中生长:每一个被报告的失败都会成为一条测试用例。

数据就是系统

在原型里,文档只是某人导出的一个文件夹。到了生产环境,它是一个不断变化的语料库,有归属方、有权限、有重复、有相互矛盾的内容,还有删除要求。那些不起眼的工作都集中在这里:解析表格和扫描版 PDF,决定如何分块,让索引与数据源保持同步,以及在文档被撤回时把它从所有地方清除。

访问控制是最常被遗漏的部分。如果检索不考虑调用方的权限,模型就会替用户总结一份他本无权阅读的文档。过滤必须在查询时依据调用方身份执行,而不是写成提示词里的一条指令。

延迟、成本与长尾

原型可以容忍慢答案,因为只有一个人在等,也没人去数 token。生产路径则有延迟预算和单位成本,而两者都由长尾决定。把多次模型调用串成一条链,其中某一次变慢、被限流或超时的概率也随之成倍放大。

应对手段都是常规的工程做法,只不过用在了一个不寻常的依赖上:

  • 采用流式响应,让用户感知到的延迟是首个 token 的到达时间,而不是最后一个。
  • 设置超时和带抖动的有限次重试,并在主模型不可用时切换到备用模型或返回降级答案。
  • 把简单请求路由到较小的模型,把大模型留给真正需要它的场景。
  • 缓存稳定的提示词前缀和重复的查询,并按功能、按租户追踪 token 用量。

非确定性需要变更管控

同样的输入可能产生不同的输出,而 API 别名背后的模型也可能在你没有任何部署的情况下发生变化。请求路径上任何一处的改动都是一次发布,需要与代码变更同等的管控。

当输出要交给另一个系统使用时,就要对它加以约束。按 schema 生成结构化输出并在使用前校验,可以把一整类解析失败变成一次重试,而不是一条被写坏的记录。

  • 把提示词、模型版本、检索配置和工具定义视为同一个发布单元。
  • 显式锁定模型版本,不要跟随会变动的别名。
  • 把提示词纳入源码管理,像评审代码一样评审它。
  • 只有评估集表明新版本不比被替换的版本差时,才予以发布。

安全与可观测性总是姗姗来迟

模型读取不可信文本时,就可能被这段文本指挥。通过检索到的文档、邮件或网页实施的提示注入,是这类系统最具代表性的安全问题,而且在提示词层面没有彻底的解法。可靠的控制手段在架构层面:限制模型能做的事,把读取权限与执行权限分开,对任何不可逆的操作要求确认。

可观测性是另一个迟到者。生产系统需要为每个请求保留一条 trace,记录提示词版本、检索到的上下文、工具调用、token 数、延迟和最终输出,其中的个人数据按既定策略处理。没有这条 trace,关于某个糟糕答案的投诉就无法复现。

原型恰到好处的时候

以上这些都不是在反对做原型。一个快速、用完即弃的实验,是判断任务是否可行、用户是否需要这个结果的最低成本方式。错误在于把实验直接升级上线,而不是重新构建。我们默认把原型当作一份规格说明:它展示了好的输出是什么样子,生产系统则依据这些证据来做工程实现。

如果只是一个少数人使用的内部工具,而且每条输出都有人审阅,那么稍作加固的原型可能就已经足够。投入的力度应当与答错的代价相称。

正在做类似的事情

我们很乐意交流心得。欢迎与撰写本文的工程师聊聊。