コンテンツにスキップ

篇前导读

大模型在预训练之后,已经具备了较强的语言生成能力,但这并不等于它天然能够稳定完成任务、准确理解要求,或给出符合人类期待的回答。因此,这一部分的核心问题可以概括为:模型为什么会说得对、说得稳、说得像人

其中,“说得对”强调模型能够理解指令、完成任务,并输出正确、相关的内容;“说得稳”强调模型在不同场景、不同输入形式和不同约束条件下,仍能保持一致、可靠、可控的表现;“说得像人”则强调模型的回答不仅正确,还要自然、清晰、有帮助,符合人类偏好与使用习惯。要实现这三个目标,不能只依赖模型本身的参数规模,更需要依赖后训练阶段的数据设计、偏好建模与质量运营。

因此,本部分将围绕大模型后训练中的关键数据问题,建立从 SFT 到偏好再到标注运营的完整链条。首先,通过 SFT 数据设计与指令体系,让模型学会按照要求回答问题,形成基本的任务遵循能力;其次,通过偏好数据与奖励信号,进一步塑造模型的行为风格,使其回答更符合人类偏好与业务目标;最后,通过标注平台、QA体系与数据运营,为高质量数据的生产、评估、迭代与规模化供给提供系统支撑。

这条链条所回答的,不只是“模型如何被训练”,更是“模型为何能够稳定输出高质量回答”。只有把 SFT、偏好对齐和标注运营作为一个连续的数据系统来看,才能真正理解模型能力形成的过程,以及高质量大模型背后的数据工程逻辑。

第12章 SFT数据设计与指令体系

在大模型从“会生成”走向“可用、可控、可部署”的过程中,监督微调(Supervised Fine-Tuning,SFT)承担着一个极其关键但又经常被误解的角色。很多团队把SFT简单理解为“收集一些问答对,然后让模型学着回答”,但在真实工程中,这样的理解远远不够。对于负责指令微调数据设计和标注规范的团队而言,SFT并不是一个单纯的数据整理环节,而是把任务目标、行为边界、输出规范、领域知识、交互风格和系统约束编码进训练样本的过程。它实际上定义了模型在上线前最后一层可显式塑形的“行为壳”。

本章面向负责SFT数据设计、模板编写、标注规范制定、质量验收与版本管理的团队成员,系统讨论SFT的目标、任务分层、指令体系、样本结构、质量评估与行业化落地问题。我们尤其强调一个核心观点:高质量SFT数据集不是若干零散问答的堆积,而是一套面向能力对齐的指令工程系统。它需要以能力覆盖为骨架,以任务模板为载体,以质量闭环为保障,以后续偏好数据和工具调用数据为延伸接口。

从组织协同的角度看,SFT数据建设通常横跨产品、算法、标注、评测、运营和领域专家多个角色。产品团队给出场景目标和上线约束,算法团队定义训练接口和样本形态,标注团队负责模板落地和样本生成,评测团队追踪失败模式,领域专家则保证知识边界与专业口径。只要其中任何一个环节缺位,SFT数据集都可能在表面上“规模很大”,但实际上缺乏结构、缺乏重点,也缺乏可持续演进能力。

因此,本章并不把SFT视为一次性的“数据准备任务”,而是把它看作一个围绕模型行为设计展开的系统工程。这个工程的难点,不在于是否能够快速造出数十万条样本,而在于是否能让这些样本真正构成一套有组织、有层次、有反馈、有版本治理能力的指令体系。只有当SFT数据被当作“模型行为的显式设计文档”来建设时,它才能成为后续偏好对齐、工具调用、Agent轨迹学习和线上反馈迭代的可靠基础。


12.1 SFT 的目标到底是什么

12.1.1 SFT在能力对齐中的位置

如果把大模型训练过程分成几个阶段来看,预训练负责让模型形成广泛的语言统计能力、知识压缩能力和基础推理潜能;SFT负责把这种“潜在能力”变成“可调度能力”;偏好对齐阶段则进一步把“可调度能力”塑造成“更符合人类偏好和平台规则的行为方式”。从这个角度看,SFT是连接“会什么”和“怎么做”的中间层。

很多团队在做SFT时容易陷入两个极端。一个极端是把SFT看得过轻,认为只要预训练模型足够强,随便补一点指令数据就能用了;另一个极端是把SFT看得过重,认为只要SFT数据够多,就能补足模型本身缺失的深层能力。前者低估了行为塑形的难度,后者高估了监督信号对底层能力的重塑能力。更准确的说法是,SFT最擅长做三件事:第一,把已有潜能组织成可调用的任务能力;第二,把回答方式约束到明确、稳定、符合场景要求的轨道上;第三,把任务接口标准化,让模型对输入结构、上下文边界和输出格式形成一致响应。

从训练链条来看,预训练得到的是一个“参数空间中蕴含大量潜能”的基础模型,但这种潜能往往是分散的、模糊的、缺乏行为接口的。模型可能知道很多知识,也具备一定的推理潜力,但并不意味着它在接收到实际业务任务时,就能稳定地给出合适格式、合适语气、合适长度、合适边界的回答。SFT的任务,就是把潜在能力整理成面向任务的行为模式。它不是凭空创造能力,而是让模型“在什么时候,以什么方式,调用哪些已有能力”这件事变得可控。

这也是为什么SFT往往是产品化前不可跳过的一步。一个仅经过预训练的模型,也许在开放式对话中偶尔表现惊艳,但在批量工单分类、结构化抽取、企业问答、敏感场景回复、固定schema输出这些任务上,通常会暴露出大量不稳定行为。它可能一会儿过于冗长,一会儿遗漏关键信息;一会儿按照格式输出,一会儿又擅自发挥。SFT的作用,正是在这种不稳定与业务要求之间搭建桥梁。

从能力对齐的角度进一步看,SFT处在一个十分特殊的位置。它既不像预训练那样广泛吸收世界知识,也不像偏好对齐那样强调人类偏好排序,而是负责定义一个“可以被后续阶段继续优化的基础行为分布”。如果这个分布本身就高度混乱,后续无论是偏好学习还是工具学习,都会建立在脆弱基础之上。相反,如果SFT已经把模型带到了一个相对规范、明确、可控的行为空间,那么后续优化才会更高效、更稳定。

因此,SFT不应被视为“让模型变聪明”的主要手段,而应被视为“让模型在业务上可控、可用、可复现”的关键工程阶段。它能显著提升模型的指令遵循性、任务稳定性、输出一致性和场景适配性,但不能替代基础模型对复杂推理、长期记忆、深领域知识和工具规划能力的根本性获得。对数据设计团队来说,理解这一点非常重要,因为这决定了SFT数据集究竟要解决什么问题,不能解决什么问题,以及哪些问题应交由上游模型选择、下游偏好学习或系统工程来处理。

12.1.2 “让模型听话”和“让模型有能力”之间的边界

“听话”与“有能力”在工程上常常被混为一谈。一个样本中,如果用户要求“请用三段回答,并给出结论”,模型学会了遵守三段结构和结论位置,这是听话;如果用户要求“比较两种方案的适用条件,并指出风险来源”,模型不仅需要遵守格式,还需要真正完成比较、抽象和归因,这里面既有听话,也有能力调用。

在SFT设计中,团队必须明确区分三类信号。第一类是行为格式信号,例如语言风格、段落组织、是否输出JSON、是否先总结后展开。第二类是任务执行信号,例如抽取、分类、重写、规划、归纳、比较、澄清、拒答等。第三类是知识与推理信号,例如对领域事实的使用、对条件的约束求解、对多轮上下文的整合。这三类信号经常共同出现在一个样本中,但它们的训练意义不同。格式信号更偏接口规范,任务执行信号更偏技能对齐,知识与推理信号更依赖模型底座和数据选取策略。

这意味着,SFT团队在评审数据时不能只问“这个答案写得像不像人”,还要问“这个样本到底在教模型什么”。若一个样本只是把正确答案写得很漂亮,却没有明确的任务边界与约束表达,那么它对模型的增益可能远低于一个结构清晰、意图明确、约束完整的样本。

在实际工程中,区分“听话”和“有能力”的一个有效方法,是分析任务失败到底是因为什么。如果模型失败的表现是格式乱、语气不对、没有按要求分段、没有遵循输出schema,那么这通常是“听话层”的问题。如果模型格式都对了,但漏掉关键证据、比较逻辑不完整、无法识别冲突条件,那更接近“能力调用层”的问题。两者在数据设计上的处理方式不同:前者需要更清晰的模板、更稳定的规范和更一致的示范;后者则需要更有代表性的任务构造、更充分的上下文和更合理的难度分层。

还有一类常见误区,是把模型“看上去很像会了”误认为“真的掌握了能力”。例如,一个模型在大量“请总结以下文本”的样本上表现良好,可能只是学会了常见摘要句式;只有当输入长度变化、风格变化、主题变化、约束变化时,它仍能稳定抓住关键信息,才能说它在摘要这一任务上形成了较稳固的能力调用模式。SFT的目标并不是让模型在少数模板上表现得漂亮,而是让它在一类任务的不同变体上保持稳定。

因此,设计团队在标注规范中应尽量避免“表面正确、实则信号稀弱”的样本。一个好的SFT样本,不仅要告诉模型最终答案是什么,还要通过任务结构和上下文条件,明确告诉模型“什么情况下该这样答,什么情况下不该这样答”。真正高质量的数据,不是把结果堆给模型,而是把行为边界和能力接口教给模型。

12.1.3 为什么SFT数据不能简单等同于问答对

把SFT数据理解成“问题—答案”二元组,是最常见也最危险的简化。真实高质量SFT样本至少包含四个层面:角色设定、任务指令、上下文条件和目标响应。换言之,模型学习的不是“看到这个问题就输出这个答案”,而是“在给定角色、限制、上下文和任务目标的条件下,如何构造合规响应”。

