不管你的理论多么漂亮,
不管你有多聪明。
如果它与实验不符,那它就是错的。
——理查德·费曼
LLM 的出现,以及随后基于 LLM 的应用(LLMBA)的快速采用,标志着软件开发、测试与验证领域发生了一次关键转变。与传统软件系统不同,传统软件系统通常以确定性输出为常态;而 LLM 和 LLMBA 引入了一种非确定性和生成式行为的领域,这对传统软件工程中的评估范式提出了挑战。
这种转变并不只是一次技术演进,而是我们构思、构建和评估商业应用方式上的根本性变化。正因为如此,如果我们仍然固守那些无法考虑 LLM 和 LLMBA 概率性质的传统测试框架,就必然会带来重大风险。
本章探讨如何弥合传统软件测试方法与 LLM、LLMBA 独特需求之间的“评估差距”,并按照如下方式展开。
首先,我们讨论 LLM 的非确定性本质,它如何传导到 LLMBA 中,以及我们如何观察这种现象。随后,我们深入讨论如何为 LLMBA 构建自己的评估框架。这一部分从有意识地设计框架开始,然后进入两个选项。第一个选项是使用客观指标来评估 LLMBA;第二个选项是使用另一个 LLM 来判断我们的 LLMBA 的质量。我们会逐步走过构建这两种方案的代码,并讨论每种方案的最佳实践、优势和弱点。
最后,我们会看一看用于判断 LLM 独立能力的基准测试。这些基准测试对 LLM 的构建者非常重要,也能帮助我们理解新模型或我们自己微调模型的能力。
LLM 的非确定性本质
与传统软件系统不同,在传统软件系统中,相同输入通常会可靠地产生相同输出;而 LLM 可以生成其训练数据中可能并不存在的新文本,并且即使提示词和输入数据完全相同,每次被查询时也可能产生不同回答。这种行为既是一种优势——当我们重视创造力和泛化能力时尤其如此——也是一个重大挑战。
LLM 的这种非确定性意味着:
-
相同的输入数据可能会得到不同的分析结论。
-
监管合规会变得更具挑战性。
-
不一致的回答可能会削弱信任和效率。
-
相比传统软件,测试会变得更加复杂。
设想一家金融服务公司正在构建一个 LLMBA,用于生成一份 10-K 文件的高管摘要。10-K 是上市公司向美国证券交易委员会(SEC)提交的文件。这类研究需要以文件为事实依据,也就是说不能包含虚假内容;但它也需要对公司披露的信息提供一定程度的有洞察力的观点——因为如果没有洞察,客户为什么要为它付费呢?在这个场景中,也就是本章会详细探索的场景中,我们希望自己的 LLMBA 可靠、准确并且合规,同时又有洞察力、有差异化,并且有价值。并且可以推测,我们的最终目标不是只针对一份 10-K 文件生成研究,而是要覆盖一个上市公司池中的数千份文件。随着规模扩大,即使是很小的非确定性结果,也可能变得有问题。
非确定性的来源
当 LLM 生成答案时,这种非确定性来自哪里?
LLM 回答中非确定性的主要来源是采样。更具体地说,在文本生成过程中,所选择的 tokenizer 会把输入文本切分成 token。每个 token 会被映射为一个唯一的数值 ID,LLM 则通过其深度神经网络处理这些 token ID。随后,模型会生成 logits,也就是每个可能的下一个 token 的原始、未归一化分数,并使用 softmax 变换将这些原始 logits 转换成概率分布。然后,模型会从这个分布中采样。logit 到分布的转换可以用下面的公式表示:
其中,, 表示给定输入 时类别 的概率, 是类别 的 ,也就是原始分数。
最高概率表示模型对下一个 token 最强的预测,或者说最高的可能性。为了继续生成文本,模型随后会基于给定策略选择下一个 token。
几个解码策略示例如下:
贪心解码
在文本生成的每一步选择概率最高的 token。严格来说,这并不是采样,因为它只是选择最高概率的 token。
Top-K
只保留 logits 排名前 K 的 token,并从这些 token 中采样。
Top-P
保留累计概率大于 P 的最小 token 集合,并从其中采样。
约束
屏蔽无效 token,只从有效 token 中采样。
非确定性之所以产生,是因为 LLM 并不只是选择最可能的下一个 token;它会根据指令从一个概率分布中采样。
Temperature
我们通过探索 temperature 参数,来看一个真实例子中这是如何工作的。Temperature 有时被称为让 LLM 更有创造力或更少创造力的参数。实际上,它是一个在 LLM 从输出或文本分布中采样之前,对该分布进行重塑的参数。
当 temperature = 0 时,分布会变得尽可能尖锐,所有概率质量都会塌缩到单个得分最高的 token 上。然而,这并不一定会让 LLM 完全确定。残余的非确定性仍然可能来自一些因素,例如混合专家模型(MoE)架构中的路由变化,或者 GPU 浮点运算在并行归约过程中的非结合性。当 temperature = 1 时,分布会按原样使用,也就是按照模型在训练中学到的原始概率进行比例采样。当 temperature = 2 时,分布会被拉平,高概率 token 不再那么占主导,低概率 token 会获得更大的概率质量份额,从而使令人意外或不太可能的 token 更有可能被采样出来。
在下面这个简单实验中,我们使用一个 LLMBA 从一份 10-K 文件中写出一句话的高管摘要,并扰动 temperature 参数,观察结果如何变化。我们会在三个 temperature 设置下运行这个实验:0.0、1.0 和 2.0。
10-K LLMBA Temperature 测试
这里的目标是生成一份我们保存为文本的 10-K 文件摘要。如果你想查看完整文件,可以在 SEC 网站上找到。重要的是,我们不会把整份 10-K 提供给 LLM,而只提供 10,000 个字符。原因是,在后面的代码中,我们选择的模型是 gpt-3.5-turbo-0613,它的限制是 4,096 个 token。我们的输入和输出加起来不能超过 4,096 个 token。
一个 token 是文本中有意义的片段,例如一个词、一个短语,或者可能是一个标点符号。10,000 个字符通常大约等于 2,500 个 token,尽管这取决于所使用的 tokenizer,也就是大约四到五页文本。因此,我们传入大约四到五页的 10-K 内容,并为四到五页的回答保留空间,如果需要的话。作为经验法则,我们可以预期大约 0.75 个英文单词对应 1 个 token。我们可以在 Tiktokenizer 网站上准确检查英文字符如何转换为 token。
下面是我们如何将文本限制为 10,000 个字符:
MAX_LENGTH = 10000
# 10-K 的文本位于一个名为 apple.txt 的文件中
with open('../data/apple.txt', 'r') as file:
sec_filing = file.read()
sec_filing = sec_filing[:MAX_LENGTH]
接下来,我们创建一个名为 generate_responses() 的函数,用于在三种不同的 temperature 水平下生成回答。在下面的代码中,我们通过创建 for temp in temperatures 循环来做到这一点。当调用这个函数时,我们会传入 temperatures=[0.0, 1.0, 2.0]。每个 temperature 我们会运行三次;这一点通过 attempts: int = 3 指定:
from dotenv import load_dotenv
import os
# 从 .env 文件加载环境变量
load_dotenv()
from openai import OpenAI
import pandas as pd
from typing import List
def generate_responses(
model_name: str,
prompt: str,
temperatures: List[float],
attempts: int = 3
) -> pd.DataFrame:
"""
在不同 temperature 设置下生成多次回答,
用于展示非确定性行为。
"""
client = OpenAI()
results = []
# 创建 temperature 循环
for temp in temperatures:
for attempt in range(attempts):
response = client.chat.completions.create(
model=model_name,
messages=[{"role": "user", "content": prompt}],
temperature=temp,
max_completion_tokens=50
)
results.append({
'temperature': temp,
'attempt': attempt + 1,
'response': response.choices[0].message.content
})
# 按 temperature 分组展示结果
df_results = pd.DataFrame(results)
for temp in temperatures:
print(f"\nTemperature = {temp}")
print("-" * 40)
temp_responses = df_results[df_results['temperature'] == temp]
for _, row in temp_responses.iterrows():
print(f"Attempt {row['attempt']}: {row['response']}")
return df_results
现在,让我们启动代码流程,加载该申报文件的前 10,000 个字符,把它传给模型,并通过一个提示词提供一些指令。在这个例子中,我们的提示词非常简单:“Write a single-statement executive summary of the following text: {sec_filing}”。
再次注意,我们选择的模型是 gpt-3.5-turbo-0613。不费太多力气,我们也可以选择更多模型,对它们进行循环,并把这个流程扩展成:在许多不同 temperature 设置下,用许多 10-K 文件评估许多模型。
df_results = generate_responses(model_name="gpt-3.5-turbo-0613",
prompt=f"Write a single-statement executive
summary of the following text: {sec_filing}",
temperatures=[0.0, 1.0, 2.0])
下面是我们的结果——每个 temperature 设置下生成三条一句话摘要:
Temperature = 0.0
----------------------------------------
Attempt 1: Apple Inc. filed its Form 10-K for the fiscal year ended September 28, 2024 with the SEC, detailing its business operations and financial performance.
Attempt 2: Apple Inc. filed its Form 10-K with the SEC for the fiscal year ended September 28, 2024, detailing its business operations, products, and financial information.
Attempt 3: Apple Inc. filed its Form 10-K with the SEC for the fiscal year ended September 28, 2024, detailing its business operations, products, and financial information.
Temperature = 1.0
----------------------------------------
Attempt 1: Apple Inc., a well-known seasoned issuer based in California, designs, manufactures, and markets smartphones, personal computers, tablets, wearables, and accessories, with a focus on innovation and technology.
Attempt 2: Apple Inc. filed its Form 10-K with the SEC for the fiscal year ended September 28, 2024, reporting on its business operations, products, and financial performance.
Attempt 3: Apple Inc., a well-known seasoned issuer, filed its Form 10-K for the fiscal year ended September 28, 2024, reporting on its financial condition and operations.
Temperature = 2.0
----------------------------------------
Attempt 1: The Form 10-K for Apple Inc. for the fiscal year ended September 28, 2024, filed with the Securities and Exchange Commission, outlines the company’s financial performance, products, and risk factors affecting future results.
Attempt 2: Apple Inc., a California-based company and leading technology manufacturer invDestacksmeticsisdiction setIspection-$20cyan evaluationseld anvisions droitEntering discernminerval Versbobprefversible vo该 Option和 meio forecast времCisco dellaischenpoihsCapabilities Geme.getTime future
Attempt 3: Apple Inc’s Form 10-K provides a comprehensive overview of the company’s financial reporting, business operations, products and market information.
我们可以观察到以下现象:
Temperature = 0.0
这些摘要看起来像是确定性的,但实际上并不是。仍然存在轻微变化。注意,这是最“贪心”的方法,也就是我们选择最可能的下一个 token,而不是从分布中采样。
Temperature = 1.0
摘要表现出一定程度的一致性,同时具有平衡的创造性。
Temperature = 2.0
我们看到随机性增加,并且实际上出现了不连贯的词语拼接。这是因为概率分布被拉平,因此我们可能采样到一个意想不到的长尾 token,甚至意外到完全没有意义。
评估挑战
正如前面的例子所展示的,即使是一个输出只有一句话的简单任务,也会引入围绕非确定性的挑战。
这就是为什么我们说,与传统软件评估技术相比,LLM 评估存在一个评估差距。传统软件评估技术通常把输出是确定的、并且总是相同的,作为第一性原理。再进一步说,LLM 评估与传统软件测试在几个关键维度上有所不同:
能力评估 vs. 功能测试
传统软件测试是根据预定义需求验证具体功能。LLM 评估必须评估的不一定只是预定义行为,还包括推理、创造力和语言理解等“涌现属性”,这些能力超出了显式编程的范围。
指标与测量挑战
传统软件指标通常可以被精确定义和测量,而 LLM 评估经常涉及“有帮助性”或“自然性”等主观质量,这些质量难以直接量化。即使我们尝试把它们拆解成数值分数,底层判断也往往仍然天然依赖人类,并且受上下文影响。
基准演进
传统软件会随着时间保持稳定的测试套件。LLM 基准则会随着能力提升而持续演进,这使得纵向性能比较变得困难,并且可能让旧的评估方法过时。
人类评估需求
传统软件测试可以自动化大部分验证。LLM 评估仍然需要大量人类监督,通过结构化标注和系统性审查流程,评估输出质量、适当性和潜在偏见。
设计一个 LLMBA 评估框架
现在,让我们开始勾勒构建一个 LLMBA 评估框架所需要的组件。
概念设计:单个 LLMBA
我们先从简单情况开始,设计对单个 LLMBA 的评估,也就是我们构建了一个应用来完成一个任务的场景。
如图 2-1 所示,单个 LLMBA 的评估由示例、应用、评估器,以及评估器产生的结果/分数组成。
图示说明:单个 LLMBA 评估的概念设计,展示从示例,到 LLM 应用,再到评估器,并最终得到分数的流程。
图 2-1 单个 LLMBA 评估的概念设计
我们可以观察到三个关键组件。首先是包含示例的组件,其中包括我们传给 LLM 的输入,例如一个查询、一段 10-K 片段或一个提示词,以及一个期望结果的参考,例如 ground truth,或者一个格式正确的 10-K 摘要示例。
接下来是 LLM 应用,也就是接收这些输入并生成输出的处理层。在这里,我们可以测试不同的 LLM,以及例如不同的 temperature 设置。
随后进入输出评估环节,在这个环节中,我们可以比较示例中的参考集合与 LLM 的输出。注意,参考示例是评估器组件的可选输入:正如我们将在后续章节中详细说明的那样,LLM 应用输出可以通过指标或其他 LLM 来评估,而不一定要求输入测试集。
最后,我们存储结果。请记住,即使只有一个模型,我们也可能有一个使用三种 temperature 设置的 LLMBA,并在每种设置下对许多输入数据运行许多实验。
概念设计:多个 LLMBA
接下来,我们可以勾勒一个框架,用于评估为完成同一任务而构建的多个 LLMBA。图 2-2 展示了一个通用概念设计,其中多个 LLMBA 会被评估。这种设计可以对不同配置的 LLMBA 进行全面评估。
图示说明:用于评估多个不同配置 LLMBA 的概念框架,展示互相关联的组件和路径。
图 2-2 多个 LLMBA 评估的概念设计
在图 2-2 中,我们标记了 app1、app2 一直到 appN,用来代表我们可以为 LLMBA 评估的各种 LLM、提示词和其他参数的排列组合。最终构建者有许多方式来设计这个流程,例如:
固定所有应用参数,并评估不同 LLM 模型在默认配置下的表现。
固定某个 LLM 模型的所有参数,并评估不同数据源。
固定某个 LLM 模型的所有参数,并评估不同提示词策略。
这里一个很大的区别是,我们最终会以排行榜结束这个过程,用来对哪个 LLMBA 最适合我们的给定任务进行排名。当我们在企业中扩大这方面的工作时,也可以开始分析排行榜,例如判断某些模型是否往往更适合某些类型的数据。这类专业能力,会区分有经验的 LLM 用户和缺乏经验的用户。
当我们思考前面勾勒出的概念框架时,每一步都伴随着若干问题和考量:
输入示例
我们如何确保输入和示例数据的质量?
是否应针对不同业务需求设置独立测试集?
如果没有足够的真实世界数据用于测试,我们能否使用合成数据?
LLM 相关
为了公平比较,每个 LLM 应用的哪些方面应该被标准化?
哪些具体配置会影响业务需求?
评估器标准
我们使用通用评估标准还是任务特定评估标准?
我们使用客观指标还是主观评估?
评估应该自动化,还是应该包含人工审查?
评分系统
不同指标应该如何加权?
分数应该归一化,还是使用绝对值?
是否应该考虑 LLM 给出的置信分数?
排行榜/排名
排名应该多久更新一次?
排名是否应该包含置信区间?
评估方法
在接下来的部分中,我们会讨论两种评估 LLM 输出的方法:定量指标和 LLM-as-a-judge。BLEU 和 ROUGE 等定量指标是基于参考答案的方法,它们衡量生成回答与人工撰写参考答案之间的文本相似度。相比之下,LLM-as-a-judge 会使用一个有能力的语言模型,从事实准确性、连贯性和相关性等维度评估回答质量,很像人类评估员会做的事情。
每种方法都有自己的优势和弱点。定量指标通常精确且可复现,但它们衡量的是表层文本重叠,而不是意义,因此在开放式任务中会变得脆弱,因为这类任务往往存在许多有效回答。LLM-as-a-judge 能捕捉指标根本无法捕捉的语义丰富度和细微差别,但也会把成本、延迟以及裁判模型自身的偏见引入评估流水线。正如我们将在后续示例中看到的,正确选择在很大程度上取决于任务性质;而在许多真实世界评估框架中,两种方法会一起使用,从而兼得二者之长。
定量指标
用于 LLM 评估的常见定量指标,是通过将生成回答与一个或多个人工撰写或模型撰写的参考答案进行比较来工作的,它们使用 n-gram 匹配等技术衡量文本重叠程度。
在本节中,我们会使用两个这样的指标:BLEU(Bilingual Evaluation Understudy)和 ROUGE(Recall-Oriented Understudy for Gisting Evaluation)。
BLEU 最初为机器翻译开发,关注的是精确率,也就是生成文本中有多少出现在参考文本中。
ROUGE 更常用于摘要任务,强调的是召回率,也就是参考文本中有多少出现在生成输出中。
这些指标特别有价值的原因在于它们简单且可靠:计算相对快速、廉价,并且在固定实现和预处理流水线下是确定性的。由于它们会产生一个单一数值分数,因此可以干净地集成到自动化测试流水线和持续集成/持续部署(CI/CD)工作流中,使我们能够直观地追踪模型性能随时间变化,并捕捉回归问题。它们背后也有几十年的研究积累,具有被充分理解的统计性质和成熟基准,使我们能够用标准化、可复现的方式,比较不同模型、论文和研究团队之间的结果。对于有明确定义正确答案的任务,例如机器翻译、摘要,以及基于固定知识库的问答,它们仍然是评估工具箱中稳健且值得信赖的工具。
在进入使用 BLEU 和 ROUGE 的示例之前,先快速看一下表 2-1。我们列出了一组常用于评估生成任务的定量指标,以及它们的定义、使用场景和局限性。我们倾向于使用 BLEU 和 ROUGE,但如果你以后需要或遇到其他指标,这张表是一个有用参考。
表 2-1 用于评估生成任务的关键指标
| 指标 | 定义 | 使用场景 | 局限性 |
|---|---|---|---|
| BLEU(Bilingual Evaluation Understudy) | 衡量生成文本与参考文本之间 n-gram 的重叠 | 机器翻译和文本摘要 | 对短文本表现可能较差;长度惩罚会惩罚较短输出;对语义含义不敏感;需要高质量参考文本 |
| ROUGE(Recall-Oriented Understudy for Gisting Evaluation) | 衡量生成文本与参考之间 n-gram、词或句子的重叠,重点关注召回 | 文本摘要任务 | 偏向较长输出;忽视语义等价;无法评估事实准确性;参考质量变得极其关键 |
| METEOR(Metric for Evaluation of Translation with Explicit Ordering) | 在 n-gram 重叠之外,同时考虑同义词、词干和改写 | 机器翻译,尤其是语义等价重要的场景 | 计算成本高;同义词/词干数据库的设计具有主观性 |
| CIDEr(Consensus-based Image Description Evaluation) | 衡量经过 TF-IDF 加权的 n-gram 重叠,专为图像描述设计 | 图像描述生成 | 在图像描述之外适用性有限;高度依赖语料统计 |
| TER(Translation Edit Rate) | 计算将候选文本转换成参考文本所需编辑次数 | 翻译质量评估 | 不考虑语义正确性;会惩罚有效改写 |
| BERTScore | 使用来自预训练 BERT 的上下文嵌入计算 token 相似度 | 需要语义等价的任务 | 计算成本高;性能随所用模型而变化 |
| SPICE(Semantic Propositional Image Caption Evaluation) | 关注图像描述中的场景图,用于评估语义内容 | 强调语义准确性的图像描述 | 仅为图像描述设计;在纯文本任务中效果较差 |
编写 BLEU 和 ROUGE 代码
为了看看这些指标如何使用,我们来写一个例子,评估前面 10-K 高管摘要的质量。正如我们之前提到的,BLEU 和 ROUGE 需要参考答案;在我们这里,这意味着需要 10-K 的参考摘要。在现实中,我们可以使用由分析师阅读并总结 10-K 后创建的摘要;但这里我们只会请另一个模型来创建参考摘要。
这意味着我们需要以下内容:
LLM 生成的 10-K 摘要。
10-K 的参考摘要。
用于创建参考摘要的基准模型:我们会使用 gpt-4o。
用于生成新摘要的测试模型:我们会测试 gpt-4o-mini、gpt-4-turbo 和 gpt-3.5-turbo。
计算并创建一个用于保存 BLEU 和 ROUGE 分数的字典。
我们首先构建一个名为 evaluate_summaries 的函数,它计算 BLEU 和 ROUGE 分数,用来评估文本生成质量。
更具体地说,evaluate_summaries 函数接收两个参数:(1)生成摘要;(2)参考摘要。它使用 evaluate 库处理它们,并返回一个包含三个关键指标的字典:
BLEU
ROUGE_1
ROUGE_2
这使我们能够对生成摘要和参考文本进行定量比较。该实现使用 Hugging Face 的 evaluate 库来加载并计算这些指标:
# 如果还没有安装 evaluate,先在终端运行 pip install evaluate。
# 这是 Hugging Face 的 evaluate 库。
import evaluate
def evaluate_summaries(generated_summary, reference_summary):
"""
使用多个指标,将生成摘要与参考摘要进行评估。
Args:
generated_summary (str): 模型生成的摘要
reference_summary (str): 参考/真实摘要
Returns:
dict: 包含不同指标分数的字典
"""
# 初始化指标
bleu = evaluate.load("google_bleu")
rouge = evaluate.load("rouge")
# 为 BLEU 格式化输入
# BLEU 期望 predictions 是 str 列表,
# references 是 str 列表的列表
predictions = [generated_summary]
references = [reference_summary]
# 计算 BLEU 分数
bleu_score = bleu.compute(
predictions=predictions,
references=[references]
)
# 计算 ROUGE 分数
rouge_score = rouge.compute(
predictions=predictions,
references=references
)
# 将所有分数合并到一个字典中
scores = {
'bleu': bleu_score["google_bleu"],
'rouge1': rouge_score['rouge1'],
'rouge2': rouge_score['rouge2']
}
return scores
注意,除了 BLEU 之外,我们这里还使用了两个 ROUGE 分数。当我们从 Hugging Face 的 evaluate 库加载 ROUGE 时,实际上会得到以下四个变体,但我们只使用其中两个,也就是 ROUGE-1 和 ROUGE-2:
ROUGE-1:一元词重叠
ROUGE-1 衡量生成回答与参考之间单个词,也就是 unigram 的重叠。它是最简单的形式,只是统计两个文本共享多少单个词,而不考虑顺序。例如,如果参考文本是 “The cat sat on the mat”,生成文本是 “The cat was on the mat”,ROUGE-1 会统计重叠的单个词,并基于这些重叠生成 precision、recall 和 F1 分数。
ROUGE-L:最长公共子序列
ROUGE-L 更复杂。它不是统计词重叠,而是在两个文本之间寻找最长公共子序列(LCS)。这意味着它在不要求连续匹配的情况下,隐式捕捉词序和句子结构。它会奖励那些保留参考文本流动和结构的回答,即使它们不是逐词匹配。
ROUGE-2:二元词组重叠
ROUGE-2 衡量生成回答与参考之间 bigram,也就是连续两个词组成的词组的重叠。ROUGE-1 只关心单个词是否同时出现在两个文本中,而 ROUGE-2 会检查两个词组成的短语是否同时出现,因此它对局部词序和措辞更敏感。例如,如果参考文本包含短语 “climate change policy”,ROUGE-2 会奖励同样包含 “climate change” 或 “change policy” 作为连续词对的生成回答,但不会奖励那些把三个词分散在文本不同位置、顺序不同的回答。这使得 ROUGE-2 比 ROUGE-1 更严格、更苛刻:一个回答不仅需要使用正确的词,还需要以与参考匹配的方式排列这些词。
ROUGE-Lsum:摘要级最长公共子序列
ROUGE-Lsum 是 ROUGE-L 的一个变体,专门为多句摘要设计。它不是把整段文本当成一个长字符串来寻找 LCS,而是对每个句子分别计算 LCS,然后聚合分数。这使它更适合评估较长生成输出,因为重要匹配可能分布在多个句子中,而不是集中在一个连续片段里。
回到这个函数。为了看看 BLEU 和 ROUGE 分数长什么样,我们用 evaluate_summaries 比较两个任意句子,并返回一个包含所选指标的字典:
sentence1 = "the cat sat on the mat"
sentence2 = "the cat ate the mat"
evaluate_summaries(sentence1, sentence2)
{'bleu': 0.3333333333333333,
'rouge1': 0.7272727272727272,
'rouge2': 0.4444444444444445}
可以看到,即使是非常简单的句子,结果之间也可能有相当大的差异。这就是为什么不建议依赖单一指标或单一测试样例。对于真实评估,我们应该在有代表性的数据集上进行评估,并报告聚合统计结果。
接下来,我们定义 generate_summary,它与之前创建 10-K 摘要的例子非常相似。注意我们如何将 LLM 的角色定义为“负责总结 SEC 文件的专家分析师”:
from openai import OpenAI
client = OpenAI()
def generate_summary(model, input):
"""
使用给定模型生成输入内容的摘要
"""
TASK = """Generate a 1-liner summary of the following excerpt from an SEC
filing."""
prompt = f"""
ROLE: You are an expert analyst tasked with summarizing SEC filings.
TASK: {TASK}
"""
response = client.chat.completions.create(
model=model,
messages=[{"role": "system", "content": prompt},
{"role": "user", "content": input}]
)
return response.choices[0].message.content
接下来,我们定义一个函数 evaluate_summary_models,也就是我们的模型评估器,用来比较由不同语言模型生成的文本摘要。在我们的例子中,测试模型会使用 gpt-4o-mini、gpt-4-turbo 和 gpt-3.5-turbo,而基准或参考生成模型会使用 gpt-4o:
def evaluate_summary_models(model_benchmark, models_test, input):
"""
评估由多个模型生成的摘要
"""
benchmark_summary = generate_summary(model_benchmark, input)
# 使用列表推导生成所有测试模型的摘要
model_summaries = [generate_summary(model, input)
for model in models_test]
# 将每个模型的摘要与基准摘要进行评估
evaluation_results = [evaluate_summaries(summary, benchmark_summary)
for summary in model_summaries]
return [evaluation_results, model_summaries, benchmark_summary]
更具体地说,evaluate_summary_models 会执行以下操作:
接收一个基准模型、一个测试模型列表和输入文本。
使用基准模型和我们的 generate_summary 函数生成参考摘要。
使用 generate_summary 函数生成所有测试模型的摘要。
使用 evaluate_summaries 将每个测试模型的摘要与基准进行比较。
返回评估结果和生成摘要。
现在,我们准备运行基准评估。我们定义一个基准模型和一个测试模型列表,然后根据基准评估每个测试模型的摘要:
model_benchmark = "gpt-4o"
models_test = ["gpt-4o-mini", "gpt-4-turbo", "gpt-3.5-turbo"]
evals, model_summaries, benchmark_summary = evaluate_summary_models(
model_benchmark,
models_test,
sec_filing
)
print(benchmark_summary)
下面是基准/参考摘要:
"Apple Inc.'s 10-K filing for the fiscal year ending September 28, 2024,
outlines its operational and financial condition, detailing the company's
diverse product lines, market activities, and compliance with SEC
requirements."
# 打印每个模型名称及其摘要
for model, summary in zip(models_test, model_summaries):
print(f"{model}: \n {summary} \n---------------")
下面是测试摘要:
gpt-4o-mini:
Apple Inc. filed its Annual Report on Form 10-K for the fiscal year ending September 28, 2024, detailing its business operations, risks, and financial condition.
---------------
gpt-4-turbo:
Apple Inc.’s Form 10-K for the fiscal year ended September 28, 2024, details its annual report as a well-known seasoned issuer, confirming compliance with SEC regulations and reporting on stock performances, securities, and corporate governance while also including forward-looking statements subject to various risks.
---------------
gpt-3.5-turbo:
Apple Inc. filed its Form 10-K with the SEC, revealing financial information for the fiscal year ended September 28, 2024, including details on its products and market performance.
---------------
将测试模型与基准比较时,我们从经验观察上看到以下情况:
gpt-4o 生成的基准摘要,对 10-K 中被分析片段提供了一个平衡概览,关注运营状态、财务状况、产品线和监管合规。
gpt-4o-mini 提供了一条简洁但全面的摘要,与基准的核心信息高度一致。虽然它省略了产品线,但有效捕捉了该申报文件的关键元素,包括业务运营、风险和财务状况。它的简洁性和重点在主观上看起来与我们的基准模型类似。
gpt-4-turbo 表现尚可,但倾向于冗长。虽然它包含了与 SEC 合规相关的信息,但也引入了有关 seasoned issuer status 和 forward-looking statements 的外围细节。额外复杂度使这条摘要不如 gpt-4o-mini 的版本聚焦。
gpt-3.5-turbo 看起来与基准差异较大。它的摘要虽然事实正确,但过于简化,遗漏了该申报文件的一些关键方面。该模型捕捉到了基本财务信息,但未能表达出基准摘要中体现的运营和合规细节的广度。
当然,这个评估只基于一个样例,而且高度主观。它是对评估结果的一次“感觉检查”。
为了进行更客观的分析,我们创建一个 visualize_prompt_comparison 函数,用来可视化测试模型在预定义定量指标上的表现:
import matplotlib
def visualize_prompt_comparison(evaluation_results, model_names):
"""
创建一个雷达图,用于比较不同提示词变体
Args:
evaluation_results (list): 包含评估指标的字典列表
model_names (list): 每个提示词变体的名称列表
"""
from evaluate.visualization import radar_plot
# 为可视化格式化数据
plot = radar_plot(data=evaluation_results, model_names=model_names)
return plot
# 创建并展示可视化
plot = visualize_prompt_comparison(evals, models_test)
plot.show()
图 2-3 展示了我们的 BLEU 和 ROUGE 结果图。
图示说明:雷达图展示了三个模型的 BLEU 和 ROUGE 分数:gpt-4o-mini、gpt-4-turbo 和 gpt-3.5-turbo,并突出它们的性能差异。
图 2-3 BLEU 和 ROUGE 结果图
可以看到,在我们预定义的指标上,被测试模型表现差异明显。评估指标认为 gpt-4o-mini 与基准最接近,其次是 gpt-4-turbo,而 gpt-3.5-turbo 偏离最大。这表明,相对于其他测试模型,gpt-4o-mini 是这个任务上的最佳模型。
虽然评估语言模型输出天然涉及主观判断,但建立一个高质量基准模型,并使用可量化指标,可以为模型性能比较提供一个更客观的框架。这种方法把原本定性的评估,转化为可测量、数据驱动的评估流程。
BLEU 和 ROUGE 这类指标因其客观性而有价值,并且非常适合摘要和文本类任务,但也存在重要局限:
任务特定性
所选择的指标集合可能无法完全捕捉复杂生成式任务的细微差别,尤其是那些涉及人类主观判断的任务。
对数据分布敏感
这些指标上的表现会受到评估所用具体数据集的影响,而该数据集可能无法代表真实世界的数据分布。
可接受阈值具有主观性
这些指标并不总是容易解释,也不总是容易设定阈值。
无法评估推理或事实准确性
这些指标主要关注表层匹配,可能无法揭示 LLM 底层推理过程,或者它生成事实正确信息的能力。
为了解决这些局限,除了在评估过程中利用人类之外,我们还可以采用 LLM-as-a-judge,下一节会讨论这一点。
请特别注意:生成 LLM 回答时,顺序很重要! 根据要求 LLM 裁判先给分再解释,还是先解释再给分,结果表现可能会有显著差异。推荐使用一种“先思考再说话”的策略,也就是先放分数解释,再放实际结果分数,这可能会改善结果。
编写 LLM-as-a-Judge 代码
让我们把这些想法付诸实践,为生成 10-K 摘要的 LLMBA 构建一个 LLM-as-a-judge 评估系统。
在下面的代码片段中,我们会做以下事情:
首先,定义一个 JudgeEvaluation Pydantic 模型,明确指定我们希望裁判给出什么:四个数值分数,分别是专业性、连贯性、流畅性和相似性。这可以确保我们得到一致、可解析的回答,而不是自由格式文本。
然后创建 evaluate_with_llm() 函数,它接收三个输入:
裁判模型名称。
被评估的候选摘要。
用于比较的参考摘要。
该函数返回一个结构化的分数字典。
在函数内部,我们构建一个详细提示词,它会:
给 LLM 分配一个明确角色:SEC 文件摘要专家。
定义四个具体评估标准,并附上具体问题。
提供参考摘要和候选摘要进行比较。
要求在标准化的 1 到 10 分量表上打分。
最后,我们使用 OpenAI API 的 client.beta.chat.completions.parse() 方法,并指定 response_format=JudgeEvaluation。这会告诉模型,必须按照我们 Pydantic 模型定义的结构返回响应。API 会自动提取并验证分数,确保我们得到一个格式正确的 JudgeEvaluation 对象,包含全部四个数值字段,而不需要我们自己解析非结构化文本。
注意,本书后续会介绍 Pydantic;简单来说,它是一个用于数据验证的 Python 库,让我们能够精确定义期望数据的结构和类型,例如要求四个整数分数。这里我们使用它,是为了确保 LLM 裁判的评估分数可以自动验证,并被解析成干净、可预测的格式:
from pydantic import BaseModel
from typing import List, Dict
class JudgeEvaluation(BaseModel):
expertise: int
coherence: int
fluency: int
similarity: int
def evaluate_with_llm(judge_model: str, candidate_summary: str,
reference_summary: str) -> Dict[str, float]:
"""
使用一个 LLM 将候选摘要与参考摘要进行评估。
Args:
judge_model (str): 用作裁判的模型名称。
candidate_summary (str): 要评估的生成摘要。
reference_summary (str): 真实摘要或基准摘要。
Returns:
dict: 包含指定标准评估分数的字典。
"""
prompt = f"""
ROLE: You are an expert evaluator of SEC filing summaries.
Evaluate the following candidate summary against the reference
summary on a scale of 1 to 10 for the following criteria:
- Expertise: Does the summary look like it was written by an expert
analyst?
- Coherence: Is the candidate summary logically organized and easy to
understand?
- Fluency: Is the language of the candidate summary clear and
grammatically correct?
- Similarity: How similar is the candidate summary compared to the
reference summary?
Reference Summary:
"{reference_summary}"
Candidate Summary:
"{candidate_summary}"
Provide scores in this format:
Expertise: X, Coherence: Y, Fluency: Z, Similarity: W
"""
completion = client.beta.chat.completions.parse(
model=judge_model,
messages=[{"role": "system", "content": prompt}],
response_format=JudgeEvaluation
)
return completion.choices[0].message.parsed
接下来,我们定义一个 evaluate_summary_models_with_judge() 函数,使用我们的裁判函数来比较由不同语言模型生成的摘要:
def evaluate_summary_models_with_judge(
judge_model: str,
benchmark_model: str,
test_models: List[str],
input_text: str):
"""
使用 LLM-as-a-judge 方法评估由多个模型生成的摘要。
Args:
judge_model (str): 用作裁判的模型名称。
benchmark_model (str): 基准模型名称。
test_models (list): 要测试的模型名称列表。
input_text (str): 用于摘要的输入文本。
Returns:
tuple: 评估结果、模型摘要和基准摘要。
"""
benchmark_summary = generate_summary(benchmark_model, input_text)
model_summaries = [
generate_summary(model, input_text) for model in test_models
]
evaluation_results = [
evaluate_with_llm(judge_model, summary, benchmark_summary)
for summary in model_summaries
]
return evaluation_results, model_summaries, benchmark_summary
这个函数在多个模型之间编排了完整的 LLM-as-a-judge 评估流程。它具体做了以下事情:
- 生成基准摘要
首先,我们使用基准模型创建一个参考摘要。这里我们会使用 gpt-4o。它会作为“黄金标准”,所有其他摘要都会与它比较。
- 生成候选摘要
我们遍历测试模型列表中的每个模型,并从相同输入文本生成摘要。这确保所有模型都在使用完全相同的源材料,从而使比较公平。
- 评估每个候选摘要
使用前面的 evaluate_with_llm() 函数,将每个候选摘要与基准摘要进行比较,并按照四个标准给分:专业性、连贯性、流畅性和相似性。
- 返回所有内容
该函数返回三项内容:
所有测试模型的评估分数。
实际候选摘要本身。
基准摘要。
这使我们既能够定量比较模型表现,也能够定性检查每个模型实际生成了什么。这个流水线设计也让我们可以通过一次函数调用,轻松评估任意数量的模型相对于单一基准的表现。这也是我们能够扩展到更多模型,或者开始纳入自己微调模型的方式。
现在,我们运行 evaluate_summary_models_with_judge() 函数,把模型和要总结的 sec_filing 传进去:
# 示例用法
model_benchmark = "gpt-4o"
models_test = ["gpt-4o-mini", "gpt-4-turbo", "gpt-3.5-turbo"]
judge_model = "gpt-4o"
evals, model_summaries, benchmark_summary = evaluate_summary_models_with_judge(
judge_model, model_benchmark, models_test, sec_filing
)
这里,我们可以看到来自基准模型 gpt-4o 的基准摘要:
benchmark_summary
Apple Inc.'s annual report for the fiscal year ending September 28, 2024,
details its business operations, financial condition, and product lines,
including iPhones, Macs, iPads, and wearables, and incorporates
forward-looking statements regarding its future performance.
接下来,我们获取由测试模型 gpt-4o-mini、gpt-4-turbo 和 gpt-3.5-turbo 分别生成的摘要和评估结果:
model_summaries
"Apple Inc. filed its annual Form 10-K report for the fiscal year ended
September 28, 2024, detailing its business operations, product lines, and
financial performance.",
"This Form 10-K filing by Apple Inc. for the fiscal year ended
September 28, 2024, is an annual report detailing the company's financial
performance, including registered securities, compliance with SEC reporting
standards, and contains sections on business operations, risk factors,
financial data, and management analysis.",
"Apple Inc., a California-based technology company, reported an aggregate
market value of approximately $2.6 trillion held by non-affiliates,
with 15.1 billion shares of common stock outstanding as of October 18, 2024."
最后,我们打印一个 Pydantic 类对象列表,其中包含我们的评估指标:专业性、连贯性、流畅性和相似性:
evals
[JudgeEvaluation(expertise=7, coherence=8, fluency=8, similarity=7),
JudgeEvaluation(expertise=7, coherence=7, fluency=8, similarity=5),
JudgeEvaluation(expertise=4, coherence=5, fluency=7, similarity=2)]
让我们创建一个快速图表来可视化结果:
# 将评估对象转换成字典
evals_list = [
{
"expertise": e.expertise,
"coherence": e.coherence,
"fluency": e.fluency,
"similarity": e.similarity
}
for e in evals
]
# 可视化结果
plot = visualize_prompt_comparison(evals_list, models_test)
plot.show()
图 2-4 展示了我们的 LLM-as-a-judge 结果。
图示说明:雷达图比较了 LLM 模型 gpt-4o-mini、gpt-4-turbo 和 gpt-3.5-turbo 在专业性、连贯性、流畅性和相似性指标上的表现。
图 2-4 LLM-as-a-judge 结果图
在分析三个测试模型 gpt-4o-mini、gpt-4-turbo 和 gpt-3.5-turbo 的评估结果时,出现了几个有意思的模式:
gpt-4o-mini 模型表现强劲,在所有指标上都取得了较高分数:专业性 7,连贯性 8,流畅性 8,相似性 7。这一表现表明,尽管它是我们的基准模型 gpt-4o 的较小变体,但仍保持了稳健质量。
gpt-4-turbo 模型展现出可比的专业性和流畅性分数,分别为 7 和 8,但连贯性略低,为 7;相对于基准,它的相似性明显更低,为 5。这些结果可能表明,它在保持整体质量的同时,与参考摘要存在一定偏离。
gpt-3.5-turbo 模型记录了最低分数:专业性 4,连贯性 5,流畅性 7,相似性 2,尤其在专业性和与基准相似性方面存在明显弱点。虽然它保持了可接受的流畅性,但相似性分数显著下降,说明它与参考摘要之间存在实质性偏离。
从 gpt-4o-mini 到 gpt-3.5-turbo,可以观察到一个清晰的性能梯度,后者在大多数指标上出现明显退化。
LLM-as-a-Judge 的局限
需要注意的是,利用 LLM 进行评估存在若干局限。
首先,考虑到运行额外模型推理迭代本身就有成本,计算开销不应被忽视。LLM 评估器也可能表现出各种偏见,包括顺序或位置偏见,也就是偏好某些序列位置;自我中心偏见,也就是偏好来自相似模型的输出;以及长度偏见。此外,它还依赖提示词质量——很小的提示词变化,或者提示词漂移,都可能导致结果发生显著变化。我们必须小心区分,我们到底是在评估提示词质量、模型质量、整体 LLMBA 质量,还是这些因素各自的变体。
此外,在金融、法律和医疗等专业领域,裁判 LLM 本身可能缺乏必要专业知识,因此可能不适合作为质量裁定者。这个问题可以通过微调来解决,本书第 8 章会讨论这一点;但即使是微调后的模型,也需要被监控和评估。
总体而言,LLM-as-a-judge 策略可以作为一种可扩展且细腻的方案,用于评估 LLMBA。虽然它不能完全替代基于指标或基于人类的评估方法,但它显著增强了评估工作流,尤其是在需要评估生成式输出的场景中,并且正在成为一种常见评估范式。
评估评估器
随着我们越来越多地让 LLM 作为 LLMBA 的裁判,衡量裁判模型评估其他模型的能力有多好,就变得很重要。
如图 2-5 所示,LLM 评估器的性能可以通过将其分数与黄金数据集或人类参考分数进行比较来衡量。更高的相关性数值可能表明 LLM 评估器表现更好。
图示说明:展示 LLM 元评估流程的图,突出人类分数、评估器分数和基于指标分数在评估性能中的角色。
图 2-5 LLM 元评估的概念概览
例如,如果我们要评估一个 LLM-as-a-judge 评估器在评估某个 LLM 多语言能力任务中的表现:
在基于指标的方法中,我们首先需要定义一组能够捕捉多语言能力任务的指标。例如,我们可以使用 BLEU 指标,将生成的 LLM 输出与黄金数据集,例如机器翻译文本,进行质量评估。然后,我们计算这些分数与 LLM 评估器生成分数之间的相关性。相关性越高,LLM 评估器越好。
在基于人类的方法中,我们需要招募在人们所评估的目标语言方面具有专业能力的人类评估员。专家人类会对输入 LLM 的一组样本给出分数。然后,我们计算这些分数与 LLM 评估器生成分数之间的相关性。相关性越高,LLM 评估器越好。
在这个快速增长的领域中,有一个值得关注的项目是开源 GLIDER。它是一个 3B 参数的评估器 LLM,在 685 个领域上训练,可以根据任意用户定义标准,对任何文本输入及其相关上下文进行评分。
GLIDER 的判断分数达到 91.3% 的人类一致性,这意味着,当 GLIDER 评估输出,而人类专家也评估同一输出时,它们在 91.3% 的时间里意见一致。这是验证一个 LLM 裁判是否可靠的主要方式:将它的判断与人类评估员会做出的决定进行比较。这表明它与该研究中的标注者高度对齐,但不应被解释为在所有领域或评分方案中都具有普遍可靠性。
关于 GLIDER 流程,可以再补充一些信息:
样本选择: 他们从测试集中随机抽取了 100 个数据点。
专家标注员: 他们招募了三位专家标注员来进行人类评估研究。
测量内容: 标注员从三个二元指标上评估 GLIDER 的输出:
分数正确性。
推理链质量。
高亮片段的相关性,也就是 GLIDER 识别为重要的文本片段。
GLIDER 在这三个指标上的平均一致性分数分别达到 91%、90% 和 91%。
除了我们的图示和 GLIDER 方法之外,还有一种替代方式:使用人类来比较不同的裁判 LLM。Judge Arena 就是一个值得注意的例子。它是一个允许用户投票判断哪个 AI 模型做出更好评估的平台,如图 2-6 所示。
图示说明:LLM 裁判成对评估系统图,展示选择裁判、生成对比样本、进行人类评估,以及基于偏好对裁判排序并创建排行榜的过程。
图 2-6 人在回路中的元评估
本质上,Judge Arena 是一个通过正面对抗比较 LLM 裁判的众包基准平台。
流程如下:
不同 LLM 裁判模型,例如 GPT-4、Claude 或专门的裁判模型,对同一组输出进行评估。这些输出可以是摘要、创意写作、代码,或者任何其他 AI 生成内容。
每个裁判给出自己的评估,通常包括分数、推理,以及关于质量、准确性或相关性等标准的具体反馈。
然后,这些评估会以成对比较的格式呈现给人类评估员。
人类评估员会并排看到两个匿名裁判评估,例如标为 “Judge A” 和 “Judge B”,同时也会看到被评估的原始内容。人类的任务是判断哪个裁判给出了更好、更准确或更有用的评估,而不是自己去评估原始内容。
在收集了不同裁判和不同内容类型下的大量人类投票之后,Judge Arena 会基于每个裁判模型的胜负记录计算 Elo 分数。
那些持续生成被人类认为更准确或更有洞察力评估的裁判,会在排名中上升。这会形成一个排行榜,显示哪些 LLM 裁判在不同领域和评估标准上最可靠。
这个平台本质上是通过聚合人类对裁判质量的偏好,众包完成 LLM 裁判的验证,而不要求每个用户都进行自己昂贵的人类评估研究。
注意,在 Judge Arena 中,LLM 输入及其提示词会展示给人类评估员,并且可以自定义,从而支持任务特定的元评估。此外,Judge Arena 的 LLM 提示词也可以由用户编辑。它的默认提示词如下:
模型是否针对用户需求或问题提供了相关且有用的回答?
评分标准:
分数 1: 模型回答与用户需求或查询无关,或没有帮助。
分数 2: 模型有时提供有用信息,但经常无法回应用户实际需求或问题。
分数 3: 模型通常提供能回应用户需求的有用回答,尽管偶尔会偏离目标。
分数 4: 模型经常提供与用户问题高度一致的有用回答,只有少数不准确之处。
分数 5: 模型始终提供高度相关且有用的回答,完美契合用户需求和问题。
Judge Arena 的方法和政策框架有三个值得强调的关键优势:
通过开源代码、文档和数据共享实现透明性。
LLM 纳入标准要求具备评分/批判能力,并且可公开访问。
基于 Elo 的排行榜系统,并让社区参与评估。
Judge Arena 是一个非常有用的平台,它在保持透明性和可访问性标准的同时,实现了对 AI 裁判的民主化评估。
LLM 基准测试简要导览
在结束之前,让我们快速看一下流行的 LLM 基准测试,因为它们在这个领域中经常被讨论和引用。基准测试像是 LLM 的标准化考试,会评估模型在一系列任务上的表现。这些任务模拟真实世界应用,例如回答问题、生成连贯文本、解决数学问题,甚至编写计算机代码。它们也可能评估更抽象的质量,例如公平性、鲁棒性和文化理解。基准测试可以被看作是全面的“考试”,它们测试不同“科目”,以便为一个 LLM 进行认证。
MMLU(Massive Multitask Language Understanding)于 2021 年推出,为模型的多学科知识提供了严格测试,涵盖从 STEM 领域到人文学科和社会科学的 57 个科目。
HumanEval 等专门基准则关注领域特定任务,例如代码生成,测试模型将自然语言描述转换成功能性程序代码的能力。相比之下,Large Model Systems Organization(LMSYS,2023)通过多轮对话评估对话式 AI,把现实世界适用性带入评估中心。LMSYS 优先考虑连贯性、上下文理解和用户满意度,为评估 GPT 和 Claude 等模型在动态场景中的表现提供了一个实用视角。
Hugging Face Open LLM Leaderboard 因其在开源社区中的透明性和可访问性而突出。这个排行榜会在包括通用知识、推理和代码编写在内的多样任务上评估大量 LLM。
Chatbot Arena(2024)排行榜是 LMSYS 的演进版本,它采用另一种方法,通过直接模型比较来衡量真实世界表现。它的评估格式是在实时对话中比较模型,并由人类裁判提供定性评估。
AlpacaEval 和 MT-Bench 排行榜则使用 LLM 进行自动化评估,以评估模型在多轮对话中的表现。
LiveBench 代表了一种新颖解决方案,专门设计来抵抗污染和评估偏见。作为第一个具备来自近期来源的持续更新问题、自动客观评分,以及覆盖多个领域的多样化挑战任务的基准,LiveBench 即使在模型持续改进的情况下,也能保持有效性。
ARC-AGI 与奖项
AI 评估领域的一个重要里程碑,是 ARC Prize, Inc. 推出了 Abstraction and Reasoning Corpus(ARC)Prize。ARC Prize, Inc. 是一个致力于开放通用人工智能(AGI)公共进步的非营利组织。ARC-AGI 最早出现在 François Chollet 2019 年的论文《On the Measure of Intelligence》中,旨在衡量流体智能,也就是推理、解决新问题和适应新情况的能力。推出时,它由类似谜题的、基于网格的视觉推理问题组成,这些问题对人类来说非常简单,但对机器来说很有挑战性,需要测试者仅通过少量输入—输出示例,通过抽象和推断推导底层规则。
该基准被称为 ARC-AGI,是因为 Chollet 认为,智能应该根据在未知任务上获得技能的效率来衡量,也就是模型学习新技能的速度,而不是根据它在可以提前准备的任务上的表现来衡量。
尽管 ARC 名称中包含 AGI,我们在宣称通过 ARC-AGI 任务就直接证明 AGI 之前,需要保持谨慎。正如 François Chollet 清楚指出的:“我认为人们并没有真正理解 ARC-AGI-1 有多简单,也没有真正理解解决它意味着什么。它被设计成对流体智能最简单、最基础的评估。无法通过它,意味着几乎完全不能适应或解决不熟悉情境中的问题。通过它,意味着你的系统表现出了非零的流体智能——你终于看到了一些并非纯粹记忆技能的东西。但它几乎不能说明你的系统有多智能,或者它离人类智能有多近。”可参见 François Chollet 的推文。
下面是 ARC 如何定义 AGI,以及它不如何定义 AGI:
共识但错误的定义:
AGI 是一个可以自动化大部分具有经济价值工作的系统。
正确的定义:
AGI 是一个能够高效获得新技能并解决开放式问题的系统。
ARC 不会直接把我们带向 AGI,但它在四个重要方面区别于其他 LLM 基准:
关注核心知识
与测试广泛知识和技能、并且通常高度依赖记忆的 LLM 基准不同,ARC 关注的是类似四五岁儿童可能拥有的核心知识。这包括物体识别、计数和基础物理等基本概念。
任务新颖性
每个 ARC 谜题都被设计为新颖任务,这意味着即使一个 LLM 已经在整个互联网上训练过,它在训练时也很可能没有见过这个任务。这一特性直接挑战了 LLM 的典型运行方式,也就是利用其庞大的“插值式记忆”。
强调程序合成
ARC 任务要求模型针对每个独特谜题,即时合成新的解决程序。这与更常见的 LLM 方法形成对比,后者通常是从记忆中检索既有解决程序。
抵抗暴力破解尝试
ARC 承认暴力方法存在可能性,但它的目标是抵抗这种方法,即防止模型通过在数百万类似谜题上训练,然后依靠与测试集的重叠获得高分。
图 2-7 展示了 ARC 任务样例,它表现为三到五个输入和输出任务序列,随后给出一个只列出输入的最终任务。每个任务都会基于极少数量的认知先验,测试某项特定已学习技能的使用。一次成功提交,是对最终任务输出的像素级完美描述,包括颜色和位置。
图示说明:一系列网格图案展示 ARC 挑战中的输入—输出任务,强调模式识别和转换技能。
图 2-7 ARC-AGI 任务样例
这些特征使 ARC 基准成为一种独特的机器智能测试,关注的是适应新颖性并解决问题的能力,而不是高度依赖记忆。这更符合通用智能的概念,因为通用智能强调的是高效学习并应对新挑战的能力。
截至本文写作时,也就是 2025 年后半段,排名最高的已验证商业模型 Claude Opus 4.5 with extended thinking 在 ARC-AGI-2 上取得了 37.6% 的分数;而基于 Gemini 3 Pro 构建的最高已验证 refinement solution 分数为 54%。GPT-5.2 的 Pro 配置在 ARC-AGI-2 上达到 54.2%;当它与 Poetiq 的专门求解系统结合时,准确率达到 75%,首次超过平均人类测试者 60% 的分数。NVIDIA 研究人员使用一个微调后的 4B 模型,并以每个任务仅 20 美分的成本,在 Kaggle ARC Prize 2025 比赛中以 27.64% 的分数获胜,展示了更小、更高效的模型可以在这一基准上超过更大的模型。尽管如此,即便有 GPT-5.2 的突破,距离完美表现仍然有 46% 到 47% 的差距,ARC-AGI-2 中大约一半任务仍然难倒了最好的 AI 系统。重要的是,ARC-AGI-2 中的所有任务,对于没有任何先前训练的人类来说都是可解的,并且 100% 的任务至少被两名独立人类测试者解出。基准创建者已经在适应变化。ARC-AGI-3 已于 2026 年初发布,目标是衡量 AI agent 中类似人类的智能。总之,虽然我们已经看到非凡进展,但基准本身也在演进,以保持领先于当前 AI 能力。
这表明,LLM 的能力和复杂性会持续提升,评估框架也必须随之演进。现代基准越来越多地纳入对细腻推理、伦理决策,以及此前无法衡量的涌现能力的测试。这种持续演进反映出一种更深层理解:语言模型的真正价值,不在于在狭窄任务特定指标的标准化测试中取得高分,而在于它们能否有意义地促进人类理解,帮助解决真实世界问题,同时展示学习和适应新任务的能力。
结论
评估 LLM 的根本挑战在于它们的非确定性——同一个问题可以有几十种有效回答方式,这使得 BLEU 和 ROUGE 等传统指标单独使用时是不够的。虽然这些指标仍然是有用工具,但我们需要纳入 LLM-as-a-judge 来评估我们真正关心的质量:准确性、有帮助性,以及在不同输出之间保持连贯性。一个 LLM 裁判可以识别出两种完全不同的表达其实传达了同一个意思,并判断哪一种更好地服务于上下文和受众。
但 ARC-AGI 这样的基准提醒我们,LLM 裁判也有局限。它们评估的是输出是否看起来像良好的人类文本,而不是模型是否真正能够推理。ARC-AGI 测试的是抽象推理和新问题解决能力——这种基础智能对人类来说很简单,但 AI 仍然困难。当你评估自己的 LLMBA 时,应当同时使用三种方法:使用确定性指标进行快速回归测试;使用 LLM 裁判进行生产中的质量评估;使用推理基准来诚实面对模型实际能做什么、不能做什么。
- 模型可用性会随着时间变化。如果该模型已被弃用或不可用,请替换为当前受支持的轻量模型;这里展示的较小 token 限制用于教学目的。
- 事实上,人类评估已经成为一门不断增长的业务,例如 Scale AI, Inc.
- Anthropic 的 Evan Miller 在 2024 年发表的《A Statistical Approach to Model Evaluations》,是关于如何估计评估指标置信水平的优秀参考。
- 生成任务是指模型产生新内容的任务,例如文本、代码或图像,而不是简单地从训练集中进行选择。
- 关于如何为 LLM 的评估指标选择阈值,可参见 Sarmah 等人在 2024 年发表的《How to Choose a Threshold for an Evaluation Metric for Large Language Models》。
- 关于这些局限的深入讨论,可参见 Zhen Li 等人在 2024 年发表的《Leveraging Large Language Models for NLG Evaluation: A Survey》。
- 可参见 Darshan Deshpande 等人在 2024 年发表的《GLIDER: Grading LLM Interactions and Decisions Using Explainable Ranking》。
- 可参见 Dan Hendrycks 等人在 2021 年发表的《Measuring Massive Multitask Language Understanding》。
- 可参见 Mark Chen 等人在 2021 年发表的《Evaluating Large Language Models Trained on Code》。
- 可参见 Lianmin Zheng 等人在 2023 年发表的《Judging LLM-as-a-Judge with MT-Bench and Chatbot Arena》。
- 可参见 Colin White 等人在 2024 年发表的《LiveBench: A Challenging, Contamination-Limited LLM Benchmark》。