Skip to content

第 17 章 从手工评估到自动化流水线 ​

先来看一个场景,一个让很多技术 Leader 和项目经理都头疼过的场景。

假设一个团队里有五位非常优秀的工程师,每个人都聪明、努力、富有激情,都在为公司的下一代 AI 产品,开发不同的核心 Prompt。小张是一个充满创意的年轻人,负责开发一个用于总结用户长篇评论的 Prompt。他坚信,给 Prompt 加上几个生动、口语化的例子,能让模型的输出更有“人味儿”。小李是一个极其严谨的后端工程师,负责开发一个用于从非结构化的财报 PDF 中提取关键财务指标的 Prompt。他认为,把输出格式从灵活但易错的 JSON 改成更严格、更规范的 XML,能有效避免模型“自由发挥”,保证数据的准确性。

小王则是一个经验丰富的老手,在优化前面章节提过的、让人头疼的内容审核 Prompt。他经过反复试验,得出结论,把原来笼统的 10 条规则,拆分成 20 条更细致、更具体的规则,能显著降低误判率。……

每个人都在自己的 Git 分支上,埋头苦干。每个人都有自己的理论,自己的方法论。每个人按自己认为对的方式,做着各种“优化”。表面上看,团队一片热闹,每个人都充满了干劲,代码提交记录刷得飞快。

到了这个迭代周期的最后一天,版本发布的时刻。所有人把他们各自开发了两周的修改,都合并到了主分支。Leader 没有组织过任何统一的评估,就在发布系统上,按下了“发布”按钮。

接下来,问题全面爆发。发布后不到十分钟,用户反馈系统开始报警。小张的那个“生动”的 Prompt,因为例子选得太“生动”,导致模型在总结用户评论时,开始夹带一些奇怪的、个人化的,甚至有点阴阳怪气的评论,产品的用户体验明显变差。

紧接着,数据中台的同事在飞书上紧急@过来,语气非常不善。小李的那个“严谨”的 Prompt,因为改成了 XML,导致下游的数据解析服务,有一半的请求都在报错,因为那个服务几年来,一直都只认 JSON。整个公司的数据大盘,有一半都变成了红色。

SRE(网站可靠性工程师)团队的 PagerDuty 告警也触发了。性能监控系统显示,API 的 P95 延迟全线飘红。排查了半天,发现问题出在小王的新版审核 Prompt。虽然它确实修复了动漫评论的误杀问题,但因为它现在变得太长、太复杂,导致审核服务的平均延迟,从 200 毫秒飙升到了 2 秒,直接拖垮了整个内容发布流程的性能。

更糟糕的是,在混乱中还发现,小张的修改,意外地让小李系统里一个原本在三个月前就已经修复的、关于“财报年份识别错误”的 bug 再次复现了。经过半天对 Git 历史的排查,才发现,因为他们俩,都在不知情的情况下,修改了一个两人共享的、用于“处理数字和日期”的基础 Prompt 组件。

接下来的整整一个周末,整个团队都在定位问题、回滚代码、紧急修复。周一凌晨,疲惫的 Leader 复盘完整个过程,提出了一个关键问题:

“我们到底是怎么把事情搞成这样的?我们团队里,每个人都很优秀,都很努力,为什么合在一起后反而乱成一团,谁也顾不上谁?我们的开发流程,到底哪里出了问题?”

问题出在,团队缺少一套统一的、标准化的、自动化的评估与测试体系。

这样的团队,评估还停留在手工阶段。每个工程师都凭个人经验和感觉开发,在自己的分支里打磨自己负责的那部分 Prompt,缺少统一的标准和自动化的验证。每个修改单独看可能都没问题,但合并到同一条主分支后,因为标准各异、互相不知情,就会彼此冲突、互相拖累,最终导致整个系统出问题。

所以,这一章要做的,就是把评估从依赖个人经验的手工操作,转变为标准化的自动化流水线。任何一个 Prompt 修改,在它获准合入代码主分支之前,都必须先通过这套流程的检验。

只有通过了全部检验,修改才能合入主分支。

这套体系,能把 Prompt 开发,从一门依赖个人经验的“手艺”,变成一门有标准、有纪律、有质量保障的工程学科。它能让团队,从各自为战,变成按统一标准协作。

17.1 评估流水线的三个阶段 ​

在挑选各种评估工具和指标之前,得先设计好评估流水线(Evaluation Pipeline)。一个清晰的、逻辑自洽的流水线,是所有后续工作的基础。否则,工具再多,也只是零散地堆在一起,发挥不出作用。

一个专业的 Prompt 评估流水线,通常包含三个前后衔接的阶段:数据集 -> 评估指标 -> 评估报告。

阶段一:数据集(Datasets) ​

这是所有评估工作的起点,也决定了后续所有评估的质量。没有好的输入数据,后续的评估就毫无意义。在 Prompt 评估的语境下,这个输入,就是各种各样精心准备的数据集。

