跳转到主内容
本站为独立第三方技术服务商,Claude™ 与 Anthropic® 为 Anthropic, PBC 的商标,本站与 Anthropic 无任何关联、授权或合作关系。

Extended Thinking 实战指南:Opus 4.7 时代该怎么用思考预算(含 adaptive 与 effort 完整代码)

Claude Opus 4.7 已经废弃 budget_tokens,只接受 adaptive thinking + effort 参数。本文给出 4.7 / 4.6 / Sonnet 4.6 三个模型上 Extended Thinking 的完整调用方式、interleaved thinking 在工具循环中的正确写法、prompt caching 的坑、以及一份带场景的 effort 选型表。

开发指南Extended Thinking思考链预计阅读10分钟
2026.05.28 发表
Extended Thinking 实战指南:Opus 4.7 时代该怎么用思考预算(含 adaptive 与 effort 完整代码)

Extended Thinking 实战指南:Opus 4.7 时代该怎么用思考预算

大多数关于 Extended Thinking 的中文资料还在教 thinking: {type: "enabled", budget_tokens: 10000}——这套写法在 Opus 4.7 上直接报错。本文按 2026-05 的实际 API 行为给出 4.7 / 4.6 / Sonnet 4.6 三个模型的正确用法,附 effort 选型表、interleaved thinking 在 tool loop 里的完整闭环、以及最容易踩的两个 prompt caching 坑。


一、半年里 thinking 接口换了一次写法

如果你的代码库里还有这样的调用:

response = client.messages.create(
    model="claude-opus-4-7",  # 这一行
    max_tokens=16000,
    thinking={"type": "enabled", "budget_tokens": 10000},  # 这一行
    messages=[...]
)
response = client.messages.create(
    model="claude-opus-4-7",  # 这一行
    max_tokens=16000,
    thinking={"type": "enabled", "budget_tokens": 10000},  # 这一行
    messages=[...]
)

把 model 改成 Opus 4.7 之后,整个请求会失败。原因是 Anthropic 在 4.6/4.7 这一代把 thinking 接口从"显式预算"切到了"adaptive + effort"——4.7 已经不再接受老写法。

变更摘要:

模型 老写法(type: enabled + budget_tokens 新写法(type: adaptive + effort
Opus 4.7 ❌ 不再接受 ✅ 唯一支持的方式
Opus 4.6 ⚠️ 仍可用但已 deprecated ✅ 推荐
Sonnet 4.6 ⚠️ 仍可用但已 deprecated ✅ 推荐
Sonnet 4.6 + tool 间思考 需要 interleaved-thinking-2025-05-14 beta header adaptive 模式自动启用

这意味着如果你打算把 Opus 4.7 接进现有 agent 链路,第一步就是把 thinking 配置改成 adaptive——而不是简单地换模型 ID。


二、adaptive thinking 是什么

老写法的设计是:你告诉模型"最多花 10000 token 思考"。模型可能用满,也可能只用一部分。问题在于:

  • 简单问题被强制思考浪费 token
  • 复杂问题如果设小了又思考不够

adaptive thinking 把这个判断权交给模型,由 effort 参数控制激进程度:

effort 行为 适用场景
low 简单问题模型常常完全跳过思考 低成本、低延迟的轻量调用
medium 平衡——只在判断有必要时思考 一般生产任务
high(默认) 几乎总会先思考 生产环境的推理任务
max(仅 Opus 4.6/4.7) 最大思考强度 AIME 级数学、长链路 agent、最难的 bug

Anthropic 的内部评测显示:在大量任务上 adaptive 的 token 利用率优于固定 budget——因为它不会在简单题上浪费推理,也不会在难题上提前收手


三、完整调用代码(Python)

环境准备:

pip install anthropic
pip install anthropic

3.1 Opus 4.7 调用(唯一支持 adaptive)

import anthropic

client = anthropic.Anthropic(
    api_key="sk-你的ClaudeAPI密钥",
    base_url="https://gw.claudeapi.com"
)

response = client.messages.create(
    model="claude-opus-4-7",
    max_tokens=16000,
    thinking={"type": "adaptive"},
    output_config={"effort": "high"},
    messages=[
        {"role": "user", "content": "证明:模 4 余 3 的素数有无穷多个。"}
    ]
)

for block in response.content:
    if block.type == "thinking":
        print(f"[思考] {block.thinking[:200]}...")
    elif block.type == "text":
        print(f"[答案] {block.text}")
import anthropic

client = anthropic.Anthropic(
    api_key="sk-你的ClaudeAPI密钥",
    base_url="https://gw.claudeapi.com"
)

response = client.messages.create(
    model="claude-opus-4-7",
    max_tokens=16000,
    thinking={"type": "adaptive"},
    output_config={"effort": "high"},
    messages=[
        {"role": "user", "content": "证明:模 4 余 3 的素数有无穷多个。"}
    ]
)

for block in response.content:
    if block.type == "thinking":
        print(f"[思考] {block.thinking[:200]}...")
    elif block.type == "text":
        print(f"[答案] {block.text}")

返回的 content 是按顺序排列的 block 数组:先一个 thinking block(包含模型的推理过程摘要),再一个 text block(最终答案)。

3.2 在 Sonnet 4.6 上同样的写法

response = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=16000,
    thinking={"type": "adaptive"},
    output_config={"effort": "medium"},  # Sonnet 不支持 max
    messages=[{"role": "user", "content": "..."}]
)
response = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=16000,
    thinking={"type": "adaptive"},
    output_config={"effort": "medium"},  # Sonnet 不支持 max
    messages=[{"role": "user", "content": "..."}]
)

