思维链技术详解 #
技术概览 #
text
┌─────────────────────────────────────────────────────────────┐
│ 思维链技术体系 │
├─────────────────────────────────────────────────────────────┤
│ │
│ Chain of Thought │
│ │ │
│ ┌────────────────┼────────────────┐ │
│ │ │ │ │
│ Zero-shot CoT Few-shot CoT Self-Consistency │
│ │ │ │ │
│ │ │ │ │
│ Auto-CoT Manual CoT Multi-path CoT │
│ │ │ │ │
│ └────────────────┼────────────────┘ │
│ │ │
│ ▼ │
│ Tree of Thoughts / Graph of Thoughts │
│ │
└─────────────────────────────────────────────────────────────┘
Zero-shot CoT #
技术原理 #
Zero-shot CoT 是最简单的思维链技术,通过在问题后添加触发语,引导模型自动生成推理步骤。
text
┌─────────────────────────────────────────────────────────────┐
│ Zero-shot CoT 原理 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 核心思想: │
│ 触发语激活模型的"推理模式",使其倾向于生成步骤化的回答 │
│ │
│ 为什么有效: │
│ 1. 触发语在训练数据中与推理任务相关联 │
│ 2. 改变了模型的输出分布,从直接答案变为推理过程 │
│ 3. 增加了输出长度,为推理提供更多"计算空间" │
│ │
└─────────────────────────────────────────────────────────────┘
实现方式 #
python
def zero_shot_cot(question):
"""
Zero-shot CoT 实现
Args:
question: 问题文本
Returns:
模型的推理回答
"""
prompt = f"""
{question}
Let's think step by step.
"""
response = llm.generate(prompt)
return response
# 使用示例
question = """
一个水箱有 500 升水,先用去了 40%,又注入了 150 升,
现在水箱里有多少升水?
"""
result = zero_shot_cot(question)
print(result)
输出示例 #
text
让我们一步步思考:
步骤1:计算用去的水量
用去了 40%,即 500 × 0.4 = 200 升
步骤2:计算用去后的剩余水量
剩余 500 - 200 = 300 升
步骤3:计算注入后的水量
注入 150 升后,水量为 300 + 150 = 450 升
答案:水箱里现在有 450 升水。
触发语优化 #
text
┌─────────────────────────────────────────────────────────────┐
│ 触发语效果对比 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 触发语 效果评分 │
│ ───────────────────────────────────────────────────── │
│ "Let's think step by step." ⭐⭐⭐⭐⭐ │
│ "Let's work this out step by step." ⭐⭐⭐⭐⭐ │
│ "Let's think through this." ⭐⭐⭐⭐ │
│ "Let's break this down." ⭐⭐⭐⭐ │
│ "Think carefully." ⭐⭐⭐ │
│ "Please explain your reasoning." ⭐⭐⭐⭐ │
│ │
│ 中文触发语: │
│ "让我们一步步思考。" ⭐⭐⭐⭐⭐ │
│ "请详细说明推理过程。" ⭐⭐⭐⭐ │
│ "让我们逐步分析这个问题。" ⭐⭐⭐⭐⭐ │
│ │
└─────────────────────────────────────────────────────────────┘
适用场景 #
text
✅ 推荐使用 Zero-shot CoT:
├── 没有现成的示例可用
├── 任务类型多样,难以准备统一示例
├── 快速原型验证
└── Token 预算有限
⚠️ 不推荐使用 Zero-shot CoT:
├── 需要特定格式的输出
├── 任务有特定的推理模式
├── 对准确率要求极高
└── 模型规模较小(< 10B)
Few-shot CoT #
技术原理 #
Few-shot CoT 通过提供带有推理步骤的示例,让模型学习特定的推理模式。
text
┌─────────────────────────────────────────────────────────────┐
│ Few-shot CoT 原理 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 核心思想: │
│ 通过示例展示期望的推理格式和风格,引导模型模仿 │
│ │
│ 为什么有效: │
│ 1. 示例提供了明确的格式模板 │
│ 2. 示例展示了推理的深度和细节 │
│ 3. 示例可以针对特定任务类型优化 │
│ │
└─────────────────────────────────────────────────────────────┘
实现方式 #
python
def few_shot_cot(question, examples):
"""
Few-shot CoT 实现
Args:
question: 问题文本
examples: 示例列表,每个示例包含问题和回答
Returns:
模型的推理回答
"""
prompt = ""
for i, example in enumerate(examples):
prompt += f"问题:{example['question']}\n"
prompt += f"回答:{example['answer']}\n\n"
prompt += f"问题:{question}\n回答:"
response = llm.generate(prompt)
return response
# 示例数据
examples = [
{
"question": "小明有 20 元,买了 3 支铅笔,每支 2 元,还剩多少钱?",
"answer": """让我一步步思考:
1. 计算铅笔花费:3 × 2 = 6 元
2. 计算剩余:20 - 6 = 14 元
答案:还剩 14 元。"""
},
{
"question": "一本书有 180 页,小红第一天读了 1/3,第二天读了剩余的 1/2,两天共读了多少页?",
"answer": """让我一步步思考:
1. 第一天读了:180 × 1/3 = 60 页
2. 剩余:180 - 60 = 120 页
3. 第二天读了:120 × 1/2 = 60 页
4. 两天共读:60 + 60 = 120 页
答案:两天共读了 120 页。"""
}
]
question = "一个长方形花园长 15 米,宽 10 米,如果每平方米种 4 朵花,一共可以种多少朵花?"
result = few_shot_cot(question, examples)
print(result)
示例设计原则 #
text
┌─────────────────────────────────────────────────────────────┐
│ 示例设计原则 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 1. 代表性 │
│ ├── 示例应覆盖典型的任务类型 │
│ ├── 示例难度应与实际问题相近 │
│ └── 示例应展示关键的推理模式 │
│ │
│ 2. 多样性 │
│ ├── 示例应有不同的数值范围 │
│ ├── 示例应有不同的步骤数量 │
│ └── 示例应有不同的推理路径 │
│ │
│ 3. 一致性 │
│ ├── 所有示例使用相同的格式 │
│ ├── 推理步骤的详细程度一致 │
│ └── 答案的表述方式一致 │
│ │
│ 4. 正确性 │
│ ├── 所有示例的答案必须正确 │
│ ├── 推理步骤必须逻辑正确 │
│ └── 计算结果必须准确 │
│ │
└─────────────────────────────────────────────────────────────┘
示例数量建议 #
text
┌─────────────────────────────────────────────────────────────┐
│ 示例数量与效果 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 示例数量 效果 Token 消耗 建议 │
│ ───────────────────────────────────────────────────── │
│ 1-2 个 基础效果 低 简单任务 │
│ 3-4 个 较好效果 中等 一般任务 │
│ 5-8 个 最佳效果 较高 复杂任务 │
│ > 8 个 效果下降 高 不推荐 │
│ │
│ 结论:3-8 个示例通常效果最佳 │
│ │
└─────────────────────────────────────────────────────────────┘
Self-Consistency CoT #
技术原理 #
Self-Consistency 通过生成多条推理路径,然后投票选择最一致的答案,提高准确率。
text
┌─────────────────────────────────────────────────────────────┐
│ Self-Consistency 原理 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 核心思想: │
│ 如果一个答案是正确的,不同的推理路径应该得出相同的结论 │
│ │
│ 工作流程: │
│ 1. 对同一问题生成多条推理路径 │
│ 2. 从每条路径提取最终答案 │
│ 3. 统计答案出现频率 │
│ 4. 选择出现频率最高的答案 │
│ │
│ 为什么有效: │
│ - 正确答案通常可以通过多条路径到达 │
│ - 错误答案通常只在特定错误路径出现 │
│ - 投票机制过滤掉偶然性错误 │
│ │
└─────────────────────────────────────────────────────────────┘
实现方式 #
python
import re
from collections import Counter
def self_consistency_cot(question, num_paths=5):
"""
Self-Consistency CoT 实现
Args:
question: 问题文本
num_paths: 生成的推理路径数量
Returns:
最终答案和所有路径
"""
prompt = f"""
{question}
Let's think step by step.
"""
answers = []
paths = []
for i in range(num_paths):
response = llm.generate(prompt, temperature=0.7)
paths.append(response)
answer = extract_answer(response)
if answer:
answers.append(answer)
if answers:
answer_counts = Counter(answers)
final_answer = answer_counts.most_common(1)[0][0]
else:
final_answer = None
return {
"final_answer": final_answer,
"all_answers": answers,
"paths": paths,
"vote_distribution": dict(Counter(answers))
}
def extract_answer(response):
"""
从回答中提取最终答案
"""
patterns = [
r"答案是[::]\s*(.+)",
r"答案[::]\s*(.+)",
r"因此[,,]\s*(.+)",
r"所以[,,]\s*(.+)",
r"So the answer is\s*(.+)",
r"The answer is\s*(.+)"
]
for pattern in patterns:
match = re.search(pattern, response)
if match:
return match.group(1).strip()
return None
# 使用示例
question = """
一个班级有 45 名学生,其中男生占 2/5,
女生比男生多多少人?
"""
result = self_consistency_cot(question, num_paths=5)
print(f"最终答案: {result['final_answer']}")
print(f"投票分布: {result['vote_distribution']}")
输出示例 #
text
推理路径1:
男生人数:45 × 2/5 = 18 人
女生人数:45 - 18 = 27 人
女生比男生多:27 - 18 = 9 人
答案:9 人
推理路径2:
男生比例:2/5
女生比例:1 - 2/5 = 3/5
男生人数:45 × 2/5 = 18 人
女生人数:45 × 3/5 = 27 人
相差:27 - 18 = 9 人
答案:9 人
推理路径3:
男生:45 × 2/5 = 18 人
女生:45 - 18 = 27 人
多:27 - 18 = 9 人
答案:9 人
推理路径4:
男生占 2/5,即 18 人
女生占 3/5,即 27 人
相差 9 人
答案:9 人
推理路径5:
男生:45 × 0.4 = 18 人
女生:45 - 18 = 27 人
多:9 人
答案:9 人
投票结果:
答案 "9 人" 出现 5 次
最终答案:9 人
参数调优 #
text
┌─────────────────────────────────────────────────────────────┐
│ Self-Consistency 参数 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 参数 建议值 说明 │
│ ───────────────────────────────────────────────────── │
│ num_paths 5-10 路径数量 │
│ temperature 0.5-0.8 生成多样性 │
│ vote_threshold 0.5 最低投票比例 │
│ │
│ 效果与成本权衡: │
│ ├── 3-5 条路径:成本较低,效果一般 │
│ ├── 5-10 条路径:成本适中,效果较好 │
│ └── > 10 条路径:成本较高,边际收益递减 │
│ │
└─────────────────────────────────────────────────────────────┘
Auto-CoT #
技术原理 #
Auto-CoT 自动生成思维链示例,减少人工标注成本。
text
┌─────────────────────────────────────────────────────────────┐
│ Auto-CoT 原理 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 核心思想: │
│ 利用模型自身生成高质量的思维链示例 │
│ │
│ 工作流程: │
│ 1. 收集一批问题(无需标注答案) │
│ 2. 使用 Zero-shot CoT 生成推理过程 │
│ 3. 筛选高质量的推理链 │
│ 4. 使用筛选后的示例构建 Few-shot CoT │
│ │
│ 优势: │
│ - 无需人工标注 │
│ - 示例与目标任务高度相关 │
│ - 可以快速适应新任务类型 │
│ │
└─────────────────────────────────────────────────────────────┘
实现方式 #
python
def auto_cot(target_question, question_pool, num_examples=3):
"""
Auto-CoT 实现
Args:
target_question: 目标问题
question_pool: 问题池(无标注)
num_examples: 需要的示例数量
Returns:
使用自动生成示例的回答
"""
generated_examples = []
for question in question_pool[:num_examples * 2]:
prompt = f"""
{question}
Let's think step by step.
"""
response = llm.generate(prompt, temperature=0.3)
if is_valid_reasoning(response):
generated_examples.append({
"question": question,
"answer": response
})
if len(generated_examples) >= num_examples:
break
return few_shot_cot(target_question, generated_examples)
def is_valid_reasoning(response):
"""
检查推理链是否有效
"""
if len(response) < 50:
return False
if "步骤" not in response and "step" not in response.lower():
return False
if "答案" not in response and "answer" not in response.lower():
return False
return True
# 使用示例
question_pool = [
"小明有 30 元,买了 5 支铅笔,每支 2 元,还剩多少钱?",
"一本书有 200 页,第一天读了 1/4,第二天读了剩余的 1/2,两天共读了多少页?",
"一个长方形长 20 米,宽 15 米,求面积和周长?",
"停车场有 50 辆车,开走了 1/5,又开来了 10 辆,现在有几辆?",
]
target_question = "一个水箱有 800 升水,用去了 3/8,又注入了 200 升,现在有多少升?"
result = auto_cot(target_question, question_pool)
print(result)
质量筛选策略 #
text
┌─────────────────────────────────────────────────────────────┐
│ Auto-CoT 质量筛选 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 筛选维度: │
│ │
│ 1. 长度筛选 │
│ ├── 推理链过短(< 50 字):可能推理不足 │
│ └── 推理链过长(> 500 字):可能冗余 │
│ │
│ 2. 结构筛选 │
│ ├── 必须包含推理步骤标记 │
│ ├── 必须包含最终答案 │
│ └── 步骤之间有逻辑连接 │
│ │
│ 3. 一致性筛选 │
│ ├── 使用 Self-Consistency 验证 │
│ ├── 多次生成答案一致 │
│ └── 排除不一致的示例 │
│ │
│ 4. 多样性筛选 │
│ ├── 选择不同类型的问题 │
│ ├── 选择不同的推理模式 │
│ └── 避免示例过于相似 │
│ │
└─────────────────────────────────────────────────────────────┘
技术对比 #
text
┌─────────────────────────────────────────────────────────────┐
│ CoT 技术对比 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 技术 准确率 成本 实现难度 适用场景 │
│ ───────────────────────────────────────────────────── │
│ Zero-shot CoT 中等 低 简单 快速验证 │
│ Few-shot CoT 较高 中等 中等 通用场景 │
│ Self-Consist. 高 高 中等 高准确要求 │
│ Auto-CoT 较高 中等 复杂 无标注数据 │
│ │
│ 推荐选择策略: │
│ ├── 快速原型:Zero-shot CoT │
│ ├── 通用应用:Few-shot CoT │
│ ├── 高准确率:Self-Consistency CoT │
│ └── 无标注数据:Auto-CoT │
│ │
└─────────────────────────────────────────────────────────────┘
技术组合策略 #
组合使用 #
python
def combined_cot(question, examples=None, use_self_consistency=False):
"""
组合 CoT 策略
Args:
question: 问题文本
examples: 可选的示例
use_self_consistency: 是否使用 Self-Consistency
Returns:
最终答案
"""
if examples:
base_prompt = build_few_shot_prompt(question, examples)
else:
base_prompt = f"{question}\n\nLet's think step by step."
if use_self_consistency:
return self_consistency_generate(base_prompt, num_paths=5)
else:
return llm.generate(base_prompt)
# 使用示例
examples = [...] # 预定义示例
# 策略1:Few-shot CoT
result1 = combined_cot(question, examples=examples)
# 策略2:Zero-shot CoT
result2 = combined_cot(question)
# 策略3:Few-shot + Self-Consistency
result3 = combined_cot(question, examples=examples, use_self_consistency=True)
# 策略4:Zero-shot + Self-Consistency
result4 = combined_cot(question, use_self_consistency=True)
最佳实践 #
text
┌─────────────────────────────────────────────────────────────┐
│ CoT 最佳实践 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 1. 根据任务复杂度选择技术 │
│ ├── 简单任务:Zero-shot CoT │
│ ├── 中等任务:Few-shot CoT │
│ └── 复杂任务:Few-shot + Self-Consistency │
│ │
│ 2. 根据资源限制选择技术 │
│ ├── 低延迟要求:Zero-shot CoT │
│ ├── 低成本要求:Few-shot CoT │
│ └── 高准确要求:Self-Consistency CoT │
│ │
│ 3. 持续优化 │
│ ├── 收集错误案例 │
│ ├── 分析失败原因 │
│ ├── 改进示例和提示词 │
│ └── 建立示例库 │
│ │
└─────────────────────────────────────────────────────────────┘
下一步 #
现在你已经掌握了思维链的核心技术,接下来学习 进阶应用,深入了解 Tree of Thoughts、Graph of Thoughts 等高级思维链技术!
最后更新:2026-04-05