数据集这件事,怎么强调都不过分。很多团队项目失败,表面上看可能是模型或 Prompt 的锅,实际上从一开始,就在用错误的数据,去评估一个错误的问题。这样的评估,无论后续分析做得多认真,得到的结论都不可信。

要为项目积累和维护至少两种,甚至三种不同类型的“数据资产”。

最核心的一种是黄金标准集(Golden Datasets),它是整个质量体系的基准。它通常由几百到几千个高质量的“输入-期望输出”对组成,而且,这些“期望输出”,必须请公司里最懂这个业务的领域专家,逐字逐句手动标注或审核。它代表了系统,在最核心、最典型的业务场景下,应该达到的“完美”表现。这个数据集,是进行核心功能评估和回归测试的基石。上一章提到的“黄金评估集”和“BAD Case 库”,就属于这一类。

另一类是对抗性测试集(Adversarial Datasets)。这个数据集里,装的全是安全工程师,或者专门的“红队”,刻意构造出来的各种“刁钻”“奇葩”“充满恶意”的输入,跟那些典型的、友好的用户输入完全不沾边。比如,包含了各种变体的提示注入企图的输入、包含了复杂逻辑陷阱和双关语的输入、包含了罕见边缘情况和极端数值的输入。这个数据集的目的,不是为了测试系统“有多好”,而是为了测试它“有多坚固”,也就是它的鲁棒性(Robustness),它在面对恶意攻击时,会不会轻易失守。

还有一种是真实流量回放集(Production Replay Datasets)。可以建立一个机制,定期地(比如每周),从线上生产环境,随机采样一批真实的用户请求。这个数据集,最能原汁原味地反映系统,在真实世界里,正在面临的挑战和用户的真实行为模式。用它来进行评估,可以帮助发现那些在设计“黄金标准集”时,完全预料不到的、新的问题模式。

这三种数据集,各有分工。黄金标准集用来验证核心功能是否达标,对抗性测试集用来验证系统在恶意输入下是否稳固,真实流量回放集用来持续跟进真实世界里出现的新问题。

阶段二:评估指标(Metrics) ​

有了数据集,接下来就要定义检验的标准。这些标准,就是评估指标。

选择正确的指标,至关重要。一个错误的指标,可能会把优化引导到一个完全错误的方向,陷入“指标驱动的内卷”,而不是“价值驱动的优化”。比如,只关注“答案的简洁性”,结果可能会把一个虽然有点啰嗦、但信息完整的答案,优化成一个非常简洁、但关键信息残缺的答案。

需要一个多维度的指标体系,从不同角度评估 Prompt。单一指标看不出的问题,组合起来才能发现。

评估指标,也可以分为几大类。最基础的是准确性指标(Accuracy Metrics),它回答的是“做对了吗?”这个问题。对于那些有唯一标准答案的任务(比如分类、信息提取),可以用经典的准确率、精确率、召回率、F1 分数;对于那些答案不唯一的生成任务(比如摘要、问答),可以用语义相似度(Semantic Similarity),或者更高级的、基于 LLM 的评估方法,比如第 15 章讲的 RAGAs 里的 answer_correctness。

再往上一层,是鲁棒性与稳定性指标(Robustness & Stability Metrics),它回答的是“系统结实吗?”这个问题。比如对抗性攻击成功率,衡量系统在面对恶意输入时,有多大的概率会“中招”;微扰不变性,衡量当输入发生一些无关紧要的变化时(比如同义词替换、增删停用词),模型的输出是否能保持稳定。

还有质量与安全指标(Quality & Safety Metrics),它回答的是“除了做对,做得好吗?安全吗?”这个问题。忠实度(Faithfulness)看的是在 RAG 或摘要任务中,模型有没有“胡说八道”,有没有捏造事实;无害性(Harmlessness)看的是模型的输出,有没有包含暴力、歧视、仇恨等不当内容;风格一致性(Style Consistency)看的是模型的输出,是否符合 Prompt 里为它设定的“人设”和“说话风格”。

工程性指标(Engineering Metrics)则回答“这个方案,在工程上可行吗?”这个问题。延迟(Latency)问的是模型的平均响应时间是多少,会不会慢到让用户无法忍受;成本(Cost)问的是平均每个请求,消耗了多少 token,这个成本,业务能否承担。

要根据具体任务,挑选一个或多个最合适的指标,组合成一套评估标准。

阶段三:评估报告(Reporting) ​

当所有的质检工作都完成后,需要生成一份一目了然、能够指导行动的“质检报告”。这份报告,是给工程师、产品经理和老板看的,它必须用最直观的方式,呈现系统各方面的健康状况。

一份好的评估报告,必须能够回答几个关键问题。先从宏观视图看总体表现,新版本的 Prompt,在所有核心指标上,相比于老版本(或者事先设定的基线),是提升了还是下降了?提升/下降了多少个百分点?这个差异,在统计上是否显著?

