阅读时间:约 16 分钟
前置知识:理解 Agent 决策循环(P01)、工具调用(P02)、重试策略(P04)


前六篇把 Agent 搭起来了:能调工具、管上下文、记东西、处理错误。但现在有一个根本问题:它到底做得好不好?怎么知道改了一个 prompt 是真的变好了,还是恰好碰对了?


前言:78% 的成功率够好吗?

先看一个真实场景。测试一个旅行预订 Agent,跑了 100 个用例,任务成功率 78%。看起来还行。

然后又跑了一遍,同样的 100 个用例,成功率变成了 65%。什么都没改,同一个 Agent,同样的输入,结果差了 13 个百分点。

这就是 Agent 评测和前六篇学过的所有东西最不一样的地方:Agent 不是确定性的。同一个任务,它今天走 A 路线成功,明天走 B 路线失败,后天走 C 路线又成功了。

所以你需要的不是简单的"对/错"标签,而是一套能分析整个执行过程的评估框架。光看最终结果,你永远不知道 Agent 在哪里摔倒了。

📌 本章核心:Agent 评测的核心不是"成功了吗",而是"在哪一层失败了"。三层评估模型:推理层(规划对不对)、行动层(工具调没调对)、执行层(任务完没完成)。


第一部分:三层评估模型

来自一线工程实践:Agent 的失败分布在三个不同的层面,每一层有自己的指标。

否,规划就错了

否,工具调用出了错

否,最后一步出错

Agent 执行任务

L1 推理层

规划合理吗?

L2 行动层

优化 Prompt/换模型

工具选对了吗?参数对吗?

L3 执行层

优化工具定义/加校验

任务完成了吗?效率呢?

✅ 成功

优化边界条件/加兜底

40% 的 Agent 失败出在行动层(选错工具或参数传错),而不是推理层。这意味着大部分问题不是"Agent 不够聪明",而是"工具描述不够清楚"或"参数约束不够严格"。

关注的指标失败意味着什么优化方向
L1 推理层规划质量、规划一致性Agent 没理解任务,制定了错误计划改 System Prompt 或换模型
L2 行动层工具选择正确率、参数正确率计划对但执行错(选了错工具、参数不对)改工具定义、加参数校验
L3 执行层任务成功率、进度率、步骤效率过程都对但最终结果不对查边界条件、加兜底逻辑

📌 本章要点:三层评估让你从"它失败了"变成"它在 L2 行动层失败了,需要优化工具定义"。精确诊断是精确修复的前提。


三层模型告诉你"问题在哪一层"。但每层怎么量化?

第二部分:六类核心指标

指标一:任务成功率(最基础,也最容易骗人)

直接问"任务完成了吗"不够。需要定义明确的验收条件。

# 差的定义
def is_success_bad(result):
    return "完成" in result or "成功" in result  # Agent 自己说完成就算?

# 好的定义
def is_success_good(task_result, acceptance_criteria):
    """
    验收条件示例:
    - 订单号存在且非空
    - 航班日期正确
    - 价格在预期范围
    - 乘客信息完整
    """
    return all(
        check(task_result) for check in acceptance_criteria
    )

指标二:工具调用准确率

分为两部分:选对工具(Tool Selection)、传对参数(Argument Correctness)。

def evaluate_tool_call(tool_calls, expected_tool, expected_args):
    """
    工具调用准确率 = 选对工具 AND 传对参数
    """
    if not tool_calls:
        return {"tool_correct": False, "args_correct": False, "score": 0}
    
    actual = tool_calls[0]
    tool_correct = actual.function.name == expected_tool
    
    args_correct = False
    if tool_correct:
        actual_args = json.loads(actual.function.arguments)
        args_correct = all(
            actual_args.get(k) == v for k, v in expected_args.items()
        )
    
    return {
        "tool_correct": tool_correct,
        "args_correct": args_correct,
        "score": 1.0 if (tool_correct and args_correct) else 0.0
    }

指标三:进度率

多步骤任务中,做到第几步就中断了?成功率 0% 但进度率 80%,说明离成功只差最后一步。

def progress_rate(completed_steps, total_steps):
    """已完成步骤数 / 总步骤数"""
    return completed_steps / total_steps if total_steps > 0 else 0

指标四:规划质量

Agent 的计划合理吗?步骤之间的顺序对吗?漏了关键步骤吗?

