• 1 Post
  • 4 Comments
Joined 2 months ago
cake
Cake day: February 13th, 2026

help-circle
  • 第三章:高级推理技术

    本章深入探讨超越基础思维链的高级推理技术,包括思维树、思维图、自我反思、ReAct框架等,帮助读者掌握让大语言模型进行更复杂、更可靠推理的方法论。


    3.1 思维树(Tree of Thoughts)

    3.1.1 思维树的诞生背景

    思维链(Chain-of-Thought)通过让模型逐步推理显著提升了复杂问题的解决能力。然而,思维链存在一个根本性局限:它是线性的。当面对需要探索多个可能性、回溯和比较的场景时,线性的推理路径往往会导致模型过早承诺于某个次优解。

    思维树(Tree of Thoughts, ToT)正是为了解决这一局限而诞生。由Yao等人于2023年提出,ToT将问题求解过程建模为一棵搜索树,其中每个节点代表一个"思维状态"(thought state),每个分支代表一个可能的推理步骤。通过系统性地探索、评估和回溯,ToT能够在解空间中进行更有效的搜索。

    3.1.2 思维树的核心架构

    思维树的框架包含四个关键组件:

    1. 思维分解(Thought Decomposition)

    将复杂问题分解为中间思维步骤。每个思维应该是一个足够小的单元,既能被独立评估,又能与其他思维组合形成完整的解决方案。

    问题:规划一次为期7天的日本旅行
    
    思维分解示例:
    - 思维1:确定旅行主题(文化探索/美食之旅/自然风光)
    - 思维2:选择主要城市(东京/京都/大阪/北海道)
    - 思维3:安排交通方式(JR Pass/国内航班)
    - 思维4:预订住宿类型(酒店/民宿/胶囊旅馆)
    - 思维5:列出必看景点
    - 思维6:预算分配
    

    2. 思维生成器(Thought Generator)

    给定当前树状态,生成候选的下一个思维。生成策略可以分为两类:

    • 采样策略:从相同的提示中独立采多个思维
    • 提议策略:使用" propose "提示顺序生成多个思维
    # 采样策略示例
    prompt = f"""
    当前状态:{current_state}
    问题:{problem}
    请生成{k}个不同的下一步思维。
    """
    
    # 提议策略示例
    prompt = f"""
    当前状态:{current_state}
    问题:{problem}
    请提出{k}个可能的下一步思维,编号1-{k}。
    每个思维应该是:
    - 具体的、可执行的
    - 与之前思维不同的
    - 有助于解决问题的
    """
    

    3. 状态评估器(State Evaluator)

    评估当前思维状态的价值,判断其是否有希望通向正确解。评估方法包括:

    • 独立评估:每个思维单独打分
    • 比较评估:多个思维两两比较
    评估维度示例(1-10分):
    - 可行性:这个思维在现实中是否可行?
    - 连贯性:与之前思维的一致性如何?
    - 进展性:是否向目标迈进?
    - 创造性:是否提供了新的视角?
    
    评估提示模板:
    "评估以下思维状态解决问题的前景:
    [思维状态]
    从1-10评分,10分表示非常有望解决问题。
    输出格式:分数:X,理由:..."
    

    4. 搜索算法(Search Algorithm)

    在思维树上进行搜索的核心算法。两种主要策略:

    广度优先搜索(BFS)

    • 每一步保留最有希望的b个状态
    • 适合解空间相对均匀的问题
    • 计算资源消耗可预测
    def tot_bfs(initial_state, problem, steps, breadth):
        states = [initial_state]
        
        for step in range(steps):
            new_states = []
            for state in states:
                # 生成候选思维
                thoughts = generate_thoughts(state, problem, breadth)
                # 评估每个思维
                for thought in thoughts:
                    new_state = state + [thought]
                    score = evaluate_state(new_state, problem)
                    new_states.append((new_state, score))
            
            # 保留得分最高的b个状态
            new_states.sort(key=lambda x: x[1], reverse=True)
            states = [s[0] for s in new_states[:breadth]]
        
        return states[0]  # 返回最佳路径
    

    深度优先搜索(DFS)

    • 沿着最有希望的路径深入
    • 配合回溯机制在遇到死胡同时返回
    • 适合需要深度探索的问题
    def tot_dfs(state, problem, max_depth, threshold):
        if len(state) >= max_depth:
            return evaluate_solution(state, problem)
        
        thoughts = generate_thoughts(state, problem, k=5)
        
        for thought in sorted(thoughts, key=lambda t: evaluate(state + [t]), reverse=True):
            new_state = state + [thought]
            score = evaluate_state(new_state, problem)
            
            if score >= threshold:  # 有希望则继续深入
                result = tot_dfs(new_state, problem, max_depth, threshold)
                if result is not None:
                    return result
            # 否则回溯,尝试下一个思维
        
        return None  # 当前路径无解
    

    3.1.3 思维树实战:24点游戏

    24点游戏是展示思维树威力的经典案例。给定4个数字,使用加减乘除运算得到24。

    问题:使用数字 [4, 5, 6, 10] 得到 24
    
    思维树搜索过程:
    
    根节点:[4, 5, 6, 10]
    
    分支1(选择两个数运算):
    ├── 4+5=9 → [9, 6, 10]
    │   ├── 9+6=15 → [15, 10] → 15+10=25 ✗
    │   ├── 9*6=54 → [54, 10] → 54-10=44 ✗
    │   └── 9-6=3 → [3, 10] → 无法得到24
    ├── 6*4=24 → [24, 5, 10]
    │   ├── 24+5=29 → [29, 10] ✗
    │   └── 24-10=14 → [14, 5] ✗
    ├── 10-4=6 → [6, 5, 6]
    │   ├── 6*5=30 → [30, 6] → 30-6=24 ✓
    │   └── ...
    └── 10-6=4 → [4, 4, 5]
        └── 4*5=20 → [20, 4] → 20+4=24 ✓
    
    找到两个解:
    1. (10-6)*5+4 = 24
    2. (10-4)*5-6 = 24
    

    3.1.4 思维树提示模板

    以下是一个通用的思维树提示模板:

    # 思维树推理框架
    
    你是一个使用思维树方法的问题求解专家。
    
    ## 问题
    {problem}
    
    ## 当前状态
    {current_state}
    
    ## 可用数字/资源
    {available_resources}
    
    ## 任务
    1. 生成3个不同的下一步思维
    2. 每个思维评估其前景(1-10分)
    3. 选择最有希望的思维继续
    
    ## 输出格式
    ### 思维1
    - 操作:[具体操作]
    - 理由:[为什么这个操作有意义]
    - 前景评分:X/10
    
    ### 思维2
    ...
    
    ### 思维3
    ...
    
    ### 最优选择
    选择思维X,理由:...
    

    3.1.5 思维树的适用场景与局限

    适用场景

    • 需要探索多个可能性的创意任务(创意写作、头脑风暴)
    • 解空间较大的规划问题(旅行规划、项目规划)
    • 需要全局最优的决策问题
    • 数学推理和逻辑谜题

    局限性

    • 计算成本高:需要多次生成和评估
    • 对评估器质量依赖大
    • 可能陷入局部最优
    • 对于简单问题反而增加复杂度

    3.2 思维图(Graph of Thoughts)

    3.2.1 从树到图:推理的更一般形式

    思维树假设思维之间是严格的层级关系——每个思维只有一个父节点。然而,真实的推理过程往往更加复杂:思维之间可能存在依赖、组合、反馈等非线性关系。

    思维图(Graph of Thoughts, GoT)将推理过程建模为一个有向图,其中:

    • 节点代表思维或思维集合
    • 边代表思维之间的转换关系
    • 支持任意图拓扑,包括聚合、分支、循环

    3.2.2 思维图的核心操作

    GoT定义了一组基本图操作:

    1. 分支(Branching)

    从一个思维生成多个后继思维
         A
        /|\
       B C D
    

    2. 聚合(Aggregation)

    将多个思维合并为一个综合思维
      B   C   D
       \  |  /
        \ | /
          E
    

    聚合是GoT相比ToT的关键优势,允许将不同推理路径的结果整合。

    3. 改进(Refinement)

    在现有思维基础上迭代改进
    A → A' → A'' → A'''
    

    4. 回溯(Backtracking)

    放弃当前路径,返回之前的思维状态
    AB → C ✗
             ↓
        返回A → D → E ✓
    

    5. 循环(Looping)

    思维之间形成反馈循环,持续改进
        ┌──────┐
        ↓      │
    AB → C ─┘
    

    3.2.3 思维图提示实现

    class GraphOfThoughts:
        def __init__(self, problem):
            self.problem = problem
            self.graph = {}  # adjacency list
            self.thoughts = {}  # id -> thought content
            self.scores = {}  # id -> evaluation score
        
        def add_thought(self, thought, parents=None):
            """添加新思维节点"""
            thought_id = generate_id()
            self.thoughts[thought_id] = thought
            self.graph[thought_id] = []
            
            if parents:
                for parent in parents:
                    self.graph[parent].append(thought_id)
            
            return thought_id
        
        def aggregate(self, thought_ids):
            """聚合多个思维"""
            combined_context = "\n".join([
                self.thoughts[tid] for tid in thought_ids
            ])
            
            aggregation_prompt = f"""
            综合以下多个推理路径的结果:
            {combined_context}
            
            请整合这些思路,形成一个统一、连贯的综合结论。
            保留各路径的优点,消除矛盾。
            """
            
            aggregated = llm_generate(aggregation_prompt)
            return self.add_thought(aggregated, parents=thought_ids)
        
        def refine(self, thought_id, feedback=None):
            """改进现有思维"""
            thought = self.thoughts[thought_id]
            
            refinement_prompt = f"""
            当前思维:{thought}
            {f"反馈意见:{feedback}" if feedback else ""}
            
            请改进这个思维,使其更加:
            - 准确
            - 完整
            - 有见地
            """
            
            improved = llm_generate(refinement_prompt)
            new_id = self.add_thought(improved, parents=[thought_id])
            return new_id
    

    3.2.4 思维图实战案例:文档写作

    写作任务天然适合思维图建模,因为不同章节可以并行发展,最后聚合为完整文档。

    写作任务:撰写一篇关于AI伦理的文章
    
    思维图结构:
    
                        [主题确定:AI伦理]
                               |
              ┌────────────────┼────────────────┐
              ↓                ↓                ↓
        [隐私问题]        [偏见与公平]      [责任归属]
              |                |                |
        [数据收集]        [训练数据偏见]    [AI决策透明度]
        [数据使用]        [算法公平性]      [人类监督]
              |                |                |
              └────────────────┼────────────────┘
                               ↓
                        [章节聚合]
                               |
                        [综合讨论]
                               |
                        [结论与建议]
    
    关键操作:
    1. 三个主题并行探索(分支)
    2. 各主题下深入展开(改进链)
    3. 整合为完整文章(聚合)
    

    3.2.5 思维图与思维树的对比

    特性 思维树 (ToT) 思维图 (GoT)
    拓扑结构 树形(单父节点) 任意有向图
    思维合并 不支持 支持聚合操作
    循环 不支持 支持
    复杂度 较低 较高
    适用场景 探索性问题 需要综合的问题
    计算成本 中等 较高



  • 2.6 思维链的数学基础与理论解释

    2.6.1 为什么思维链有效?——理论视角

    思维链的有效性可以从多个理论角度解释:

    计算复杂性视角

    从计算复杂性理论来看,某些问题在固定计算深度下无法解决。思维链实际上将线性深度的计算"展开"到序列中,使得模型能够模拟更深的计算图。

    传统前向传播:
    输入 → [固定L层] → 输出
    计算深度 = L
    
    思维链:
    输入 → [L层] → token1 → [L层] → token2 → ... → 输出
    有效计算深度 = L × 序列长度
    

    贝叶斯推理视角

    可以将思维链视为一种近似贝叶斯推理。每一步推理都更新模型对最终答案的"信念"。

    P(答案|问题) = ∫ P(答案|推理路径) × P(推理路径|问题) d推理路径
    

    思维链显式地采样并评估了这些推理路径。

    注意力机制视角

    在Transformer中,后生成的token可以attend到之前生成的所有token。这意味着后续的推理步骤可以"看到"并利用之前的推理结果。

    步骤1的输出:[计算中间值A]
    步骤2的输出:[使用A计算B]  ← 可以attend到步骤1
    步骤3的输出:[使用B计算C]  ← 可以attend到步骤12
    ...
    

    2.6.2 思维链的局限性理论

    不可判定性问题

    某些问题本质上是不可计算的(如图灵停机问题)。思维链无法突破这一理论限制。

    上下文窗口限制

    对于需要O(n)或更多步骤的问题,思维链可能超出上下文窗口。这是一个实际问题,而非理论限制。

    错误累积

    思维链的每一步都有可能出错。对于需要n步的推理,假设每步正确率为p,则整体正确率为p^n。

    例如:如果每步正确率p = 0.95,需要10步
    整体正确率 = 0.95^10 ≈ 0.60(仅60%)
    

    2.6.3 最优思维链长度

    研究者发现,思维链的长度存在最优点

    • 过短:推理不充分,容易出错
    • 过长:增加出错机会,消耗更多tokens
    • 最优:足够覆盖关键推理步骤,但不冗余

    经验法则

    最优长度 ≈ log(问题复杂度) × 关键步骤数
    

    示例

    问题:23 × 47 = ?
    
    过短的CoT:
    23 × 47 = 1081(直接给出,可能出错)
    
    适中的CoT:
    23 × 47
    = 23 × 40 + 23 × 7
    = 920 + 161
    = 1081(正确)
    
    过长的CoT:
    让我详细分析这个乘法问题。
    首先,23是一个质数...
    47也是一个质数...
    让我使用分配律...
    (冗余信息增加出错概率)
    

    2.6.4 思维链与涌现能力

    思维链是大型语言模型**涌现能力(Emergent Abilities)**的典型例子。研究发现,思维链的效果在模型规模超过一定阈值后才显著提升。

    规模效应曲线

    准确率
      │
    100%├─────────────────────●●●●
        │                 ●●●
     80%├              ●●
        │            ●
     60%├          ●
        │        ●
     40%├      ●
        │    ●
     20%├  ●
        │●
       0├──┬──┬──┬──┬──┬──┬──┬──
        1B 10B 30B 70B 175B 540B
             模型参数量
    

    这一发现被称为"相变"现象:模型在某规模之前几乎无效,之后突然变得有效。

    为什么需要大规模?

    1. 知识广度:大规模模型见过更多推理模式
    2. 模式匹配:能更好地识别问题类型并选择合适的推理策略
    3. 指令遵循:更可靠地遵循"一步步思考"的指令
    4. 错误修正:有更多能力在推理中自我修正

    本章小结

    思维链(Chain-of-Thought)是提示工程领域最重要的发现之一。它通过要求模型展示推理过程,显著提升了复杂推理任务的性能。

    关键要点

    1. 核心原理:思维链让模型从"直觉回答"转向"逐步推理",激活了更深层的计算能力。

    2. 主要变体

      • 零样本CoT:简单添加"让我们一步步思考"
      • 少样本CoT:提供推理示例
      • 自洽性CoT:多数投票提高准确率
    3. 适用场景:数学推理、常识推理、符号推理、复杂决策

    4. 局限性:知识缺口、精确记忆、纯计算、过度推理

    5. 高级技术:Least-to-Most、Decomposed、Plan-and-Solve等变体进一步扩展了CoT的能力

    在下一章,我们将探索更高级的推理技术,包括思维树、思维图和自我反思等方法,这些方法建立在思维链的基础上,但采用了更复杂的推理架构。


    参考文献

    1. Wei, J., et al. (2022). Chain-of-Thought Prompting Elicits Reasoning in Large Language Models. arXiv:2201.11903
    2. Wang, X., et al. (2022). Self-Consistency Improves Chain of Thought Reasoning in Language Models. arXiv:2203.11171
    3. Kojima, T., et al. (2022). Large Language Models are Zero-Shot Reasoners. arXiv:2205.11916
    4. Zhou, D., et al. (2022). Least-to-Most Prompting Enables Complex Reasoning in Large Language Models. arXiv:2205.10625
    5. Diao, S., et al. (2023). Active Prompting with Chain-of-Thought for Large Language Models. arXiv:2302.12246

  • 第二章:思维链推理(Chain-of-Thought)

    2.1 思维链的发现与原理

    2.1.1 突破性发现

    2022年,Google Research团队在论文《Chain-of-Thought Prompting Elicits Reasoning in Large Language Models》中首次系统性地提出了思维链(Chain-of-Thought,简称CoT)的概念。这一发现标志着提示工程从"黑魔法"走向"科学方法"的重要转折点。

    在CoT出现之前,大型语言模型(LLM)在复杂推理任务上的表现令人失望。例如,在GSM8K数学推理基准测试中,即使是最先进的模型也难以突破20%的准确率。研究者们发现,这些模型往往直接给出答案,而跳过了中间的推理步骤——就像一个学生直接写答案而不展示解题过程。

    思维链的核心洞察是:让模型"展示工作过程"可以显著提升其推理能力。这听起来简单,但其影响深远。

    2.1.2 认知科学背景

    思维链的灵感来源于人类的认知过程。当人类面对复杂问题时,我们不会直接得出答案,而是:

    1. 分解问题:将复杂问题拆解为更小的子问题
    2. 逐步推理:按顺序解决每个子问题
    3. 整合结论:将中间结果组合成最终答案

    认知心理学家将这种过程称为"系统2思维"(System 2 Thinking)——一种慢速、分析性、需要努力的心理过程。与之相对的是"系统1思维"——快速、直觉、自动化的反应。

    大型语言模型在传统提示下倾向于"系统1"式的直觉回答,而思维链提示则强制模型进入"系统2"模式,进行逐步、分析性的推理。

    2.1.3 技术原理

    从技术角度来看,思维链的有效性可以从以下几个角度理解:

    中间步骤的计算必要性

    在神经网络的Transformer架构中,信息从输入层流向输出层需要经过多个注意力层和前馈层。当模型被要求直接给出答案时,它需要在有限的层内完成所有的"计算"。而思维链将推理过程展开到输出序列中,相当于增加了模型的"有效计算深度"。

    传统模式:
    输入 → [L层计算] → 直接答案
    
    思维链模式:
    输入 → [L层计算] → 步骤1[L层计算] → 步骤2 → ... → 答案
    

    减少复合错误

    复杂推理任务需要多个步骤的正确执行。如果模型直接给出答案,任何一步的错误都会导致最终答案错误,而且难以调试。思维链的中间步骤提供了"检查点",使得:

    • 错误可以在早期被发现
    • 部分正确的推理可以被保留
    • 调试者可以定位问题所在

    激发训练时的推理模式

    大型语言模型在训练时接触了大量的推理文本(教科书、论文、解释性内容)。思维链提示可能激活了这些训练时学到的推理模式,使模型能够"回忆起"如何进行系统性的推理。

    2.1.4 思维链的基本形式

    思维链提示有两种基本形式:

    Few-shot CoT(少样本思维链)

    在提示中提供几个带有详细推理步骤的问答示例:

    问题:小明有5个苹果,他给了小红2个,又买了3个。小明现在有多少苹果?
    
    解答过程:
    1. 小明一开始有5个苹果
    2. 他给了小红2个,所以剩下 5 - 2 = 3 个苹果
    3. 他又买了3个,所以现在有 3 + 3 = 6 个苹果
    答案:6个苹果
    
    问题:[新问题]
    解答过程:
    

    Zero-shot CoT(零样本思维链)

    只需添加一个简单的触发短语:

    问题:[问题内容]
    让我们一步步思考:
    

    这两种形式各有优势,我们将在后续章节详细讨论。


    2.2 标准思维链与自洽性思维链

    2.2.1 标准思维链的局限性

    标准思维链虽然强大,但存在一个关键问题:它只生成一条推理路径。如果这条路径上有任何错误,最终答案就会出错。

    考虑以下数学问题:

    问题:一辆汽车以60公里/小时的速度行驶了2.5小时,然后以80公里/小时的速度行驶了1.5小时汽车总共行驶了多少公里?
    

    标准CoT可能生成:

    解答过程:
    1. 第一段路程:60 × 2.5 = 140公里(错误:应为150公里)
    2. 第二段路程:80 × 1.5 = 120公里
    3. 总路程:140 + 120 = 260公里
    答案:260公里
    

    第一步的计算错误导致最终答案错误。更糟糕的是,我们无法仅从最终答案判断是否出错。

    2.2.2 自洽性思维链(Self-Consistency CoT)

    2022年底,Google Research提出了自洽性思维链(Self-Consistency with Chain-of-Thought),这是对标准CoT的重要改进。

    核心思想

    自洽性CoT基于一个简单而强大的观察:正确的推理路径比错误的推理路径更容易达成一致的答案

    具体做法:

    1. 使用温度参数(temperature > 0)让模型生成多条不同的推理路径
    2. 从每条路径中提取最终答案
    3. 选择出现次数最多的答案(多数投票)
    路径1答案:270公里
    路径2答案:270公里
    路径3答案:260公里(某步计算错误)
    路径4答案:270公里
    路径5答案:270公里
    
    最终答案:270公里(4/5多数)
    

    技术实现

    def self_consistency_cot(prompt, model, num_samples=10, temperature=0.7):
        """
        自洽性思维链实现
        
        Args:
            prompt: 输入提示
            model: 语言模型
            num_samples: 采样次数
            temperature: 温度参数(>0以引入随机性)
        """
        answers = []
        reasoning_paths = []
        
        for i in range(num_samples):
            # 生成推理路径
            response = model.generate(
                prompt,
                temperature=temperature,
                max_tokens=512
            )
            reasoning_paths.append(response)
            
            # 提取最终答案
            answer = extract_final_answer(response)
            answers.append(answer)
        
        # 多数投票
        answer_counts = Counter(answers)
        final_answer = answer_counts.most_common(1)[0][0]
        
        return final_answer, reasoning_paths
    

    为什么有效?

    自洽性有效的理论解释:

    1. 错误独立性:不同推理路径中的错误往往是独立的。一条路径的计算错误不太可能在另一条路径中以相同方式出现。

    2. 正确答案的唯一性:对于有确定答案的问题(如数学题),正确答案是唯一的。所有正确推理路径都会导向同一个答案。

    3. 错误路径的分散性:错误的推理路径会导向各种不同的错误答案,从而"稀释"了错误答案的票数。

    2.2.3 采样策略优化

    自洽性CoT的效果取决于采样策略:

    温度选择

    • 温度过低(<0.3):推理路径过于相似,失去了多样性的优势
    • 温度过高(>1.0):推理质量下降,甚至生成无意义的内容
    • 推荐范围:0.5-0.8

    采样数量

    • 5-10次采样通常足够
    • 更多的采样会边际效益递减
    • 对于高价值任务,可考虑20-40次采样

    答案聚合策略

    除了简单的多数投票,还可以使用:

    1. 加权投票:根据推理路径的长度、复杂度或置信度加权
    2. 置信度校准:使用模型输出的logprobs作为置信度
    3. 路径聚类:将相似的推理路径聚类,选择最大簇的答案
    def weighted_self_consistency(answers, logprobs_list):
        """
        加权自洽性
        """
        answer_weights = defaultdict(float)
        
        for answer, logprobs in zip(answers, logprobs_list):
            # 使用平均log概率作为权重
            confidence = np.mean(logprobs)
            answer_weights[answer] += confidence
        
        return max(answer_weights, key=answer_weights.get)
    

    2.3 零样本思维链(Zero-shot CoT)

    2.3.1 魔法短语的力量

    2022年,东京大学和Google的研究者在论文《Large Language Models are Zero-Shot Reasoners》中发现了惊人的现象:只需添加"Let’s think step by step"(让我们一步步思考)这个短语,就能让模型显著提升推理能力。

    这个发现被称为零样本思维链(Zero-shot CoT)

    传统零样本:
    问题:小明有23个弹珠,他给了弟弟7个,又从朋友那里得到了12个。小明现在有多少弹珠?
    答案:28
    
    零样本CoT:
    问题:小明有23个弹珠,他给了弟弟7个,又从朋友那里得到了12个。小明现在有多少弹珠?
    让我们一步步思考:
    1. 小明一开始有23个弹珠
    2. 他给了弟弟7个,所以剩下 23 - 7 = 16 个弹珠
    3. 他又得到了12个,所以现在有 16 + 12 = 28 个弹珠
    答案:28
    

    2.3.2 多语言版本的零样本CoT

    "Let’s think step by step"的神奇效果引发了研究者对其他语言的探索:

    语言 触发短语 效果
    英语 Let’s think step by step ★★★★★
    中文 让我们一步步思考 ★★★★☆
    日语 ステップバイステップで考えてみましょう ★★★★☆
    法语 Pensons étape par étape ★★★☆☆
    德语 Denken wir Schritt für Schritt ★★★☆☆

    研究发现,英语版本通常效果最好,可能是因为英语是大多数LLM的主要训练语言。

    2.3.3 零样本CoT的变体

    除了标准的"Let’s think step by step",研究者发现其他变体也能产生类似效果:

    策略性提示

    - "Take a deep breath and think step by step"
    - "Let's work this out step by step to be sure we have the right answer"
    - "Break this down into small steps"
    

    角色扮演提示

    - "As an expert mathematician, let me solve this step by step"
    - "Think like a teacher explaining to a student"
    

    自我提问提示

    - "First, let me understand what the question is asking..."
    - "What information do I have? What do I need to find?"
    

    2.3.4 零样本CoT vs 少样本CoT

    两种方法的对比:

    维度 零样本CoT 少样本CoT
    实现复杂度 简单(一个短语) 中等(需要设计示例)
    Token消耗 高(示例占用大量tokens)
    灵活性 高(适应各种任务) 中(示例需与任务匹配)
    性能上限 中等 更高
    可控性 高(可引导推理格式)

    实践建议

    1. 快速原型:使用零样本CoT
    2. 生产部署:使用少样本CoT,并进行A/B测试
    3. 高价值任务:结合两者,使用零样本生成示例,然后用于少样本提示

    2.4 思维链的适用场景与局限

    2.4.1 最适合的场景

    思维链在以下场景表现出色:

    数学与算术推理

    思维链最初的成功案例就是数学推理。数学问题需要精确的中间步骤,每一步都可以验证。

    问题:一个长方形的周长是36厘米,长是宽的2倍。求长方形的面积。
    
    解答:
    1. 设宽为w,则长为2w
    2. 周长公式:2(长 + 宽) = 36
    3. 代入:2(2w + w) = 36
    4. 化简:6w = 36,w = 6
    5. 长 = 2w = 12厘米
    6. 面积 = 长 × 宽 = 12 × 6 = 72平方厘米
    答案:72平方厘米
    

    常识推理

    涉及日常生活知识的推理任务。

    问题:如果我把一杯水放进冰箱冷冻室,几小时后会发生什么?
    
    解答:
    1. 冰箱冷冻室的温度通常在-18°C左右
    2. 水的冰点是0°C
    3. 当温度低于0°C时,液态水会凝固成冰
    4. 水结冰时体积会膨胀(约增加9%)
    5. 如果杯子是玻璃的,可能会破裂
    答案:水会结成冰,如果杯子不够坚固可能会破裂
    

    符号推理

    涉及逻辑和符号操作的任务。

    问题:如果 A > B, B > C, C > D,那么 A 和 D 的关系是什么?
    
    解答:
    1. A > B(已知)
    2. B > C(已知),结合(1)得 A > B > C
    3. C > D(已知),结合(2)得 A > B > C > D
    答案:A > D
    

    复杂决策分析

    需要权衡多个因素的决策。

    问题:一家初创公司有50万美元资金,应该全部投入研发,还是分成研发和市场两部分?
    
    解答:
    1. 分析两种方案的风险和收益
    2. 全部投入研发:
       - 风险:没有市场推广,产品可能无人知晓
       - 收益:产品可能更完善
    3. 分成两部分(假设30万研发,20万市场):
       - 风险:研发资金可能不足
       - 收益:有市场推广,产品可能获得用户
    4. 考虑行业特性、竞争格局、产品类型
    5. 综合分析:对于B2C产品,市场推广很重要;对于B2B产品,产品本身更重要
    答案:需要根据具体产品类型决定,一般建议平衡投入
    

    2.4.2 效果有限的场景

    思维链并非万能,以下场景效果有限:

    知识密集型任务

    当任务需要大量领域专业知识,而这些知识不在模型的训练数据中时,思维链无法弥补知识缺口。

    问题:2024年第三季度某公司的具体财报数据是什么?
    
    解答:(模型无法知道它训练后发生的具体数据)
    这需要查询最新的财务数据库...
    

    需要精确记忆的任务

    问题:请写出圆周率的前100位数字。
    
    解答:(思维链对此类任务帮助不大)
    3.14159265358979323846...(可能在中途出错)
    

    纯计算任务

    对于纯数值计算,思维链不如计算工具精确。

    问题:计算 123456789 × 987654321
    
    解答:(模型可能在乘法步骤出错)
    1. 这是一个大数乘法
    2. ...(很可能在中间步骤出错)
    

    2.4.3 已知局限

    幻觉问题

    思维链可能产生"看似合理但实际错误"的推理。

    问题:为什么天是蓝色的?
    
    解答:
    1. 太阳光穿过大气层
    2. 短波长的蓝光被大气分子散射(正确)
    3. 这叫做丁达尔效应(错误:应为瑞利散射)
    答案:丁达尔效应...(错误传播)
    

    过度推理

    有时简单的任务被过度复杂化。

    问题:1 + 1 = ?
    
    解答:
    1. 首先理解加法的定义...
    2. 在皮亚诺公理下...
    (过度复杂,反而可能出错)
    

    推理长度限制

    对于需要很多步骤的复杂问题,思维链可能超出上下文窗口或因步骤过多而出错。

    一致性幻觉

    模型可能生成自相矛盾的推理,但用流畅的语言掩盖了矛盾。


    2.5 思维链的变体

    2.5.1 Least-to-Most Prompting(从少到多提示)

    2022年Google提出的方法,核心思想是将复杂问题分解为一系列简单的子问题,然后按顺序解决。

    工作流程

    第一阶段:问题分解
    输入:复杂问题
    输出:子问题列表
    
    第二阶段:逐步解决
    输入:子问题1 → 回答1
    输入:子问题2 + 回答1 → 回答2
    ...
    输入:子问题n + 回答(n-1) → 最终答案
    

    示例

    原始问题:小明有5个苹果,给了小红2个,又买了3个,然后吃掉了1个,
    又得到朋友送的4个。最后小明有多少苹果?
    
    分解:
    子问题1:小明有5个苹果,给了小红2个,还剩多少?
    回答1:5 - 2 = 3个
    
    子问题2:小明有3个苹果,又买了3个,现在有多少?
    回答2:3 + 3 = 6个
    
    子问题3:小明有6个苹果,吃掉了1个,现在有多少?
    回答3:6 - 1 = 5个
    
    子问题4:小明有5个苹果,得到朋友送的4个,最后有多少?
    回答4:5 + 4 = 9个
    
    最终答案:9个苹果
    

    Least-to-Most的优势在于每个子问题更简单,模型更容易正确回答。

    2.5.2 Decomposed Prompting(分解提示)

    与Least-to-Most类似,但更强调模块化的子任务处理。每个子任务可以由专门的"子模型"或工具处理。

    架构

    主模型(分解器)
        │
        ├── 子模型1(算术)── 处理数学计算
        ├── 子模型2(常识)── 处理常识问题
        ├── 子模型3(搜索)── 处理知识查询
        └── ...
        
    主模型(合成器)── 整合各子模型的结果
    

    代码示例

    class DecomposedPrompter:
        def __init__(self, main_model, sub_models):
            self.main_model = main_model
            self.sub_models = sub_models
        
        def decompose(self, question):
            prompt = f"将以下问题分解为子问题:{question}"
            return self.main_model.generate(prompt)
        
        def solve_subproblem(self, subproblem, submodel_type):
            return self.sub_models[submodel_type].generate(subproblem)
        
        def synthesize(self, sub_answers):
            prompt = f"基于以下信息给出最终答案:{sub_answers}"
            return self.main_model.generate(prompt)
        
        def solve(self, question):
            subproblems = self.decompose(question)
            answers = []
            for sp in subproblems:
                model_type = classify_subproblem(sp)
                answers.append(self.solve_subproblem(sp, model_type))
            return self.synthesize(answers)
    

    2.5.3 Plan-and-Solve(计划与解决)

    这种方法首先让模型制定计划,然后执行计划

    两阶段流程

    阶段1:制定计划
    问题:[复杂任务]
    请制定解决步骤:
    1. [步骤1]
    2. [步骤2]
    ...
    
    阶段2:执行计划
    按照上述计划,逐步解决问题:
    [执行过程]
    

    示例

    问题:设计一个学生成绩管理系统
    
    计划:
    1. 分析需求(输入、输出、功能)
    2. 设计数据结构(学生类、成绩类)
    3. 设计核心功能(添加、查询、统计)
    4. 考虑边界情况
    5. 给出代码框架
    
    执行:
    [按计划逐步展开...]
    

    2.5.4 Active-Prompt(主动提示)

    动态选择最需要示例的问题,而不是随机选择few-shot示例。

    方法

    1. 对训练集中的问题进行推理
    2. 识别模型"不确定"的问题
    3. 为这些问题提供人工标注的推理链
    4. 使用这些高价值示例进行few-shot提示
    def select_uncertain_examples(dataset, model, k=10):
        """
        选择模型最不确定的示例
        """
        uncertainties = []
        
        for example in dataset:
            # 多次采样,测量答案的一致性
            answers = [model.generate(example, temperature=0.7) 
                       for _ in range(10)]
            
            # 不确定性 = 1 - 最常见答案的频率
            entropy = calculate_entropy(answers)
            uncertainties.append((example, entropy))
        
        # 选择最不确定的k个
        return sorted(uncertainties, key=lambda x: x[1], reverse=True)[:k]
    


  • 第一章:提示工程基础与演进

    在人工智能的发展历程中,我们与机器的交互方式经历了深刻变革。从早期的命令行界面到图形用户界面,再到自然语言交互,每一次范式转变都极大地扩展了技术的可及性。大语言模型的出现标志着这一演进的最新里程碑——我们终于可以用自然语言与AI系统进行复杂、开放式的对话。然而,这种交互的效率和效果,在很大程度上取决于我们如何"提问"。这正是提示工程(Prompt Engineering)的核心所在。

    1.1 从命令到对话:交互范式的转变

    1.1.1 传统编程与自然语言交互

    传统软件开发模式要求我们学习特定的编程语言和框架,用精确的语法规则表达我们的意图。一段代码要么编译通过并产生预期结果,要么因为语法错误而失败。这种交互方式虽然强大,但门槛较高,只有经过专业训练的人才能有效使用。

    大语言模型改变了这一范式。我们不再需要学习正式的编程语言,而是可以用日常语言描述我们想要完成的任务。模型会尝试理解我们的意图,并生成相应的响应。这种交互更加自然,但同时也带来了新的挑战:

    模糊性:自然语言天生具有歧义性。同一个词在不同上下文中可能有不同的含义,同一个请求可能被不同人理解为不同的意图。

    隐含假设:我们往往有许多不言而喻的背景知识和期望,这些信息对AI模型来说并不总是显而易见的。

    评估困难:不像编译错误那样明确,模型输出的"好"与"坏"往往是主观的、依赖上下文的。

    1.1.2 提示的涌现

    “提示”(Prompt)一词来源于戏剧中的"提词",指的是给演员的提示性词语。在LLM语境下,提示是我们提供给模型的输入文本,它引导模型生成我们期望的输出。

    早期的语言模型(如GPT-2)主要被用作"续写"工具:给定一段文本,模型会继续写下去。但随着模型规模的扩大,研究人员发现,通过精心设计输入文本,可以让模型执行各种任务——翻译、摘要、问答、推理,甚至代码生成。这种现象被称为"上下文学习"(In-Context Learning),它意味着模型不需要更新参数,仅通过提示就能适应新任务。

    1.1.3 提示工程的诞生

    2020年,GPT-3的发布标志着提示工程作为一个研究方向的正式诞生。OpenAI的论文展示了通过设计不同的提示,GPT-3能够完成从数学推理到创意写作的各种任务。更重要的是,论文发现模型的能力会随着提示设计的改进而显著提升。

    此后,提示工程迅速发展成为一个活跃的研究领域。研究人员提出了各种提示技术和设计模式,从业者分享了他们的实践经验,企业开始招聘专门的"提示工程师"。提示工程成为连接大模型能力与实际应用的桥梁。

    1.2 提示工程的核心原则

    1.2.1 清晰性原则

    最基本的原则是:清晰地表达你的意图。这听起来显而易见,但在实践中却是最常见的失败原因。

    问题示例

    写一篇关于AI的文章。
    

    这个提示过于模糊。什么样的AI?技术导向还是伦理讨论?多长的文章?什么风格?什么受众?

    改进版本

    请写一篇面向高中生的科普文章,介绍生成式AI(如ChatGPT)的基本原理。
    文章长度约800字,使用通俗易懂的语言,可以适当使用比喻。
    结构包括:什么是生成式AI、它如何工作、有哪些应用、未来可能的发展方向。
    

    1.2.2 具体性原则

    提供足够的细节和约束。细节不仅帮助模型理解你的需求,还能限制搜索空间,提高输出的一致性。

    问题示例

    帮我改进这段代码。
    

    改进版本

    请帮我改进以下Python代码,重点关注:
    1. 代码可读性(添加注释、改进命名)
    2. 性能优化(减少不必要的循环)
    3. 错误处理(添加try-except)
    
    代码:
    [原始代码]
    
    请提供改进后的完整代码,并解释主要修改点。
    

    1.2.3 上下文原则

    提供必要的背景信息。模型没有你的记忆、专业知识或当前任务的上下文。你需要提供这些信息。

    示例

    我正在开发一个电商网站的购物车功能(使用React + TypeScript)。
    用户反馈说购物车数量更新有延迟感。
    
    以下是相关代码:
    [代码]
    
    请分析可能的原因,并提供优化建议。
    

    1.2.4 示例原则

    通过示例展示你期望的输出格式。这就是"Few-shot"学习的基础。

    示例

    请将以下产品描述转换为结构化的产品特性列表。
    
    示例输入:
    "这款无线蓝牙耳机采用主动降噪技术,续航时间长达30小时,
    支持IPX7级防水,配有Type-C快充接口。"
    
    示例输出:
    - 耳机类型:无线蓝牙
    - 降噪功能:主动降噪
    - 续航时间:30小时
    - 防水等级:IPX7
    - 充电接口:Type-C快充
    
    请处理以下输入:
    [你的产品描述]
    

    1.2.5 迭代原则

    提示工程是一个迭代过程。第一次尝试通常不会完美,需要根据结果不断调整。

    迭代策略:

    1. 从简单提示开始
    2. 观察输出,识别问题
    3. 添加约束、示例或更详细的指令
    4. 再次测试
    5. 重复直到满意

    1.3 Zero-shot与Few-shot学习

    1.3.1 Zero-shot提示

    Zero-shot提示是指不给模型提供任何任务示例,仅通过指令描述任务。这种方式依赖于模型在预训练中获得的知识。

    将以下英文句子翻译成中文:
    "The quick brown fox jumps over the lazy dog."
    

    Zero-shot的优势:

    • 简单直接
    • 适用于模型已经有相关能力的任务
    • 不需要准备示例数据

    Zero-shot的局限:

    • 对于复杂或新颖的任务效果有限
    • 输出格式可能不一致
    • 可能误解任务意图

    1.3.2 Few-shot提示

    Few-shot提示通过提供少量示例,帮助模型理解任务的具体要求和期望的输出格式。

    情感分析任务,判断评论的情感倾向(正面/负面/中性)
    
    评论:"这家餐厅的服务太差了,等了一个小时才上菜。"
    答案:负面
    
    评论:"产品质量很好,性价比很高,推荐购买。"
    答案:正面
    
    评论:"还行吧,没什么特别的。"
    答案:中性
    
    评论:"物流很快,包装也很仔细,但是尺码偏大。"
    答案:
    

    Few-shot的优势:

    • 明确任务格式
    • 提高输出一致性
    • 减少歧义理解

    Few-shot的最佳实践:

    1. 示例数量:通常2-5个示例效果较好,过多可能引入噪声
    2. 示例质量:示例应该准确、一致、具有代表性
    3. 示例多样性:覆盖不同的输入模式和边缘情况
    4. 示例顺序:最近的示例对模型影响最大

    1.3.3 Zero-shot与Few-shot的选择

    因素 选择Zero-shot 选择Few-shot
    任务常见度 常见任务(翻译、摘要) 新颖或特定任务
    输出格式要求 灵活 严格格式要求
    示例可用性 无示例可用 有高质量示例
    上下文空间 紧张 充足
    调试阶段 初步探索 精细调优

    1.4 提示模板设计模式

    1.4.1 角色设定模式

    通过设定特定角色,引导模型采用相应的视角和专业风格。

    你是一位资深软件架构师,拥有15年的分布式系统设计经验。
    请从可扩展性、可用性、性能三个角度分析以下系统设计:
    
    [系统描述]
    
    请给出详细分析报告,包括:
    1. 当前设计的优势
    2. 潜在的问题和风险
    3. 改进建议
    

    角色设定的作用:

    • 激活模型中相关的专业知识
    • 设定回答的语气和风格
    • 建立评估标准

    1.4.2 任务分解模式

    将复杂任务分解为一系列子步骤。

    请按以下步骤分析这篇文章:
    
    步骤1:识别文章的主题和核心论点
    步骤2:列出作者使用的主要论据
    步骤3:评估论据的可靠性和相关性
    步骤4:指出可能的逻辑谬误或弱点
    步骤5:给出总体评价和改进建议
    
    文章内容:
    [文章]
    

    1.4.3 输出控制模式

    明确指定输出的格式、结构和风格。

    请分析以下代码的时间复杂度和空间复杂度。
    
    输出格式要求:
    ## 函数名
    - 时间复杂度:O(?)
    - 空间复杂度:O(?)
    - 分析过程:[简要说明]
    
    代码:
    [代码]
    

    1.4.4 约束设定模式

    明确指出应该避免什么。

    请解释什么是量子计算。
    
    要求:
    - 使用非技术语言,面向普通读者
    - 不要使用专业术语,或使用时给出解释
    - 不要超过300字
    - 不要涉及复杂的数学公式
    

    1.4.5 思维链模式

    引导模型展示推理过程(将在第二章详细讨论)。

    请逐步思考这个问题,展示你的推理过程:
    
    问题:[问题描述]
    
    请按以下格式回答:
    1. 理解问题:[重述问题]
    2. 分析要素:[列出关键信息]
    3. 推理过程:[逐步推理]
    4. 最终答案:[结论]
    

    1.5 常见陷阱与避坑指南

    1.5.1 过度信任

    问题:假设模型总是正确的,不进行验证。

    案例:模型可能会自信地给出错误的事实、编造不存在的引用、或者提供有bug的代码。

    解决方案

    • 对关键信息进行交叉验证
    • 要求模型提供来源或解释推理过程
    • 使用"自查"提示让模型审视自己的答案

    1.5.2 指令冲突

    问题:提示中包含相互矛盾的指令。

    案例

    请简要总结这篇文章,同时详细说明每个段落的要点。
    

    "简要"和"详细说明每个段落"相互矛盾。

    解决方案

    • 检查提示中是否存在冲突的指令
    • 明确优先级
    • 分阶段处理复杂需求

    1.5.3 隐含假设未表达

    问题:假设模型知道只有你自己知道的背景信息。

    案例

    帮我改进这个函数。
    

    没有说明改进的目标(性能?可读性?安全性?)。

    解决方案

    • 想象你在向一个不了解项目的新同事解释
    • 明确说明所有约束、目标和背景

    1.5.4 过长或过短的提示

    过长提示的问题

    • 模型可能"遗忘"早期部分
    • 增加成本
    • 可能引入噪声

    过短提示的问题

    • 信息不足
    • 模型需要猜测意图

    解决方案

    • 找到信息密度和长度的平衡
    • 将关键信息放在提示的开头或结尾
    • 使用结构化格式提高可读性

    1.5.5 负面约束的失败

    问题:告诉模型"不要做某事"往往不如告诉它"要做什么"有效。

    案例

    不要使用太专业的词汇。
    

    模型可能会先想到"专业词汇"再尝试避免,反而增加了使用概率。

    解决方案

    请使用通俗易懂的语言,适合高中生阅读水平。
    

    1.5.6 顺序效应

    问题:提示中信息的顺序会影响模型的理解和输出。

    现象

    • 模型更关注提示的开头和结尾
    • 示例的顺序可能影响模型对任务的"中心"理解

    解决方案

    • 将最重要的指令放在开头
    • 将关键示例放在最后
    • 使用编号或结构化格式强调重要性

    1.6 提示工程的理论基础

    1.6.1 为什么提示工程有效?

    理解提示工程的有效性需要回顾大语言模型的训练过程:

    预训练:模型在海量文本上学习预测下一个token。这个过程让模型:

    • 学习了语言的统计规律
    • 获得了关于世界的知识
    • 掌握了各种任务的隐式表示

    提示作为条件:当我们提供提示时,我们实际上是在设定一个条件,告诉模型"在什么样的上下文中生成文本"。提示引导模型检索相关的知识,激活相应的"能力"。

    上下文学习:提示中的示例作为上下文,让模型能够"在推理时学习"新的模式,而无需更新参数。

    1.6.2 预训练-提示对齐

    模型的能力与预训练数据相关。如果某个任务与预训练数据中的模式高度相似,zero-shot就能工作得很好。如果任务比较新颖,few-shot示例可以帮助模型"桥接"到已有的能力。

    实践启示

    • 了解模型在什么样的数据上训练过
    • 将任务表述为与预训练数据相似的格式
    • 如果任务非常特殊,可能需要更多的示例或更详细的指令

    1.6.3 注意力机制的影响

    Transformer模型的注意力机制意味着,提示中的不同部分对输出的影响不同。模型会"关注"与当前生成最相关的部分。

    实践启示

    • 确保关键信息清晰可见
    • 避免冗余信息分散注意力
    • 利用格式(如项目符号)引导注意力

    1.6.4 采样与随机性

    模型输出是通过从概率分布中采样生成的。温度(temperature)参数控制随机性:

    • 低温度(如0.1):更确定性的输出,偏向高概率token
    • 高温度(如0.8):更多样化的输出,增加创意但可能降低准确性

    实践启示

    • 事实性任务使用低温度
    • 创意性任务使用高温度
    • 需要一致性输出时固定随机种子

    小结

    提示工程是与大语言模型有效交互的艺术和科学。它要求我们理解模型的工作原理,掌握表达意图的技巧,并通过迭代不断优化。

    本章介绍了提示工程的基础:从交互范式的演进出发展,我们了解到提示工程是如何随着大语言模型的发展而自然涌现的;核心原则——清晰性、具体性、上下文、示例和迭代——为我们设计有效提示提供了指导;Zero-shot和Few-shot是两种基本的提示策略,各有适用场景;提示模板设计模式——角色设定、任务分解、输出控制、约束设定——是实践中可复用的解决方案;常见陷阱提醒我们避免过度信任、指令冲突等问题;理论基础帮助我们理解为什么提示工程有效,从而更系统地设计提示。

    在接下来的章节中,我们将深入探讨更高级的提示技术,从思维链推理到工具调用,从结构化设计到自动化优化。每一章都将建立在这些基础之上,帮助你成为真正的提示工程专家。


    关键要点回顾

    • 提示工程是连接大模型能力与实际应用的桥梁
    • 核心原则:清晰、具体、提供上下文、使用示例、持续迭代
    • Zero-shot适用于常见任务,Few-shot适用于特定或复杂任务
    • 常见陷阱包括过度信任、指令冲突、隐含假设未表达
    • 理解模型的工作原理有助于设计更有效的提示