“
Claude Code意外泄漏51.2万行TS核心代码
Think / Extended Thinking 机制详解
本文档说明本仓库中与 模型侧 Extended Thinking(API thinking 参数) 相关的配置、默认策略、与 Effort / UI / 消息管线 / 上下文管理的关系,并区分 Think Back 插件产品功能。核心类型与开关在 src/utils/thinking.ts,请求组装在 src/services/api/claude.ts 的 queryModel → paramsFromContext。
1. 概念:两套「Think」
| 含义 | 说明 |
|---|---|
| Extended Thinking | 调用 Anthropic Messages API 时在请求体中设置 thinking(adaptive 或 enabled + budget_tokens),模型在工具/回答前进行可计费或可摘要的推理;响应中带 thinking / redacted_thinking 内容块。 |
| Think Back(/think-back) | 独立插件与命令(src/commands/thinkback/、thinkback-play),生成年终回顾动画等,不是 API extended thinking 开关。 |
下文默认指 Extended Thinking,除非单独标注 Think Back。
2. 配置类型:ThinkingConfig
定义于 src/utils/thinking.ts:
export type ThinkingConfig =
| { type: 'adaptive' } // 逻辑含义:允许走 API 自适应思考(实际下发见 §4)
| { type: 'enabled'; budgetTokens: number } // 非自适应模型下的 token 预算提示
| { type: 'disabled' } // 完全关闭 thinking 请求
adaptive/enabled的 CLI 语义:src/main.tsx在用户传入--thinking adaptive|enabled时把thinkingConfig设为{ type: 'adaptive' };与MAX_THINKING_TOKENS、--max-thinking-tokens(若存在)等组合时,thinkingEnabled与thinkingConfig会同步更新。- 会话内关闭:
AppState.thinkingEnabled === false时,REPL构造的toolUseContext.options.thinkingConfig会强制为{ type: 'disabled' }(见src/screens/REPL.tsx中s.thinkingEnabled !== false ? thinkingConfig : { type: 'disabled' })。
3. 默认是否开启:shouldEnableThinkingByDefault()
src/utils/thinking.ts:
- 若设置环境变量
MAX_THINKING_TOKENS:解析为整数,> 0 视为默认开启 thinking。 - 否则读合并设置:若
alwaysThinkingEnabled === false(settings.json/ ConfigTool 等,src/utils/settings/types.ts),则默认 关闭。 - 否则默认 开启(注释要求变更需同步 model launch)。
QueryEngine.submitMessage(src/QueryEngine.ts)在未传入 thinkingConfig 时,用 shouldEnableThinkingByDefault() !== false 决定初始为 { type: 'adaptive' } 还是 { type: 'disabled' }。
4. API 层:何时发 thinking、adaptive 还是 budget
src/services/api/claude.ts 中 paramsFromContext(摘要逻辑):
hasThinking:thinkingConfig.type !== 'disabled'且 未 设置CLAUDE_CODE_DISABLE_THINKING。modelSupportsThinking(model)(src/utils/thinking.ts):按 provider(1P / Foundry / Bedrock / Vertex)与 canonical 模型名判断;3P 能力可被get3PModelCapabilityOverride(model, 'thinking')覆盖;内部注释警告勿随意改名单。- 若二者满足:
-
- 若 未
CLAUDE_CODE_DISABLE_ADAPTIVE_THINKING且modelSupportsAdaptiveThinking(model):请求使用{ type: 'adaptive' }(无 budget)。 - 否则:使用
{ type: 'enabled', budget_tokens },默认 budget 为getMaxThinkingTokensForModel(model)(src/utils/context.ts:upperLimit - 1,与 max output 对齐);若thinkingConfig.type === 'enabled'且提供了budgetTokens则采用用户值,并与maxOutputTokens - 1取 min。
- 若 未
- 温度:
hasThinking为真时不单独下发 temperature(API 在 thinking 开启时期望默认为 1)。
自适应支持modelSupportsAdaptiveThinking:对已知 opus-4-6 / sonnet-4-6 等显式允许;其它 legacy opus/sonnet/haiku 名返回 false;对 未知模型字符串 在 1P / Foundry 上默认 true(注释:避免悄悄降级新模型)。
5. Beta 头:交错思考、脱敏思考、与 UI
src/utils/betas.ts:
INTERLEAVED_THINKING_BETA_HEADER:未DISABLE_INTERLEAVED_THINKING且modelSupportsISP(model)时加入。REDACT_THINKING_BETA_HEADER(1P、交互会话):在满足仅 1P beta、modelSupportsISP、非 non-interactive、且showThinkingSummaries !== true时加入。效果是 API 返回redacted_thinking而非完整 thinking 文本摘要;TUI 用AssistantRedactedThinkingMessage显示 stub「✻ Thinking…」,完整内容用 Ctrl+O 展开的场景减少(见betas.ts注释)。
交互模式下完整 thinking 的展示:AssistantThinkingMessage(src/components/messages/AssistantThinkingMessage.tsx)——非 verbose / 非 transcript 时仅显示「∴ Thinking」+ 展开提示;verbose 或 transcript 模式下列出 Markdown 正文。
6. 上下文管理:clear_thinking_20251015
src/services/compact/apiMicrocompact.ts 中 getAPIContextManagement:
- 当
hasThinking且 未 处于 redact-thinking(!isRedactThinkingActive)时,加入策略clear_thinking_20251015: -
- 默认
keep: 'all'(保留历史 assistant turn 中的 thinking)。 - 若
clearAllThinking(见 §7)为 true:keep: { type: 'thinking_turns', value: 1 },只保留最后一轮 thinking,避免长间隔后缓存与 schema 默认行为不一致。
- 默认
7. 长时间空闲后的「清 thinking」锁存:thinkingClearLatched
src/services/api/claude.ts:
- 仅对 agentic 主路径(
isAgenticQuery)考虑:若距离上次 API 完成超过约 1 小时(CACHE_TTL_1HOUR_MS),将thinkingClearLatched置 true 并写入 bootstrap state(setThinkingClearLatched)。 - 该标志参与
getAPIContextManagement({ clearAllThinking: thinkingClearLatched }),从而触发 §6 中「只保留最后一轮 thinking」的策略。 - 设计意图:与 prompt cache / 长 idle 后的上下文策略对齐;且注释说明 classifier 等非 agentic 调用不应误触发锁存。
状态读写:src/bootstrap/state.ts(thinkingClearLatched)。
8. 与其它子系统的关系
8.1 Effort 与 Ultrathink
- Effort(
src/utils/effort.ts):独立 API 参数,决定「任务投入度」;与 thinking 并行存在,claude.ts中configureEffortParams与thinking同一次paramsFromContext内组装。 - Ultrathink(
src/utils/thinking.ts):feature('ULTRATHINK')+ GrowthBooktengu_turtle_carbon。开启且模型支持 effort 时,getDefaultEffortForModel等路径可把默认 effort 设为 medium,用户在输入里写ultrathink时由src/utils/attachments.ts的getUltrathinkEffortAttachment附加ultrathink_effort(levelhigh)并打tengu_ultrathink事件;PromptInput 用findThinkingTriggerPositions/getRainbowColor做关键词高亮。
8.2 子 Agent / Hook / 侧路查询
- Fork 子 Agent(
src/tools/AgentTool/runAgent.ts):默认继承父级toolUseContext.options.thinkingConfig;useExactTools等分支仍会传入同一 thinking 配置(见文件内注释)。 - 若干 hook 与辅助查询 显式
thinkingConfig: { type: 'disabled' },避免在分类器、prompt hook、agent hook、API query helper、skill improvement 等路径上浪费 thinking 配额或破坏缓存键预期(src/utils/hooks/*.ts)。 sideQuestion(src/utils/sideQuestion.ts):注释说明 不要覆盖thinkingConfig,因其参与 API cache key。
8.3 消息与持久化
src/utils/messages.ts:区分thinking/redacted_thinking; assistant 消息 不能以 thinking 块结尾(API 约束)时有 strip/merge 逻辑;另有去掉签名类 block 的路径供压缩/导出。- Token 估算(
src/services/tokenEstimation.ts):对 thinking 类 block 使用固定预算常数简化计数。
8.4 分类器(YOLO)
src/utils/permissions/yoloClassifier.ts:getClassifierThinkingConfig可按模型关闭 thinking 或增加 padding,避免分类用小请求触发 thinking。
8.5 Web 搜索子调用
src/tools/WebSearchTool/WebSearchTool.ts:使用 Haiku 时可对子查询关闭 thinking,否则跟随context.options.thinkingConfig。
9. UI:ThinkingToggle
src/components/ThinkingToggle.tsx:会话级开关文案为「Claude will think before responding」;若在 对话中途 修改,会先 二次确认(警告延迟与质量风险)。
10. 环境变量与设置速查
| 变量/设置 | 作用 |
|---|---|
CLAUDE_CODE_DISABLE_THINKING | 强制不向 API 发送 thinking(即使 ThinkingConfig 非 disabled)。 |
CLAUDE_CODE_DISABLE_ADAPTIVE_THINKING | 有 thinking 时退回 budget 模式而非 adaptive。 |
DISABLE_INTERLEAVED_THINKING | 不请求交错 thinking beta。 |
MAX_THINKING_TOKENS | 影响默认是否启用 thinking(shouldEnableThinkingByDefault)及 CLI/main 初始化分支。 |
alwaysThinkingEnabled(settings) | false 时默认关闭 thinking。 |
showThinkingSummaries | true 时可不走 redact-thinking beta,偏向可读的 thinking 摘要路径(见 betas.ts)。 |
ConfigTool 暴露项见 src/tools/ConfigTool/supportedSettings.ts(含 alwaysThinkingEnabled)。
11. Think Back(插件,非 Extended Thinking)
- 命令:
/think-back、thinkback-play等(src/commands/thinkback/、thinkback-play/)。 - 依赖 Statsig gate
tengu_thinkback;通过 Skill 工具调用thinkbackskill 生成动画资源。 - 与上文的 API
thinking参数 无直接关系;命名上易混淆,故单独列出。
12. 关键源文件索引
| 主题 | 路径 |
|---|---|
| 类型、模型能力、默认开关、Ultrathink feature 标志 | src/utils/thinking.ts |
请求体 thinking + context_management + 空闲锁存 | src/services/api/claude.ts |
clear_thinking_20251015 策略 | src/services/compact/apiMicrocompact.ts |
| Beta 头(interleaved / redact) | src/utils/betas.ts |
| Thinking token 上限辅助 | src/utils/context.ts(getMaxThinkingTokensForModel) |
主循环初始 thinkingConfig | src/QueryEngine.ts |
REPL 注入 toolUseContext.options.thinkingConfig | src/screens/REPL.tsx |
CLI 启动 --thinking / MAX_THINKING_TOKENS | src/main.tsx |
| 展示:完整 vs 脱敏 | AssistantThinkingMessage.tsx、AssistantRedactedThinkingMessage.tsx |
| Ultrathink 输入附件 | src/utils/attachments.ts |
| Effort 默认与 ultrathink 交互 | src/utils/effort.ts |
13. 与仓库内其它文档
若存在 SKILLS.md 、 ARCHITECTURE.md,Extended Thinking 属于 模型调用层 横切 concern;Skill 的 effort 与主循环 thinkingConfig 仍独立,需分别在 API 请求中理解。