注意:Sonnet 4.6 上 effort: max 不被接受——max 是 Opus 系列独占的。日常生产用 medium,关键推理才上 high

3.3 Opus 4.6 上的两种写法都能用,但应该用 adaptive

# ✅ 推荐
response = client.messages.create(
    model="claude-opus-4-6",
    max_tokens=16000,
    thinking={"type": "adaptive"},
    output_config={"effort": "high"},
    messages=[...]
)

# ⚠️ 仍可工作但已 deprecated,建议尽快迁移
response = client.messages.create(
    model="claude-opus-4-6",
    max_tokens=16000,
    thinking={"type": "enabled", "budget_tokens": 10000},
    messages=[...]
)
# ✅ 推荐
response = client.messages.create(
    model="claude-opus-4-6",
    max_tokens=16000,
    thinking={"type": "adaptive"},
    output_config={"effort": "high"},
    messages=[...]
)

# ⚠️ 仍可工作但已 deprecated,建议尽快迁移
response = client.messages.create(
    model="claude-opus-4-6",
    max_tokens=16000,
    thinking={"type": "enabled", "budget_tokens": 10000},
    messages=[...]
)

四、Node.js / TypeScript 版本

import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic({
  apiKey: "sk-你的ClaudeAPI密钥",
  baseURL: "https://gw.claudeapi.com",
});

const response = await client.messages.create({
  model: "claude-opus-4-7",
  max_tokens: 16000,
  thinking: { type: "adaptive" },
  output_config: { effort: "high" },
  messages: [{ role: "user", content: "你的复杂推理任务" }],
});

for (const block of response.content) {
  if (block.type === "thinking") {
    console.log("[思考]", block.thinking);
  } else if (block.type === "text") {
    console.log("[答案]", block.text);
  }
}
import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic({
  apiKey: "sk-你的ClaudeAPI密钥",
  baseURL: "https://gw.claudeapi.com",
});

const response = await client.messages.create({
  model: "claude-opus-4-7",
  max_tokens: 16000,
  thinking: { type: "adaptive" },
  output_config: { effort: "high" },
  messages: [{ role: "user", content: "你的复杂推理任务" }],
});

for (const block of response.content) {
  if (block.type === "thinking") {
    console.log("[思考]", block.thinking);
  } else if (block.type === "text") {
    console.log("[答案]", block.text);
  }
}

五、interleaved thinking:tool 循环里的关键变化

Extended Thinking 在 agent 场景下真正强大的地方,是允许模型在每次调用 tool 后再思考一轮——也就是 interleaved thinking。

老写法在 Sonnet 4.6 上要手动加 beta header:

client = anthropic.Anthropic(
    api_key="sk-你的ClaudeAPI密钥",
    base_url="https://gw.claudeapi.com",
    default_headers={"anthropic-beta": "interleaved-thinking-2025-05-14"}
)
client = anthropic.Anthropic(
    api_key="sk-你的ClaudeAPI密钥",
    base_url="https://gw.claudeapi.com",
    default_headers={"anthropic-beta": "interleaved-thinking-2025-05-14"}
)

Opus 4.7 和 4.6 的 adaptive 模式下,interleaved thinking 默认就开,不需要任何 beta header。这是迁移到 4.7 的一个隐藏收益——agent 链路里不再需要管 thinking 旗子。

完整 tool-use 循环(关键点:上一轮的 thinking block 必须原样回填):

weather_tool = {
    "name": "get_weather",
    "description": "获取指定城市的实时天气",
    "input_schema": {
        "type": "object",
        "properties": {"city": {"type": "string"}},
        "required": ["city"]
    }
}

# 第一轮:模型先思考再决定调 tool
response_1 = client.messages.create(
    model="claude-opus-4-7",
    max_tokens=8000,
    thinking={"type": "adaptive"},
    output_config={"effort": "high"},
    tools=[weather_tool],
    messages=[
        {"role": "user", "content": "巴黎现在适合穿什么?给出具体建议。"}
    ]
)

# 第二轮:把 thinking block + tool_use block 原样回填,加 tool_result
thinking_block = next(b for b in response_1.content if b.type == "thinking")
tool_use_block = next(b for b in response_1.content if b.type == "tool_use")

response_2 = client.messages.create(
    model="claude-opus-4-7",
    max_tokens=8000,
    thinking={"type": "adaptive"},
    output_config={"effort": "high"},
    tools=[weather_tool],
    messages=[
        {"role": "user", "content": "巴黎现在适合穿什么?给出具体建议。"},
        {
            "role": "assistant",
            "content": [thinking_block, tool_use_block]  # ← 关键
        },
        {
            "role": "user",
            "content": [{
                "type": "tool_result",
                "tool_use_id": tool_use_block.id,
                "content": "巴黎 22°C,晴,微风。"
            }]
        }
    ]
)
weather_tool = {
    "name": "get_weather",
    "description": "获取指定城市的实时天气",
    "input_schema": {
        "type": "object",
        "properties": {"city": {"type": "string"}},
        "required": ["city"]
    }
}

# 第一轮:模型先思考再决定调 tool
response_1 = client.messages.create(
    model="claude-opus-4-7",
    max_tokens=8000,
    thinking={"type": "adaptive"},
    output_config={"effort": "high"},
    tools=[weather_tool],
    messages=[
        {"role": "user", "content": "巴黎现在适合穿什么?给出具体建议。"}
    ]
)

# 第二轮:把 thinking block + tool_use block 原样回填,加 tool_result
thinking_block = next(b for b in response_1.content if b.type == "thinking")
tool_use_block = next(b for b in response_1.content if b.type == "tool_use")

response_2 = client.messages.create(
    model="claude-opus-4-7",
    max_tokens=8000,
    thinking={"type": "adaptive"},
    output_config={"effort": "high"},
    tools=[weather_tool],
    messages=[
        {"role": "user", "content": "巴黎现在适合穿什么?给出具体建议。"},
        {
            "role": "assistant",
            "content": [thinking_block, tool_use_block]  # ← 关键
        },
        {
            "role": "user",
            "content": [{
                "type": "tool_result",
                "tool_use_id": tool_use_block.id,
                "content": "巴黎 22°C,晴,微风。"
            }]
        }
    ]
)

没回填 thinking block 的后果:模型会"失忆",把刚才的推理过程丢掉,第二轮决策质量明显下降。这是接 agent 链路时最常踩的坑。


六、effort 选型:到底用哪一档

按业务任务类型选,不要默认 high:

任务 推荐 effort 模型 备注
简单分类、信息抽取 low 或不开 thinking Haiku 4.5 / Sonnet 4.6 开 thinking 反而加成本与延迟
常规问答、文档生成 medium Sonnet 4.6 性价比甜点
代码 review、PR 分析 mediumhigh Sonnet 4.6 / Opus 4.6 多步推理但不至于 max
复杂算法、架构设计 high Opus 4.7 需要长链条思考
AIME 级数学、最难的 debug max Opus 4.7 / 4.6 极限场景,单次成本明显上升

