第 13 章 第四部分:工程细节

Feature Flags 与灰度发布

50+ 个功能开关的分类与作用、构建时消除机制、GrowthBook 集成、内部/外部用户差异化策略

Claude Code Feature Flags 灰度发布 功能开关 Bun GrowthBook

13.1 Feature Flags 的角色

Claude Code 有 ~45+ 个编译时 Feature Flag + 25+ 个 GrowthBook 运行时门控,总计 70+ 个功能开关(v2.1.88 source map 泄漏快照;作为参照,官方公开 changelog 在本书修订时已至 v2.1.303 / 2026-10-18,中间相隔 181 个 release)。其中约 20 个对外部用户隐藏。

这些 Flag 不只是简单的”开/关”开关——它们深度嵌入了系统的各个层面,控制着 Claude Code 的能力边界。

这个数字之所以保留原值而不替换成”更新的猜测”,是因为新数字同样不可核验——换一个会腐烂的数字没有意义。真正有用的是快照锚点:读者看到 70+ 时知道它对应 v2.1.88,而非”当前版本”。

参照系已刷新,同时修正一处计数口径(2026-09-29 记,2026-10-19 再记:本节自己犯过同一个错)。锚点版本更新为 v2.1.303(2026-10-18,latest;同期 stable 为 v2.1.292)。release 间隔由 164 改为 181,即 npm registry 上 2.1.89 至 2.1.303 区间的实际发布数。

间隔由”约 180”改为 164(上一轮)的原因不是版本前进了 16 个,而是原来的 180 算错了:它是按版本号相减(268 − 88)得到的,而 Claude Code 的版本号并不连续。按实际发布记录数,v2.1.268 当时对应 149 个,v2.1.284 对应 164 个,v2.1.303 对应 181 个。

上一轮给出的空号清单是错的,本轮按 npm registry 逐号重核。 上一版写”该区间内 2.1.93、95、99、100、102–104、104(重复)、106、115、124、125、127、130、134、135、146、151、155、164、171、177、180、182、184、188、189、192、194、213、230 等号均无对应发布”。逐号核对 npm registry 的 versions 与 time 字段后:

  • 7 个号实际存在,且有 tarball 与发布日期:2.1.100(2026-04-10)、2.1.104(2026-04-12)、2.1.124(2026-04-30)、2.1.146(2026-05-20)、2.1.177(2026-06-13)、2.1.182(2026-06-18)、2.1.213(2026-07-17);
  • 9 个真实空号被漏列:244、249、253、254、255、256、262、264、279;
  • 同一区间还多出 2 个空号:297、298(2.1.285 之后)——这是本书记录的第六次”同族空号坑”。

npm 实测 2.1.89–2.1.284 区间的空号完整清单为:93、95、99、102、103、106、115、125、127、130、134、135、151、155、164、171、180、184、188、189、192、194、230、244、249、253、254、255、256、262、264、279,共 32 个。对账:区间共 196 个号,196 − 32 = 164,与上一版给出的总数自洽——164 这个数一直是对的,错的是用来支撑它的枚举。

含 2.1.285–2.1.303 的完整区间(215 个号)里,空号为上述 32 个加 297、298,共 34 个;215 − 34 = 181。

本书保留这条纠错痕迹,不悄悄改掉。 因为本节的方法论论点正是”版本号是给人读的标签,不是可运算的量”,并用”按版本号相减得出 180 是高估”来示范这个错误。结果支撑这个论点的枚举清单本身含有 7 个假条目——这是同一个错误落在本书自己身上的第二个实例,比悄悄改掉更有教学价值。

更值得记住的是这个错误本可以在不访问 npm 的情况下被发现:上一版列出 30 个空号,而区间共有 196 个号,196 − 30 = 166 ≠ 它自己给出的 164。总数与枚举互相矛盾本身就是错误的探针——凡清单类陈述,先把总数与枚举做一次加减,再去外部核对,往往更省力。

这处修正本身是本书 13.1 论点的又一个例证:版本号是给人读的标签,不是可运算的量。本章通篇在讲 Flag 会让”你以为的默认值”与”实际生效的路径”脱节,而一个用版本号相减得出的 release 数,是同一类错误落在本书自己身上。后面的 13.6.3 会看到,官方在 2026 年 9 月连着四个版本改 auto mode 分类器的默认位置——对这类东西,只有实际发布记录可信。

⚠️ 另一个流传的 Flag 数:91,以及为什么不能直接替换 45+(第三方来源,待验证)。第三方社区 wiki(claude-wiki.com《Feature Flags (Build-Time)》,页面实体日期戳 2026-04-10)称”代码库中通过 feature() 调用引用的独立 feature flag 约 91 个”,并逐条列出了 flag → 环境变量 → 门控内容。

91 与本章 45+ 的差距主要来自计数口径,而不是版本演进。该页统计的是所有 feature() 调用点(含带环境变量回退的、门控单个命令或单个 UI 元素的),本章 45+ 计的更接近”门控了完整子系统的”。两个数字回答的是不同问题,不应读作”官方又加了 46 个 flag”,也不应据此把 70+ 改写为任何新总数——这也正是本节开头那条原则(不换一个会腐烂的数字)要防的事。

该页另有两条对本章有用、且不依赖那个总数的观察:

  • ABLATION_BASELINE:描述为”harness-science ablation:设置环境变量以关闭 thinking、compaction、auto-memory、background tasks,外部构建中恒为 false”。这是一个反向开关——它的用途不是开新功能,而是为对照实验一次性关掉四项默认能力。把它和 13.2 的”两种 Flag 机制”放在一起,能补上一个本章没明说的 Flag 用途分类:Flag 不只是”发布通道”(渐进放量)与”能力边界”(谁能用什么),还是实验装置(在内部构建里系统性地做消融,以量化每个子系统到底贡献了多少)。而”外部构建中恒为 false”这一句同时说明,这类开关的存在本身对用户是不可见的——它只活在 Anthropic 内部的构建里。
  • 两层门控:该页称许多 flag 采用”构建时 feature() 做死代码消除 + 运行时 GrowthBook/Statsig 做灰度与 kill-switch”的两层结构。这与 13.2 的双机制划分互相独立地吻合,可作为该节结构判断的一个旁证(但仍是第三方转述)。

需要说明的是:以上均出自第三方社区 wiki,非 Anthropic 官方一手材料,页面日期戳(2026-04)与本章 v2.1.88 快照同期或更早。引用它只用于说明”口径差”与”Flag 还有实验用途”,不作为新的数值依据。

影响范围被控制的内容示例 Flag
System Prompt条件加载提示词模块PROACTIVE、KAIROS
代理加载哪些内置代理可用VERIFICATION_AGENT、COORDINATOR_MODE
工具可用性哪些工具被加载MONITOR_TOOL、内部专用工具
命令集哪些 Slash 命令可用部分命令根据 Flag 动态导入
权限行为Auto 模式分类器策略YOLO 分类器的行为调整
UI 功能界面元素显示/隐藏实验性 UI 组件
记忆模式记忆系统的运行模式TEAMMEM、KAIROS

13.1.1 读者可核验的官方开关

