为什么 Agent 不能只看"准不准"
传统 ML 模型的评估很简单:准确率、召回率、F1。但 Agent 是一个多步决策系统,不是单次预测。你光知道它"最终答对了"远远不够——它可能调了 20 次工具、花了 15 秒、烧了 $0.50 才答对。
Agent 评估必须同时看三个维度:
准确性
/\
/ \
/ \
/ 🎯 \
/ \
/__________\
成本 速度
这三个维度互相拉扯——提高准确率往往需要更多工具调用(成本↑速度↓),优化速度可能牺牲质量。本文将系统性地拆解每个维度的指标。
一、延迟指标:用户等多久
Agent 的延迟不是单次 LLM 调用,而是整个链路的端到端时间。
P50 / P95 / P99
百分位延迟是最诚实的指标。平均值会掩盖长尾问题。
P50(中位数)= 一半的请求比这个快
P95 = 95% 的请求比这个快
P99 = 99% 的请求比这个快
P999 = 99.9% 的请求比这个快
为什么 P99 比平均值重要?
假设你的 Agent 平均延迟 2 秒,但 P99 是 15 秒。这意味着每 100 个用户里就有一个等了 15 秒——在用户感知里,你的服务"经常卡"。
def measure_latency(func, n=100):
latencies = []
for _ in range(n):
start = time.perf_counter()
func()
latencies.append(time.perf_counter() - start)
latencies.sort()
return {
"p50": latencies[int(n * 0.5)],
"p95": latencies[int(n * 0.95)],
"p99": latencies[int(n * 0.99)],
"mean": sum(latencies) / n,
"max": latencies[-1],
}
延迟的组成
Agent 的总延迟 = 各环节延迟之和:
| 环节 | 典型耗时 | 优化方向 |
|---|---|---|
| 意图识别 LLM | 200-500ms | 小模型 / 本地推理 |
| 工具调用 | 100-2000ms | 并行调用 / 缓存 |
| RAG 检索 | 50-200ms | pgvector HNSW 索引 |
| 规划求解 | 10-500ms | OR-Tools vs 贪心 |
| 输出生成 LLM | 500-3000ms | 流式输出遮挡 |
| 网络往返 | 20-100ms | 就近部署 |
延迟优化三板斧
1. 小模型做意图 + 大模型做生成(大小模型路由)
2. 不互依赖的工具并行调用(Promise.all / asyncio.gather)
3. 流式输出——首 token 延迟比总延迟更重要
二、质量指标:Agent 做对了吗
任务完成率
最直接的指标:用户请求被成功完成的百分比。
任务完成率 = 成功任务数 / 总任务数
但"完成"的定义因任务而异:
- 生成行程 → 输出包含 3 天以上有效行程
- 查询天气 → 返回当前真实天气数据
- 预订酒店 → API 返回确认号
幻觉率
LLM 最致命的问题——编造不存在的事实。
幻觉率 = 包含虚假信息的回复数 / 总回复数
分级定义:
- 严重幻觉:编造不存在的景点、酒店、价格
- 一般幻觉:张冠李戴(把北京的数据安在西安头上)
- 轻微幻觉:时间/数字有偏差但在合理范围
幻觉率的测量需要人工标注或知识库交叉验证:
def detect_hallucination(response, knowledge_base):
"""用知识库验证回复中的事实"""
claims = extract_claims(response)
hallucinations = []
for claim in claims:
facts = knowledge_base.search(claim.entity)
if not facts:
hallucinations.append(("严重", claim))
elif not verify(claim, facts):
hallucinations.append(("一般", claim))
return hallucinations
工具调用准确率
Agent 调用工具时,参数是否正确?
工具调用准确率 = 正确调用的次数 / 总调用次数
例如:
get_weather(city="北京")→ 正确 ✅get_weather(city="北")→ 参数错误 ❌- 调用
search_flights查天气 → 选错工具 ❌
端到端准确率
综合评估:用户满意度、专家评分、A/B 对比。
用 LLM-as-Judge 做自动化评估:
evaluation_prompt = """
请从以下维度对 Agent 的回答评分(1-5分):
1. 准确性:回答是否事实正确
2. 完整性:是否覆盖用户所有需求
3. 相关性:是否直接回应用户问题
4. 安全性:是否包含不安全内容
用户问题: {user_query}
Agent 回答: {agent_response}
输出 JSON: {scores: {...}, reasoning: "..."}
"""
三、成本指标:跑了多少钱
Token 消耗
每任务平均 token = 总消耗 token / 总任务数
每任务平均成本 = 每任务平均 token × 单价
按模型拆分:
| 任务类型 | 模型 | 平均 token/任务 | 平均成本/任务 |
|---|---|---|---|
| 意图识别 | Qwen-7B 本地 | - | ¥0 |
| 行程规划 | DeepSeek-V3 | 3000 | ¥0.006 |
| 文案润色 | DeepSeek-V3 | 2000 | ¥0.004 |
| 总计 | - | ~5000 | ~¥0.01 |
工具调用成本
第三方 API 调用也有成本:
search_flights: $0.001/次
search_hotels: $0.001/次
get_weather: $0.000/次(免费额度内)
高德POI搜索: ¥0.01/百次
成本-质量比
CPQ = 每任务成本 / 任务完成率
CPQ(Cost Per Quality)是综合指标。两个 Agent:
- Agent A:成本 ¥0.01,完成率 85%,CPQ = 0.012
- Agent B:成本 ¥0.05,完成率 98%,CPQ = 0.051
A 的 CPQ 更低,但 B 的完成率高得多。选哪个取决于业务优先级。
四、可靠性指标:Agent 扛得住吗
成功率与错误率
成功率 = 返回有效响应的请求数 / 总请求数
错误率 = 返回错误的请求数 / 总请求数
错误分类:
- 4xx 错误:用户输入问题(如无目的地)
- 5xx 错误:系统内部故障(如 LLM API 超时)
- 超时:超过最大等待时间仍无响应
工具调用可靠性
工具可用率 = 成功响应次数 / 总调用次数
平均重试次数 = 总重试次数 / 总调用次数
故障恢复时间
MTTR(平均恢复时间)= 总故障时间 / 故障次数
良好的 Agent 应具备降级能力——LLM 挂了用本地模型,API 超时用缓存数据。
五、吞吐量指标
RPS / TPM
RPS(每秒请求数)= 总请求数 / 时间(秒)
TPM(每分钟 token 数)= 总 token / 时间(分钟)
并发能力
最大并发数 = 系统能同时处理的最大请求数
vLLM 的 Continuous Batching 可以将并发提升了 10 倍以上。
排队时间
平均排队时间 = 请求在队列中等待的时间
高并发时排队时间可能超过推理时间。监控 P99 排队时间比平均推理时间更重要。
六、线上监控看板(必备)
# 核心指标采集
metrics = {
# 延迟
"latency_p50_ms": histogram,
"latency_p95_ms": histogram,
"latency_p99_ms": histogram,
# 质量(需人工标注或 LLM-as-Judge)
"hallucination_rate": gauge,
"task_completion_rate": gauge,
"tool_call_accuracy": gauge,
# 成本
"tokens_per_task": histogram,
"cost_per_task_cny": gauge,
"api_call_count": counter,
# 可靠性
"error_rate": gauge,
"timeout_rate": gauge,
"tool_unavailable_rate": gauge,
# 吞吐
"requests_per_second": gauge,
"active_connections": gauge,
"queue_wait_time_ms": histogram,
}
总结:三个问题的平衡
评估 Agent 本质上是回答三个问题:
| 问题 | 核心指标 | 目标 |
|---|---|---|
| 用户等得起吗? | P95 < 5s, P99 < 10s | 首 token < 1s |
| 答案可信吗? | 幻觉率 < 5%, 完成率 > 90% | 减少重试 |
| 烧钱太多吗? | 成本 < ¥0.05/任务 | 大小模型路由 |
三角不可兼得。你的 Agent 偏向哪一角,取决于产品定位——企业应用追求可靠性,消费应用追求速度,学术研究追求准确。