如何为您的用例评估一个新的 LLM
当一个新的 LLM 发布时,您可能想确定它在您的特定用例中是否优于当前模型。本指南将向您展示如何使用 Ragas 框架在两个模型之间进行准确性比较。
您将完成什么
阅读完本指南后,您将能够:
- 建立一个结构化的评估,比较两个 LLM
- 在真实的业务任务上评估模型性能
- 生成详细结果,为您的模型选择决策提供信息
- 拥有一个可重用的评估循环,每当新模型发布时都可以重新运行
评估场景
我们将使用折扣计算作为我们的测试用例:给定一个客户资料,计算适当的折扣百分比并解释原因。这项任务需要规则应用和推理能力——这些技能可以区分不同模型的能力。
注意:您可以将此方法应用于任何对您的应用程序重要的用例。
📁 完整代码:此示例的完整源代码可在 Github 上找到
设置环境和 API 访问
首先,安装 ragas-examples 包,其中包含基准 LLM 示例代码
接下来,确保您已配置好 API 凭据
LLM 应用程序
我们在示例包中为您设置了一个简单的 LLM 应用程序,以便您可以专注于评估而不是构建应用程序本身。该应用程序根据业务规则计算客户折扣。
这是定义折扣计算逻辑的系统提示
SYSTEM_PROMPT = """
You are a discount calculation assistant. I will provide a customer profile and you must calculate their discount percentage and explain your reasoning.
Discount rules:
- Age 65+ OR student status: 15% discount
- Annual income < $30,000: 20% discount
- Premium member for 2+ years: 10% discount
- New customer (< 6 months): 5% discount
Rules can stack up to a maximum of 35% discount.
Respond in JSON format only:
{
"discount_percentage": number,
"reason": "clear explanation of which rules apply and calculations",
"applied_rules": ["list", "of", "applied", "rule", "names"]
}
"""
您可以使用一个示例客户资料来测试该应用程序
from ragas_examples.benchmark_llm.prompt import run_prompt
# Test with a sample customer profile
customer_profile = """
Customer Profile:
- Name: Sarah Johnson
- Age: 67
- Student: No
- Annual Income: $45,000
- Premium Member: Yes, for 3 years
- Account Age: 3 years
"""
result = await run_prompt(customer_profile)
print(result)
📋 输出
{
"discount_percentage": 25,
"reason": "Sarah qualifies for a 15% discount due to age (67). She also gets a 10% discount for being a premium member for over 2 years. The total stacking of 15% and 10% discounts results in 25%. No other discounts apply based on income or account age.",
"applied_rules": ["Age 65+", "Premium member for 2+ years"]
}
检查评估数据集
为了进行此评估,我们构建了一个包含以下测试用例的合成数据集:
- 结果明确的简单案例
- 规则边界上的边缘案例
- 信息模糊的复杂场景
每个案例都指定了:
customer_profile:输入数据expected_discount:预期折扣百分比description:案例复杂性指标
数据集结构示例(添加一个 id 列以便于比较)
| ID | 客户资料 | 预期折扣 | 描述 |
|---|---|---|---|
| 1 | 玛莎是一位 70 岁的退休人员,喜欢园艺。她最近没有报读任何学术课程,年退休金为 5 万美元,九年前注册了我们的服务,并且从未升级到高级会员。 | 15 | 仅老年人 |
| 2 | 阿尔琼,19 岁,是一名全日制计算机科学本科生。他的兼职工作年收入约 4.5 万美元。他一年前开设了账户,没有高级会员资格。 | 15 | 仅学生 |
| 3 | 辛西娅是一位 40 岁的自由艺术家,年收入约 2.5 万美元。她没有在任何地方学习,五年前订阅了我们的基础计划,并且从未升级到高级会员。 | 20 | 仅低收入 |
要为您的用例自定义数据集,请创建一个 datasets/ 目录并添加您自己的 CSV 文件。有关更多信息,请参阅核心概念 - 评估数据集。
最好从您的应用程序中抽样真实数据来创建数据集。如果没有真实数据,您可以使用 LLM 生成合成数据。由于我们的用例稍微复杂,我们建议使用像 gpt-5-high 这样的模型,它可以生成更准确的数据。请务必手动审查和验证您使用的数据。
注意
虽然本指南中的示例数据集大约有 10 个案例以保持简洁,但对于实际评估,您可以从 20-30 个样本开始,但请确保逐步迭代改进,使其达到 50-100 个样本的范围,以从评估中获得更可信的结果。确保广泛覆盖您的代理可能面临的不同场景(包括边缘案例和复杂问题)。您的准确性最初不需要达到 100%——使用结果进行错误分析,迭代提示、数据和工具,并不断改进。
加载数据集
def load_dataset():
"""Load the dataset from CSV file. Downloads from GitHub if not found locally."""
import urllib.request
current_dir = os.path.dirname(os.path.abspath(__file__))
dataset_path = os.path.join(current_dir, "datasets", "discount_benchmark.csv")
# Download dataset from GitHub if it doesn't exist locally
if not os.path.exists(dataset_path):
os.makedirs(os.path.dirname(dataset_path), exist_ok=True)
urllib.request.urlretrieve("https://raw.githubusercontent.com/vibrantlabsai/ragas/main/examples/ragas_examples/benchmark_llm/datasets/discount_benchmark.csv", dataset_path)
return Dataset.load(name="discount_benchmark", backend="local/csv", root_dir=current_dir)
数据集加载器会检查本地是否存在 CSV 文件。如果未找到,它会自动从 GitHub 下载。
指标函数
通常最好使用一个简单的指标。您应该使用与您的用例相关的指标。有关指标的更多信息,请参见核心概念 - 指标。评估使用此准确性指标为每个响应评分。
@discrete_metric(name="discount_accuracy", allowed_values=["correct", "incorrect"])
def discount_accuracy(prediction: str, expected_discount):
"""Check if the discount prediction is correct."""
import json
parsed_json = json.loads(prediction)
predicted_discount = parsed_json.get("discount_percentage")
expected_discount_int = int(expected_discount)
if predicted_discount == expected_discount_int:
return MetricResult(
value="correct",
reason=f"Correctly calculated discount={expected_discount_int}%"
)
else:
return MetricResult(
value="incorrect",
reason=f"Expected discount={expected_discount_int}%; Got discount={predicted_discount}%"
)
实验结构
每个模型评估都遵循此实验模式
@experiment()
async def benchmark_experiment(row, model_name: str):
# Get model response
response = await run_prompt(row["customer_profile"], model=model_name)
# Parse response (strict JSON mode expected)
try:
parsed_json = json.loads(response)
predicted_discount = parsed_json.get('discount_percentage')
except Exception:
predicted_discount = None
# Score the response
score = discount_accuracy.score(
prediction=response,
expected_discount=row["expected_discount"]
)
return {
**row,
"model": model_name,
"response": response,
"predicted_discount": predicted_discount,
"score": score.value,
"score_reason": score.reason
}
运行实验
使用基准模型和候选模型运行评估实验。我们将比较这些示例模型:
- 基准模型:"gpt-4.1-nano-2025-04-14"
- 候选模型:"gpt-5-nano-2025-08-07"
from ragas_examples.benchmark_llm.evals import benchmark_experiment, load_dataset
# Load dataset
dataset = load_dataset()
print(f"Dataset loaded with {len(dataset)} samples")
# Run baseline experiment
baseline_results = await benchmark_experiment.arun(
dataset,
name="gpt-4.1-nano-2025-04-14",
model_name="gpt-4.1-nano-2025-04-14"
)
# Calculate and display accuracy
baseline_accuracy = sum(1 for r in baseline_results if r["score"] == "correct") / len(baseline_results)
print(f"Baseline Accuracy: {baseline_accuracy:.2%}")
# Run candidate experiment
candidate_results = await benchmark_experiment.arun(
dataset,
name="gpt-5-nano-2025-08-07",
model_name="gpt-5-nano-2025-08-07"
)
# Calculate and display accuracy
candidate_accuracy = sum(1 for r in candidate_results if r["score"] == "correct") / len(candidate_results)
print(f"Candidate Accuracy: {candidate_accuracy:.2%}")
每个实验都会在 experiments/ 目录下保存一个 CSV 文件,其中包含每行的结果,包括:
- id, model, response, predicted_discount, score, score_reason
实验输出示例(为便于阅读,仅显示部分列)
| ID | 描述 | 预期 | 预测 | 得分 | 得分原因 |
|---|---|---|---|---|---|
| 1 | 仅老年人 | 15 | 15 | 正确 | 正确计算折扣=15% |
| 2 | 仅学生 | 15 | 5 | 不正确 | 预期折扣=15%;得到折扣=5% |
| 3 | 仅低收入 | 20 | 20 | 正确 | 正确计算折扣=20% |
| 4 | 老年人、低收入、新客户(有上限) | 35 | 35 | 正确 | 正确计算折扣=35% |
| 6 | 仅限 2 年以上高级会员 | 10 | 15 | 不正确 | 预期折扣=10%;得到折扣=15% |
注意
在可能的情况下,固定并记录确切的模型快照/版本(例如,使用“gpt-4o-2024-08-06”而不是仅仅“gpt-4o”)。提供商会定期更新别名,不同快照之间的性能可能会发生变化。您可以在提供商的模型文档中找到可用的快照(例如,参见 OpenAI 的模型目录)。在您的结果中包含快照,可以使未来的比较公平且可复现。
比较结果
在使用不同模型运行实验后,并排比较它们的性能
from ragas_examples.benchmark_llm.evals import compare_inputs_to_output
# Compare the two experiment results
# Update these paths to match your actual experiment output files
output_path = compare_inputs_to_output(
inputs=[
"experiments/gpt-4.1-nano-2025-04-14.csv",
"experiments/gpt-5-nano-2025-08-07.csv"
]
)
print(f"Comparison saved to: {output_path}")
这种比较会:
- 读取两个实验文件
- 打印每个模型的准确性
- 创建一个新的 CSV 文件,将结果并排显示
比较文件显示:
- 测试用例详情(客户资料、预期折扣)
- 每个模型:其响应、是否正确以及原因
📋 输出
使用合并的 CSV 分析结果
在此次运行示例中:
- 筛选一个模型优于另一个模型的案例,会显示以下情况:“老年人且新客户”、“学生且新客户”、“仅学生”、“仅限 2 年以上高级会员”。
- 每个模型响应中的原因字段显示了它给出该输出的原因。
比较 CSV 文件中的示例行(为便于阅读,仅显示部分列)
| id | customer_profile | description | expected_discount | gpt-4.1-nano-2025-04-14_score | gpt-5-nano-2025-08-07_score | gpt-4.1-nano-2025-04-14_score_reason | gpt-5-nano-2025-08-07_score_reason | gpt-4.1-nano-2025-04-14_response | gpt-5-nano-2025-08-07_response |
|---|---|---|---|---|---|---|---|---|---|
| 2 | 阿尔琼,19 岁,是一名全日制计算机科学本科生。他的兼职工作年收入约 4.5 万美元。他一年前开设了账户,没有高级会员资格。 | 仅学生 | 15 | 不正确 | 正确 | 预期折扣=15%;得到折扣=0% | 正确计算折扣=15% | ...原因="阿尔琼 19 岁,因此不符合基于年龄或老年人的折扣条件。他 45,000 美元的年收入超过了 30,000 美元的门槛,因此不适用基于收入的折扣。他一年前开设账户,已超过 6 个月,因此不是新客户。他没有高级会员资格,也没有其他适用的折扣。"... | ...原因="因学生身份(阿尔琼 19 岁,本科生)有资格享受 15% 的折扣。"... |
| 6 | 莱昂纳多 64 岁,下个月满 65 岁。他的薪水正好是 30,000 美元。他已维持高级会员订阅两年零七个月,并已使用我们服务五年。 | 仅限 2 年以上高级会员 | 10 | 不正确 | 正确 | 预期折扣=10%;得到折扣=25% | 正确计算折扣=10% | ...原因="莱昂纳多即将满 65 岁,因此他有资格享受 15% 的年龄折扣。注意到有 2 年以上高级会员资格"... | ...原因="莱昂纳多 64 岁,下个月满 65 岁。2 年以上高级会员:10%"... |
新模型发布时重新运行
一旦这个评估流程与您的项目并存,它就成了一个可重复的检查。当有新的 LLM 发布时(现在通常是每周一次),将其作为候选模型接入,并重新运行相同的评估,以与您当前的基准模型进行比较。
解读结果并做出决策
需要关注什么
- 基准模型准确性 vs 候选模型准确性 以及 差异。
- 本次运行示例:基准模型 50% (5/10),候选模型 90% (9/10),差异 +40%。
如何解读数据行
- 快速浏览两个模型结果不一致的行。
- 使用每行的 score_reason 来查看其被标记为正确/不正确的原因。
- 寻找规律(例如,错过的规则叠加、边界情况如“将近 65 岁”、精确的收入门槛)。
超越准确性
- 检查成本和延迟。如果速度太慢或成本太高,即使准确性更高也可能不值得。
做出决定
- 如果新模型在您重要的案例上明显更准确,并且符合您的成本/延迟需求,就切换。
- 如果提升很小,失败发生在关键案例上,或者成本/延迟不可接受,则保持原样。
在这个例子中: - 我们会切换到 "gpt-5-nano-2025-08-07"。它将准确性从 50% 提高到 90% (+40%),并修复了关键的失败模式(错过的规则叠加、边界条件)。如果其延迟/成本符合您的限制,那么它就是更好的默认选择。
适应您的用例
要为您的特定应用程序评估模型,您可以使用 GitHub 代码 作为模板,并根据您的用例进行调整。
Ragas 框架会自动为您处理编排、并行执行和结果聚合,帮助您专注于评估和您的用例!