上表的 Flag 与 13.3 的清单都来自源码泄漏与社区逆向,读者无法在自己的 Claude Code 里验证——这是本章证据结构的一个弱点。下面这批开关不同:它们在官方 settings 文档中公开记录,读者可以立即写入 settings.json 看到效果。

一个先给的锚点:2026-10-19 官方 settings-reference 中 scope 为 Managed 的设置键共 44 项。下表是其中读者最容易亲手试的 11 项——也就是说,这张表不是”挑了 11 个例子”,而是从官方亲口承认的 44 个可远程配置项里挑出的 11 个。这个计数本身会继续增长,记快照日期比记数字重要。

设置项作用Scope
disableBundledSkills关闭 Claude Code 内置的 skills 与 workflowsAny file
disableSkillShellExecution禁止技能与自定义命令运行内联 shellAny file
skillOverrides不改 SKILL.md 即可隐藏或折叠某个技能Any file
pluginSuggestionMarketplaces限制 /plugin 能推荐哪些市场Managed
extraKnownMarketplaces(亦可写作 additionalMarketplaces)为仓库或组织注册额外插件市场Any file
autoMode向 Auto Mode 分类器追加自定义 allow/deny 规则User or managed
autoMode.classifyAllShell所有 Bash/PowerShell 命令都送分类器,即使命中了窄 allow 规则User or managed(需 v2.1.193+)
availableModelsMatch设为 "exact" 时,availableModels 的条目只放行它所命名的那个模型版本Managed(v2.1.283+)
deniedModels阻止特定模型——即使 availableModels 允许它们Managed(v2.1.283+)
modelPricing.multiplier内部加价计费倍率,支持 1 以上至 10;Claude apps gateway 的 pricing 块同样支持Managed(v2.1.271+)
gatewayInternalNetworks允许 /login 访问组织自有公网 IPv4 段上的 gatewayManaged(v2.1.268+)
strictPluginOnlyCustomization含 .agents / .hooks / .mcp / .skills 四子键,阻止来自用户与项目源的 skills / agents / hooks / MCP serversManaged(2026-10 新增)
allowManagedHooksOnly只运行组织下发的 hookManaged(2026-10 新增)
disableSideloadFlags拒绝 --plugin-dir、--agents、MCP sideload 用的 CLI 参数Managed(2026-10 新增)
parentSettingsBehavior决定 SDK / IDE 宿主传入的策略是被采纳还是被丢弃Managed(2026-10 新增)
requiredMinimumVersion低于该版本拒绝启动Managed(2026-10 新增)
requiredMaximumVersion自动更新与 claude update 跳过更高版本(只约束更新,不约束启动)Managed(2026-10 新增)

环境变量层的七个新开关(写在环境里立刻可见,同属”读者可核验”这一类):

环境变量作用版本
CLAUDE_CODE_DISABLE_1M_CONTEXT=1Bedrock / Vertex / Foundry / gateway 上把 Opus 4.7+ 与 Fable 的默认 1M 上下文退回 200Kv2.1.287
CLAUDE_CODE_DISABLE_STRUCTURED_OUTPUTS关掉结构化输出(Mantle,或拒绝结构化输出的网关)v2.1.288
MCP_PROTOCOL_NEGOTIATION=legacy退出 2026-07-28 起的协议协商v2.1.292
CLAUDE_CODE_IDLE_COMPACT_MIN_TOKENS 与设置项 "idleCompaction": false空闲压缩的门槛与开关v2.1.299
CLAUDE_CODE_AUTO_MODE_MODEL指定客户端 auto mode 分类器使用的模型(见 13.6.3)v2.1.302
CLAUDE_CODE_DISABLE_ULTRATHINK关闭 ultrathink 关键字v2.1.316
CLAUDE_CODE_DISABLE_FEATURE_FLAGS停止 feature-flag 拉取但不关闭遥测;此后每个 flag 使用其内置默认值v2.1.319

这一批有个共同特征值得单独抽出来:几乎全是”关掉某个新默认”的反向开关。 1M 上下文要退回 200K 得设 DISABLE_1M_CONTEXT;结构化输出要关掉得设 DISABLE_STRUCTURED_OUTPUTS;协议协商要退回旧行为得设 =legacy;空闲压缩要停得设 "idleCompaction": false。默认值在往前推,退路以环境变量的形式提供。

这与 13.1 已记的 ABLATION_BASELINE(内部反向开关)是同一设计取向的用户可见版:新能力先上,旧行为不删,只给一条需要你自己去设的退路。工程含义是双向的——好处是不会硬断裂,代价是“你以为的默认值”与”实际生效的路径”之间的偏差必须由用户主动消除,而大多数人不会去读环境变量清单。

这条规律有一个反例边界,值得单独划出来。 Opus 4.8 的 fast mode 自 2026-10-30 起弃用,2026-11-30 移除;移除后 fast mode 请求直接报错、不回退到标准 Opus 4.8,官方指引迁移到 Opus 5.5(v2.1.316)。对照之下,“任何硬闸门都要配一条管理员自己能退出来的路”(见本节末 requiredMaximumVersion 一段)的适用域是治理侧闸门;产品能力生命周期可以完全不留退路地硬下线——但官方给了 31 天窗口与明确的迁移目标,作为替代性的”软着陆”。两种形态并列后规律本身更完整:退路的有无取决于谁被闸门卡住——管理员被卡住时必须留退路,用户侧的能力让位则可以用时间窗口加迁移指引来消化。顺带一提,v2.1.304 已把 Opus 5.5 /fast 对话框的 “(research preview)” 标签摘掉——旧 fast mode 让位给新模型的 fast mode,是 13.6.3 模型矩阵的自然延伸。

这十一项证明了与源码泄漏清单相同的架构判断——行为在运行时可配置——但证据链完全不依赖泄漏源码。对本书的读者来说,这也是一个可操作的自检入口:想确认本节说的是不是真的,挑一项写进 settings 试一下即可,不必信任任何第三方分析。

新增的四个都属托管设置(Managed),合起来把”管理员能远程决定什么”从选哪个模型扩展到了四个新方向:

  • 版本钉死(availableModelsMatch: "exact"):availableModels 里写 claude-opus-5 就只放行这一个版本,Opus 5.5 发布后不会自动进入许可范围,必须显式加入才解禁。这是把”新模型自动可用”反过来变成”新模型默认被挡”——对需要在新模型上做完内部评估才放行的组织,这是唯一不用改客户端的做法。
  • 黑名单优先(deniedModels):官方明写它即使 availableModels 允许也生效。这是一次明确的优先级设计:白名单与黑名单并存时,黑名单压过白名单。有了它,availableModels 就可以写成较宽的家族范围,再用 deniedModels 打洞,而不必把允许清单维护到版本粒度。
  • 价格倍率(modelPricing.multiplier):倍率上限 10,用于内部加价计费。它把”哪个模型能用”和”用这个模型记多少账”拆成了两件事——前者是能力治理,后者是成本治理。
  • 网络范围(gatewayInternalNetworks):允许 /login 连到组织自有公网 IPv4 段上的 gateway,解决的是 gateway 部署在组织 IP 段内却被登录流程拦在外面这一具体问题。