一个有用的经验法则:开 thinking 之前先用普通模式跑一遍,如果普通模式答得不错,就不开;如果普通模式有明显问题(漏了约束、逻辑跳步、答非所问),再上 thinking。盲目默认 high 是 Uber 月人均 $2000 账单的成因之一。


七、容易踩的坑

坑 1:thinking 与 prompt caching 的隐藏耦合

prompt caching 的 cache key 包含 thinking 配置。这意味着:

# 第一次:建缓存
client.messages.create(
    ...,
    thinking={"type": "adaptive"},
    output_config={"effort": "medium"},
    system=[{"type": "text", "text": LONG_SYSTEM, "cache_control": {"type": "ephemeral"}}],
    ...
)

# 第二次:把 effort 改成 high → 缓存失效,重新计费
client.messages.create(
    ...,
    thinking={"type": "adaptive"},
    output_config={"effort": "high"},  # 改了
    system=[{"type": "text", "text": LONG_SYSTEM, "cache_control": {"type": "ephemeral"}}],
    ...
)
# 第一次:建缓存
client.messages.create(
    ...,
    thinking={"type": "adaptive"},
    output_config={"effort": "medium"},
    system=[{"type": "text", "text": LONG_SYSTEM, "cache_control": {"type": "ephemeral"}}],
    ...
)

# 第二次:把 effort 改成 high → 缓存失效,重新计费
client.messages.create(
    ...,
    thinking={"type": "adaptive"},
    output_config={"effort": "high"},  # 改了
    system=[{"type": "text", "text": LONG_SYSTEM, "cache_control": {"type": "ephemeral"}}],
    ...
)

实战建议:同一条工作流内 effort 固定,不要在 A/B 测试时改 effort 又指望 cache 命中。

坑 2:thinking block 不会跨轮保留

模型每次返回 thinking block,但在下一轮请求时这些 block 默认不在上下文里——除非你像第五节那样手动回填。多轮对话场景里如果忽略这点,模型会反复"重新思考一遍"已经想过的事,token 浪费严重。

坑 3:thinking 计费是全过程,不是可见摘要

你拿到的 block.thinking 是模型自己生成的思考摘要——但计费按完整内部思考过程,可能是摘要的 3-5 倍。一个看起来 200 字的 thinking block,背后可能消耗了 5000 token。月底账单和你看屏幕估算的不一样,原因常常在这里。

坑 4:thinking 与几个采样参数互斥

开启 thinking 时不能用:

  • temperature ≠ 1 或 top_k
  • top_p < 0.95
  • forced tool use(tool_choice 指定具体工具名)
  • response prefill(用 assistant 消息预填模型回复)

如果原代码里有这些参数,迁移到 thinking 时要先拿掉。


八、对照 checklist:从老代码迁移到 adaptive

代码层:

  • [ ] 把 thinking: {"type": "enabled", "budget_tokens": N} 改成 thinking: {"type": "adaptive"}
  • [ ] 加上 output_config: {"effort": "..."},按上表选档
  • [ ] 移除 interleaved-thinking-2025-05-14 beta header(adaptive 自动开)
  • [ ] 检查 temperaturetop_ktool_choice、prefill 是否与 thinking 冲突

工程层:

  • [ ] 多轮对话的 thinking block 回填逻辑
  • [ ] prompt caching 的 effort 一致性
  • [ ] 账单告警:把 thinking token 与可见输出 token 分开监控

测试层:

  • [ ] 同一个 prompt 在 effort: low / medium / high 三档下跑一遍,记录质量与 token 消耗
  • [ ] agent 链路:tool_result 回填后第二轮 thinking 是否仍然合理

九、小结

做对一件事就够了:默认用 adaptive,按任务类型选 effort,不要一上来就 high。

claudeapi.com 提供 Claude Opus 4.7、Opus 4.6、Sonnet 4.6、Haiku 4.5 完整能力,兼容 Anthropic SDK 格式,仅需替换 base_url 即可平滑接入现有项目。控制台支持按 API Key 维度查看 thinking token 与普通 token 的分项消耗,定位"思考太狠"问题更直接。

立即体验:claudeapi.com · 完整模型与定价见 console.claudeapi.com

相关文章