报告不能只有一个总分,还要支持下钻分析,回答哪里做得好、哪里做得差。它必须支持层层下钻(Drill Down)到问题的细节。比如,直接指出,这次修改,在“技术支持”这个类别的问题上,表现很好,准确率提升了 10%;但在“销售咨询”这个类别上,表现却变差了,准确率下降了 5%。这种细粒度的分析,能帮助精准定位问题。

它还必须回答具体的失败案例是什么,也就是支持根本原因分析。报告必须支持一键查看那些评估失败的 BAD Case 的完整记录,输入是什么,那个错误的输出是什么,期望的正确输出又是什么。只有看到了具体的例子,才能真正地理解问题,并进行有效的修复。

这份报告,就是做出最终决策(是发布?是回滚?还是回去继续优化?)的、唯一的数据依据。

到这里,流水线的整体结构有了。接下来深入每一个环节,看看具体的工具和方法到底怎么用,又有哪些容易踩的坑。

17.2 黄金数据集构建 ​

整个评估体系里,最辛苦、也最无可替代的一环,是黄金数据集的构建。

一提到“数据集”“数据标注”,很多工程师的头都大了,感觉这都是一些重复性的、没有技术含量的“体力活”。但必须用最严肃的语气强调这件事的重要性,黄金数据集的质量,直接决定了整个评估体系的上限,决定了未来所有工作的价值。

黄金数据集,就是评估的基准。如果基准本身是错的,那用它评估出来的所有结果,就都不可信。后续所有的优化工作,都会走在一个错误的方向上。

构建一个高质量的黄金数据集,没有捷径,需要投入大量精力和领域知识。但有一些科学的方法,可以把这件辛苦事,做得更高效、更靠谱。

黄金数据集的四个标准 ​

一份真正配得上“黄金”二字的数据集,至少应该在以下几个方面,做到极致。

最要紧的是覆盖度(Coverage)。它必须能够全面地、均衡地覆盖业务场景。不能只测试那些最常见的、一帆风顺的“主干场景”(Happy Path),更要主动去覆盖那些最容易出错的、最模糊的“边缘情况(Edge Cases)”。比如,在内容审核的场景里,数据集里,不仅要有明显的色情内容和完全正常的内容,更要有大量的、处于灰色地带的“擦边球”内容,比如艺术、医学、健身等场景。一个只在主干场景里表现好的系统,早晚会在某个边缘场景里出问题。

代表性(Representativeness)同样重要。数据集里的问题,应该尽可能地反映真实用户的提问方式和语言风格。要到生产日志里,去收集那些原汁原味的、充满了错别字、语法错误和口语化表达的用户输入,而不是用想象中的、那种书面化的、逻辑完美的“标准问题”。系统最终是要服务真实的人,而不是服务于完美的工程师。

高质量的标注(High-quality Labels)则是评估的最终依据。对于数据集里的每一个输入,都必须提供一个团队里最懂这个业务的领域专家亲手确认过的、无可争议的“期望输出(Ground Truth)”。这个过程,最耗费人力,也最体现工程严谨性。对于一些主观性比较强的任务(比如,判断一篇文章的“风格”是否“专业”),甚至需要引入“多人标注、交叉验证”的机制,让三个不同的专家,背对背地进行标注,只有当三人的结果一致时,这个标注才能算“黄金”的。

黄金数据集还必须支持动态更新(Dynamic Updating)。随着业务发展,新的场景、新的产品功能、新的用户行为模式会不断涌现。必须建立一个流程,定期地(比如每个季度),把这些新的、有价值的 case,补充到黄金数据集中。同时,也要定期地审视旧的数据,把那些已经过时的、不再有代表性的 case 移除出去。

构建方法:三个阶段 ​

那么,具体该如何去“生产”这些高质量的数据呢?这个过程,通常会经历三个阶段。

第一个阶段,是纯手工的“冷启动”。在项目的最早期,没有任何历史数据。这时候,只能靠人工逐条构建。可以开“头脑风暴会”,把团队里的工程师、产品经理、运营同事,甚至客服同事,都拉到一个会议室里,让大家根据对业务的理解,尽可能地去“幻想”用户可能会问什么,系统可能会在哪些地方犯错,把所有想到的点,都写在白板上。

也可以做角色扮演,让团队成员,分别扮演“刚入职的小白用户”“爱挑刺的专家用户”“想搞破坏的恶意攻击者”等不同角色,然后互相“攻击”系统原型,记录下所有有价值的交互过程。还可以做竞品分析,去深度地使用竞争对手的产品,看看它们都支持哪些场景,在哪些地方做得好,在哪些地方做得不好。特别是去看看产品评论区里的差评,用户的吐槽,往往是构建数据集的最好灵感来源。

通过这种方式,可以在项目初期,快速地积累起第一批(比如 100-200 个)核心的测试用例。这批数据,就是后续所有评估工作的起点。