与之配套的一条告警也值得记:v2.1.284 起,gateway 在托管策略的 availableModels 为空、或未包含 Claude Code 启动所用模型且未设 model / enforceAvailableModels 时,会在启动时告警。这是一条典型的”配置能生效但配错了”的兜底——策略本身不报错,只是让客户端在一个自己不允许的模型上跑。

其中 autoMode 有一处值得单独记下:它的规则数组里可包含字面量 "$defaults" 来保留官方内置规则并把自定义规则插在指定位置;省略则整体替换。这个设计让”扩展分类器”和”接管分类器”成为两个独立选择,而不是非此即彼。官方另在 /permissions 中提供了 Auto Mode 标签页用于查看和编辑这些规则——Auto Mode 已从实验特性变成一等公民配置项。

"$defaults" 的语义还有一条边界场景(v2.1.316 修补)。 “扩展”与”接管”之外存在第三种形态——被第三方入口悄悄扩回去:v2.1.316 修复了托管 autoMode.allow 列表不含 "$defaults" 时,内置例外仍会被宿主 app 的 --settings、/permissions 里新增的首条规则或 /auto-mode-setup 加回来的 bug;同版的另一条 Changed 则让不含 "$defaults" 的 allow 列表不再移除 scheduled-task prompts 的内置规则。读者若发现 allow 列表”没动却被扩了”,先查这三个入口:宿主 --settings、/permissions 首条规则、/auto-mode-setup——加上调度任务这条独立处理路径,共四个会绕过你对 allow 列表意图的场景。

2026 年 10 月这一批新增的方向是”来源治理”。 上面四个方向(版本钉死 / 黑名单优先 / 价格倍率 / 网络范围)管的都是”能用哪个模型、记多少账、能连哪里”。strictPluginOnlyCustomization、allowManagedHooksOnly、disableSideloadFlags 这三个管的是另一件事——什么样的扩展物才存在:

  • disableSideloadFlags 堵的是命令行这条旁路(--plugin-dir、--agents、MCP sideload);
  • strictPluginOnlyCustomization 堵的是用户目录与项目目录这两条主路(skills / agents / hooks / MCP 四类各一个子键);
  • allowManagedHooksOnly 把 hook 收回到组织下发(与第 11 章同源)。

三条都关上之后,“一个技能是怎么来到这台机器上的”就只剩一个答案:来自插件或托管源。这是比 disallowed-tools(管技能能用什么工具)更上游的一刀——前者限制能力,后者决定存在。

版本号在两侧是两种性质的东西。 13.1 的核心论点是”版本号是给人读的标签,不是可运算的量”——对读者而言,268 − 88 得出 180 是高估。而 requiredMinimumVersion / requiredMaximumVersion 恰恰相反:组织钉一个区间后,低于最低版本拒绝启动,高于上限则自动更新与 claude update 跳过更高版本。比较在这里不仅有意义的,而且是硬闸门。

两者合起来的读法是:版本号对用户不可运算(相减无意义),对管理员可运算(比较即硬闸门)。 官方还给出一处精确的语义边界——requiredMaximumVersion 只约束更新、不约束启动,且 claude update / install / doctor 在上限之上仍可用,以便恢复。这个”留一条恢复路径”的写法与上面”反向开关”那条规律是同一个思路在治理侧的表现:任何硬闸门都要配一条管理员自己能退出来的路。

13.1.2 changelog 也会什么都不写

本章与第 12 章大量依赖官方 changelog 作为观测 Flag 与默认值漂移的主通道。这条通道有一个此前没写明的性质:它不是单调的,一个版本可以在 changelog 里什么都不写。

v2.1.303(2026-10-18)的完整条目只有一行——* Bug fixes and reliability improvements。没有 Added,没有 Changed,没有 Fixed,也没有往常附在末尾的展开式安全修复块。作为对照,同一份文档里 v2.1.302(2026-10-16)有 56 条条目。

两条结论:

  1. 不能按 changelog 条目的有无或多少来判断一个版本是否重要。 一个”空”的版本仍然可能包含 Flag 翻转、默认值变更或安全修复——changelog 是披露口径,不是变更清单。把它当成后者的读者会系统性地低估那些没有条目的版本。
  2. 这反过来加固了 13.1 开头的做法:当观测通道本身会静默时,快照锚点比任何派生结论都可靠。 “本书修订时已至 v2.1.303 / 2026-10-18”这句话的价值,正在于它不依赖那一版 changelog 写了什么。

13.2 两种 Flag 机制

Claude Code 使用两种互补的 Feature Flag 机制:

构建时 Flag(Static)

// 构建前(源码)
if (feature('VERIFICATION_AGENT')) {
  agents.push(VERIFICATION_AGENT);
}

// 构建后(如果 Flag 为 false)
// 整个 if 块被移除(Tree Shaking)

构建时 Flag 由 Bun 打包工具在编译阶段处理。如果某个 Flag 为 false,对应的代码分支会被 Tree Shaking 完全移除——它不会出现在最终的 cli.js 中。

这意味着:

  1. 外部用户的发布版本中,禁用的功能代码根本不存在
  2. 反向工程泄露代码时,看到的 Flag 分支不代表实际发布版本的行为
  3. 构建后的包体积更小

运行时 Flag(Dynamic)

// 运行时检查,通过 GrowthBook 远程控制
if (getFeatureValue_CACHED('tengu_kairos_brief', false)) {
  enableKairosBriefMode();
}

运行时 Flag 通过 GrowthBook 远程功能开关平台管理。getFeatureValue_CACHED 函数从本地缓存读取 Flag 值——注意后缀 _CACHED_MAY_BE_STALE 说明值可能不是最新的,但避免了每次检查都发起网络请求。

这里补上双机制讨论此前缺的一环:flag 停拉之后的默认值从哪来? 答案是编译期内置默认。v2.1.319 的 CLAUDE_CODE_DISABLE_FEATURE_FLAGS 官方说明明写——停止拉取后”每个 flag 使用其内置默认值”。也就是说运行时 Flag 的完整取值链是”远程值优先、内置默认兜底”,构建时消除机制(13.2 上半节)在运行时路径里仍然以默认值的形式在场。

13.3 已知的关键 Feature Flags

从泄露代码中可以识别出以下主要 Flag 及其功能:

Flag功能影响范围状态
PROACTIVE主动性模块——模型主动发现问题和提建议System Prompt已上线
KAIROS日记/自动日志系统记忆模式 + System Prompt灰度
KAIROS_BRIEFKAIROS 的快速速记功能BriefTool 可用性灰度
COORDINATOR_MODE多代理协调器模式代理加载 + 协作模式部分上线
VERIFICATION_AGENT代码验证代理代理可用性需配合 Feature Value
MONITOR_TOOLMCP 服务器监控任务工具可用性条件加载
EXPLORE_PLAN_AGENTSExplore 和 Plan 代理代理可用性根据配置启用
TEAMMEM团队记忆同步记忆模式需 GitHub 仓库
MEMORY_SHAPE_TELEMETRY记忆系统遥测遥测数据数据收集
daemon守护进程模式(常驻 Agent)后台运行未上线
voice_mode语音交互模式语音 I/O未上线
web_browser_tool浏览器工具集成工具可用性未上线
fork_subagentFork 子代理功能多 Agent 编排未上线
context_collapse上下文压缩记忆管理未上线
experimental_skill_search实验性技能搜索技能发现未上线
enable_capybara_modelsCapybara 模型族模型选择未上线
enable_undercover_modeUndercover 模式身份隐藏已上线
BUDDY虚拟伙伴系统——18 物种、5 属性(DEBUGGING/PATIENCE/CHAOS/WISDOM/SNARK)、稀有度从 common 到 1% legendary交互体验内部实验
CHICAGO_MCPComputer Use MCP——GUI 自动化(鼠标移动、点击、截图)工具可用性实验性
CLAUDE_CODE_WORKFLOWS环境变量门控——Workflow Tool(确定性多 Agent 编排)工具可用性实验性(需手动启用)
tengu_workflows_enabledGrowthBook 门控——Workflow Tool 的远程开关工具可用性灰度(编译默认 true)