一个看似简单的客服样本,如果只保留用户提问和客服回答,模型可能学到的是表面措辞;但如果补充系统规则、政策片段、用户历史信息和格式要求,模型学到的就是条件化响应机制。这两者差别极大。前者更像记忆模板,后者才接近任务执行。

此外,很多高价值SFT任务根本不是单步问答。例如,多轮澄清需要模型先识别信息不足,再提出补充问题;工具辅助任务需要模型在回答前输出调用参数或行动计划;约束式输出要求模型以特定schema生成结构化结果;系统任务则要求模型在冲突指令下保持优先级一致。所有这些都说明,SFT数据设计本质上是“交互结构设计”,而不是“答案收集”。

从训练接口上说,SFT样本的本质是“条件到响应”的映射,而这个“条件”远远不止一个自然语言问题。它可能包含系统指令、开发者限制、业务规则、历史对话、工具结果、外部文档、字段schema、拒答策略,甚至还包含某些隐式但必须显式标出的上下文变量。若忽略这些条件,只剩一个孤立问句和一个孤立答案,模型学到的往往只是脆弱的表面对应关系,而不是可靠的任务机制。

这也是为什么很多团队在早期SFT中会遇到一个现象:离线抽样看起来数据很“干净”,模型在一些静态问答上也答得不错,但一旦进入真实交互环境,就开始出现风格漂移、格式不稳、指令优先级错乱、过度脑补、上下文遗忘等问题。根本原因在于,训练数据并没有真实描述业务交互的条件结构,只是收集了一批回答文本。模型学会的是“说点像样的话”,而不是“在特定条件下执行特定任务”。

因此,面向生产场景的SFT设计必须把“问答对思维”升级为“任务实例思维”。所谓任务实例,就是将角色、输入、上下文、约束、响应方式、质量目标全部纳入同一个训练单元。只有这样,SFT数据才真正具备工程意义。

12.1.4 SFT目标的工程化表述

为了避免SFT目标在团队协作中变得空泛,实际项目中往往需要将其转写为更可执行的工程目标。很多团队在项目初期都会说,希望模型“更听话”“更稳定”“更适合业务”“别老犯那些明显错误”。这些说法本身没有问题,但如果不继续往下拆,就很难真正指导数据建设。因为标注团队不知道该优先写什么样的样本,审核团队不知道该按什么标准验收,算法团队也很难判断一次训练结果到底有没有向目标靠近。说到底,SFT不是靠愿景驱动的,而是靠一组可以落到样本、模板、评分和回归集上的工程目标来推进的。

一般而言,SFT至少承担以下几个工程职责。

第一,是行为对齐。也就是让模型在面对指令时知道要执行什么、优先执行什么、哪些约束不能越过。行为对齐听上去很抽象,放到工程里其实非常具体。用户让它提取字段,它就应该提取字段,而不是顺手解释背景;用户要求先总结再展开,它就不该擅自换一种组织方式;system里规定了拒答边界,它就不能因为用户换了一种说法就越过去。很多模型的问题,并不在于完全不会做任务,而在于它总会在“差不多”与“严格按要求”之间摇摆。SFT在这里要解决的,就是把这种摇摆尽量压缩,让模型形成更稳定的任务执行习惯。

第二,是接口对齐。也就是让模型输出的形式能够被系统接住,例如稳定的JSON、固定字段、特定语言风格、受控长度和规范措辞。接口对齐的重要性,往往只有做过系统集成的人才会特别敏感。对于训练阶段来说,一次字段顺序错乱、一次空值表达不一致、一次多输出了一句说明,看起来都像小问题;但到了真实系统里,这些小问题会直接变成解析失败、流程中断或者人工兜底成本上升。所以很多时候,SFT的价值并不体现在“模型变聪明了多少”,而体现在“它终于能稳定按照系统需要的方式说话”。这种能力不是模型自然会长出来的,而是要通过大量一致、清楚、边界明确的样本一点点训出来。

第三,是场景对齐。也就是让模型对不同业务语境形成不同的表达与边界意识,例如医疗场景更保守,客服场景更流程化,法务场景更强调证据与条件。很多团队把场景对齐理解成“换一批领域数据”,其实远远不够。真正的场景对齐,不只是让模型认识更多专业词汇,而是让它学会在不同责任结构下调整自己的说话方式。同样是回答一个问题,在客服场景里也许要尽快给出下一步操作,在法务场景里则要先说明判断依据和限制条件,在医疗场景里可能首先要判断有没有风险信号。也就是说,场景对齐训练的不是知识本身,而是知识如何在特定场景中被安全、合适、可执行地表达出来。

第四,是失败收敛。也就是通过有针对性的样本设计,把高频失败模式逐步压缩到可接受范围。很多项目在做SFT时,只盯着“平均效果有没有提高”,却忽视了真正影响产品体验的,往往是那几类反复出现的错误。比如结构化输出时总漏某个字段,多轮对话时总忘记上一轮限制,工具调用时参数经常缺必填项,拒答场景里语气忽硬忽软,长文本摘要里习惯性丢掉结论段。这些问题如果不单独盯、不单独补,数据量再大也不一定会自己消失。SFT工程化的一个核心思路,就是不要幻想模型会在海量样本里自动把所有坏习惯磨平,而是要明确识别那些最常见、最影响上线质量的失败模式,然后用专门的模板、回归样本和质量门槛把它们一点点压下去。

这几个目标之所以重要,是因为它们都能够被数据集设计直接影响。换句话说,它们不是停留在口号层面的“希望模型更好”,而是可以明确映射到数据工作上的。行为对齐对应任务模板和约束表达方式,接口对齐对应输出schema和格式验收,场景对齐对应system设计、语气规范与领域边界,失败收敛对应困难集、长尾样本和失败样本回收机制。目标一旦能这样落到数据层,团队的分工才会真正清楚:哪些问题要靠模板改,哪些问题要靠样本补,哪些问题要靠审核标准收紧,哪些问题需要单独建回归集长期盯住。

反过来看,像“提升模型世界知识总量”“显著增强跨领域复杂推理上限”这样的目标,往往并不是SFT能够单独承担的。标注团队如果不清楚这一点,就容易在样本建设中陷入方向性浪费:一方面拼命堆数据,另一方面又无法解释模型为什么仍然在底层复杂能力上没有本质变化。更常见的情况是,团队会不自觉地把一些本该由基础模型能力、预训练质量、检索系统、工具系统甚至推理架构承担的任务,统统压到SFT阶段来解决。这样做的结果通常是,SFT目标越来越大,样本越来越杂,最后什么都想教,什么都没教透。

这也是为什么项目里常会出现一种误判:模型上线后表现不够理想,第一反应永远是“是不是SFT数据还不够多”。但很多时候问题不是数据不够多,而是目标本来就没有被正确限定。比如希望模型通过SFT突然掌握一个此前几乎没见过的专业知识体系,希望它仅靠监督样本就把复杂多跳推理稳定下来,希望它在没有工具支持的前提下解决原本应由外部系统完成的查询任务。这些期待一旦混进SFT目标里,团队就很容易在后续迭代中不断加数据、改模板、补样本,却始终感到效果“不成体系”。

因此,在项目立项时,建议团队就明确SFT的成功标准。例如,模型是否需要在某类任务上达到90%以上的格式稳定率,是否需要将高风险错误率压到某个阈值以下,是否需要保证多轮回答风格一致,是否需要在工具任务中维持较高的参数正确率。只有当SFT目标被转化为可评估的工程标准时,数据设计工作才真正具备方向。

这里最关键的,不是指标一定要设计得多复杂,而是它必须真的能指导生产。比如“让回答更自然”这种目标,如果不能继续拆成更可观察的维度,就很难落实;但如果把它改写成“客服场景下避免过度书面化表达,并保证下一步操作说明完整”,数据团队就知道该怎么写模板,审核团队也知道该怎么打分。再比如“增强模型安全性”听起来很大,但如果进一步落成“医疗场景中高风险症状不得给出延迟就医建议”“法务场景中信息不足时必须显式说明限制条件”,那它就已经从空泛目标变成可执行规范了。

很多成熟团队在这里都会多做一步:不只写总体目标,还会把目标拆成版本目标。也就是说,第一阶段先把格式稳定性和基本行为边界做稳,第二阶段再补高频业务流程,第三阶段专门压高风险长尾错误。这样做的好处是,团队不会一开始就把所有期待压在同一个版本里,也不会因为目标过大而导致评估失焦。SFT工程里最怕的,往往不是目标低,而是目标太散、太虚、太同时发生,最后谁都说不清这一次训练到底想解决什么。

从这个意义上说,SFT目标的工程化表述,其实是在给整个项目建立一套共同语言。产品团队关心上线体验,算法团队关心可训练性,标注团队关心样本规则,评测团队关心失败模式,管理者关心版本进展。要让这些角色真正协同起来,靠的不是大家都认同“模型要更好”这样的大方向,而是大家能不能围绕一组明确目标说同一种话。只有当“行为对齐”“接口对齐”“场景对齐”“失败收敛”这些目标被进一步写成可执行标准、可检查样本、可回归的指标时,SFT才真正从一个模糊的训练环节,变成了一个可以被规划、被验收、被持续迭代的工程过程。


12.2 任务分层与指令体系

12.2.1 通用任务、技能任务、领域任务、系统任务的分层

一个成熟的SFT数据体系,不能只按“业务线”来组织,而应同时按“任务层级”来组织。对负责数据设计与标注规范的团队来说,最实用的分层方法通常包括四层。

通用任务层,是所有大模型都需要具备的基本交互能力,例如总结、改写、翻译、抽取、分类、问答、解释、头脑风暴和结构化输出。这一层决定模型的广谱可用性,是大部分通用助理能力的骨架。

