news 2026/9/20 19:35:52

AI Agent评估数据集:构建高质量回归测试体系的关键实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
AI Agent评估数据集:构建高质量回归测试体系的关键实践

1. 为什么评估数据集应该排在 agent 功能开发的前面

我在好几个 agent 项目里吃过没有评估数据集的亏。上线前手动把核心用例点了一遍,觉得一切正常,结果灰度到一半,某个关键场景被改坏了,要等用户在工单系统里连续投诉之后才被察觉。那次事故之后我就明白了一件事:agent 这类多步骤、带随机性的系统,光靠发版前的人工验证根本兜不住,必须把 evaluation dataset 当成和业务代码同等级的基础设施来建设。

这篇文章把这个建设流程完整串一遍——如何定标准、如何从真实日志里挖样本、如何构造边缘 case、如何组织判断器、以及跑评估时那些反直觉的细节。适合负责 agent 落地、正在被手工测试折腾得没脾气的工程团队,也适合刚接手 agent 项目、想知道下一步该怎么走的技术负责人。

1.1 为什么每天手点浏览器,代替不了评估数据集

很多团队,包括早年的我们,都试图用“每天手动点一遍”来替代评估集。每天让产品和研发花二十分钟,把主要功能走一遍,觉得效果差不多就能发。表面上看没什么问题,但手动测试有几个无法回避的短板。

第一是覆盖范围非常有限。人是有习惯的,测来测去总是那么几条熟悉的路径,那些低频但高风险的分支,比如外部 API 超时、工具返回字段缺失、用户一句话里包含多个互相冲突的意图,基本不会被日常手点覆盖到。第二是复现能力弱。这周测通过,下周想再复现同样的环境条件,光是恢复上下文就要花掉不少时间;如果中间还改过 Prompt,好坏结论根本没法归因。第三是判断标准一直在漂移。同一个结果,这周看觉得是好的,下周看到更好的版本,就反过来觉得之前的不合格,但这种标准变化沉淀不下来,人走了标准也跟着走了。

评估数据集恰恰相反。它把“好的标准”硬化成一批可以随时回放、反复比较的样板。改任何一版 Prompt 或换一个模型之后,拿同一条数据跑一遍,和以往的结论对比,就能严谨地判断这次改动是变好了还是变坏了。在 agent 高频迭代的场景下,这种 A/B 可对比性就是最核心的价值。

1.2 评估数据集在整个 agent 迭代循环里的位置

如果给 agent 项目画一个最简迭代循环,大概是这么走的:先设计或调整 agent 的流程和 Prompt,然后在典型输入上跑一批结果,检查结果是否符合预期,再根据差异调整 Prompt 和流程,同时把没跑好的输入补充进样本库,然后重新开始下一轮。

评估数据集的作用是“检查结果”和“补充样本”这两个环节之间的连接器。没有它,“检查结果”只能靠肉眼抽样,“补充样本”也变成凭感觉,整个循环就是随意且不可追溯的。有了它之后,每一次循环都能清晰地回答三个问题:上一轮有没有变好?变好体现在哪些样本上?变坏又是哪一批样本引入的?

所以不要把评估数据集想象成做完一次就放在角落里落灰的清单,它其实是跟着迭代周期持续增长、持续修正的资料库。可以说,agent 项目的天花板,一半取决于模型和框架的天花板,另一半取决于你有没有一套能稳定衡量“好和坏”的数据基础设施。

2. 定义“好”的标准——任务成功率、路径质量、安全边界三层拆解

“给 agent 建立评估数据集”这句话很容易让人误解成“找一堆用户问题,再标注一下答案对不对”。但工程实践跑过几轮之后会发现,问题没这么简单。agent 的输入是一个用户诉求,输出却是一长串动作和最终回应。最终回应看起来没问题,过程可能走了大量弯路、浪费了大量 token,甚至踩了安全边界。所以建数据集的第一步,不是找数据,而是先把“好”拆成可以观测、可以判定的维度。

2.1 三个核心层:任务层、过程层、安全层