def evaluate_plan_quality(agent_plan, expected_plan_points):
    """
    规划质量 = 必需步骤的覆盖率
    用 LLM 评估:把 Agent 的计划和标准步骤对比
    """
    evaluation_prompt = f"""
    Agent 的计划:{agent_plan}
    必需步骤:{expected_plan_points}
    
    评估:
    1. Agent 的计划覆盖了哪些必需步骤?
    2. 步骤顺序是否合理?
    3. 是否有冗余或缺失?
    
    返回 JSON:{{"coverage": 0-1, "order_score": 0-1, "summary": "..."}}
    """
    return call_llm(evaluation_prompt)

指标五:步骤效率

一个任务最少 3 步能完成,Agent 用了 10 步。Steps/MinSteps 越小越好。

def step_efficiency(actual_steps, min_required_steps):
    """理想步骤数 / 实际步骤数"""
    return min_required_steps / actual_steps if actual_steps > 0 else 0

指标六:稳定性

同一个任务跑 10 次,每次结果都不一样?标准差不只衡量平均值,也衡量一致性。

def stability_score(success_rates_over_runs):
    """
    同一批测试用例,在 5 次独立运行中的成功率波动
    标准差越小越稳定
    """
    import statistics
    return {
        "mean": statistics.mean(success_rates_over_runs),
        "stdev": statistics.stdev(success_rates_over_runs) if len(success_rates_over_runs) > 1 else 0
    }

指标与三层的映射关系

指标对应层数值低说明
规划质量、规划一致性L1 推理层Prompt 或模型本身有问题
工具选择、参数正确率L2 行动层工具定义或约束不够
成功率、进度率、效率L3 执行层边界条件或兜底不足
稳定性全层Agent 的不确定性过高

📌 本章要点:六类指标覆盖三层。定义验收条件 > 问 Agent “你成功了吗”。40% 失败在 L2,别一上来就换模型。


指标定义好了。但人工一个个看执行轨迹不现实。怎么办?

第三部分:自动化评估:LLM 当裁判

LLM-as-Judge 的用法

让另一个 LLM 来评估 Agent 的输出,是当前最主流的自动化方案。但有个硬前提:必须用人工标注的数据做校准。

def llm_judge_evaluate(agent_trace, rubric):
    """
    用 LLM 评估 Agent 的执行轨迹
    agent_trace: Agent 的完整执行记录
    rubric: 评分标准(必须是明确的规则,不是模糊描述)
    """
    judge_prompt = f"""
    你是一个 Agent 评估专家。请严格按照以下标准评分。
    
    ## 执行轨迹
    {agent_trace}
    
    ## 评分标准
    {rubric}
    
    ## 输出格式
    返回 JSON:
    {{
        "task_success": true/false,
        "tool_selection_score": 0-1,
        "argument_correctness_score": 0-1,
        "efficiency_score": 0-1,
        "failure_reason": "如果失败,说明在哪一步出的问题"
    }}
    """
    response = call_llm(judge_prompt)
    return json.loads(response)

一个好的评分标准长这样(不是模糊描述):

good_rubric = """
- task_success: 订单系统中确实存在该订单,且订单状态为"已确认"
- tool_selection_score: 调用了 search_flights,且未调用无关工具
- argument_correctness_score: 参数中 departure_date 为明天的日期,格式为 YYYY-MM-DD
"""

bad_rubric = """
- task_success: Agent 完成了任务(❌ 太模糊)
- tool_selection_score: 工具选择合理(❌ "合理"怎么判断?)
"""

LLM-as-Judge 的局限

在专家知识任务上,LLM 裁判与人类专家的一致性可能很低。你的评估系统应该定期抽样让人类校验:抽 5% 的评估结果人工复核,如果一致性低于 85%,说明评估标准需要调整。

📌 本章要点:LLM-as-Judge 能自动化大量评估,但评分标准必须是可操作的规则而不是模糊描述。定期 5% 人工抽样校准是底线。


指标 + 自动化评估都有了。但 Agent 是动态的,一次评测不够。怎么做持续评测?

第四部分:评测不是一次性事件

评测应该是一个循环:上线 → 收集 → 评估 → 改进 → 再上线。

