Agent 不只是生成一段文本。它会理解目标、规划步骤、调用工具、读取环境反馈,并在多轮交互中调整行为。这意味着,传统的大模型问答评测无法完整回答一个关键问题:这个 Agent 到底能不能稳定地完成业务任务?
一套可落地的 Agent 评测体系,需要把抽象的“效果好不好”拆成任务结果、过程质量、系统成本和安全边界,并让离线实验与线上真实反馈形成闭环。相关实践往往不是一次设计完成的,而是在深入业务、持续复盘失败案例的过程中逐步打磨出来。
评测的对象不是一句回答,而是一条执行轨迹
普通文本评测通常关注答案是否正确、相关或流畅。Agent 的输出则是一条轨迹,例如:
用户目标
-> Agent 制定计划
-> 调用搜索工具
-> 读取搜索结果
-> 调用订单接口
-> 根据异常重新规划
-> 返回结果
只检查最终回复,会漏掉很多问题:Agent 可能给出了看似正确的答案,却调用了错误接口;也可能完成任务,但执行了十几次重复搜索,成本和延迟不可接受;还可能依赖偶然出现的工具结果,换一组数据就失败。
因此,Agent 评测至少要覆盖四个层面:
| 层面 | 需要回答的问题 | 常见指标 |
|---|---|---|
| 任务结果 | 用户目标是否真正完成 | 成功率、结果正确率、约束满足率 |
| 执行过程 | 是否选择了合理步骤和工具 | 工具选择准确率、参数正确率、无效步骤数 |
| 系统效率 | 完成任务付出了多少资源 | 延迟、Token 数、工具调用次数、单次成本 |
| 风险控制 | 是否越权或产生危险行为 | 越权调用率、敏感信息泄露率、拒答准确率 |
这些指标不能相互替代。一个任务成功率更高、但成本翻倍且越权风险增加的版本,未必适合发布。
从业务目标反推评测集
建立体系时,最容易犯的错误是先找一个公开数据集,再思考它与业务有什么关系。更可靠的顺序是从业务目标出发,定义任务、风险和验收标准。
可以把评测集分成三层:
- 核心任务集:覆盖线上频率高、价值明确的主要工作流,例如查询订单、修改配置或生成分析报告。
- 边界与异常集:覆盖工具超时、参数缺失、数据冲突、权限不足和用户意图模糊等情况。
- 对抗与安全集:检查提示词注入、敏感数据访问、越权操作以及高风险动作确认机制。
每条样例不应只有输入和参考答案。对于 Agent,更有价值的样例结构通常包含:
id: refund_001
user_goal: 查询订单 A100 的退款状态
initial_state:
user_id: U42
allowed_order_ids:
- A100
available_tools:
- get_order
- get_refund
expected:
task_completed: true
required_tools:
- get_order
- get_refund
forbidden_tools:
- update_order
max_tool_calls: 4
must_include:
- 退款状态
risk_tags:
- authorization
- read_only
这是一个可以改造的样例格式,并非对特定平台接口的描述。实际接入时,需要把字段映射到自己的工具协议、权限模型和业务状态。
这里还有一个重要决策:什么算成功?如果验收条件只写“回复中包含退款状态”,Agent 即使查询了别人的订单也可能得分。业务断言必须检查真实环境状态、调用权限和最终回复,而不是只做字符串匹配。
自动指标、规则断言与模型裁判如何分工
Agent 评测很难依赖单一方法完成。更实用的做法是分层判定。
确定性规则适合检查可以精确验证的事实,例如工具名称、参数、数据库状态、调用次数和权限范围。这类规则成本低、结果稳定,应当优先使用。
模型裁判适合判断难以写成规则的质量,例如解释是否清晰、计划是否合理、回复是否真正解决用户问题。不过,模型裁判会受到提示词、模型版本和样例顺序影响,不能直接等同于客观事实。
人工评审适合处理高风险任务、新场景和裁判分歧,也是建立高质量标注集的重要手段。人工评审成本较高,通常不必覆盖每次回归,而应集中在抽样、争议案例和版本发布门禁上。
推荐的判定顺序是:
环境状态与权限断言
-> 工具轨迹规则
-> 最终结果规则
-> 模型裁判评价软质量
-> 分歧样例进入人工复核
对模型裁判本身也要评测。可以准备一批经过人工确认的样例,计算裁判与人工结论的一致率,并固定裁判提示词、模型版本和温度。否则,Agent 没变,评分系统却可能先发生漂移。
可以这样实践:搭建一个最小离线评测器
下面是一个仅依赖 Python 标准库的最小示例。它假设 Agent 运行结果包含最终回复、工具调用轨迹、耗时和 Token 数。将代码保存为 evaluate.py 后,可直接运行 python evaluate.py。
from dataclasses import dataclass
from typing import Any
@dataclass
class EvalCase:
case_id: str
must_include: list[str]
required_tools: list[str]
forbidden_tools: list[str]
max_tool_calls: int
max_latency_ms: int
@dataclass
class AgentResult:
answer: str
tool_calls: list[dict[str, Any]]
latency_ms: int
tokens: int
def evaluate(case: EvalCase, result: AgentResult) -> dict[str, Any]:
called_tools = [call["name"] for call in result.tool_calls]
checks = {
"answer_contains_required_facts": all(
text in result.answer for text in case.must_include
),
"required_tools_called": all(
tool in called_tools for tool in case.required_tools
),
"forbidden_tools_not_called": all(
tool not in called_tools for tool in case.forbidden_tools
),
"tool_call_budget_met": len(called_tools) <= case.max_tool_calls,
"latency_budget_met": result.latency_ms <= case.max_latency_ms,
}
critical = [
"answer_contains_required_facts",
"required_tools_called",
"forbidden_tools_not_called",
]
return {
"case_id": case.case_id,
"passed": all(checks[name] for name in critical),
"checks": checks,
"metrics": {
"tool_calls": len(called_tools),
"latency_ms": result.latency_ms,
"tokens": result.tokens,
},
}
if __name__ == "__main__":
case = EvalCase(
case_id="refund_001",
must_include=["退款状态", "处理中"],
required_tools=["get_order", "get_refund"],
forbidden_tools=["update_order"],
max_tool_calls=4,
max_latency_ms=3000,
)
result = AgentResult(
answer="订单 A100 的退款状态为处理中。",
tool_calls=[
{"name": "get_order", "arguments": {"order_id": "A100"}},
{"name": "get_refund", "arguments": {"order_id": "A100"}},
],
latency_ms=820,
tokens=436,
)
report = evaluate(case, result)
print(report)
这个示例故意保持简单。接入真实系统时,应进一步补充环境状态校验,例如确认查询的订单属于当前用户;对有副作用的工具,应在隔离沙箱中执行,并在每条测试后重置数据。
在持续集成中,可以为关键指标设置发布门禁:
python evaluate.py
# 实际项目中让脚本在关键用例失败或成功率低于阈值时返回非零退出码
不要只比较总分。更有诊断价值的报告应该按业务场景、难度、工具、风险标签和失败阶段切片。例如整体成功率没有变化,但“权限不足”场景从 90% 降到 55%,这已经足以阻止发布。
让离线评测与线上反馈形成闭环
离线评测适合快速回归,却无法完整复现真实用户的表达方式、数据分布和工具异常。线上监控则能发现真实问题,但如果没有可复现样例,很难稳定修复。
一个有效闭环通常包含以下动作:
- 记录经过脱敏的任务轨迹、工具错误、用户中断和人工接管信号。
- 对失败轨迹进行归因,区分意图理解、规划、工具参数、环境异常和结果表达问题。
- 将高价值失败案例转化为离线回归样例。
- 修复后先跑分层评测,再通过灰度发布观察真实指标。
- 定期清理重复、过时或标签错误的评测数据。
线上指标也需要谨慎解释。用户没有追问,不一定代表任务成功;执行时间更短,也可能是 Agent 提前放弃。最好同时观察业务结果、用户行为、系统日志和人工抽检,而不是依赖单一代理指标。
落地时应守住的几条边界
Agent 评测的价值不在于生成一个漂亮总分,而在于让团队知道版本是否可发布、问题出现在哪一层,以及修复是否带来新的代价。
落地时可以检查这些事项:
- 是否为核心业务任务定义了可验证的成功条件。
- 是否同时评估最终结果、执行轨迹、成本、延迟和安全性。
- 是否用确定性规则验证权限、参数和环境状态。
- 是否校准模型裁判,并保留人工复核机制。
- 是否按场景和风险标签分析指标,而不是只看平均分。
- 是否将线上失败案例持续回灌到离线评测集。
- 是否在沙箱中测试写操作,并保证数据可以重置。
评测体系应该随 Agent 一起演进。工具、模型、提示词和业务规则都会变化,评测数据与判定标准也需要版本化。只有把评测变成开发、发布和线上运营的一部分,它才能真正降低 Agent 上线后的不确定性。