我习惯把 agent 评估拆成三层。

第一层是任务成功率。用户的目标最终有没有达成。比如一个让 agent 查库存、下采购订单的任务,“成功”意味着订单真的创建成功,从 API 返回的 order_id 能对得上,而不是 agent 嘴上说“已下单”但实际没有调用下单接口。这个维度是大家最容易理解的“标准答案”层面,但注意:任务成功率不要求过程完美,只要结果达成就算成功,过程低效也算成功。

第二层是路径质量。衡量的是达成结果的过程中,动作是否合理、高效、符合预期。同样完成一个资料汇总任务,一个 agent 在无关页面来回跳转、反复调用同一个查询工具,另一个 agent 用知识库检索直接命中并做了摘要,两者在任务成功率上可能都是“已完成”,但第二个显然更符合我们对一个好 agent 的预期。路径质量通常看这么几个点:工具调用参数是否正确、是否有重复调用或无效调用、查询意图是否清晰、上下文利用是否合理、最终回复是否与中间过程一致。

第三层是安全边界。这是 agent 特有的高风险点。很多 agent 被授予了内部系统的操作权限,评估时必须覆盖“在什么情况下 agent 不该继续操作”“出现越权或高成本动作之前有没有主动确认”“外部输入注入的指令有没有被识别并拒绝”等行为。安全边界这一层的样本量不要求很大,但重要性极高。

评估维度关注的问题判定方式
任务成功率用户目标最终是否达成检查最终状态、API 返回值、结果结构
路径质量工具调用、上下文利用是否合理高效检查 action 序列、调用参数、token 消耗
安全边界是否拒绝非法操作、是否防止注入、是否主动确认检查行为是否越权、输出是否合规

这张表不是让你把三个维度做成三个独立的数据集,而是说每一条评估样本都应该带着这几个视角的标注。成熟的评估集里,一条样本上同时出现“任务成功=False、路径质量=低、安全边界=通过”这种多标签,是很常见的。

2.2 标注尺度上的一点建议:两级比三级更靠谱

很多团队刚开始喜欢用优秀、良好、及格、不及格这种四级制,也有用 1 到 5 分的李克特量表。我在实际标注里发现,agent 评估用二级制(通过/不通过)会稳定得多,并且强制要求写一句判定理由更好。原因是三四级尺度会产生大量边界争议,良好和及格怎么切分?3 分和 4 分的差别到底是什么?每个标注者心里的尺子都不一样,这种不确定性会被直接带进最终指标里。

那路径质量这类中间态信息怎么办?我的办法是把它拆成若干二级判断题:是否存在重复工具调用?是否使用了不必要的工具?最终回复是否与中间过程一致?是否存在未经请求的高成本操作?每一个判断都只需回答是或否,彼此之间不重叠。汇总时才把问题数量映射成一个路径质量分。这样既保留了中间信息,又避免了模糊尺度带来的标注噪音。

2.3 和团队对齐标准比写文档更重要

还有一个细节很容易忽略——评估标准的对齐。数据集建出来之后,如果产品、算法、标注员对“成功”的定义不一致,指标就没有公信力,后面也很难推动大家真的用起来。我见过太多团队,评估文档写得漂漂亮亮,但真正标注起来各做各的。

建议在建集初期就做一次小范围标注对齐:随便拉 20 条样本,每个人独立打分,再一条条对分差。这个过程通常能暴露很多基线理解上的差异,比如“用户让 agent 汇总报表,agent 只给了汇总结果但没有附带可追溯的数据来源链接,这算成功还是失败”这种典型问题。等大家的口径收敛了再大规模标注,效率会高很多。

3. 从真实日志、构造样本到样本仓库——建立评估数据集的具体流程

定好维度之后,真正耗精力的就是采集和生成样本了。下面这套流程是我在多个项目里沉淀下来的,基本步骤是:先从真实日志挖一批基线样本,再针对薄弱环节做构造补充,然后划分开发集/测试集,最后建立带版本管理的样本仓库。

