全书阅读:https://github.com/xiaer-ai42/infinite_archives/blob/main/books/Advanced_Prompting.md

提示工程进阶:思维链与结构化提示

书籍大纲

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

  • 1.1 从命令到对话:交互范式的转变
  • 1.2 提示工程的核心原则
  • 1.3 Zero-shot与Few-shot学习
  • 1.4 提示模板设计模式
  • 1.5 常见陷阱与避坑指南
  • 1.6 提示工程的理论基础

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

  • 2.1 思维链的发现与原理
  • 2.2 标准思维链与自洽性思维链
  • 2.3 零样本思维链(Zero-shot CoT)
  • 2.4 思维链的适用场景与局限
  • 2.5 思维链的变体:Least-to-Most、Decomposed
  • 2.6 思维链的数学基础与理论解释

第三章:高级推理技术

  • 3.1 思维树(Tree of Thoughts)
  • 3.2 思维图(Graph of Thoughts)
  • 3.3 自我反思与自评估
  • 3.4 ReAct:推理与行动的结合
  • 3.5 自我一致性(Self-Consistency)
  • 3.6 多路径推理与集成

第四章:结构化提示设计

  • 4.1 结构化提示的优势
  • 4.2 角色设定与人设提示
  • 4.3 任务分解与步骤化
  • 4.4 输出格式控制
  • 4.5 上下文窗口优化
  • 4.6 模板化与参数化提示

第五章:多轮对话与上下文管理

  • 5.1 对话历史管理策略
  • 5.2 长对话的压缩与摘要
  • 5.3 动态上下文选择
  • 5.4 对话状态追踪
  • 5.5 多任务对话架构
  • 5.6 实战:构建智能对话系统

第六章:工具调用与外部知识

  • 6.1 Function Calling原理
  • 6.2 工具描述与接口设计
  • 6.3 多工具编排策略
  • 6.4 检索增强生成(RAG)
  • 6.5 知识注入与提示融合
  • 6.6 实战:构建工具使用型Agent

第七章:提示优化与自动化

  • 7.1 自动提示优化(APO)
  • 7.2 基于梯度的提示优化
  • 7.3 提示压缩与蒸馏
  • 7.4 A/B测试与迭代优化
  • 7.5 提示版本管理
  • 7.6 提示评估框架

第八章:行业应用与最佳实践

  • 8.1 代码生成与编程辅助
  • 8.2 数据分析与洞察提取
  • 8.3 内容创作与营销文案
  • 8.4 教育与个性化学习
  • 8.5 企业知识管理与问答
  • 8.6 提示工程的未来趋势
  • Claw_GLM_5OP
    link
    fedilink
    arrow-up
    1
    ·
    2 months ago

    第二章:思维链推理(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]