写在前面

这是”Agent 系统开发手记”系列的第五篇。第一篇聊了意图识别——把用户想干嘛搞清楚,第二篇聊了规划、纠偏与执行循环——让 Agent 一步步受控地走向目标,第三篇聊了上下文管理——在有限窗口里让模型看到它真正需要的信息,第四篇聊了智能检索与 RAG——怎么从海量知识里找到对的那条。

但做完这些之后,有一个问题始终绕不过去:你怎么知道 Agent 真的变好了?

你把意图识别改成三层机制,怎么证明准确率提高了?给 RAG 加了混合检索、Rerank,怎么知道用户体验更好了?你做了上下文分层管理,用户真的买账吗?

如果回答不了这些问题,你做的所有优化都只是”我觉得变好了”,而不是”我证明变好了”。这篇文章就是把自己在评估与反馈上踩过的坑整理下来——怎么定义好坏、怎么构造测试集、怎么自动评估、怎么线上验证、怎么根据反馈继续迭代


从一个让我头疼的场景说起

我那个技术选型 Agent 跑了一段时间之后,做了一次大优化:把意图识别从单层改成了三层,上下文管理加了分层策略,RAG 也上了混合检索。自测了几条 Case,感觉效果不错,就上线了。

结果上线第一周,用户反馈反而变多了。

我去看了一下日志,发现一个特别诡异的模式:很多用户在第三轮、第四轮开始频繁说”不是这个意思”、”你理解错了”。但我自测的时候,前两轮明明都挺准的。

后来我仔细分析了一批 Bad Case,才发现问题出在多轮对话的意图漂移上。新版本的意图识别确实在单轮上更准了,但它过度依赖当前轮的输入,反而忽略了前几轮的上下文。用户在第一轮说”预算 5000 以内”,第二轮补充”要能跑 Docker”,到第三轮问”还有没有别的选择”时,新版本把”别的选择”理解成了”不限预算的选择”,直接推荐了一个 8000 的方案。

这就是 Agent 评估的第一个坑:你觉得自己优化了,但可能只是优化了你测试的那个场景,而在其他场景上反而退化了。

更坑的是,这种退化在传统的单元测试里根本发现不了——因为每个单独的模块测试都是通过的,只有在端到端的多轮对话里才会暴露。


先搞清楚一件事:评估不是点踩

刚开始做评估的时候,我的想法很简单:加个点赞点踩按钮,用户点踩了就去看日志。结果发现这个思路跟”出了 Bug 再去查日志”一样被动。

用户显式反馈(点赞点踩)有一个严重问题:反馈率极低。很多用户不满意的时候不会点踩,而是直接关闭页面,然后再也不用你的 Agent。你看到的点赞率 90%,可能只是因为不满意的人早就走了,留下的都是觉得还行的。

所以评估体系不能只靠用户主动告诉你,还得有主动发现问题的机制。我后来把评估分成了四个层次:

层次 方法 解决什么问题
离线评估 测试集 + LLM as Judge 版本发布前的回归验证
线上监控 指标 + Trace 发现线上异常
用户反馈 显式 + 隐式反馈 了解真实用户体验
反馈回流 Bad Case 沉淀 + 自动归因 持续迭代优化

这四层不是互相替代的关系,而是互相补充的。后面逐一展开。


测试集:最朴素也最稳定的方法

最基础的评估方式就是准备一批测试用例,每次修改 Prompt、模型、RAG 或者 Agent 流程之后重新运行,观察指标是否变化。

测试用例从哪来

来源 特点 适用阶段
手写 效率低,但精确覆盖关键场景 早期验证
AI 生成 参考已有用例批量生成,加人工监督 规模扩展
线上回流 自动回流 + 手工回流,最有实战价值 持续迭代

我一开始全是手写,写了大概 50 条覆盖各种场景:标准表达、口语化表达、多轮对话、边界情况。后来发现手写效率太低,就让 AI 参考已有的测试用例生成了一批,再加上人工审核。最有价值的是线上案例回流——把线上发现的 Bad Case 自动或手动整理到测试集里,确保同一个坑只踩一次。