3.1 第一步:从真实日志中挖出初始样本

最能代表业务真实分布的东西永远是生产日志。启动评估集建设时,我会拉最近一到两周的 agent 运行日志,筛选出有代表性的会话作为初始样本。筛选条件一般包括:覆盖不同的任务类型、覆盖不同难度的用户请求、以及至少 20% 到 30% 的失败案例。

这里有一个特别容易踩的坑:很多团队只想挑成功日志,因为成功日志看起来“干净”,方便标注期望结果。但失败案例才是评估集最有价值的部分。失败日志会告诉你 agent 在哪个环节容易翻车,后续每次回归测试时,最先挂掉的往往就是这些样本。我甚至会把生产里每次明显让用户不满意的会话单独打上标签,定期拉入评估集,充当“踩坑回忆录”。

初始样本数量不需要巨大。对于大多数单域 agent,80 到 150 条就够了。数量太多会让标注成本失控,也让团队不敢改评估集;关键是覆盖全面,而不是数量够多。

每条样本记录的基础字段,我至少保存这些:

  • 会话 ID 和来源时间范围,便于追溯
  • 原始的用户请求(必要时要先脱敏)
  • 期望结果或任务完成条件(人工标注)
  • 该样本所属的任务类型标签
  • 该样本曾被观测到的失败模式(如果历史日志里有失败记录)

3.2 第二步:构造样本,把薄弱地带补齐

真实日志很难覆盖干净那些低频但关键的边缘情况。比如用户一次请求里包含多个任务且互相有依赖,外部 API 返回状态码 500 导致工具中途挂掉,上下文里出现“请忽略之前的指令”这种提示注入尝试。这些场景可能隔几周才出现一次,但绝不能等它出现了才补样本,漏过去就直接影响用户。

构造样本有三种方式,我经常混合用。

第一种是人工编写。人肉写一批典型的困难任务,比如数据查询任务里用户给的字段名故意不标准,需要 agent 先做推理再决定用哪个工具。这种方式产出的样本质量最高,但效率低,适合核心样本和小批量打样。

第二种是 LLM 改写。让一个强模型在真实请求的基础上做改写、扩展、难化处理。把单任务改成多任务,把时间条件从“上月”改成“去年春节前后”,把查询对象从明确字段名改成模糊描述,这样一批一批地生成。使用时要留意模式雷同的问题,纯 LLM 生成容易得到一批结构相似、套路相近的样本,覆盖度反而会下降。

第三种是对抗样本,单独用一个分区存放。这里的样本往往不是用户正常自然的问法,而是刻意设计的越权指令、攻击性输入、模糊引用。目的是守住安全边界,而不是模拟真实分布。一个没有对抗分区的评估集,在安全上基本是裸奔的。

3.3 第三步:划分开发集和测试集

样本收集完之后,处理方法跟传统机器学习类似,但角色分配有差别。开发集主要用来在日常迭代时判断和调整,测试集作为发版验收的最终标准。调 Prompt 时我们一直对着开发集跑,指标变好就继续,指标变差就回滚;发版评审时,最终结论以测试集为准。

划分比例常见的是 80/20 到 70/30。我习惯开发集 70%、测试集 30%。这里有一条红线:测试集一旦划分出去,应该处于半冻结状态,只能补充新场景,不能频繁修改已有样本的期望结果。如果今天觉得指标不好就顺手把某个样本的期望值放宽,明天再放一条,测试集就会慢慢变成一套已经见过答案的题,再跑出来的分数就失去意义了。

除了比例,还要避免按时间简单切分带来的泄漏。如果开发集和测试集的样本取自同一批日志,且样本之间存在很强的相似性,比如同一个用户短时间内发的两条请求,就很容易出现“开发集看多了、测试集也跟着受益”的假象。处理方式很简单,切分前做去重和相似度筛查,保证同一个用户、同主题的交互只进同一个分区。

3.4 第四步:建立可追溯的样本仓库

