☰
Agent微调的数据集收集:从轨迹清洗到训练闭环
2026/10/20 12:55:25 网站建设 项目流程

去年年底开始密集面大模型岗位,二面时面试官突然问了一句:“有微调过 Agent 能力吗?数据集如何收集?”说实话,这个问题看着不起眼,但答起来特别容易露馅。我身边不少朋友在简历里写过“熟悉 Agent”,真被追问到数据层面时,不是含糊其辞就是答得特别散,最后只能尬聊几句通用流程。

这篇文章就把我当时整理的思路和后来实际跑通的经验完整说一下。无论是准备面试,还是真的要上手微调一个带工具调用能力的模型,核心都跑不开两件事:训练数据的形态,以及数据从哪来、怎么清洗、怎么配比。我尽量把每个环节背后的“为什么”也讲清楚,方便你直接拿去参考。

1. 面试官问“微调过 Agent 吗”,到底在试探什么

1.1 这个问题的真实考察点

很多人以为这是在考察模型训练的基本功,比如会不会写 SFT 脚本、知不知道 learning rate 怎么调。但以我后来复盘面试的经验来看,面试官真正想确认的是:你有没有理解 Agent 微调和普通指令微调的本质区别。

普通指令微调解决的是“让模型会回答问题”,而 Agent 微调解决的是“让模型会行动”。这里的“行动”指的是:观察环境或工具返回的结果、决定调用哪个工具、生成正确的参数、根据中间反馈修正下一步计划。这套完整循环能力,不是靠几条 QA 数据就能让模型凭空学会的。

当时面试官又追问了一句:“你如果没实际微调过,怎么证明你理解这里面的难点?”这个问题比第一个问题更刁钻,也是在测试你是否有自己的方法论,而不是只会背概念。我后来总结出一个比较稳的应答框架:

  • 先说清楚 Agent 微调和普通微调的本质差异(数据形态 + 优化目标)。
  • 再说清你了解哪些可行的数据来源和采集手段。
  • 最后给出一个最小闭环方案,证明你能从零把这件事跑起来。

这三层答完,哪怕你没真实做过大规模训练任务,也能让对方觉得你“有体系”。如果真有实操经历,再把具体指标和踩坑细节补上,可信度会高很多。

1.2 大多数人答不上来的原因

为什么这个问题能卡住很多人?我自己体会下来,主要是两个原因。

第一,Agent 相关数据集不像通用指令数据那样容易获取。通用 SFT 数据,社区有很多开源整理好的对话集,拿来清洗就能用。但 Agent 轨迹数据需要模拟环境支撑,比如代码解释器、网页浏览、命令行操作、接口调用等,每一个工具都要有对应的执行环境和结果采集逻辑。没有真实环境,就造不出高质量轨迹数据。

第二,训练回路比常规微调更长。普通 SFT 是一轮输入输出就结束了,Agent 微调一个样本往往包含多轮“调用-反馈”的交替内容。写数据脚本时,必须兼顾角色、工具名、参数 JSON、观察结果、最终回答等结构性字段。处理不好,训练时模型会混淆说话和调用,出现“边生成 JSON 边输出自然语言”的混乱状态。

我当时犯过一个典型错误:直接把对话日志里的工具返回值原封不动塞进训练样本,没有做格式统一和截断处理。结果模型在评估时经常重复调用同一个错误工具,根本不懂“这个工具已经报错了,该换一个”。这个坑后面会展开讲。

提示:面试时如果对方问“你踩过什么坑”,能说出这类具体问题,比干讲流程有用十倍。

2. Agent 微调与传统 SFT 的三个核心差异

面试官问“微调过 Agent 能力吗”,潜台词就是:“你知不知道 Agent 微调根本不是换个数据集那么简单”。我把三个最核心的差异列出来,这些也是面试时最值得展开的点。

2.1 数据形态:从“问答对”到“完整轨迹”

普通 SFT 的样本长这样:

  • system 指令
  • user 提问
  • assistant 回答

三段式就完了。Agent 微调样本则是一个多轮轨迹。以 ReAct 风格的样本为例,典型结构是:

  • system(包含候选人设、可用工具列表、使用方法说明)
  • user(初始任务)
  • assistant(思考 + 工具调用请求)
  • tool/observation(工具返回结果)
  • assistant(基于观察结果的下一步思考与调用,或最终答案)
  • 循环若干轮直到任务结束

这个结构看起来只是多了几轮,但训练时对模型的影响完全不同。模型要在每一轮学会判断:当前信息够不够?不够就继续调用工具;够了就停止调用,直接给最终答案。这个“停止”判断,本质上是二分类能力,需要用大量“足够/不够”的边界样本去训练。

