6.3 可控生成
在模型对齐的基础上,可控生成技术旨在精确驾驭模型的输出。从基础的提示词工程(如角色设定、格式约束)到引导模型思考的高级技巧(如思维链),再到强制性的结构化输出控制和参数级微调(如温度、Top-p),这些方法共同构成了一个工具箱,让开发者能够确保模型生成的内容在格式、风格和内容上都符合预期。
经过指令微调和对齐优化后,语言模型已经能听懂人话,且大致按照人类期望行为。然而,这些还远远不够。实际应用中,我们希望能够更加精确地控制模型输出的格式、内容、风格甚至是思维过程。这就是 可控生成(Controllable Generation) 技术所要解决的核心问题。
6.3.1 提示词工程
可控生成中,最基础也是最重要的技术是 提示词工程(Prompt Engineering)。简单地说,就是对模型提问时,输入经过精心设计和组合的词句,使其产生更准确、更有用、更给力的输出。
提示词工程有很多技巧,我们先简单介绍三个最基础也是最核心的技巧。
1. 清晰、明确的指令
清晰、明确的指令是控制语言模型输出的第一道防线。
大模型虽然聪明,但它并不能“读心”。模糊的提示会让模型陷入猜测、主观臆断、语义漂移,导致结果不准确、不完整、风格飘忽不定。
比如,当你只说“写一个函数”,模型并不确定你想用什么语言、解决什么问题。但如果你改成:
请用Python编写一个函数,接收两个整数参数,返回它们的最大公约数,使用欧几里得算法实现。
模型的输出就变得更加准确、有用、对齐。
语言模型是通过上下文预测下一个词的,因此越是具体、明确的上下文,越容易收敛出符合预期的输出。尤其在包含多个潜在选择(语言/算法/风格)的场景下,模糊提示等于放任模型“自由发挥”。
除了清晰描述“做什么”,还可以补充“不做什么”,用负面约束增强准确性。
2. 角色设定
大模型的语言风格、知识重点、表达方式会因“身份”设定而发生显著变化。提示词中加入角色设定,可以让模型在语气、知识水平、专业术语、写作风格等方面更贴近你期望的输出风格。比如:
你是一位经验丰富的Python导师。现在需要向初学者解释列表推导式的概念,请用简单易懂的语言,并提供具体例子。
你也可以换一种角色对比查看下同一问题不同角色下的输出对比。
一般模型聊天系统中通常会把角色设定常放在 系统提示(system prompt) 中,这样能影响整个对话过程中的风格,而不仅限于单轮。
3. 输出格式约束
很多时候,我们不仅想让模型“说得对”,还想它“说得整齐”。通过在提示词中明确说明期望的输出格式,我们可以让模型生成结构化内容,如 Markdown、JSON、表格、段落、甚至 LaTeX 公式等。比如:
请分析下面代码的时间复杂度,按照以下格式回答:
算法分析:[简要描述算法逻辑]
时间复杂度:[Big O表示法]
解释:[详细解释为什么是这个复杂度]
6.3.2 引导模型“思考”
初级提示词只是详细说明“做什么”,而高级提示技巧则尝试教模型“怎么做”,从而进一步提高可控性。这里我们介绍三种典型的技巧:
思维链提示(Chain-of-Thought Prompting)
通过引导模型按步骤思考,提升其在推理、计算、规划等复杂任务中的表现。
比如当用户输入“请使用 Python 解决这个编程问题,并展示你的思考过程:给定一个数组,找到其中缺失的最小正整数”,模型的回答如下:
让我一步步思考这个问题:
步骤1:理解问题
- 需要找到数组中缺失的最小正整数
- 正整数指1, 2, 3, 4...
- 如果数组是[1, 2, 4],那么缺失的最小正整数是3
步骤2:分析方法
- 可以使用哈希集合来记录存在的数字
- 从1开始遍历,找到第一个不在集合中的数字
步骤3:实现代码
def find_missing_positive(nums):
num_set = set(nums)
i = 1
while i in num_set:
i += 1
return i
这种技巧可以显著提升数学题、逻辑题、代码调试类问题的正确率。
少样本提示(Few-shot Prompting)
通过在提示词中提供几个示例来建立模式,让模型理解期望的输出风格。
比如我们可以这样输入提示词:
请按照下面的风格为函数编写文档注释:
示例1:
def add(a, b):
"""
计算两个数的和
Args:
a (int): 第一个数
b (int): 第二个数
Returns:
int: 两数之和
"""
return a + b
现在请为这个函数编写类似风格的文档:
def factorial(n):
if n <= 1:
return 1
return n * factorial(n - 1)
我们在提示词中给定一个或多个示例,再让模型基于示例去输出期望的风格,这种方式有点“举一反三”的意思,模型可以从多个例子中掌握规律后再作答。
自我一致性(Self-Consistency)
让模型多次解决同一个问题,然后选择最一致的答案。比如:
这个编程问题请用三种不同的方法解决,然后比较哪种方法最优:
[问题描述]
方法1:[第一种解法]
方法2:[第二种解法]
方法3:[第三种解法]
比较分析:[从时间复杂度、空间复杂度、代码可读性等角度比较]
推荐方案:[说明推荐哪种方法及原因]
6.3.3 结构化输出控制
在提示词工程中,我们通过自然语言提示引导模型按照特定格式输出内容,这种方式可以称为“格式引导”或“软约束”。它依赖的是模型对语言指令的理解能力,虽然灵活但也不总是可靠。然而,在真实的生产环境中,模型输出往往需要被其他系统直接解析或用于程序逻辑处理,比如生成符合某种 JSON Schema 的数据,或返回结构化报告。这时,我们就需要一种更强约束、更可靠的生成方式 —— 结构化输出控制(Structured Output Control),也被称为 语法约束生成(Grammar-Constrained Generation)。
与提示词引导不同,结构化控制不是“建议模型怎么写”,而是从生成机制层面“硬性规定”模型只能生成满足结构要求的内容。它可以通过语法规则、模板占位符或约束条件,严格限定输出的语法结构与格式范围,从而实现可预测、可校验、可复用的模型输出。
1. 语法引导生成
语法引导(Grammar-Guided Generation) 是通过构建语法规范(如 BNF、JSON Schema、正则等)并将其嵌入到生成过程中的方式。它的原理是在解码过程中动态筛选候选词,只保留那些符合当前语法路径的输出,最终形成一棵合规的“生成树”。
举例来说,如果我们希望模型输出一个特定结构的 JSON,比如用于分析函数性能,我们可以先定义一个 JSON Schema:
{
"type": "object",
"properties": {
"function_analysis": {
"type": "object",
"properties": {
"complexity": {"type": "string"},
"optimization_suggestions": {"type": "array", "items": {"type": "string"}}
},
"required": ["complexity", "optimization_suggestions"]
}
}
}
配合语法引导生成的提示词或大模型提供的技术手段,模型将只能生成符合该Schema结构的JSON,否则生成会被拒绝或回退。这对于生成代码分析报告、结构化问答、表单自动填充等任务尤为重要。
2. 约束解码
除了结构上的语法控制,我们还可以对生成内容的语义和行为层面加以约束。这种方式称为 约束解码(Constrained Decoding),通常用于要求模型满足某些功能特征或生成模式。
例如,当我们希望模型生成符合特定编码规范的 Python 函数时,可以设置如下逻辑规则:
constraints = [
"must_contain_try_except",
"must_have_docstring",
"must_use_type_hints"
]
在生成过程中,模型会实时检测是否满足这些语义条件,如未满足则通过惩罚机制回退、重采样,直到符合全部约束。这种方法在代码生成、自然语言计划(NL2Plan)等任务中尤为常见。
3. 模板填充
模板填充(Template Filling) 是一种更直接的结构控制方法。它的思路是预先定义一个格式模板或占位框架,由模型在其中“填空”,避免自由生成带来的不可控性。
例如,一个代码质量评审模板可能如下:
# 代码审查模板
template = """
代码质量评估:
功能正确性:[评分1-10] - [详细说明]
性能效率:[评分1-10] - [详细说明]
代码风格:[评分1-10] - [详细说明]
改进建议:
1. [具体建议1]
2. [具体建议2]
总体评价:[简短总结]
将这个模板作为生成任务的结构要求,提示模型按模板结构填充内容而非自由写作,可以显著提升输出的可读性、一致性和系统可解析性。这在构建 AI 助手报告、文档生成、结构化写作等场景中非常常见。
6.3.4 安全过滤机制
安全性不仅是在训练模型时靠 RLHF 或 Constitutional AI 就可以完美解决的问题,它还需要在模型实际部署过程中加以运行时控制。
这类控制手段被称为安全过滤机制,可以拦截风险提示、审查模型输出、评估多轮上下文,防止模型生成违法、攻击性或敏感内容。
几种比较典型的方式是:
- 输入拦截:对用户输入进行关键词检测和语义评估,发现风险提示词时直接拒绝处理;
- 输出过滤:在模型完成生成后,使用正则、关键词、内容规则等进行拦截;
- 上下文评估:结合对话上下文、会话历史,识别用户是否试图通过多轮套话绕过安全限制。
虽然它和对齐优化中部分内容目标是相似的,但他们处于不同的阶段,对齐优化属于训练阶段,是“教模型有良知”。而安全过滤属于推理阶段,是“加一道最后的守门人”。从工程角度看,对齐是教育,过滤是监管,两者缺一不可。
6.3.5 参数级控制
除了提示词工程和结构化输出控制,我们还可以通过微调生成参数来影响模型的输出风格和行为。这些参数就像控制台上的旋钮,决定了模型在生成过程中的“胆大”还是“稳重”、“丰富”还是“简洁”、“跳脱”还是“规矩”。
我们介绍三类最常用、最核心的参数控制策略,如果你有使用过 OpenAI、DeepSeek 等大模型的 API,一定会在接口文档中见过这些参数:
温度(Temperature)
温度参数是最直观的行为调节器,它控制的是模型在生成过程中“冒险”的程度,也就是对概率分布的平滑程度。
- 低温度(如 0.1 ~ 0.3):模型倾向于选择概率最高的词,生成内容稳定、保守、重复度高。适合需要准确、规整输出的场景,如生成代码、填表、问答等。
- 高温度(如 0.7 ~ 1.0):模型会更愿意尝试低概率词,输出更具创造性、想象力和多样性,但可能伴随逻辑跳跃或偶发性错误。适合写作创意、头脑风暴等场景。
比如我们输入“给我写一首关于雪的短诗”:
Temperature = 0.2:雪落无声,冬夜安静,树影微斜,世界宁明。
Temperature = 0.9:银羽飘舞,思绪滑入月光下的梦,冰凉的孤独被窗灯点燃成诗。
核心采样(Top-p)
Top-p 也叫 nucleus sampling(核心采样),它控制的是模型在每次生成时只从“累计概率前 p 的词”中挑选。与温度不同,Top-p 不是调整分布形状,而是截断低概率选项。
- 较小的 p 值(如 0.1 ~ 0.3):只考虑最可能的少量词,输出更确定但单一。
- 较大的 p 值(如 0.8 ~ 0.95):纳入更多可能词汇,输出更丰富、发散,但可能降低精度。
比如我们输入“形容一个程序员的工作状态”:
Top-p = 0.2:安静、专注、持续敲键。
Top-p = 0.9:精神高度集中,像黑夜中的光标,一闪一闪,把思想打磨成代码。
频率惩罚(Frequency Penalty)
频率惩罚参数(在 OpenAI 等 API 中通常为 frequency_penalty)是用于降低模型重复使用同一个词的倾向。这尤其适用于防止生成啰嗦或机械重复的场景。
- 默认值为 0,表示不惩罚重复。
- 较高值(如 0.5 ~ 1.0) 会显著降低模型重复使用词语的概率,从而提高表达多样性。
比如我们输入“请描述春天的美好”:
无频率惩罚:春天很美,美在花开,美在阳光,美在绿意,美在希望……
添加频率惩罚:春天是一幅充满活力的画卷,阳光透过枝叶,洒在新生的花蕾上,空气中弥漫着青草的气息。
Last updated on
6.2 对齐优化
指令微调教会模型“听懂话”,而对齐优化则教模型“说对话”。为确保模型行为符合人类安全、伦理和价值观,研究者们提出了基于人类反馈的强化学习(RLHF)和宪法式AI等方法。这些技术通过人类偏好或预设原则来引导模型,使其在执行任务时不仅有效,而且负责任,尤其是在编程等高风险领域。
6.4 如何放大模型能力?
尽管大模型本身能力强大,但其知识截止日期、计算能力瓶颈、缺乏实时交互以及无法持续学习等内在局限性,使其难以独立应对真实世界的复杂任务。要真正释放其潜力、放大其能力,就必须将其与外部工具、实时数据源、专业知识库和API进行整合,使其从一个封闭的“语言大脑”演变为一个开放的、能够与世界互动的智能体。