不要把所有样本塞进一个 JSON 文件就交差,版本管理一定要跟上。我们的做法是把评估样本放在独立的 Git 仓库里,每条样本一个 JSONL 行,包含稳定 ID、任务描述、期望结果、标签、标注时间、标注人字段。每一轮迭代后对样本仓库打 tag,改崩了随时能回滚到上一个版本的样本基线。

样本仓库同时要方便审计。标注人是谁、什么时候改过、为什么改,都要留痕。这不一定需要上复杂工具,Git 本身就够,关键是养成提交时写清楚变更理由的习惯。我们内部甚至列了一条规矩:不写变更原因的样本修改不允许合入主分支。

4. 把评估跑起来:代码、执行节奏以及判断器设计的坑

有了数据集,下一步是解决怎么把评估效率和稳定性提上来。我会讲一些具体执行细节,包括最简可用的 Runner 框架、三种判断方式、以及 LLM-as-a-judge 使用时的几个注意点。

4.1 最简可用的评估 Runner 长什么样

不用一上来就上厚重框架,最轻量的评估系统只需要四个部分:加载器(读取 JSONL 数据集)、执行器(把样本提交给被测 agent 运行)、判断器(比对结果)、聚合器(把多轮结果汇总成指标)。

我常用 Python 写一个极简 Runner。数据集的每行长这样:

{ "id": "eval-0001", "task": "查询上月华东区销售额,并与前月对比,给出变化率", "expected": { "task_success": true, "key_metrics": ["revenue"], "constraints": ["不得调用日报工具"], "judge_type": "llm" }, "tags": ["data_query", "multistep"] }

Runner 的执行循环大致是:

import json def load_dataset(path): with open(path, encoding="utf-8") as f: return [json.loads(line) for line in f if line.strip()] def run_eval(dataset, agent_runner, judge_func): results = [] for sample in dataset: trace = agent_runner(sample["task"]) verdict = judge_func(sample, trace) results.append({ "id": sample["id"], "task": sample["task"], "trace": trace, "verdict": verdict }) return results def aggregate(results): total = len(results) ok = sum(1 for r in results if r["verdict"]["task_success"]) return { "task_success_rate": round(ok / total, 4), "total": total, "detail": results }

这段代码不是生产级方案,但足够传达本质:评估就是把数据集、执行器、判断器三者串起来。生产级方案会在外面加并发、缓存、超时控制、trace 落库,但骨架就是这么简单。

为什么要坚持先写最简 Runner,而不是直接上那些成熟的评测框架?因为 agent 项目的评估需求变化太快,你的任务类型、工具列表、判断口径每周都可能调整,太重的框架反而会把精力消耗在与业务无关的抽象层上。轻量结构可以随时改、随时拆,等到确实需要并发、调度、报告展示时再逐步加能力。从项目经验看,这种方式在快速迭代期效率最高。

跑的方式也要讲究。每条样本只跑一次的结果,只能当作非正式参考;agent 输出有随机性,同样的输入跑 3 到 5 次得到的整体趋势才稳定。我用 3 次居多,取多数结果或平均值,成本可控且能明显压住抖动。

4.2 三种判断器:规则、人工、LLM 裁判

判断器是把 agent 的产物和期望结果作对比的地方。业内常用三种。

第一种是纯规则判断。适用于有明确结构的任务,比如订单接口返回了 200 且包含 order_id,或者输出文本里包含指定字段。规则判断最稳定、开销最低,但它只能覆盖能形式化刻画的点,很多语义层面的问题判断不了。

第二种是人工评审。适合样本量小、质量要求高的关键用例。人工评审要注意标注一致性,两个人独立评,再统一核分。人工评审不参与每一次回归,只有在发版前或指标异常需要重新确认时才用。

第三种是 LLM-as-a-judge。这是目前最主流的扩充方式,用一个足够强的模型读任务描述、agent 的执行轨迹和最终输出,输出一个结构性判定。它的语义理解能力强,能处理“最终回复是否与中间过程一致”“是否按要求避免了某个工具”这类抽象判定。

