Thinking Effort 控制 — Adaptive / Level-Switched¶
更新日期:2026-04-26
2024-2026 的 reasoning model(o1 / o3 / Claude 3.7+ / DeepSeek-R1 / Qwen3-Thinking / Kimi K2-Reasoning)共同特征:模型显式生成思考 token 后再回答。问题是 —— 思考多少?
本文按四个角度过:
- 怎么实现 thinking budget 控制(API / 模型层面)
- 怎么训练 adaptive thinking(让模型自己决定)
- 怎么训练 level-switched(用户给信号控制)
- 数据怎么构造、结构怎么改
主要参考:
- DeepSeek-R1 (2025)
- Claude 3.7 Sonnet — Extended Thinking 公告
- GPT-5 / o-series reasoning_effort(待核实)
- Qwen3-Thinking technical report(待核实)
一、什么是 thinking effort¶
flowchart LR
prompt["User<br/>2^17 = ?"]
think["<think><br/>多步推理"]
answer["<answer><br/>131072"]
prompt --> think --> answer
classDef stage fill:#fff,stroke:#cc785c,color:#1a1a1a;
class prompt,think,answer stage
Thinking effort = 思考阶段的 token 数(或 reasoning depth)。极简任务("Hi")几乎不需要 think,复杂题(IMO 题)可能需要 30k+ token thinking。
控制 effort 的两个维度:
- Adaptive:模型自动判断难度,动态决定 thinking 长度
- Level-switched:用户传
low / medium / high信号,模型按级别 think
二、API 层面控制:当前各家实现¶
2.1 OpenAI (GPT-5 / o-series)¶
# 推测的 API 形态(待核实当前 API spec)
response = client.chat.completions.create(
model="gpt-5",
messages=[...],
reasoning_effort="medium", # low / medium / high / auto
)
OpenAI 把 reasoning effort 暴露成 API 参数。具体每级对应多少 thinking token 不公开,估计:
low: < 1k thinking tokensmedium: 1k-10khigh: 10k-100kauto: 模型决定
2.2 Anthropic (Claude 3.7+ Extended Thinking)¶
response = client.messages.create(
model="claude-sonnet-4",
messages=[...],
thinking={"type": "enabled", "budget_tokens": 16000}, # 0 = disabled
)
Anthropic 用 budget_tokens 显式给上限。模型可以在 budget 内自由决定用多少。
2.3 DeepSeek (R1 / V3.1)¶
R1 没有 API 级 effort 参数 —— 模型总是输出 <think>...</think> reasoning。控制 thinking 长度靠 sampling 参数(max_tokens / stop strings)。
V3.1 引入 hybrid mode(reasoning ON/OFF 二态切换),由 system prompt 触发。
2.4 Qwen / Kimi(待核实)¶
Qwen3-Thinking 公开声明支持 <think>...</think>,effort 控制方式见各家 system prompt 约定。
2.5 Native vs API 实现差异¶
| 实现层 | 例子 | 优点 | 缺点 |
|---|---|---|---|
| API 参数 | OpenAI reasoning_effort | 用户简单 | 模型必须训过这个参数才能 work |
| Token budget | Anthropic budget_tokens | 灵活 | 用户得估 budget |
| System prompt 触发 | DeepSeek V3.1 | 兼容现有 API | 切换不直观 |
| 永远 thinking | R1, o1(无切换) | 不需要参数 | 简单问题浪费 token |
三、Adaptive thinking — 模型自己决定¶
3.1 什么是 adaptive¶
输入 prompt,模型根据 difficulty 自动决定 reasoning length:
- "Hi" → 0 thinking token
- "What is the capital of France?" → ~50 thinking token (verify)
- "Solve this PDE..." → 5k+ thinking token
3.2 训练目标设计¶
Adaptive thinking 的难点:怎么 reward "用最少 token 答对"。
朴素 reward:correctness only → 模型学会 "always think 20k tokens" 增加正确率 朴素加 length penalty → 模型学会 "skip thinking" 容易答错的题
3.3 已知方法¶
A. Length-Aware Reward¶
R1-style RL 加 length normalization:
def length_aware_reward(output, ground_truth, max_useful_length=10000):
correctness = check_correctness(output, ground_truth) # 0 or 1
length = len(extract_thinking(output))
# 正确时奖励短,错误时不惩罚长(让难题继续 think)
if correctness:
length_bonus = max(0, 1 - length / max_useful_length)
return 1.0 + 0.2 * length_bonus
else:
return 0.0
实际 R1 paper Section 2.3.4 提到尝试了 length penalty 但对 reasoning 能力有害,最终不用。OpenAI o1 / Anthropic 怎么做不公开。
B. Difficulty-conditioned curriculum¶
Anthropic / OpenAI 推测路线:
- 训练数据按难度分级(easy / medium / hard)
- 每个难度对应不同 thinking length 标签
- 训练时模型隐式学到 "看到难题就 think 长"
C. Self-evaluation reward¶
让模型自己判断"我需要再想一下吗":
# 推理时
think_step = generate_one_thinking_step()
confidence = model.estimate_confidence(prompt, think_so_far + think_step)
if confidence > THRESHOLD:
break # 模型觉得想够了
训练时奖励 confidence calibration —— 自评准的模型。
3.4 测 adaptive 是否 work¶
- Easy / hard 题对照:同模型,easy 题 thinking 短、hard 题 thinking 长 → adaptive
- Token efficiency:达到给定准确率所用 thinking token 数(越少越好)
- Calibration:模型对自己 confidence 的预测准不准
实际 frontier model(o1 / Claude 3.7)观察上确实 adaptive —— prompt 一句话回 200 tokens、prompt 一道竞赛题回 30k tokens。但具体训练方法不公开。
四、Level-switched thinking — 用户控制¶
4.1 高 / 中 / 低三档怎么训¶
Low / Medium / High 信号通常通过两种方式传进 model:
A. System prompt 编码¶
或:
训练时数据形如:
{
"system": "Reasoning level: low",
"user": "What's 2+3?",
"thinking": "5",
"answer": "5"
}
{
"system": "Reasoning level: high",
"user": "What's 2+3?",
"thinking": "Let me verify: 2+3 = 5. Indeed, 2 plus 3 is 5.",
"answer": "5"
}
模型学到 system prompt 里的 level → 控制 thinking 长度。
B. Special control token¶
# 在 tokenizer 里加 <|reasoning_low|>, <|reasoning_med|>, <|reasoning_high|>
input_ids = tokenizer.encode(
f"<|reasoning_high|>{prompt}"
)
模型在训练时看到 control token 时会 condition thinking length。比 system prompt 更确定(不依赖自然语言理解)。
C. Prefix tuning¶
每个 effort level 学一组 prefix embedding,inject 到 input 前段。轻量但需要训练时显式设计。
4.2 数据构造¶
训 level-switched 模型需要同 prompt 多种 effort 的数据:
def build_multi_effort_dataset(prompts, model_high_effort):
"""
针对每个 prompt,生成 low/med/high 三个版本的 (thinking, answer)
"""
dataset = []
for p in prompts:
# high effort: 完整 reasoning chain(用强模型 R1 / o1 生成)
high = model_high_effort.generate(p, reasoning="full")
# low effort: 直接 answer,最小 thinking
low_thinking = "Direct calculation."
low_answer = high.answer # 同样答案
# medium: high 的 reasoning 砍掉 50%(关键步骤保留)
med_thinking = condense_reasoning(high.thinking, ratio=0.5)
med_answer = high.answer
dataset.extend([
{"system": "level=low", "user": p, "thinking": low_thinking, "answer": low_answer},
{"system": "level=med", "user": p, "thinking": med_thinking, "answer": med_answer},
{"system": "level=high", "user": p, "thinking": high.thinking, "answer": high.answer},
])
return dataset
关键 trick:
- 三档的 answer 必须相同(不然模型学到 "low 等于错")
- thinking 的层次不是一刀切,要"按推理 step 截断"(保留最关键的 1-3 步)
- 难题在 low 级别可能答错 —— 这是符合设计的(low 速度优先,准确率次要)
4.3 Level vs token budget 的取舍¶
| 方式 | 训练复杂度 | 推理控制粒度 | 用户体验 |
|---|---|---|---|
| Level (low/med/high) | 中(需要分级数据) | 粗(3 档) | 简单,快速选 |
| Token budget | 简单(不需要分级) | 细(任意 token 数) | 用户得猜 budget |
| Auto (adaptive) | 高(需要 difficulty data) | 自动 | 最简单 |
| Hybrid (auto + override) | 高 | 自动 + 强制 | 最强 |
OpenAI 走 level(low/med/high/auto),Anthropic 走 budget,DeepSeek V3.1 走 binary on/off。当前没有"标准答案"。
五、结构怎么改¶
5.1 Tokenizer / Special tokens¶
加 reasoning control tokens:
<|think_start|> ... <|think_end|> # thinking 区间
<|reasoning_low|> / <|med|> / <|high|> # level 控制
<|stop_thinking|> # 强制结束 thinking
DeepSeek-R1 用 <think>...</think> (XML-like) 而不是 special token。两种方式都 work,trade-off:
- Special token:训练时 attention 容易识别,但加 vocab size
- XML-like:兼容现有 tokenizer,但模型需更大学习量
5.2 Position embedding 注意¶
Thinking 段经常很长(10k+ token)。如果 base model 训的 context 是 4k,YaRN 扩展到 32k+ 可能在 thinking 阶段失效。
实战经验:reasoning model 必须在长 context 训练(至少 32k),否则 thinking 长度受限。
5.3 Sampling parameter 调整¶
Reasoning model 在 thinking 阶段需要多样性(探索不同 reasoning path);answer 阶段需要确定性:
- Thinking: temperature ~0.6-0.8, top-p ~0.95
- Answer: temperature ~0.0-0.2, top-p ~0.5
实现上:在 <think> token 时切换 sampling param。vLLM / SGLang 有相关支持(待核实)。
5.4 KV Cache 处理¶
长 thinking → 大 KV cache。优化:
- Thinking KV discard:answer 生成完后 thinking 的 KV 不再需要,可释放
- Compressed thinking memory:长 thinking 段压缩到 latent vector(类似 Activation Beacon)
- Hierarchical thinking:先生成 high-level plan,每个 sub-step 独立 generate(树形 thinking)
六、如何训 adaptive 模型(伪代码 pipeline)¶
flowchart LR
base["Base LLM"]
s1["S1<br/>分级 SFT"]
s2["S2<br/>Adaptive RL"]
s3["S3<br/>Eval + 迭代"]
final["Adaptive<br/>Reasoning Model"]
base --> s1 --> s2 --> s3 --> final
classDef stage fill:#fff,stroke:#cc785c,color:#1a1a1a;
class base,s1,s2,s3,final stage
S1: prompt 含 low/med/high 三档 + adaptive 标记;S2: reward = correctness × token efficiency + KL 到 ref;S3: 检查 calibration + token efficiency。
6.1 Stage 1: 分级 SFT¶
sft_data = build_multi_effort_dataset(
prompts=collect_diverse_prompts(),
model_high_effort=existing_reasoning_model, # R1 / o1
)
# train: input = (system + user), target = (thinking + answer)
sft_model = sft(base_model, sft_data, epochs=2)
6.2 Stage 2: Adaptive RL¶
def adaptive_reward(output, ground_truth, prompt):
correctness = verify(output.answer, ground_truth)
thinking_len = len(output.thinking_tokens)
# 难题阈值:用 baseline correct rate 估计
difficulty = estimate_difficulty(prompt)
expected_len = difficulty * 1000 # 简单 → 100, 难 → 5000
# length 偏离 expected 越远越扣分
length_penalty = -abs(thinking_len - expected_len) / expected_len
return correctness + 0.1 * length_penalty
# GRPO 训练
adaptive_model = grpo(sft_model, adaptive_reward, **rl_config)
6.3 Stage 3: 评测¶
- Token efficiency curve:(accuracy, avg thinking tokens) 在 easy/med/hard 上
- Calibration:模型 self-confidence 跟 actual correctness 的相关性
- User study:实际用户感觉模型 "thinking too much / too little / 合适"
七、具体数据来源 — 怎么造分级数据¶
7.1 Easy 数据来源¶
- GSM8K easy subset(小学数学)—— 通常 1-3 step,thinking 短
- TriviaQA / NQ(事实 QA)—— 单 fact 检索
- Conversational data("hi", "thanks")—— 几乎不需要 thinking
- Translation 短句
构造:直接 SFT,thinking 段简短("Direct: ..." or 空)。
7.2 Medium 数据来源¶
- MATH 中难度题(高中数学)
- HumanEval / MBPP(标准编程)
- Multi-fact QA(需要 2-3 step)
- General knowledge with verification
构造:thinking 中等(200-1000 token),答案后简单 verify step。
7.3 Hard 数据来源¶
- AIME / IMO / Putnam 数学题
- Codeforces Div1 / LeetCode Hard
- GPQA Diamond 物理 / 化学专业题
- 专业 benchmark:MathOlympics, FrontierMath, ARC-AGI
构造:thinking 长(5k-30k token),含 multiple paths + dead-ends + self-correction。
7.4 难度自动分级¶
不能手工标几百万条数据。自动分级:
def auto_grade_difficulty(prompt, sample_model, n_attempts=10):
"""
用一个中等强度模型多次尝试,按通过率估计难度
"""
successes = 0
for _ in range(n_attempts):
out = sample_model.generate(prompt)
if verify(out, ground_truth):
successes += 1
pass_rate = successes / n_attempts
if pass_rate > 0.8:
return "easy"
elif pass_rate > 0.3:
return "medium"
else:
return "hard"
这是 R1 / Qwen3 / Kimi 等大概率用的自动 grading 方法(具体细节不公开)。
八、实操建议¶
如果在 Kimi K2 / 自家模型上加 thinking effort 控制:
- 第一版做 binary on/off(DeepSeek V3.1 路线)—— 最容易,system prompt 触发 + SFT 即可
- 第二版做 3 级(low/med/high):
- 收集 100k 多样 prompt
- 自动分级(pass-rate 法)
- 每 prompt 用 R1-style 模型生成 high-effort answer
- 用 LLM truncate 成 medium / low 版本
- SFT on 3-level data
- 第三版做 adaptive(最难):
- 加 length-aware reward 的 RL
- 配 calibration eval
- 调 reward weight 是核心难点
最大的坑:
- 三级数据的 answer 必须一致 —— 不然模型学到 "low = 简化但错",废
- Thinking 必须真的有意义 —— low 不要简化成 "Direct: 5",要有最小 verification
- Curriculum 别跳级 —— 先 easy/medium 训稳,再加 hard
九、未公开 / 待核实¶
各家 thinking control 实现细节几乎都不公开:
- OpenAI 怎么训 reasoning_effort 4 级(low/med/high/auto)?
- Anthropic budget_tokens 是 hard limit 还是 soft hint?
- DeepSeek V3.1 怎么从 V3 加 reasoning ON/OFF 切换 —— 是新训还是 adapter?
- Qwen3-Thinking 的 thinking detection 机制
- Kimi K2-Reasoning thinking budget 控制方法
这些是各家 moat。学术界(Adaptive Reasoning、[Self-Adaptive Cognitive Debate])有相关工作但没规模化复现。
参考文献¶
- DeepSeek-AI. DeepSeek-R1. 2025. arXiv:2501.12948
- Anthropic. Claude 3.7 Sonnet — Extended Thinking. 2025. anthropic.com/news/claude-3-7-sonnet
- OpenAI. Learning to Reason with LLMs (o1). 2024. openai.com/index/learning-to-reason-with-llms
- Kimi Team. Kimi K2: Open Agentic Intelligence. 2025. arXiv:2507.20534
- Qwen Team. Qwen3 Technical Report. 2025. arXiv:2505.09388(待核实)
- Wei et al. Chain-of-Thought Prompting. 2022. arXiv:2201.11903
- Kojima et al. Large Language Models are Zero-Shot Reasoners. 2022. arXiv:2205.11916
- Lightman et al. Let's Verify Step by Step (PRM). 2023. arXiv:2305.20050
↑ 上级 · J. 推理行为与失败模式