Chapter 04

Claude 扩展思考模式:Extended Thinking API

Anthropic 于 2025 年在 Claude 3.7 Sonnet 中引入扩展思考,并持续在后续版本中增强。这是目前工程上最易用的推理模型 API。

Extended Thinking 的基本使用

import anthropic

client = anthropic.Anthropic()

response = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=16000,
    thinking={
        "type": "enabled",
        "budget_tokens": 10000  # 最多允许思考 10000 token
    },
    messages=[{
        "role": "user",
        "content": "证明:√2 是无理数"
    }]
)

# 响应包含 thinking block 和 text block
for block in response.content:
    if block.type == "thinking":
        print("[思考过程]", block.thinking[:200], "...")
    elif block.type == "text":
        print("[最终答案]", block.text)

响应结构解析

# 完整响应结构
{
  "id": "msg_01Xfn...",
  "type": "message",
  "role": "assistant",
  "content": [
    {
      "type": "thinking",
      "thinking": "我需要证明 √2 是无理数...\n假设 √2 = p/q(最简分数)...\n则 2 = p²/q²...\n..."
      # 注意:thinking 内容可能不完整,是模型草稿
    },
    {
      "type": "text",
      "text": "**证明**\n\n采用反证法:假设 √2 是有理数..."
    }
  ],
  "usage": {
    "input_tokens": 30,
    "cache_creation_input_tokens": 0,
    "cache_read_input_tokens": 0,
    "output_tokens": 8420  # 包含思考 token
  }
}

budget_tokens 的影响

budget_tokens 控制模型可以用于"思考"的最大 token 数,直接影响效果和成本:

budget_tokens适用场景估算成本(输出)
1,000 – 2,000简单多步问题,基本验证
5,000 – 8,000中等复杂度(推荐默认值)
10,000 – 16,000数学竞赛、复杂代码分析
32,000+极复杂研究问题很高
budget_tokens 是上限,不是保证 设置 budget_tokens=10000 不代表模型一定会思考 10000 个 token。模型会根据问题复杂度自行决定思考多少。简单问题即使预算很大也只会思考几百 token。

流式输出:实时显示思考过程

with client.messages.stream(
    model="claude-sonnet-4-6",
    max_tokens=16000,
    thinking={"type": "enabled", "budget_tokens": 8000},
    messages=[{"role": "user", "content": prompt}]
) as stream:
    current_block_type = None

    for event in stream:
        if hasattr(event, 'type'):
            if event.type == 'content_block_start':
                current_block_type = event.content_block.type
                if current_block_type == 'thinking':
                    print("\n🤔 [思考中...]", end="", flush=True)
                elif current_block_type == 'text':
                    print("\n\n💬 [回答]")

            elif event.type == 'content_block_delta':
                if current_block_type == 'thinking':
                    print(".", end="", flush=True)  # 思考时显示进度
                elif current_block_type == 'text':
                    print(event.delta.text, end="", flush=True)

在多轮对话中保留思考上下文

# 多轮对话中,需要将 thinking block 传回
conversation_history = []

def chat_with_thinking(user_message: str) -> str:
    conversation_history.append({
        "role": "user",
        "content": user_message
    })

    response = client.messages.create(
        model="claude-sonnet-4-6",
        max_tokens=16000,
        thinking={"type": "enabled", "budget_tokens": 5000},
        messages=conversation_history
    )

    # 将完整响应(含 thinking block)加入历史
    conversation_history.append({
        "role": "assistant",
        "content": response.content  # 必须包含 thinking block
    })

    # 只返回 text block 给用户
    return next(b.text for b in response.content if b.type == "text")
Prompt Caching + Extended Thinking 两者可以组合使用。在 System Prompt 中添加 "cache_control": {"type": "ephemeral"},可以缓存系统提示,减少重复的输入 token 费用。这在多轮推理对话中效果显著。
本章小结 Extended Thinking API 通过 budget_tokens 控制思考深度,响应包含 thinking(草稿)和 text(最终答案)两种 block。多轮对话需要将完整 content 传回。下一章进入推理模型的提示工程技巧。