AI 评测系列(05):Agent 评测——工具调用准确率与轨迹质量

Agent 评测为什么特殊

评测一个 RAG 系统,最终答案就是评测对象------对或错,准确或不准确。

Agent 的过程本身也是评测对象。绕 3 步找到的正确答案,和调对工具但参数错误的情况,只看最终答案都会漏掉。

Agent 评测需要覆盖两个维度:

csharp 复制代码
维度 1:工具调用准确性(可自动化)
  工具名准确率:选了正确的工具?
  参数准确率:工具调用参数正确?
  步骤效率:用了多少步完成任务?

维度 2:轨迹质量(LLM-as-Judge)
  推理是否合理:每步调用有逻辑依据?
  有无冗余调用:是否存在重复或无效的工具调用?
  错误处理:工具返回空结果时有没有正确应对?

实验设计

被测 Agent: 客服助手,3 个工具:

python 复制代码
search_faq(query)                                  # 搜索产品常见问题
get_order_status(order_id)                         # 查询订单状态
calculate_refund(amount, days_since_purchase)       # 计算退款金额

15 个测试用例,覆盖三类场景:

类别 用例数 示例
简单单工具 9 个 "退款政策是什么" → search_faq
多步骤 3 个 "ORD-004 能退款多少" → get_order_status + calculate_refund
边界情况 3 个 不存在的订单、已取消的订单、无需工具的闲聊

每个用例有 ground truth:期望的工具调用序列和参数。


运行结果

工具调用准确率

ini 复制代码
  [T01] ✓ tools=['search_faq']                     name=✓  params=100%
  [T02] ✓ tools=['get_order_status']                name=✓  params=100%
  [T03] ✗ tools=[]  期望=['search_faq']             name=✗  params=100%
  [T04] ✗ tools=[]  期望=['get_order_status',...]   name=✗  params=100%
  [T05] ✓ tools=['calculate_refund']                name=✓  params=100%
  [T06] ✓ tools=['get_order_status','calculate_refund'] name=✓ params=100%
  ...
  [T10] ✗ tools=[]  期望=['search_faq']             name=✗  params=100%
  [T13] ✓ tools=[]  期望=[](闲聊,无需工具)       name=✓  params=100%
  [T14] ✗ tools=[]  期望=['get_order_status']       name=✗  params=100%

汇总指标

ini 复制代码
Tool Name Accuracy:   73%  (11/15 correct sequences)
Parameter Accuracy:  100%  (avg across all tool calls)
Step Efficiency:     0.73x  (1.0 = optimal)
Trajectory Quality:  3.73/5  (LLM-as-Judge)

Failed cases (4):
  [T03] expected=['search_faq']                actual=[]
  [T04] expected=['get_order_status', 'calculate_refund']  actual=[]
  [T10] expected=['search_faq']                actual=[]
  [T14] expected=['get_order_status']          actual=[]

Per-category breakdown:
  Simple (1 tool)        tool_acc=75%  trajectory=3.75/5
  Multi-step (2 tools)   tool_acc=67%  trajectory=3.67/5
  Edge cases             tool_acc=67%  trajectory=3.67/5

三个发现

发现 1:失败类型只有一种------"应调工具却没调"

4 个失败案例的失败模式完全一致:Agent 直接给出答案,没有调用任何工具。参数准确率 100% 说明凡是 Agent 决定调工具的情况,参数都是对的。

失败分布:

复制代码
工具选错类型(调了但选错):0 个
参数错误类型(选对但参数错):0 个
未触发工具类型(应调未调):4 个

工具执行逻辑没有问题,工具触发逻辑是瓶颈。Agent 在某些情况下认为自己知道答案,跳过了工具调用。

T03("配送需要多少天?")和 T10("我是会员,有什么优惠?")失败原因:这两类问题 glm-4-flash 有内置知识,即使 Prompt 要求"必须使用工具",模型仍然直接回答了。T04(需要先查订单再计算退款)和 T14(已取消订单的退款问题)失败原因:复合问题和边界问题,模型倾向于直接推断而不是查询。

修复方向: 在 System Prompt 里针对这些场景加更强的约束,或者用 Rule-based 路由在 LLM 判断之前预处理特定类型的问题。

发现 2:步骤效率 0.73x------低于 1.0 是因为有些任务少用了步骤

步骤效率 < 1.0 看起来是好事,实际原因是失败案例中 Agent 少做了必要步骤。

复制代码
理想情况(无失败)下的效率:
  T06(需要 2 步):Agent 用了 2 步 → 效率 1.0
  T12(需要 2 步):Agent 用了 2 步 → 效率 1.0

失败案例(减少了步骤,但答案质量下降):
  T04(需要 2 步):Agent 用了 0 步 → 效率 0.0

步骤效率低于 1.0 有两种原因:

  1. Agent 真的找到了更高效的路径(好事)
  2. Agent 跳过了必要步骤(坏事)

单看步骤效率数字无法区分这两种情况,需要结合工具名准确率一起解读。

发现 3:多步骤任务和边界情况的轨迹质量更低

ini 复制代码
Simple (1 tool):        tool_acc=75%  trajectory=3.75/5
Multi-step (2 tools):   tool_acc=67%  trajectory=3.67/5
Edge cases:             tool_acc=67%  trajectory=3.67/5