class ContinuousEvaluator:
    """持续评测:每次变更后自动评估"""
    
    def __init__(self, test_suite, judge_model="deepseek-v4-flash"):
        self.test_suite = test_suite      # 测试用例集
        self.judge_model = judge_model    # 评估用模型(用小模型降成本)
        self.baseline = None              # 基准结果
        self.history = []                 # 历史评估记录
    
    def establish_baseline(self, agent):
        """建立基准线:当前 Agent 在这套用例上表现如何"""
        results = [self._eval_one(agent, case) for case in self.test_suite]
        self.baseline = {
            "success_rate": sum(r["success"] for r in results) / len(results),
            "tool_accuracy": sum(r["tool_score"] for r in results) / len(results),
            "avg_efficiency": sum(r["efficiency"] for r in results) / len(results),
            "timestamp": time.time()
        }
        return self.baseline
    
    def check_regression(self, agent):
        """变更后评估,检测是否回退"""
        current = self.establish_baseline(agent)
        
        if self.baseline is None:
            return {"status": "no_baseline", "current": current}
        
        regression = {
            "success_rate_delta": current["success_rate"] - self.baseline["success_rate"],
            "tool_accuracy_delta": current["tool_accuracy"] - self.baseline["tool_accuracy"],
            "avg_efficiency_delta": current["avg_efficiency"] - self.baseline["avg_efficiency"]
        }
        
        # 任意指标下降超过 5% 就报警
        alerts = []
        for metric, delta in regression.items():
            if delta < -0.05:
                alerts.append(f"{metric}: {delta:+.1%}(下降超过 5%)")
        
        self.history.append({"baseline": self.baseline, "current": current, "alerts": alerts})
        
        return {
            "status": "regression_detected" if alerts else "passed",
            "baseline": self.baseline,
            "current": current,
            "alerts": alerts
        }
    
    def _eval_one(self, agent, case):
        """评估单个用例"""
        trace = agent.run(case["input"])
        judge_result = llm_judge_evaluate(trace, case["rubric"])
        return {
            "case_id": case["id"],
            "success": judge_result["task_success"],
            "tool_score": judge_result["tool_selection_score"],
            "efficiency": judge_result.get("efficiency_score", 0)
        }

三种评测频率

评测类型频率规模目的
快速冒烟每次改 prompt 后10-20 个核心用例确认没引入明显回退
基准评测每次发布前50-200 个标准用例确认整体能力没下降
深度评测每周/每月全部用例 + 新用例发现退化趋势,补充边界用例

📌 本章要点:评测是持续循环。每次变更都跑核心用例看是否回退。小模型做评估降低成本(小模型评估成本降低约 90%)。


第五部分:实战:完整的评测流水线

把前面讲的串起来:测试用例 → 运行 Agent → 收集轨迹 → LLM 评分 → 汇总报告。

# ═══════════════════════════════════════════
# AgentEval:完整评测流水线
# ═══════════════════════════════════════════

class AgentEval:
    def __init__(self, eval_model="deepseek-v4-flash"):
        self.evaluator = ContinuousEvaluator(
            test_suite=self._load_test_suite(),
            judge_model=eval_model
        )
    
    def _load_test_suite(self):
        """加载测试用例集"""
        return [
            {
                "id": "weather_001",
                "input": "北京今天天气怎么样?",
                "rubric": """
                - task_success: 回复中包含温度数值和天气状况
                - tool_selection_score: 调用了 get_weather 工具
                - argument_correctness_score: 参数 city 为 "北京"
                """,
                "min_steps": 1
            },
            {
                "id": "booking_001",
                "input": "帮我订明天从北京到上海的机票,要最便宜的",
                "rubric": """
                - task_success: 返回了包含航班号和价格的预订确认
                - tool_selection_score: 依次调用了 search_flights 和 book_flight
                - argument_correctness_score: search_flights 参数包含 departure=北京, arrival=上海
                """,
                "min_steps": 2
            },
            # 更多用例...
        ]
    
    def full_eval(self, agent):
        """完整评测:建立基准 + 逐用例评估 + 生成报告"""
        print("=" * 50)
        print("Agent 评测报告")
        print("=" * 50)
        
        baseline = self.evaluator.establish_baseline(agent)
        print(f"\n📊 综合指标:")
        print(f"   任务成功率: {baseline['success_rate']:.1%}")
        print(f"   工具调用准确率: {baseline['tool_accuracy']:.1%}")
        print(f"   平均步骤效率: {baseline['avg_efficiency']:.1%}")
        
        # 逐用例分析
        print(f"\n📋 逐用例详情:")
        for case in self._load_test_suite():
            result = self.evaluator._eval_one(agent, case)
            status = "✅" if result["success"] else "❌"
            print(f"   {status} {case['id']}: {case['input'][:40]}...")
            if not result["success"]:
                print(f"      工具分: {result['tool_score']:.1%}")
        
        return baseline


# 使用
eval_pipeline = AgentEval()
results = eval_pipeline.full_eval(my_agent)

# 每次改 prompt 后,快速检查是否回退
regression = eval_pipeline.evaluator.check_regression(my_agent)
if regression["alerts"]:
    print(f"⚠️ 检测到回退:{regression['alerts']}")

