Agentic数据管线实战:从数据合成到清洗的工程化落地
做 SFT、mid-training 和 RL 的朋友最近应该都有一个共同感受模型结构越来越不是瓶颈真正卡脖子的地方变成了训练数据。以前我们写规则脚本清洗语料后来用 LLM 做单轮打分过滤现在越来越多团队开始用 agentic 的方式去合成和清洗数据——也就是把造数据这件事本身交给一个会规划、会调用工具、会自我检查的多步 agent 工作流来做。这篇文章我会把 09-14 这段时间我在 agentic 数据管线上的完整实践整理出来包括 SFT、mid-training、RL 三种场景下的合成与清洗方案、每一步的取舍逻辑以及踩过的坑。内容偏实操适合那些已经在用 LLM 造数据、但觉得质量不稳、成本偏高、效果不可控的团队参考。1. 为什么训练数据要靠 agent 来做而不是一把梭生成1.1 单轮生成的天花板以及它卡在哪先说个很现实的场景。你对着一个强模型说给我生成 5000 条数学题和答案第一轮出来的数据往往质量不错但等你生成到第 2000 条的时候你会发现题目开始高度同质化换汤不换药。再往后错误开始出现计算步骤跳步、答案对不上、题目条件自相矛盾。这是单轮生成single-pass generation的典型症状核心问题有三个。第一没有反馈回路。模型生成完一条数据就算完事没人检查它对不对、好不好、有没有重复。相当于写代码从来不编译不跑测试全靠手感交付。第二多样性靠的是采样随机性而采样随机性在指令空间的覆盖上是很弱的模型会往自己概率分布里高密度区域坍缩产出大量看起来像的数据。第三错误会传播。尤其是链式推理类数据一步错步步错如果后续把这个数据拿去作为 SFT 的正样本模型学到的是错误的推理过程。我试过直接用最强模型批量生成指令数据单看每条数据文本都很漂亮但拿去做完一轮 SFT 之后模型在评测集上的表现不升反降。后来抽样人工看才发现不少数据存在逻辑断裂和知识性错误。这就是单轮生成的代价表面质量高实际不可控。1.2 agentic 方式到底改了什么agentic 方式的核心变化是把生成数据从一个单步动作变成一个多角色、多步骤、带验证闭环的工作流。我在实践中通常拆成五个角色规划器Planner根据目标场景拆解数据需求产出数据 schema、主题分类、难度分布、数量配额。生成器Generator按照规划产出原始样本可以是一个或者多个模型并行。评审器Critic对照质量标准逐条检查输出具体问题和修改建议而不是简单打一个分。重写器Rewriter根据评审意见对样本做定向修改。验收器Verifier用规则、工具调用、二次生成等方式做终检通过才入库。这个流程本质上就是工业界的质检闭环。一个实习生写初稿主编审稿提意见作者修改质检终检通过后才交付。每一条数据都要经历一轮或多轮生成—评审—重写—验收质量中位数会被明显拉高尤其是能过滤掉那些看似通顺但经不起推敲的样本。我自己的体会是agentic 方式和普通的多轮 prompt 反思最大的区别在于评审和重写是分开的而且每一个角色都有明确的责任边界。如果让同一个模型在一条 prompt 里既生成又反思模型很容易自我感动觉得写得很棒。把评审角色的 prompt 独立出来甚至换一个更严格的模型效果会完全不同。1.3 SFT、mid-training、RL 对数据的要求完全不一样很多人一开始会用同一套 agentic 管线去合成所有数据但这是最典型的误区。三种训练场景对数据的偏好差异极大如果不区分管线越复杂反而越帮倒忙。训练场景数据形态核心质量维度agentic 工作流重点SFTinstruction-response 对指令多样性、答案正确性、格式规范指令演化 推理校验 答案评审mid-training长文本语料连贯性、知识密度、领域一致性大纲规划 分段写作 一致性检查RL偏好对 / 奖励信号可区分度、排序正确性、标签干净度多响应采样 评审对抗 投票去噪SFT 数据要求的是正确答案评审重点在正确性与指令匹配度多样性也不可忽视。mid-training 数据要求的是好文本本身重点在长程连贯和领域深度单条样本可能几千字需要分段合成再合并。RL 数据要求的是能区分好坏重点在于成对数据的可比较性——如果 chosen 和 rejected 差距太小模型学不到东西如果评审错判标签就脏了。所以在设计 agentic 管线之前先问自己一个问题这条数据最终要服务于哪个训练阶段、要教会模型什么能力。这个答案决定了后续所有的角色分工、验证信号和成本分配。2. agentic 数据合成的整体设计从一个最小可用管线开始2.1 一个可以跑通的最小管线我知道很多人一看 agentic 就感觉要上很重的框架其实不用。第一次落地我用一个简单的 Python 脚本加上几个 prompt 就串起了整个流程核心逻辑就是循环调用不同角色的 prompt并且设定最大迭代轮数和退出条件。以一个简单的 SFT 数据生成任务为例管线长这样def generate_one_sample(schema, max_iters3): # 1. 规划从 schema 中获取主题和难度 plan planner(schema) for i in range(max_iters): # 2. 生成模型产出指令和回答 sample generator(plan) # 3. 评审是否通过质量标准 issues critic(sample, schema) if not issues or i max_iters - 1: # 4. 验收规则检查 格式检查 if verifier(sample): return sample return None # 4. 重写根据评审意见修改 sample rewriter(sample, issues) return None这个最小版本里最关键的参数是max_iters。我一开始设成 5后来发现绝大多数数据在第 2 到第 3 轮评审重写后就能通过第 4 轮以后基本是边际收益递减还烧钱最后统一调到 3。verifier一开始也只做简单格式检查比如 JSON 字段是否完整、指令是否为空、答案长度是否低于阈值。先跑通再逐步加验证逻辑。这个流程跑通之后你会发现对比单轮生成有三点改善错误率明显下降因为评审环节兜住了格式一致性更好因为每条数据都过了验收器多样性有所改善因为评审会指出与已有样本太像的问题。当然代价就是单条数据的生成成本翻了几倍这个后面专门聊预算控制。2.2 模型分层与预算控制agentic 管线最容易被诟病的就是成本。我算过一个账如果用 top 级商用模型跑三跳路线每条高质量训练数据的 token 成本大概在 0.02 到 0.05 美元之间一千万条数据就是几十万美元绝大多数团队扛不住。所以我的做法是模型分层model routing。先用一个小而快的模型做生成器的初稿再用一个更强但更贵的模型做评审器只在评审不过的时候才让强模型参与重写。实践中这个组合的效果非常接近全程使用强模型成本却只有三分之一到四分之一。有一个经验值可以参考当评审模型和生成模型的能力差距越大评审越能抓到生成模型的问题如果两个模型水平差不多评审的挑剔度会明显下降。预算的另一个大头是重试浪费。数据没通过评审需要重写但如果评审意见本身就模糊重写模型只能瞎猜来回折腾三次还是老样子。我在评审器的 prompt 里强制要求先引用原文的具体问题再给出修改建议并且建议必须可执行不许写增强逻辑性这种空话。加了这条约束之后重试轮次的中位数从 2.4 降到了 1.5。还有个小技巧对生成结果做 embedding 向量缓存。如果两条指令的语义相似度极高直接复用之前的处理结果省去重复生成的开销。实测对同类主题的数据生成缓存命中率大概在 15% 到 20%积少成多。2.3 质量信号怎么定义才靠谱agentic 管线里评审依据什么标准是决定数据质量的根源。很多人让 LLM 打分最后发现打分和人工评估的相关性很差原因就是没有给模型可操作的评分维度。我在实践中把质量信号分成三层。第一层是硬规则包括字段完整性、格式正确性、长度约束、敏感词过滤这些用代码做不让 LLM 打分。第二层是软性质量维度每个维度都要有明确的判断标准和反面示例比如指令清晰度指令是否包含足够背景信息让人理解任务答案正确性推理链是否有断点或跳步。第三层是全局约束包括语义去重、与测试集的相似度检查这些通常要借助 embedding 或 n-gram 工具。验收标准也必须量化。我会把通过率设成一个具体指标比如评审通过且人工抽检准确率不低于 90%低于这个阈值就说明管线配置需要调整要么评审器太宽松要么生成器能力不够。没有量化标准的 agentic 管线很容易在工程上自我感觉良好最后被下游训练效果打脸。3. 按训练场景拆解实操方案SFT、mid-training、RL 各自怎么做3.1 SFT 数据合成从 seed 指令到多样化的 instruction-responseSFT 数据合成我的主力方法是种子指令 演化 评审闭环大体思路和 Evol-Instruct 类似但把无引导的演化换成了有规划的 agentic 扩写质量稳定了很多。第一步准备几百条高质量的种子指令覆盖目标能力域的不同分支。种子数据一定要精我在实践中发现种子质量直接决定演化产物的质量上限。种子不够好的话后续怎么演化都会带着种子的毛病。第二步规划器基于种子指令和一个能力分类树生成演化方向比如把简单指令改写为需要多步推理的版本把通用问题限定到具体业务场景把单轮问题扩展为需要上下文理解的问题。第三步生成器按照演化方向产出新的指令和回答评审器负责检查指令是否真的变难了、答案是否正确、是否与种子过于雷同。有一个特别容易被忽视的点SFT 数据不只是要正确答案还要合理的推导过程。我在生成器 prompt 里明确要求先给出逐步推理草稿再由一个压缩器把冗长的推理压缩成符合目标模型输出格式的最终答案。这个思路是从蒸馏场景里借鉴过来的——直接让模型输出短答案它可能会跳步先长后短能保留逻辑链的完整性。多样性方面我强烈建议在生成器里注入检索到的真实参考文本。也就是说给生成器一批真实的文档片段当作素材让它基于素材出题。这比纯靠模型脑补要好得多一是素材天然多样二是模型基于给定事实出题幻觉的概率降低。这个做法我在指令数据合成里测过同样数量的数据素材注入版本在评测集上的效果提升了差不多 5 个点代价只是多花一些构造检索索引的时间。3.2 mid-training 数据合成长文本连贯性是硬骨头mid-training也叫 domain-adaptive continued pretraining要的是大段连贯、知识密度高的领域文本。合成这类数据最大的难点是LLM 写短文本还行写几千字的深度长文往往会前后矛盾、观点漂移或者变成正确的废话。agentic 管线在这里的用法是大纲—分段—合并—一致性检查。规划器先基于领域主题库生成一份详细的分章节大纲每个章节包含核心论点、需要覆盖的关键知识点和预期字数。生成器按章节逐段写作每次只写一节避免一次生成过长导致失控。写完全部章节之后由一个一致性评审器通读全文检查章节之间的逻辑衔接、术语一致性、是否有重复表述。发现问题的章节重写器只针对该章节局部修改不从全局推倒重来。我踩过的坑是如果只让生成器直接写一篇 2000 字的长文而没有任何 checkpoint模型后半段的概率分布会高度飘忽经常出现前面说 A 方案可行、后面又说 A 方案有致命缺陷这种前后矛盾。拆段之后单段字数控制在 400 到 600 字问题减少了 80%。这可能和你用的模型上下文长度有关但即使是我的主力模型我也建议拆段写作因为长文的一致性主要是规划问题不是记忆问题。mid-training 数据的清洗和 SFT 不太一样这里的重点不是对错而是信息密度。我会用一个评审器专门评估文本的知识增量——如果一段文本随便用一个通用模型都能写出来那它对模型学到领域知识没有帮助。知识增量偏低的文本会被直接丢弃。这个维度的引入让最终语料的整体困惑度优化效果好了不少。另外mid-training 里我很推荐做反向 QA 生成给定一段领域文本让 agent 生成一批基于该文本的问答对再通过问答对来反向筛选文本。如果一个问题答案是我无法从文本中得出说明文本这个位置的信息密度或可推理性不足。用 QA 的可回答性作为文本质量的代理指标比纯人工看语料高效得多。3.3 RL 数据合成与清洗偏好对、奖励信号和 rollout 筛选RL 阶段的数据是我认为 agentic 方式最能发挥价值的场景因为 RL 数据比拼的不是生成能力而是判断能力——而这个判断过程天然适合多 agent 评审对抗。先讲偏好对preference pair的合成。我的标准做法是给定一条指令让多个模型或多个采样温度各生成多条候选响应。然后由一个评审 agent 按照 Rubric比如有帮助性、正确性、忠实度逐条评估选出 best 和 worst 作为 chosen 和 rejected。这里有个容易犯的错误直接拿最强模型的输出和弱模型的输出配对。这种 pair 差距太大模型很快就学会了只要像强模型风格的就是对的学不到细粒度的好坏判断。正确做法是让候选响应之间的质量差距适当且可比。我一般让同一个模型用不同温度采样或者让同级别的两个模型各出几条再让评审 agent 挑出明显更好和明显更差的。差距太小的 pair 直接丢弃因为评审和模型都很难从中学习。我会在管线里加一个判断步骤如果评审 agent 认为两个候选质量相当、难以区分这一对数据就不入库。再讲奖励信号 / RM 数据的清洗。RLHF 里 reward model 最怕标脏数据——chosen 和 rejected 标反了模型训练直接崩。所以 RM 数据入库之前我用多个评审 agent 做独立投票每个人投 best 和 worst只有投票一致或者至少多数一致的样本才保留。这个实践的代价是数据量会缩水 20% 到 30%但 reward model 的准确率能提升 3 到 4 个点非常值得。独立投票的关键在于每个 agent 的评估 prompt 不要完全一样我会在 prompt 里注入不同的评价侧重比如一个强调事实性、一个强调推理步、一个强调用户意图匹配让他们形成真实的多角度竞争。最后是 rollout 数据清洗。做 RL尤其是数学或代码任务时策略模型会生成大量采样结果传统 pipeline 靠规则验证比如结果字符串比对来筛选正样本。我在此基础上加了一个解释验证 agent不仅看最终答案是否对还要看过程推导是否合理。有时候答案碰巧对了但推理过程是瞎编的这种 rollout 对训练有害无益。过程验证 agent 会检查每步推理和最终答案之间是否有因果关联把蒙对的样本筛掉。在数学任务上这个过滤能去掉差不多 15% 的伪正样本训练后的最终准确率提升明显。4. 数据清洗的 agentic 管线过滤只是地板重写才是天花板4.1 清洗不只是过滤更重要的是重写与扩写很多团队把清洗等同于过滤agent 打分分数低就删。这个思路太浪费了。我做过统计被 LLM 打低分的样本里有相当一部分不是无价值而是有价值但表达不合格——比如一段领域知识正确的文本但术语使用不规范、逻辑跳跃、或者格式混乱。直接删掉相当于把金子扔了。我现在的清洗策略是三分类保留、重写、删除。评审 agent 给出低分时会同时判断这是内容问题还是形式问题。内容问题——比如事实错误、逻辑硬伤——直接删除。形式问题——比如表达冗余、结构混乱、衔接生硬——交给重写 agent 改写。这样整个数据池的利用率能提升不少。重写也要分级。轻度清洗只做符号归一化和格式标准化用规则就好不需要 agent。中度清洗做段落重组和术语统一用普通模型。重度清洗是做语义增强比如把口语化的表达改写为规范的书面语、给论证补充缺失的中间步骤这个才动用强模型。分级的目标是避免所有数据都走昂贵的高强度重写其实绝大部分数据不需要那么大动干戈。4.2 去重与去污染两个容易被忽视的隐形杀手数据去重这件事如果只做精确去重你会漏掉大量语义重复的样本。我用三层去重第一层 MinHash 做 n-gram 级别的近似去重处理完全复制或轻微改写的文本。第二层用 embedding 相似度去重处理那些说法不同但意思一样的样本。第三层才是 agent 级别的语义去重针对剩余的小规模重复——生成器偶尔会产出同一道题换个人名当新题embedding 相似度可能并不高评审 agent 能看得出来。去污染decontamination更关键尤其是用合成数据的时候。如果你的评测集是公开 benchmark而对照模型在生成数据时见过这些评测题那训练结果就是虚高的。我在验收器里加了一步强制检查把生成的样本和评测集做 n-gram overlap 和 embedding 相似度比对超过阈值直接丢弃。这个检查必须在数据入库之前做不然后期再发现污染整批数据要重新生成。我最开始没做这步结果在某个公开评测集上刷出了非常好看的分数但换到自建评测集就原形毕露。后来定位原因就是合成数据里混进了和评测集高度重合的题目。从那以后我的验收器里 100% 会有去污染检查宁可多丢一些数据。4.3 清洗效果怎么验证清洗管线改完之后怎么知道清洗是有效而不是过度我的验证方法分三步。第一步是抽样人工审计。每批数据清洗完成后随机抽 100 条让人看统计三个指标格式通过率、内容正确率、风格统一度。这三个比例要有一个预期区间比如格式通过率 95% 以上、内容正确率 90% 以上。低于预期说明清洗不够或者清洗错了方向需要看具体失败案例。第二步是对比清洗前后的分布变化。我会统计文本长度的分布、主题分布的多样性、指令型式的离散度确保清洗没有把某类数据洗没了。第三步是最重要的——小规模训练验证。清洗数据先拿去跑一个 1k 到 2k 步的小训练看评测曲线是否正常上升。不要等全量数据都洗完了才训练那样发现问题已经晚了。我经历过一次过度清洗的翻车一个评审 agent 的 prompt 里写了语言要正式专业结果数据池里短指令、口语化指令、反问式指令全被改了或者删了模型训练完变得非常死板回答风格千篇一律就像同一个模子刻出来的。所以我后来在评审 prompt 里特别强调只有当风格问题影响理解时才需要修改否则保留原始风格。风格多样性对训练数据的价值经常被低估。5. 常见问题与排查技巧实录5.1 生成数据坍缩、多样性不足症状生成到一定轮次后数据内容越来越像主题集中在一小块区域指令的句式结构雷同。排查方向先检查种子指令的多样性是否足够。种子就几百条如果集中在两三个主题演化出来自然走不出那个圈。其次检查生成器的 temperature 和 top_p温度太低采样太保守。最后看规划器的演化方向是否有约束如果规划器总是给出类似让问题更难的方向多样性也会受限。我常用的修复手段有三个给规划器注入外部检索结果从真实语料中提取新的主题和句式为种子池扩容在评审器中加入与已有样本重复度的检查项让评审主动拦截相似样本对生成器做 temperature 调度前几轮低温度保证稳定后面高温度增加探索。这套组合拳打下来多样性指标self-BLEU 和 embedding 平均距离能改善明显。5.2 清洗过度导致信息丢失和信息风格单一症状数据池整体的句长分布变得很窄所有文本都是同一风格的完成品边角案例和特色表达消失了。这通常发生在多个重写 rule 叠加的情况下。每个规则单独看都有道理——统一术语、修正语法、补充细节、提升正式度——但串联起来就把原始语料的毛刺全磨掉了。而正是这些毛刺往往才是模型泛化所需要的。我的建议是第一层清洗做最小干预非必要不改写。第二层再针对特定问题做定向重写并且保留重写记录。最关键的是每次清洗都保留原始版本一旦下游训练效果不理想可以回到原始数据做 A/B 对比。另外我强烈建议每隔一段时间把清洗后数据的分布指标和新清洗前的作对比不要等出了问题再查。5.3 预算失控、管线跑不完症状数据量需求很大但 agentic 多轮迭代之后成本指数上升管线一周都跑不完一批。我的处理方式是先慢后快。新任务第一次跑抽样 1 万条数据人工细看把管线调好再放开全量。全量阶段用分层模型降低成本上面已经提过。还有就是加一个快速失败机制生成器产出的样本如果在前两轮评审中连续不通过说明这条 seed 有问题立刻终止迭代避免无限烧钱。还有一个容易被忽略的是并发控制——很多商用模型 API 有 QPS 限制用一个简单的信号量控制并发量整体吞吐反而更稳定不会因为限流导致重试浪费。成本监控方面我习惯把每一条数据的累计 token 消耗都记录下来按主题、按模型路由、按迭代轮数分维度统计。这个数据能帮你快速定位预算黑洞。我见过一个团队预算黑洞居然是重写器——他们把所有评审不过的样本都丢给最强的模型重写但很多简单问题小模型就能改好。加上按问题复杂度路由重写器的逻辑后总成本降了三成。5.4 快速验收清单检查项通过标准说明格式通过率≥ 95%字段完整、类型正确、无解析失败内容正确率抽检≥ 90%人工抽检 100 条无明显事实或逻辑错误去污染检查0 命中和评测集 n-gram/embedding 比对无超阈值样本语义去重率重复对 1%任意两条样本的语义相似度不超过阈值多样性指标与上一批持平或更优self-BLEU 不升高、embedding 距离不缩小小规模训练收益评测曲线正向上用 1k-2k 步训练验证数据有效性每次批数据入库前我都会用这张表跑一遍。全部通过了才敢送训练任何一项飘红都要回溯管线。这不是流程繁琐而是吃过太多次数据入库容易、出库难的亏。最后再分享一个小技巧不是所有的合成数据都需要完整的 agentic 分级流程。有些简单任务比如把 100 万条 FAQ 整理成 instruction-response 格式用规则加单轮生成就够了上 agentic 是杀鸡用牛刀。我在实践中总结了一条成本经验线——如果一条数据只用一次、且对质量要求是可用即可别上复杂管线如果数据会进核心训练集、影响模型的关键能力再把 agentic 的评审重写闭环跑起来。数据管线本身也需要分层设计不是越复杂越好而是该重的重、该轻的轻。