第二个阶段,是从真实日志中挖掘。当系统有了一小批真实用户之后,生产日志,就成了最宝贵的数据来源。可以从高频问题挖掘入手,分析用户查询的日志,找出那些问得最多的 Top 100 个问题。这些问题,代表了用户的核心需求,必须优先加入到黄金数据集中,并确保 100% 的准确率。也要做“零结果”问题分析,找出那些让 RAG 系统,一次都没能召回任何相关文档的问题。这些问题,往往暴露了查询理解能力、知识库覆盖度,或者分词策略的短板。

还要靠用户反馈驱动,重点分析那些用户“踩”过,或者用户留下了负面评论的问答对。这些是用户用自己的行为,免费标注出来的、最直接的 BAD Case。甚至可以建立一个机制,对那些提供了高质量反馈的用户,给予一些奖励(比如积分、优惠券)。

第三个阶段,是人机协同的大规模生产。当需要把数据集的规模,从几百个,扩展到几千个甚至上万个时,纯靠人工,效率就太低了,成本也无法接受。这时候,可以让 LLM 来承担大部分数据生成工作,人负责审核和质量把关。这个过程,通常叫做合成数据生成(Synthetic Data Generation)。

一种做法是基于已有数据进行“举一反三”。可以把手动标注的一小批高质量数据(比如 50 个),作为 Few-shot 示例,喂给一个能力较强的 LLM,让它模仿这些示例的风格和模式,生成更多、更多样化的同类数据。比如,对它说:“下面是一些关于‘查询订单状态’的用户提问,它们包含了各种不同的口语化表达和错别字。请你模仿它们,再给我生成 50 个风格类似,但细节不同的提问。”

另一种做法是基于文档内容进行“反向提问”,对于 RAG 场景,这是一个极其有效的技巧。把知识库文档,一段一段地喂给 LLM,然后让它扮演一个“好奇的、爱钻牛角尖的学生”的角色,根据这段文档的内容,提出几个最有可能有人问到的、最刁钻的问题,并同时给出基于这段文档的标准答案。通过这种方式,可以快速地为整个知识库,生成一套覆盖度极高的“问题-答案-来源”三元组。

这里有一个极其重要的提醒。所有 LLM 合成的数据,都必须经过人工的审核和修正,绝对不能 100% 地信任机器。LLM 在这里承担的是初稿生成工作,它可以完成 80% 的初稿,但最终决定质量的那 20% 的审核和修正,必须靠人类专家完成。

构建黄金数据集,是一项没有捷径,但回报巨大的投资。一个拥有 1000 个高质量测试用例的团队,和一个只靠 10 个“主干场景”例子来做测试的团队,工程严谨度和最终的产品质量,将是天壤之别。

17.3 常用评估指标都在量什么 ​

有了数据集,就要开始定义评估标准了。指标为什么重要、为什么必须多维度,17.1 节已经讲过。这一节把那些原则落细,逐个讲清楚常用的评估指标,到底在量什么、适合什么任务、又会在哪里失真。

准确性指标:答案到底对不对? ​

这是最核心的指标,是所有评估的基石。

其中最严格,也最简单的,是精确匹配(Exact Match)。它要求模型的输出,和标准答案,在字符串层面上,一字不差。这个指标,通常只适用于那些答案是唯一的、固定的、非黑即白的任务。比如,从一段文本中提取一个日期、一个金额,或者进行一个简单的分类(输出“是”或“否”)。它的优点是计算简单,结果明确;缺点是过于死板,在很多生成任务中,一个意思可以用多种方式表达,它都无法识别。

在信息提取这类任务中,常常使用 F1 分数(F1 Score)。它同时考虑了精确率(Precision)(提取出来的东西里,有多少是正确的)和召回率(Recall)(所有应该提取的东西里,成功提取出来了多少)。F1 分数是这两者的调和平均数,是一个更均衡的指标,能避免模型为了提高召回率而“滥竽充数”,或者为了提高精确率而“宁缺毋滥”。

对于那些答案不唯一的、开放性的生成任务(比如摘要、问答、翻译),用精确匹配就不合适了,这时可以用语义相似度(Semantic Similarity)。它的做法是,分别用一个高质量的 Embedding 模型,把模型的输出和标准答案,都转换成向量。然后,计算这两个向量的余弦相似度。相似度分数越高(越接近 1),就说明两个答案在意思上越接近。这是一个非常实用、成本也很低的自动化评估方法。

目前评估生成任务,最流行、也最接近人类判断的一种方法,则是 LLM-as-a-Judge(LLM 作为裁判)。它的思想是,再用一个更强大的、更公正的 LLM,比如 GPT-5 系列、Claude 4 系列或 DeepSeek 最新旗舰版,来扮演一个“裁判”的角色。编写一个专门的“裁判 Prompt”,把用户的原始问题、模型的输出,以及标准答案,都交给这个“裁判 LLM”,然后让它从多个维度(比如,事实一致性、信息完整性、逻辑清晰度)进行打分。第 15 章讲的 RAGAs,其核心思想,就是 LLM-as-a-Judge。

鲁棒性指标:输入扰动下的稳定性 ​