技能任务层,是比通用任务更接近“能力原子”的层次,例如多步推理、信息对比、错误纠正、反事实分析、条件规划、长文整合、表格到文本转换、从上下文引用证据等。它们不一定绑定某个行业,但往往决定模型在复杂工作流中的上限。

领域任务层,是围绕具体行业或组织知识构建的任务,例如法律条文解释、医疗分诊建议、售后工单分类、保险拒赔原因说明、金融产品适配建议、教育作业讲解等。这里不仅有知识差异,更有风险等级、语言规范、责任边界和输出口径差异。

系统任务层,则是很多团队最容易忽视但最重要的一层。这一层不面向业务内容,而面向系统行为本身,例如遵守安全策略、识别越权请求、执行拒答模板、根据开发者设定保持语气、优先服从system指令、控制工具调用格式、处理上下文冲突等。系统任务决定模型是否“稳定像一个产品”,而不是“偶尔像一个会说话的模型”。

这四层不是互斥关系,而是叠加关系。一个法律客服样本可能同时包含领域知识、澄清技能、结构化输出要求和系统安全边界。SFT设计团队需要做的,不是强行给每个样本贴单一标签,而是建立可组合的标签体系,清楚标明一个样本主要训练哪一层能力、辅助覆盖哪几种行为。

在项目实践中,之所以要采用这种分层方法,是因为不同层的任务在建设逻辑上完全不同。通用任务讲究广覆盖和高密度,目的是让模型具备基本可交流性;技能任务强调任务原子的纯度和组合性,便于后续迁移到多场景;领域任务强调口径、风险和知识边界,通常需要专家参与;系统任务则更接近产品规则和平台政策,往往由算法、产品和安全团队共同定义。

如果没有这套层级意识,数据集很容易陷入两种常见失衡。第一种是“只有业务,没有能力”。也就是样本都围绕具体场景堆积,但缺乏对可迁移技能的系统覆盖,导致模型一旦脱离原业务表述就性能下滑。第二种是“只有通用,没有约束”。也就是样本形式很多,但几乎没有针对系统边界、冲突指令和风险场景的训练,结果模型在真实部署中容易越界。

因此,任务分层不仅是数据组织方式,更是一种风险控制方式。它能帮助团队明确:哪些能力是底盘,哪些能力是增强项,哪些内容是领域化差异,哪些行为属于必须稳定执行的系统规则。只有在这种分层之下,SFT数据集才能既保持广度,又形成重点。

12.2.2 分层体系下的标签设计与样本归档

有了任务分层之后,样本建设就不能再停留在“先多写一些再说”的阶段了。数据量小时,很多问题还不明显;一旦规模上来,没有标签体系,后面几乎什么都做不了。你很难说清某一类能力到底覆盖了多少,也很难解释某次训练退化究竟是哪些样本出了问题。表面上看是管理混乱,实际很快就会变成训练问题和评测问题。

一个真正有用的标签体系,通常不会只回答“这条样本属于什么任务”,而是要同时回答几件事:它主要在训练什么,它发生在什么场景里,输出形式是什么,风险高不高,值不值得作为核心样本保留。也就是说,主任务标签、能力标签、场景标签、格式标签、风险标签和质量标签,最好都要有。主任务标签解决“这是在做什么”,能力标签解决“重点在练什么”,场景标签解决“它在哪类业务里成立”,格式标签解决“它最后要怎么输出”,风险标签和质量标签则决定它在后续训练和回归里该被放在什么位置。

标签真正麻烦的地方,不在于想出几个名字,而在于它必须能支撑后面的检索、抽样和归因。比如同样是一条法律客服样本,表面上是在回答问题,实际上可能同时训练了澄清、证据引用、风险提示和固定格式输出。如果标签只打一个“法律问答”,那这条样本在库里看起来很普通,等到后面要查“哪些样本训练过证据引用”或者“哪一批高风险样本同时要求结构化输出”,它就很容易被埋掉。数据刚开始少的时候,这种损失还不明显;数据一多,整个库会越来越像仓库,而不是一个能调度的系统。

样本归档也一样,不能只图省事按业务线粗分几个文件夹。更稳妥的做法,往往是模板作为主轴,标签作为检索条件,版本号作为冻结边界。这样做的好处是,物理存储可以保持整齐,逻辑组织又不会被目录结构绑死。评测团队如果发现“医疗场景下的多轮澄清最近明显变差”,数据团队就能顺着标签很快捞出对应子集,而不是靠人肉翻样本。

不过,标签也不是越多越好。很多团队一开始很认真,把标签体系做得特别细,结果标注员打不准,审核员懒得看,最后谁都不相信这些标签。那样的标签系统看起来很完整,实际上没有任何工程价值。真正合适的状态,通常是标签数量不算太多,但语义清楚,边界稳定,平台里填起来也不累。说到底,标签不是为了把数据写得更漂亮,而是为了让后面的人还能看懂这堆数据到底在干什么。

代码示例:一条样本的“可检索标签元数据”

很多团队会把“样本文本”和“样本元数据”分开存。文本用于训练,元数据用于检索、抽样、统计与归因。下面给出一个适合教材阅读的最小可用元数据示例(JSON Lines 中的 meta 字段)。

{
  "id": "sft_legal_extract_000127",
  "meta": {
    "primary_task": "information_extraction",
    "ability_tags": ["schema_following", "evidence_use"],
    "scenario": "legal",
    "output_format": "json",
    "risk_level": "high",
    "quality": {
      "instruction_clarity": 5,
      "response_correctness": 5,
      "format_consistency": 5,
      "boundary_safety": 5,
      "trainability": 5
    },
    "template": {
      "name": "legal_contract_payment_terms_v2",
      "version": "2.1.0"
    },
    "dataset_version": "sft_zh_v0.3.0",
    "source": "offline_redteam",
    "created_at": "2026-04-24"
  }
}

12.2.3 单轮、多轮、工具辅助、约束式输出的模板设计

模板是SFT工程化的核心。没有模板,数据集会迅速退化为风格混乱、约束缺失、难以扩展的样本堆。模板也不是机械的句式替换,而是把任务目标固化为可复用的样本框架。

单轮模板最适合作为基础覆盖层。它强调意图明确、输入充分、响应稳定。此类模板适用于摘要、改写、抽取、直接问答、分类判断等任务。设计时重点不在于语言多华丽,而在于任务边界是否清楚,答案是否唯一或可接受范围是否明确。

多轮模板则更接近真实交互。其价值在于训练模型理解上下文延续、识别信息缺口、在历史轮次中保持立场一致,并对用户追问做局部更新而非全盘重答。多轮模板中最重要的不是轮次数量,而是轮次关系是否有意义。例如,用户补充条件、纠正前提、改变目标、要求压缩表达、请求转换格式,这些都是真实高价值场景。

工具辅助模板是现代SFT中越来越关键的一类。它要求模型不仅会“说”,还会“决定何时行动、如何行动、行动结果如何融入最终回答”。在这类模板里,标注团队必须明确工具名、参数schema、调用时机、异常处理和最终回答整合方式。如果模板只教模型“看到某类问题就输出某种工具调用字符串”,而没有教它判断工具使用边界,那么上线后很容易出现误调用或滥调用。

约束式输出模板则面向结构化系统集成场景,尤其适用于RAG、Agent、表单处理、审阅系统、数据标注辅助等任务。其关键不是“输出JSON”这么简单,而是让模型理解字段约束、枚举值范围、空值策略、缺失信息处理方法以及字段间依赖关系。很多格式错误并不是模型不会括号,而是模板没有让模型学会“在不确定时如何合法地表达不确定”。

从模板工程的角度看,单轮模板负责打底,多轮模板负责逼近真实交互,工具模板负责打开行动能力接口,约束式输出模板负责系统对接能力。四者共同构成一个完整的指令体系。如果只有单轮模板,模型往往“静态任务”表现不错,但一进入真实对话就开始漂移;如果只有多轮模板而缺少结构化输出训练,模型又难以接入下游系统;如果只教工具调用,不教调用前的判断与调用后的整合,模型又会显得机械而脆弱。

因此,模板设计应遵循“形态多样,但规则统一”的原则。不同模板的表面形式可以不同,但它们都应遵守统一的字段划分、统一的约束表达方式、统一的异常处理策略和统一的质量标准。模板不是为了让样本看起来整齐,而是为了确保监督信号可复用、可扩展、可审查。

代码示例:四元结构样本(system/instruction/context/response)

下面以“信息抽取 + JSON约束输出”为例,展示一条可直接用于SFT的数据样式。注意:示例重点不是“答案写得漂亮”,而是把任务边界、缺失值策略、字段约束写清楚。

{
  "messages": [
    {
      "role": "system",
      "content": "你是企业合同助手。仅依据给定文本抽取信息,不得臆测补全。输出必须是合法JSON;无法从文本确认的字段用 null 表示。不要输出与JSON无关的解释性文字。"
    },
    {
      "role": "user",
      "content": "【任务】从合同片段中抽取付款条款,并按指定schema输出。\n\n【schema】\n{\n  \"currency\": \"CNY|USD|EUR|null\",\n  \"payment_amount\": \"number|null\",\n  \"payment_method\": \"string|null\",\n  \"payment_due_days\": \"number|null\",\n  \"penalty_rate\": \"string|null\"\n}\n\n【合同片段】\n乙方应在验收合格后15日内向甲方支付合同总价款的30%作为首付款;余款于项目上线后30日内付清。逾期付款的,按每日0.05%计收违约金。"
    },
    {
      "role": "assistant",
      "content": "{\n  \"currency\": \"CNY\",\n  \"payment_amount\": null,\n  \"payment_method\": null,\n  \"payment_due_days\": 15,\n  \"penalty_rate\": \"每日0.05%\"\n}"
    }
  ]
}

