Agent微调数据集收集实战:从轨迹格式到清洗配比全攻略
那天二面面试官抛出来一个问题“有微调过 Agent 能力吗数据集如何收集”我垂死病中惊坐起。不是没准备而是这个问题正好卡在我的知识最深处——模型结构、loss 函数、训练策略这些我在简历和口头表达里都准备了一堆话术但“Agent 微调的数据集到底怎么来”确实是我以前容易被带偏、也最容易露怯的环节。面试官显然不想要一个“用过 LLaMA-Factory 跑过 SFT”这种流水账回答。他真正想听的是你知不知道 Agent 微调和普通大模型微调有什么本质区别你知不知道训练一个能调用工具、能按步骤执行任务的 Agent需要什么样的数据形态数据从哪来、怎么清洗、怎么配比、怎么防止模型学坏这一连串问题才是大模型应用岗二面的核心压力测试。这篇文章就把我当时在脑子里快速梳理的完整逻辑写出来。不是面试话术的堆砌而是我在多个 Agent 微调项目里踩坑踩出来的实操经验包括数据格式、收集渠道、清洗规则、配比策略以及最容易被忽略的失败样本和评估方法。如果你正在准备大模型岗面试或者正准备自己动手微调一个 Agent这篇文章应该能帮你少走不少弯路。1. 面试官为什么偏偏问“Agent 微调”和“数据集”很多候选人面对“有没有微调过 Agent 能力”这个问题第一反应是解释微调的原理、讲 LoRA 和全参微调的区别、报一堆训练参数。这些当然不算错但面试官真正想看的是你对“数据”这件事的敏感度。1.1 Agent 微调不是普通 SFT普通 SFT 的数据长什么样一段 prompt 配一段 response模型学会的是“接话”。比如用户说“帮我写一封请假邮件”模型输出一封邮件。这种数据的结构是线性的模型只要学会文本生成规律就行。但 Agent 微调的数据完全不一样。Agent 要做的不是“接话”而是“干活”。它需要理解任务、拆解步骤、决定调用哪个工具、观察工具返回结果、再决定下一步动作。整个过程是一条多轮、带状态、带环境反馈的决策链。这个差异直接决定了数据形态的不同。普通指令数据的格式是{ instruction: 写一封请假邮件, output: 尊敬的领导您好因个人事务需要请假一天时间…… }而 Agent 训练数据的格式至少是{ conversation: [ {role: user, content: 帮我查一下明天北京到上海的航班}, {role: assistant, content: 好的我来查询。, tool_calls: [{name: search_flight, arguments: {date: 明天, from: 北京, to: 上海}}]}, {role: tool, content: [{flight: CA123, depart: 08:00, arrive: 10:30}]}, {role: assistant, content: 为您找到明天北京到上海的航班CA12308:00起飞10:30到达请问需要预订吗} ] }看到区别了吗Agent 微调数据里有“环境反馈”这一环。模型要根据工具返回的结果决定下一步而不是凭文本概率脑补答案。这也是为什么很多团队把 Agent 微调叫做“行为克隆”或“轨迹学习”——学的不是语言风格而是决策行为。1.2 面试官真正在考察的三层能力第一层你是否理解 Agent 微调和传统指令微调在数据形态上的差异。如果连 tool_calls 字段都没见过基本可以判定简历注水。第二层你是否具备从零构建训练数据的能力。数据来源有哪些、怎么采集、怎么清洗、怎么防止敏感信息泄露这决定你能不能独立撑起一个微调项目。第三层你是否知道数据质量和配比比模型结构更影响最终效果。很多人只关心 GPU 和框架选型却忽视数据面试官要的就是这个认知差。我当时在脑子里快速过了一遍自己做过的项目把回答拆成了三层先讲 Agent 微调的数据格式再讲数据收集的三个主要来源最后讲清洗和配比。面试官听完之后明显状态松弛了很多。2. Agent 微调的数据形态和格式设计2.1 主流数据格式ReAct、ToolLLM 与类 Tora 结构现在 Agent 微调最主流的数据组织方式是 ReAct 思路的变体也就是把推理过程和工具调用过程交替写进对话里。ReAct 原本是提示词工程里的方法核心是让模型“先想再动”微调阶段直接把这种思维模式烧进权重里效果比纯靠 prompt 约束稳定得多。整理数据时我习惯把一条 Agent 交互轨迹拆成下面几个关键字段字段含义示例instruction用户给的任务往往带明确目标和隐含约束“帮我订明天北京到上海的机票经济舱尽量早上的航班”thought模型当前的推理过程可保留也可在推理时隐藏“用户需要订早班航班我需要先搜索航班信息”tool_call模型调用哪个工具、传什么参数{name: search_flight, arguments: {from: 北京, to: 上海, date: 2026-01-20, cabin: 经济}}tool_response工具执行后的真实返回结果{success: true, data: [...]}final_answer模型根据工具反馈汇总后给用户的最终答复“已为您找到最早航班CA123……”这种格式的价值在于它把模型的“思考—行动—观察—结论”全链路都纳入训练信号。模型不再只是学习“怎么说话”而是学习“怎么根据观察来行动”。2.2 微调目标SFT 还是继续预训练在 Agent 微调场景里我目前只用 SFT有监督微调很少碰继续预训练。原因很简单Agent 微调要的是行为对齐和格式对齐不是知识注入。模型的基础世界知识在预训练阶段已经有了微调阶段要解决的是“在什么场景下调用什么工具、怎么组织参数、怎么根据反馈决定下一步”。这些问题本质上都是条件行为学习SFT 足够覆盖。具体到参数效率工作环境里普遍用 LoRA 或 QLoRA。一是显存压力小8张A100能跑 7B 甚至 13B 的模型全参微调对显存和数据量要求都高得多小团队根本玩不转。二是 LoRA 的抗遗忘效果比全参微调好。基础能力不退化对 Agent 这种需要模型同时具备“通用对话能力工具调用能力”的场景极其重要。我实践下来的经验是LoRA rank 设置在 16 到 32 之间alpha 设为 rank 的两倍左右初始效果最稳。数据量在 5000 到 20000 条轨迹区间时LoRA 的收敛速度和效果与全参微调差距非常小但训练成本却能省下 70% 以上。2.3 失败轨迹要不要进训练集这是数据格式设计里最容易被忽视的一个问题。很多初次做 Agent 微调的同学只收集模型成功完成任务的轨迹失败样本一律丢进垃圾桶。这是大错特错。想象一个真实场景Agent 调用天气工具工具返回“查询超时”模型应该怎么处理如果训练数据里全是“工具正常返回→模型正常回答”的样本模型遇到异常反馈就会胡编乱造。比如明明工具没返回数据模型却根据常识脑补一个天气结果告诉用户。这种“幻觉式补全”在生产环境里危害极大。正确的做法是刻意保留三类失败样本工具返回空数据模型要学会说“暂时没有查到相关信息请稍后再试”。工具报错模型要学会判断是重试、换参数还是转人工兜底。用户推翻结果模型要学会承认错误并重新规划。我在一个客服 Agent 项目里专门把失败样本比例从 0 提到 15% 左右效果立竿见影——线上测试的无效兜底率下降了接近一半。面试官问数据集收集时你不妨主动提这一点非常加分。3. 数据集收集来源、方法与取舍3.1 数据收集的三个主要来源面试官追问“数据集如何收集”时我一般会把数据来源拆成三块开源数据集、业务日志挖掘、合成数据生成。这三块各有用处也各有坑。开源数据集目前社区里已经有不少 Agent 训练相关的数据集。比如 ToolBench 这类聚焦工具调用的大规模数据以及一些基于框架自动生成的轨迹数据集网上都找得到。优点是拿过来就能用缺点是领域偏通用跟具体业务场景匹配度不高如果直接拿来微调一个医疗客服 Agent效果大概率不理想。我的用法是把开源数据当作“格式热身”数据让模型先学会工具调用的基本格式再用业务数据做精调。就好比练字先临摹字帖字帖不是你的风格但能帮你掌握笔画结构。业务日志挖掘这是我认为最有价值的数据来源。你线上的 Agent 系统只要已经在运行就会产生海量的用户请求、模型输出、工具调用结果。把这些日志捞出来筛选出“任务成功完成”的轨迹再稍作清洗就是非常高质量的训练数据。具体做法是在日志系统里给每条 Agent 会话打一个标签比如“任务完成路径”或“用户满意度反馈”只抽标签为正向的轨迹。然后人工抽检一部分确认没有错误信息就可以进训练集。这个方式的优点是真实验证过、且符合业务语气缺点是数据噪声大、清洗成本高。合成数据生成当你没有现成日志开源数据又不贴业务时合成数据是兜底方案。做法是用更强的模型比如旗舰模型作为“老师模型”把任务清单喂给它让它生成完整的 Agent 调用轨迹再人工抽检修正。合成数据最大的坑是多样性不足。如果你只给“老师模型”喂同一批 prompt它生成出来的轨迹会高度同质化模型微调出来遇到真实世界的多样输入直接歇菜。所以我一般会把任务清单设计得足够多样在任务描述里注入随机实体、随机约束、随机边界条件。比如订机票任务可以随机切换城市、日期、舱位、人数让轨迹样本丰富起来。3.2 数据集收集流程的完整拆解我以一个“智能客服 Agent”微调项目为例把数据收集流程拆成几个动作你可以照着参考。第一步列出 Agent 的核心能力清单。客服 Agent 至少包含订单查询、退换货、优惠券咨询、物流跟踪、人工转接。每个能力对应若干种任务变体比如“订单查询”要覆盖订单号查询、手机号查询、按时间范围查询。第二步定义数据字段标准。提前规定好整条轨迹数据的 JSON schema包括上面说的 instruction、tool_call、tool_response、final_answer 等字段。这一步不做后续清洗和配比会极其痛苦。第三步采集原始数据。如果线上有日志写一个离线脚本按会话维度抽取轨迹。脚本逻辑大概是# 伪代码示例从日志中抽取Agent轨迹 def extract_trajectories(log_stream): trajectories [] current_session [] for event in log_stream: if event.session_id ! current_session_id: if is_successful(current_session): trajectories.append(current_session) current_session [] current_session.append(event) return trajectories注意一个关键细节日志抽取只捞“任务成功完成”的会话。判断“成功”不能只看模型有没有输出要看工具调用链是否完整闭合最终答案是否与工具返回结果吻合。第四步人工抽检修正。抽检比例至少 20%。主要检查有没有幻觉内容、工具参数有没有错误、多轮对话是否上下文连贯。第五步脱敏处理。业务日志里一定会有用户手机号、订单详情、地址等敏感信息。上训练前必须做字段级脱敏否则轻则数据违规重则给公司挖坑。3.3 合成数据的 Prompt 设计思路合成数据在收集阶段还有个隐藏技巧就是设计任务 prompt 时不能只给“老师模型”干巴巴一句“帮我生成一个Agent轨迹”。你需要给它一个完整的 Agent 系统设定让它知道自己有哪些工具、工具的参数 schema、用户可能的语气风格。我自己常用的老师模型提示词结构分四块身份设定、工具清单、任务目标、格式要求。比如你是一个智能客服Agent负责处理用户的订单相关咨询。 你拥有以下工具 1. query_order(order_id, user_phone) —— 查询订单信息 2. cancel_order(order_id, reason) —— 取消订单 3. express_tracking(tracking_no) —— 查询物流 用户的问题是我想查一下昨天买的那个快递到哪了。 请根据工具调用方式生成完整的Agent运行轨迹包括thought、tool_call、tool_response、final_answer。这种提示词的成功率比直接问“生成一条客服对话”高得多。因为工具清单给了老师模型约束生成出来的轨迹就不会出现“模型凭空回答快递位置”这种不调用工具的伪轨迹。4. 数据清洗、配比与质量评估数据收集回来了不意味着能直接训练。这一步最花时间也最体现功力。很多团队训出来的模型“弱智”根本原因不是模型不行是数据没洗干净。4.1 清洗规则哪些数据必删我个人总结了一套“四删”原则分享出来供参考。一删重复样本。同一用户反复提交同样问题日志里可能出现大量一模一样的轨迹。用文本哈希去重保留少量代表即可否则模型会被重复样本带偏产生严重过拟合。二删矛盾样本。即同一个任务两条轨迹给出了完全不同的工具调用顺序和最终结论。矛盾样本会把模型搞糊涂在推理时犹豫不决。处理方法是保留和业务规则一致的那条删除另一条。三删幻觉样本。模型在工具没有返回某字段的情况下硬是编造了一个字段值。这种样本必须手动揪出来删掉。怎么发现写一个规则引擎比对 final_answer 里出现的数字、单号、时间是否在 tool_response 里出现过。不在就是幻觉。四删“假成功”样本。任务没真正完成但模型礼貌性地回复了“已完成”。比如用户问“帮我改签机票”Agent 只调用了一次查询工具然后回复“您的机票已改签成功”但工具返回里根本没有改签成功的状态码。这类样本很有迷惑性清洗时稍不注意就漏过去。我通常靠工具返回的状态字段来交叉验证模型说“成功”必须和 tool_response 里的 status 字段一致。4.2 数据配比数量不是关键结构才是经常有人问我Agent 微调到底要多少条数据我的回答是看结构不看绝对数量。5000 条结构合理的多样轨迹效果可能比 50000 条同质化轨迹更好。重点在于覆盖度。我给不同能力项的数据量分配大概遵循以下经验值能力项建议数据量说明主路径能力3000-5000 条每个能力 500-1000 条覆盖常见变体边界条件800-1500 条空输入、超长输入、模糊意图、多任务混合失败与异常500-1000 条工具报错、空数据、超时、用户取消多轮澄清500-800 条用户补充信息、纠正错误前提、追问细节还有一个非常容易被忽略的点要保证每个工具在训练集里出现的次数相对均衡。如果某个工具在数据里出现频率特别高模型就会形成“路径偏好”遇到适合用另一个工具的场景仍然选择调用这个高频工具。比如客服 Agent 里“订单查询”工具出现 80% 以上模型就很容易在用户问物流时也去调“订单查询”导致答非所问。4.3 数据质量评估训练前的最后一道关数据准备完毕、正式训练之前我会先做一轮质量抽检记录。抽检边抽边标注出问题类型比如信息缺失、格式错误、逻辑错误、幻觉回答等。质量评估不追求所有指标都完美但至少要确认整体合格率在 90% 以上否则不建议开训。抽检的时候我发现一个规律标注者之间对“成功轨迹”的判定往往有分歧。有的人认为只要模型最终给了一个合理文本就算成功有的人坚持必须严格匹配工具返回的字段。这份分歧本身就是一个信号——说明你们的任务定义还不够清晰。我建议在项目开始时就建立统一的成功判定标准例如“任务完成必须满足三个条件工具调用链完整、最终答案与工具返回一致、用户意图被完全满足”然后把标准写进标注文档。4.4 训练数据与评估数据的切分除了训练集一定要单独切一份评估集而且评估集的构建逻辑要和训练集不同。很多同学直接把训练数据随机抽 10% 当评估集这样评估结果虚高得离谱——因为模型在训练时已经见过这些任务类型了评估时自然“熟门熟路”。我的做法是按任务类型切分。比如训练集覆盖 80% 的任务变体评估集里全放剩下的 20% 变体。这样模型在评估阶段遇到的都是“没见过但同类”的任务才能测出真实的泛化能力。这一步在面试时讲出来也很有记忆点。5. 完整实操项目流程从 0 到 1 微调一个客服 Agent前面讲了很多方法论这章用一个完整的模拟项目把所有环节串一遍。假设我们要微调一个 7B 模型让它成为某电商平台的智能客服 Agent支持订单查询、物流跟踪、退换货申请三个核心工具。训练目标就是让模型学会这三类任务的完整工具调用轨迹。5.1 环境与框架准备我这边的工作环境普遍用 LLaMA-Factory 或者自研的微调脚本。如果你是从零开始建议先用成熟的框架跑通流程再自己改源码。依赖组件主要是 transformers、peft、deepspeed 这些模型底座用 chat 版本比 base 版本更容易收敛因为 Agent 微调希望保留模型的对话能力而不是从零学语言。训练参数给出一套可复用的配置model_name_or_path: /models/7b-chat template: chatml stage: sft finetuning_type: lora lora_rank: 16 lora_alpha: 32 dataset: agent_train cutoff_len: 2048 per_device_train_batch_size: 8 gradient_accumulation_steps: 4 learning_rate: 2e-4 num_train_epochs: 3 lr_scheduler_type: cosine warmup_ratio: 0.1这套参数里有两个点值得说明。一是 cutoff_len 设 2048因为 Agent 轨迹数据通常比普通指令长太短会把轨迹截断导致模型学到一半的动作链。二是训练轮次不宜过多3 轮左右足够多了容易过拟合。5.2 数据准备过程怎么落地假设我们没有现成日志只能用合成数据为主的方式。具体操作如下第一步结合业务方梳理出 30 个高频任务场景模板每个模板再生成若干变体。比如“查询订单”模板的变体包括按订单号查、按手机号查、查最近一笔订单、查半个月前的订单。第二步把模板和变体批量喂给“老师模型”生成轨迹。每条生成结果都会经过一个规则校验脚本检查工具名是否存在于工具清单、参数类型是否匹配、tool_response 是否跟 tool_call 对应。第三步清洗与人工抽检。抽检时重点盯着那些“老师模型”自己都绕晕了的多轮轨迹比如用户先说“帮我查个订单”后说“算了我还是先看看物流吧”模型能不能正确切换工具。这类轨迹如果质量差就直接删掉不强求数量。整个过程做完我通常能得到约 8000 条有效轨迹其中 6000 条进训练集2000 条按任务类型切分做评估集。5.3 训练后评测与回归训练完之后不能只看 Loss 降没降必须做三类评测。第一类是格式评测。随机挑 100 条评测样本检查模型输出的 tool_calls 是否符合 JSON schema。格式错误率超过 5% 就要考虑是不是数据格式设计有问题或者 cutoff 截断了轨迹。第二类是功能评测。把评估集跑一遍看每个任务的成功率、工具调用准确率。关键指标是“工具调用正确率”就是该调 search 的时候有没有调 search该传的参数有没有传对。第三类是回归评测。准备一份与 Agent 无关的通用对话集确保微调后模型没有丧失正常的问答能力。很多 Agent 微调项目失败就失败在回归测试上——Agent 能力上去了通用对话能力垮了产品照样没法用。我们当时跑完一次评测后发现模型在退换货场景下经常把“退货原因”字段漏传。排查下来发现是合成数据里老师模型生成的轨迹里这个字段缺失率太高。后来在提示词里强制要求“退货场景必须传 reason 字段”重新生成了一部分数据问题解决。这就是数据质量直接影响模型行为的典型案例。6. 常见问题与排查技巧实录Agent 微调不是一个一次就能成功的活。下面把我在实际项目里反复遇到的几个问题整理成速查表希望对你有直接参考价值。常见问题可能原因排查思路与解决方案模型微调后不会调用工具了训练数据里工具调用轨迹占比太低检查数据集工具调用样本比例至少要占 60% 以上工具参数经常填错或漏填数据里参数 schema 标注不规范统一工具调用的参数名、类型、必填项清洗时校验模型在工具返回空数据时仍硬答失败样本和空返回样本缺失补充工具异常和空返回轨迹至少占总体 10%-15%通用对话能力明显退化LoRA rank 过高或者训练轮次过多降低 rank 到 16 以内、减少 epoch增加通用 SFT 数据混合训练模型总是优先调用同一个工具数据配比中工具出现频率不均衡按工具出现次数做分层重采样保持各工具调用频率接近训练 Loss 下降但评测指标很差评估集和训练集分布重叠按任务类型切分评估集保证评估任务不直接在训练集中出现模型输出的 JSON 格式经常解析失败数据里 JSON 格式不统一、被截断统一工具调用的序列化格式必要时在 prompt 里加入 few-shot这些问题里我最想强调的还是“工具调用出现频率不均衡”这个坑。它非常隐蔽训练 Loss 看着是正常的Loss 曲线也很漂亮但模型一到线上就“偏科”。有一次我做数据分析工具 Agent训练数据里“画图表”工具出现频率太高结果用户问“帮我算个平均值”时模型直接调了画图工具输出一张没有数值结论的图。后来我把各类工具调用频率拉平重新训练才解决了这个“路径惯性”。还有一个排查技巧当模型出现某种固定错误时不要急着调模型参数先回数据里搜索同类型样本看看是不是数据本身就有同样的错误。Agent 微调的模型本质是在模仿训练数据里的行为模式数据里如果有“坏习惯”模型学得比谁都牢。所以遇到问题第一反应永远是查数据、查数据、查数据。7. 面试回答的思路整理最后回到开头的面试题。如果你也准备参加大模型岗面试我的建议是不要背稿把逻辑理顺。面试官问“有微调过 Agent 能力吗”你的回答可以按这个顺序展开先定义“Agent 微调”的特殊性——它和普通 SFT 不一样它学的是决策行为和工具调用轨迹数据必须包含 tool_call 和 tool_response。再讲数据收集——我习惯用三类数据源开源数据打底、业务日志挖真实轨迹、合成数据补覆盖度。真实日志最宝贵合成数据要特别注意多样性。失败样本和异常样本必须有这是很多人忽略但决定线上稳定性的关键。接着讲清洗和配比——四删原则、工具调用频率均衡、训练/评估按任务类型切分。这些细节是区分“做过”和“做过且做得好”的关键。最后若面试官追问“效果如何”可以讲评估指标体系格式正确率、任务成功率、工具调用准确率、通用能力回归。再配一个自己实战中踩坑解决的案例整个回答就有血有肉。这个时代的 Agent 微调数据工程的重要性远远大于模型结构的选择。谁对数据更敏感谁就能做出更稳定的 Agent。我自己在一开始也踩过“数据不够就硬训”的坑模型训出来各种乱调用工具后来踏踏实实把数据整理工作做细了效果立刻上了一个台阶。如果你正在准备面试或者即将开始 Agent 项目希望这篇文章能帮你少踩几个坑把精力真正花在刀刃上。