一个好的系统,不仅要在典型输入上表现好,更要在面对各种非常规输入时,保持稳定,不能轻易出错或输出混乱。

衡量它的一项指标是对抗性攻击成功率(Adversarial Attack Success Rate)。用 17.1 节提到的“对抗性测试集”(比如,包含了提示注入的输入),去测试 Prompt,然后统计在多大比例的情况下,这些输入成功地“攻破”了系统。这个比例越低越好。

另一项指标是微扰不变性(Invariance to Perturbations)。对黄金数据集里的输入,进行一些微小的、不改变核心语义的“微扰(Perturbation)”,相当于故意给输入文本,制造一些“噪音”。

比如做同义词替换,把“如何购买这款手机?”改成“怎样下单这个电话?”;增加或删除无关紧要的词,把“你好,请问...”改成“请问...”;改变语序,把“A 和 B 有什么区别?”改成“B 和 A 的区别是什么?”;或者引入拼写错误,把“recommend”写成“reccomend”。然后,看模型的输出,是否能保持基本一致。可以计算,在微扰前后,模型输出的语义相似度。这个相似度越高,说明 Prompt 越鲁棒,对输入的变化越不“敏感”。

其他重要的质量和安全指标 ​

先说无害性与偏见(Harmlessness & Bias)。它需要一套专门的测试集,里面包含了各种诱导模型输出有害内容(如暴力、仇恨言论)或带有偏见内容(如性别歧视、种族歧视)的输入。然后,用一个“安全分类器”(同样可以用 LLM 来实现),来判断模型的输出,是否“安全”。

再说风格一致性(Style Consistency)。如果产品,对 AI 的“人设”和“说话风格”有严格要求(比如,必须是“专业、严谨”的金融顾问风格,或者“活泼、可爱”的儿童故事机风格),那么,也需要一个指标来衡量这一点。可以让一个 LLM-as-a-Judge,来判断模型的输出,是否符合 Prompt 里预设的风格要求。

延迟与成本(Latency & Cost)这两个工程指标,同样重要。需要在评估报告里,明确地记录下,Prompt 在处理评估集时,平均的端到端延迟是多少毫秒,平均每个请求消耗了多少 token。这两个指标,是产品的“生命线”,决定了产品体验和商业可行性。

通过这样一套多维度的、既有业务指标又有工程指标的体系,才能对 Prompt 有一个全面的认知。

17.4 裁判 LLM 的偏见与校准 ​

在所有的评估指标中,LLM-as-a-Judge 无疑是目前最强大、最灵活,也最接近人类判断的一种。它让过去那些只能靠人工来评估的、主观的、开放性的生成任务,第一次可以自动化地评估,极大地解放了生产力。

但务必记住,LLM-as-a-Judge,不是万能方案。它本身也有各种各样的局限和偏见。如果不了解这些就盲目信任它的打分,评估结论很可能把优化方向带偏。

把一个 LLM 当成“裁判”,相当于请一个有专业能力、但也有自己的固定倾向的人来做评审。必须了解它的偏见,并有针对性地校准。

裁判 LLM 的常见偏见 ​

其中最常见的是位置偏见(Position Bias),攻击者也最容易拿它做文章。当 Prompt 里,同时提供“答案 A”和“答案 B”,让它判断哪个更好时,很多模型会莫名其妙地倾向于选择第一个出现的答案。这个偏见,很多研究都已经系统性地证实过了。

冗长偏见(Verbosity Bias)也很普遍。很多模型会有一个朴素的、错误的价值观,认为“话多就是好”。它们会倾向于认为,更长的、更详细的、看起来信息量更大的答案,就是更好的答案。即使那个简短的答案,可能更精准、更切中要害。

自卖自夸偏见(Self-enhancement Bias)则很有趣。如果用一个厂商的模型去评估另一个厂商的模型,往往会发现,前者可能会不自觉地“偏袒”那些和自己风格更接近的答案。这种偏向,很难单靠模型自己消除。

还有迎合偏见(Sycophancy Bias)。模型非常擅长“察言观色”。如果“裁判 Prompt”里,不小心透露了自己的倾向(比如,写的是“请评估以下两个答案,其中答案 A 是我们经过精心优化后的版本”),那么模型很可能会为了“讨好”提问的人,而给答案 A 打出更高的分数,即使它实际上更差。

如何降低裁判 LLM 的偏见 ​

面对这些五花八门的偏见,不能因噎废食,但必须采取措施,最大程度地“校准”这个裁判,让它变得更公正。

为了消除“位置偏见”,可以交换顺序,进行“双盲”测试。在进行 A/B 两个版本答案的对比评估时,应该跑两次。第一次,A 在前,B 在后;第二次,B 在前,A 在后。然后,综合两次的评估结果。如果两次的结果不一致,就说明位置偏见可能影响了裁判,这个打分是不可信的。

