这是什么
本页覆盖两个相互独立的系统,它们都不依赖千手大师的默认构建行为,而是按配置启用:
GrowthBook 是一个运行时的、基于用户属性的功能门控与 A-B 测试系统。它与构建时的
feature() 宏互补:feature() 是「全有或全无」的编译期开关,而
GrowthBook 支持按用户、设备、组织、订阅类型等属性细粒度灰度。业务代码通过
getFeatureValue_CACHED_MAY_BE_STALE(feature, defaultValue) 查询以
tengu_* 前缀命名的开关;每个调用都带默认值,因此不配置任何 feature 也能正常运行。
Sentry 用于捕获运行时异常并上报到指定的 Sentry 实例。启用后自动捕获未处理异常和关键错误, 上报前会剥离敏感请求头,并忽略网络不可达与用户主动取消类噪声错误;未配置时所有导出均为 no-op。
isGrowthBookEnabled() 在没有自定义服务器配置时,回退到
is1PEventLoggingEnabled()。在当前构建中该方法为 stub(恒返回 false),
因此 GrowthBook 默认不启用;只有同时设置
CLAUDE_GB_ADAPTER_URL 与 CLAUDE_GB_ADAPTER_KEY(适配器模式)时才会真正拉取远程配置。
前置条件
GrowthBook
- 一个 GrowthBook 实例:自部署(Docker / Kubernetes)或 GrowthBook Cloud 均可。
-
实例中的 SDK Connection 及其 SDK Key(形如
sdk-xxxxx), 作为CLAUDE_GB_ADAPTER_KEY。 -
实例的 API 地址,形如
https://gb.example.com/,作为CLAUDE_GB_ADAPTER_URL。两个变量必须同时提供。
Sentry
- 一个 Sentry 实例:自托管或 sentry.io Cloud 均可。
- 在实例中创建一个 Node.js 平台的 Project,并从 Settings → Projects → Client Keys 取得该项目的 DSN。
- 运行环境网络可访问 DSN 指向的主机。
安装 / 启用
启用 GrowthBook(适配器模式)
-
部署或选择一个 GrowthBook 实例
自部署可用官方 Docker 镜像;也可以直接用 GrowthBook Cloud。
-
创建 SDK Connection,取得 SDK Key
在实例中创建一个 Environment(如 production),再创建 SDK Connection。
-
设置两个适配器环境变量
两个变量都设置时启用适配器模式,否则完全跳过 GrowthBook。
CLAUDE_GB_ADAPTER_URL=https://gb.example.com/ \ CLAUDE_GB_ADAPTER_KEY=sdk-abc123 \ qsdashi -
按需创建 Feature
Feature Key 与类型须与代码中查询的 key 一致(见配置一节);未创建的 key 一律走代码默认值。
启用 Sentry
-
获取项目 DSN
从 Sentry Project 的 Client Keys 页面复制 DSN。
-
设置 SENTRY_DSN
只需这一个变量,设置后
initSentry()即自动初始化。不设置则完全静默。SENTRY_DSN=https://public_key@your-sentry.example.com/123 qsdashi
配置
GrowthBook 环境变量
| 环境变量 | 必填 | 说明 |
|---|---|---|
CLAUDE_GB_ADAPTER_URL |
是 | GrowthBook API 地址,如 https://gb.example.com/(优先于内置默认地址) |
CLAUDE_GB_ADAPTER_KEY |
是 | GrowthBook SDK Client Key,如 sdk-xxxxx(优先级高于内置 client key) |
CLAUDE_INTERNAL_FC_OVERRIDES |
否 |
传入 JSON 对象直接覆盖任意 flag 值,例如
'{"tengu_kairos": true}';仅在
USER_TYPE=ant 的构建中生效
|
QS_DISABLE_LOCAL_GATES |
否 | 设置后禁用本地 gate 默认值,查询直接回退到调用方默认值 |
QS_GB_BASE_URL |
否 | 仅 ant 构建使用的内置地址覆盖,优先级低于 CLAUDE_GB_ADAPTER_URL |
GrowthBook 缓存与失效策略
| 机制 | 说明 |
|---|---|
| 内存缓存 | 进程内 remoteEvalFeatureValues,读取时最先命中 |
| 磁盘缓存 | ~/.claude.json 的 cachedGrowthBookFeatures 字段,跨进程持久化 |
| 周期刷新 | 外部用户每 6 小时、ant 构建每 20 分钟自动重新拉取(定时器 unref,不阻止进程退出) |
| 初始化超时 | 首次连接超时 5000 ms,超时后使用磁盘缓存或代码默认值 |
| Auth 变更 | 登录 / 登出时销毁并重建客户端,并刷新配置 |
GrowthBook 取值优先级(第一个命中即返回):
1. CLAUDE_INTERNAL_FC_OVERRIDES 环境变量(JSON 覆盖)
↓ 未命中
2. growthBookOverrides 配置(~/.claude.json,仅 ant 构建)
↓ 未命中
3. 内存缓存(本次进程从服务器拉取)
↓ 未命中
4. 磁盘缓存(~/.claude.json 的 cachedGrowthBookFeatures)
↓ 未命中
5. 代码中的 defaultValue 参数
Sentry 环境变量与行为
| 项 | 说明 |
|---|---|
SENTRY_DSN |
唯一的启用开关;未设置则所有 Sentry 调用为 no-op |
| 全局关闭 |
DISABLE_ERROR_REPORTING 让 logError 路径跳过上报(含 Sentry);
DISABLE_TELEMETRY 关闭遥测侧;QS_DISABLE_NONESSENTIAL_TRAFFIC
进入 essential-traffic 级别,同样跳过该路径
|
| 3P Provider |
设置 QS_USE_BEDROCK / QS_USE_VERTEX /
QS_USE_FOUNDRY 时 logError 直接返回,不上报
|
| release | 取自 MACRO.VERSION,自动附带 |
| environment | 构建环境值,缺省回退到 NODE_ENV 或 development |
| sampleRate | 1.0(捕获全部错误事件) |
| maxBreadcrumbs | 20(控制 payload 体积) |
| 性能事务 | 已关闭(beforeSendTransaction 返回 null),仅上报错误 |
安全过滤:beforeSend 会剥离 authorization、
x-api-key、cookie、set-cookie 请求头。
忽略错误:ECONNREFUSED / ECONNRESET /
ENOTFOUND / ETIMEDOUT(网络不可达)、
AbortError / The user aborted a request(用户取消)、
CancelError(交互式取消)。
常用命令与参数
两个系统都没有独立的 CLI 子命令:GrowthBook 由启动流程中的
initializeGrowthBook() 惰性初始化,Sentry 由 initSentry()
在 src/entrypoints/init.ts 启动时调用。开关与参数全部走环境变量。
| 项 | 说明 |
|---|---|
getFeatureValue_CACHED_MAY_BE_STALE(key, default) |
业务代码读取开关值的标准入口,非阻塞;未启用时直接返回默认值 |
initializeGrowthBook() |
初始化客户端并等待就绪;auth 条件变化时重建 |
refreshGrowthBookFeatures() |
轻量刷新:不重建客户端,仅重新拉取并重建内存缓存 |
initSentry() |
初始化 Sentry SDK;SENTRY_DSN 缺失时为 no-op |
captureException(error, context?) |
手动上报异常,可附加额外上下文 |
setTag(key, value) / setUser({...}) |
设置标签或用户上下文,用于面板分组与归因 |
closeSentry(timeoutMs?) |
优雅退出时刷出队列并关闭客户端(默认 2000 ms) |
isSentryInitialized() |
检查 Sentry 是否已初始化,可用于条件渲染 |
运行时开关统一以 tengu_ 前缀命名(如
tengu_auto_background_agents、tengu_birch_trellis),
名称刻意保持不透明。在 GrowthBook 实例中创建的 Feature Key 必须与代码查询的 key 完全一致;
类型也需匹配(boolean / number / object / string)。
实战示例
指向自建 GrowthBook 实例并覆盖一个开关(ant 构建):
CLAUDE_GB_ADAPTER_URL=https://gb.internal.example.com/ \
CLAUDE_GB_ADAPTER_KEY=sdk-abc123 \
CLAUDE_INTERNAL_FC_OVERRIDES='{"tengu_auto_background_agents": true}' \
qsdashi
不使用 GrowthBook(默认行为,读取直接返回代码默认值,零网络请求):
qsdashi
# 所有 getFeatureValue_CACHED_MAY_BE_STALE("xxx", defaultValue) 直接返回 defaultValue
启用 Sentry 并同时关闭遥测侧的其余上报:
SENTRY_DSN=https://public_key@sentry.example.com/123 \
DISABLE_TELEMETRY=1 \
qsdashi
# Sentry 仍会初始化并上报;Datadog / 1P 事件等遥测被关闭
在项目外彻底关闭两者(不设任何相关环境变量):
# 不设置 CLAUDE_GB_ADAPTER_* 与 SENTRY_DSN 即可
qsdashi
常见问题排错
CLAUDE_GB_ADAPTER_URL 与 CLAUDE_GB_ADAPTER_KEY
必须同时设置才启用适配器模式。只设其一会被视为未配置,直接跳过 GrowthBook。
取值优先读内存缓存,其次是 ~/.claude.json 的
cachedGrowthBookFeatures 磁盘缓存;远程刷新为每 6 小时(外部)/ 20 分钟(ant)。
在 GrowthBook 侧改动后需要等待周期刷新,或重启进程重新拉取。
客户端 init 超时为 5000 ms。超时不会报错中断,而是回退到磁盘缓存或代码默认值。
若实例不可达,检查网络与 CLAUDE_GB_ADAPTER_URL 地址是否正确。
依次确认:SENTRY_DSN 未设置会导致全部 no-op;设置了
DISABLE_ERROR_REPORTING 或 QS_DISABLE_NONESSENTIAL_TRAFFIC
(essential-traffic 级别)会跳过 logError 上报;使用 Bedrock / Vertex / Foundry
时该路径也会直接返回。注意 DISABLE_TELEMETRY 只关闭 Datadog / 1P 遥测,
并不会阻止 Sentry 经 logError 上报。
Sentry 是独立的错误上报通道,不与 GrowthBook 或 1P 事件日志共用开关:
GrowthBook 依赖 1P 事件日志(本构建中为 stub,故默认关闭),而 Sentry 只需
SENTRY_DSN 即可工作。两者可分别单独启用,互不影响。