配置分层与模型/成本
昨天(Day 16)讲了记忆分层;今天讲另一套分层——settings.json 五层怎么合并、/model 怎么选、请求怎么到 Anthropic、退出时那句"花了多少钱"怎么算的。你会发现全项目的分层哲学是同一套。贴真实枚举和定价表。
settings 五层优先级(真实枚举)
Claude Code 的配置来自五个来源,后者覆盖前者。真实代码(src/utils/settings/constants.ts:7):
export const SETTING_SOURCES = [
'userSettings', // 用户全局:~/.claude/settings.json
'projectSettings', // 项目共享:.claude/settings.json(进 git)
'localSettings', // 本机项目:.claude/settings.local.json(gitignore)
'flagSettings', // 命令行 --settings 旗标传的
'policySettings', // 企业策略:managed-settings.json 或远程 API(最高)
] as const
深合并与 policy 的特殊规则
合并逻辑(src/utils/settings/settings.ts:657):先以插件 settings 作最低基座,再用 lodash mergeWith 按启用顺序深合并。但 policySettings(企业策略)走不同规则——"first-source-wins"(首个来源胜出):remote → MDM(Windows 注册表/macOS plist)→ managed-settings.json,按此顺序取第一个有值的。
请求怎么抵达 Anthropic
Day 03/06 讲了循环怎么调 callModel。真正发 HTTP 到 Anthropic 的是 src/services/api/claude.ts:
- 客户端工厂
getAnthropicClient(client.ts:84):构造new Anthropic({ apiKey })。 - 发流式请求:
anthropic.beta.messages.create({ ...params, stream: true })(claude.ts:1917)。 - 中枢生成器
queryModel(:1048)处理流式响应(Day 03 讲过的 switch)。
@anthropic-ai/sdk。它不重造 HTTP 层,直接用官方 SDK 发请求、拿流式响应,自己重写的是上面的一切(循环、工具、UI)。这很务实:底层协议对接用官方 SDK(稳定),业务逻辑自己实现(可控)。beta.messages 用 beta 端点是为了拿较新的能力(prompt caching 等)。/model 与默认模型
/model 命令(type:'local-jsx',Day 11)弹一个模型选择面板。模型选择优先级(src/utils/model/model.ts:111 的 getMainLoopModel):
- 用户明确指定的(
ANTHROPIC_MODEL环境变量 或settings.model)。 - 否则按订阅档位给默认(
:260):Max/Team Premium → Opus,PAYG/Pro/Enterprise → Sonnet。
/model 改。选完通过 onDone 把"已切换"消息插回对话(Day 11 讲的 local-jsx onDone)。主模型 vs 小快模型
Claude Code 其实同时用两个模型:
| 模型 | 用途 | 怎么取 |
|---|---|---|
| 主模型(Opus/Sonnet) | 主循环,干真活 | getMainLoopModel |
| 小快模型(Haiku) | 摘要、侧查询等杂活 | getSmallFastModel(model.ts:42) |
小快模型的调用入口 queryHaiku(claude.ts:3396,thinking: disabled)。Day 10 的 autocompact 摘要、各种后台判断都用它。
成本怎么算(真实定价表)
退出时那句"本次花了 $0.xx"是这么来的。真实的定价档位常量(src/utils/modelCost.ts:36):
export const COST_TIER_3_15 = { ... } // Sonnet:输入 $3 / 输出 $15(每百万 token)
export const COST_TIER_15_75 = { ... } // Opus 4/4.1:$15 / $75
export const COST_TIER_5_25 = { ... } // Opus 4.5:$5 / $25
export const COST_TIER_30_150= { ... } // fast mode:$30 / $150
// MODEL_COSTS:每个模型 → 对应档位(含 cache 读写单价)
export const MODEL_COSTS = { 'claude-sonnet-...': { COST_TIER_3_15, ... }, ... }
实时计费发生在流式增量处(claude.ts:2357):calculateUSDCost(model, usage) → addToTotalSessionCost。退出打印 hook useCostSummary(src/costHook.ts:6)在 process.on('exit') 打印 + 保存。
$0.072,累加进 session 总额。退出时打印"本次花了 $0.07"。--continue 恢复(Day 16),跨会话累计。每百万 token 计价:$3/百万 意思是每处理 100 万个输入 token 收 3 美元。多 Provider(本 fork 扩展)
官方 Claude Code 只走 Anthropic(含官方 Bedrock/Vertex)。本 fork 扩展了一大堆供应商——作为"扩展"了解即可:
client.ts里有 Bedrock / Azure Foundry / Vertex 分支。- 独立的非 Anthropic 供应商目录
src/services/api/{openai,gemini,grok}/。 - OpenAI 兼容多供应商注册表
src/services/providerRegistry/(/provider use,支持 cerebras/groq/deepseek)。 - 甚至有 ChatGPT/Codex 模式(
chatgptModels.ts)。
feature('...') 门控、包名 @claude-code-best/*、成片 stub。多 Provider 就属于这类扩展。核心的 Anthropic 调用、/model、成本追踪是官方真实机制。今日小结 + 动手
🧠 今天你应该能回答
- settings 五层优先级 + 为什么后者覆盖前者?
- policy 为什么用"首个胜出"而非深合并?
- 请求怎么到 Anthropic?为什么用官方 SDK?
- /model 优先级 + 为什么按订阅档位定默认?
- 主模型 vs 小快模型的分工(省钱纪律)?
- 成本怎么算?缓存 token 为什么单独计价?
✋ 动手:对着真实代码读一遍
# 1. settings 五层枚举(L01)
sed -n '7,22p' src/utils/settings/constants.ts
# 2. 请求发送与客户端(L03)
grep -n "beta.messages.create\|getAnthropicClient" src/services/api/*.ts | head
# 3. 模型选择(L04)
sed -n '111,130p' src/utils/model/model.ts
# 4. 成本定价表(L06)
sed -n '36,120p' src/utils/modelCost.ts
# 5. 实操:/model 换模型,退出看成本
bun run dev # 里面输入 /model,退出看花费