这三种不是互斥的。工程实践里最常见的做法是:能规则判的先规则判,规则判不了的再进 LLM 裁判,关键样本最后人工抽检。这样在效率、成本、稳定性上都能兼顾。

4.3 LLM 裁判的几个坑:顺序敏感、标准漂移和幻觉放行

LLM 裁判好用,但有三个明显的坑。

第一个是顺序敏感。同样的两条候选结果,先看好的再看坏的,跟先看坏的再看好的,打分结论可能不同。降敏感的方法比较直接:把样本的期望标准写详细一些,让它独立判断,而不是和参考结果放在一起比;必须两两比较时,至少交换顺序跑两次,取一致的结论。

第二个是标准漂移。裁判模型本身迭代版本,或者 judge prompt 里措辞稍微变一点,整体分数就会左右漂。解决方法是把每个版本使用的 judge prompt 和模型版本记录在评估报告里,尽量固定 judge 版本。如果确实要升级,一次只换一个变量,同时跑新旧两套,确认差异来源。

第三个是幻觉式放行。强模型在判断复杂轨迹时,偶尔会“脑补”一个不存在的成功,尤其是面对特别长的工具调用历史时。有效手段是强制要求“先给出证据链,再给出判定”,让它把判断依据逐条列出来之后再下结论。对关键样本,我还会要求裁判先把每一步 action 的关键字段做摘要再判断,这样做之后幻觉率明显下降。

4.4 把评估接进发布门禁

评估集和 Runner 建好之后,还要把它接进发布流程,否则还是会靠自觉跑。我有一个很实用的建议:把开发集跑测挂在每次提 PR 的时候,测试集跑测挂在发版评审之前。也就是说,开发者改完代码,先自己跑一遍开发集,指标明显下滑就回滚或继续调;等所有改动合入后,发布评审前再跑一遍测试集,作为最终把关。

这里要特别注意开发集和测试集的使用频率不一样。开发集可以每天跑几十次,因为它就是拿来被“钻空子”的;但测试集不能频繁跑,跑得越频繁,它就越像另一份开发集,会失去验收的意义。很多团队跑着跑着就把测试集也当成调参工具,等发现数据泄漏的时候,整个发布门禁已经形同虚设了。

5. 踩坑实录:数据泄漏、标注噪音、评估集版本斗争

前面讲的都是正确做法,但这几个问题我是真真切切踩过坑之后才长记性的,单独拎出来讲,主要为了让后来的人少走点弯路。

5.1 开发集和测试集的隐性重叠

我经历过一次评估集跑得很顺利、发布指标一直很高、但一上生产效果明显缩水的诡异情况。排查之后发现问题出在初始日志采集阶段:切分开发集和测试集时只按时间盲切,结果同一个用户连续几天的操作,有的进了开发集、有的进了测试集。由于会话主题高度相似,agent 在开发集上的调整行为让测试集被动“白捡”了一部分迁移效果,测试分数虚高。

解决办法前面提过:切分前按用户 ID、会话 ID、请求特征做聚类去重,保证同一个用户的同主题请求只进同一个分区。这是一个非常普遍但特别隐蔽的坑,会让整套指标失去公信力。

还有一个相关的泄漏问题是 Prompt 泄漏。如果评估集的样本内容、期望结果、判断标准混进了 agent 的 system prompt 上下文,那它就不是在评估系统的能力,而是在考系统对既有数据的记忆。规避方式简单直接:评估环境里,向被测 agent 提供的只有用户请求本身,标签、期望、判断标准一律放在外部读取,不许出现在 agent 可读的上下文中。

5.2 标注不一致会摧毁整个指标体系

有次我们请两个人对 60 条“路径质量”样本做独立标注,结果一致率只有 55%,比随机好一点点。问题出在路径质量定义不清晰:一个标注员把“用了额外工具但结果很好”判定为优秀,另一个则认为“任何额外工具都算冗余”。标准分叉不解决,所有基于路径质量的统计都是白算。