代码示例:多轮澄清模板(先追问“最小必要信息”)

在信息不足时,不要让模型“猜一个合理答案”,而是训练它追问最小必要信息。下面示例中,助手只问一个关键问题,避免反复盘问。

{
  "messages": [
    {
      "role": "system",
      "content": "你是客服助手。信息不足时先追问最小必要信息;不要猜测订单号或用户身份。语气礼貌但简洁。"
    },
    { "role": "user", "content": "我想退货,怎么弄?" },
    {
      "role": "assistant",
      "content": "可以的。我先确认一个信息:你购买的是【自营订单】还是【第三方商家订单】?这会决定退货入口和处理时效。"
    }
  ]
}

2.4 模板设计中的常见错误

很多SFT项目做到后面效果一般,不是因为团队不努力,也不是因为样本数量不够,而是模板一开始就写偏了。模板出了问题,后面样本做得越多,偏差只会被放大,不会自己变好。

最常见的一类问题,是模板太依赖固定说法。比如所有总结都从“以下是总结”开始,所有拒答都长得差不多,所有解释题都喜欢先来一句几乎一样的过渡。人看上去会觉得整齐,模型却很容易把这些表面句式当成捷径。结果就是,一旦真实用户换一种说法,模型就不稳了。它学到的不是任务本身,而是模板里那几句高频套话。

还有一种问题更隐蔽,就是模板把关键要求藏起来了。写模板的人自己是明白的,标注员做熟了也明白,于是默认很多东西“不写也知道”。可模型不吃这一套。该输出哪些字段、缺失信息时怎么处理、工具调用前要不要先校验、冲突条件下该优先遵守什么,这些只要没在模板里写出来,训练信号就是虚的。人可以靠经验补全,模型只会学得半懂不懂。离线抽样时看起来还能过,一上线就开始飘。

再有一类问题,是模板永远只覆盖“顺利场景”。信息完整、流程标准、用户表达清楚、结果可以直接给出,这样的样本当然容易写,也容易验收,但真实交互里最值钱的恰恰不是这部分,而是那些不顺的时候怎么处理。订单号缺了要不要追问,用户条件前后冲突怎么办,证据不足时能不能直接下结论,系统返回空结果后该怎么接着说,这些如果模板里没有,模型上线后就会在异常流程里暴露得特别快。很多团队会误以为这是模型能力不够,其实常常只是模板把最难的那部分绕过去了。

还有一种很常见但不太容易被及时发现的情况,是示范答案写得太“漂亮”。标注员总想把回答写完整、写圆润、写得像范文,这个心情完全可以理解,但问题在于,真实系统并不总需要这种满分作文。很多任务要的不是完整铺开,而是稳、准、短、能落地。如果response长期被写成一种过度展开、处处照顾、句句圆满的样子,模型学出来的往往不是专业,而是啰嗦。看起来很会说,真正接系统的时候反而不合适。

模板之间彼此打架,也是后面经常出问题的来源。一套模板强调先给结论,一套模板默认先讲背景;一套模板要求信息不足先追问,另一套模板又习惯直接补全;一套模板写得特别克制,另一套模板又鼓励展开分析。单看每一条,可能都能说得过去,可一旦放在同一个训练集里,它们就在给模型喂相互冲突的监督信号。最后模型不是学会灵活,而是学会摇摆。

所以模板设计最怕的,从来不是文笔不够好,而是结构上没把该教的东西教清楚。真正成熟的模板,往往不是最花哨的那种,而是把任务边界、异常情况、优先级和输出方式都写得很稳。样本数量可以后面再补,模板要是一开始就糊了,后面很难补救。

12.2.5 system、instruction、context、response 的角色划分

高质量SFT样本必须在结构上清楚区分system、instruction、context、response四个部分,因为这四部分分别承担不同的训练职责。

system定义全局行为边界。它告诉模型“你是谁、遵循什么规则、优先级如何”。这部分更接近运行时系统设定,因此在数据中应保持克制和稳定,避免写成冗长的任务说明书。system最重要的不是信息量大,而是规范明确、优先级清晰、可跨样本复用。

instruction定义当前任务目标。它直接对应用户或上层系统给模型的工作要求,例如“请从以下合同中提取付款条款,并按JSON输出”。instruction应聚焦当前任务本身,而不应承担太多领域背景说明,否则会稀释任务边界。

context提供完成任务所需的条件材料。它可能是文章、表格、对话历史、政策文本、病例摘要、商品信息,也可能是工具返回结果。context不是装饰材料,而是模型生成过程中的证据基础。标注规范中应强调:只有真正参与答案构造的内容才应纳入context,避免无关冗余导致模型学会“忽略上下文”。

response则是目标行为的显式示范。它不仅要“答对”,还要体现对system、instruction和context的综合服从。一个好的response需要同时满足内容正确、格式一致、信息充分、语气适配、边界清楚等要求。它是模型最直接模仿的对象,因此不能只是结果正确,还必须是“方式正确”。

进一步说,这四部分分别对应四种不同的训练含义。system主要训练优先级与全局行为框架;instruction主要训练任务触发与局部约束;context主要训练条件理解与证据利用;response主要训练最终表现形式与执行质量。若这四者混在一起,模型就难以学到清晰的边界。例如,把system写成业务背景长文,会模糊全局规则;把context写进instruction,会削弱“证据来自哪里”的意识;把response写得过于依赖context原文复述,则容易让模型形成复制而非整合倾向。

为了帮助团队统一理解,图12-1给出了SFT指令体系的架构示意图。

图12-1:SFT指令体系的架构示意图

图12-1:SFT指令体系的架构示意图

12.2.6 四元结构在标注规范中的落地方式

system、instruction、context、response 这四块,光在方法论里讲清楚还不够,真正难的是把它们写进标注规范之后,团队能不能长期按同一套方式执行。很多项目嘴上都知道四元结构重要,实际做的时候还是喜欢把内容混着写,最后模型学到的是一团模糊的条件,而不是清楚的行为边界。

system最好尽量稳,不要每条样本都换一种说法。它承担的是全局规则,不是临场发挥。像角色设定、基本边界、优先级要求、语气基调这类东西,一旦今天这么写、明天那么写,模型最后学到的就不是规则,而是风格噪声。对system来说,统一比华丽重要得多。能复用的就尽量复用,能短句表达的就别拖成长段。

instruction则要把当前任务说清楚。它不是背景介绍,也不是system的替代品,更不是把所有要求一股脑塞进去的杂物箱。很多时候一条instruction写得又长又乱,并不是信息充分,而是职责不清。身份要求放一点,领域说明塞一点,输出格式写一点,上下文里本来该出现的内容也顺手揉进去。这样人看着勉强能懂,模型却很难分辨什么是任务本身,什么只是附带说明。instruction最该做的,是把“这一次到底要完成什么”说清楚。

context也不是把材料原封不动贴上去就结束了。它最好有基本结构,至少让人和模型都知道哪些内容是证据,哪些只是补充信息。长文本要分段,表格要保留字段关系,对话历史最好区分说话人,工具返回结果也要标清来源。这样做不是为了形式好看,而是为了后面能追踪response究竟依据了什么。如果context本身就是一整团糊在一起的材料,到了审核和归因的时候,谁都很难判断模型到底错在没看见、没理解,还是压根没学会引用证据。

response更不能只看“最后答对了没有”。它是整个样本里最直接的示范信号,system有没有被遵守,instruction有没有被执行,context有没有被真正用上,最后都得在response里落下来。尤其是结构化输出任务,哪些字段必须写,哪些字段允许空,空值怎么表达,解释性内容能不能放在结构外面,这些都得稳定。很多训练后出现的格式漂移,并不是模型突然学坏了,而是response本身就没示范清楚。

真实项目里,经常能看到一种问题样本:system写得很虚,instruction又把角色、任务、格式全揉在一起,context里资料来源混杂,response最后还一边按格式输出,一边在外面补几句自由发挥的话。人读起来未必觉得特别别扭,但对模型来说,这就是在教它“边界可以松一点,结构外面也能随便加”。样本一多,这种习惯就会被放大。

所以四元结构真正落地以后,最重要的变化不是“样本更规范了”,而是每个字段终于各司其职了。system负责全局规则,instruction负责当前任务,context负责证据条件,response负责最终示范。分工一旦稳定,后面的审核、回归、归因和版本对比都会轻很多。要不然,哪怕每条样本单拿出来都好像还能看,整个数据集放在一起还是会越来越乱。


12.3 覆盖度、难度与样本结构

12.3.1 能力覆盖矩阵与知识点地图

SFT数据集最常见的问题,不是样本太少,而是覆盖失衡。某些高频任务被重复采样,导致模型在少数表达形式上看起来很稳;而真正决定可用性的长尾场景、边界条件和异常流程却几乎没有进入数据集。解决这个问题的关键,不是盲目扩容,而是建立能力覆盖矩阵与知识点地图。

能力覆盖矩阵通常以“任务类型 × 场景变量 × 约束方式”为基本框架。例如,在“信息抽取”任务下,可以进一步覆盖合同、病例、工单、论文摘要、客服对话等不同语料;在每类语料中,再覆盖简短输入、长文本、多字段、模糊表达、噪声文本、冲突信息等情况;最后再覆盖自然语言输出、表格输出、JSON输出等不同响应形式。这样建立起来的矩阵,才能真正回答“模型在哪些条件下被训练过”。

知识点地图则更适用于强领域任务。以法律场景为例,不能只说“做了合同问答”,而要映射到付款条款、违约责任、管辖约定、解除条件、证据要求、争议解决等子知识点;以医疗场景为例,则应映射到症状描述、初步分诊、禁忌提示、就医建议、信息不足澄清、风险升级等节点。知识点地图的价值在于,它让数据设计团队看到“知识空洞”而不仅是“样本数量”。

