Agent评估体系-怎么知道你的Agent够不够好
评估软件系统的质量,通常有清晰的方法:单元测试、集成测试、性能基准。这些方法的共同前提是:对于给定的输入,存在明确的"正确输出",可以用程序自动验证。
Agent 评估体系:怎么知道你的 Agent 够不够好
1.1 为什么 Agent 评估是一个特殊的难题
评估软件系统的质量,通常有清晰的方法:单元测试、集成测试、性能基准。这些方法的共同前提是:对于给定的输入,存在明确的"正确输出",可以用程序自动验证。
Agent 打破了这个前提,带来了三个不同寻常的挑战。
挑战一:输出的非确定性
LLM 的输出是概率性的。同样的问题,Agent 每次跑出来的回答措辞不同、顺序不同、详细程度不同。这不是 bug,而是 LLM 工作原理的必然结果(temperature 参数控制随机性,但哪怕 temperature=0 在不同批次也可能有细微差异)。
传统测试方法——断言输出等于期望输出——在这里完全失效。
挑战二:评估标准本身的模糊性
对于"帮我写一封拒绝邮件"这样的任务,什么叫"好的回答"?礼貌但坚定?还是直接但简短?不同用户有不同偏好,不存在客观的"正确答案"。评估标准本身需要人来定义,而且标准之间可能相互矛盾(完整性 vs 简洁性)。
挑战三:评估成本与覆盖率的矛盾
人工评估准确但昂贵,自动化评估便宜但精度有限。一个生产 Agent 每天处理上万个对话,人工全部审核不现实;只抽样评估,又担心漏掉重要问题。这个矛盾没有完美的解法,只有工程上的权衡。
正确的心态:接受不完美,建立持续改进的机制
Agent 评估的目标不是"证明 Agent 没有问题",而是"建立足够灵敏的感知,在 Agent 退化时能尽早发现"。这意味着:评估不是一次性的,而是持续的;评估方法不追求完美覆盖,而是追求成本可持续、能驱动决策。
本章介绍 Agent 质量评估的完整方法论,包括主流评估基准、实际项目中的评估方法,以及关键评估指标的定义和实现。
没有评估体系,Agent 的优化就是凭感觉。无法判断当前状态,更无法判断改进方向——每次修改 Prompt 后重新部署,下一次收到的反馈可能和上次差不多,无法确认是否真的改好了,也不知道改好了多少。
1.2 为什么 Agent 评估比普通软件测试难
传统软件测试的逻辑很清晰:给定输入 X,期望输出 Y,实际输出 Z,比较 Y 和 Z 是否一致。确定性强,自动化容易。
Agent 不一样,有三个根本性的难点。
输出不确定。同一个问题,同一个 Agent,每次跑出来的答案可能不一样。LLM 的输出是概率性的,temperature 不为零就有随机性。无法像传统测试那样直接比较字符串是否相等——就算答案内容完全正确,表达方式稍有不同也会判定失败。
评估标准模糊。"回答质量好不好"这件事,很难量化。对于"帮我写一份项目总结"这类开放性任务,不存在唯一正确答案,评分标准本身就需要人来制定和校准。
评估成本高。人工审核 100 条 Agent 对话记录,每条平均花 3 分钟,就是 5 个小时。还不算需要了解每个问题的背景知识。大规模人工评估的成本是不可持续的。
正因为这三个问题,很多团队的 Agent 评估停留在"自己多用用,觉得不错就上线"这个层次。结果就是上线踩坑、依赖用户反馈、亡羊补牢。
1.3 主流评估基准
学术界和工业界都在尝试解决这个问题,已经有了几个值得了解的评估基准。
BFCL(Berkeley Function Calling Leaderboard,伯克利函数调用排行榜)
加州大学伯克利分校推出,专门评估 LLM 的工具调用能力。这个基准的设计非常务实——它把工具调用场景分成四个类别:
- Simple:调用单个工具,参数直接从用户输入提取
- Multiple:从多个候选工具中选择正确的那个
- Parallel:一次调用多个工具(比如同时查北京和上海的天气)
- Irrelevance:用户的问题根本不需要调用工具,模型不应该乱调
判断正确性用 AST(Abstract Syntax Tree,抽象语法树,一种将代码结构化表示为树形结构的方式)匹配:把模型输出的函数调用解析成语法树,和标准答案的语法树比较。这样即使参数顺序不同,只要语义等价就算正确。比直接比字符串要合理得多。
如果 Agent 工具调用频繁出问题,可以参考 BFCL 的测试用例设计思路,给自己的工具构建类似的测试集。
GAIA(General AI Assistants benchmark)
Meta AI 与 HuggingFace 合作于 2023 年推出,目标是评估 AI 助手处理真实世界问题的能力。466 个问题,分三个难度级别:
- Level 1:单步推理,一两个工具调用就能解决
- Level 2:多步推理,需要调用多个工具、组合信息
- Level 3:复杂任务,需要长链推理和多轮工具调用
GAIA 的评分方式是准精确匹配(quasi-exact match):答案不需要一模一样,但关键信息必须正确。比如答案是"2024 年 3 月 15 日",模型回答"3 月 15 日,2024 年"也算对。
GAIA 的题目都是真实世界的问题,而不是人造的测试用例,这让它的评分更贴近实际能力。
AgentBench
清华大学发布,覆盖多种 Agent 应用场景:操作系统命令执行、数据库操作、网页浏览、代码生成、家庭场景决策等。不只是测语言能力,而是测 Agent 在实际环境中完成任务的能力。
这三个基准更多用于模型选型阶段——在决定用哪个 LLM 作为 Agent 底座时,可以参考这些排行榜数据。但它们不能直接替代业务场景的自定义评估。
1.4 实际项目里的评估方法
学术基准是通用评估,真正要保障自己 Agent 质量,还是得建适合业务场景的评估体系。
第一步:构建测试集
目标:50 到 100 个有标准答案的问答对,覆盖主要使用场景。
不用很多,但要有代表性。每个测试用例包含:用户输入、期望的最终回答、期望调用的工具(如果有)。
test_cases = [
{
"input": "帮我查一下北京今天的天气",
"expected_tools": ["get_weather"],
"expected_answer_keywords": ["北京", "天气", "温度"],
"category": "工具调用-天气查询"
},
{
"input": "1+1 等于多少",
"expected_tools": [], # 这个问题不应该调用工具
"expected_answer_keywords": ["2"],
"category": "直接回答-数学"
},
{
"input": "帮我分析一下苹果公司最近的股价走势",
"expected_tools": ["get_stock_price", "search_news"],
"expected_answer_keywords": ["苹果", "股价"],
"category": "多工具调用-金融分析"
},
]
第二步:LLM-as-Judge
人工评估成本高,但自动化评估精度低。折中方案是用 GPT-4 或 Claude 评估另一个模型的输出。这就是 LLM-as-Judge 方法。
LLM-as-Judge 能工作的原因是:一个强大的 LLM(如 GPT-4)在评估其他模型的输出时,其判断质量接近人类专家。它可以理解问题的细微之处、识别事实错误、判断回答是否完整——这些都是程序难以自动化的能力。
评估维度通常是三个:正确性(答案在事实上是否准确)、完整性(有没有遗漏关键信息)、相关性(回答有没有跑题)。
验证目的:实现一个 LLM-as-Judge 评估函数,并用 Win Rate 方法对比两个 Agent 版本,建立一个可复用的评估管道。
from openai import OpenAI
import json
client = OpenAI()
def llm_judge(question: str, reference_answer: str, model_answer: str) -> dict:
"""
用 LLM 评估 Agent 的回答质量。
返回三个维度的评分(1-5 分)和评估理由。
"""
judge_prompt = f"""你是一个严格的 AI 评估员。请评估下面的 AI 回答质量。
【用户问题】
{question}
【参考答案】
{reference_answer}
【待评估回答】
{model_answer}
请从以下三个维度打分(1-5 分,5 分最高):
1. 正确性:回答在事实上是否准确,有没有错误信息
2. 完整性:是否回答了问题的所有关键点,有没有遗漏
3. 相关性:回答是否紧扣问题,有没有跑题或冗余
请以 JSON 格式返回结果:
{{
"correctness": <1-5 的整数>,
"completeness": <1-5 的整数>,
"relevance": <1-5 的整数>,
"reason": "<简短的评估理由>"
}}"""
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": judge_prompt}],
response_format={"type": "json_object"},
temperature=0, # 评估要稳定,temperature 设为 0
)
return json.loads(response.choices[0].message.content)
# 示例使用
result = llm_judge(
question="北京今天天气怎么样?",
reference_answer="北京今天晴天,气温 22°C,东南风 3 级,适合户外活动。",
model_answer="北京今天天气不错,气温大约 22 度,阳光明媚。"
)
print(result)
# {"correctness": 4, "completeness": 3, "relevance": 5, "reason": "回答准确,但缺少风力信息"}
第三步:Win Rate(胜率对比)
当改了 Prompt 或换了模型,想知道新版本是不是真的更好,Win Rate 是比绝对分数更可靠的方法。
把同一批问题分别跑新旧两个版本,然后让评估模型选出更好的那个答案。胜率超过 55% 就基本可以认为有显著提升。
def compare_responses(question: str, response_a: str, response_b: str) -> str:
"""
让 LLM 比较两个回答,返回 'A'、'B' 或 'tie'。
A/B 顺序会随机交换以避免位置偏差。
"""
import random
# 随机交换顺序,避免 LLM 偏向第一个答案
swap = random.random() > 0.5
if swap:
response_a, response_b = response_b, response_a
compare_prompt = f"""请比较以下两个 AI 回答,选出更好的那个。
【用户问题】
{question}
【回答 A】
{response_a}
【回答 B】
{response_b}
请只回复 'A'、'B' 或 'tie'(表示两者质量相当)。不要解释原因。"""
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": compare_prompt}],
temperature=0,
)
winner = response.choices[0].message.content.strip()
# 如果交换过,把结果换回来
if swap:
if winner == "A":
winner = "B"
elif winner == "B":
winner = "A"
return winner
def calculate_win_rate(questions: list, agent_v1, agent_v2) -> dict:
"""计算 v2 相对于 v1 的胜率"""
wins, losses, ties = 0, 0, 0
for q in questions:
resp_v1 = agent_v1(q)
resp_v2 = agent_v2(q)
result = compare_responses(q, resp_v1, resp_v2)
if result == "B": # B 是 v2
wins += 1
elif result == "A": # A 是 v1
losses += 1
else:
ties += 1
total = len(questions)
return {
"win_rate": wins / total,
"loss_rate": losses / total,
"tie_rate": ties / total,
"conclusion": "v2 更好" if wins / total > 0.55 else "没有明显提升"
}
第四步:人工验证
不管自动化评估做得多好,关键场景必须有人工审核这道关。尤其是:
- 涉及金融、医疗等高风险场景的回答
- 自动评估分数明显异常的用例
- 新上线功能的首批真实用户对话
1.5 评估流程
1.6 关键评估指标
Agent 评估六维度雷达图 — 任务完成率、工具调用准确性、推理质量、响应速度、成本效率、安全性
准确率:最终答案正确的比例。对于有确定答案的问题(查天气、查数据),可以做精确匹配;对于开放性问题,用 LLM-as-Judge 的平均分代替。
工具调用成功率:Agent 应该调用工具的时候调了、不该调的时候没乱调、调用参数正确——三个子指标合并。这个指标直接反映 Agent 的工具使用能力。
def evaluate_tool_calls(
actual_tools: list[str],
expected_tools: list[str]
) -> dict:
"""评估工具调用的准确性"""
actual_set = set(actual_tools)
expected_set = set(expected_tools)
# 该调的都调了
recall = len(actual_set & expected_set) / len(expected_set) if expected_set else 1.0
# 调的都是该调的(没有乱调)
precision = len(actual_set & expected_set) / len(actual_set) if actual_set else 1.0
# 综合指标
f1 = 2 * precision * recall / (precision + recall) if (precision + recall) > 0 else 0.0
return {"precision": precision, "recall": recall, "f1": f1}
任务完成率:用户的目标有没有最终达成。这是最接近用户体验的指标,但也最难自动化。对于有明确终止条件的任务(比如"帮我预订一张机票"),可以检查关键步骤是否都完成了。
平均步骤数:Agent 完成任务平均需要多少轮工具调用。步骤数越少,效率越高,成本越低。如果同样能完成任务,步骤从 5 步降到 3 步,这是明显的优化。
1.7 持续评估:不是一次性的
每次改动都要跑评估:换了 Prompt、升级了模型版本、新增了工具、修改了工具的描述文字……任何一个变动都可能影响 Agent 的整体表现,而且影响方式往往是意想不到的。改了一个工具的描述,可能导致模型在完全不相关的场景里开始乱调这个工具。
最好的实践是把评估集成进 CI/CD(持续集成/持续交付,一种软件工程实践,每次代码变更时自动运行测试和检查,确保质量达标才允许合并)流程:每次合并代码,自动跑一遍评估,如果核心指标下降超过阈值,阻止合并。在生产环境,每天抽样 5% 的真实对话跑评估,当指标出现异常波动时立刻告警。
没有评估的 Agent 优化是盲目的。有可能在一个指标上提升、在另一个指标上退步,最终原地踏步甚至越改越差。
评估不是额外的工作,它是工程化 Agent 的基础。没有评估,连"当前状态"都说不清楚,更别说"朝哪个方向改进"了。