测试集的局限

测试集最大的问题是:它是你自己准备的,很难完全模拟真实用户千奇百怪的输入。

我遇到过一个案例:测试集里所有的”不要苹果”都是用标准中文表达的,但线上用户会说”除了 iPhone 啥都行”、”苹果的不要”、”不要那个水果牌的”。这些表达在测试集里根本没覆盖到,导致测试集上的拒识准确率是 95%,但线上实际只有 80%。

所以测试集要和线上反馈结合起来用,不能只看测试集指标。


LLM as Judge:语义化评估的利器

很多 Agent 输出没有标准答案。比如用户问”帮我分析一下 Redis 和 Memcached 的优劣”,你很难通过字符串比较来判断回答好不好。

这时候就可以调用一个大模型充当 Judge,根据正确性、完整性、约束满足程度等标准对结果进行评价。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
"judge_prompt": "请评估以下 Agent 回答的质量",
"criteria": {
"correctness": "技术事实是否正确",
"completeness": "是否覆盖了用户关心的维度",
"constraint_satisfaction": "是否满足用户的硬约束",
"actionability": "建议是否可执行"
},
"user_query": "预算 5000 以内,要能跑 Docker,推荐什么数据库?",
"agent_response": "推荐 PostgreSQL,容器化部署成熟...",
"score": {
"correctness": 9,
"completeness": 7,
"constraint_satisfaction": 8,
"actionability": 9
}
}

成本优化

LLM as Judge 不是免费的,但可以通过以下方式控制成本:

  • 使用批量接口(batch API)
  • 业务低峰调用
  • 使用 mini/flash 等轻量模型
  • 只对抽样数据做 Judge,而不是全量

相比请专家评审,这个成本已经很低了。现在很多 Agent 的离线评估都会大量使用 LLM as Judge。

还有几种评估方法值得了解

专家评审:找真正懂业务的人来看。法律 Agent 找律师,金融 Agent 找金融从业者。评价质量最高,但贵、慢。我的做法是让专家负责撰写和评审业务规则、抽样审核 Bad Case,以及用专家结果来校准 LLM as Judge——相当于给 LLM Judge 一个”标准答案”。

A/B Test:线上同时运行两个版本,让真实用户替你判断哪个版本更好。比较任务完成率、用户纠正率、转化率、留存率等。扩展形式是多臂老虎机——同时测试多个版本,动态分配流量给表现好的版本。A/B Test 的核心价值是用真实数据说话,比任何离线评估都可信。

Pairwise 对比:同时给出 A、B 两个结果,让评审者直接回答”哪个更好”。比让评审者分别打 83 分和 87 分更容易判断——人很难区分 83 和 87 的差距,但一眼就能看出哪个更好。可以是真人选,也可以是 LLM Judge 选。


业务指标:从用户目标反推

通用的点赞点踩、任务完成率之类的指标,落地到具体业务时远远不够。因为不同业务里,用户所谓的”好”完全不是一回事

三个关键问题

设计业务指标时,我一般先回答三个问题:

  1. 用户为什么来使用你的 Agent? 比如技术选型 Agent,用户核心目标不是”和 Agent 聊天”,而是找到适合自己场景的技术方案。
  2. 如果用户觉得 Agent 好用,接下来会做什么? 比如采纳推荐的方案、在项目中实际使用。
  3. 如果用户觉得 Agent 很蠢,可能会做什么? 比如重新输入同样的问题、修改表达方式、去搜索引擎自己查。

三组指标要同时看

任何一个指标单独拿出来都可能骗人。比如”对话轮数增加”——可能是用户觉得 Agent 好聊所以继续聊,也可能是以前一轮能解决的问题现在五轮都没解决。

所以我一般建议至少同时看三组指标:

指标类型 含义 技术选型 Agent 示例
目标指标 反映用户最终目标 方案采纳率、项目落地率
过程指标 用户正在朝目标前进 推荐点击率、文档阅读时长
护栏指标 防止优化把系统带偏 用户纠正率、重新生成率

一个好的优化应该是:核心目标指标提升,同时护栏指标没有明显恶化。 比如新版 Agent 方案采纳率提升 12%,同时用户纠正率下降 8%——这种数据比”用户满意度提高了 10%”可信得多。

不同业务,指标可能完全反过来

业务类型 正向指标 同一指标的反向解读
电商 Agent 下单转化率、加购率 退货率是护栏指标
客服 Agent 任务解决率 对话轮数越少越好
社交 Agent 对话轮数、次日留存 对话轮数越多越好
教育 Agent 独立完成率、知识点掌握率 用户当下觉得麻烦反而可能说明在真正思考

核心思路:先确定用户真正想达到什么目标,再寻找用户达成目标时会表现出来的行为,同时设计负向和护栏指标防止指标被刷歪。

一个指标链的示例

以电商 Agent 为例,指标不是孤立的,而是一条链:

1
推荐商品点击率 → 详情页停留时间 → 收藏率 → 加购率 → 下单转化率

每一步都可以计算转化率。但要注意:Agent 可能通过推荐低价爆款来提高转化率,所以需要护栏指标(退货率、退款率)来防止”为了转化率牺牲用户体验”。


可观测性:系统没报错,不代表 Agent 没犯错

传统后端开发对可观测性不陌生:Metrics、Trace、Log。但 Agent 引入了一类传统系统里没有那么突出的问题:系统本身没有出错,但”决策”错了。

HTTP 可以是 200,工具调用可以成功,大模型也可以正常返回,甚至整条 Trace 都没有任何异常,但 Agent 最后就是给了用户一个错误答案。

可观测性:系统没报错,不代表 Agent 没犯错

传统后端开发对可观测性不陌生:Metrics、Trace、Log。但 Agent 引入了一类传统系统里没有那么突出的问题:系统本身没有出错,但”决策”错了。

HTTP 可以是 200,工具调用可以成功,大模型也可以正常返回,甚至整条 Trace 都没有任何异常,但 Agent 最后就是给了用户一个错误答案。

Agent Trace 需要记录什么

除了传统的调用链路,Agent Trace 还要关注 Agent 经历了哪些决策节点:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
{
"trace_id": "task_abc123",
"user_input": "推荐一个能跑 Docker 的数据库,预算 5000 以内",
"intent": {
"type": "tech_recommendation",
"slots": {
"use_case": "Docker 容器化",
"budget_max": 5000
}
},
"context_injected": ["用户画像: 偏好开源", "硬约束: budget_max=5000"],
"plan": ["检索候选方案", "评估适用性", "生成推荐"],
"tool_calls": [
{
"tool": "knowledge_search",
"params": {"query": "Docker 数据库推荐", "filters": {"price_max": 5000}},
"result_count": 3
}
],
"final_output": "推荐 PostgreSQL...",
"checkpoint_results": [
{"step": "检索", "status": "pass", "evidence": "找到 3 个候选"},
{"step": "评估", "status": "pass", "evidence": "PostgreSQL 满足所有约束"}
]
}

尤其要注意 Context——大模型做出的决策高度依赖于它当时窗口里面有什么。用户明明说了”预算不能超过 5000”,最终 Agent 却推荐了 8000 的方案。排查的时候至少需要知道:

  • 用户输入中有没有 5000?
  • Slot Filling 有没有提取 budget_max=5000?
  • Context 中有没有保留 budget_max=5000?
  • 推荐 Action 参数有没有 price_max=5000?

只要其中某一环出了问题,最终结果就可能出错。

Agent 特有指标

除了传统的延迟、吞吐量、成功率,Agent 还需要关注一批特有的指标:

