ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Agentic合成数据流水线:SFT、mid-training与RL三阶段实战

Agentic合成数据流水线:SFT、mid-training与RL三阶段实战 1. 为什么“合成数据”这件事值得单独拎出来讲做模型训练的人都有一个共同的体感模型能力的上限往往不是被算法卡住的而是被数据卡住的。尤其是当你已经跑通了 SFT监督微调准备往 mid-training中期训练和 RL强化学习阶段推进时你会发现一个很尴尬的现实——公开数据集不够用业务数据又脏又少人工标注成本高得离谱而且标注质量还参差不齐。我最近几个月一直在折腾一套agentic 方式的数据合成与清洗流水线核心思路很简单把“造数据”这件事本身交给一组有分工、有工具、有反馈回路的智能体去干而不是靠一条写死的脚本从头跑到尾。这套东西覆盖了 SFT、mid-training、RL 三个阶段的训练数据需求从原始语料进来到最终能直接喂给训练框架的干净样本出去中间的所有环节都由 agent 编排。这篇文章我会把这套流水线完整拆开讲为什么这么设计、每个环节怎么落地、参数怎么定、坑在哪里、怎么排查。适合已经有一定训练经验、正在被数据问题折磨的同行参考也适合刚接触 agentic 思路、想看看它到底能落地到什么程度的朋友。我不会只讲概念会把能直接抄的配置和步骤都放出来。先说结论性的判断agentic 合成数据的价值不在于“自动化”而在于“可迭代”。传统脚本流水线一旦跑完你很难知道哪条数据好、哪条数据坏而 agentic 流水线里每个环节都有评估和回写机制数据质量是可以被持续优化的。这一点在 RL 阶段尤其关键因为 RL 对数据分布和难度的敏感度远高于 SFT。2. 整体架构设计三个阶段的数据到底差在哪2.1 SFT、mid-training、RL 对数据的诉求差异很多人把这三个阶段的数据混着用结果就是 SFT 学得还行一到 RL 就崩。根本原因是三个阶段对数据的要求完全不同我整理了一张对照表阶段数据核心诉求样本形态质量容忍度典型规模SFT指令-回复对齐、格式规范单轮/多轮对话中等格式必须严万级到十万级mid-training领域知识注入、能力打底长文本、结构化语料较高噪声可容忍十万到百万级RL难度分层、可验证奖励prompt 可判定答案极高错一条毁一批千级到万级SFT 阶段最怕的是格式不统一你混进去几种不同的对话模板模型学出来的输出就会飘。mid-training 阶段最怕的是领域覆盖不全你喂的全是通用语料模型在你的垂直领域就是外行。RL 阶段最怕的是奖励信号不可靠一条标注错误的样本可能让整个策略跑偏。所以这套 agentic 流水线的第一件事就是按阶段分流。原始语料进来之后先过一个分类 agent判断这批数据更适合哪个阶段然后走不同的合成和清洗分支。这个判断不是拍脑袋而是基于几个可量化的信号文本长度分布、是否含可验证答案、领域标签密度、指令密度。2.2 为什么用 agentic 而不是传统 ETL 脚本传统 ETL 脚本的问题在于它是单向的读数据、处理、写数据中间没有反馈。你写了一个清洗规则它就把所有数据按这个规则过一遍至于清洗完的数据质量如何脚本自己不知道。agentic 方式的核心区别是引入了角色分工和反馈回路。我这条流水线里主要有四类 agent规划 agentPlanner负责拆解任务决定这批数据走哪条分支调用哪些工具。执行 agentExecutor负责实际的数据合成、改写、扩增。评估 agentCritic负责给生成的数据打分判断是否达标。修复 agentFixer负责把不达标的数据打回重做或者直接丢弃。这四类 agent 之间通过一个共享的数据状态表通信每条数据都有自己的状态字段raw → planned → synthesized → evaluated → passed/rejected → fixed。这样整条流水线就是可观测、可回溯的哪条数据在哪个环节卡住了一目了然。提示不要一上来就把四类 agent 全用上。我建议先用 Planner Executor 跑通主流程等数据量上来了、问题暴露出来了再补 Critic 和 Fixer。过早引入评估环节会让流水线变得很重调试成本陡增。2.3 流水线的整体数据流整条流水线的数据流大致是这样的原始语料先做去重和基础清洗这一步用传统脚本就行没必要上 agent然后进入分流判断接着按阶段走不同的合成路径合成完的数据统一进入质量评估评估通过的写入最终数据集不通过的进入修复队列修复两次还不行的直接丢弃。这里有个经验值修复队列的规模控制在总数据量的 15% 以内比较健康。如果超过 30%说明你的合成 prompt 或者评估标准有问题应该回头调 prompt而不是让 Fixer 硬扛。我一开始没注意这个比例结果 Fixer 队列堆了几十万条跑了两天才清完纯属浪费算力。3. 核心环节拆解合成、清洗、评估怎么落地3.1 合成环节让 agent 学会“按需造数据”合成环节的核心不是让 agent 随便生成文本而是让它带着约束生成。我在 Executor 的 prompt 里固定了几个约束维度领域约束这批数据属于哪个垂直领域必须用该领域的术语和表达习惯。难度约束目标难度等级简单/中等/困难通过控制推理步数和干扰项数量来实现。格式约束输出必须符合指定的对话模板包括 system prompt、user turn、assistant turn 的结构。多样性约束同一批数据里句式、场景、提问角度要有差异避免模型学到模板化表达。具体实现上我用了一个种子扩增的策略。先人工准备一小批高质量种子样本每个阶段 50 到 100 条然后让 Executor 基于种子做变体生成。变体的方式包括换场景、换问法、增加推理步骤、引入干扰信息、改变输出格式要求。这里有个关键参数每条种子扩增多少条变体。我的经验是 SFT 阶段 1:20 到 1:50mid-training 阶段 1:100 到 1:200RL 阶段 1:10 到 1:30。RL 阶段比例最低因为 RL 数据对质量要求最高扩增太多容易引入噪声。# 种子扩增的核心配置示例 expansion_config { sft: {ratio: 30, difficulty_levels: [easy, medium], format_strict: True}, mid_training: {ratio: 150, difficulty_levels: [medium], format_strict: False}, rl: {ratio: 20, difficulty_levels: [medium, hard], format_strict: True} }3.2 清洗环节规则和模型双管齐下清洗这件事纯靠规则会漏纯靠模型会误杀。我的做法是规则先过一遍粗筛模型再过一遍精筛。粗筛规则包括长度过滤太短太长都丢、重复检测精确去重 近似去重、敏感词过滤、格式校验JSON 能不能解析、字段全不全。这一步能干掉 40% 到 60% 的脏数据成本极低。精筛用一个小模型做质量打分打分维度包括流畅度、信息密度、指令遵循度、事实一致性。这里的事实一致性检查很关键尤其是 mid-training 阶段的领域语料如果 agent 合成的时候编造了不存在的事实模型学进去就是灾难。我的做法是让 Critic agent 对每条数据做一次自洽性检查把数据里的关键断言抽出来看能不能在原始语料里找到支撑找不到的就标记为待核实。注意事实一致性检查不要追求 100% 准确那样成本太高。我的标准是关键断言必须有支撑次要细节允许合理演绎。这个度需要根据你的领域来调医疗、法律这类领域要严创意、营销类可以松。3.3 评估环节怎么给合成数据打分评估是整条流水线里最难的部分因为你要让机器判断“这条数据好不好”。我的评估体系分三层第一层是硬性规则比如格式对不对、长度在不在范围内、有没有敏感内容。这层是布尔判断不通过直接拒。第二层是模型打分用一个经过微调的评估模型对数据的质量、难度、多样性打分输出 1 到 5 分。这层的阈值我设的是 3.5 分低于这个分的进修复队列。第三层是抽样人工复核每天从通过的数据里随机抽 1% 到 2% 做人工检查用来校准模型打分的偏差。这一步不能省因为模型打分本身也会漂没有人工校准跑一周之后评估标准就偏了。评估层级判断方式通过标准成本硬性规则布尔判断全部满足极低模型打分1-5 分≥3.5 分中等人工复核抽样检查偏差5%高3.4 修复环节打回重做还是直接丢弃修复环节的策略直接决定了流水线的效率。我的原则是能修则修修不好就丢不要恋战。可修复的问题包括格式错误、长度不达标、多样性不足、难度偏差。这类问题让 Fixer agent 带着具体的修改指令重做一遍通常一次就能过。不可修复的问题包括事实性错误、逻辑矛盾、敏感内容。这类直接丢弃不要试图修复因为修复成本高于重新合成。这里有个实操技巧给每条数据记录修复次数修复超过两次的直接丢弃。我见过有些数据被反复修复五六次最后改得面目全非还不如重新生成一条。修复次数这个字段在数据状态表里一定要有方便后续分析。4. 实操过程从零搭一条能跑的流水线4.1 环境准备和依赖选型这套流水线对环境的依赖不算重核心是一个能调模型 API 的客户端 一个任务队列 一个数据存储。我的选型是这样的模型调用用统一的 LLM 客户端封装支持多模型切换方便对比不同模型在合成和评估上的表现。任务队列用 Redis 做队列Celery 做 worker支持并发和重试。数据存储中间状态用 PostgreSQL最终数据集用 JSONL 文件方便直接喂给训练框架。监控用 Prometheus Grafana 看流水线的吞吐、通过率、修复率。# 核心依赖安装 pip install openai anthropic redis celery psycopg2-binary pip install pandas numpy tqdm选型逻辑说明一下为什么用 Celery 而不是自己写多进程因为 agentic 流水线的任务粒度很细每条数据可能要经过好几个 agent 的处理用 Celery 可以很方便地做任务编排、失败重试、优先级调度。自己写多进程的话这些都要重新造轮子不划算。4.2 数据状态表的设计数据状态表是整条流水线的中枢设计得好不好直接决定了可观测性。我的表结构大致是这样CREATE TABLE data_pipeline ( id BIGSERIAL PRIMARY KEY, raw_content TEXT, stage VARCHAR(20), -- sft / mid_training / rl status VARCHAR(20), -- raw / planned / synthesized / evaluated / passed / rejected / fixed quality_score FLOAT, difficulty VARCHAR(10), fix_count INT DEFAULT 0, created_at TIMESTAMP DEFAULT NOW(), updated_at TIMESTAMP DEFAULT NOW(), metadata JSONB );metadata字段用 JSONB 存一些灵活的信息比如合成时用的种子 ID、评估时的详细打分、修复时的具体指令。这样后续做数据分析的时候不用改表结构。提示status字段一定要建索引因为流水线里大量的查询都是按状态过滤的。我一开始没建索引数据量到十万级之后查询慢得没法看。4.3 合成 agent 的 prompt 设计合成 agent 的 prompt 是整条流水线的灵魂写得好不好直接决定数据质量。我的 prompt 结构分四块角色定义、任务描述、约束条件、输出格式。角色定义要具体不要写“你是一个数据合成助手”这种空话要写“你是一个专注于[领域]的数据合成专家擅长生成符合[格式]要求的训练样本”。任务描述要包含输入是什么、要做什么、输出是什么。比如“基于以下种子样本生成 20 条变体变体需要在场景、问法、难度上有所差异”。约束条件是最关键的部分要把所有硬性要求列清楚包括长度范围、格式要求、禁止出现的内容、多样性要求。输出格式要给出明确的 schema最好带一个示例这样 agent 输出的数据可以直接被解析。SYNTHESIS_PROMPT 你是一个专注于{domain}领域的数据合成专家。 任务基于以下种子样本生成{count}条变体样本。 种子样本 {seed} 约束条件 1. 每条变体必须在场景、问法或难度上与种子有差异 2. 输出长度在{min_len}到{max_len}字之间 3. 必须符合以下对话格式{format_spec} 4. 禁止出现以下内容{forbidden} 5. 难度分布{difficulty_dist} 输出格式JSON数组 [{{instruction: ..., response: ..., difficulty: ..., scenario: ...}}] 4.4 评估 agent 的打分逻辑评估 agent 的打分逻辑要尽量可解释不能只给一个分数要给出打分的理由。这样后续分析的时候才知道为什么这批数据通过率低。我的评估 prompt 要求 agent 从四个维度打分每个维度 1 到 5 分最后取加权平均流畅度语言是否自然有没有明显的机器味。信息密度单位长度内包含的有效信息量。指令遵循度是否严格按照要求生成。事实一致性关键断言是否有支撑。权重设置上SFT 阶段指令遵循度权重最高0.4mid-training 阶段信息密度权重最高0.4RL 阶段事实一致性权重最高0.5。这个权重不是拍脑袋定的是根据各阶段最容易出问题的环节来调的。4.5 跑通第一条数据的完整记录我第一次跑通流水线的时候用了一条种子样本走完了全流程。记录一下关键节点原始种子是一条 SFT 样本长度 200 字左右。Planner 判断走 SFT 分支Executor 扩增出 30 条变体耗时约 90 秒。评估环节 28 条通过2 条因为长度不达标进修复队列。Fixer 修复后 1 条通过1 条丢弃。最终产出 29 条可用数据通过率 96.7%。这个通过率看起来很高但这是因为种子质量好。实际跑大批量数据的时候通过率通常在 70% 到 85% 之间。如果低于 60%就要检查 prompt 或者评估标准了。5. 常见问题与排查技巧实录5.1 合成数据“机器味”太重怎么办这是最常见的问题agent 生成的数据读起来就是一股 AI 味句式雷同、用词重复、缺乏真实感。我的解决办法有三个第一在 prompt 里加入风格约束明确要求“避免使用‘首先、其次、最后’这类模板化连接词”、“句式要有多样性长短句交替”。第二用真实数据做 few-shot 示例不要只给种子样本还要给几条真实的人工样本作为风格参考。第三引入风格评估维度让 Critic agent 专门判断“这条数据读起来像不像人写的”不像的打回重做。实测下来这三个措施一起上机器味能降低 60% 以上。但要注意风格约束不能太严否则 agent 会为了追求“像人写的”而牺牲信息量。5.2 评估标准漂移怎么发现和纠正评估标准漂移是个隐蔽的问题表现是流水线跑了一周之后通过率突然变高或变低但数据质量其实没变。原因是评估模型的标准在不知不觉中偏了。发现漂移的方法是固定一批“锚点数据”这批数据的质量是人工确认过的每天让评估 agent 给它们打分看分数有没有变化。如果锚点数据的分数波动超过 0.3 分说明评估标准漂了需要重新校准。纠正的方法是用锚点数据重新微调评估模型或者在评估 prompt 里加入更明确的打分标准。我一般每周校准一次跑大批量数据的时候每天校准。5.3 修复队列堆积怎么处理修复队列堆积通常有三个原因合成 prompt 有问题导致大量数据不达标、评估标准过严、Fixer 处理速度跟不上。排查顺序是先看修复原因分布如果集中在某一类问题上说明是合成 prompt 的问题改 prompt 比让 Fixer 硬修更有效。如果原因很分散说明评估标准可能过严适当放宽阈值。如果前两个都没问题那就是 Fixer 的并发不够加 worker 就行。问题现象可能原因排查方法解决措施修复队列堆积合成 prompt 有问题看修复原因分布改 prompt修复队列堆积评估标准过严看通过率趋势放宽阈值修复队列堆积Fixer 并发不足看队列消费速度加 worker通过率突然下降评估标准漂移看锚点数据分数重新校准通过率突然下降上游数据变脏看原始数据质量加强粗筛5.4 几个我踩过的坑坑一不要用同一个模型做合成和评估。我一开始图省事合成和评估都用同一个模型结果就是模型自己觉得自己生成的数据很好通过率虚高实际质量很差。后来换成两个不同的模型评估才靠谱。坑二不要忽略数据的难度分布。我有一批数据全是简单样本模型在 SFT 阶段学得很快但一到 RL 阶段就崩了因为没见过难题。后来在合成环节强制要求难度分布简单、中等、困难按 3:5:2 的比例来问题才解决。坑三不要一次性合成太多数据。我试过一次合成十万条结果评估环节跑了整整一天中间发现 prompt 有问题想改都来不及。后来改成小批量迭代每批 5000 条跑完评估看效果有问题马上改效率高很多。坑四数据状态表一定要有 updated_at 字段。这个字段看起来不起眼但排查问题的时候特别有用。比如你想知道某批数据在评估环节卡了多久直接查 updated_at 和 created_at 的差值就行。5.5 性能优化的几个实操技巧流水线跑起来之后性能优化主要从三个方向入手并发控制模型 API 的并发不是越高越好太高了会被限流反而拖慢整体速度。我的经验是并发数控制在 API 限流的 70% 左右比较稳。批量处理评估环节可以批量做一次给 agent 10 条数据让它一起打分比一条一条打分快很多。但批量不能太大超过 20 条 agent 的打分质量会下降。缓存复用相同的种子样本扩增出来的变体评估结果可以缓存。如果两条数据的相似度超过 0.95直接复用评估结果不用重新打分。这个优化能省 20% 到 30% 的评估成本。6. 三个阶段的差异化配置建议6.1 SFT 阶段格式优先多样性其次SFT 阶段的数据配置我的建议是格式严格度拉满多样性适度。因为 SFT 的核心是让模型学会“怎么回答”格式不对的话模型学出来的输出就没法用。具体配置格式校验用最严的标准任何字段缺失或格式错误直接拒多样性要求可以放宽同一类问题有几种不同的问法就行难度以简单和中等为主困难样本占比不超过 20%。合成比例上SFT 阶段我建议种子和变体的比例控制在 1:30 左右。太高了多样性会下降太低了数据量不够。6.2 mid-training 阶段知识密度优先格式可以松mid-training 阶段的核心是注入领域知识所以数据配置的重点是知识密度和领域覆盖度。格式要求可以适当放宽因为 mid-training 的数据形态本来就比较多样长文本、结构化语料、问答对都可以。具体配置信息密度权重调到最高流畅度权重可以降一点领域覆盖度要做检查确保每个子领域都有足够的数据事实一致性检查要严因为 mid-training 的数据会被模型当成知识记住。合成比例上mid-training 阶段可以到 1:150 甚至更高因为长文本的合成成本相对低而且需要的数据量本来就大。6.3 RL 阶段质量优先宁缺毋滥RL 阶段的数据配置我的原则是质量优先宁缺毋滥。RL 对数据的敏感度太高了一条错误的数据可能让整个策略跑偏所以这个阶段的数据量可以少但质量必须高。具体配置事实一致性权重拉到 0.5 以上难度分布要覆盖中等和困难简单样本占比不超过 30%每条数据都要有可验证的答案或奖励信号没有的不要。合成比例上RL 阶段控制在 1:20 左右而且每条数据都要经过人工抽检。这个阶段不要追求数据量追求的是数据质量。注意RL 阶段的数据合成建议用更强的模型来做不要为了省钱用弱模型。弱模型合成的 RL 数据奖励信号往往不可靠训练出来的策略会走偏。7. 我个人的一些实操体会这套流水线我断断续续调了几个月最大的体会是agentic 合成数据的难点不在技术在于“度”的把握。合成太多质量下降评估太严通过率低修复太频繁成本高。每个环节都有一个最优的平衡点而这个平衡点只能靠实际跑数据来摸索。另一个体会是不要指望一套 prompt 打天下。不同领域、不同阶段、不同模型对 prompt 的要求都不一样。我现在的做法是每个领域维护一套独立的 prompt 模板跑之前先小批量测试效果好了再放量。最后分享一个我觉得很实用的小技巧给每条数据打上“来源种子”的标签。这样当某批数据出问题的时候你可以快速定位到是哪条种子扩增出来的然后针对性地调整那条种子的扩增策略。这个标签在数据状态表的 metadata 里加一个字段就行成本很低但排查问题的时候能省很多时间。这套流水线目前还在持续迭代后面我打算把评估环节做得更细引入更多维度的自动检查减少人工抽检的比例。等有新进展了再回来更新。
返回列表