成熟团队通常会把能力覆盖矩阵作为采样和评审的底盘:新增样本不是为了把数据量从一百万做成两百万,而是为了填补矩阵中仍然空缺或质量薄弱的区域。

从管理角度看,覆盖矩阵还有一个重要作用,就是避免“以量代质”的幻觉。很多项目在周报中会汇报新增样本量,但如果没有覆盖矩阵,这个数字几乎没有解释力。新增的一万条样本,可能只是把已有高频任务重复得更密,也可能是真正补齐了最关键的长尾缺口。两者对模型的价值完全不同。

此外,覆盖矩阵并不是一成不变的。随着模型能力提升、业务扩展和失败模式变化,矩阵本身也应动态调整。例如,早期阶段也许更重视通用任务和格式稳定性,中期则更多补技能任务与多轮样本,后期则将资源集中到高风险长尾场景和工具接口稳定性上。一个成熟团队的覆盖矩阵,往往会随版本演进而不断更新,而不是一次制定后长期不变。

12.3.2 样本长度、复杂度、风格与领域深度的配比

SFT数据设计不是“越长越好”或“越复杂越好”。一个数据集要有效,必须在样本长度、任务复杂度、语言风格和领域深度之间形成合理配比。

短样本的价值在于密度高、收敛快、格式学习效果好。它们适合训练明确指令遵循、基础输出模式和高频任务骨架。中等长度样本更适合训练上下文整合、信息筛选和段落组织。长样本则主要用于训练长上下文依赖、复杂条件约束、跨段归纳、证据引用和稳健表达。

复杂度方面,团队不应让所有样本都停留在“输入明确、答案唯一”的安全区。真实系统中,模型经常面对信息缺失、目标冲突、要求变更、语境含混和边界模糊的问题。因此,SFT中应有意识地配置一定比例的中高复杂度样本,训练模型在不完美输入条件下的行为稳定性。

风格分布同样重要。若一个数据集全部采用统一、教科书式语气,模型上线后很可能面对真实用户口语、断句、情绪化表达、拼写错误和非规范指令时表现下降。相反,如果过度追求口语多样性而牺牲任务清晰性,又会使监督信号变得模糊。因此,标注规范需要明示:哪些任务应强调标准表达,哪些任务应故意保留真实噪声,哪些任务应做风格等价改写。

领域深度则决定模型在垂直场景中的专业感。如果一个法律SFT数据集只是把通用问答改写成“法律口吻”,那它训练出的只是风格伪装,而不是领域能力。真正的领域深度,来自术语使用、边界把握、风险提示、规范口径和知识组织方式的共同体现。

从配比设计的角度,样本长度与复杂度并不总是正相关。一个短样本也可以非常复杂,例如一句含混用户指令加上严格的JSON约束;一个长样本也可能只是冗长却简单。因此,团队在做数据统计时,不应只看token长度,还应建立复杂度标签。例如,是否需要多步条件判断,是否存在信息缺失,是否有冲突约束,是否要求结构化输出,是否需要跨段引用证据。只有把“长短”与“难易”分开统计,才能看清数据集真实形态。

对于风格与领域深度的配比,也应避免两个极端。一种极端是为了追求真实用户分布,大量保留噪声表达,结果样本任务边界不清,标注员之间理解不一致;另一种极端是把所有样本都写得过于规范,导致模型上线后面对真实用户语言的鲁棒性不足。比较合理的做法,是在主训练集里维持清晰样本为主、适量噪声为辅,同时构建专门的困难集、口语集、异常集去训练和评测鲁棒性。

12.3.3 样本结构的层次化设计

除了单条样本本身的配比,整个数据集也需要结构化。一个高质量SFT数据集通常不会是“所有样本混在一起”,而会在内部形成不同层次。例如,可以有基础覆盖层、难例增强层、长尾边界层、格式强化层和领域深挖层。这样做的好处,是训练时可以按阶段使用、按权重采样,也便于分析某一层对模型行为的影响。

基础覆盖层的任务是保证模型具备广谱可用性,包括通用问答、基础摘要、常见改写、简单抽取、基础分类等。难例增强层则聚焦复杂条件、信息缺失、多轮修正、边界不清等情况。长尾边界层主要面向高风险或低频但关键的场景,例如越权请求、敏感问题、异常输入、对抗式表达。格式强化层专门负责结构化输出、schema一致性和工具参数规范。领域深挖层则用于建立行业差异化能力。

这种层次化设计的价值在于,它让数据集从“一个平面仓库”变成“一个有功能分工的系统”。当模型在某一类能力上出现退化时,团队可以更容易定位应该回看哪一层数据,而不是在一个庞大无序的数据池里盲目排查。

12.3.4 高价值长尾样本的发现与补齐

决定SFT上限的往往不是头部样本,而是长尾样本。所谓高价值长尾样本,通常具有以下特点:出现频率不高,但一旦发生就强烈影响用户体验或业务风险;对模型的边界意识、澄清能力、异常处理能力和格式稳定性提出更高要求;很难通过简单模板自然覆盖。

长尾样本的发现可以来自多个渠道。第一类来源是线上失败案例,例如模型误答、漏答、格式崩溃、拒答不当、澄清不足。第二类来源是业务专家总结的高风险场景,例如法律咨询中的责任归属、医疗问答中的紧急症状、客服中的退款时限争议。第三类来源是对抗式测试与人工红队,它们能暴露模型在绕规则表达、指令冲突、嵌套约束和噪声输入下的脆弱点。第四类来源是模板组合产生的“复杂交叉角落”,例如“多轮对话 + 工具调用 + JSON输出 + 信息缺失澄清”。

长尾样本的补齐不是简单复制失败样本,而是要抽象失败模式。例如,如果模型在多次样本中都把“信息不足”误判为“可以猜测补全”,那么团队要补的不是某一个具体问句,而是一类以“不足证据下的保守响应”为核心的模板簇。只有这样,数据集才能从“修一个洞”变成“修一类洞”。

在实际操作中,高价值长尾样本往往最难标,也最容易在生产压力下被忽略。因为它们数量少、制作成本高、审核要求严,短期看似不如大批量生成头部样本“划算”。但恰恰是这些样本,决定了模型在关键场景中的可信度。一个模型能否在普通问答上表现良好,也许决定用户是否觉得它“聪明”;而它能否在长尾高风险场景下稳住边界,才决定用户是否敢真正使用它。

因此,成熟团队通常会单独为长尾样本建立发现、归档和复训机制,而不是把它们零散混入普通样本中。这样做的目的,不只是提高训练效率,更是为了在版本迭代中持续跟踪关键风险是否被压制。

为了便于团队建立任务映射关系,表12-1给出了指令类型与适用任务的示例关系。

表:指令类型与适用任务表

指令类型 典型输入形态 目标输出形态 适用任务 标注重点 常见风险
直接问答型 问题或问题+简短背景 自然语言回答 通用问答、知识解释、客服回复 意图识别准确,回答完整不过度延展 幻觉补全、答非所问
信息抽取型 文本、表格、对话记录 字段列表、表格、JSON 合同抽取、病例抽取、工单归档 字段定义清楚,缺失值处理一致 漏字段、字段越界、格式不统一
重写改写型 原文+风格/长度要求 改写文本 润色、压缩、扩写、风格迁移 保留原意,控制长度与语气 信息失真、风格漂移
分类判断型 样本内容+标签体系 类别或多标签结果 意图识别、情感分析、风险分级 标签边界一致,解释口径统一 标签混淆、判定依据不稳定
多轮澄清型 对话历史+新问题 澄清问题或更新回答 客服、咨询、助手交互 识别缺失信息,追问最小必要信息 重复追问、过早下结论
工具辅助型 任务描述+工具说明 工具调用参数或工具后回答 搜索、数据库查询、日程处理 调用时机正确,参数完整合法 误调用、漏调用、调用后整合错误
约束输出型 指令+schema或格式要求 JSON、XML、表单、固定格式文本 Agent、RAG、系统集成 严格遵守字段、枚举、嵌套结构 格式崩溃、字段缺失、无效值
拒答与边界型 高风险或越权请求 合规拒答或替代建议 安全对齐、权限控制 拒答理由清楚,替代路径适度 生硬拒答、边界不一致
系统规则执行型 指令冲突、多约束输入 优先级一致的响应 平台助手、企业内控场景 system优先级执行,保持语气与策略一致 规则冲突时行为漂移

12.3.5 覆盖优先级如何排序

资源总是有限的,样本不可能一下子把所有地方都补满。所以覆盖顺序这件事,不能只靠感觉,也不能谁声音大就先做谁。很多项目后面做得辛苦,往往不是不努力,而是一开始优先级就排乱了。

通常更稳妥的顺序,还是先把底盘做稳,再把高频做厚,然后把高风险补上,最后再慢慢磨那些真正细的长尾。这个顺序听起来不新鲜,但在实际项目里反而最难坚持,因为大家很容易被两种东西带偏:一种是“看起来很高级”的复杂样本,另一种是“眼前最容易批量生产”的头部样本。前者容易让团队过早沉迷于炫技,后者则容易把数据做成一大片重复而密集的安全区。

先保底盘,说白了就是先保证模型像个系统,而不是像个偶尔发挥不错的演示品。基本的指令遵循、基础格式稳定、系统边界不乱跑、常见拒答能站住,这些东西如果还没稳住,后面再做再复杂的行业样本,收益都不会太高。一个连schema都经常飘、连system优先级都守不住的模型,很难靠几批高难样本突然变得可用。

高频任务要尽早做厚,这一点常常被低估。因为真实系统里的用户并不是平均使用所有功能,而是反复走那几条最常见的路径。企业助手会反复遇到制度问答、流程解释、邮件改写、摘要整理;客服助手会反复遇到退款、物流、发票、账号这些问题。把这些主路径做密、做稳、做全,带来的体验提升通常比零散补很多冷门样本更直接。用户对模型“稳不稳”的第一印象,往往就来自这些地方。

