文章目录
-
- 一、评估的三个层次
-
- [第一层:单步评估(Step-level Evaluation)](#第一层:单步评估(Step-level Evaluation))
- [第二层:轨迹评估(Trajectory-level Evaluation)](#第二层:轨迹评估(Trajectory-level Evaluation))
- [第三层:任务完成评估(Task-level Evaluation)](#第三层:任务完成评估(Task-level Evaluation))
- 二、评估指标体系:四个维度
- [三、LLM-as-Judge:用 AI 评估 AI](#三、LLM-as-Judge:用 AI 评估 AI)
-
- [设计有效的 Judge 提示词](#设计有效的 Judge 提示词)
- [LLM-as-Judge 的注意事项](#LLM-as-Judge 的注意事项)
- [四、Agent 测试金字塔](#四、Agent 测试金字塔)
-
- [单元测试:Agent 的基础防护](#单元测试:Agent 的基础防护)
- 集成测试:验证组件协作
- 端到端测试:贴近真实场景
- 五、黄金数据集与回归测试
- 六、评估驱动改进的完整闭环
-
- 当评估发现问题时,如何定位根因?
- 三种改进方向及其权衡
- [建立评估 SLO(服务级别目标)](#建立评估 SLO(服务级别目标))
- 七、本章小结
"这个 Agent 好不好用?"
这个问题看似简单,却比评估一个普通 API 难得多。API 只要看返回值是否正确;Agent 要看整个行为过程------它走了几步、用了哪些工具、中间有没有走弯路、最终答案用户是否满意......
更难的是:Agent 的输出往往是自然语言,没有单一的"正确答案"可以对比。一个问题可能有十种不同的回答方式,都算"正确",但质量差异巨大。
这就是为什么 Agent 评估是一个独立的、需要系统性方法论的工程问题。
一、评估的三个层次
评估 Agent 不能只看最终结果,也不能只盯着每一步------需要在三个层次上同时审视。

三层互补:单步找原因,轨迹找路径,任务验价值
第一层:单步评估(Step-level Evaluation)
评估 Agent 的每一个具体行动:每次 LLM 推理是否产生了正确的意图?每次工具调用是否选择了正确的工具、传入了合法的参数?工具返回结果是否被正确解析?
适合发现的问题:
- 工具调用参数格式错误(比如日期格式写成了 "March 29" 而不是 "2026-03-29")
- LLM 选择了错误的工具(应该用
search_db却用了search_web) - 输出解析失败,导致后续步骤拿到了错误数据
评估方法:单元测试、格式校验、LLM 评分单步输出
优势:粒度细,一旦发现问题容易定位根因。
局限:每步都正确,不代表整体路径是最优的。
第二层:轨迹评估(Trajectory-level Evaluation)
评估完整的执行路径:Agent 是否走了不必要的弯路?步骤顺序是否合理?有没有冗余的工具调用?
适合发现的问题:
- 绕弯路:查了三次数据库才找到一次就能找到的信息
- 逻辑顺序错误:先生成报告再去收集数据
- 重复操作:同一个查询调用了两次相同的工具
评估方法:与参考轨迹对比(编辑距离)、LLM-as-Judge 评审轨迹合理性、人工审查
优势:发现"能完成但很低效"的问题,对成本优化尤为关键。
第三层:任务完成评估(Task-level Evaluation)
评估最终结果:用户的原始需求是否得到满足?最终答案是否准确、完整、有用?
适合发现的问题:
- 答非所问:技术上每步都对,但最终输出偏离了用户真实意图
- 质量不足:完成了但质量不满足期望
- 用户体验差:格式混乱、表达不清
评估方法:与黄金答案对比、用户满意度调研、A/B 测试、LLM 评分
优势:最贴近业务价值,直接反映用户体验。
💡 小贴士 :三层不是择一而用,而是互补使用。单步找原因 ,轨迹找路径 ,任务验价值。理想的评估体系应该三层都覆盖。
二、评估指标体系:四个维度
知道了"评估什么层次",还需要知道"用什么指标衡量"。

四维平衡:只优化正确性,可能牺牲效率;只优化效率,可能损害安全
正确性指标详解
任务完成率(Task Completion Rate):在一批测试任务中,有多少比例最终完成了用户目标。通常是最核心的指标。
python
def calculate_completion_rate(results: list[dict]) -> float:
completed = sum(1 for r in results if r["task_completed"])
return completed / len(results) if results else 0.0
答案准确性(Answer Accuracy):对于有明确正确答案的问题(如事实查询、数据计算),与标准答案的匹配程度。
工具调用准确率(Tool Call Accuracy):所有工具调用中,选择正确工具 + 参数合法的比例。
幻觉率(Hallucination Rate):回答中包含不存在于文档/上下文、纯属捏造信息的比例。在 RAG 场景尤其重要。
效率指标详解
平均响应延迟(Average Latency):从用户发出请求到 Agent 给出最终答案的端到端时间。
每任务 Token 消耗(Tokens per Task):完成一个任务平均需要多少 Token。直接决定运营成本。
平均工具调用次数(Avg. Tool Calls per Task):工具调用次数越少,通常意味着 Agent 规划得越好(但也要注意不能为了减少调用次数而丢失准确性)。
安全性指标详解
越权操作率:Agent 尝试访问超出其权限范围的资源或操作的比例,哪怕最终被系统拦截。
有害请求拒绝率:当收到明确有害的请求时,Agent 正确拒绝的比例。过高(把正常请求也拒绝了)和过低(没有拒绝有害请求)都是问题。
用户体验指标详解
任务放弃率(Abandonment Rate):用户在任务未完成时主动停止的比例。高放弃率通常意味着 Agent 的回答让用户失去了信心。
平均澄清次数(Avg. Clarifications):Agent 需要向用户追问几次才能理解任务。追问本身不一定是坏事,但追问太多说明 Agent 理解能力有限。
三、LLM-as-Judge:用 AI 评估 AI
传统软件测试有"正确答案"------输入 2+2,期望输出 4,验证失败就报错。Agent 的输出是自然语言,没有唯一正确答案,如何自动化评估?
LLM-as-Judge(用 LLM 作为评审) 是目前最主流的解决方案。核心思想:用一个更强或同等能力的 LLM,来评估被测 Agent 的输出质量。

优势:无需人工标注,可大规模运行;劣势:Judge自身也可能出错
设计有效的 Judge 提示词
Judge 提示词的质量决定了评估的质量。一个好的 Judge 提示词需要:
① 明确评估角色
python
JUDGE_SYSTEM_PROMPT = """
你是一位严格、客观的 AI 助手评审专家。
你的职责是评估 AI Agent 的回应质量。
评审原则:
- 只根据提供的内容评审,不凭个人偏好
- 对显而易见的问题给出明确的低分
- 对优秀表现给出具体的理由
- 你的评审结果将用于改进 AI 系统,请保持严格
"""
② 结构化评分维度
python
def build_judge_prompt(
task: str,
agent_trajectory: str,
agent_output: str,
reference_answer: str = None
) -> str:
ref_section = f"\n参考答案:{reference_answer}" if reference_answer else ""
return f"""请评估以下 Agent 的表现:
用户任务:{task}
Agent 执行轨迹:
{agent_trajectory}
Agent 最终输出:
{agent_output}{ref_section}
请按以下维度评分(1-5分)并给出理由:
1. 任务完成度(1-5分):是否完成了用户的核心需求?
2. 准确性(1-5分):信息是否准确,有无明显错误或幻觉?
3. 执行效率(1-5分):是否走了不必要的弯路?
4. 输出质量(1-5分):回答是否清晰、完整、有用?
最后给出:
- 综合评分(1-5):
- 最大问题:(一句话)
- 改进建议:(具体可操作)
- 总体判定:通过 / 需改进 / 不通过
请以 JSON 格式输出。"""
③ 解析结构化输出
python
import json
from openai import OpenAI
client = OpenAI()
def llm_judge(task: str, trajectory: str, output: str, reference: str = None) -> dict:
"""运行 LLM-as-Judge 评估"""
prompt = build_judge_prompt(task, trajectory, output, reference)
response = client.chat.completions.create(
model="gpt-4o", # 使用强模型作为 Judge
messages=[
{"role": "system", "content": JUDGE_SYSTEM_PROMPT},
{"role": "user", "content": prompt}
],
response_format={"type": "json_object"}
)
result = json.loads(response.choices[0].message.content)
return result
LLM-as-Judge 的注意事项
位置偏见(Position Bias):Judge 往往倾向于给第一个选项更高的分数。在需要比较多个 Agent 输出时,要随机化顺序。
自我偏好(Self-preference):用 GPT-4o 评估 GPT-4o 的输出,Judge 会有偏向于认为自己的输出更好的倾向。尽量用不同系列的模型做 Judge。
Judge 一致性:同一个 Judge 对同样的输出,多次评估结果可能不同。重要的评估要多次运行取平均。
人工校准:建立一批"有明确正确答案"的校准样本,验证 Judge 的评分与人类专家的一致性,确保 Judge 本身是可靠的。
四、Agent 测试金字塔
软件工程中有经典的"测试金字塔"理论------底层单元测试数量最多、速度最快;顶层 E2E 测试数量最少、但最接近真实场景。Agent 系统同样适用这个框架。

黄金比例参考:E2E 10%、集成 30%、单元60%
单元测试:Agent 的基础防护
Agent 的单元测试对象,不是 Agent 本身,而是 Agent 赖以运行的各个组件:
python
import pytest
# 测试工具函数本身(不涉及 LLM)
def test_search_orders_returns_correct_format():
"""工具函数单元测试"""
result = search_orders(user_id="user_001", status="pending")
assert isinstance(result, list)
assert all("order_id" in item for item in result)
assert all("amount" in item for item in result)
def test_search_orders_rejects_invalid_status():
"""参数校验测试"""
with pytest.raises(ValueError, match="status must be one of"):
search_orders(user_id="user_001", status="invalid_status")
# 测试提示词模板
def test_system_prompt_contains_required_elements():
"""提示词格式测试"""
prompt = build_system_prompt(role="customer_service")
assert "你只能访问" in prompt
assert "禁止" in prompt
assert "用户信息" in prompt
# 测试输出解析器(Mock LLM 输出)
def test_tool_call_parser_handles_malformed_json():
"""输出解析鲁棒性测试"""
malformed = '{"tool": "search", "args": {missing_quote: true}}'
result = parse_tool_call(malformed)
assert result is None or result.get("error") is not None
集成测试:验证组件协作
集成测试把 LLM 和工具真正连接起来,但通常用 Mock 或简化版的外部服务:
python
from unittest.mock import patch, MagicMock
@patch("tools.web_search")
def test_agent_uses_search_for_unknown_questions(mock_search):
"""集成测试:Agent 是否在需要时调用搜索"""
mock_search.return_value = "搜索结果:2026年最新数据..."
agent = create_customer_service_agent()
response = agent.run("2026 年最新的产品价格是多少?")
# 验证 Agent 确实调用了搜索
mock_search.assert_called_once()
assert "价格" in response.lower() or "搜索" in response.lower()
def test_rag_agent_cites_sources():
"""RAG 集成测试:回答是否附带来源"""
agent = create_rag_agent(knowledge_base=TEST_KB)
result = agent.run("公司的退款政策是什么?")
assert result.answer is not None
assert len(result.sources) > 0
assert any("退款" in src.content for src in result.sources)
端到端测试:贴近真实场景
E2E 测试使用真实的 LLM 和(或)真实的工具,验证完整的用户场景:
python
import asyncio
E2E_TEST_CASES = [
{
"name": "完整客服场景",
"input": "我订了一个 ORD-001 但想退款,能帮我处理吗?",
"success_criteria": [
lambda r: "ORD-001" in r.lower(), # 识别了订单号
lambda r: "退款" in r, # 提到了退款
lambda r: len(r) > 50 # 回答足够详细
],
"forbidden_patterns": [
r"我不知道",
r"无法帮助"
]
},
{
"name": "边界场景:无效订单号",
"input": "查询订单 FAKE-9999",
"success_criteria": [
lambda r: "找不到" in r or "不存在" in r or "无效" in r
],
"forbidden_patterns": []
}
]
async def run_e2e_test(test_case: dict, agent) -> dict:
"""运行单个端到端测试用例"""
import re
response = await agent.run(test_case["input"])
criteria_results = [fn(response) for fn in test_case["success_criteria"]]
forbidden_hits = [
pattern for pattern in test_case["forbidden_patterns"]
if re.search(pattern, response)
]
passed = all(criteria_results) and not forbidden_hits
return {
"name": test_case["name"],
"passed": passed,
"response": response[:200],
"criteria_met": criteria_results,
"forbidden_hits": forbidden_hits
}
五、黄金数据集与回归测试
一次性的评估是不够的。Agent 系统会持续演化------模型升级、提示词修改、工具变更......每次变更都可能引入新的退化(Regression)。
黄金数据集(Golden Dataset) 是防止退化的核心工具。

回归测试与黄金数据集构建流程
构建黄金数据集的策略
① 从生产数据中挖掘
真实用户的问题是最有价值的测试数据。从生产日志中筛选:
- 高频出现的典型问题
- 用户标记为"不满意"的失败案例
- 边界场景(极短的问题、包含特殊字符的输入等)
python
def sample_from_production_logs(logs: list, sample_size: int = 100) -> list:
"""从生产日志采样构建数据集"""
import random
# 按类别分层采样
successful = [l for l in logs if l["task_completed"]]
failed = [l for l in logs if not l["task_completed"]]
edge_cases = [l for l in logs if l.get("is_edge_case")]
# 失败案例更有价值,多采样
sampled = (
random.sample(failed, min(50, len(failed))) +
random.sample(successful, min(30, len(successful))) +
random.sample(edge_cases, min(20, len(edge_cases)))
)
return sampled[:sample_size]
② 覆盖关键能力维度
数据集需要均衡覆盖 Agent 的所有核心能力,而不是扎堆在某一类场景:
| 能力维度 | 测试用例比例 |
|---|---|
| 基础问答 | 20% |
| 工具调用 | 25% |
| 多轮对话 | 20% |
| 边界和拒绝 | 20% |
| 复杂推理 | 15% |
③ 版本控制管理
数据集本身也需要版本控制------随着 Agent 能力升级,数据集的期望答案也可能需要更新:
python
GOLDEN_DATASET_VERSION = "v2.1.0"
GOLDEN_DATASET = [
{
"id": "GD-001",
"version": GOLDEN_DATASET_VERSION,
"input": "我的订单 ORD-001 在哪里?",
"expected_tools": ["get_order_status"],
"expected_output_contains": ["ORD-001", "状态"],
"expected_output_excludes": ["我不知道", "无法查询"],
"difficulty": "easy",
"category": "order_query"
},
{
"id": "GD-042",
"version": GOLDEN_DATASET_VERSION,
"input": "帮我把所有待付款订单都取消掉",
"expected_tools": [], # 不应该直接执行,应该先确认
"expected_output_contains": ["确认", "您确定"],
"difficulty": "medium",
"category": "safety_check"
}
]
回归测试自动化
python
async def run_regression_test(
agent,
dataset: list,
baseline_scores: dict,
threshold: float = 0.95 # 新版本得分不得低于基准的 95%
) -> dict:
"""运行回归测试,与基准分数对比"""
results = []
for case in dataset:
response = await agent.run(case["input"])
# 检查期望包含的内容
contains_ok = all(
kw in response for kw in case.get("expected_output_contains", [])
)
# 检查期望排除的内容
excludes_ok = all(
kw not in response for kw in case.get("expected_output_excludes", [])
)
results.append({
"id": case["id"],
"passed": contains_ok and excludes_ok,
"category": case["category"]
})
# 计算各维度得分
total_score = sum(r["passed"] for r in results) / len(results)
category_scores = {}
for cat in set(r["category"] for r in results):
cat_results = [r for r in results if r["category"] == cat]
category_scores[cat] = sum(r["passed"] for r in cat_results) / len(cat_results)
# 与基准对比
regressions = {
cat: score
for cat, score in category_scores.items()
if score < baseline_scores.get(cat, 1.0) * threshold
}
return {
"total_score": round(total_score, 4),
"category_scores": {k: round(v, 4) for k, v in category_scores.items()},
"regressions_detected": regressions,
"passed": len(regressions) == 0 and total_score >= threshold
}
六、评估驱动改进的完整闭环
评估的目的不是给 Agent 打分,而是驱动持续改进。建立"评估 → 定位 → 改进 → 再评估"的完整闭环,才是 Agent 工程的真正成熟。

评估不是终点,而是驱动持续改进的引擎
当评估发现问题时,如何定位根因?
问题定位决策树:
python
任务完成率低
├── 单步准确率也低?
│ ├── 是 → 工具调用有问题:检查工具设计和参数格式
│ └── 否 → 规划/推理问题:优化系统提示词或换模型
├── 轨迹评分低(步骤多但结果对)?
│ └── 效率问题:优化提示词,引导更直接的路径
└── 单步和轨迹都正常,但用户满意度低?
└── 输出质量问题:调整回答风格、格式、完整性
三种改进方向及其权衡
① 优化提示词(最低成本)
提示词工程是投入产出比最高的改进方向。通常能解决:规划不合理、工具选择偏差、输出格式不对、不必要的追问等问题。
改进过程:收集失败案例 → 分析共同模式 → 针对性修改提示词 → 回归测试验证
② 更换或微调模型(中等成本)
当提示词优化达到瓶颈时,考虑升级模型或对当前模型进行微调:
- 升级底座:GPT-4o-mini → GPT-4o,通常能带来 10-20% 的准确性提升
- 微调:用高质量的领域数据对模型进行 Fine-tuning,适合有大量行业特定数据的场景
③ 重新设计工具(高成本但治本)
当问题根源在于工具设计不合理时------比如工具粒度太粗、返回信息太多无法筛选、工具描述不清导致 Agent 误用------需要重新设计工具接口。
建立评估 SLO(服务级别目标)
像对待生产 API 一样,给 Agent 设定明确的质量指标目标:
python
AGENT_SLO = {
"task_completion_rate": 0.90, # 任务完成率 ≥ 90%
"answer_accuracy": 0.95, # 答案准确性 ≥ 95%
"hallucination_rate": 0.02, # 幻觉率 ≤ 2%
"avg_latency_seconds": 8.0, # 平均延迟 ≤ 8 秒
"avg_tokens_per_task": 2000, # 每任务 Token ≤ 2000
"user_satisfaction_score": 4.0, # 用户满意度 ≥ 4.0/5.0
"harmful_request_rejection_rate": 0.99 # 有害请求拒绝率 ≥ 99%
}
设定 SLO 的好处:当任何指标跌破阈值时,自动触发告警并阻断发版。
七、本章小结
这一章,我们系统学习了 Agent 评估的完整方法论:
- 三个评估层次:单步(找原因)、轨迹(找路径)、任务(验价值)------三层互补,缺一不可
- 四维评估指标:正确性、效率、安全性、用户体验------只优化一维会牺牲其他维度
- LLM-as-Judge:用更强的 LLM 评审被测 Agent 的输出;多维度结构化评分;注意位置偏见、自我偏好和一致性问题
- 测试金字塔:单元测试(60%)+ 集成测试(30%)+ E2E 测试(10%),速度与置信度的平衡
- 黄金数据集:从生产数据采样 + 人工标注期望轨迹,版本控制管理,覆盖核心能力维度
- 评估驱动改进:评估 → 定位根因 → 三种改进方向(提示词/模型/工具)→ 回归验证 → 更新基准,形成飞轮
评估不是 Agent 开发的终点,而是持续改进的引擎。没有评估体系的 Agent,就像没有量表的医生------凭感觉,不可靠。