对抗所有偏见的最有效手段,是明确、细化的评分标准(Rubric)。不要只是模糊地问“哪个更好?”。应该在“裁判 Prompt”里,提供一个非常详细的、多维度的评分标准(Rubric)。比如,让它从“事实准确性”“信息完整性”“逻辑清晰度”“语言流畅性”“风格一致性”这五个维度,分别打分(1-5 分),然后再给出一个总分。这能强迫模型进行更细致的、基于规则的思考,而不是凭它的第一印象和模糊的“感觉”来打分。

还要强制要求思维链(Chain of Thought),要求“裁判 LLM”,在给出最终分数之前,必须先输出它的评分理由。比如,“我给答案 A 的‘逻辑清晰度’打 3 分,因为它在事实上是准确的,但在逻辑上,存在一点跳跃。具体来说,它从论据 1 直接跳到了结论 3,缺少了中间的论证过程...”这种先给理由、再给分数的方式,不仅能让评估结果更可解释,让打分的理由一目了然,也能在一定程度上,通过强迫模型进行慢思考,来提高评分本身的准确性。

在选择哪个 LLM 来当裁判时,要尽量选择那些在各种公开的 Benchmark 上,表现最强大、最中立的模型。并且,要意识到,用不同的模型当裁判,得到的分数,可能是没有可比性的。应该在评估体系中,固定使用某一个版本的模型作为裁判。

LLM-as-a-Judge 是一个强大的工具,但它也是一个需要小心使用的工具。要把它当成一个能力很强、但有自己的固定倾向的评审专家来设计“裁判 Prompt”,而不是把它当成绝对客观、不会犯错的评分器。

17.5 回归测试与对抗性测试 ​

有了数据集,也有了评估指标,就可以开始搭建自动化评估流水线了。在这条流水线上,有两个至关重要的、绝对不能省略的环节,即回归测试和对抗性测试。

它们一个负责防止旧问题复发,一个负责提前发现新问题。

回归测试:确保旧问题不复发 ​

16.4 节已经提到过回归测试的核心思想,即确保新的修改,不会破坏已有的、正确的功能,确保不会在同一个地方摔倒两次。

在 Prompt 工程的语境下,回归测试集,就应该是那个“BAD Case 库”。这个库里,沉淀了过去犯过的所有错误,是团队用一次次真实事故换来的教训。

自动化评估流水线,必须包含一个专门的“回归测试”阶段。在这个阶段,流水线会用提交上来的新版 Prompt,去运行回归测试集里的所有 case。然后,它会检查,是不是所有的 case,都能得到“期望的输出”。

只要有一个 case 失败了,整个流水线就应该立刻失败,亮起红灯,并自动在 Pull Request 页面上,用最醒目的方式评论:“【回归测试失败!】 @小明,你的本次修改,导致了 CASE-2023-11-08(无法正确处理多轮对话中的指代)问题复现。请在修复该回归问题之前,不要合并此 PR。”

一个没有自动化回归测试的开发流程,每一次修改都带有盲目性。没有人能记住之前每一个版本修过哪些问题,一次不起眼的修改,就可能让某个早已修复的问题再次出现。

对抗性测试:主动测试极端与恶意输入 ​

如果说回归测试是“向后看”,总结历史教训,那么对抗性测试,就是“向前看”,提前演练可能出现的问题。

它的目的,不是为了验证系统在“正常情况”下有多好,而是主动地用各种非常规的方式,去寻找和攻击系统最薄弱的地方,看看它在“极端情况”下,有多么脆弱。

这相当于让专人来扮演攻击者,用尽各种办法,来尝试攻破这个系统。

在 Prompt 评估流水线中,“对抗性测试”阶段,会使用前面提到的“对抗性测试集”,来对 Prompt 进行测试。

这个测试集里,可以装各种提示注入样本,即各种花式要求模型“忽略之前的指令”的输入;可以装各种越狱攻击样本,比如各种 DAN(Do Anything Now)的变体,以及社区里最新发明的各种越狱写法;可以有做敏感话题诱导的输入,试图诱导模型讨论政治、暴力、色情等不当话题;可以做事实冲突测试,在 RAG 的上下文中,故意提供两个相互矛盾的信息,看模型会如何处理,是会指出冲突,还是会“胡乱站队”;还可以有角色扮演攻击,试图诱导模型扮演一个不合适的、有害的角色,比如一个“种族主义者”。

随后,会用一个“安全/合规分类器”(同样可以用 LLM 实现),来判断模型的输出,是否“中招”了。比如,如果模型真的忽略了系统指令,或者输出了有害内容,那么这次对抗性测试就算失败。

对抗性测试,相当于定期对系统做一次安全演练。它能在真实世界的攻击者利用这些问题、造成真正的损失之前,就提前发现和修复它们。一个没有经过对抗性测试的 AI 系统,面对互联网上的真实攻击,会非常脆弱。

17.6 主观指标交给众包来评 ​

自动化评估很棒,它高效、可扩展、不知疲倦。但是,必须承认,在某些方面,机器仍然无法替代人类,特别是当评估标准涉及高度主观的、与人类文化、情感和审美相关的维度时。