高风险任务不能拖得太后。它们不一定高频,但决定模型能不能真正上线。法律场景里乱下结论,医疗场景里漏掉风险提示,企业场景里越权泄露信息,这种错误哪怕只出现少数几次,也足以让整个系统失去信任。所以高风险样本不是“等大盘做完再说”的边角料,它们应该在底盘和高频基本站住之后,尽快被单独拉出来做定向补强。

长尾样本当然也重要,但它更像后期打磨上限的工作。多轮纠错、异常输入、对抗表达、跨任务组合、复杂约束,这些都很值钱,只是它们更适合建立在前面几层已经稳住的基础上。否则团队很容易出现一种错觉:少量长尾样本做得很精彩,仿佛模型能力很强,实际上主干路径还在掉链子。

如果换成一个更具体的场景来看,比如做企业内部知识助手,第一阶段最该补的不是多跳推理,而是“能按要求回答”“不知道时不乱编”“格式别乱”“权限别越”。第二阶段把制度问答、流程说明、常见术语、高频工单这类主路径做厚。第三阶段再把权限边界、敏感信息、冲突口径这些风险点补齐。等这些基本稳了,再去专门磨多轮追问、历史修正、噪声输入和对抗表达,整个节奏会顺很多。

说到底,覆盖优先级不是一张漂亮的规划表,而是在回答一个很现实的问题:手里这点时间、人力和预算,到底先砸在哪里,最能让模型尽快变得稳定、可用,而且不容易出大错。这个顺序如果排对了,后面的扩写和迭代都会轻很多;如果排错了,团队会一直觉得很忙,但模型进步不明显。


12.4 质量评价与迭代

12.4.1 指令清晰度、响应正确性、格式一致性的评估

SFT数据的质量,不应只靠“看起来不错”来判断。对一个面向生产的标注团队而言,必须把质量拆成可评估、可复核、可回溯的维度。最基础也最重要的三个维度,是指令清晰度、响应正确性和格式一致性。

指令清晰度关注的是监督信号是否明确。一个样本即便答案写得很漂亮,如果instruction本身含糊、约束条件不完整、任务边界摇摆不定,那么它对模型的训练作用就会被削弱。评估时应检查任务意图是否单一明确、输入是否足以支持输出、是否存在隐性要求未显式说明、system与instruction是否冲突。

响应正确性是最直观但也最容易被过度简化的维度。正确性不仅指事实正确,还包括推理过程是否符合题意、结论是否覆盖关键点、是否恰当地表达不确定性、是否在证据不足时避免强答。在领域场景中,还应加入专业口径正确性和风险边界正确性。

格式一致性看起来是低层问题,实际上对可用性影响极大。一个经常在结构化输出上出错的模型,即使内容理解不错,也难以接入真实系统。格式一致性的评估不能只检查括号和字段名,还要检查字段顺序、空值策略、异常返回格式和多轮场景中的响应结构是否稳定。

在很多项目里,这三个维度常常存在“相互掩盖”的现象。比如,某条样本response内容本身没错,但instruction表达模糊,导致标注员和审核员对“正确答案应是什么”理解不一致;又或者某条样本回答逻辑完整,但由于格式不合规,实际训练价值和上线价值都打折扣。因此,质量评估必须拆维度,而不能只打一个笼统的“好/不好”。

更进一步,团队应认识到,质量维度不仅用于验收数据,也用于指导模板优化。若大量样本在指令清晰度上分数偏低,说明模板设计本身就存在表达问题;若大量样本在格式一致性上出错,说明schema或输出约束设计不够稳健;若响应正确性问题集中出现在某类任务,则可能意味着上下文不足、知识点覆盖不够或标注员理解不一致。换句话说,质量打分不是终点,而是通向迭代的诊断工具。

代码示例:用脚本做“格式一致性”离线体检(JSON输出任务)

当你的任务要求“只输出JSON”时,可以先用脚本在入库前做一次硬校验,把“括号不闭合、字段缺失、枚举值越界”等问题尽量挡在训练前。

import json
from typing import Iterable, Dict, Any


SCHEMA = {
    "currency": {"type": "enum", "values": ["CNY", "USD", "EUR", None]},
    "payment_amount": {"type": "number_or_null"},
    "payment_method": {"type": "string_or_null"},
    "payment_due_days": {"type": "number_or_null"},
    "penalty_rate": {"type": "string_or_null"},
}


def _is_number(x: Any) -> bool:
    return isinstance(x, (int, float)) and not isinstance(x, bool)


def validate_response_json(text: str) -> Dict[str, Any]:
    """
    返回一个结构化校验结果,便于统计错误类型。
    """
    try:
        obj = json.loads(text)
    except Exception as e:
        return {"ok": False, "error": "invalid_json", "detail": str(e)}

    if not isinstance(obj, dict):
        return {"ok": False, "error": "not_object"}

    # 1) 必须字段齐全(严格接口对齐场景)
    missing = [k for k in SCHEMA.keys() if k not in obj]
    if missing:
        return {"ok": False, "error": "missing_fields", "detail": missing}

    # 2) 枚举值校验
    currency = obj.get("currency")
    if currency not in SCHEMA["currency"]["values"]:
        return {"ok": False, "error": "invalid_enum", "detail": {"currency": currency}}

    # 3) 类型/空值策略校验(示例只做最常用的几类)
    if obj["payment_amount"] is not None and not _is_number(obj["payment_amount"]):
        return {"ok": False, "error": "type_error", "detail": {"payment_amount": obj["payment_amount"]}}

    if obj["payment_due_days"] is not None and not _is_number(obj["payment_due_days"]):
        return {"ok": False, "error": "type_error", "detail": {"payment_due_days": obj["payment_due_days"]}}

    for k in ["payment_method", "penalty_rate"]:
        if obj[k] is not None and not isinstance(obj[k], str):
            return {"ok": False, "error": "type_error", "detail": {k: obj[k]}}

    return {"ok": True}


def batch_check(responses: Iterable[str]) -> Dict[str, int]:
    stats: Dict[str, int] = {"ok": 0}
    for t in responses:
        r = validate_response_json(t)
        if r["ok"]:
            stats["ok"] += 1
        else:
            stats[r["error"]] = stats.get(r["error"], 0) + 1
    return stats


if __name__ == "__main__":
    demo = [
        "{\"currency\":\"CNY\",\"payment_amount\":null,\"payment_method\":null,\"payment_due_days\":15,\"penalty_rate\":\"每日0.05%\"}",
        "{\"currency\":\"RMB\"}",  # 缺字段 + 枚举越界
        "不是JSON",  # 非法JSON
    ]
    print(batch_check(demo))

12.4.2 除基础三维之外的补充质量维度

只看清晰度、正确性和格式一致性,很多样本表面上已经能过了,可真正放进训练集,问题还是会冒出来。原因就在于,有些样本虽然“答得没错”,却不一定适合拿来教模型。对行业化场景来说,这类样本还不少。

边界与安全性就是最典型的一类补充维度。很多回答在知识点上未必错,但边界上已经出事了。医疗样本里漏掉危险症状提醒,法律样本里把带条件的判断说成确定结论,企业样本里没有守住权限范围,这些都不一定会在“正确性”这一栏里立刻被打成低分,可它们对训练的伤害很大。模型一旦把这种表达学进去,后面再靠偏好或规则往回拽,成本会高很多。

风格适配性也不是表面功夫。不同场景要的不是同一种“好看”。法律场景要克制、条件化、少用绝对措辞;客服场景要稳、清楚、能安抚情绪,还得把下一步说明白;企业内部场景常常更看重简洁直接,不希望模型每次都写成客气的大段话。风格如果总是错位,用户会很快感觉到不对。哪怕内容本身没问题,也会觉得这个系统“不像干这个的”。

可训练性则是另一个很现实的维度。不是所有真实样本都适合直接进主训练集。有些对话当然很真实,但边界过于模糊,连审核员都说不清到底什么才算好答案;有些样本上下文残缺得厉害,标注员只能靠猜补全;还有些样本把多个目标缠在一起,最后谁也说不清模型究竟该学哪一个。这种样本留作评测、红队或者困难集都可以,但如果大面积放进主训练集,监督信号会越来越浑。

这也是为什么很多团队后面会遇到一种奇怪现象:样本看起来很真实,语言也自然,单条抽查时甚至觉得不错,可训练完效果就是不稳。问题并不一定在模型上,很可能就在样本本身不够“可教”。训练集和评测集本来就不该完全重合。训练集需要的是清楚、稳定、可复用的示范,评测集才更适合承载那些真实但含混、复杂甚至故意刁钻的输入。

所以把这些补充维度加进来,真正改变的不是打分表变长了,而是团队开始区分两件事:一件是“这个回答看上去对不对”,另一件是“这条样本拿来训练会不会把模型教偏”。前者解决验收问题,后者解决训练问题。很多数据工作做到后面,真正拉开差距的,往往就是这一步。

12.4.3 失败样本回收与模板修订

SFT建设不可能一轮成型。真正有生命力的数据体系,必然建立在“失败样本回收—原因归因—模板修订—再生成—再验收”的迭代闭环之上。

失败样本的价值并不在于它“错了”,而在于它暴露了模板或规范的缺陷。有些失败来自模型能力不足,但更多失败来自数据设计问题。例如,某类抽取任务频繁漏字段,可能不是模型不行,而是字段定义在不同标注员之间不一致;某类多轮任务常常重复澄清,可能是因为模板中没有明确“何时应直接回答、何时应追问”;某类工具调用输出总是参数不全,可能是因为schema没有把必填与可选字段区分清楚。

