如何在生产前评估LLM
How to evaluate LLMs before production
GitHub 分享了在生产环境中评估基于 LLM 系统的实践,以秘密扫描误报减少为例。团队将评估分为主要结果、安全约束和操作护栏,采用一次一变量、版本化配置的集成测试方法,保持离线评估贴近生产任务,并将生产标签视为信号而非绝对真理。通过合成数据补充覆盖、错误分析定位失败来源,以及 LLM-as-judge 分流人工审查,最终在离线数据集上实现误报减少 95%,同时召回率保持在定义护栏内。
语言模型在干净的基准测试上可能表现良好,但在实际生产中遇到的情况却可能难以应对。在构建基于LLM的系统原型时,基准测试和精选数据集非常有用。它们帮助团队比较模型、测试初始提示,并判断某个想法在技术上是否可行。但随着系统接近生产环境,评估问题发生了变化。真实输入往往模糊不清,标签可能不一致,重要上下文可能缺失或被截断,评估集可能无法反映生产分布。基准测试中很少出现的边缘情况可能成为常见的失败来源。即使离线指标有所改善,这些结果也不一定能顺利转化为生产行为。
我们在评估一个基于LLM的系统时遇到了这些挑战,该系统旨在减少GitHub秘密扫描中的误报。秘密扫描用于识别可能已提交到仓库的凭据,如令牌和密钥。由于某些候选字符串看起来像秘密,但实际上并不代表真实凭据,开发者可能会花费时间调查无需修复的警报。我们需要的不是判断LLM能否正确分类字符串,而是了解系统能否减少噪音警报,同时保持足够的召回率,以确保安全工作流的安全。在这篇文章中,我们分享了一些实践,帮助我们从有前景的原型结果走向生产。这些经验广泛适用于代码分析、开发者工具、安全、数据分析及其他生产工作流中的LLM驱动系统。
1. 从产品决策开始,而非模型
当LLM系统表现不如预期时,第一反应往往是调整其技术组件。团队可能会重写提示、添加上下文、引入另一个推理步骤、调整周围管道或更换模型。在进行任何这些更改之前,他们应该明确评估旨在支持的决策。对于我们的秘密扫描工作,我们问:系统能否在保持足够召回率以确保生产安全工作流安全的同时减少误报?要回答这个问题,团队必须决定哪些错误是可接受的,哪些指标应驱动产品决策,以及哪些护栏必须保持在定义的阈值内。
在秘密扫描中,错误地抑制真实凭据可能比要求开发者审查额外警报更严重。因此,我们没有将精确率和召回率视为同等可互换的指标。我们的主要目标是减少误报并提高精确率。召回率作为安全约束:只有当任何下降保持在预定义的可接受范围内时,实验才能推进。这给了我们一个清晰的方式来评估权衡。我们选择了在满足召回率要求和操作护栏的同时,实现最强误报减少的配置。
我们将评估标准分为三个级别:
主要结果:这衡量了我们试图改善的用户利益:误报减少、精确率
安全约束:这防止表面上的改进引入不可接受的安全风险:召回率
操作护栏:这些决定了结果是否实际可部署:延迟、成本、可靠性、生产兼容性
这种区分防止我们将每个指标视为可互换的。一个减少误报但显著降低召回率的更改并不自动是改进。同样,一个提高质量但使系统过慢、过贵或难以集成的更改也不是改进。考虑两个假设的实验结果:
| 实验 | 精确率 | 召回率 | 延迟 | 决策 |
|---|---|---|---|---|
| 实验A | 大幅改进 | 低于安全护栏 | 可接受 | 不推进 |
| 实验B | 适度改进 | 保持在护栏内 | 可接受 | 继续测试 |
如果单独看精确率,实验A可能看起来更强。实验B更符合产品目标,因为它改善了开发者体验而不违反召回率护栏。在评估LLM系统之前,决定成功对用户意味着什么,以及系统必须尊重哪些护栏。我们想要生成支持产品决策的证据。
2. 将离线评估视为集成测试
基于LLM的系统在首次成功评估后仍会继续变化,因此评估不应是一次性工作。团队会修改提示、采用新模型、改变输入和上下文的构建方式,并优化周围的业务逻辑。任何这些更改都可能改进系统、引入回归或以意外方式改变其行为。因此,我们将离线评估视为端到端集成测试。每当我们对提示、模型、输入构建或更广泛的系统逻辑进行有意义的更改时,我们都会重新运行它。
评估还需要足够可重复,以便每个新结果都能与已知基线进行比较。每次运行,我们都记录提示、模型、数据集版本和系统配置。这使得回答以下问题成为可能:新提示是否在不降低召回率的情况下提高了精确率?模型升级是否在整个数据集上有所帮助,还是仅在特定类别中?输入或上下文的更改是否修复了一个错误模式却引入了另一个?周围逻辑的更改是否一致地改善了结果,还是仅仅转移了错误出现的位置?没有这种纪律,团队很容易在不同条件下比较结果,并将改进归因于错误的更改。
一次更改一个主要变量
仅可重复性是不够的。实验还需要设计得使结果的原因清晰。我们一次更改一个主要变量,并将每次运行与已知基线进行比较。例如,我们在同时测试提示修订和模型升级之前,分别评估了它们。这很重要,因为即使微小的提示更改也可能改变模型行为,而模型升级可能影响质量、成本、延迟或输出一致性。如果两者在同一实验中更改,我们就不知道哪个导致了改进或回归。我们将提示和评估配置视为代码。我们对它们进行版本控制,记录更改内容,保持先前配置可重现,并支持回滚。
| 运行ID | 提示版本 | 模型版本 | 精确率 | 召回率 | 延迟 | 备注 |
|---|---|---|---|---|---|---|
| R-001 | v1 | 模型A | 0.71 | 0.78 | 1.2秒 | 基线 |
| R-002 | v2 | 模型A | 0.75 | 0.77 | 1.2秒 | 仅提示更改 |
| R-003 | v1 | 模型B | 0.74 | 0.80 | 1.0秒 | 仅模型更改 |
上述评估运行跟踪表中的值是假设的,仅用于说明如何跟踪和比较评估运行。
定期测试模型升级
当LLM系统表现不佳时,开发者通常会在提示中添加更多指令。有时这有帮助,但并非总是如此。例如,提示可能承载了来自模型本身的复杂性。更强的模型可能用更简单的提示表现更好,而旧模型则需要大量调优。更简单的提示也更容易理解、测试和维护。模型升级仍需仔细评估。新模型可能在一个类别中提高性能,但在其他地方引入回归。它还可能影响成本、延迟、输出格式或与现有管道的兼容性。评估过程应足够廉价和可重复,使测试新模型成为常规操作。任何对提示、模型或管道的有意义更改都应在进入生产前通过离线评估。
3. 保持离线评估接近生产环境
离线评估只有在类似于系统将在生产中执行的任务时才有用。在秘密扫描工作流中,模型很少评估一个干净、孤立的值。它可能需要评估特定候选值以及周围代码和其他相关信息,这些信息可能相关、不完整或可能分散注意力。信息呈现方式的差异可能实质性影响结果。因此,我们的离线评估需要保留生产任务的重要特征,包括:被评估的候选值、模型可用的周围上下文、相关的支持信息、输入格式化和约束的方式、模型周围的更广泛系统逻辑。
即使微小的差异也可能扭曲结果。更干净的数据集可能排除模糊案例、提供更完整的上下文或移除可能分散模型注意力的附近值。考虑一个简化的例子:
example_token = "sample_value_for_documentation"
production_api_key = get_secret_from_environment()
candidate_value = "flagged_value"
假设candidate_value是系统预期评估的值。模型可能反而关注example_token,因为其变量名看起来更与安全相关,从而产生关于错误值的看似合理的解释。当评估示例只包含一个明显候选值时,这种失败很容易被忽略。它之所以出现,是因为离线评估保留了真实秘密扫描工作流中的一些模糊性和干扰。离线管道越接近生产管道,评估就越有用。当两者不同时,强离线分数可能只是反映了比部署问题更简单的问题。
4. 将生产标签视为信号,而非绝对真理
生产数据可以使评估更具代表性,但其标签通常捕捉工作流结果,而非可靠的真实标签。例如,已关闭或已解决的秘密扫描警报不一定代表误报。开发者可能因为以下原因解决警报:凭据已轮换、风险已被接受、警报需要清除以解锁工作流、警报被错误分类。这些结果在产品数据中可能看起来相似,但代表不同的真实状态。在使用生产标签之前,问:标签是如何创建的?它是否匹配评估试图回答的问题?不同的工作流结果是否被归入同一类别?对于重要或模糊的子集,您可能需要完成手动审查。您不是要消除每个不完美的标签,但需要确保评估数据足够准确以支持所做的决策。
5. 使用合成和开放数据集填补覆盖空白
代表性的生产数据可能在开发早期有限、敏感或不可用。合成示例、学术基准和开放数据集可以帮助开发者启动评估并扩大覆盖范围,但这些示例应补充而非替代类似生产的数据。考虑到这一点,合成示例可以大大帮助填补测试罕见或难以收集案例的空白,如模糊输入、缺失上下文、异常格式和代表性不足的失败模式。例如,凭据字符串列表可以测试模型是否识别常见格式,但不能完全评估模型如何在真实代码中推理候选值。我们调整外部示例以匹配我们的任务,并审查与产品定义不一致的标签。我们还使用现实的失败模式创建了针对性的合成案例,涉及附近的凭据类似值、测试代码、占位符、间接引用和缺失上下文。
6. 使用错误分析发现聚合指标隐藏的内容
聚合指标告诉您系统是否整体改进。错误分析告诉您接下来要更改什么。更高的精确率分数不会揭示剩余错误是来自模糊输入、提示框架不佳、上下文缺失、标签噪音还是数据集狭窄。要理解这些问题,检查失败案例。我们审查了误报和漏报的样本,并按可能来源分组:模型、提示、输入、管道、数据集或标签。反复出现的问题包括已讨论的几种,如推理错误候选值、上下文缺失和与评估定义不匹配的标签。每个类别建议不同的响应。推理错误值指向提示或输入框架,证据缺失指向上下文构建,错误标签需要数据清理。重复的领域特定模糊性可能表明需要更清晰的产品政策或专门的评估类别。
手动审查数十或数百个示例需要时间,但通常能带来更快的进展。一旦反复出现的失败模式清晰,团队可以进行有针对性的更改并衡量是否解决了问题。每个错误的一个有用问题是:这个失败来自模型、提示、输入、管道、数据集还是标签?这种分类将模糊的质量问题转化为具体的工程任务。
7. 使用LLM-as-judge聚焦人工审查
手动审查每个评估示例可能无法扩展。LLM-as-judge可以通过分类清晰案例、识别可能错误标记的示例以及优先处理模糊案例供人工审查来减轻这一负担。由于法官也可能犯错或出于错误原因同意另一个模型,其输出应被视为另一个预测而非真实标签。更安全的模式是使用法官进行分流:自动处理清晰、低风险案例。将低置信度、冲突或高影响案例路由给人工审查员。定期抽样高置信度案例以检查系统性错误。跟踪法官、被评估系统和人工审查员之间的分歧。像任何其他模型组件一样对法官提示进行版本控制和评估。这样使用,法官将人工注意力集中在审查最可能改变结果的案例上。
8. 秘密扫描教给我们的
我们的目标是在安全敏感工作流中减少误报同时保持召回率。离线评估为我们提供了一种受控方式,在开始在线实验之前比较提示、模型、输入和管道更改。通过反复评估和针对性错误分析,我们在评估的离线数据集上实现了误报减少95%,同时将召回率保持在定义的护栏内。更重要的是,我们理解了结果是如何产生的:评估更接近生产任务,更改针对可重现基线进行测量,剩余失败模式已记录。离线评估并未证明系统在每个生产场景中的行为。它提供了足够的结构化证据,以证明在明确理解风险和护栏的情况下进入在线实验是合理的。
清单:在将LLM系统推向生产之前
使用此清单评估您的评估是否提供了足够的证据来推进系统。逐节确认目标、数据、实验和剩余生产风险已清晰理解。
产品目标
- 产品决策和主要成功指标是否清晰?
- 安全和操作护栏是否已定义?
数据和标签
- 评估数据是否类似生产工作流并包含困难案例?
- 我们是否理解标签如何创建以及哪些地方需要人工审查?
评估严谨性
- 是否记录了提示、模型、数据集和管道版本?
- 主要更改是否隔离并与已知基线进行比较?
错误分析和生产准备
- 是否按类别审查了误报和漏报?
- 我们能否重新运行评估并解释离线结果可能在生产中不同的地方?
在信任之前评估
随着基于LLM的系统进入生产,评估应成为常规工程工作流的一部分。强离线评估可以显示产品目标是否在代表性条件下达成、不确定性在哪里,以及系统是否准备好进行受控生产部署。生产不确定性不可避免。评估使其可见、可衡量和可管理。
探索秘密扫描文档 >
《如何在生产前评估LLM》一文最初出现在GitHub博客上。