Agentic数据流水线:从SFT到RL的训练数据合成与清洗实战
最近几个月我一直在折腾一件事怎么用 agentic 的方式去合成和清洗训练数据覆盖 SFT、mid-training、RL 三个阶段。起因倒不复杂——之前做数据标注几十人的团队铺开一天产出也就几万条质量还得靠人工抽检兜底改成用大模型当数据工人以后我发现自己更像是带实习生团队的组长给规则、配工具、盯产出、抽烂尾。这篇把这段时间的尝试、踩坑和沉淀下来的方法做个系统梳理给准备在数据环节上换打法的朋友做个参考。先说清楚一个边界agentic 不是把数据丢给 ChatGPT 让它批量生成就完事而是围绕理解数据—设计任务—执行处理—质量自检—人工抽检这条链用具备规划、调用工具、自我校验能力的智能体流程来替代固定脚本。我试过最朴素的 prompt 批量清洗也试过框架化的多 agent 协作最后的结论是方向完全正确但魔鬼全在细节里。1. 从规则脚本到智能体流水线数据工程为什么换打法在做 agentic 改造之前我先把传统数据管线的痛点摆到桌面上。不是规则脚本不好了而是它处理不了几类高频问题这几类问题恰好卡住了 SFT、mid-training、RL 这三个场景的数据咽喉。1.1 规则清洗的三个硬边界第一类是规则写不全。清洗脏数据时最常遇到的是语义层面的问题比如一份来自社区的中文语料里面有yyds这类的网络用语旁边的标注是夸奖还是讽刺正则表达式很难回答这个问题。区分苹果(水果)和苹果(公司)需要上下文去重时今天天气真不错和今儿天气挺好到底算不算一条重复数据规则只能靠字符相似度去猜猜错率不低。第二类是领域知识进不去。举个例子做中医药问答模型的训练数据里面气虚血瘀和气血两虚在语义上有关联但不完全相同需要判断数据是否适合某个特定训练阶段时纯规则没有办法做这种判断。热搜词里那些mmrotate训练dota数据集bevfusion训练数据坐标标定的搜索本质上也是同一个问题——垂直场景的数据只有懂场景的人或模型才知道什么是好。第三类是回流改进成本高。规则清洗发现问题改的是正则、查的是黑名单每加一条规则就要回归一遍全部数据几轮之后规则集变成一坨谁也不敢动的代码。这种状态下做 10 万条 SFT 数据的清洗迭代到第五轮基本就推不动了。1.2 agentic 方案的逻辑支点agentic 思路之所以能解这三个问题靠的不是更长的 prompt而是三个结构性变化从一次性执行变成循环思考-行动-观察agent 可以对每条数据做多步处理。比如先判断数据领域再选择清洗策略清洗后自己检查一遍不满意就重来。这个循环能把很多隐性质量问题的发现过程自动化。从写死规则变成可插拔工具代码、检索、schema 校验、相似度计算都包装成工具agent 判断这里需要去重就调用去重工具判断这里疑似缺字段就调用 field 补全工具而不是靠一段 if-else 走天下。从人盯规则变成人盯目标把质量目标交给 agent比如去除语义重复但保留领域术语多样性让它自己拆解步骤。拆得不对也没关系因为你可以从 trace 里看到它为什么错比调正则可解释得多。这不是说规则脚本就该被淘汰。我在实际跑管线时第一道过滤仍然是规则纯长度过滤、URL 剔除、乱码检测、敏感词匹配这些用规则又快又便宜。agent 只在规则处理不了的地方介入——一句话总结就是规则做粗筛agent 做精修。1.3 什么时候才值得上 agentic也不是所有数据任务都适合 agentic。我自己给了一个判断标准数据量在万级以下、内容高度结构化比如从数据库导出的字段直接用脚本数据量几万到几十万、语义复杂程度高对话、长文、跨领域agentic 清洗/合成的性价比开始显现数据量到百万级就要考虑先聚类抽样对代表样本做 agentic 处理学习模式再回灌规则批量处理而不是让 agent 一条条跑全量。这个选择和模型选型类似小问题用重武器只会拖慢节奏、烧掉预算。2. 一个 agentic 数据团队的最小可跑架构如果你也想搭一套 agentic 数据管线我建议不要一开始就上那些重框架先搭一个最小可跑版本跑通之后再逐步加角色。下面是我实际在用的一套结构。2.1 四个角色对应四道工序我把 agent 拆成四个角色每个角色只干一件事通过任务队列串联而不是一个 agent 干完全程。这样每个环节可以单独迭代、单独抽检出问题定位也快。规划器Planner读入原始数据样本做初步判断决定这批数据该走清洗、合成、还是混合路线把任务拆解成子任务下发给执行器。执行器Worker真正干活的部分。按规划器的指令处理数据调用工具产出中间结果。同一个执行器角色下可以挂多个专门化的实例比如改写器扩写器翻译器格式规整器。质检器Critic对执行器产出的每条数据打分并给出修改建议。它是最关键的兜底网负责发现语义重复、逻辑矛盾、语言堆砌等问题。仲裁器Reviewer汇总质检结果决定放行/返工/丢弃并把返工原因写清楚回传给执行器形成闭环。这个结构的核心不是角色多而是质量和生产分离。如果让同一个 agent 既生产又质检它很容易自我感觉良好错误会成批放行——这一点后面讲质量时还会展开。2.2 工具层的三个必备件执行器手里的工具决定了它能处理的任务上限。我实践下来最先需要补齐的三个工具是数据操作工具去重、聚类、关键词抽取、格式转换。这些用代码实现再以工具函数暴露给 agent让它按需调用。检索工具对于专业知识类数据agent 在改写时需要查询领域知识库。比如清洗医疗问答数据时它可以查一个权威术语库来确认辨证和辩证哪一个在语境里是正确的。自检工具包括困惑度计算、文本熵值、N-gram 重复率、embedding 相似度。这些指标质检器在打分时可以直接调用作为客观证据而不是主观感觉。工具接口要尽量单一、文档化。我踩过的一个坑是工具参数设计得太复杂agent 频繁调用失败最后不是提升质量而是浪费时间。后来把所有工具的参数都约束在 2-3 个以内调用成功率立刻上去了。2.3 最小实现一个清洗 agent 的骨架这是我在项目里用的清洗 agent核心循环用伪代码表达的逻辑如下def clean_agent(record, tools, max_steps5): context { raw: record, plan: None, tool_observations: [], issues: [] } for step in range(max_steps): action planner_llm(context) # action 可能为: call_tool, rewrite, self_check, finish if action[type] call_tool: result call_tool(action[tool_name], record) context[tool_observations].append(result) elif action[type] rewrite: context[cleaned] rewrite_llm(record, context[tool_observations]) elif action[type] self_check: issues critic_llm(context[cleaned]) context[issues] issues if not issues and quality_gate(context[cleaned]): return context[cleaned] # 质检通过 # 超过 max_steps 强制退出防止死循环 return None # 返回 None 表示处理失败走丢弃或标记人工复核这里用max_steps5做轮次上限不是拍脑袋定的。我试过 3 步很多数据来不及完成清洗-自检-二次修改的完整闭环试过 10 步token 成本暴涨还出现 agent 反复修改同一句话的振荡现象。5 步是一个覆盖绝大多数干净样本的甜点值。一个清洗 agent 的 system prompt 骨架大致长这样你是一个严谨的中文训练数据清洗员。你的工作目标是在保持原始语义不变的前提下修正以下问题 1. 去除口语化填充词如嗯嗯那个那个 2. 修正明显的语法错误和不完整句子 3. 统一数字、单位、专有名词的写法 4. 删除与主题无关的重复表述 规则 - 不得改变事实性内容如日期、数字、专有名词含义 - 不得添加原始文本没有的信息 - 如果原始文本过于混乱输出UNK并在 issues 字段说明原因 在处理前先观察是否需要用工具做去重或术语校验。注意 prompt 里写不得添加原始文本没有的信息这是清洗和合成的分界线。后面的合成任务会换一套完全不同的 prompt。2.4 用 trace 追踪替代黑盒信任Agentic 流水线和规则脚本最大的不同是每条数据都留下一份可以查看的操作轨迹trace包括它调用了哪些工具、观察到了什么、做了哪些修改、质检器提了什么意见。这个 trace 不是给机器看的是给人看的。实际操作中我会定期从 trace 里抽样看看agent 的思考是不是合理。有一次我发现大量数据的处理路径都是直接调用了改写工具而没有先做问题判断说明规划器变懒了其实就是模型上下文太长导致它倾向于省事。发现后我在 prompt 里加了一条强制约束必须明确指出你识别到的具体问题再决定是否改写这个问题就缓解了。3. 三个训练阶段对数据的不同口味SFT、mid-training、RL 各需要什么顺着标题走合成和清洗策略必须跟着训练阶段走。同一个 agent 架构在 SFT、mid-training、RL 三个阶段的任务配置完全不同。3.1 SFT 阶段重指令质量agent 做精修和扩写SFT 数据最核心的要求是对齐指令遵循能力所以数据的重心不在量大而在多样性和单条质量。这里 agent 最擅长做三件事指令改写把网上的文章、问答、社区内容改写成符合 SFT 格式的指令-回答对。比如一篇技术博客里的一段解释改写成一个请解释什么是 RoPE的问题加一个结构化回答。指令扩写一个原始问题扩写成多个变体提升指令多样性。比如怎么清洗训练数据可以扩写成你在准备 SFT 数据时怎么处理低质量文本如何过滤掉语义重复的样本用词不同但意图域相同。回答规整原文答案可能口语化、发散需要规整成结构清晰、用词准确、长度适中的标准回答。这一步要注意别过度规整把原本的自然表达改成一股 AI 味——这是合成数据最容易出现的灾难后面重点讲。SFT 阶段我用的质量指标是指令多样性 回答自然度 事实一致性三方去平衡。agent 质检器打分时这三个维度各占权重低于阈值就返工。3.2 mid-training 阶段重领域丰富agent 做过滤和配平mid-training也有人叫 continued pretraining 或 domain adaptation的目的是让模型在特定领域获得更充分的语料分布覆盖。这个阶段对单条数据的精致度要求不高但对语料整体的纯净度和分布配比要求高。Agent 在这个阶段有两个关键任务领域过滤判断一条语料是否真的属于目标领域。比如你在做中医问答模型一篇健身博主写的气血不足怎么办就不一定符合医学语料标准。用关键词可以粗筛但 agent 能做语义层面的判断准确率明显更高。去重配平mid-training 语料最忌大量重复模板。Agent 可以对一批语料做聚类分析发现密集重复的主题/句式区块再通过工具采样实现配平防止某一种表述方式在训练语料里占比过高。mid-training 阶段有一个和 SFT 相反的注意点不要过度清洗。如果每一条语料都被 agent 改写成通顺规范的标准文本等于人为压缩了语料多样性模型在这个领域的泛化能力会被削弱。我给清洗 agent 的 mid-training 版本 prompt 里专门加了一句如果原始文本符合领域要求且无事实性错误尽量原样保留不做润色。这一点太重要了我之前吃过大亏后面细讲。3.3 RL 阶段重偏好数据agent 做对比和判据RL尤其是 RLHF/DPO 这类需要偏好标注的阶段消耗的数据形态是好-坏对或者排序序列。Agent 在这里的作用不是生成新数据而是生成和判断偏好。偏好判据生成给定一个 promptagent 生成多个候选回答并配上为什么这个回答优于另一个的判据。比如回答 A 结构清晰直接给出了操作步骤回答 B 虽然在讲同一件事但夹杂了大量背景介绍回答效率低。这样生成的 not 只是排序结果还附带解释后续可以直接用来训练奖励模型。困难样本挖掘利用 agent 对数据的理解筛选模型当前最容易犯错的区域。一种做法是把模型对某类 prompt 的输出和 SFT 标准答案做比对让 agent 找出差异并判断模型错在哪批量形成偏好样本。这是我认为 agentic 在 RL 阶段最有价值的地方——它把被动标注变成了主动找茬。拒绝采样辅助在 RL 训练中经常要跑一个采样-筛选循环agent 可以作为筛子快速从模型的大量采样输出中挑出可用的作答组合。比纯规则厚实比人工快得多。训练阶段核心目标Agent 主要任务单条质量关注点数据量级偏好SFT指令遵循能力改写、扩写、规整指令多样性、自然度、事实一致性万级重质量mid-training领域分布适配过滤、去重、配平领域相关性、分布多样性、不过度规整十万至百万级重覆盖RL偏好对齐偏好判据、困难挖掘、拒绝采样排序合理性、判据可解释性千至万级重对比质量4. 质量红线agentic 清洗不是全自动放手很多文章把 agentic 数据管线描述成设置好就跑睡一觉起来数据就干净了。我的实际经验不是这样。Agent 产出质量波动的剧烈程度超出大多数人预期它更像一个聪明但偶尔会犯懒、会幻觉的实习生必须有硬红线兜底。4.1 合成数据的三类隐形污染第一类模板化复读。Agent 合成数据时非常容易出现句式趋同比如所有的 SFT 回答都用首先、其次、最后三段式或者所有清洗后的文本都变成进行了一个...的操作。用 N-gram 重复率能检测一部分但更隐蔽的是语义层面的复读——看起来句子不同内核全是如何做数据分析的同一套路。我是用 embedding 向量做聚类检测出来的一堆合成数据聚成一团就意味着多样性崩了。第二类幻觉美化。清洗 agent 在修正文本时为了让它更通顺擅自补充了原文没有的信息尤其容易出现在专业领域。比如医学文本清洗agent 在患者自述胸口疼痛后面补了一句需排除心肌梗死风险这句话本身对但不是原始数据的内容。我用事实一致性检查工具拦截这一类问题方法是把 modifier 和原始文本做 entailment 比对不一致就打回。清洗任务里最常见的就是这个错误——它远比合成任务里的幻觉更难防因为清洗 agent 的本职工作就是改句子。第三类分布扭曲。Mid-training 语料被 agent 统一改写后原本丰富的口语表达全被规范化了。最极端的例子我把一批客服对话语料全部规整成书面语后下游任务里模型对口语问法的理解能力反而下降了。这直接证明了清洗过度比清洗不足更伤数据。4.2 分层质检别指望单一大模型当裁判我使用的质检体系分三层从便宜到贵依次执行规则层零成本长度、格式、去重哈希、敏感词、标点符号异常。这层能拦掉 20%-30% 的明显问题数据速度极快。小模型层低成本用一个 7B 级别的开源模型做初筛判断数据是否有前后矛盾、是否偏离任务要求、是否包含幻觉标记。它比大模型便宜很多能分担掉 40% 以上的常规坏样本。大模型层高成本只做抽检对前两层通过的样本按 5%-10% 比例抽样用强模型做深度质检给出细粒度评分和修改建议再人工复核。这套漏斗式质检是我优化成本的关键。如果全部用大模型逐条质检token 消耗会比清洗本身还贵几倍所以必须让便宜层先兜底。人工的介入点不是逐条审核而是定期查看抽样和大模型的判据校准各层的阈值。4.3 给每条数据打生产路径标签Agentic 管线处理过的数据我会强制要求每条输出都带上生产路径标签类似这样path: rewrite-v3 | tools: [term_check, dedup] | critic_score: 0.92 | steps: 4这个 tag 的价值在训练阶段才显现当模型在评测集上表现异常时我能回溯这批训练数据是被哪一层、哪个版本、什么工具处理过的再快速锁定可疑批次做线下 review。没有这个 tag十几万条数据出了问题你只能干瞪眼。我还经历过一个具体的 RL 任务用 agentic 合成了一批偏好数据模型训练后出现了一个诡异现象——对任何 prompt只要回答里带了结构化步骤编号就倾向给高分不管内容对不对。最后的根因就是合成偏好数据时agent 在好回答里高频使用了第一、第二、第三的格式奖励模型把格式偏好学成了内容偏好。这就是合成数据里风格特征被误当语义特征的典型事故而生产路径标签帮我快速定位到了那批数据的合成 prompt避免了大范围回滚。4.4 黄金集管线质量的唯一标尺为了不让每一轮 agent 改动都变成盲调我维护了一个固定的小型黄金集大约 500 条覆盖各任务的典型难度。任何 agent 版本、任意 prompt 改动上线前先拿黄金集跑一遍对比 precision、recall、语义保持率等指标。黄金集跑不过就不上全量。这个习惯帮我避免了很多次拍脑袋优化。之前我觉得某个清洗 prompt 里的让它更简洁不够具体就改成了删除超过 25 字的从句结果线上表现看着是变好了输出更短黄金集一测事实保留率从 92% 掉到了 74%——因为很多关键细节恰恰在长从句里。没有黄金集这种回归可能要等训练完才发现。5. 实测数据成本构成、踩坑记录与参数经验这部分把我在真实跑批中积累的工程细节直接放出来方便你评估要不要用同样方案。5.1 Token 成本怎么算才不失控Agentic 管线的 token 消耗远比一条 prompt 生成一条结果要高因为每个 agent 内部是多轮思考、工具调用、自检返工。以 SFT 清洗 10 万条文本为例我的实测平均成本构成环节平均输入 token/条平均输出 token/条占比说明规划器判断900120需要读入原文和元信息执行器改写1200400多轮重写会让输出翻倍质检器评分1100150输出虽短但要看原文改写结果返工追加约 800200约 25% 数据会经历一次返工工具调用开销30050工具结果需要重新喂回上下文合计单条约 5000 token 输入、900 token 输出。按当前主流大模型 API 的定价粗算10 万条大约花费小几千元级别的人民币。如果你第一批跑完觉得价格高最有效的降本手段不是换更便宜的模型而是提高一次通过率。把质检器给的返工原因累计起来持续改进执行器的 prompt让返工率从 25% 降到 15%成本立刻下降约 15%再配合设立规则层拦掉本来就该删的数据大概能省 10% 的调用量整体成本可以压到接近原来的一半。5.2 并发、缓存和重试工程上的三个坑并发控制别把一个批次几万条一次性全丢进 agent 池。我用的滑动窗口是 500 条一个 batch每批结束后统计质检通过率低于阈值就暂停回头检查 prompt 或数据源。全量跑完才发现问题返工成本太高。命中缓存同一条数据在清洗和质检阶段会被重复读取多次。我在中间层加了一个简单的 key-value 缓存以文本哈希为 key 存工具的中间结果尤其是 embedding、去重结果这类计算贵的产物至少省掉了 25% 的重复计算。重试策略Agent 偶发调用超时或格式异常是常态。阈值设 3 次超过就标记为人工复核而不是无限重试。无限重试不仅烧钱还会让整个管道卡死在一个坏数据上。5.3 开源模型跑 agentic 管线的真实差距预算紧张时我也尝试过纯粹用开源模型搭全套 agentic 管线。结论是可行但需要非常精细的 prompt 和更严的兜底。开源 7B 级别模型在规划这个环节的表现最弱。它经常把任务拆得过于琐碎或者跳过必要的工具调用直接改写。我的折衷方案是规划器用大模型 API执行器和质检器用开源模型。因为执行器任务相对明确在给定的规范下改写、扩写开源模型能胜任质检器用开源模型时需要把评分维度切得更细分开问多次比如这段文本是否有事实性错误单独问一次是否语言堆砌再单独问一次不要让它一次输出综合评分一旦合并它就开始和稀泥。另外开源模型跑 agentic 管线时的返工率通常更高我实测大约在 35%-45% 之间。这个数字意味着 token 成本的优势会被稀释掉一部分最后总成本大概是大模型方案的 50%-60%质量上会比大模型方案低一档。如果你的数据容错率低比如 RL 偏好数据建议不要省这个钱如果是 mid-training 粗过滤开源模型完全够用。5.4 多语言与垂直场景的适配经验我在处理非英语数据时发现agentic 管线的语言适配问题比想象中更隐蔽。清洗 agent 在改写中文数据时经常把分词风格改掉比如把做数据清洗/建训练集改成进行数据清洗并构建训练集表面更书面但语料里原本的口语特点和断句节奏被抹平了。后来我在 prompt 里明确写保留原文的语体风格不要做语体转换只做必要修正。对多语言混合文本还加了一步语言识别工具让 agent 先判断语言再决定处理策略不然中英混杂的语义会被单语 agent 误伤。垂直场景的另一个问题是术语处理。我见过一个项目用通用 agent 清洗水利工程语料结果 agent 把闸门开度这类专业术语当作不规范表达统一替换成门打开的程度语义全变。解决方案是任何垂直领域的清洗任务先建一个术语白名单把领域专有名词、缩写、惯用组合喂给 agent 作为不可变项。这个白名单用人工整理加自动抽取从语料里统计高频 n-gram结合几百条起步就能明显降低误伤率。5.5 几个改动前要想清楚的问题给 prompt 加任何一条规则时先问自己三个问题这条规则会不会过滤掉我们其实需要的多样性会不会引入新的格式偏好能不能用工具实现而不是用提示词靠自觉实现我踩过最深的一个坑就是加了一条回答要专业严谨直接导致合成答案全部变成一种腔调训练完模型说话像自动生成的 FAQ幽默感全无。后来把规则改成在保持信息准确的前提下允许不同的表达风格这个问题才缓解。跑 agentic 数据管线时间长了我有一个明显的体感转变以前做数据是写代码筛数据现在是带团队出数据。Agent 确实比规则脚本聪明得多但它同样会自作聪明。你必须给它明确的目标边界、可靠的工具、可见的 trace、以及随时校准质量标尺的机制。把这四件事做好agentic 合成的数据才能真正顶上去而不是把一堆看起来像样的垃圾倒进训练流程。如果你手头也正被数据质量不稳、清洗规则越改越乱、合成数据一股 AI 味这些问题缠着我建议你先选一个 1 万条以内的小批次按上面这套最小架构跑一遍对比一下黄金集指标、成本、返工率这几个数你会对这个打法值不值得铺开有自己的判断。