模型系统
Claude Code 如何跨四个提供商、五个选择层和两个扩展上下文层解析、配置和迁移 AI 模型。
模型系统分为两个目录。 下面的每条路径都在 src/.
| File | Responsibility |
|---|---|
| utils/model/configs.ts | 提供商特定的型号 ID 字符串; 所有已知型号的单一注册表 |
| utils/model/providers.ts | 检测活跃的 API 提供商(firstParty / bedrock / vertex / Foundry) |
| utils/model/model.ts | 选择优先级链、别名解析、每个订阅层的默认值 |
| utils/model/aliases.ts | 规范别名列表:sonnet、opus、haiku、best、opusplan、[1m] 变体 |
| utils/model/modelStrings.ts | 运行时模型字符串解析; 基岩推理-剖面发现 |
| utils/model/modelAllowlist.ts | availableModels 实施 — 三层匹配逻辑 |
| utils/model/modelOptions.ts | 每个订阅层的构建/模型选择器选项 |
| utils/model/agent.ts | 子代理模型解析、基岩区域前缀继承 |
| utils/model/check1mAccess.ts | 订阅者额外使用计费背后的 Gate 1M 上下文 |
| utils/model/deprecation.ts | 每个提供商的退休日期警告 |
| utils/model/validateModel.ts | 通过最少的 API 探针调用进行实时模型验证 |
| utils/model/modelSupportOverrides.ts | 3P env-var 覆盖努力/思考能力标志 |
| utils/model/modelCapabilities.ts | 仅 Ant:从 API 获取/缓存模型功能元数据 |
| utils/model/antModels.ts | Ant-only:来自 Statsig 功能标志的代号模型 |
| utils/model/bedrock.ts | AWS Bedrock 推理配置文件列表和区域前缀实用程序 |
| utils/effort.ts | 工作量级别、API 映射、持久性规则 |
| utils/fastMode.ts | 快速模式切换、冷却时间、可用性检查 |
| commands/model/ | /model 斜线命令 + ModelPicker UI |
| commands/effort/ | /effort 斜杠命令 |
| commands/fast/ | /快斜杠命令 |
| migrations/migrate*.ts | 启动时自动升级设置 |
系统可以引用的每个模型都在单个对象中声明 configs.ts。 每个条目都是一个 ModelConfig — 由提供者键入的记录 — 因此,无论 Bedrock 或 Vertex 如何命名,相同的逻辑模型都具有一个规范条目。
// utils/model/configs.ts
export type ModelConfig = Record<APIProvider, ModelName>
export const CLAUDE_OPUS_4_6_CONFIG = {
firstParty: 'claude-opus-4-6',
bedrock: 'us.anthropic.claude-opus-4-6-v1',
vertex: 'claude-opus-4-6',
foundry: 'claude-opus-4-6',
} as const satisfies ModelConfig
// @[MODEL LAUNCH]: Register the new config here.
export const ALL_MODEL_CONFIGS = {
haiku35: CLAUDE_3_5_HAIKU_CONFIG,
haiku45: CLAUDE_HAIKU_4_5_CONFIG,
sonnet35: CLAUDE_3_5_V2_SONNET_CONFIG,
sonnet37: CLAUDE_3_7_SONNET_CONFIG,
sonnet40: CLAUDE_SONNET_4_CONFIG,
sonnet45: CLAUDE_SONNET_4_5_CONFIG,
sonnet46: CLAUDE_SONNET_4_6_CONFIG,
opus40: CLAUDE_OPUS_4_CONFIG,
opus41: CLAUDE_OPUS_4_1_CONFIG,
opus45: CLAUDE_OPUS_4_5_CONFIG,
opus46: CLAUDE_OPUS_4_6_CONFIG,
} as const satisfies Record<string, ModelConfig>
@[MODEL LAUNCH] 评论是一个搜索目标。 新模型发布时需要编辑的所有七个文件都标有相同的标签。 查找它会给出一个启动清单。
四大提供商
firstParty
默认。 清理模型 ID,例如 claude-opus-4-6.
bedrock
AWS跨区域推理配置文件; 启动时自动发现。
vertex
GCP。 格式: claude-opus-4-6 (无日期后缀)。
foundry
天蓝色。 部署ID是用户定义的; 营销名称查找已禁用。
// utils/model/providers.ts
export function getAPIProvider(): APIProvider {
return isEnvTruthy(process.env.CLAUDE_CODE_USE_BEDROCK)
? 'bedrock'
: isEnvTruthy(process.env.CLAUDE_CODE_USE_VERTEX)
? 'vertex'
: isEnvTruthy(process.env.CLAUDE_CODE_USE_FOUNDRY)
? 'foundry'
: 'firstParty'
}
如何在运行时解析基岩模型字符串
Bedrock 用户可能有自定义的跨区域推理配置文件(例如 eu.anthropic.claude-opus-4-6-v1)与硬编码字符串不同 configs.ts。 启动时 Claude Code 调用 getBedrockInferenceProfiles() — 其中列出了 SYSTEM_DEFINED 来自 AWS 的配置文件 — 然后匹配每个配置的 firstParty ID 作为子字符串,用于查找用户所在区域的正确配置文件。
此操作在后台异步发生,因此 REPL 不会被阻止。 当配置文件获取正在进行时,请求会回退到硬编码的 Bedrock ID。 获取的是 memoized — 每个进程生命周期一次调用。
async function getBedrockModelStrings(): Promise<ModelStrings> {
const profiles = await getBedrockInferenceProfiles()
const out = {} as ModelStrings
for (const key of MODEL_KEYS) {
const needle = ALL_MODEL_CONFIGS[key].firstParty
out[key] = findFirstMatch(profiles, needle) || fallback[key]
}
return out
}
此外,用户可以通过以下方式覆盖各个模型字符串 settings.json → modelOverrides。 这是由规范的第一方 ID(例如 "claude-opus-4-6": "arn:aws:bedrock:...")并且每次都分层在发现的字符串之上 getModelStrings() 被称为。
getMainLoopModel() in model.ts 是确定哪个模型运行对话的单一函数。 它按照严格的优先级顺序遍历五层:
-
会话期间的 /model 命令 在引导状态下存储为
mainLoopModelOverride。 最高优先级 — 覆盖会话其余部分的所有内容。 -
--model CLI 启动时标志 还设置
mainLoopModelOverride处于引导状态,但仅在会话开始之前。 -
ANTHROPIC_MODEL 环境变量 同步检查。 接受完整的模型 ID 和别名。
-
settings.json → 模型字段 设置者
/model并在各个会话中持续存在。 唯一的层迁移接触。 -
内置订阅默认 最大/团队高级 → Opus 4.6。 其他人 → Sonnet 4.6(3P 可能默认为 4.5)。
getUserSpecifiedModelSetting() 检查模型 settings.availableModels。 如果用户指定的模型不在允许列表中,则会默默地忽略它并使用默认值。
// utils/model/model.ts — simplified
export function getUserSpecifiedModelSetting(): ModelSetting | undefined {
const modelOverride = getMainLoopModelOverride() // layers 1+2
if (modelOverride !== undefined) return modelOverride
const settings = getSettings_DEPRECATED() || {}
const specifiedModel =
process.env.ANTHROPIC_MODEL || settings.model || undefined // layers 3+4
if (specifiedModel && !isModelAllowed(specifiedModel)) return undefined
return specifiedModel
}
opusplan 和运行时模式如何影响模型选择
某些模型值所携带的行为超出了简单模型 ID 的范围。 opusplan 是根据当前权限模式在 Sonnet 和 Opus 之间切换的别名:
export function getRuntimeMainLoopModel(params: {
permissionMode: PermissionMode
mainLoopModel: string
exceeds200kTokens?: boolean
}): ModelName {
if (getUserSpecifiedModelSetting() === 'opusplan'
&& permissionMode === 'plan'
&& !exceeds200kTokens) {
return getDefaultOpusModel() // upgrade to Opus in plan mode
}
if (getUserSpecifiedModelSetting() === 'haiku' && permissionMode === 'plan') {
return getDefaultSonnetModel() // upgrade haiku to sonnet for plan
}
return mainLoopModel
}
如果一个 haiku 别名处于活动状态并且用户进入计划模式,它会静默升级到 Sonnet。 这可以防止计划模式在动力不足的模型上运行。
用户永远不需要输入完整版本的模型 ID。 别名系统将短名称解析为当前提供者适当的模型字符串:
// utils/model/aliases.ts
export const MODEL_ALIASES = [
'sonnet', 'opus', 'haiku', 'best',
'sonnet[1m]', 'opus[1m]',
'opusplan',
] as const
The [1m] 后缀很特殊:它被接受 any 别名或模型 ID,并发出 100 万个令牌上下文窗口变体的信号。 parseUserSpecifiedModel() 在解析基本模型之前将其剥离,然后重新附加它,以便 API 接收正确的模型字符串:
export function parseUserSpecifiedModel(modelInput: ModelName | ModelAlias): ModelName {
const has1mTag = has1mContext(normalizedModel) // checks for [1m] suffix
const baseModel = has1mTag
? normalizedModel.replace(/\[1m]$/i, '').trim()
: normalizedModel
if (isModelAlias(baseModel)) {
switch (baseModel) {
case 'opus': return getDefaultOpusModel() + (has1mTag ? '[1m]' : '')
case 'sonnet': return getDefaultSonnetModel() + (has1mTag ? '[1m]' : '')
case 'haiku': return getDefaultHaikuModel() + (has1mTag ? '[1m]' : '')
// ...
}
}
return modelInputTrimmed // preserve original case for custom IDs
}
model: opus, resolveSkillModelOverride() 自动携带 [1m] 从父会话到技能调用的后缀 - 只要目标系列支持 1M 上下文。 一项技能 model: haiku 会故意删除 1M,因为俳句没有 1M 变体。
扩展上下文不是一个单独的模型; 它是现有模型上的运行时标志。 这 [1m] 后缀遍历整个管道,并且仅在 API 调用边界处被剥离 normalizeModelStringForAPI().
出入口
两个功能可访问 1M,Opus 和 Sonnet 各一个:
// utils/model/check1mAccess.ts
export function checkOpus1mAccess(): boolean {
if (is1mContextDisabled()) return false // CLAUDE_CODE_DISABLE_1M_CONTEXT env
if (isClaudeAISubscriber()) return isExtraUsageEnabled() // subscriber: extra-usage billing
return true // API/PAYG: always available
}
Opus 1M 合并
对于 Max 和 Team Premium 订阅者,只有一种 Opus 选项: opus[1m] ——他们总是能得到扩展的背景信息。 这种“合并”是由 isOpus1mMergeEnabled():
export function isOpus1mMergeEnabled(): boolean {
if (is1mContextDisabled() || isProSubscriber() || getAPIProvider() !== 'firstParty')
return false
if (isClaudeAISubscriber() && getSubscriptionType() === null)
return false // fail closed: unknown sub type → no 1M (avoids API rate-limit error)
return true
}
getSubscriptionType() === null 防护存在是因为 OAuth 令牌可以在没有 subscriptionType 场地。 如果没有这个保护,部分刷新的令牌将错误地暴露 opus[1m] 专业版用户的 API 层会拒绝它,并显示误导性的“已达到速率限制”错误。
每个订阅层的模型选择器选项
The /model 选择器根据登录者显示不同的选项列表:
| Tier | Default | 显示选项 |
|---|---|---|
| 最大/团队溢价 | 作品 4.6 (1M) | 作品、十四行诗、十四行诗 1M、俳句 |
| 专业/团队标准 | 十四行诗 4.6 | 十四行诗、十四行诗 1M、作品、作品 1M、俳句 |
| PAYG 1P(API 密钥) | 十四行诗 4.6 | 十四行诗、十四行诗 1M、作品 1M、俳句 |
| PAYG 3P(基岩/顶点) | 十四行诗 4.5 | 定制或十四行诗 4.6/4.5、Opus 4.1/4.6、俳句 |
“Ant”层(Anthropic 员工)获得一个完全不同的列表,该列表是根据 Statsig 功能标志构建的 - 请参阅 antModels.ts.
工作量是作为参数发送到 API 的思考预算提示。 它仅适用于支持它的型号 - 目前 claude-opus-4-6 and claude-sonnet-4-6.
决议顺序
// utils/effort.ts — resolveAppliedEffort()
// Priority: env > appState > model default
const envOverride = getEffortEnvOverride() // CLAUDE_CODE_EFFORT_LEVEL env var
if (envOverride === null) return undefined // null = explicit 'unset'
const resolved = envOverride ?? appStateEffortValue ?? getDefaultEffortForModel(model)
// API rejects 'max' on non-Opus-4.6 — auto-downgrade
if (resolved === 'max' && !modelSupportsMaxEffort(model)) return 'high'
return resolved
持久化规则
并非所有的努力值都可以保存到 settings.json。 这 toPersistableEffort() 函数强制执行这些约束:
low,medium,high——一直坚持max— 仅适用于 Anthropic 员工(USER_TYPE === 'ant'); 会话范围内的其他人- 数值(例如
42) — 从未持久化,仅模型默认
CLAUDE_CODE_EFFORT_LEVEL 设置并且用户运行 /effort high,CLI 将设置保存到磁盘,但警告它们:“CLAUDE_CODE_EFFORT_LEVEL=max 覆盖此会话 — 清除它并由 high 接管。” 环境变量总是在运行时获胜; 清除环境后,该设置将在下一个会话中生效。
快速模式是一项研究预览功能,可为以下内容提供较低延迟的执行路径: 仅 Opus 4.6 在第一方 API 上。 它是通过切换的 /fast 或设置,并且该命令将被隐藏,除非快速模式可用于会话。
// commands/fast/index.ts
const fast = {
type: 'local-jsx',
name: 'fast',
get description() { return `Toggle fast mode (${FAST_MODE_MODEL_DISPLAY} only)` },
availability: ['claude-ai', 'console'],
isEnabled: () => isFastModeEnabled(),
get isHidden() { return !isFastModeEnabled() },
}
可用性检查
快速模式在提供给用户之前会经过分层可用性检查:
CLAUDE_CODE_DISABLE_FAST_MODE=1全局硬禁用它- 仅适用于
firstParty提供商 — 不在 Bedrock/Vertex/Foundry 上 - 需要付费订阅; 免费帐户请参阅“快速模式需要付费订阅”
- 订户需要启用额外使用计费; 如果没有它,原因是“快速模式需要额外的使用计费”
- 不适用于代理 SDK(非交互式会话),除非
fastMode: true在标志设置中明确设置 - Statsig 功能标志
tengu_penguins_off可以使用自定义原因字符串远程杀死它
模型切换开关
如果当前模型不支持快速模式,则启用快速模式仅切换模型。 如果您已经使用 Opus 4.6,则模型保持不变:
// commands/fast/fast.tsx — applyFastMode()
if (enable) {
setAppState(prev => {
const needsSwitch = !isFastModeSupportedByModel(prev.mainLoopModel)
return {
...prev,
...(needsSwitch ? { mainLoopModel: getFastModeModel() } : {}),
fastMode: true,
}
})
}
clearFastModeCooldown().
企业和团队管理员可以通过设置限制用户可以选择的模型 availableModels 在策略设置文件中。 匹配逻辑分为三层,按顺序应用:
- 家庭通配符 —
"opus"允许任何 Opus 模型,除非该系列还存在更窄的条目 - 版本前缀 —
"opus-4-5"or"claude-opus-4-5"匹配段边界处该版本的任何构建 - 确切的ID —
"claude-opus-4-5-20251101"仅匹配该确切的字符串
// Example: restrict to Sonnet 4.6 and Haiku 4.5 only
// ~/.claude/settings.json (admin policy)
{
"availableModels": ["sonnet", "haiku"]
}
// Example: allow only Opus 4.5 (not 4.6)
{
"availableModels": ["opus-4-5"]
}
// Example: empty allowlist blocks ALL user-specified models
// (user gets the subscription default only)
{
"availableModels": []
}
"opus" and "opus-4-5" 出现在白名单中,家庭通配符 "opus" 被忽略。 系统检测到该 opus 系列存在更具体的条目,并且仅应用版本前缀匹配。 这可以防止管理员在打算限制一个版本的同时意外允许所有 Opus。
完整的白名单匹配实现
export function isModelAllowed(model: string): boolean {
const { availableModels } = settings
if (!availableModels) return true // no restriction
if (availableModels.length === 0) return false // empty blocks all
// 1. Direct match — but skip family aliases that are narrowed
if (allowlist.includes(model)) {
if (!isModelFamilyAlias(model) || !familyHasSpecificEntries(model, allowlist))
return true
}
// 2. Family wildcard (only if no specific entries for that family)
for (const entry of allowlist) {
if (isModelFamilyAlias(entry)
&& !familyHasSpecificEntries(entry, allowlist)
&& modelBelongsToFamily(model, entry)) return true
}
// 3. Version-prefix match at segment boundary
for (const entry of allowlist) {
if (!isModelFamilyAlias(entry) && !isModelAlias(entry)) {
if (modelMatchesVersionPrefix(model, entry)) return true
}
}
return false
}
当 Claude Code 生成子代理(通过任务工具或 SDK)时,子代理需要知道要使用哪个模型。 决议发生在 utils/model/agent.ts 并遵循以下优先顺序:
-
CLAUDE_CODE_SUBAGENT_MODEL 环境变量 所有子代理的全局覆盖。 在 CI 管道中很有用。
-
工具指定的模型(任务调用上的模型参数) 编排模型可以请求子代理的特定模型。
-
代理配置模型字段 在代理定义中设置。 接受任何别名或模型 ID。
-
“继承”(默认) 子代理使用与父线程相同的模型,包括 opusplan 解析。
别名匹配父层优化
当一个裸家庭别名(opus, sonnet, haiku) 匹配父模型的系列,子代理继承父模型的确切模型字符串,而不是将别名解析为提供程序默认值。 这可以防止固定 Opus 版本上的 Vertex 用户让子代理静默降级:
// utils/model/agent.ts
function aliasMatchesParentTier(alias: string, parentModel: string): boolean {
const canonical = getCanonicalName(parentModel)
switch (alias.toLowerCase()) {
case 'opus': return canonical.includes('opus')
case 'sonnet': return canonical.includes('sonnet')
case 'haiku': return canonical.includes('haiku')
default: return false
}
}
// Note: opus[1m], best, opusplan fall through — they have extra semantics
基岩地区前缀继承
在 Bedrock 上,跨区域推理配置文件带有区域前缀 (eu., us.)。 如果父模型使用 eu.anthropic.claude-opus-4-6-v1,使用别名模型的子代理也必须使用 eu. 前缀。 这是由 applyParentRegionPrefix() — 如果子代理的模型规范已经带有自己的显式前缀,则跳过该步骤。
当 Claude Code 升级其默认模型时,之前固定特定模型的用户需要自动迁移其设置。 迁移系统在每次启动时运行一组功能; 每个迁移都是幂等的(可以安全地重新运行)。
migrateFennecToOpus
仅限蚂蚁。 重新映射代号别名(fennec-latest, fennec-fast-latest, opus-4-5-fast)到他们的公共等价物(opus, opus[1m]和快速模式标志)。 只触及 userSettings — 项目/政策引脚保持不变。
migrateLegacyOpusToCurrent
仅限第一方。 重写显式 Opus 4.0/4.1 字符串(claude-opus-4-20250514, claude-opus-4-1-20250805)到 opus 别名。 套 legacyOpusMigrationTimestamp 在全局配置中,以便 REPL 可以显示一次性通知。 CLAUDE_CODE_DISABLE_LEGACY_MODEL_REMAP=1 跳过这个。
migrateSonnet1mToSonnet45
Pins sonnet[1m] 设置为显式 sonnet-4-5-20250929[1m] 细绳。 需要,因为 Sonnet 4.6 1M 提供给与 Sonnet 4.5 1M 不同的访问组 — sonnet 别名现在解析为 4.6。 追踪者 sonnet1m45MigrationComplete flag.
migrateSonnet45ToSonnet46
仅限 Pro/Max/Team Premium 第一方用户。 将显式 Sonnet 4.5 字符串升级回 sonnet 别名(现在解析为 4.6)。 套 sonnet45To46MigrationTimestamp 对于新版本通知 - 但跳过全新用户的通知(启动计数 ≤ 1)。
migrateOpusToOpus1m
对于启用 1M 合并的 Max/Team Premium:升级固定的 opus 设置为 opus[1m]。 如果升级会导致与订阅默认值相同的解析模型,则跳过(以避免存储冗余的显式设置)。
resetProToOpusDefault
没有自定义模型的第一方 Pro 订阅者会获得迁移时间戳 - 这使得 REPL 能够显示一次性“您已升级到 Opus 4.5 作为默认版本”标注。 已经拥有自定义模型设置的用户将被默认标记为完成。
userSettings,从不合并/项目/策略设置; (2) 使用完成标志或幂等写入逻辑,以便重新运行是安全的; (3) 记录分析事件,以便团队可以衡量迁移成功率。
实时模型验证
当用户在其中输入自定义模型 ID 时 /model,系统无法仅通过字符串匹配来知道它是否有效。 validateModel() 发送一个 真实的API调用 with max_tokens: 1 探测模型:
// utils/model/validateModel.ts
await sideQuery({
model: normalizedModel,
max_tokens: 1,
maxRetries: 0,
querySource: 'model_validation',
messages: [{ role: 'user', content: [{ type: 'text', text: 'Hi' }] }],
})
A NotFoundError (404) 表示该模型不存在。 对于 3P 用户,将返回后备建议(例如,如果您要求 opus-4-6 在 Vertex 上,但它还不可用,它表明 opus-4-1).
弃用警告
弃用表在 deprecation.ts 将模型子字符串映射到每个提供商的退休日期:
const DEPRECATED_MODELS: Record<string, DeprecationEntry> = {
'claude-3-7-sonnet': {
modelName: 'Claude 3.7 Sonnet',
retirementDates: {
firstParty: 'February 19, 2026',
bedrock: 'April 28, 2026',
vertex: 'May 11, 2026',
foundry: 'February 19, 2026',
},
},
// ...
}
如果活动模型与任何条目匹配并且具有当前提供程序的停用日期,则 UI 会显示黄色警告横幅。 Bedrock 和 Vertex 的退休窗口通常比第一方更长。
要点
- 一个注册中心,四个提供商。
ALL_MODEL_CONFIGSinconfigs.ts是每个模型 ID 的单一事实来源。 添加新模型需要更新该文件以及其他六个标记位置 - 全部标记为@[MODEL LAUNCH]. - 选择正好有五层。 /model 命令 → --model 标志 → ANTHROPIC_MODEL env → settings.json → 订阅默认值。 许可名单门在其中任何一个之前运行。
- [1m] 后缀不是单独的型号。 它是一个在 API 边界被剥离的运行时标志
normalizeModelStringForAPI()。 访问权限由订阅级别和额外使用计费控制。 - 努力和快速模式是正交旋钮。 努力控制思维预算(低/中/高/最大)。 快速模式是一种延迟优化,仅限 Opus 4.6 第一方。 两者都有 env-var 覆盖,可以胜过 UI 设置。
- 迁移仅涉及用户设置。 项目和策略设置有意保留,以避免默默地将项目范围的 pin 升级为全局默认值。
- 子代理默认为“继承”。 传递父级的确切模型字符串,包括 opusplan → Opus 分辨率。 基岩区域前缀也会被继承以避免 IAM 权限失败。
- 允许名单缩小规则并不明显。
["opus", "opus-4-5"]不允许所有 Opus — 特定条目将系列通配符缩小到仅 opus-4-5。 - 快速模式仅适用于第一方,并且需要对订阅者进行额外的使用计费。 检查是多层的:env 标志、Statsig 终止开关、提供商检查、订阅检查、计费检查。