← 返回首页
🧠

思维链

📂 llm ⏱ 2 min 309 words

--- title: "思维链" description: "Chain-of-Thought提示技术详解,提升模型推理能力的核心方法" tags: ["Chain-of-Thought", "思维链", "提示工程", "推理"] category: "llm" icon: "🧠"

思维链

思维链(Chain-of-Thought, CoT)是一种通过引导LLM展示中间推理步骤来提升其在复杂任务上表现的提示技术。由Google Brain的Jason Wei等人在2022年提出,CoT已成为提示工程中最重要的技术之一。

工作原理

CoT的核心思想是将复杂问题分解为一系列中间步骤:

CoT变体实现

Few-shot CoT

在提示中提供包含推理过程的示例:

def few_shot_cot_prompt(question, examples):
    """构建Few-shot CoT提示"""
    prompt = "请一步步思考来解决以下问题。\n\n"
    
    for ex in examples:
        prompt += f"问题:{ex['question']}\n"
        prompt += f"思考过程:{ex['reasoning']}\n"
        prompt += f"答案:{ex['answer']}\n\n"
    
    prompt += f"问题:{question}\n思考过程:"
    return prompt

# 示例数据
examples = [
    {
        "question": "Roger有5个网球,他又买了2罐,每罐3个。他现在有多少个?",
        "reasoning": "Roger开始有5个球。2罐×3个=6个。5+6=11。",
        "answer": "11"
    },
    {
        "question": "食堂买了2打鸡蛋,用了10个做早餐,又买了6个。现在有多少个?",
        "reasoning": "2打=24个。24-10=14个。14+6=20个。",
        "answer": "20"
    }
]

prompt = few_shot_cot_prompt("图书馆有35本书,借出12本,归还5本,又新到8本。现在有多少本?", examples)

Zero-shot CoT

仅添加简单提示即可激活CoT能力:

def zero_shot_cot(question):
    """Zero-shot CoT:无需示例"""
    return f"{question}\n\n让我们一步步思考:"

# 或使用英文变体
def zero_shot_cot_en(question):
    return f"{question}\n\nLet's think step by step."

# 使用示例
question = "一个水池有两个进水管和一个排水管。A管每小时进水3吨,B管每小时进水5吨,排水管每小时排水2吨。水池容量50吨,从空池开始,多久能装满?"

prompt = zero_shot_cot(question)
# 模型将自动展示推理过程:
# 1. A管每小时进3吨
# 2. B管每小时进5吨
# 3. 排水管每小时排2吨
# 4. 净进水速度 = 3+5-2 = 6吨/小时
# 5. 50÷6 ≈ 8.33小时

Self-Consistency(自洽性)

生成多条推理链,通过投票选择最一致的答案:

import torch
from collections import Counter

class SelfConsistency:
    def __init__(self, model, tokenizer, num_samples=10):
        self.model = model
        self.tokenizer = tokenizer
        self.num_samples = num_samples
    
    def solve(self, question, temperature=0.7):
        """通过多路径投票提高准确性"""
        answers = []
        reasoning_chains = []
        
        for _ in range(self.num_samples):
            prompt = f"{question}\n让我们一步步思考:"
            inputs = self.tokenizer(prompt, return_tensors="pt")
            
            outputs = self.model.generate(
                **inputs,
                max_new_tokens=512,
                temperature=temperature,
                do_sample=True,
                top_p=0.95,
            )
            
            response = self.tokenizer.decode(outputs[0], skip_special_tokens=True)
            answer = self._extract_answer(response)
            answers.append(answer)
            reasoning_chains.append(response)
        
        # 多数投票
        answer_counts = Counter(answers)
        best_answer = answer_counts.most_common(1)[0][0]
        confidence = answer_counts[best_answer] / len(answers)
        
        return {
            "answer": best_answer,
            "confidence": confidence,
            "all_answers": dict(answer_counts),
            "reasoning_chains": reasoning_chains,
        }
    
    def _extract_answer(self, text):
        markers = ["答案:", "答案是", "最终答案:", "Answer:"]
        for marker in markers:
            if marker in text:
                return text.split(marker)[-1].strip().split("\n")[0]
        return text.strip().split("\n")[-1]

Auto-CoT(自动思维链)

自动构建推理示例,减少人工编写成本:

class AutoCoT:
    def __init__(self, model, tokenizer):
        self.model = model
        self.tokenizer = tokenizer
    
    def generate_demonstrations(self, questions, num_demos=8):
        """自动从问题集生成CoT示例"""
        # 聚类问题
        clusters = self._cluster_questions(questions, num_demos)
        
        demonstrations = []
        for cluster in clusters:
            # 选择每个聚类的代表问题
            representative = cluster[0]
            # 自动生成推理过程
            demo = self._generate_single_cot(representative)
            demonstrations.append(demo)
        
        return demonstrations
    
    def _generate_single_cot(self, question):
        prompt = f"请为以下问题生成详细的推理过程和答案:\n\n问题:{question}"
        inputs = self.tokenizer(prompt, return_tensors="pt")
        outputs = self.model.generate(**inputs, max_new_tokens=512)
        return self.tokenizer.decode(outputs[0], skip_special_tokens=True)

适用场景

局限性

  1. 简单问题上CoT可能引入噪声
  2. 中间步骤的错误会传播到最终答案
  3. 增加输出长度,消耗更多Token
  4. 小模型使用CoT效果可能不佳

CoT正在与工具调用、搜索算法等技术深度融合,推理时间计算的概念也与CoT密切相关,共同推动模型推理能力的提升。