我当时在构造数据集时,刻意加入了很多“只差一个字段就能回答”的中间状态,让模型学会在信息不足时继续追问或调用工具,而不是硬编一个答案出来。这个细节在普通 SFT 里是不存在的。

2.2 优化目标:从“回答正确”到“行为收敛”

普通指令微调只要有一点模型基础,把问答对丢进去,loss 降到合理范围,回答质量一般不会差到哪里去。但 Agent 微调的难点在于,模型不仅要输出语法正确的调用格式,还要做出一系列动作来收敛到最终结果。

这里有三个层面:

  • 格式层:工具名写对、参数是合法 JSON、没有多余的文本干扰。
  • 决策层:该调用哪个工具、参数该传什么、前一步报错后下一步是重试还是换方案。
  • 路径层:多轮调用之间是否相互矛盾,是否走了太多无效步骤。

训练数据覆盖的路径质量,直接决定模型的行为倾向。我跑过一次实验,用两版数据做对比:一版全是“顺利一次调用成功”的轨迹,另一版混入大量“先错后对”的轨迹。结果在评测集上,第二版模型的路径成功率比第一版高出接近两倍。这个数据说明:Agent 微调的核心是教模型“遇到异常怎么做”,而不是教它“标准路径怎么做”。

2.3 评测方式:从“单轮打分”到“环境反馈”

模型微调完,怎么看效果?普通对话任务可以请人打分,或者按关键词评估。但 Agent 任务必须放到环境里跑闭环评估。

我的做法是构建一个离线评测环境,准备 N 个真实任务,让模型自主调用工具完成。评测指标选用:

  • 任务完成率:最终答案是否满足需求。
  • 工具调用成功率:有没有大量语法错误或参数错误。
  • 路径效率:平均调用轮数,超过阈值算失败。
  • 异常恢复率:遇到报错后能否自愈,还是直接卡死。

面试时如果能说出这套评测体系,基本就能证明你真正跑过流程,而不只是看过论文。

3. 数据集收集:从原始轨迹到可训练样本的完整链路

这才是这个问题的主菜部分。我刚开始也以为数据集收集就是把日志拼接一下,实际做下来发现链路远比想象的长,每一步都有讲究。

3.1 轨迹数据的三种来源

我把可行来源归纳为三类,各有优缺点。

模拟环境自动采集

这是最主流的方式。准备好工具环境(比如代码执行器、搜索接口、计算器、数据库查询接口),然后用一批种子任务让模型或脚本自动执行,把完整轨迹录下来。

优点是成本低、数据量大、覆盖面广。缺点是轨迹质量参差不齐,可能有大量无效调用或错误示范混在里面。我通常会在自动采集后加一个成功率过滤器,只保留最终完成任务的轨迹。

人工录制与行为采集

让标注员或内部同学在真实产品界面里操作,按预置任务步骤走,记录每一步操作与中间结果。这种数据质量最高,因为标注员可以故意制造“先失败再纠正”的场景,把好的行为示范录进去。

缺点是成本高、速度慢。一个复杂任务的轨迹可能就要三到五分钟去录制。我当时用了一批实习生来录制,配合统一的脚本模板,一天大概能产出两三百条高质量轨迹。

开源数据与已有日志清洗

开源社区有一些 Agent 数据,公开的 ReAct 样本、爬取网页操作轨迹、开源代码库的 API 调用数据等。真实产品日志也是一种来源,但需要做严格的隐私脱敏和格式清洗。

我的经验是:不要迷信开源数据的数量,更关键的是看工具类型是否跟你的业务一致。如果模型实际要面对的是数据库查询工具,你却拿一堆网页搜索轨迹来微调,效果一定打折。

3.2 数据清洗与格式化的具体操作

拿到原始日志后,我先做的不是急着格式化,而是先去除多余字段。日志里往往包含时间戳、内存信息、调用 ID 等与训练无关的内容,留着只会让模型分心。

清洗流程我按五步来:

  1. 脱敏:去掉任何可能包含用户隐私、内部 token、个人信息的字段,用占位符替换。
  2. 截断:工具返回结果超过一定长度就截断,截断策略尽量是“取头取尾”,保留最关键的信息。
  3. 格式统一:所有工具返回都改成同一套 JSON 结构,包含状态码、摘要、耗时等固定字段。
  4. 轨迹终止打标:每条轨迹末尾标注“任务完成”或“任务失败”,失败的轨迹再判断是否值得保留。
  5. 去重:相似轨迹按文本相似度聚类,每组只保留代表性样本。

这里有一个特别重要的原则:保留失败的中间步骤,但不保留失败结局。也就是说,一条轨迹如果最终成功,中间哪怕有两次错误调用,也要留下来,因为这类样本教会模型纠错。但如果整条轨迹最终是失败的,一般不建议直接采信,除非你想用负样本训练“停止继续无用操作”的能力。