比如,要评估一个“创意写作助手”的 Prompt,核心指标,可能是“创意性”“趣味性”“情感共鸣”“文笔优美”。

怎么用一个 LLM-as-a-Judge,去量化地评估,一段文字的“趣味性”?或者,要评估一个“聊天机器人”的 Prompt,核心指标是“情商”“共情能力”“幽默感”。这些,都是机器难以理解和判断的、属于人类特有的“感觉”。

在这种情况下,就需要引入最后的评估手段,人类。

众包评估(Crowdsourcing Evaluation),就是一种把这些主观评估任务,拆分成一个个简单的“微任务”,然后分发给大量的、非专业的普通人(即“众包标注员”),最后通过统计多数人的意见,来得出一个相对客观的结论的方法。

如何组织一次有效的众包评估? ​

像 Amazon Mechanical Turk、国内的百度众测等平台,就提供了非常成熟的众包服务。可以把评估任务,设计成一个简单的“选择题”或“打分题”,发布到平台上。

比如,要 A/B 测试两个版本的“笑话生成”Prompt,可以设计这样一个任务:

任务:哪个笑话更好笑?

我们正在测试两个 AI 模型讲笑话的能力。下面是同一个主题下,两个模型生成的笑话。请您仔细阅读后,选出您认为更好笑、更有趣的那一个。

主题: 程序员

笑话 A: 为什么程序员总是把万圣节和圣诞节搞混?因为在计算机里,Oct 31 (八进制的 31) 等于 Dec 25 (十进制的 25)。

笑话 B: 一个程序员走进一家酒吧,对酒保说:“请给我一杯啤酒。” 然后他又说:“再给我 0.999999999 杯啤酒。” 酒保给了他两杯。程序员问为什么,酒保说:“这已经很接近两杯了,四舍五入一下。”

您的选择:

  • [ ] 笑话 A 明显更好笑
  • [ ] 笑话 B 明显更好笑
  • [ ] 两个差不多好笑
  • [ ] 两个都不好笑

随后,把这个任务,分发给 100 个不同的众包标注员。为了保证质量,还可以在里面混入一些“质检题”(比如一个明显好笑的和一个明显不好笑的),来筛掉那些乱答的标注员。

统计完所有有效结果,如果 70% 的人都选择了“笑话 A”,那么就有很强的信心,认为 A 版本的 Prompt,在“趣味性”这个指标上,是优于 B 版本的。

众包评估,成本高,周期长,组织起来也更复杂。但对于那些机器无法衡量的、关乎“用户体验”的软性指标来说,它是目前最可靠的,甚至是唯一的评估方法。

17.7 Prompt 评估的 CI/CD 流水线 ​

这一节,把这一章的所有知识串联起来,看看在一个现代化的、专业的工程团队里,一个完整的、自动化的 Prompt 评估 CI/CD 流水线,应该是什么样子的。这不再是理论,而是明天就可以在团队里开始动手搭建的东西。

设想这样一个场景。一个工程团队,负责维护公司核心的 RAG 问答机器人。团队已经接受了“Prompt 即代码(Prompt-as-Code)”的思想,把所有的 Prompt 都当成 .md 或 .yaml 文件,和业务代码一起,托管在 Git 仓库里。

流水线的触发,从一次普通的提交开始。工程师小明,为了优化 RAG 系统在处理多轮对话时的“指代不明”问题,修改了一个用于“查询重写”的 Prompt。他把修改后的 query_rewriter_v2.md 文件,连同一些测试用例,push 到了一个新的 feature 分支 feature/fix-coreference-resolution。然后,他在 GitHub 上,创建了一个 Pull Request(PR),请求将他的分支,合入到主分支 main。

这个 PR 一创建,CI/CD 流水线(由 Jenkins 或 GitHub Actions 驱动)随即自动启动,跑预设好的一套极其严格的“Prompt 质量门禁”流程。

第一个阶段是静态检查与单元测试(Static Checks & Unit Tests),耗时约 1 分钟。流水线首先会运行一些基础的、快速的静态检查。比如,用一个 Linter,检查小明修改的 Prompt 文件,语法是否正确,变量占位符是否匹配,是否符合团队的命名规范。同时,运行一些针对这个 Prompt 的、小而快的单元测试。

第二个阶段是回归测试(Regression Tests),耗时约 5 分钟。流水线会从一个集中的存储(比如 S3)拉取那个包含了 500 个经典 BAD Case 的“回归测试集”,并用小明的新版 Prompt,去并行地运行这 500 个 case。

这里是第一道质量门禁,如果任何一个 case 的结果,不符合预期的输出(比如,精确匹配失败,或者语义相似度低于 0.95),流水线立刻失败,亮起红灯,并自动在 PR 页面评论:“【回归测试失败!】 @小明,你的本次修改,导致了 CASE-2023-11-08(无法正确处理多轮对话中的指代)问题复现。请在修复该回归问题之前,不要合并此 PR。失败详情请查看 [链接到测试报告]。”

