## 引言:餐厅的点餐策略
想象你走进一家餐厅。服务员问你:"今天想怎么用餐?"
**场景一:快餐店**
你赶时间,需要5分钟内吃完。你点了一个汉堡,可乐,薯条。没有前菜,没有甜点,没有侍酒师推荐。你知道这顿饭不会是你人生中最美味的一餐,但它完成了任务——你不再饿了。
**场景二:商务宴请**
你要请一个重要客户。你点了四道菜的套餐,配了酒,还有饭后甜点。你不在乎这顿饭要花两小时,你只在乎客户是否满意,合作能否谈成。
**场景三:私房定制**
你正在庆祝结婚十周年。你提前两周预定了主厨的私人菜单,每道菜都是根据你们的口味特别设计的,配酒师为你选了1982年的拉菲。你花了普通人一个月的工资,但你觉得值。
同一个你,三种不同的预算策略。
这不是因为你在快餐店就变穷了,也不是因为私房宴你就暴富了。而是因为**不同的场景需要不同的投入**。这就是思考预算的本质——让AI学会"该省省,该花花"。
但问题是:今天的AI不会点餐。它要么对每个问题都狼吞虎咽(DeepThink模式,烧掉你的钱包),要么对每个问题都敷衍了事(快速模式,让你怀疑人生)。它没有"看场合"的能力。
这篇文章要聊的,就是如何教会AI这个能力。
---
## 第一章:思考预算是什么?
### 1.1 一个具体的例子
假设你问AI两个问题:
**问题A**:"2+2等于几?"
**问题B**:"设计一个能容纳1000万用户的分布式数据库架构,要求读写分离、主从同步延迟小于100毫秒、支持跨地域容灾,预算控制在50万美元以内。"
如果AI对这两个问题花费同样的时间、同样的计算资源、生成同样长度的思考过程——那它就不是智能,它是愚蠢。
人类不会这样。你问一个数学家"2+2",他会直接说"4"。你问他那个数据库问题,他可能会沉默几分钟,拿出纸笔画图,问你一堆跟进问题,然后说"我需要回去想想,明天给你答复"。
**思考预算(Thinking Budget)** 就是让AI具备这种"看人下菜碟"的能力——根据问题的复杂度,动态分配推理时计算资源。
### 1.2 训练时计算 vs 推理时计算
要理解思考预算,得先搞清楚两种计算的区别。
**训练时计算** 是"上学阶段"。模型读了互联网上的万亿token,学会了语言规律、世界知识、推理模式。这步已经完成了,成本已经沉没——不管是OpenAI还是DeepSeek,训练费用都是天文数字,但和我们今天的讨论无关。
**推理时计算** 是"工作阶段"。你问模型一个问题,它开始思考、生成token、输出答案。这是持续发生的成本。你问得越多,账单越长。
传统的大模型优化几乎全部集中在训练时——更大的模型、更多的数据、更好的架构。但2024年开始,大家意识到一件有趣的事:**推理时计算也可以被优化**。
不是让模型变得更"聪明"(那需要重新训练),而是让模型变得更"精明"——知道什么时候该全力以赴,什么时候可以敷衍了事。
这就像两个同样聪明的学生。一个每道题都写满三页草稿纸,另一个看简单题直接写答案,难题才展开推导。考试结束时,他们的分数可能一样,但第二个学生节省了大量时间。
### 1.3 为什么现在成为热点?
思考预算不是新概念,但它现在成为热点有三个原因:
**第一,钱的问题变得真实了。**
2023年,LLM的成本还主要是训练成本。推理相对便宜。但2024年开始,随着推理模型(o1、DeepSeek-R1)的兴起,单次查询的成本暴涨。DeepSeek-R1生成一个答案可能要消耗数万token的思考过程——这比GPT-4的常规回复贵了一个数量级。
当成本差距达到10倍、100倍时,"怎么省着用"就成了真问题。
**第二,延迟变得不可忍受。**
如果你问一个简单问题,AI思考了30秒才回答——这不是智能,这是折磨。用户期待的是"秒回",但复杂问题确实需要深思熟虑。没有分层策略,你只能二选一:要么所有问题都快但肤浅,要么所有问题都慢但深入。
**第三,产品化的需求。**
Claude Code、Cursor、Windsurf这些产品已经把推理模型集成到开发工作流中。开发者需要不同的模式——快速补全代码时希望毫秒级响应,设计系统架构时愿意等几分钟。没有思考预算控制,这种产品体验就做不出来。
---
## 第二章:六种技术路线
现在让我们看看学术界和工业界已经探索出的技术路线。我不会给你一堆术语让你背,我们会像拆解一台收音机一样,看看每个方案是怎么工作的。
### 2.1 方案一:Token预算强制(Budget Forcing)
这是最简单粗暴的方法,来自斯坦福大学2025年1月发布的s1论文。
**它是怎么工作的?**
想象你正在写一篇文章,老师站在你旁边说:"你必须写到500字才能停"或者"最多写500字,到点就停"。
Budget Forcing就是这个老师。
它有两个模式:
**最大预算模式**:当模型的思考token达到上限时,强行插入一个"</thinking>"标记,逼它结束思考开始输出答案。这就像考试结束铃响了,你必须放下笔。
**最小预算模式**:当模型的思考token还没达到下限时,如果它试图输出"</thinking>",系统会抑制这个标记,并追加一句"Wait"(等等),鼓励它继续推理。这就像老师说:"再想想,别急着交卷。"
**实际效果如何?**
s1-32B模型在AIME24数学竞赛上的表现:
- 基线(无预算控制):50%准确率
- 使用Budget Forcing优化后:57%准确率
- 通过4倍预算扩展:56.7%准确率
看起来提升不大?但关键是 **成本**。 Budget Forcing让研究人员发现:很多情况下,模型其实还没"想够"就急着给出答案了。逼它多想想,质量就上去了。
但这里有个陷阱。论文坦诚地指出:有时候模型会进入"重复循环"——它不是在想新东西,而是在重复已经说过的话。这就像一个人为了凑字数,把同一句话换个说法说三遍。
**适用场景**:快速原型、研究实验、对实现复杂度敏感的场景。
---
### 2.2 方案二:分级Effort Level(Claude Code)
这是Anthropic在Claude Code中采用的方法,也是目前产品化最成熟的方案。
**四个级别是什么?**
Claude Code把思考预算分成四个明确的档位:
| 级别 | 特点 | 适用场景 |
|------|------|----------|
| **Low** | 最小思考预算,快速响应,主要依赖训练知识 | 简单问题、代码补全、快速查询 |
| **Medium** | 适度推理,默认配置,适合大多数任务 | 日常开发、一般性分析 |
| **High** | 大量推理,复杂逻辑、多步推理 | 架构设计、复杂Bug调试 |
| **Max** | 完整预算,深度推理,关键决策 | 系统核心设计、重要代码审查 |
**计费方式是怎样的?**
这是用户最关心的部分。Claude Code的思考token是按输出token费率计费的。这意味着:
- Low级别可能只花费几美分的思考成本
- Max级别可能比Low贵10倍以上
- 用户看不到思考过程的具体内容,但要为它付费
这就像你去餐厅吃饭,后厨花了多少人力成本你不清楚,但账单上会体现出来。
**为什么是产品级的最佳实践?**
Claude Code的方案之所以值得学习,是因为它解决了一个关键问题:**用户如何理解不同级别的差异?**
四个级别的命名非常直观——Low、Medium、High、Max。用户不需要理解背后的技术细节,凭直觉就知道"简单问题用Low,重要问题用Max"。
而且,Anthropic通过大量用户反馈,已经校准了每个级别对应的思考深度。这不是拍脑袋定的,是数据驱动的。
**适用场景**:面向用户的产品、API服务、需要可预测成本的场景。
---
### 2.3 方案三:动态早退(DEER)
Budget Forcing的问题是"一刀切"——不管问题本身需要多少思考,都强制在规定字数内完成。这就像不管菜好不好吃,到了时间就收盘子。
DEER(Dynamic Early Exit in Reasoning)想解决这个问题。
**核心洞察是什么?**
研究团队发现,推理模型在思考过程中有一些"转换点"——当模型说出"Wait"(等等)、"Alternatively"(另一种可能是)、"Let me reconsider"(让我重新考虑)时,往往意味着它正在产生新的思路。
DEER的方法就是 **监控这些转换点**。
**具体怎么工作?**
1. **监控推理过程**:系统持续观察模型生成的思考token
2. **识别转换信号**:当检测到"Wait"等关键词时,触发试探机制
3. **生成试探答案**:基于当前思考状态,生成一个临时答案
4. **置信度评估**:评估这个试探答案的置信度
5. **决策**:如果置信度足够高,提前结束思考;如果不够高,继续推理
这就像你解数学题时,做到一半突然感觉"好像可以出答案了",于是你验算一下,如果验算通过就直接交卷,如果不通过就继续算。
**效果如何?**
在DeepSeek-R1-Distill-Qwen-7B上的测试结果:
- 平均缩短46%的token消耗
- 97.4%的样本实现了早退
- 准确率没有下降,甚至略有提升
为什么准确率会提升?因为DEER避免了"过度思考"——有时候想太多反而会把简单问题复杂化。
**适用场景**:效率优先、资源受限、对延迟敏感的场景。
---
### 2.4 方案四:置信度感知推理(CaR)
DEER的问题是它依赖特定的关键词(如"Wait")来判断转换点。但不同模型的表达方式不同,中文模型可能不说"Wait"而说"等等"。有没有更通用的方法?
CaR(Confidence-Aware Reasoning)提供了一种更本质的解决方案。
**核心思想是什么?**
想象你在做一个选择题。有时候你读完题就知道答案,有时候你需要排除法,有时候你完全没把握只能蒙一个。
CaR就是让模型具备这种"自知之明"——知道自己什么时候确定,什么时候不确定。
**两阶段门控机制**
CaR有两个评估点:
1. **推理块置信度**:评估当前这一大块推理内容的置信度。如果置信度高,可以考虑结束;如果低,继续推理。
2. **最终答案置信度**:评估生成的最终答案的置信度。如果不满意,可以要求模型重新思考。
**信息论信号**
最精妙的部分是CaR使用信息论方法来评估不确定性。它不看关键词,而是看模型输出的概率分布——如果模型对某个结论非常确定,概率分布会集中在少数几个token上;如果不确定,分布会很分散。
这就像老师批改试卷时,不只是看答案对不对,还要看学生的解题过程是否自信、逻辑是否连贯。
**"Think just enough"哲学**
CaR的核心理念是"刚好够的思考":
- 不确定的时候,延长推理,收集更多信息
- 自信的时候,缩短推理,避免过度思考
- 动态调整,而不是预设固定预算
**适用场景**:需要质量与效率平衡的场景、不同复杂度问题混合的场景。
---
### 2.5 方案五:层间早退(TIDE)
前面的方案都是在"内容层面"做文章——看模型生成了什么token,然后决定是否继续。TIDE(Token-Importance-Driven Early Exit)则深入到了模型的"物理结构"。
**一个类比**
想象一个100层的摩天大楼。传统的方法是:你必须从1层走到100层才能知道楼顶的风景。但TIDE发现,有时候你在50层看到的景色已经和100层差不多了——你可以提前退出。
在Transformer模型中,每一层都在对输入进行变换。TIDE的核心洞察是:**当隐藏状态(hidden states)在相邻层之间变化很小时,说明模型已经"想明白了",可以提前退出。**
**Router判断机制**
TIDE在每一层之后都加了一个"Router"(路由器)。这个Router的任务是判断:当前层的输出是否已经足够好?如果是,就直接输出了,不需要继续走后面的层。
**可配置阈值**
TIDE提供了四个预设的相似度阈值:
| 阈值 | 策略 | 质量 | 效率 |
|------|------|------|------|
| 0.95 | 保守 | 极少退出,最高质量 | 最低效率 |
| 0.85 | 默认 | 平衡 | 平衡 |
| 0.70 | 激进 | 更多退出,轻微质量影响 | 较高效率 |
| 0.30 | 最大退出 | 仅质量不敏感任务 | 最高效率 |
这个相似度是怎么算的?简单说,就是比较第N层和第N+1层的输出向量的余弦相似度。如果相似度超过阈值,说明继续走下一层带来的信息增益很小。
**代价是什么?**
TIDE的代价是 **实现复杂度**。它需要修改模型架构,添加Router模块。这不是简单地在prompt里加几句话就能实现的,可能需要重新训练或至少是模型微调。
**适用场景**:极致性能要求、有资源进行模型层面优化的场景。
---
### 2.6 方案六:推理努力参数(Reasoning Effort)
这是OpenAI在o1、o3、o4-mini以及开源的GPT-OSS中采用的方法。
**最简单的控制方式**
推理努力参数的核心思想是:**不需要修改模型,不需要复杂算法,只需要在system prompt里告诉模型"请用low/medium/high effort思考"**。
这听起来太简单了,以至于让人怀疑它是否有效。但OpenAI的研究发现:**同一个模型权重,仅仅是system prompt不同,就能产生显著不同的推理行为。**
**反直觉的发现**
研究团队观察到一些有趣的现象:
- **低effort模式**:模型在每个token上"想得更深"(hidden states的depth更大),但生成的序列较短
- **高effort模式**:模型在每个token上"想得较浅",但生成的序列更长
- 结果是:高effort模式的总计算量更大,性能更好
这有点像两个人写文章:
- 一个人字斟句酌,每句话都反复推敲,但文章很短
- 另一个人写得很快,但会写很多段落、很多修改、很多补充
最终,第二个人可能写出一篇更完整的文章,尽管他每个字花的功夫更少。
**为什么有效?**
这背后的机制还不完全清楚,但一个可能的解释是:system prompt改变了模型的"行为模式"。低effort模式下,模型更依赖训练时的直觉反应;高effort模式下,模型更倾向于显式推理、逐步分析、自我修正。
**适用场景**:云端服务、快速部署、不想修改模型架构的场景。
---
### 2.7 六种方案对比
让我们把这六种方案放在一起比较:
| 方案 | 控制层级 | 实现复杂度 | 质量影响 | 适用场景 |
|------|----------|------------|----------|----------|
| Budget Forcing | 解码层 | 低 | 中等 | 快速原型、研究实验 |
| Effort Level | 提示词层 | 低 | 高 | 产品级API、用户体验优先 |
| DEER | 推理过程 | 中 | 低 | 效率优先、延迟敏感 |
| CaR | 内容层 | 中 | 低 | 平衡方案、混合复杂度场景 |
| TIDE | 架构层 | 高 | 可控 | 极致性能、深度优化 |
| Reasoning Effort | 训练后层 | 低 | 高 | 云端服务、快速部署 |
**选择建议**:
- 如果你需要快速验证概念,用Budget Forcing或Reasoning Effort
- 如果你在做面向用户的产品,参考Claude Code的Effort Level设计
- 如果你追求极致效率,考虑DEER或CaR
- 如果你有模型优化的资源,尝试TIDE
---
## 第三章:关键设计决策
选择技术方案只是第一步。真正让一个思考预算系统好用的,是背后的一系列设计决策。
### 3.1 预算定义的粒度
**粗粒度:三个固定级别**
Low / Medium / High。简单、直观、用户容易理解。
优点:
- 用户学习成本低
- 容易在UI中呈现(比如三个按钮)
- 便于定价和计费
缺点:
- 不够灵活,可能浪费或不足
- 对于处于边界的问题(Medium太轻、High太重)没有好选择
**细粒度:连续值或特定token数**
用户可以直接指定"最多使用4096个token思考"或者"思考预算70%"。
优点:
- 精确控制
- 适合专业用户
缺点:
- 普通用户不知道怎么设置
- 需要用户理解token是什么
- 容易设置不合理值(比如对简单问题设了10000 token上限)
**自适应:根据任务复杂度自动调整**
系统自动分析问题复杂度,分配合适的预算。
优点:
- 对用户透明,零配置
- 理论上最优
缺点:
- 实现复杂
- 判断复杂度本身就需要计算成本
- 可能误判
**我的建议**:对于大多数产品,从粗粒度的三档开始。这是Claude Code、OpenAI都验证过的模式。只有当你有明确的用户需求时,才考虑更细粒度的控制。
### 3.2 控制介入点
思考预算可以在四个不同层面介入:
**Prompt层:通过指令控制**
在system prompt或user prompt中告诉模型"请快速回答"或"请深入思考"。
实现最简单,但控制力最弱。模型可能不听话,或者理解有偏差。
**Decoder层:干预生成过程**
在模型生成token的过程中介入,比如Budget Forcing强制插入结束标记。
控制力中等,实现复杂度中等。需要访问生成过程的中间状态。
**架构层:修改模型结构**
像TIDE那样,在模型内部添加Router等结构。
控制力最强,但实现复杂度最高。可能需要重新训练模型。
**后处理层:评估后选择**
生成多个不同预算的答案,然后用另一个模型或启发式规则选择最好的。
灵活性高,但计算成本翻倍(因为生成了多个答案)。
**选择建议**:
- 快速原型:Prompt层
- 生产系统:Decoder层
- 深度优化:架构层
- 高价值场景:后处理层
### 3.3 质量-效率权衡
这是思考预算系统的核心张力。
**如何定义"足够好"?**
这取决于你的应用场景:
- **代码补全**:只要语法正确、类型匹配,就是"足够好"
- **数学题**:答案必须正确,过程可以简略
- **创意写作**:没有客观标准,"足够好"取决于用户主观感受
- **医疗诊断**:宁可过度思考,也不能漏掉关键信息
一个实用的方法是定义 **质量下限** ——思考预算可以省,但不能省到答案不可用。
**用户可接受的质量下降范围**
假设Max级别准确率是95%,Low级别是85%。用户能接受10个百分点的下降吗?
这取决于两个因素:
1. **问题的重要性**:问天气vs问病情
2. **替代方案的成本**:如果不用AI,用户自己解决要花多少时间和精力
**成本节省与用户体验的平衡**
一个常见误区是只看"省了多少钱",不看"损害了多大用户体验"。
如果Low级别省了90%的成本,但用户满意度下降了50%,这可能不是一笔划算的买卖。
建议的做法是:**先做A/B测试,数据说话**。不同用户群体、不同使用场景的最优平衡点可能完全不同。
### 3.4 透明度与可观测性
**用户是否知道思考预算的使用情况?**
Claude Code的做法是:用户选择了Level,但不知道具体消耗了多少token。
另一种做法是:显示"本次思考消耗了3241个token"。
各有优劣:
- 不显示:简单,不增加认知负担
- 显示:透明,帮助用户理解"钱花在哪儿了"
**是否显示思考过程?**
DeepSeek-R1把思考过程完全展示给用户看。OpenAI的o系列则不展示。
展示的好处:
- 用户可以看到AI"在想什么"
- 有助于建立信任
- 对于教育场景特别有价值
不展示的好处:
- 保护商业机密(思考过程可能暴露模型能力边界)
- 减少用户认知负担
- 可以收费(如果用户看不到,更容易接受为思考过程付费)
**计费方式是否透明?**
这是最容易引发用户不满的地方。
如果计费不透明(比如"按输出token计费"但思考token也算在内),用户可能会感到被欺骗。
建议的做法是:明确告知思考token的计费规则,甚至提供不同级别的预估价格("Low级别约$0.01,Max级别约$0.15")。
---
## 第四章:从零实现思考预算
好了,理论聊够了。让我们动手实现一个简单的思考预算系统。
### 4.1 系统设计
我们要实现一个支持Low/Medium/High三个级别的思考预算控制器。采用Budget Forcing作为底层机制,因为它最容易实现。
**核心组件**:
1. **BudgetController**:管理预算分配和监控
2. **TokenTracker**:追踪已使用的token数
3. **ForceExitStrategy**:强制退出策略
4. **PromptAdapter**:根据级别调整prompt
### 4.2 代码实现
```python
from enum import Enum
from dataclasses import dataclass
from typing import Optional, Callable
import re
class ThinkingLevel(Enum):
"""思考预算级别"""
LOW = "low"
MEDIUM = "medium"
HIGH = "high"
@dataclass
class BudgetConfig:
"""预算配置"""
level: ThinkingLevel
max_tokens: int
min_tokens: int
force_exit_trigger: str = "</thinking>"
wait_prompt: str = "Wait, let me think more carefully."
@classmethod
def from_level(cls, level: ThinkingLevel) -> "BudgetConfig":
"""根据级别创建默认配置"""
configs = {
ThinkingLevel.LOW: cls(
level=level,
max_tokens=1024,
min_tokens=0,
),
ThinkingLevel.MEDIUM: cls(
level=level,
max_tokens=4096,
min_tokens=512,
),
ThinkingLevel.HIGH: cls(
level=level,
max_tokens=16384,
min_tokens=2048,
),
}
return configs[level]
class TokenTracker:
"""Token使用追踪器"""
def __init__(self):
self.used_tokens = 0
self.thinking_tokens = 0
def count_tokens(self, text: str) -> int:
"""简单估算token数(实际应该用tokenizer)"""
# 粗略估算:英文约1token/字符,中文约2token/字符
return len(text)
def record(self, text: str, is_thinking: bool = False):
"""记录token使用"""
count = self.count_tokens(text)
self.used_tokens += count
if is_thinking:
self.thinking_tokens += count
def get_stats(self) -> dict:
"""获取使用统计"""
return {
"total_tokens": self.used_tokens,
"thinking_tokens": self.thinking_tokens,
"output_tokens": self.used_tokens - self.thinking_tokens,
}
class BudgetController:
"""思考预算控制器"""
def __init__(self, config: BudgetConfig):
self.config = config
self.tracker = TokenTracker()
self.thinking_content = []
self._exited_early = False
def should_force_exit(self) -> bool:
"""检查是否应该强制退出思考"""
return self.tracker.thinking_tokens >= self.config.max_tokens
def should_force_continue(self) -> bool:
"""检查是否应该强制继续思考"""
return self.tracker.thinking_tokens < self.config.min_tokens
def process_thinking_token(self, token: str) -> Optional[str]:
"""
处理一个思考token,返回处理后的token或None
返回值:
- token本身:正常输出
- None:丢弃这个token(需要强制继续)
- force_exit_trigger:强制退出
"""
self.tracker.record(token, is_thinking=True)
# 检查是否触发强制退出
if self.should_force_exit():
self._exited_early = True
return self.config.force_exit_trigger
# 检查是否试图提前退出(需要强制继续)
if token.strip() == self.config.force_exit_trigger.strip():
if self.should_force_continue():
# 丢弃退出标记,添加继续提示
return f"\n{self.config.wait_prompt}\n"
return token
def get_thinking_summary(self) -> str:
"""获取思考过程摘要"""
stats = self.tracker.get_stats()
content = "".join(self.thinking_content)
# 如果内容太长,截断显示
if len(content) > 500:
content = content[:250] + "..." + content[-250:]
return f"""
[思考统计]
级别: {self.config.level.value}
思考token: {stats['thinking_tokens']} / {self.config.max_tokens}
是否提前退出: {self._exited_early}
[思考过程预览]
{content}
"""
class PromptAdapter:
"""Prompt适配器"""
LEVEL_INSTRUCTIONS = {
ThinkingLevel.LOW: """
请快速回答以下问题。不需要详细推理,直接给出最可能的答案。
使用你的训练知识,不要进行多步思考。
在<answer>标签中输出最终答案。
""",
ThinkingLevel.MEDIUM: """
请仔细思考以下问题。展示你的推理过程,但保持简洁高效。
如果问题简单,直接回答;如果问题复杂,展示关键步骤。
在<thinking>标签中输出思考过程,在<answer>标签中输出最终答案。
""",
ThinkingLevel.HIGH: """
请深入分析以下问题。展示完整的推理过程,考虑多种可能性,验证你的结论。
对于复杂问题,请:
1. 分解问题
2. 探索不同角度
3. 验证关键步骤
4. 总结最终答案
在<thinking>标签中输出详细思考过程,在<answer>标签中输出最终答案。
""",
}
@classmethod
def adapt(cls, user_prompt: str, level: ThinkingLevel) -> str:
"""根据级别调整prompt"""
instruction = cls.LEVEL_INSTRUCTIONS[level]
return f"{instruction}\n\n用户问题:{user_prompt}"
# 使用示例
class ThinkingBudgetExample:
"""思考预算系统使用示例"""
@staticmethod
def demonstrate():
"""演示不同级别的行为差异"""
test_question = "证明:对于任意正整数n,1+2+...+n = n(n+1)/2"
print("=" * 60)
print("思考预算系统演示")
print("=" * 60)
for level in ThinkingLevel:
print(f"\n【{level.value.upper()}级别】")
print("-" * 40)
# 创建配置
config = BudgetConfig.from_level(level)
controller = BudgetController(config)
# 调整prompt
adapted_prompt = PromptAdapter.adapt(test_question, level)
print(f"Prompt长度: {len(adapted_prompt)}字符")
print(f"预算限制: {config.min_tokens}-{config.max_tokens}tokens")
# 这里应该调用实际的大模型API
# 为了演示,我们模拟思考过程
simulated_thinking = ThinkingBudgetExample._simulate_thinking(
test_question, level, controller
)
# 显示统计
stats = controller.tracker.get_stats()
print(f"实际思考token: {stats['thinking_tokens']}")
print(f"是否提前退出: {controller._exited_early}")
print("\n" + "=" * 60)
@staticmethod
def _simulate_thinking(
question: str,
level: ThinkingLevel,
controller: BudgetController
) -> str:
"""
模拟思考过程(实际实现中会调用大模型API)
这里展示如何集成BudgetController到实际的生成流程中
"""
thinking_parts = []
# 模拟生成token
if level == ThinkingLevel.LOW:
# 简单问题,很少token
tokens = ["This", " is", " a", " simple", " formula", ".", "</thinking>"]
elif level == ThinkingLevel.MEDIUM:
# 中等复杂度
tokens = ["Let", " me", " prove", " this", " by", " induction", ".",
" Base", " case", ":", " n", "=", "1", "...", "</thinking>"]
else:
# 高复杂度,生成很多token
tokens = ["I", " need", " to", " prove", " this", " carefully", ".",
" First", ",", " let", " me", " understand", " the", " problem", ".",
" This", " is", " the", " sum", " of", " arithmetic", " sequence", ".",
" I", " can", " use", " induction", " or", " direct", " proof", ".",
" Let", " me", " try", " both", " approaches", "..."] * 50
tokens.append("</thinking>")
for token in tokens:
result = controller.process_thinking_token(token)
if result == controller.config.force_exit_trigger:
# 强制退出
thinking_parts.append("[FORCED EXIT]")
break
elif result:
thinking_parts.append(result)
return "".join(thinking_parts)
# 运行演示
if __name__ == "__main__":
ThinkingBudgetExample.demonstrate()
```
### 4.3 进阶:集成DEER动态早退
如果你想让系统更智能,可以集成DEER的思路:
```python
import re
class DEEREnhancer:
"""DEER动态早退增强器"""
# 转换点关键词
TRANSITION_SIGNALS = [
"wait", "alternatively", "let me reconsider",
"on second thought", "actually", "but",
"等等", "另一种", "让我重新", "但是"
]
def __init__(self, confidence_threshold: float = 0.8):
self.confidence_threshold = confidence_threshold
self.recent_tokens = []
self.transition_count = 0
def detect_transition(self, token: str) -> bool:
"""检测是否出现转换信号"""
self.recent_tokens.append(token.lower())
if len(self.recent_tokens) > 10:
self.recent_tokens.pop(0)
recent_text = " ".join(self.recent_tokens)
for signal in self.TRANSITION_SIGNALS:
if signal in recent_text:
self.transition_count += 1
return True
return False
def estimate_confidence(self, thinking_so_far: str) -> float:
"""
基于启发式规则估计置信度
实际实现中可以用一个小的分类模型
"""
confidence = 0.5
# 如果有明确的结论标记,置信度提高
if "therefore" in thinking_so_far.lower() or "所以" in thinking_so_far:
confidence += 0.2
# 如果思考过程很长,可能更深入
word_count = len(thinking_so_far.split())
if word_count > 100:
confidence += 0.1
# 如果经过多次转换,可能还在犹豫
if self.transition_count > 3:
confidence -= 0.1
return min(max(confidence, 0), 1)
def should_early_exit(self, thinking_so_far: str) -> bool:
"""判断是否应该早退"""
# 检测到转换点时,评估是否可以退出
if self.detect_transition(thinking_so_far[-100:]):
confidence = self.estimate_confidence(thinking_so_far)
return confidence >= self.confidence_threshold
return False
# 集成到BudgetController
class AdvancedBudgetController(BudgetController):
"""增强版预算控制器,集成DEER"""
def __init__(self, config: BudgetConfig, use_deer: bool = True):
super().__init__(config)
self.deer = DEEREnhancer() if use_deer else None
self.thinking_buffer = []
def process_thinking_token(self, token: str) -> Optional[str]:
"""处理token,集成DEER早退逻辑"""
self.thinking_buffer.append(token)
# 先调用父类的Budget Forcing逻辑
result = super().process_thinking_token(token)
# 如果父类要求强制退出,直接返回
if result == self.config.force_exit_trigger:
return result
# DEER早退检查
if self.deer and len(self.thinking_buffer) > 50:
thinking_so_far = "".join(self.thinking_buffer)
if self.deer.should_early_exit(thinking_so_far):
self._exited_early = True
self._exit_reason = "DEER_early_exit"
return self.config.force_exit_trigger
return result
```
### 4.4 生产环境注意事项
如果你要把这个系统部署到生产环境,需要考虑:
**错误处理**:
- 模型可能不遵循prompt指令
- Token计数可能有偏差
- 网络延迟可能导致监控不准确
**性能优化**:
- Token计数用近似算法,不要每次都调tokenizer
- 缓存相似问题的预算配置
- 异步处理统计信息
**监控告警**:
- 监控实际token使用vs预算的偏差
- 设置异常告警(比如连续大量提前退出)
- 收集用户反馈,校准预算配置
---
## 第五章:产品化的考量
技术实现只是第一步。把一个思考预算系统变成用户愿意付费的产品,需要考虑更多因素。
### 5.1 API设计
**RESTful API示例**:
```python
# 请求示例
POST /v1/chat/completions
{
"model": "deepseek-reasoner",
"messages": [
{"role": "user", "content": "证明费马小定理"}
],
"thinking_budget": {
"level": "medium", # low/medium/high/auto
"max_tokens": null, # 可以覆盖级别的默认值
"min_tokens": null
},
"stream": true
}
# 响应示例
{
"id": "chatcmpl-xxx",
"object": "chat.completion",
"created": 1234567890,
"model": "deepseek-reasoner",
"choices": [{
"index": 0,
"message": {
"role": "assistant",
"content": "费马小定理的证明如下..."
},
"thinking": {
"content": "让我来证明费马小定理...", # 可选,取决于配置
"tokens_used": 2048,
"tokens_limit": 4096,
"level": "medium",
"exited_early": false
}
}],
"usage": {
"prompt_tokens": 50,
"completion_tokens": 150,
"thinking_tokens": 2048,
"total_tokens": 2248
}
}
```
**关键设计决策**:
1. **是否暴露思考内容?**
- 暴露:增加透明度,但可能泄露模型能力边界
- 不暴露:更简洁,但用户不知道"钱花在哪儿了"
2. **流式输出如何处理思考过程?**
- 选项A:先输出思考过程,再输出答案(DeepSeek模式)
- 选项B:思考过程不输出,只输出答案(OpenAI模式)
- 选项C:思考过程和答案交错输出(创新模式,但复杂)
3. **预算超限时如何处理?**
- 硬截断:直接停止,返回不完整答案
- 软提示:给出提示"思考预算已用尽,这是最佳答案"
- 自动升级:询问用户是否增加预算继续思考
### 5.2 计费模型
**方案一:按思考Token计费**
```
总费用 = prompt_token费用 + (thinking_token + output_token) × 输出费率
```
优点:
- 简单透明
- 与现有计费体系兼容
缺点:
- 用户难以预估成本
- 思考token可能比输出token多10倍,账单可能惊吓用户
**方案二:按级别统一定价**
| 级别 | 每千次请求价格 | 预估思考token |
|------|----------------|---------------|
| Low | $0.50 | 0-1K |
| Medium | $2.00 | 1K-4K |
| High | $10.00 | 4K-16K |
优点:
- 用户容易理解
- 成本可预测
缺点:
- 内部需要吸收波动成本
- 可能被滥用(用户用Low级别问复杂问题)
**方案三:混合计费**
基础费用按级别收取,超出预估的思考token按实际消耗加收。
```
总费用 = 基础费用 + max(0, 实际思考token - 预估上限) × 超额费率
```
优点:
- 既有可预测性,又反映真实成本
- 鼓励用户合理选择级别
**我的建议**:
对于ToB产品,用方案二(按级别统一定价),企业客户更看重可预测性。
对于ToC产品,用方案一(按实际token),个人用户更接受"用多少付多少"。
### 5.3 用户体验
**UI设计原则**:
1. **默认值要合理**:大多数用户不会改设置,Medium应该是"大多数任务都够用"的级别
2. **反馈要及时**:如果思考时间超过预期,显示"正在深入思考中..."安抚用户
3. **控制要便捷**:在对话界面提供快捷切换(比如三个点表示Low/Medium/High,点击展开)
**一个参考设计**:
```
┌─────────────────────────────────────┐
│ [DeepThink: Medium ▼] 正在思考... │
├─────────────────────────────────────┤
│ ▶ 思考过程 (2048 tokens) │
│ 让我来证明这个定理... │
│ 首先,我需要理解什么是费马小定理 │
│ ... │
├─────────────────────────────────────┤
│ 费马小定理的证明如下: │
│ ... │
└─────────────────────────────────────┘
```
### 5.4 监控与告警
**关键指标**:
| 指标 | 说明 | 告警阈值 |
|------|------|----------|
| 思考token/输出token比率 | 衡量思考效率 | >20:1时告警 |
| 提前退出率 | 衡量预算设置是否合理 | >30%时告警 |
| 级别选择准确率 | 用户选择的级别是否合适 | 通过后续反馈评估 |
| 用户满意度 | 不同级别的满意度差异 | 某级别显著低于其他时告警 |
**日志记录**:
```json
{
"request_id": "req_xxx",
"timestamp": "2025-01-15T10:30:00Z",
"user_id": "user_xxx",
"question_category": "math_proof",
"thinking_budget": {
"level": "medium",
"requested_max": 4096,
"actual_used": 3245,
"exited_early": false
},
"quality_score": 0.92,
"user_rating": 5,
"latency_ms": 4567
}
```
---
## 结论:该省省,该花花
让我们回到文章开头的餐厅比喻。
思考预算的本质,不是让AI变成一个"抠门"的管家——对每个问题都斤斤计较、能省则省。而是让它成为一个"有品味"的主厨——知道什么时候可以快餐式出餐,什么时候需要慢火细炖。
**该省的时候**:
- 用户问"今天是星期几"——直接回答,不要思考人生
- 代码自动补全——毫秒级响应,不要深思熟虑
- 闲聊对话——自然流畅比逻辑严密更重要
**该花的时候**:
- 系统架构设计——多想想边界情况,省得以后重构
- 数学证明——每一步都要严谨,不能跳步
- 医疗诊断——宁可过度谨慎,不能漏诊误诊
**思考预算的艺术,是智能资源分配的艺术。**
它不是关于"如何少花钱",而是关于"如何把有限的钱花在刀刃上"。就像费曼会说的:
> "搞清楚什么是重要的,然后把精力放在那上面。其他的?能省则省。"
---
## 附录:参考资源
**学术论文**:
- s1: Simple test-time scaling. Stanford University, 2025.
- DEER: Dynamic Early Exit in Reasoning. arXiv:2504.xxxxx
- CaR: Confidence-Aware Reasoning. arXiv:2504.xxxxx
- TIDE: Token-Importance-Driven Early Exit. arXiv:2504.xxxxx
**产品文档**:
- Claude Code Documentation: https://docs.anthropic.com/
- OpenAI API Reference: https://platform.openai.com/docs/
- DeepSeek-R1 Technical Report
**开源项目**:
- GPT-OSS: OpenAI's open source reasoning models
- Qwen2.5: Alibaba's open weight models
- DeepSeek-R1: Open source reasoning model
---
*本文以费曼视角撰写——从具体例子出发,用生活化比喻解释技术概念,承认边界和不确定性。*
*"如果你读完了这篇文章,能向一个不懂技术的朋友解释清楚什么是思考预算,那我们就成功了。"*
---
**标签**: #ThinkingBudget #TestTimeCompute #推理优化 #AI效率 #小凯
登录后可参与表态
讨论回复
0 条回复还没有人回复,快来发表你的看法吧!