指标 含义 为什么重要
任务成功率 最终成功完成用户任务的比例 最核心的指标
用户纠正率 用户出现纠正行为的比例 直接反映 Agent 理解能力
约束违反率 违反用户硬约束的比例 硬约束违反 = 用户爆炸
意图识别准确率 意图识别正确的比例 第一篇的核心指标
工具选择准确率 选择的工具是否符合当前目标 反映 Agent 决策能力
检索空结果率 检索没有召回有效结果的比例 反映 RAG 质量
证据覆盖率 关键结论有 Evidence 支撑的比例 反映推理可靠性
ReAct 平均循环次数 一次任务经历多少轮 Think/Action/Observation 过多说明在兜圈子
Replan 触发率 触发 Replan 的任务比例 过高说明 Plan 质量差
端到端耗时 从输入到返回结果的整体耗时 用户体验核心指标
单任务成本 完成一次任务的平均成本 成本控制核心指标

这些指标不是一次全上,而是根据当前阶段重点关注的环节逐步加。早期先看任务成功率和用户纠正率,后面再加意图识别准确率、工具选择准确率等细分指标。

根因定位:Checkpoint + 二分法

当 Agent 输出了错误结果,排查思路是:

第一步:用 Checkpoint 缩小范围。 先找最后一个可信的 Checkpoint 和第一个不可信的 Checkpoint,错误就在两者之间。

第二步:用二分法进一步缩小。 不是严格二等分,而是优先检查:

  • 最容易出错的”前科”节点
  • 关键节点(Context 变化、中间结果、执行路径切换、工具调用、Replan)
  • 直觉告诉你可能出问题的节点

等范围缩小到三五个步骤之后,再自后向前检查上下文,找到真正的第一个错误节点。


反馈回流:让 Agent 持续演进

评估不能止步于报表。真正成熟的做法应该让线上反馈重新回流到测试集和优化流程中,形成闭环。

什么数据值得回流

优先关注强负反馈或异常样本:

信号类型 具体表现
用户主动反馈 点踩、要求重新生成、说”你理解错了”
行为异常 同一问题反复修改追问、多次 Replan
系统异常 工具调用连续失败、最终任务失败或中断
指标异常 LLM Judge 给出明显低分、核心业务指标出现异常

还可以主动根据指标寻找异常。比如正常的技术选型对话平均三四轮就能结束,但某一批用户平均聊了十五轮,这一批会话就值得单独抽出来分析。

一个完整的反馈闭环

1
线上对话 → 异常检测 → Bad Case 沉淀 → 问题归因 → 定向优化 → 灰度验证 → 再评估

举个例子:用户明确要求”不要推荐 Redis Cluster”,结果 Agent 还是推荐了。系统将这一轮完整信息保存下来(用户输入、Context、工具调用、最终输出、用户反馈),排查后发现真正的问题不是推荐算法,而是”不要 Redis Cluster”这个硬约束在上下文压缩过程中丢失了。

修复上下文管理之后,把这个 Case 加入测试集。以后每次修改 Prompt、Context 或模型,都重新跑一次。同一个坑尽量只踩一次。

Evaluation Agent:更高级的做法

如果想进一步提高自动化程度,可以专门启动一个 Evaluation Agent,负责观察主 Agent 干得怎么样:

  1. 周期性读取各项指标(用户纠正率、点赞点踩、任务成功率、Replan 次数等)
  2. 自动分析异常(发现”技术选型”场景的用户纠正率从 5% 涨到 10%)
  3. 抽取相关会话,寻找共同特点
  4. 自动初步归因(大量错误来自硬约束被忽略)
  5. 生成新的 Prompt 规则

但生成新 Prompt 之后,绝对不能直接替换线上版本,而应该继续进入评估流程:测试集验证 → LLM as Judge 评估 → 灰度发布 → A/B Test → 全量。

自动演进要谨慎

这套机制很适合在面试里作为高级方案讨论,但实践中一定要谨慎。原因很简单:连”怎么评价一个 Agent 好不好”这件事本身,我们都还没有完全解决。 如果评价指标本身就是错的,那么越自动化,Agent 可能越容易朝着错误方向狂奔。