新增实验性/未上线 Flag(v2.1.147+ 社区逆向分析):

Flag功能状态
NATIVE_CLIENT_ATTESTATION原生客户端密码学认证(placeholder)未上线
ANTI_DISTILLATION_CC向 API 请求注入 decoy tools——毒化竞品训练数据未上线
TRANSCRIPT_CLASSIFIER会话 transcript 自动分类未上线
LODESTONE未记录功能未知
CLAUDE_CODE_VERIFY_PLAN计划执行验证工具未上线
tengu_heron_brookSystem Prompt 远程注入(v2.1.150 激活)已上线
tengu_workflows_enabledWorkflow Tool GrowthBook 远程开关灰度

编辑说明:Flag 数量(~45+ 编译时 + 25+ GrowthBook,具体数量随版本变化)和新 Flag(daemon、voice_mode、fork_subagent 等)基于 Claude Code v2.1.88 source map 泄漏分析(theplanettools.ai 2026)。v2.1.147+ 新增 NATIVE_CLIENT_ATTESTATION、ANTI_DISTILLATION_CC 等 Flag 来自社区逆向分析(theplanettools.ai 2026-06)。v2.1.139+ 已新增 CLAUDE_CODE_OPUS_4_6_FAST_MODE_OVERRIDE、CLAUDE_CODE_RESUME_PROMPT 环境变量和 claude-empty-* 空模型系列。BUDDY(150+ 源码引用)和 CHICAGO_MCP 的详细描述来自 theplanettools.ai 深度分析。COORDINATOR_MODE 状态从”灰度”更新为”部分上线”,因 Agent 视图(v2.1.139)已实现多 Agent 协调能力。

外部用户默认能看到的大约是一半——另一半是 Ant 内部专用的实验性功能。

13.4 Ant-native 构建

Claude Code 有两条构建管线,产出两个不同的版本:

构建面向Flag 策略特殊配置
External Build外部用户只启用稳定 Flag标准工具集
Ant-native BuildAnthropic 内部启用所有实验性 Flag额外内部工具

Ant-native 构建的差异不只是 Flag——它还有一些硬编码的特殊路径:

差异点ExternalAnt-native
搜索工具Glob + Grep(ripgrep)Bash 内嵌 bfs + ugrep
内部工具无Tmux 控制等
性能采样率0.5%100%
MDM 预启动无有(移动设备管理)
用户类型判断process.env.USER_TYPE !== 'ant'process.env.USER_TYPE === 'ant'

这种双轨构建让 Anthropic 可以在内部快速实验新功能,验证后再推到外部版本。内部用户实际上是新功能的”零成本测试组”。

更精细的构建变体。根据源码泄漏分析,Claude Code 的构建实际上可细分为四种变体:

变体额外启用的 Flag产品定位
Standard CLI无基础功能,面向个人开发者
Bridge Build+BRIDGE_MODE, CCR_AUTO_CONNECT企业中间件模式
Daemon Build+DAEMON, BG_SESSIONS常驻守护进程模式
Enterprise+TEAMMEM, TEAMMEM_SYNC团队协作与记忆同步

⚠️ 注意:构建变体信息来自源码分析,非官方确认,仅供参考。

13.5 Feature Flag 与 System Prompt 的耦合

Feature Flag 对 System Prompt 的影响是深度的——不同 Flag 组合会产生完全不同的 System Prompt:

getSystemPrompt()
  ├── 基础角色定义(始终包含)
  │
  ├── if feature('PROACTIVE')
  │     └── 注入主动性模块提示词
  │
  ├── if feature('KAIROS')
  │     └── 注入日记模式提示词
  │
  ├── if feature('COORDINATOR_MODE')
  │     └── 注入协调器模式提示词
  │
  ├── if feature('VERIFICATION_AGENT')
  │     └── 注入验证代理提示词
  │
  └── ... 20+ 其他条件分支

这意味着两个用户看到的 Claude Code 可能在行为上有显著差异——不是因为模型不同,而是因为 System Prompt 不同。

13.6 GrowthBook 集成

运行时 Flag 通过 GrowthBook(开源功能开关平台)管理。源码中的 tengu_ 前缀(如 tengu_kairos_brief、tengu_paper_halyard)暗示了 Anthropic 内部可能使用 “Tengu” 作为 Claude Code 的内部代号。

GrowthBook 的集成方式:

  1. 启动时从 GrowthBook 拉取最新的 Flag 配置
  2. 缓存到本地,后续读取不走网络
  3. 缓存可能过期(_CACHED_MAY_BE_STALE),但不影响功能

这种”缓存优先 + 异步更新”的模式与插件加载策略(第 12 章)一致——都是为了保证启动速度。

13.6.1 GrowthBook 的透明度边界

⚠️ 安全警示:从泄漏源码中发现,GrowthBook 支持企业管理员通过 tengu_ant_model_override 等 Flag 强制执行用户无法覆盖的策略——包括设置默认模型、追加系统提示词、定义自定义模型别名。这意味着 Anthropic 可通过远程 Flag 控制极其广泛的功能,且在很大程度上没有用户可见性或同意机制。

企业用户在使用 Claude Code 企业版时,建议与管理员确认 GrowthBook 配置策略,确保符合内部安全合规要求。这一透明性问题在 CLI 工具中尚属新议题,需要行业共同关注。

13.6.2 远程 System Prompt 注入机制

v2.1.150(2026-05-22)激活了此前仅为占位代码的两个远程 System Prompt 注入通道,这是 Feature Flag 机制中透明度差距最大的设计:

Bootstrap 端点。Claude Code 启动时调用 api.anthropic.com/api/claude_cli/bootstrap,返回的内容注入 system context,在所有用户输入之前生效。这意味着每次启动时,服务端都有一条单向通道向客户端注入上下文。

GrowthBook tengu_heron_brook。该 Flag 每 60 分钟轮询一次 GrowthBook,可修改 System Prompt。v2.1.158 进一步升级为完整替换模式——当 CLAUDE_CODE_SYSTEM_PROMPT_GB_FEATURE 环境变量指向某个 GrowthBook Flag 且 CLAUDE_CODE_REMOTE=1 时,整个运行时 System Prompt 被该 Flag 的值替换,无客户端 allowlist(任何 Flag 名都接受)、无用户通知、无审计日志。

