跳到主要内容

LLM 应用的 CI/CD:为什么部署 Prompt 与部署代码完全不同

· 阅读需 12 分钟
Tian Pan
Software Engineer

你的代码通过一个流程发布:特性分支 (feature branch) → 合并请求 (pull request) → 自动化测试 → 预发布 (staging) → 生产环境 (production)。每一步都有门槛。如果没有通过你定义的检查,任何东西都无法到达用户手中。这种“枯燥”正是它最好的地方。

现在想象你需要更新一个系统提示词 (system prompt)。你在仪表盘中编辑字符串,点击保存,更改立即生效 —— 没有测试,没有预发布,版本控制中没有 diff,除了手动改回去之外没有回滚的方法。这就是大多数团队的运作方式,也是提示词更改成为 LLM 应用非预期生产事故主要原因的原因。

挑战不在于团队粗心大意。而在于持续交付 (continuous delivery) 的规范是为确定性系统构建的,而 LLM 并非确定性的。整个思维模型需要从头重建。

核心问题:Prompt 是未经测试的代码

在传统软件中,Bug 通常是可以检测到的。错误的值会抛出异常,缺失的字段会返回 404,损坏的查询会返回零结果。系统会以“大声”的方式失败。

LLM 应用的失败是无声无息的。你的 API 返回 HTTP 200,延迟看起来正常,Token 使用量也正常 —— 但模型现在给出的答案却有细微的错误,幻觉出了上周还没有出现的细节,或者忽略了你认为已经明确指定的约束。用户看到的是质量下降的输出,而你的仪表盘却什么也看不出来。

这就是为什么 Prompt 更改如此危险。从系统提示词中删除一个词、重新排列一条指令、为了节省成本而修剪几个 Token —— 其中任何一项操作都可能改变模型的行为,而这些改变在初看时可能没什么问题,只有在整体汇总时才会显现。对 1,200 多个生产环境 LLM 部署的分析发现,Prompt 更新是导致非预期生产行为的首要原因,排在模型版本更改和基础设施故障之前。

显而易见的解决办法是将 Prompt 视为代码 —— 对其进行版本化、测试,并根据通过标准来设置部署门槛。但这立即引出了更深层的问题:你如何测试一个非确定性的东西?

对 LLM 而言,“通过 CI”意味着什么

在传统的 CI 流程中,测试要么通过,要么失败。函数的输出要么与预期值匹配,要么不匹配。

LLM 评估从根本上是不同的。你定义指标,根据这些指标对输出进行评分,并设置阈值。当评估分数超过你定义的最小值时,测试就算“通过” —— 而不是当输出完全匹配时。

一个 LLM CI 门槛的组成部分:

评估数据集 (Evaluation datasets) —— 一组经过策划的具有预期行为的输入。不是预期的精确输出(每次运行都会变化),而是预期的属性:“这应该包含免责声明”、“这不应推荐竞争对手”、“这应该在三句话内回答”。

评估器 (Evaluators) —— 对输出进行评分的函数。这些函数的范围从简单的字符串匹配(“输出是否包含‘我不知道’?”)到使用独立模型评估质量、相关性或政策合规性的 LLM-as-judge 评估器。

阈值和门槛 (Thresholds and gates) —— 定义“足够好”含义的数字目标。准确率指标可能要求 85% 的通过率。安全性指标可能要求 100% —— 不允许任何失败。

基准对比 (Baseline comparison) —— 使用与当前生产版本相同的数据集对新版本进行评分。如果新版本的评分明显变差,即使它通过了绝对阈值,也被视为回归 (regression)。

像 Braintrust 这样的工具会直接将评估结果发布到合并请求 (pull request) 中,如果分数下降则阻止合并。LangSmith 提供数据集管理和自动评估器运行。DeepEval 将类似 pytest 的评估引入到现有的 Python 测试套件中。这些平台已经从“线下实验的可选配置”转变为“安全部署的必需基础设施”。

关键的洞察在于门槛不是二元的 —— 它是概率性的。这改变了你对发布 (rollout) 的看法。

影子测试:部署新 Prompt 的正确方式

影子模式 (Shadow mode) 是 LLM 变更中置信度最高的部署模式。其核心理念非常直接:当新的 Prompt 版本准备好投入生产时,你将其与在线系统并行运行,为其提供相同的输入,但在输出到达用户之前将其丢弃。

每一个真实的生产请求都在加深你对新版本行为方式的理解。你不再依赖于可能无法捕捉到真实用户查询分布的合成评估数据集。你是在针对真实流量运行候选版本,收集真实输出,并进行离线评分。

运作机制:

  • 在请求到达 LLM 之前,在应用层复制传入的请求
  • 将一份副本路由到当前的生产环境 Prompt,另一份路由到候选版本
  • 仅将生产环境的响应返回给用户
  • 记录两个响应以进行异步评估
  • 在夜间运行你的评估器;次日早晨查看汇总结果

与 A/B 测试的关键区别在于,影子模式完全不会让用户接触到候选版本。A/B 测试会分流,这意味着在测试期间,一半的用户可能会得到质量下降的输出。影子测试则完全推迟了这种风险,直到你对新版本有了统计学上的信心。

局限性在于成本 —— 你正在运行两倍的 LLM 调用。对于高流量应用来说,这笔开销可能非常显著。一些团队通过对采样百分比的流量进行影子测试,而不是全部流量,来缓解这一问题。

金丝雀发布与何时停止

一旦影子测试让你有了信心,下一步就是受控流量曝光。LLM 的金丝雀部署遵循与微服务相同的模式——将一小部分真实流量路由到新版本——但推进或停止的标准完全不同。

对于微服务,你会观察错误率和延迟。对于 LLM,你需要持续运行在线评估:近乎实时地对输出进行评分的轻量级自动化检查。这是一个更难的基础设施问题,因为 LLM 评估本身既昂贵又缓慢。

实际做法:

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