这道题问的是[[SFT]] prompt模板的设计,其实本质是在问:你如何给模型设计一个受控的交互协议,让它能准确理解任务、稳定输出。不是随便写个句子就行,而是要考虑角色、边界和扩展性。
核心原则我重点讲两个。先说角色分离。说白了就是把system、user、assistant三个角色划清楚。system设定全局行为,比如人设、安全策略、输出格式;user承载具体指令和输入;assistant就是模型要学习的标准输出。如果混在一起,模型容易混淆到底该听谁的。再一个是指令结构化,也就是把任务指令和输入上下文明确分开。比如翻译任务,instruction是“将以下中文句子翻译成英文”,input是具体句子,output是译文。如果混在一起写,模型可能把部分输入当成指令,导致理解偏差。
举个例子,Alpaca格式就是典型的结构化模板,它用三个字段把instruction、input、output分开。实际对话里,像Llama-2-chat风格会封装成带特殊标记的模板:用<<SYS>>包系统指令,[INST]和[/INST]标出用户输入边界,<s>和</s>控制生成起始和结束。这些组件各有作用:系统指令锚点定义基础行为,边界符让模型知道指令从哪开始到哪结束,占位符保证模板复用。
这里有个坑:不同基座模型的chat template差异很大。比如Qwen用<|im_start|>,ChatGLM用[Round]。如果你不严格对齐,模型可能把特殊token当成普通文本输出,或者生成位置错乱。所以上线前一定要确认模板和模型训练时用的格式一致。
另外,我特别看重system字段的扩展性。实际业务中,你可能需要根据用户场景动态切换人设或安全策略,比如客服场景和金融场景的system指令不同。如果模板把system写死,后面改起来就很麻烦。所以我会在模板里预留system的动态注入接口,这样可以通过system prompt做能力切换,而不动整体模板结构。
还有一个容易被忽略的点是output的多样性。同一个input,如果只配一个output,模型学到的映射太单一。我会配多个高质量的output,比如不同的表达方式或风格,这样数据丰富度更高,模型泛化能力更强。
说到输出多样性,其实引出一个更深入的问题:如果output质量参差不齐,反而会引入噪声。所以我会在数据清洗环节做一致性校验,确保多个output在语义上等价,并且符合任务要求。
所以整体上,我会把SFT prompt模板看作一个受控接口,核心是角色分离、结构化、对齐基座模型,同时留好扩展性。这样模型才能稳定输出,也方便后续迭代。