版本时间线:

  • v2.1.150(2026-05-22):函数激活,注入通道上线
  • v2.1.158(2026-06 初):升级为完整 System Prompt 替换模式
  • v2.1.178(2026-06 底):瘦客户端架构收敛(见 13.7 节分析)
  • v2.1.268(2026-09-10):影响面从 System Prompt 扩展到定价与遥测

远程配置的影响面不止提示词。v2.1.268 起,Claude apps gateway 的 gateway.yaml 中设置 pricing: 后,签名登录的 Claude Code 客户端会通过托管设置接收相同费率,使 /cost 与遥测跟消费计量对齐。这条新增说明远程配置能触及的不只是”模型知道什么”(System Prompt),还包括”用户看到自己花了多少钱”(/cost 显示口径)——管理员可远程改写客户端的成本显示。

第三条通道在 2026 年 10 月出现:模型目录本身(v2.1.311)。 Bedrock / Mantle / Vertex / Foundry 上的 Claude Code 改为从 downloads.claude.ai 的签名文件加载模型设置——哪个模型叫什么名、上下文窗口多大(第 14 章的 ModelConfig 映射所依赖的那张表),此前硬编码在版本里,现在也远程化了;CLAUDE_CODE_MODEL_CATALOG=off 可退出。三件事值得记:① 影响面序列呈加速态——System Prompt(v2.1.150)到定价遥测(v2.1.268)隔了 100 个 release,定价到模型目录(v2.1.311)只隔 41 个 release(npm 实际发布数;按版本号相减会得 118 与 43,正是 13.1 纠正过的口径);② 签名文件是三条远程通道中唯一带完整性校验的,可作为”官方自己也知道这条通道敏感”的旁证;③ 这是 13.7 第 7 条”瘦客户端收敛”叙事的又一推进证据。模型目录的具体语义详见第 14 章。

首个被官方确认的活案例(2026-10-27)。 此前 tengu_heron_brook 只能以安全研究视角描述(机制知道、后果悬想)。2026-10-27 前后,Opus 5.5 上的 Claude Code 会话开始携带两句新指令:“Do build original games, games in a genre, and games from the user’s own designs and assets. Don’t build a recreation of a specific existing game, even if it is renamed or called original.”——多方在 2.1.314(及 2.1.316)二进制中核验到该字符串挂在 tengu_heron_brook 名下,按模型与 effort 键控下发;配套遥测事件 tengu_brook_heron_applied 记录注入文本长度与会话 effort。Anthropic 工程负责人 Addy Osmani 于 10-30 确认改动,理由是使用政策禁止 IP 侵权;官方 changelog 304~319 全程未提及,也无任何用户侧开关。这个案例恰好逐字命中本章两条论点:13.1.2 的”changelog 是披露口径不是变更清单”(有官方确认、无 changelog 记载),与 13.6.2 的”无用户通知”(从设计描述变成已发生事实)。它还填补了 13.6.1 二分法之外的第三种形态——有官方确认、无产品披露的中间态:比”可见的治理”少一个控制台,比”不可见的治理”多一句事后承认。(另有单源数字称 2.1.308 二进制实测该程序携带 3,181 个同类具名配置槽,出自 majormatters 对二进制的实测、未见第二来源,仅作记录。)

反面还有一例:不是管理员改的,是官方自己改的。 v2.1.296(2026-10-09)把 Sonnet 5.5 的 cache reads 价格由此前公告的 $0.20/Mtok 改为 $0.10/Mtok,并且是四处同步改:/cost、状态栏、--max-budget-usd、SDK 的成本数字。

上一例说明”管理员可远程改写成本显示”,这一例说明更基本的一件事:连成本口径本身都不是稳定值。 同一个模型的同一个计价项,在两周内被改了一次;而它必须四处同步,恰好说明口径不统一会立刻表现为用户可见的矛盾(/cost 与状态栏对不上)。

由此给本章一条硬约束:本书此后记录任何模型价格,都必须带日期与版本锚点。 否则读者按本章的数字算出来的成本会与他自己 /cost 里的数对不上——而他会以为是自己的账算错了。这也是 13.1 那条”记快照锚点比记数字重要”在价格维度上的同一应用。

用户缓解措施(v2.1.319 起为三件套):

  • CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1:阻断新的 GrowthBook 拉取(但已缓存的 Flag 值仍可被读取)——断网络旁路,语义最宽
  • DISABLE_GROWTHBOOK=1:彻底禁用 GrowthBook 集成(副作用:其他 GrowthBook 门控的实验性功能也会失效)——禁生态
  • CLAUDE_CODE_DISABLE_FEATURE_FLAGS=1(v2.1.319 新增):停止 feature-flag 拉取但不关闭遥测,此后每个 flag 使用其内置默认值——只断 flag 流,语义最窄最干净

安全评估。Anthropic HackerOne 将此标记为 Informative 关闭,理由是 TLS-MITM 是高门槛前提。但社区指出企业 TLS 拦截代理和本地代理在 MITM 姿态下运行是常态——这意味着在大量企业环境中,局域网内的攻击者即可完成 MITM 并注入任意 System Prompt。

与 13.6.1 的关联。13.6.1 讨论了企业管理员通过 tengu_ant_model_override 控制用户设置——这是可见的治理(有管理控制台、配置项明确、用户可以询问管理员)。而本节讨论的 tengu_heron_brook + bootstrap 则是不可见的治理——Anthropic 通过远程通道静默注入或替换 System Prompt,用户没有任何可见性或同意机制。两者共同构成了 GrowthBook 透明度的两极:一端有审计和授权,另一端完全无感知。

13.6.3 案例研究:Auto Mode 默认化——Feature Flag 驱动的 UX 范式迁移

2026 年 8 月 7 日,Anthropic 宣布 Auto Mode 将于 2026 年 8 月 14 日对 Pro/Max/Team 计划用户成为默认交互模式——这是 Feature Flag 灰度发布的一个典型案例。

灰度时间线:

  • 2026-03:Auto Mode 作为 opt-in 实验功能上线
  • 2026-04~07:内部全量使用 + 外部 opt-in → 收集安全数据(1,053 名付费测试者对照研究)
  • 2026-07-11(v2.1.207):Bedrock / Vertex AI / Foundry 上的 Auto mode 取消 CLAUDE_CODE_ENABLE_AUTO_MODE opt-in 要求,管理员可用 disableAutoMode 关闭
  • 2026-08-07:公告默认化决定(为期 7 天的预告窗口)
  • 2026-08-14:Pro/Max/Team 新会话默认启用

⚠️ 生效时间必须分环境看。早期版本把最后一条写成”Enterprise/API/云平台保持 opt-in”,与官方 changelog 冲突:三大云厂商(Bedrock / Vertex AI / Foundry)在 2026-07-11 就已免 opt-in,比消费级订阅的 08-14 早 5 周。08-14 默认化适用的是 Pro/Max/Team 订阅;云平台走的是另一条时间线。

这类错误的形态值得记住:只查了消费级订阅的公开公告,就把它当成”全环境”结论。凡是读到”X 功能于某日生效”,先问一句”在哪个环境”——CLI、API 与各云平台在 Anthropic 的发布节奏里经常不同步。