因此,失败样本不应只被加入“困难样本池”,更应触发模板和规范层面的修订。每次修订都应回答三个问题:到底是哪一类错误反复出现;这一错误是样本偶发问题,还是模板系统性问题;修订后如何设计回归测试,验证问题是否真正缓解。

这要求标注团队和评测团队不要割裂。前者负责生成监督信号,后者负责验证信号有效性,而闭环的真正价值在于二者围绕“错误模式”建立共同语言。

很多团队的问题在于,失败样本虽然被收集了,但只是作为“坏例子”堆在仓库里,并没有形成结构化归因。更有效的做法,是把失败原因抽象为若干固定类别,例如任务边界不清、字段定义歧义、上下文不足、示范答案过度发挥、多轮状态维护失败、工具参数缺失、拒答边界不一致等。这样一来,团队每次看到一个失败案例,不再只是“修这一条”,而是能迅速判断它属于哪个错误模式,应该回到哪一类模板去修订。

另外,失败样本回收最好分为两个层次。一个层次是训练前的离线失败回收,主要来自人工抽检、静态评测和规则校验;另一个层次是上线后的在线失败回收,主要来自真实用户交互、系统日志和运营反馈。前者有助于在模型上线前解决结构性问题,后者则能提供最真实的场景触发条件。一个成熟的数据闭环,必须同时吸收这两类信号。

12.4.4 数据集版本演进与冻结规则

一套SFT数据集如果没有版本治理,最终一定会失控。新增样本、修改模板、修复标签、替换system、调整格式要求,这些看似局部的变动,都可能改变模型行为分布。因此,数据集版本管理不只是文件命名问题,而是训练可追溯性的基础。

通常来说,数据集版本应至少记录以下内容:样本来源、模板版本、标注规范版本、清洗规则、过滤规则、质量门槛、任务分布、领域分布、难度分布和特殊修订说明。对于关键版本,还应保留冻结快照,以支持模型回滚和行为对比。

所谓冻结规则,核心是界定“什么情况下一个版本可以进入训练主干”。这通常包括覆盖度达标、关键任务质量达标、格式错误率控制在阈值内、核心模板通过回归测试、长尾失败模式得到阶段性修复等。冻结并不意味着不再迭代,而意味着在某一时间点上,为训练实验提供稳定输入边界。

很多团队的问题在于:数据一直在变,但没有明确区分“探索集”“候选主集”“冻结训练集”和“回归测试集”。结果就是每次训练结果波动很大,却无法判断是模型参数问题还是数据漂移问题。对SFT负责人来说,版本治理能力本身就是训练工程能力的一部分。

更细一些说,版本演进通常至少应包含三个层级。第一层是模板版本,记录任务结构和字段规范的变化;第二层是数据版本,记录样本内容和质量门槛的变化;第三层是训练版本,记录某次训练实际使用了哪些模板和哪些数据子集。只有这三层同时可追溯,团队才能真正解释模型行为变化来自哪里。

冻结规则也应尽量量化。例如,关键任务覆盖率需达到某个阈值,结构化输出错误率不能超过某比例,高风险边界样本必须全部通过双审,失败模式回归集中的核心项通过率必须达到某标准。量化不是为了增加流程负担,而是为了让“是否可以训练”不再依赖口头判断。

代码示例:一个“可冻结”的数据集目录与版本文件(推荐形态)

下面给出一种常见、好用、便于追溯的组织方式:模板、样本与回归集分开;每次可训练版本都有一个 MANIFEST(清楚写明“我是谁、从哪来、怎么验收”)。

datasets/
  sft_zh/
    templates/
      legal_contract_payment_terms_v2.yaml
      customer_refund_clarify_v1.yaml
    snapshots/
      v0.3.0/                       # 冻结快照:训练只读
        train.jsonl
        dev.jsonl
        regression.jsonl            # 关键失败模式回归集
        MANIFEST.json               # 版本清单(见下)
{
  "dataset_name": "sft_zh",
  "dataset_version": "v0.3.0",
  "frozen_at": "2026-04-24",
  "inputs": {
    "templates": [
      {"name": "legal_contract_payment_terms_v2", "version": "2.1.0"},
      {"name": "customer_refund_clarify_v1", "version": "1.0.0"}
    ],
    "quality_gate": {
      "json_format_error_rate_max": 0.003,
      "high_risk_double_review_required": true,
      "regression_pass_rate_min": 0.98
    }
  },
  "distribution": {
    "primary_task": {
      "information_extraction": 0.22,
      "multi_turn_clarification": 0.18,
      "constraint_output": 0.25,
      "refusal_boundary": 0.12,
      "other": 0.23
    },
    "risk_level": {"high": 0.15, "medium": 0.35, "low": 0.50}
  },
  "notes": [
    "本版本重点收敛:结构化输出漏字段、信息不足时的过度补全。",
    "新增回归集:tool参数缺失/枚举越界/拒答语气不一致。"
  ]
}

为了便于实际验收,表12-2给出了一个可落地的SFT质量维度评分表示例。

表:SFT 质量维度评分表示例

评分维度 1分 2分 3分 4分 5分
指令清晰度 任务含混,约束缺失,难以判断目标 任务大致可懂,但存在明显歧义 任务基本明确,仍有少量隐含要求 任务清楚,输入输出关系明确 任务边界极清晰,约束完整,无歧义
上下文充分性 上下文不足以支持作答 有部分信息,但关键证据缺失 可基本作答,但仍需推测补全 上下文充分,支撑主要结论 上下文完整且组织合理,支持高质量响应
响应正确性 明显错误或严重偏题 部分正确,遗漏关键内容 主体正确,但细节不足或表达不稳 内容正确完整,少量可优化 内容准确、完整、边界恰当
格式一致性 与要求严重不符 存在多处格式错误 基本符合,偶有不规范 格式稳定,满足使用要求 严格一致,可直接进入系统使用
风格适配性 语气不符合场景 风格有偏差,专业感不足 基本适配,但不够稳定 风格与场景匹配良好 风格高度贴合场景与角色设定
边界与安全性 越界回答或缺少必要提醒 存在边界模糊问题 基本安全,但拒答/提示不稳定 能较好遵守边界 边界意识强,拒答、提示、替代建议都恰当
可训练性 样本噪声大,监督意义弱 有一定训练价值,但问题明显 可用于训练,信号中等 监督信号明确,训练价值高 高密度高质量样本,可作为模板代表样本

在实际操作中,团队可设置加权总分,例如将“响应正确性”“指令清晰度”“边界与安全性”赋予更高权重,并规定进入主训练集的最低门槛。对于不同样本层级,也可以采用不同阈值:基础覆盖样本重视一致性与清晰度,长尾困难样本则允许语言风格略有波动,但不能牺牲边界与正确性。

为了帮助团队理解从生成到修订的整体流程,图12-2给出了样本生成与验收的闭环示意。

图12-2:样本生成与验收的闭环示意图

图12-2:样本生成与验收的闭环示意图

12.4.5 质量评估如何嵌入日常生产流程

高质量SFT团队的一个标志,是质量评估并不是最后的“抽查动作”,而是嵌入在日常生产流程里的。模板编写时就应有规范评审,样本生成时就应有自动规则校验,人工审核时应按维度打分,进入主库前应通过回归集检查,训练后则应用评测结果反推数据薄弱点。

也就是说,质量不是一个单点环节,而是一条贯穿模板、标注、审核、入库、训练和复盘的连续链路。只有这样,质量体系才不会停留在表格上,而会真正影响数据集演进。


12.5 行业案例与承接

12.5.1 法律、医疗、客服等场景的指令体系差异

当SFT进入行业场景时,真正的难点不在于“换一批领域文本”,而在于指令体系本身必须随着行业责任结构而变化。不同场景对模型的要求,不仅体现在知识内容上,更体现在边界、语气、证据、责任和行动建议方式上。

法律场景强调规范性、条件性和边界性。模型不能把法律解释写成生活建议,也不能把不确定条款说成绝对判断。法律SFT中的指令设计,常常要突出“依据给定法条/合同片段回答”“区分事实与解释”“在信息不足时提示需结合司法实践或专业律师意见”。它要求模型形成谨慎、结构化、证据导向的表达方式。

医疗场景则更强调风险分级和安全提示。很多医疗类SFT失败并不是知识错误,而是边界错误。例如,对潜在急症给出了过于轻描淡写的建议,或者对普通症状给出了过度诊断式回应。因此,医疗指令体系必须把“何时建议立即就医、何时只能提供一般信息、何时需要澄清症状”显式编码到数据中。这里的系统任务权重往往高于普通内容任务。

客服场景的重点则在流程性和稳定性。客服模型常常要面对大量高频、低复杂但强规范的任务,例如查询、解释政策、处理退款、安抚情绪、引导下一步操作。与法律和医疗相比,客服场景对格式和语气的稳定要求更高,对领域推理深度要求可能相对低一些,但对多轮一致性和流程可执行性要求更强。

因此,行业SFT不能只在同一套模板里替换“领域词汇”。真正成熟的做法,是围绕行业目标重新定义优先级。例如,法律优先“证据与边界”,医疗优先“安全与分诊”,客服优先“流程与体验”。模板、评分标准和失败样本回收逻辑也应随之变化。

进一步看,这三类行业在数据建设流程上也不同。法律数据往往更依赖条文、案例和合同材料,强调证据可追溯;医疗数据更依赖标准化分诊逻辑和风险升级规则,强调不可过度承诺;客服数据则更依赖业务规则、操作流程和情绪交互设计,强调一致性和可执行性。也就是说,行业差异并不只是“内容不同”,而是训练目标和责任约束都不同。

因此,面向行业的SFT团队不能简单复用通用任务模板后加一点术语包装,而应从“这个行业最怕模型犯什么错”开始反推数据设计。法律最怕无依据断言,医疗最怕风险判断失控,客服最怕流程出错和语气失当。只有围绕行业真正的失败成本去设计指令体系,SFT数据才具备实际价值。