3.3 标注与增强:如何低成本提升样本质量

完全靠自动采集,样本的多样性往往不够。模型可能只会在一种固定模式里调用工具,遇到换一种方式描述任务就懵了。所以我会做两件增强的事:

第一,任务改写。同一个目标,用不同的话术表达。比如“查询北京今天的天气”和“我想知道现在北京适不适合出门”,对 Agent 来说是同一类任务,但描述方式完全不同。用 LLM 做改写,一套轨迹可以扩充成多个训练样本,成本比重新录制低得多。

第二,指令扰动。在 system 提示词里变换工具描述顺序、加干扰工具、修改参数必填项,让模型对工具列表变化更鲁棒。我甚至试过在训练时随机屏蔽 10% 的工具描述,模型居然还能保持不错的调用准确率,说明这个扰动确实激发了它对任务本质的抽象能力。

增强数据的量我一般控制在原始数据的 1.5 到 2 倍之间。超过这个比例,样本同质化反而会让模型过拟合。面试官如果问“怎么避免增强后数据单一”,就可以从相似度去重和多样性采样这个角度回答。

4. 数据配比、质量过滤与去重:决定成败的隐性环节

很多讲 Agent 微调的文章都止步于“收集数据→格式化→开训”,很少讲配比和过滤。但我在实际实验中踩过坑后确认,这部分恰恰是最能拉开效果差距的。

4.1 正负样本配比的经验值

先说正样本。所谓正样本,就是一条完整且最终成功的轨迹。这里我按“任务的复杂度”分档配比:

  • 单步调用任务(简单查询类):占比 20%-30%。
  • 多步调用任务(需要 2-5 次工具调用):占比 50%-60%。
  • 长链路任务(5 次以上且带分支):占比 20% 左右。

这个配比的目的,是让模型既能快速处理简单任务,又能在复杂任务中保持稳定的调用节奏。如果简单任务占比过高,模型会倾向于“少调用工具”,遇到复杂任务就开始瞎猜答案。如果长链路任务占比过高,模型又容易为了调用而调用,把简单问题复杂化。

负样本的选择也很关键。我保留两类负样本:一类是“调用格式完全错误”的样本,用来强化格式约束;另一类是“调用逻辑合理但最终无法完成任务”的样本,用来让模型学会及时停止。

正负样本比例我控制在 8:2 左右。负样本太少模型会过于乐观,什么都敢调;负样本太多模型会变得保守,该调工具的时候反而停在原地。

4.2 哪些坏轨迹必须淘汰

我总结了几类在实际清洗时一定会被删掉的轨迹,供你参考:

  1. 循环死磕型:同一个工具报错超过 5 次还在重试,看不到任何策略变化。
  2. 参数伪造型:工具返回结果被模型自己编造,跟真实 observation 对不上。
  3. 跳步型:在缺少关键 observation 的情况下直接给出答案,常见于自动采样时模型“偷懒”。
  4. 超长冗余型:明明两步能做完的任务,模型绕了十几步,路径效率太低。

判定方法很简单:跑一遍轨迹回放,对每一步检查“工具输入是否来自前一步的输出”以及“最终答案是否能被轨迹支撑”。凡是逻辑链路断裂的一律删除。这一步看起来费时,但对最终效果影响极大。

4.3 去重与多样性的平衡

数据集去重不光是简单的文本去重。轨迹长度相似、工具名相似、中间步骤几乎一样的样本,虽然文本不完全相同,但训练时给模型带来的信息增益很低。

我通常用两步去重:

  • 第一步,按 system + 首轮 user 文本做 MinHash 粗筛,把明显重复的先合并。
  • 第二步,对剩余样本用“工具序列 + 关键参数类型”做指纹去重。比如两条轨迹都调用了同一个查询接口,并且都是传字符串参数,指纹相同,就只留一条。

但去重也要小心别把多样性误删。尤其是那些“最终成功路径相同,但中间经历过不同失败方式”的轨迹,它们的基础路径一样,可是异常恢复能力完全靠中间差异来学习。所以我设了一个规则:如果中间存在失败节点,指纹计算时会忽略失败节点,只保留成功路径指纹,保证异常类样本不会被去重误伤。

5. 如果没微调过 Agent,怎么把这个问题答成加分项

不是每个人都有机会在面试前完整跑一次 Agent 微调。我当时的情况比较特殊,项目做了一半,数据也没大规模验证过。这种情况下,硬编故事肯定不行,关键是让面试官看到你对整件事的思考深度。

5.1 诚实但分层的应答策略

我的应答策略是“承认未实操,但给出完整方案”。直接说“我没做过”,会显得很没准备。直接说“我做过”,容易被追问细节当场露馅。比较稳的说法是:

