引言
在大语言模型(Large Language Model, LLM)中,“思维链”提示(Chain of Thought Prompting,CoT)指的是让模型显式产出中间推理步骤,帮助其在回答复杂问题时更可靠、更具可解释性。根据是否在提示中提供示例来演示“如何写出思维链”,CoT可分为:
- 少样本思维链提示(Few-Shot CoT Prompting):在提示中包含若干带有思维链的示例。
- 零样本思维链提示(Zero-Shot CoT Prompting):仅用文字指令“要求模型给出思维过程”,不提供具体思维链示例。
二者都旨在提高大语言模型的推理质量。本文将结合更多数学公式,深入剖析Few-Shot与Zero-Shot CoT的核心原理与实现方式。
思维链(Chain of Thought, CoT)简述
思维链(CoT)可以理解为一条从问题 QQQ 到答案 AAA 的显式“推理路径”。在生成式语言模型中,若我们让模型在输出最终答案前,先写出一段(或多段)文本来阐明它的思考过程(例如逻辑、计算步骤等),就能显著减少“跳步”或错误回答,并且为人类用户提供可解释的中间结论。
在数学上,可将思维链 CCC 视为问题 QQQ 与答案 AAA 之间的某个中间(或辅助)变量。当我们只看最终答案时,模型实际上暗含了一个对 CCC 的内部推理;而当我们使用CoT提示时,就让这个内部推理在最终输出中得以显式呈现。
少样本思维链提示(Few-Shot CoT Prompting)
定义与动机
- 少样本(Few-Shot):在给模型的提示(Prompt)里,先提供少量“带有思维链的示例”作为范例,然后再提出新的问题,期望模型按类似形式输出“思维链 + 答案”。
- 动机:
- 示范学习(in-context learning):大模型会从提示示例中“模仿”如何先写出推理过程,再得出结论;
- 复杂任务的可解释性:某些任务(如数学题、逻辑推断)需要多步推理;示例能让模型更轻松地抓住如何分步思考;
- 减少幻觉与错误:拥有思维链示例后,模型更倾向于“循迹”而不是无中生有地跳到答案。
数学模型
在Few-Shot场景下,假设我们给模型提供了 kkk 个示例,记为
{(Q1,C1,A1), (Q2,C2,A2),…,(Qk,Ck,Ak)},
\Bigl\{(Q_1, C_1, A_1),\, (Q_2, C_2, A_2), \dots, (Q_k, C_k, A_k)\Bigr\},
{(Q1,C1,A1),(Q2,C2,A2),…,(Qk,Ck,Ak)},
并且我们还有一个新问题 QnewQ_{\text{new}}Qnew,要求模型输出
Ynew=(Cnew,Anew).
Y_{\text{new}} = (C_{\text{new}}, A_{\text{new}}).
Ynew=(Cnew,Anew).
这里:
- QiQ_iQi 是第iii个示例的问题;
- CiC_iCi 是该示例的思维链(显式推理过程);
- AiA_iAi 是该示例的最终答案。
提示可表示为一个大序列 XXX,其中顺序地拼接了 kkk 个示例,再加上新问题:
X=(Q1, C1, A1;Q2, C2, A2;… ;Qk, Ck, Ak;Qnew).
X = \Bigl(Q_1,\,C_1,\,A_1;\quad Q_2,\,C_2,\,A_2;\quad \dots;\quad Q_k,\,C_k,\,A_k;\quad Q_{\text{new}}\Bigr).
X=(Q1,C1,A1;Q2,C2,A2;…;Qk,Ck,Ak;Qnew).
基于语言模型的自回归性质,模型会根据
Pθ(Cnew,Anew ∣ X)
P_\theta(C_{\text{new}}, A_{\text{new}} \;\big\vert\; X)
Pθ(Cnew,AnewX)
进行采样或解码,试图在输出里“复制”并“类比”示例中的推理风格。
如果从条件分布角度写得更显式一点:
Pθ(Cnew,Anew ∣ Qnew,{Qi,Ci,Ai}i=1k).
P_\theta\bigl(C_{\text{new}}, A_{\text{new}} \;\big\vert\; Q_{\text{new}}, \{Q_i, C_i, A_i\}_{i=1}^k\bigr).
Pθ(Cnew,AnewQnew,{Qi,Ci,Ai}i=1k).
模型倾向于在生成 CnewC_{\text{new}}Cnew 的同时,借鉴示例里对问题—思维链—答案的映射关系。
训练或推理过程
- 在推理阶段(推断新问题时),我们会直接把上述提示 XXX 输入到模型的上下文中,让其生成 Cnew,AnewC_{\text{new}}, A_{\text{new}}Cnew,Anew。
- 在训练或微调(如有)时,可采用对带有思维链标注的数据进行明示或暗示式训练,使模型学会“当看到问题就输出中间推理+答案”。
- 对于大多数开箱即用的LLM(如GPT系列),通常是直接推理,不做额外训练,只要在Prompt中给出少样本示例即可。
示例
假设我们想让模型做一些简单数学计算。我们提供两条示例(Two-Shot为例):
-
示例1:
- 问:2+3=?2 + 3 = ?2+3=?
- 思维链:“先把2和3相加,得到5”\text{“先把2和3相加,得到5”}“先把2和3相加,得到5”
- 答案:5
-
示例2:
- 问:5+7=?5 + 7 = ?5+7=?
- 思维链:“5和7相加得到12”\text{“5和7相加得到12”}“5和7相加得到12”
- 答案:12
然后我们提出新问题:10+6=?10 + 6 = ?10+6=?。把上面所有内容拼成提示让模型看:
问题:2+3=? 思维链:先把2和3相加得到5 答案:5
问题:5+7=? 思维链:5与7相加得到12 答案:12
问题:10+6=? 思维链:
模型就会模仿上述示例的形式输出:
思维链:先把10和6相加得到16
答案:16
零样本思维链提示(Zero-Shot CoT Prompting)
定义与特点
- 零样本(Zero-Shot):“不提供”任何带有思维链的具体示例,而是使用指令或问题中一句类似**“请详细列出你的推理过程”**的文本,引导模型输出思维链。
- 特点:
- 提示非常简洁,主要依赖模型对自然语言指令的理解;
- 模型必须具备在预训练或微调中学到的“如何撰写中间推理”之能力,才能产生有用的思维链;
- 适合对提示长度有限制、或想直接用自然语言指令触发CoT的场景。
数学视角
零样本时,给定新问题 QnewQ_{\text{new}}Qnew,我们只添加一句文本说明,如“请写下你的思维过程并给出答案”——记做指令 III。整个提示可写为:
X′={I, Qnew}.
X' = \{ I,\; Q_{\text{new}}\}.
X′={I,Qnew}.
模型的任务是基于
Pθ(Cnew,Anew ∣ X′)
P_\theta(C_{\text{new}}, A_{\text{new}} \;\big\vert\; X')
Pθ(Cnew,AnewX′)
来生成显式推理过程 CnewC_{\text{new}}Cnew 以及最终回答 AnewA_{\text{new}}Anew。
如果再展开,可写为:
Pθ(Cnew,Anew∣Qnew,I)=∏t=1TPθ(yt∣y1:t−1,Qnew,I),
P_\theta(C_{\text{new}}, A_{\text{new}} \mid Q_{\text{new}}, I)
= \prod_{t=1}^{T} P_\theta\bigl(y_t \mid y_{1:t-1}, Q_{\text{new}}, I \bigr),
Pθ(Cnew,Anew∣Qnew,I)=t=1∏TPθ(yt∣y1:t−1,Qnew,I),
其中 yty_tyt 表示生成序列的第 ttt 个token(可能是思维链的一部分,也可能是答案的一部分)。与Few-Shot不同的是,这里不包含{Qi,Ci,Ai}\{Q_i, C_i, A_i\}{Qi,Ci,Ai}示例的限制或引导,完全依靠模型对指令 III 的理解。
示例
还是同一个问题 10+6=?10 + 6 = ?10+6=?,零样本提示可以非常简洁:
请写出你的详细推理步骤,并在最后给出答案。 问题:10+6=? 思维链:
如果模型能力足够,则会自行输出:
思维链:将10和6相加,得到16
答案:16
Few-Shot 与 Zero-Shot CoT 的对比
方面 | Few-Shot CoT Prompting | Zero-Shot CoT Prompting |
---|---|---|
示例数量 | 需要若干带思维链示例(如2~5个以上) | 不提供任何带思维链示例,只有指令 |
Prompt 长度 | 往往更长;需容纳示例的“问题-思维链-答案” | 相对更短,只给自然语言指令和新问题 |
对模型能力依赖 | 模型需能基于示例“模仿”输出CoT | 模型需能通过指令触发CoT生成,要求模型本身更“通用” |
对复杂任务的效果 | 通常更好:示例能帮助模型对齐正确的推理模式 | 效果有时不如Few-Shot;但大型模型在零样本下也可能表现出色 |
典型场景 | 复杂计算、多跳问答时,提供示例可大幅减少错误 | 快速试用,或场景受限时用简单指令触发CoT |
提示工程成本 | 需要精心构造示例、占用一定Token长度 | 提示更简洁,但不一定保证最佳效果 |
应用效果与局限性
-
应用效果
- 对于复杂任务(数学推理、逻辑问答、多跳推理等),思维链提示能有效提高正确率和可解释性;
- 在Few-Shot场景下,展示的示例越贴近目标任务,模型越容易生成“正确风格”的推理;
- 在Zero-Shot场景下,若模型规模和质量足够,简单的“请展示推理”也能得到不错的结果。
-
局限性
- Hallucination(幻觉)仍可能存在:即使有CoT,一旦模型“想偏了”,它会输出看似合理、实则错误的推理过程;
- 对提示工程的依赖:Few-Shot需要示例收集、编写;Zero-Shot对模型能力要求更高,且指令设计也有技巧;
- 长文本成本:尤其Few-Shot时可能耗费大量Token来展示示例,在实际系统中需要权衡上下文长度限制;
- 安全与隐私:思维链中可能包含敏感或错误信息,也需要注意在某些场景下是否允许对外暴露中间推理。
总结
少样本与零样本思维链提示(Few-Shot & Zero-Shot CoT Prompting),是提升大语言模型多步推理能力的重要方法:
- Few-Shot CoT:通过展示带有“问题—思维链—答案”的示例,引导模型模仿示例的方式来思考并回答新问题。
- Zero-Shot CoT:直接通过一句指令,要求模型给出显式推理过程。
这两种方式在学术界和工业界广泛使用,用于数学运算、逻辑推断、多跳阅读理解等任务。随着模型规模的增大,Zero-Shot CoT的表现也越来越好,但当任务特别复杂或需要高度定制时,Few-Shot CoT往往能更好地“规范”模型输出。对于任何想利用大语言模型进行深度推理的开发者或研究者而言,充分掌握Few-Shot与Zero-Shot CoT的使用与差异,是提升模型表现、减少错误与幻觉的关键。
示例代码
以下为简单的伪代码示例,展示如何在Python中构造Few-Shot与Zero-Shot CoT Prompt。真实应用中,需要使用真实的模型API(例如OpenAI API)来发送这些Prompt并获得模型回复。
def few_shot_cot_prompt(question):
"""
构造 Few-Shot CoT 提示示例(仅演示)。
"""
examples = [
{
"Q": "2+3=?",
"C": "思维链:先把2和3相加得5",
"A": "5"
},
{
"Q": "5+7=?",
"C": "思维链:先把5和7相加得12",
"A": "12"
}
]
# 将示例及新问题拼接成提示
prompt_text = ""
for ex in examples:
prompt_text += f"问题:{ex['Q']}\n{ex['C']}\n答案:{ex['A']}\n\n"
prompt_text += f"问题:{question}\n思维链:"
return prompt_text
def zero_shot_cot_prompt(question):
"""
构造 Zero-Shot CoT 提示示例(仅演示)。
直接用一句话让模型生成思维链和答案。
"""
prompt_text = (
"请展示你的完整推理过程,并在最后给出答案。\n"
f"问题:{question}\n思维链:"
)
return prompt_text
# 测试
test_question = "10+6=?"
few_shot_prompt = few_shot_cot_prompt(test_question)
zero_shot_prompt = zero_shot_cot_prompt(test_question)
print("=== Few-Shot CoT Prompt ===")
print(few_shot_prompt)
print("\n=== Zero-Shot CoT Prompt ===")
print(zero_shot_prompt)