CI 流水线中的 AI 智能体:如何为无法单元测试的部署设置质量关口
发布一个调用 LLM 的功能很容易。但要判断该功能的下一个版本是否优于生产环境中的当前版本,却相当困难。传统 CI/CD 对确定性行为提供通过/失败信号:函数要么返回正确值,要么不返回。但当函数封装了一个语言模型时,输出是概率性的——相同的输入在不同运行、不同模型版本和不同时间会产生不同输出。
大多数团队的应对方式是绕过这个问题。他们运行单元测试,对几个提示词做快速的人工检查,然后发布。这种方式在出问题之前都还能用——直到某个模型提供商悄悄更新了底层权重,或者一个看似没问题的提示词改动在孤立测试中没有异常,却在凌晨三点以生产流量规模改变了输出分布。
更好的答案并非假装 LLM 输出是确定性的,而是构建基于分布、阈值和评分标准的 CI 质量关口,而不是精确匹配。
为什么现有 CI 无法捕获 LLM 回归
单元测试的陷阱根深蒂固。团队编写评估来检查给定提示词产生的响应是否在某个指标上超过某个阈值——有用性、忠实度、相关性——并在 CI 中运行这些评估。如果分数高于阈值,构建就通过了。这看起来很严格,但实际上大多不是。
第一个问题是单个评估是点估计,而不是分布。LLM 评估的单次运行是有噪声的——相同的提示词每次产生不同的输出,而对这些输出进行评分的评审模型又增加了另一层噪声。对单个样本的单次通过/失败几乎无法告诉你行为是否在真实输入群体中退化了。
第二个问题是大多数评估套件测试的是快乐路径。工程师根据他们期望模型能处理好的内容编写测试用例。他们真正关心的失败模式——格式错误的输入、对抗性查询、训练数据未预期到的边缘情况——被系统性地低估了。评估套件自信地通过,而真正会在生产中出问题的边缘情况仍未经测试。
第三个问题是集成覆盖率。一个通过所有单元评估的智能体,在与真实外部系统交互时仍可能灾难性地失败:返回意外模式的 API、充满脏数据的数据库、导致智能体陷入循环的超时。模拟这些依赖项会给你一个干净的绿色构建和虚假的安全感。数据即控制流——当你模拟完美响应时,你只测试了快乐路径。
最小可行部署关口
在添加智能体 CI 步骤之前,你需要一个能真正捕获回归的基线。该基线有三个组成部分:
从生产流量中精心整理的黄金数据集。 不是你凭空想出来的合成示例——而是你的系统已经处理过的真实输入,并标注了"良好"的样子。样本应包括边缘情况和接近失败的输入,而不仅仅是你的模型表现良好的输入。精心整理的 50 个真实示例胜过从提示词生成的 500 个合成示例。
评分标准,而不是模糊的问题。 "这是个好答案吗?"这样的评估标准会产生嘈杂、不可靠的分数。有用的标准会明确维度(准确性、完整性、语气符合度、引用正确性),并具体定义每个分数级别的含义。评分标准是产品决策,而不是工程决策——让定义"完成"的团队签字确认。
比较基线,而不是绝对阈值。 与其问"这个输出的分数是否高于 0.8?",不如问"这个输出的分数是否明显低于当前生产环境的提示词?"相对于你正在发布的内容来定义回归,比用数据集和评分标准都已更新后校准的绝对阈值要稳定得多。
有了这三样东西,你就可以设置部署关口:对候选版本和当前生产版本都运行评估,计算差值,如果新版本在分布上的统计得分明显更差,则让构建失败。
添加智能体步骤:它们真正有价值的地方
一旦基线评估关口正常运行,为特定问题类别添加智能体 CI 步骤就有了真正的价值。关键是要明确智能体应该做什么——"让 AI 看一眼"不是一个 CI 步骤。