涉及的 Feature Flag(推测):

Flag作用类型
autoModeEnabled单个用户/会话的 Auto Mode 开关运行时 / GrowthBook 门控
defaultMode管理员设置组织级默认权限模式托管设置(managed settings)
disableAutoMode管理员强制关闭 Auto Mode(优先级高于 defaultMode)托管设置(官方 scope 为 Any file,最常用于托管设置;亦可写作 permissions.disableAutoMode)

安全分类器 vs 人工审核。Anthropic 的对照研究表明:人工审核仅捕获 13.6% 的危险命令,而 Auto Mode 的分类器捕获了 89%——人工审核批准了 800 条 Auto Mode 会拦截的危险命令,而 Auto Mode 仅漏放 6 条人工会拦截的命令。这一数据直接支持了从 permission prompts(置信度低)向分类器审查(置信度高)的默认迁移。

分类器开销费用取消。2026 年 8 月 7 日起,Claude Code 取消了对 Pro/Max/Team 用户每次 tool call 的分类器推理额外 Token 费用——此前 classifier overhead 是 Auto Mode 的隐性成本。这一经济激励与默认化策略协同:取消费用 → 降低使用门槛 → 加速 Auto Mode 采用率 → 自然过渡至默认化。

分类器跑在哪一侧:四天内的两次翻转,以及之后的两轮微调(2026-09-29 补)。上面讲的是”是否默认”与”是否收费”,还有一个维度本章此前完全没写:分类器本身部署在哪一侧。这个维度在 2026 年 9 月被连续改了四次:

版本日期变更
v2.1.2732026-09-15Bedrock / Vertex / Foundry 上的 auto mode 改为默认使用本地分类器(原文明写 for now);设 CLAUDE_CODE_AUTO_MODE_SERVER=1 可改用平台的服务端分类器
v2.1.2782026-09-19Claude API 与 Enterprise 用户,加上 Bedrock / Vertex / Foundry 与 gateway,统一改为默认使用服务端分类器(不收 classifier overhead);CLAUDE_CODE_AUTO_MODE_SERVER=0 在 B/V/F/gateway 上退出;计费回退时会告警
v2.1.2812026-09-23CLAUDE_CODE_AUTO_MODE_SERVER 扩展到直连 Anthropic API:0 退出服务端分类器(改用本地分类器,计入用量),1 启用
v2.1.2822026-09-24直连 Anthropic API 且遥测关闭时,auto mode 默认走服务端分类器(CLAUDE_CODE_AUTO_MODE_SERVER=0 退出)
v2.1.2932026-10-07回滚了 v2.1.281 对 auto mode 拒绝消息措辞的改动(那次改动告诉 Claude:拒绝覆盖的是结果而不只是那条命令)。12 天后撤回
v2.1.3022026-10-16新增 CLAUDE_CODE_AUTO_MODE_MODEL,可指定客户端分类器使用的模型;对服务端分类器无效
v2.1.3192026-11-06遥测或 feature flags 关闭(含 LLM gateway 后)时,服务端查不了的调用改为询问或拒绝,不再回退内置分类器;CLAUDE_CODE_AUTO_MODE_SERVER=0 可保住本地分类器(Bedrock/Vertex/Foundry 不变)
v2.1.3192026-11-06LLM gateway 后 CLAUDE_CODE_AUTO_MODE_SERVER=1 即使在 CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS 下也生效;托管设置若设了后者必须同时设 1
v2.1.3192026-11-06项目的 settings 文件或插件不再能把你在项目外关掉的服务端检查重新打开

2026-11-06 的 v2.1.319 给这个维度加了三种新形态,其中第一种是对既有”回退”语义的直接收紧。 此前这个维度的故障模式是”静默切换”(你不知道自己跑在哪一侧);现在多了一种”无回退”:gateway 之后加上遥测关闭的组合下,服务端查不了的调用直接询问或拒绝,内置分类器不再兜底——分类器直接不可用。好在失败第一次变得可见:v2.1.319 同时修复了 claude -p 在此场景下动作被拒却以退出码 0 结束的问题,文本与 JSON 输出现在退出码 1——CI 管道至少能捕获到失败,而不再是无声地”成功”。第二条是又一处”两处都写否则静默失效”(与 14 章优先级链同源):托管设置设了 DISABLE_EXPERIMENTAL_BETAS 就必须同时设 AUTO_MODE_SERVER=1,否则服务端检查被静默关掉。第三条则是”优先级链短路”主题的再现:项目内 settings 或插件不能再把你在项目外关掉的服务端检查重新打开——项目源对”项目外”的决定不再有翻案权。

上表补的两行把”不稳定”这一条推到了新的一层。

v2.1.293 是第三个”改了又改”的实例,而这次改的不是开关,是一个字符串。 本章已记录 auto mode 默认化的四步来回与默认权限模式的四步来回,那两次改的都是布尔语义的默认状态;v2.1.281 → v2.1.293 改的是给模型的拒绝措辞——“拒绝覆盖的是结果而不只是那条命令”这句话上线 12 天后被撤回。含义是:Flag / 远程配置驱动的不稳定性已经从”默认值”延伸到“模型读到的提示措辞”这一层。对上面那段”读到带 for now 的默认值应按临时状态处理”是同族佐证,且更极端:连措辞都是临时状态。

v2.1.302 让”分类器”有了两个独立可调的维度,且两者不可同时调。 现在可调的有两个东西:分类器跑在哪一侧(CLAUDE_CODE_AUTO_MODE_SERVER),以及分类器用什么模型(CLAUDE_CODE_AUTO_MODE_MODEL)。关键在两者的覆盖面互相错开:

旋钮覆盖不覆盖
CLAUDE_CODE_AUTO_MODE_SERVER退出服务端分类器(改用本地)云侧分类器本身的启停方式与此不同
CLAUDE_CODE_AUTO_MODE_MODEL客户端分类器用哪个模型对服务端分类器无效(官方明示)

两个旋钮各自只覆盖一半场景,且方向相反。 这是”由平台决定而非由你决定”这一论点最硬的一条证据——不是”默认值不好记”,而是根本不存在一个能同时调两者的入口。想完整控制自己的分类器行为,必须同时知道自己跑在哪一侧,而”在哪一侧”这件事本身又由平台和遥测状态决定。

这比”静默切模型”更能说明 Flag 的代价,原因有三。其一,它改的是代码路径而非参数:同一个 auto mode,本地分类器与服务端分类器是两条不同的执行路径,判定结果、计费归属、用量计入方式都不同。其二,它由平台决定而非由你决定:v2.1.273 与 v2.1.278 的措辞都是按平台分组的,你在 Bedrock 上和在直连 API 上拿到的默认值不一样;v2.1.282 甚至把”遥测是否关闭”也变成了决定因素。其三,它不稳定:v2.1.273 的官方原文里那句 for now 是最值得注意的两个词——官方在写这条 changelog 时就知道这个默认值还会变,三天后(v2.1.278)确实变了,之后又用两个版本把直连 API 的默认值分两次补齐。读到带 “for now” 的默认值,应当按”临时状态”而非”稳定契约”处理。