“我目前还没在正式项目里完整跑过千万级的 Agent 微调,但我在实验环境里复现过开源方案,并且拆解过整个数据流水线。如果让我从头做,我会从 xxx 开始,按 xxx 流程推进,其中最关键的是 xxx。”

这个句式里,xxx 必须是真实能展开的内容。我当时展开讲的是数据清洗中的格式统一和轨迹终止打标,以及评测环境设计。面试官听完之后没有再追问,因为这两块确实是一般人不会凭空想出来的细节。

5.2 把传统数据集经验迁移过来

如果你做过图片分类或文本分类的数据收集,Agent 数据集收集原理上是相通的。我在面试时特意做了这个迁移类比:

  • 图片分类要均衡类别,Agent 要均衡任务复杂度。
  • 文本分类要去除标注噪声,Agent 要去除错误调用轨迹。
  • 图像数据增强靠几何变换,Agent 增强靠任务改写和工具描述扰动。

这样回答的好处是显得有条理,也让面试官觉得你是有扎实基础功的,只是暂时没有在这个细分方向上深入而已。

5.3 现场补课的正确姿势

如果面试官继续追问细节,比如“你具体怎么判断一条轨迹是成功的”,你可以现场画一个“结束条件判据”:

  • 最终答案包含用户需要的全部关键字段。
  • 所有工具调用参数都是合法 JSON。
  • 工具返回的状态码没有出现 fatal error。
  • 推理路径中间不存在自相矛盾的结论。

这套判据哪怕你没有实际操作过,也能展示你对 Agent 任务本质的理解。我当时就是把判据一条条列出来,面试官表情明显放松了不少。

6. 我复盘的完整跑通路径:选型、训练到评估

为了不再让这个问题成为我的面试盲点,面完之后我花了一周时间,把整条链路从零跑了一遍。这里分享一下最终的方案,算是给大家一个可以直接“抄作业”的参考。

6.1 基础模型选型与训练框架

我选了市面上参数量适中、工具调用能力还算不错的开源对话模型作为基础。选型标准就两条:一是原生支持较长多轮上下文,二是对 JSON 输出的稳定性已经足够好,这样微调只用聚焦在行为层面。

训练框架用的是常见的大模型微调工具,支持多轮对话格式。Data Collator 那边要特别注意,Agent 轨迹中的 tool 轮和 assistant 轮是交替出现的,不能像普通对话那样把每条消息独立 mask,要把整个轨迹当作一条完整样本去计算 loss,只对 assistant 部分的 token 算损失,observation 和 system 部分全部 mask 掉。

刚开始我不小心把 tool observation 也算进了 loss,导致模型学会了复述工具返回的原文,而不是基于工具结果做下一步判断。这个问题排查了挺久才发现。

6.2 训练参数的参考值

没有硬性推荐,只给一组我实测后效果还不错的参数供参考:

参数取值说明
学习率1e-5 到 2e-5太高容易破坏底座能力,太低新行为学不进去
Batch Size16受显存限制,8 也可以但效果略差
Epoch2 到 3数据质量高时 2 轮就够,轮次多了会过拟合
最大序列长度4096短于轨迹长度会导致样本被截断,建议先把数据长度分布统计好
LoRA Rank32任务比较复杂,秩太低学不住多轮调用模式

训练完成后,第一步不是看 loss,而是看验证集里的工具调用格式正确率。格式正确率低于 80% 时,别急着调参,先回看数据清洗环节,大概率是训练集中混入了大量格式混乱的样本。

6.3 一个可以复现的最小闭环

如果你想快速验证效果,我推荐一个最经济的方案:

  1. 准备一个小型工具环境:一个本地命令执行器 + 一个 mock 的查询接口,把环境封装成统一格式的工具调用入口。
  2. 用 50 个种子任务,通过脚本自动采样,产出原始轨迹。
  3. 按第 3 节的流程清洗、格式化、增强,大概凑出 2000 到 3000 条可用样本。
  4. 用 LoRA 做一轮低参数微调。
  5. 在测评环境跑 20 个新任务,统计完成率和调用轮数。

这个闭环两三天就能跑完。跑完之后,你对“数据怎么收集、收集完怎么处理、处理完怎么验证”会有非常直观的感知。下次面试再被问到,你甚至可以主动说“我用一个最小闭环实验验证过,发现 xxx”,比背一百篇教程都管用。

我在跑完这个闭环后最大的感受是:Agent 微调的数据工作,消耗时间最多的不是训练本身,而是观察每一步工具反馈、判断轨迹是否值得保留、设计合适的异常恢复样本。这个经验也让我在后来回答任何数据集相关问题时,都能先把“数据从哪里来、怎么判断好坏、怎么提升多样性”放在前头,再讲模型和参数的事。准备面试的朋友,建议你也按这个顺序去组织自己的素材,会显得特别有说服力。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询