12.5.2 不同行业下system与response的差异化写法

行业差异不仅体现在任务内容,还体现在system和response的写法上。以法律场景为例,system通常会强调依据提供材料回答、避免替代正式法律意见、遇到信息不足时需说明限制。response则应保持审慎、结构清楚、避免绝对化措辞。医疗场景的system则可能更强调风险优先、紧急情况提示和不替代专业诊疗。response需要在信息不足时优先引导补充症状或建议线下就医,而不是直接给出确定诊断。客服场景的system则更可能强调礼貌、效率、流程准确和品牌语气一致;response需要更强的可执行性,例如明确下一步操作、材料要求和时间说明。

这说明,SFT中的system并不是一段通用前缀,而是行业责任结构的集中体现;response也不是“答对就行”,而要体现行业所要求的语气、边界和行动方式。

很多团队在这一步吃亏,往往不是因为不知道要区分行业,而是把system写得太空,把response写得太像通用好答案。system里写一句“你是专业助手,请准确回答用户问题”,看上去没有错,但放到法律、医疗、客服这些高责任场景里,其实几乎没有提供真正有效的行为约束。这样的system太泛,谁都能用,结果就是谁都没被真正定义。

法律场景下的system,通常要先把“依据什么回答”和“不能替代什么”交代清楚。它要提醒模型:结论必须建立在给定法条、合同片段、案件材料或用户提供事实之上;若信息不足,应明确说明判断范围有限;不得把一般信息表达成正式法律意见。这样的system一旦写稳,模型在response里才更容易保留条件、说明依据、控制语气。否则它很容易沿着通用问答的惯性,把所有问题都往“给出一个完整结论”的方向推。

法律response的写法,也不只是把语气放得谨慎一点。更关键的是,它往往要体现一种层次:哪些是用户给出的事实,哪些是材料中可以直接支持的内容,哪些是基于这些材料做出的解释,哪些地方目前还不能确定。真正合适的法律response,常常不是一句压轴式判断,而是一种把结论放回证据框架里的说法。这样写出来的答案,虽然不一定最“痛快”,但更符合这个行业对责任和边界的要求。

医疗场景下的system则往往把“安全优先”放在更靠前的位置。它需要明确告诉模型:当存在潜在危险信号时,应优先提示尽快就医或急诊,而不是继续做安慰式解释;当信息明显不足时,应先引导补充症状、持续时间、严重程度和伴随情况;模型可以提供一般健康信息,但不能替代正式诊疗。这样写system,不是为了把模型写得更保守,而是为了让它在真正关键的时候先做对分流,而不是先做对表达。

医疗response的差异也很明显。它通常不能太快进入“像诊断一样”的陈述,而应该先判断当前信息够不够、风险高不高、用户最需要的是科普、观察建议还是立刻就医的提醒。尤其在信息不足的时候,response更合适的写法往往不是直接猜一个方向,而是先把需要补充的症状问出来,或者先把高风险情况排除掉。真正好的医疗response,不是看起来最像医生,而是最能在安全边界内帮助用户做下一步判断。

客服场景的system又是另一种写法。它更强调语气一致、流程准确、引导清楚和品牌规范。法律和医疗更关注“不要越界”,客服则常常更关注“不要掉链子”。模型需要知道哪些步骤必须说,哪些承诺不能乱给,哪些话术要保持稳定,什么时候应该安抚情绪,什么时候应该直接给用户下一步操作。客服system如果写得太泛,模型就会在多轮交互里越聊越散,最后变成一种很客气但不解决问题的回答风格。

客服response也因此更强调动作性。它不只是把事情解释清楚,还要把事情往前推进。比如告诉用户下一步要提供什么信息、预计多久处理、如果当前条件不满足该怎么办、是否需要转人工、哪里可以查询进度。相比法律和医疗,客服response通常不需要保留太多理论分析,却特别需要保持口径稳定、节奏清楚、措辞友好。如果一个客服回答内容都对,但下一步讲不清、材料要求前后不一,用户仍然会觉得系统不好用。

这三类行业放在一起看,就会发现system和response其实是在共同定义“行业行为风格”。system更像上层约束,告诉模型这个行业把什么放在前面;response则是把这种优先级真正落到语言和动作上。法律把依据和边界放在前面,医疗把安全和分流放在前面,客服把流程和体验放在前面。它们并不是换几句口气,而是在回答同一个问题:在这个行业里,模型最先该守住什么。

因此,写行业SFT样本时,不能把system当作永远不变的背景板,也不能把response当成“把问题答对”的最后一步。system和response之间应该形成明显的呼应关系。system里强调了什么,response里就应该体现什么;system里限定了什么,response里就不该越过去。要是两者之间没有这种呼应,整个样本虽然看起来完整,实际教给模型的东西还是松的。

从工程上说,行业差异最终都会沉到这些很具体的写法里。数据团队如果只在任务层面说“这是法律数据、这是医疗数据、这是客服数据”,但没有把system和response写出真正不同的责任感和动作感,训练出来的模型大概率还是一个通用底色很重的助手。只有当行业要求进入到字段级、句式级、边界级的写法里,行业SFT才算真正落地。

12.5.3 SFT数据如何承接偏好数据和工具调用数据

SFT不是终点。对大多数现代大模型系统而言,SFT之后通常还会接偏好优化数据、工具调用数据、轨迹数据或在线反馈数据。因此,在设计SFT阶段时,团队就应考虑后续承接关系。

首先,SFT决定了模型的基础行为空间。偏好数据并不是从零开始教模型,而是在一个已被SFT塑形的行为分布上做选择性偏置。如果SFT阶段没有把可接受输出空间收紧,后续偏好优化就会变得低效,因为模型可能在完全错误的响应区域中大幅波动。换句话说,SFT负责先把模型带到“候选答案大体都像样”的区域,偏好数据再决定“哪一种像样更受欢迎”。

其次,工具调用数据对SFT具有很强的前置依赖。一个不会稳定理解schema、不会区分自然语言回答和行动指令边界的模型,很难在工具调用阶段表现出色。因此,哪怕当前项目尚未进入完整Agent阶段,SFT中也应预留一部分“结构化行动表达”样本,让模型熟悉调用式交互的基本范式。

再次,偏好数据与工具数据的标注逻辑,也可以反向影响SFT规范。例如,如果后续偏好阶段非常关注“简洁但不失关键信息”,那么SFT阶段就不能一味鼓励冗长回答;如果后续工具阶段要求严格JSON schema,那么SFT阶段就应尽早让模型习惯字段级约束与异常值处理。

从工程链路上看,更稳妥的做法是把SFT设计成一个承上启下的中间层:向前兼容基础模型能力,向后兼容偏好建模和工具学习。这样,数据体系才不是孤立工件,而是训练栈中的结构性组成部分。

更具体地说,SFT对偏好数据的承接,主要体现在三个方面。第一,是收窄答案空间。让模型在进入偏好优化之前,先学会哪些回答方式大致可接受。第二,是显式暴露可比较维度,例如简洁性、礼貌性、结构性、证据完整性,这样后续偏好排序才更容易发挥作用。第三,是避免把明显错误或低质风格带入后续阶段,否则偏好数据不得不花大量容量去“纠偏”,而不是做细化优化。

SFT对工具调用数据的承接,则主要体现在接口纪律上。模型首先要理解什么时候应该回答,什么时候应该行动;其次要学会把工具名、参数和自然语言解释区分开;最后还要学会在工具结果返回后如何把结果整合成最终答复。如果这些前置习惯没有在SFT阶段打好基础,后续工具学习往往会显得脆弱,容易在真实工作流里失控。

12.5.4 一个面向团队协作的承接思路

对于负责数据设计与标注规范的团队而言,最实用的承接思路,不是把偏好数据、工具数据看作“下一个阶段的事”,而是在SFT阶段就保留接口意识。也就是说,在模板设计时就考虑哪些字段未来可用于偏好比较,哪些任务未来可能扩展为工具调用,哪些system规则未来将成为Agent控制规则。

这样做的好处,是避免训练栈各阶段各自为战。SFT不是孤立地造一堆样本,而是在为后续更复杂的行为学习准备基础结构。一个具有承接意识的SFT数据体系,往往更容易扩展,也更经得起后期产品需求变化。


本章小结

SFT数据设计的核心,不是“做多少问答对”,而是“如何把任务结构、行为边界、输出规范和场景责任编码为高质量监督信号”。对负责指令微调数据设计和标注规范的团队而言,真正需要建立的是一整套可持续运转的方法:先明确SFT在能力对齐中的定位,再按通用、技能、领域、系统四层组织任务;通过单轮、多轮、工具辅助、约束输出等模板把任务抽象为可复用样本;用能力覆盖矩阵和知识点地图控制数据分布;再通过质量评分、失败样本回收、模板修订和版本冻结构建长期迭代闭环。

当团队具备这套方法之后,SFT数据集就不再只是训练前的一次性交付物,而会成为模型行为设计的主战场。它既决定模型是否听话,也决定模型是否能以正确的方式使用已有能力;它既服务当前任务,也为后续偏好优化、工具调用和系统化部署打下接口基础。对于真正面向生产环境的大模型系统而言,SFT不是“补一点数据”,而是“设计模型如何工作”。

从实践角度总结,本章有三个最重要的落点。第一,SFT的目标必须被工程化,团队要明确它负责什么、不负责什么。第二,SFT数据必须体系化,不能停留在零散问答和经验驱动的样本堆积上。第三,SFT建设必须闭环化,模板、样本、评测、失败归因和版本治理应成为一个长期运行的系统。只有这样,SFT才能真正承担起“把大模型变成可部署系统”的关键职责。

参考文献