Chapter 05

推理提示工程:激发高质量思维链

推理模型的提示工程与普通模型截然不同。很多普通模型的"最佳实践"在推理模型上适得其反。

核心差异:推理模型不需要 CoT 触发词

普通模型需要"Let's think step by step"来激活推理;对于已经内置了推理能力的模型(o1、Claude Extended Thinking),这类触发词不仅无用,有时还会干扰模型的内部推理过程

普通 LLM 提示

  • 需要 CoT 触发词
  • 需要 Few-shot 示例
  • 需要指定推理步骤格式
  • 详细的 System Prompt 有帮助
  • 可以用 XML 标签指导结构

推理模型提示

  • 不需要 CoT 触发词
  • Few-shot 效果有限甚至负面
  • 不要规定推理步骤格式
  • 简洁的 System Prompt 更好
  • 只约束最终输出格式

System Prompt 设计准则

推理模型的 System Prompt 要提供背景约束,而不是指导推理过程

# ❌ 错误:告诉模型如何推理(会干扰内部思维链)
bad_system = """你是一个数学助手。
解题时请按以下步骤:
1. 首先分析题目类型
2. 选择合适的方法
3. 逐步计算
4. 验证答案
最后用 <answer> 标签包裹答案。"""

# ✅ 正确:只提供背景和输出约束
good_system = """你是一个数学助手,专注于高中数学竞赛题。
回答时,最终答案用 \\boxed{} 格式表示。"""

# ✅ 正确(Claude):利用内置推理能力
response = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=16000,
    thinking={"type": "enabled", "budget_tokens": 8000},
    system=good_system,  # 简洁的系统提示
    messages=[{"role": "user", "content": question}]
)

约束输出格式而不限制推理

关键原则:约束"你要输出什么",不要约束"你要怎么想":

# 场景:代码审查,需要 JSON 输出
system = """你是一个代码审查专家。
审查完成后,只输出以下 JSON 格式(不要其他内容):
{
  "bugs": [{"line": 数字, "severity": "high/medium/low", "description": "说明"}],
  "suggestions": ["建议1", "建议2"],
  "overall_score": 0-10
}"""

# 模型会在 thinking 中自由分析,最终输出符合格式
user_message = f"""请审查以下代码:
```python
{code}
```"""

难题分解:DECOMP 策略

对于极度复杂的问题,即使推理模型有时也需要帮助拆解:

def decomp_solve(complex_problem: str) -> str:
    # Step 1: 让模型分解问题(用简单的非推理模型即可)
    decompose_response = client.messages.create(
        model="claude-haiku-4-5-20251001",  # 快速模型
        max_tokens=1024,
        messages=[{"role": "user", "content":
            f"将以下复杂问题分解为3-5个必须按序解决的子问题:\n\n{complex_problem}"}]
    )
    sub_problems = parse_sub_problems(decompose_response.content[0].text)

    # Step 2: 逐个用推理模型解决子问题
    sub_solutions = []
    for sp in sub_problems:
        sol = client.messages.create(
            model="claude-sonnet-4-6",
            max_tokens=8000,
            thinking={"type": "enabled", "budget_tokens": 4000},
            messages=[{"role": "user", "content":
                f"已知背景:{sub_solutions}\n\n当前子问题:{sp}"}]
        )
        sub_solutions.append(extract_text(sol))

    # Step 3: 综合所有子解答
    final = client.messages.create(
        model="claude-sonnet-4-6",
        max_tokens=4000,
        messages=[{"role": "user", "content":
            f"原始问题:{complex_problem}\n\n子问题解答:{sub_solutions}\n\n请综合给出最终答案。"}]
    )
    return extract_text(final)

避免 Over-thinking 的技巧

问题简单时降低 budget_tokens
对于简单问题,设置 budget_tokens = 1000 防止模型"想太多"。过度思考不仅浪费 token,有时还会让模型把简单问题复杂化。
明确说明"不需要推导过程"
对于需要快速检索类的问题(如"Python 的列表方法有哪些"),可以在 prompt 中说明"请直接列出,不需要分析",节省推理 token。
用难度分级路由
对问题进行难度预估,简单问题用普通模型,复杂问题才启用推理模式。下一章的 Agent 架构中会详细介绍路由策略。
本章小结 推理模型的提示:简洁的 System Prompt + 只约束输出格式 + 不要触发词 + 难题用 DECOMP 分解。下一章将推理模型集成到 Agent 架构中。