多步骤和边界情况的工具名准确率都是 67%,比简单任务的 75% 低。轨迹质量分也低。

多步骤任务的失败模式:Agent 认为可以一步完成,跳过了中间步骤。边界情况(已取消订单)的失败模式:Agent 直接推断"已取消订单没有退款",没有先查询订单状态确认信息。

这个分布符合大多数 Agent 系统的规律:简单直接的任务表现好,复合/边界任务表现差。测试集设计时必须包含足够比例的多步骤和边界用例,否则准确率数字会被单步任务拉高,掩盖真实问题。


工具调用评测的实现

工具名准确率

最严格的评测:工具调用序列必须完全匹配。

python 复制代码
def tool_name_accuracy(actual: list[str], expected: list[str]) -> bool:
    """检查工具调用序列是否完全匹配。"""
    if len(actual) != len(expected):
        return False
    return all(a == e for a, e in zip(actual, expected))

参数准确率

允许字符串部分匹配和数值容差,避免因格式差异导致漏判:

python 复制代码
def param_match_score(actual_calls, expected_args) -> float:
    """计算参数准确率,返回 0.0-1.0。"""
    total, correct = 0, 0
    for actual, expected in zip(actual_calls, expected_args):
        for key, expected_val in expected.items():
            total += 1
            actual_val = actual["args"].get(key)
            if actual_val is None:
                continue
            # 数值容差(允许 0.01 以内误差)
            if isinstance(expected_val, (int, float)):
                if abs(float(actual_val) - float(expected_val)) < 0.01:
                    correct += 1
            # 字符串部分匹配
            elif str(expected_val).lower() in str(actual_val).lower():
                correct += 1
    return correct / total if total > 0 else 1.0

轨迹质量(LLM-as-Judge)

python 复制代码
TRAJECTORY_JUDGE_PROMPT = """评估以下 Agent 执行轨迹的质量(1-5分):

用户问题:{question}
Agent 调用的工具:{tool_calls}
Agent 的最终回答:{answer}

5分:工具调用完全合理,每步都有必要,回答准确完整
4分:工具调用基本合理,有1个小问题
3分:工具调用方向正确,但有冗余或遗漏
2分:工具调用部分错误,回答质量差
1分:工具调用完全错误或完全无关

只返回 1-5 的整数分数。"""

测试集设计的三个关键

1. ground truth 需要工具序列,不只是最终答案

python 复制代码
TestCase(
    id="T04",
    question="ORD-004 这个订单能退款多少钱?",
    expected_tools=["get_order_status", "calculate_refund"],   # 工具序列
    expected_args=[
        {"order_id": "ORD-004"},
        {"amount": 99.0, "days_since_purchase": 15}
    ],  # 期望参数
    expected_min_steps=2,   # 最少需要几步
)

2. 覆盖三类难度

erlang 复制代码
简单(单工具):    测基础工具识别能力,应占 50%
多步骤(多工具):  测规划能力,应占 30%
边界情况:          测鲁棒性(不存在的资源、空结果处理),应占 20%

3. 包含"不需要工具"的用例

纯闲聊和问候测试 Agent 是否会过度调用工具。一个正确的 Agent 应该知道"你好"不需要查订单数据库。


总结

  1. 工具名准确率 73%,参数准确率 100%:失败全是"应调未调",不是"调错了";这说明工具触发逻辑是瓶颈,工具执行逻辑没问题,优化方向很清晰
  2. 步骤效率 < 1.0 需要结合工具名准确率解读:低效率可能是找到更短路径(好),也可能是跳过必要步骤(坏)
  3. 测试集必须包含多步骤和边界用例:简单单工具任务准确率 75%,多步骤和边界任务只有 67%,如果测试集全是简单任务,73% 会虚报成 85%+

参考资料


欢迎访问 PrimeSkills ------ 一个精心策划的 AI Agent 与技能市场,所有内容均经过真实企业级工作流验证。没有噱头,只有真正有效的东西。

更多实用知识和有趣产品,欢迎访问我的个人主页

相关推荐
阳光是sunny1 小时前
LangGraph高级教程:Multi Schema多状态管理详解
前端·人工智能·后端
CHrisFC1 小时前
环保第三方检测行业LIMS横向对比与选型指南
大数据·人工智能
DeepAgent1 小时前
AI Agent 工程实践(17):Agent 为什么需要可观测性(Observability)?
android·llm·agent
惊讶的猫1 小时前
CLGSI
人工智能·算法·机器学习
冬奇Lab1 小时前
开源项目第167期:Buzz — Block 开源的人机协作工作空间,Agent 是成员不是 Bot
人工智能·开源·agent
生命涌现1 小时前
生命涌现的小龙虾技能之【Human Pose Recognition Skill | 人体姿态识别技能】简介
人工智能·目标检测·计算机视觉·多模态大模型·openclaw小龙虾技能
funkygroove1 小时前
ChatGPT Business 包含 Pro 吗?两者区别一次说清
人工智能·chatgpt
神奇霸王龙2 小时前
Gemini CLI 中转站配置使用教程
人工智能·ai·ai作画·aigc·ai编程·gemini·goolge
stereohomology2 小时前
Kimi K3编程实力远超GLM5.2:一个Trae复赛证据
人工智能·大模型·对比·why不coding