后来我们内部把标注指南写得很细,每条判断都是一道明确的二选一或三选一题目,并给每个选项配了最小示例。每次更换标注人员,先用 15 条校准样本对齐,校准完成后才让正式动工。数据合入前做一轮抽检,抽检不一致超过 10% 就整体回炉。这套机制之后,标注一致率基本稳定在 90% 上下。

5.3 评估集也会过时,不要把它当成存档文件

agent 产品迭代很快,业务流程、权限模型、工具数量都会变。半年前正确的期望,半年后可能已经跟不上业务规则了。我们有一个内部知识库查询 agent,早期版本允许直接改文章状态,后来权限收紧之后,这类动作就被禁止了。如果评估集还在期望 agent 完成“改文章状态”,它就会一直挂在一批不可能再发生的任务上,反而误导调优方向。

所以每两周到一个月要安排一次评估集审查:哪条样本和当前业务流程不一致,哪条已经无法复现,哪条的期望值描述需要更新。审查之后记录变更原因,打新的版本 tag。这个维护成本看起来不起眼,但长期来看,正是它决定了一个评估集能不能一直用下去。

5.4 从评估数量到评估质量的转变

最后聊一个理念上的变化。早期我很爱攒样本,觉得数据集越大越有权威感。攒到几千条之后发现,真正每一次迭代都会暴露问题的,往往是那么几十条“刁钻”样本。与其盲目扩量,不如把容易把 agent 跑挂的真实失败日志精心整理进评估集,再配几组对抗样本。一个 200 条高质量、覆盖分层的评估集,通常比 2000 条稀释的评估集更值得依赖。

现在我在项目里推动的节奏是:每个版本至少更新 5 到 10 条新鲜样本,样本必须优先来自最近一个迭代周期里暴露的真实缺陷;每季度做一次评估集大盘点,删掉失活条目,清洗标注噪音,从数量驱动慢慢转为质量驱动。

最后再分享一个小技巧:给每条评估样本加一个“创建动机”字段,记录它是因为什么真实事故或者缺陷被加进来的。这个字段在调 Prompt 时非常有用——当指标下滑时,你能很快搞明白是哪些旧账又翻出来了,这比看着一堆冷冰冰的任务描述靠谱得多。评估集的生命力不在于它有多大,而在于它是不是真的持续跟着你的系统一起成长。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/20 19:33:51

Spring Boot集成Redisson:原始依赖与Starter方案对比

1. Redisson与Spring Boot集成概述Redisson作为Redis的Java客户端,提供了分布式锁、分布式集合等高级功能,是企业级应用处理缓存和分布式场景的利器。在Spring Boot项目中集成Redisson有两种主流方式:直接引入原始Redisson依赖和使用Spring B…

作者头像 李华
网站建设 2026/9/20 19:33:42

YOLOv8实战全流程:从环境配置到自有数据集训练与部署

简介:一套基于YOLOv8的图像识别Python工程包,适合具备Python基础、正在学习深度学习目标检测的开发者,可用于安全监控、工业质检、自动驾驶等场景的对象识别与动手实践。资源共包含53个文件,打包为18.4MB的rar压缩包,主…

作者头像 李华
网站建设 2026/9/20 19:33:31

区块链赋能的可验证联邦学习框架设计与实践

简介:本资源是面向高校计算机专业本科生及人工智能方向毕设学生的区块链与联邦学习交叉实践项目源码,聚焦数据隐私保护下的分布式模型协同训练难题,适用于课程设计、毕业设计及前沿技术探索场景。压缩包共15个文件,含5个核心Pytho…

作者头像 李华
网站建设 2026/9/20 19:31:45

agent-skills 实战:用 CLI 为 AI coding agents 构建可复用技能库

1. 从"装完就吃灰"说起:agent-skills 到底解决什么问题如果你最近半年在折腾 AI coding agents,大概率经历过这个循环:兴冲冲装好 Claude Code 或者 Cursor,敲了几个 prompt,觉得"也就那样"&#…

作者头像 李华