唯一的好消息是可观测性在补:v2.1.278 起 /status 新增 Auto mode server 一行,显示本次会话的分类器跑在哪一侧。这是判断”我这个会话到底走哪条路径”的唯一官方入口,也说明官方自己清楚这类漂移需要给用户一个抓手——一个需要专门加一行状态来澄清的默认值,本身就说明默认值已经不可预测了。

架构意义——验证 thick→thin 迁移叙事。Auto Mode 默认化是第 13.7 节”从厚客户端到瘦客户端”叙事的直接验证:将更多决策权从用户移交给 Agent 的分类器,本质是将控制逻辑从”用户逐次审批”卸载到”服务端安全策略”——这正是薄客户端架构的核心特征。Feature Flag 在此过程中扮演了”迁移通道”的角色:先通过 Flag 让用户 opt-in 试水 → 收集数据验证安全性 → 通过 GrowthBook 渐进式提升默认激活比例 → 最终完成全量默认切换。

模型路由切换——不是一次切换,而是一个多维矩阵。早期版本曾把这件事写成”v2.1.219 将默认模型从 Opus 4.1 切至 Opus 5”。回官方 changelog 逐条核对,实际存在四次独立的默认模型变更,且维度各不相同:

⚠️ 更正:官方 v2.1.219 的原文是 Claude Opus 5 “now the default Opus model”——即 Opus 家族内部的默认指向,不是 Claude Code 的全局默认模型。全局默认模型在更早的 v2.1.197(2026-06-30)就已是 Claude Sonnet 5。早期版本把”默认 Opus 模型”读成了”默认模型”,属机制对但描述错。

版本日期变更维度
v2.1.732026-03-11Bedrock / Vertex / Foundry 的默认 Opus 模型改为 Opus 4.6(原 Opus 4.1)云厂商
v2.1.1972026-06-30Claude Sonnet 5 成为 Claude Code 默认模型(原生 1M 上下文,2/2/10 per Mtok 促销价至 8/31)全局
v2.1.2192026-07-24新增 Claude Opus 5(claude-opus-5),成为默认 Opus 模型(1M 上下文,fast mode 10/10/50 per Mtok)模型家族
v2.1.2512026-08-28座席制 Enterprise 订阅的默认模型改为 Opus 5,与其他 premium 计划对齐订阅类型
v2.1.2802026-09-22新增 Claude Opus 5.5(claude-opus-5-5),成为默认 Opus 模型(1M 上下文,4/4/20 per Mtok,$0.20/Mtok cache reads)模型家族
v2.1.2842026-09-28新增 Claude Sonnet 5.5(claude-sonnet-5-5),成为 Anthropic API 上的默认 Sonnet 模型(1M 上下文,$2/$10 per Mtok,cache reads 由 $0.20/Mtok 改为 $0.10/Mtok,v2.1.296 起)模型家族

六条并列说明:Flag 控制的模型发布不是一次切换,而是按云厂商、订阅类型、模型家族分别灰度的多维矩阵。这比单一时间线更能支撑本节论点——渐进式发布的真正复杂度不在”改哪个模型”,而在”对谁改”。

新增的两条值得单独看一眼,因为它们与 v2.1.219 完全同型:官方措辞同样是”now the default Opus / Sonnet model”,改的同样是家族内部的默认指向,不是 Claude Code 的全局默认模型。也就是说 13.6.3 那处”把默认 Opus 模型读成默认模型”的误读,在三个月后有了两次新的犯错机会——这是一种结构性误读,不是一次性的笔误。读者在 changelog 里再看到”default X model”字样时,第一反应应该是问”是哪个家族的默认值”。

另一处细节能佐证这条矩阵有多细:v2.1.280 同时改了 effort 的继承规则——在 /effort 变成按模型保存之前存的档位,不再套用到新发布的模型(官方点名 Opus 5.5),这些模型从自己的默认值起步直到你重新选档。发布一个新模型,连带要修一条与之无关的历史设置迁移路径。

矩阵还可以从 v2.1.311 的另一条 Changed 里多读出一个名字:ultrathink 在交互终端改为以 xhigh effort 跑当轮,适用模型清单为 Opus 5.5、Sonnet 5.5、Haiku 5.5、Fable 5.1——这是 Haiku 5.5 首次在本章的官方一手材料中出现(此前的模型矩阵只到 Opus/Sonnet 两族的新款),它随一条与发布无关的 effort 条目被顺带披露,本身就是”changelog 是披露口径不是变更清单”的又一例。

Flag 驱动模型路由的代价。上面讲的是收益(渐进发布、灰度回退、按订阅分层),代价同样存在:v2.1.268 修复了一个 bug——当另一个 Claude Code 进程刷新了过期的 model-access 条目时,正在运行的会话会静默切换到组织的默认模型。用户视角是模型毫无提示地变了,且没有任何日志说明发生了什么。这是”远程可配置模型路由”这一架构必然附带的故障模式:可远程改变的东西,也可能在你不知情时被改变。

一个相关的缓解方向也来自该版本:同一个 v2.1.268 还修复了”授权用户在重启后或 Desktop Code 标签页中,因缓存的 model-access 拒绝记录过期而被提示模型受限”。两条修复合起来看,说明官方也在持续收敛 Flag/远程配置带来的状态不一致问题。

Flag 驱动的不只是模型路由,还有工具集(2026-09-29 补)。上面这个故障模式——远程可配置的东西在你不知情时被改变——有一个更易被忽略的变体:被改的不是模型,而是工具集。

v2.1.275 修复了一个 bug:--resume 与 --continue 在某个内置工具被服务端 flag 关掉之后,会丢掉会话此前生成的 thinking。把它和”静默切模型”放在一起比较,能看出为什么这一支更坏:

被 Flag 改动的对象用户能否感知后果
v2.1.268 的静默切模型模型能(回答风格、能力明显变化)本次会话行为改变
v2.1.275 的工具集变更工具集不能(工具只是不出现了)恢复的会话丢掉已生成的 thinking

差别在于:模型换了,用户至少能在产出里察觉;工具集变了,用户看到的只是”这个工具怎么没了”,而真正发生的是会话的历史状态在被恢复时悄悄损坏——已经生成的 thinking 是会话上下文的一部分,丢掉它是不可逆的信息损失,且发生在恢复那一刻而非使用期间。

工具集被 Flag 门控并不是偶发:v2.1.268 起,任务追踪工具(TaskCreate / TaskGet / TaskUpdate / TaskList、TodoWrite)只在 Claude 3.x、Opus 4.0–4.7、Sonnet 4.0–4.6、Haiku 4.5 上提供,其他模型需设 CLAUDE_CODE_ENABLE_TODO_TOOLS=1。(更早的 v2.1.233 曾把这些工具从 Opus 4.8、Sonnet 5、Fable 5、Mythos 5 及更新模型上撤下,同样的环境变量可以取回。)也就是说”你能不能用 TodoWrite”取决于你当前挂的是哪个模型——这是 13.1 那张”影响范围”表里工具可用性一行在 2026 年下半年的具体形态。

合起来看,Flag 的作用面已经从”路由”扩展到”能力集合”。路由变了换条路走,能力集合变了会直接损伤已经存在的会话状态——后者才是远程可配置架构里更该被盯住的部分。