📌 本章要点:完整评测流水线 = 标准测试用例 + 三层指标 + LLM 自动评分 + 回退检测。改一次 prompt 就跑一次冒烟。


第六部分:从指标到行动:看到数字后怎么办

评测的最终目的不是收集数字,是找到改进方向。一个实用的诊断流程:

def diagnose_agent_issues(eval_results):
    """
    根据评测结果推荐优化方向
    """
    diagnosis = []
    
    # L1 问题:规划质量低
    if eval_results.get("plan_quality", 1.0) < 0.7:
        diagnosis.append({
            "layer": "L1 推理层",
            "symptom": "规划质量低",
            "action": "优化 System Prompt → 更明确的任务分解指令"
        })
    
    # L2 问题:工具调用不准(最常见)
    if eval_results.get("tool_accuracy", 1.0) < 0.8:
        diagnosis.append({
            "layer": "L2 行动层",
            "symptom": "工具调用准确率低",
            "action": "检查工具描述 → 加明确的使用条件和参数示例 → 加参数校验"
        })
    
    # L3 问题:成功率高但效率低
    if (eval_results.get("success_rate", 0) > 0.8 and 
        eval_results.get("efficiency", 1.0) < 0.5):
        diagnosis.append({
            "layer": "L3 执行层",
            "symptom": "能完成但步骤太多",
            "action": "优化 Prompt → 引导更直接的执行路径 → 消除冗余工具调用"
        })
    
    # 稳定性问题
    if eval_results.get("stability", {}).get("stdev", 0) > 0.1:
        diagnosis.append({
            "layer": "全层",
            "symptom": "表现不稳定",
            "action": "检查工具超时设置 → 检查是否有非确定性依赖 → 加更多测试用例"
        })
    
    return diagnosis
你看到的实际在说什么该做什么
成功率低、规划也低L1 推理问题改 Prompt,不是加工具
成功率高、工具调用率低L2 行动问题优化工具描述和参数约束
成功率高、但步骤太多L3 效率问题精简 Prompt,引导直接路径
每次结果不一样稳定性问题增加用例数,检查超时设置

📌 本章要点:评测的终局不是"Agent 得分 78 分",而是"Agent 在 L2 需要优化工具定义,L3 需要补充边界用例"。数字是导航,不是终点。


总结:读完这篇,你应该带走这几件事

  1. 评测看过程,不是只看结果。 78% 成功率掩盖了 40% 失败在 L2 行动层的事实。不看过程,你永远在瞎优化。
  2. 三层评估模型:L1 推理层(规划)、L2 行动层(工具)、L3 执行层(完成)。每层有各自的指标和优化策略。
  3. 六类核心指标,但本质是三个问题:规划对吗、工具调对了吗、任务完成了吗。
  4. LLM-as-Judge 必须校准。 评分标准是操作规则不是模糊描述。定期 5% 人工抽检。
  5. 评测是循环不是一次性。 每次改 prompt 跑冒烟,每次发布跑基准,每周深度评测。小模型评估降 90% 成本。
  6. 从数字到行动。 成功率低看 L1、工具调用率低看 L2、效率低看 L3、不稳定看超时设置。

🤔 思考一下:你现在怎么判断 Agent 改好了还是改坏了?有没有一套固定的测试用例,每次改动后跑一遍?


思维导图

  • Agent 评测体系
    • 三层评估模型
      • L1 推理层:规划质量、规划一致性
      • L2 行动层:工具选择、参数正确率
      • L3 执行层:成功率、进度率、步骤效率
    • 六类核心指标
      • 成功率(需要明确验收条件)
      • 工具调用准确率(40% 失败在这)
      • 进度率、规划质量、步骤效率、稳定性
    • 自动化评估
      • LLM-as-Judge + 操作规则
      • 5% 人工校准底线
      • 小模型评估降成本
    • 持续评测循环
      • 冒烟(每次改动)
      • 基准(每次发布)
      • 深度(每周/每月)
    • 从指标到行动
      • L1 低 → 改 Prompt
      • L2 低 → 改工具定义
      • L3 低 → 查边界条件
      • 不稳定 → 加用例 + 查超时

下一篇预告

P08. 从单 Agent 到 Agent 工作流:LangGraph/CrewAI 实战

系列最后一篇,串起前七篇的所有组件:把决策循环、工具调用、上下文管理、重试策略、记忆系统和评测体系整合成一个完整的 Agent 工作流。从概念到代码到上线,一个端到端的实战项目。

🤔 思考一下:P01 到 P07 的所有组件,你的项目里哪些已经落地了、哪些还在"以后再说"?

更多推荐