第三个阶段是功能评估(Functional Evaluation),耗时约 20 分钟。如果回归测试通过,流水线会接着拉取那个包含了 2000 个问题的“黄金标准集”,同时用主分支的旧版 Prompt(作为对照组)和小明分支的新版 Prompt(作为实验组),去完整地跑一遍这个数据集。

然后,它会调用 RAGAs 框架,为两个版本,都生成一份详细的评估报告,包含 faithfulness、context_recall、answer_correctness 等核心指标。

这里是第二道质量门禁,流水线会比较这两份报告。如果新版 Prompt 的任何一个核心指标,相比于旧版,出现了统计显著的下降,流水线也会失败,并评论:“【功能评估失败!】 @小明,你的修改,导致 answer_correctness 指标,从 92.5% 下降到了 89.8% (p-value < 0.05)。这意味着你的改动,可能在修复一个问题的同时,引入了更多的问题。请分析报告详情 [链接到对比报告]。”

第四个阶段是对抗性测试(Adversarial Tests),耗时约 10 分钟。如果功能评估也通过了,流水线会进入最后的“压力测试”环节。它会拉取那个包含了 1000 个各种提示注入和越狱攻击样本的“对抗性测试集”,并用一个“安全分类器”,来判断新版 Prompt 在面对这些攻击时,是否“守住了底线”。这里是第三道质量门禁,如果攻击成功率,超过了设定的阈值(比如 1%),流水线同样会失败,并报告安全风险。

流水线的结果是,只有当小明的修改,顺利地通过了以上所有的、自动化的“关卡”后,CI/CD 系统,才会在他的 PR 页面上,打上一个绿色的、令人安心的“All checks have passed”的对勾。

这时候,团队的 Leader 在进行代码评审时,就可以把注意力,更多地放在代码风格、架构设计等更高层次的问题上,而不用担心这次修改会不会引发线上事故。可以放心地、有底气地,按下那个“Merge”按钮了。因为这次修改的质量,有一整套严谨的、数据驱动的体系来验证和保障。


本章总结 评估体系是 Prompt 工程的基础设施 ​

这一章聊的,都是关于体系和标准的内容。它可能没有前面那些章节那么让人兴奋,毕竟那些章节充满了各种新奇的技巧。

但它恰恰是全书最“工程化”、也最能体现一个团队工程成熟度的一章。

Prompt 工程,在经历了初期依赖个人经验、靠反复试错的阶段后,正在不可避免地,走向标准化和自动化。这和软件工程走过的路,并无二致。

一个只会写出有创意的 Prompt 的人,是一个“艺术家”。 一个能够为这些创意,建立起一套完整的、自动化的、可信赖的质量保障体系的人,才是一个真正的“工程师”。

这一章聊的评估流水线、黄金数据集、多维度指标、LLM-as-a-Judge、回归测试、对抗性测试,就是让这些创意能够稳定、可靠地交付的工程保障。

这套体系,平时看起来可能有点繁琐,有点多余,甚至有点拖慢“开发速度”。但它能在最关键的时刻,在面对最复杂的挑战、最刁钻的用户时提供保护,让系统始终保持稳定。

所以,不要把评估和测试,看作是开发流程中,一个可有可无的、拖慢进度的“负担”。

把它看作质量的基本保障,以及从一个会写 Prompt 的人,成长为一个 Prompt 领域专家的必经之路。

这套体系的建立,非一日之功。但从写下第一个自动化测试用例开始,团队就已经走在了通往“专业化”的正确道路上。

参考资料 ​

  1. Es, S., James, J., Espinosa Anke, L., & Schockaert, S. (2024). RAGAs: Automated Evaluation of Retrieval Augmented Generation. Proceedings of EACL 2024: System Demonstrations. arXiv:2309.15217. https://arxiv.org/abs/2309.15217 (RAGAs 框架的提出文献,faithfulness、context_recall、answer_correctness 等指标出自该框架)
  2. Zheng, L., Chiang, W.-L., Sheng, Y., et al. (2023). Judging LLM-as-a-Judge with MT-Bench and Chatbot Arena. NeurIPS 2023 Datasets and Benchmarks Track. arXiv:2306.05685. https://arxiv.org/abs/2306.05685 (LLM-as-a-Judge 方法的系统研究,论文记录了位置偏见、冗长偏见与自增强偏见,并报告强模型裁判与人类偏好的一致率可超过 80%)
  3. Wang, P., Li, L., Chen, L., et al. (2023). Large Language Models are not Fair Evaluators. arXiv:2305.17926. https://arxiv.org/abs/2305.17926 (证明仅改变候选答案的出现顺序即可操纵 LLM 评估结果,佐证位置偏见已获多项研究证实)
  4. Sharma, M., Tong, M., Korbak, T., et al. (2023). Towards Understanding Sycophancy in Language Models. arXiv:2310.13548. https://arxiv.org/abs/2310.13548 (语言模型谄媚行为的实证研究,17.4 节“迎合偏见”的概念依据)