13.6.4 远程配置失效时朝哪个方向倒

13.6.1 与 13.6.2 分别讲了两件事:远程配置能看到什么,以及它能注入什么。还有一个问题本章此前没有正面回答——远程配置自身坏掉时,系统朝哪个方向倒。这不是学术问题:托管策略是组织下发的安全边界,如果一份写错的文件会让边界静默消失,那么”我们配置了”与”我们被保护了”就是两件事。

2026 年 9 月连续三个版本给出的答案,是方向并不一致:

场景版本失效时的行为方向
布尔锁键(disableClaudeAiConnectors、allowManagedPermissionRulesOnly)取值拼写错误v2.1.282此前锁不生效;v2.1.282 起锁生效,且启动时指出是哪个键修复前 fail-open
strictKnownMarketplaces / blockedMarketplaces 中一条格式错误v2.1.277静默禁用整个企业市场策略修复前 fail-open
托管 permissions / autoMode / worktree / attribution 中一个嵌套值无效v2.1.282此前整块被忽略;修复后其余部分仍生效修复前 fail-open
托管白名单(allowedHttpHookUrls、httpHookAllowedEnvVars、allowedChannelPlugins)无法读取v2.1.267官方原文是 “admit nothing, not everything”——不放行任何东西(修复前是放行一切)fail-closed
Team/Enterprise 服务端托管设置的存档副本校验不过v2.1.316存档副本拒绝使用——宁可回到无策略状态,也不带病运行(同版起托管设置无需批准提示即生效)fail-closed

第五行落在”策略能否到达客户端”这一层(第 14 章”到达条件”的同源问题):存档副本验不过就整个不用。它给 fail-closed 侧补齐了第二行,两行合起来看,fail-closed 的语义更清晰了——宁可回到更受限或无策略状态,也不运行一份来历不明的策略。这与 fail-open 侧”写错了就当没写”的宽松形成对照,本节原有的概括(对外部可达性的限制偏保守、对内部行为的限制偏宽松)由此获得再确认;“无需批准提示”还改变了 Team/Enterprise 的到达语义,验收清单里那条”升级后主动构造一次错误配置”从此多了一个必查项:构造一份验不过的存档副本,确认客户端是拒绝使用而不是带病运行。

把这张表和 13.6.1 的”透明度边界”放在一起看,结论比任何一条单独看都更有意思:官方并没有一个统一的失效策略。涉及”能不能往外发请求”的白名单是 fail-closed(读不到就全部拒绝),而涉及”要不要锁住某行为”的布尔锁、市场名单、权限块,在修复前一律是 fail-open(写错了就当没写)。前者宁可误伤可用性,后者宁可牺牲约束——这个分野大体可以概括为对外部可达性的限制偏保守,对内部行为的限制偏宽松,但没有任何官方文档把它写成一条原则,读者只能从逐条修复里反推。

对使用托管策略的组织,可操作的结论是两条。其一,不要假设”配上了就等于生效了”:v2.1.282 之前,一个拼错的布尔值会让锁整个失效且不报错;v2.1.277 之前,一条格式错误的市场条目会让整个企业市场策略静默消失。修复后这两类都会报出具体键名或继续生效,但前提是版本够新。其二,把失效方向写进自己的验收清单:升级后应主动构造一次错误配置(拼错一个锁键、写坏一条市场条目),观察它是报错还是静默放行——这比读 changelog 更能确认你所在版本的真实行为。

可观测性这一侧也补上了入口:v2.1.274 新增 OTel 事件 claude_code.managed_settings_resolved,记录托管设置的来源与策略 helper 的状态;配 OTEL_LOG_MANAGED_SETTINGS=1 可输出脱敏后的设置内容与摘要。想知道一个客户端到底从哪些来源、按什么顺序解析出了哪些托管设置,这是唯一的官方手段——13.6.2 讲远程 System Prompt 注入时提到的”你不知道自己拿到的是哪一份”,在配置侧靠这个事件才有了答案。另有一条跨章提醒:OTel 事件清单同样是快照不是契约——claude_code.safety_event 事件 v2.1.307 新增、v2.1.312 移除,存活仅六天(第 00/01/07 章已记为历史条目),依赖任何单个事件做监控管道前,先确认它在当前版本仍然存在。

13.7 设计启示

  1. 构建时消除优于运行时检查。安全性更高(代码不存在就无法被利用),性能更好(没有运行时分支)。

  2. 双轨构建 + 内部测试是高速迭代的关键。50+ 个 Flag 说明了 Anthropic 在 Claude Code 上同时进行大量实验。

  3. Feature Flag 是产品策略工具。它们不只控制技术功能,还控制用户体验——不同用户群看到不同的能力集。

  4. Flag 与 System Prompt 的耦合是 Context Engineering 的一部分。Feature Flag 本质上决定了”模型知道什么、能做什么”——这是产品能力的核心控制手段。

  5. 从 Flag 路线图看演进方向。从源代码中的未上线 Flag 推断,Claude Code 正从”单用户 CLI 助手”进化为”多 Agent 协作平台”——fork_subagent、COORDINATOR_MODE、daemon 等 Flag 揭示了大量未上线的 Agent 编排功能和常驻守护机制。这一趋势意味着 Claude Code 的定位正在从”工具”升级为”团队成员”。

  6. 双重门控 = 编译时 Flag + 运行时 GrowthBook 远程 Flag。Workflow Tool(v2.1.147)采用了独特的双重门控设计——必须同时满足编译时 Flag(CLAUDE_CODE_WORKFLOWS=1)和 GrowthBook 远程 Flag(tengu_workflows_enabled=true)才能激活。这种设计将”快速 kill switch”(GrowthBook 远程关闭)和”构建级安全”(编译时消除代码)组合在一起,是一种精细的灰度控制手段。但需注意 DISABLE_GROWTHBOOK=1 的副作用——它会禁用所有远程 Flag,绕过远程门控的同时也丢失其他实验性功能,因此仅适合单次实验会话使用,不建议写入 shell profile。

  7. 从厚客户端到瘦客户端——Feature Flag 是架构迁移的隐形载体。持续追踪 v2.1.150→v2.1.178 的版本演进,Claude Code 正从本地 CLI 工具向远程控制的瘦客户端收敛。三条核心证据:① Bootstrap + GrowthBook 远程 Prompt 注入将 System Prompt 控制权卸载到服务端;② v2.1.178 工具输出过大时持久化到磁盘,以引用替换原始内容——模型不再直接看到全部工具输出;③ 记忆存储增加周期性远程重同步,服务端可发起本地数据删除。Feature Flag 在此过程中扮演”隐形迁移载体”——每一个新增的远程依赖都不是通过 UI 或文档暴露,而是通过 Flag 静默激活。对开发者产品设计的启示:Feature Flag 不只是功能开关,也是架构迁移的通道。当客户端功能通过远程 Flag 逐步卸载到服务端时,用户感知到的”本地工具”可能已不再是本地工具。

编辑说明:第5条基于源码泄漏中 Flag 清单的合理推断,非官方信息,来自 theplanettools.ai 2026 和 claudemythosai.io。