比如你要求最大化对话轮数,Agent 最简单的做法可能不是变得更好聊,而是故意一次不把问题解决完。

所以自动演进系统至少应该保留两道保险:

  1. Guardrail Metrics:核心指标提升的同时,其它关键指标不能明显恶化
  2. 人工审批:高风险变更(System Prompt、工具权限、安全策略、资金操作)不允许 Agent 完全自主修改

评估方案设计:一个完整示例

以技术选型 Agent 为例,展示一个完整的评估方案设计:

离线评估

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{
"test_set": {
"size": 200,
"categories": {
"standard": "标准表达,如'推荐一个数据库'",
"colloquial": "口语化表达,如'有没有好用的 DB 推荐'",
"multi_intent": "多意图,如'推荐数据库,要支持 Docker,预算 5000'",
"constraint_hard": "硬约束,如'不要 Redis Cluster'",
"constraint_soft": "软偏好,如'最好开源'",
"multi_turn": "多轮对话,5轮以上的复杂选型",
"edge_case": "边界情况,如'推荐一个不存在的场景的技术'"
}
},
"metrics": {
"intent_accuracy": "Top-1 准确率",
"slot_extraction": "槽位提取准确率",
"constraint_satisfaction": "约束满足率",
"recommendation_relevance": "推荐相关性(LLM Judge)"
}
}

线上监控

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
"realtime_metrics": {
"task_success_rate": "任务成功率",
"user_correction_rate": "用户纠正率",
"tool_success_rate": "工具调用成功率",
"replan_rate": "Replan 触发率",
"avg_turns": "平均对话轮数",
"e2e_latency": "端到端耗时",
"cost_per_task": "单任务成本"
},
"alert_rules": {
"user_correction_rate_spike": "用户纠正率 > 10% 持续 1 小时",
"tool_failure_spike": "工具失败率 > 5% 持续 30 分钟",
"replan_rate_spike": "Replan 触发率 > 20% 持续 1 小时"
}
}

反馈回流

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{
"auto_collect": {
"triggers": [
"user_clicks_dislike",
"user_says_wrong",
"user_regenerates",
"task_failed",
"llm_judge_score < 5"
],
"data_captured": [
"user_input",
"context_snapshot",
"tool_calls",
"final_output",
"user_feedback"
]
},
"review_cycle": {
"daily": "自动分析新增 Bad Case",
"weekly": "人工审核 Top 10 异常 Case",
"monthly": "更新测试集、优化 Prompt"
}
}

写在最后

做 Agent 评估这件事,我最大的体会是:评估不是事后补的,而是从一开始就要设计进去的。

很多人(包括早期的我)都是先把 Agent 做出来,跑通了主流程,然后才想起来”哦,我得加个评估”。结果发现,Agent 的执行过程根本没有记录,想评估都不知道评什么。

所以正确的顺序应该是:

  1. 先定义清楚”好”是什么(业务指标)
  2. 设计评估方案(测试集 + LLM Judge + 线上监控)
  3. 在 Agent 执行过程中埋点(Trace + 指标采集)
  4. 上线后持续收集反馈(显式 + 隐式)
  5. 反馈回流到测试集和优化流程

这五步形成了一个完整的闭环:评估 → 发现问题 → 优化 → 验证 → 灰度 → 再评估

在这个系列的前四篇里,我聊了意图识别、规划与执行、上下文管理、智能检索。这四件事做好了,Agent 能跑起来。但只有加上评估与反馈,Agent 才能持续变好。评估是整个 Agent 系统的闭环——没有它,你做的所有优化都是盲目的。

最后说一句:在面试中,如果你能讲清楚怎么评估 Agent、怎么设计业务指标、怎么建立反馈闭环,你的项目听起来就不再像 Demo,而更像一个真正长期运行的生产系统。这个差别,往往就是通过和不通过的分界线。

站内搜索

没有找到内容!