claude-code-best/docs/Claude_Code_的光明和阴影面.md
James Feng 7eb5530b2c docs: sync 光明和阴影面 doc + update README numbers to 3699
- Copy doc from user manual to docs/
- Quality table: 3383 → 3699 (+692)
- Local dev section: 3383 tests → 3699 tests
- Version table: add v2.2.1, v2.2.2 entries
2026-06-04 21:03:57 +08:00

19 KiB
Raw Blame History

Claude Code 的光明和阴影面

副标题: Anthropic 遥测系统的逆向工程、纵深防御与自用改造

作者: James Feng基于 CC_Pure 代码库逆向分析2026年6月

标签: 逆向工程 遥测 隐私 GrowthBook OpenTelemetry 数据分析


目录

  1. 前言:为什么要写这篇文章
  2. 光明面:一套工业级的数据工厂
  3. 阴影面:数据去哪了
  4. 解剖:遥测系统的五层架构
  5. 防御:我们做了什么
  6. 为己所用:如何让这套系统服务于你
  7. 附录:事件词典

1. 前言

Claude Code内部代号 "tengu")是 Anthropic 的终端 AI 编程助手。它不仅仅是一个命令行工具——它是一套完整的数据采集和分析基础设施。每当你输入一个命令、调用一个工具、触发一次 API 请求,几十个遥测事件在后台被捕获、采样、路由和上报。

本文基于对 CC_PureClaude Code 反编译还原项目)的深度代码审计,完整拆解这套遥测系统:

  • 它收集了什么?
  • 数据流向了哪里?
  • 我们如何发现并防御?
  • 更重要的是,我们如何把它变成自己的利器

核心结论: Anthropic 的遥测基础设施本身就是一套值得学习的工业级数据工程范例。我们不需要摧毁它——我们需要接管它


2. 光明面

2.1 工程设计的精妙之处

Claude Code 的遥测系统不是简单的埋点+上报。它是一套分层架构:

logEvent()
  ├── 本地 JSONL 写入(我们加的防御层)
  ├── 事件队列sink 未初始化时的缓冲)
  ├── GrowthBook 动态采样(云端控制的抽样引擎)
  ├── Datadog 监控(运维告警)
  └── 1P 事件上报Anthropic 内部 BigQuery 分析)

亮点 1零依赖入口设计

logEvent() 函数(src/services/analytics/index.ts)本身没有任何模块级依赖。所有事件先进入队列,等 attachAnalyticsSink() 在应用初始化时被调用后才真正路由到后端。这个设计避免了循环依赖,也让测试变得极其容易。

// 精妙:零依赖的入口
export function logEvent(eventName, metadata) {
  // ① 本地写入(我们的注入点)
  writeLocalEvent(eventName, metadata)
  // ② 如果 sink 未就绪,入队;否则直接发送
  if (sink === null) {
    eventQueue.push({ eventName, metadata, async: false })
    return
  }
  sink.logEvent(eventName, metadata)
}

亮点 2GrowthBook 动态实验平台

整个项目的 feature flag 系统建立在 GrowthBook 之上。这不是简单的 if (feature_enabled) —— 它是一个完整的 A/B 实验平台:

  • 远程评估remote eval 服务器预先计算每个 feature 的值,客户端直接使用,无需本地规则引擎
  • 磁盘缓存 + 会话内刷新: 首次获取后写 ~/.claude.json,后续进程启动用缓存,会话期间通过 onGrowthBookRefresh 推送更新
  • 实验曝光追踪: 每个被访问的 feature 自动记录实验分配事件到 1P 事件管道
  • 动态配置JSON config 不仅是开关,还支持复杂的 JSON 配置如事件采样率、批处理参数、sink kill switch

src/services/analytics/growthbook.ts 文件高达 1256 行,处理了远程评估响应格式的 workaround、env-var override、config override、刷新信号机制等细节。

亮点 3ToolSearchTool —— RL 数据工厂的核心

ToolSearchTool 不仅是一个工具搜索功能,它是一台强化学习数据收集机器

// 搜索评分权重(精确调优的参数)
if (parsed.parts.includes(term)) {
  score += parsed.isMcp ? 12 : 10    // MCP 工具名精确匹配权重更高
} else if (parsed.parts.some(part => part.includes(term))) {
  score += parsed.isMcp ? 6 : 5      // 部分匹配
}
// searchHint 匹配
score += 4
// 描述匹配
score += 2

每一次搜索都上报 tengu_tool_search_outcome 事件,包含:

  • query:用户的搜索词
  • queryTypeselectkeyword
  • matchCount:命中数量
  • totalDeferredTools:延迟工具总数
  • hasMatches:是否有命中

这套数据让 Anthropic 能够量化分析模型如何使用工具,从而持续优化工具描述、搜索算法和评分权重。

亮点 4多层 PII 防护

代码中随处可见隐私保护设计:

  • AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS 类型标记——强制开发者验证不上传代码/路径
  • sanitizeToolNameForAnalytics() —— MCP 工具名(可能暴露用户配置)被替换为 mcp_tool
  • stripProtoFields() —— PII 标记字段只在 1P 特权列中,不进入通用 Datadog
  • getFileExtensionForAnalytics() —— 只上传文件扩展名,不上传完整路径
  • getUserBucket() —— 用户 ID 哈希分桶,去匿名化计数但不暴露身份

2.2 事件体系全景

通过代码审计,我们统计出 190+ 处 logEvent() 调用,分布在 52 个文件中。主要事件类别:

类别 事件数 代表事件
API 查询 ~20 tengu_query_error, tengu_api_success, tengu_token_budget_completed
工具使用 ~15 tengu_tool_search_outcome, tengu_bash_tool_used
权限决策 ~10 tengu_tool_use_granted, tengu_tool_use_rejected
认证/OAuth ~15 tengu_oauth_success, tengu_oauth_token_refresh_failure
会话生命周期 ~10 tengu_started, tengu_exit, tengu_init
压缩/内存 ~5 tengu_auto_compact_succeeded, tengu_orphaned_messages_tombstoned
实验/A/B ~8 tengu_willow_mode, GrowthBook assignment
Bridge/Remote ~15 tengu_bridge_message_received, tengu_ws_transport_reconnected
迁移 ~8 tengu_opus_to_opus1m_migration
遥测自监控 ~3 analytics_sink_attached

2.3 数据工厂:四线并行

Anthropic 实质上运行着四条独立的数据管道

  1. Datadog运维:白名单制,只发送 ~40 种预定义事件到 Datadog用于 API 错误率、OAuth 故障率等 SRE 告警
  2. 1P Event Logging分析:基于 OpenTelemetry SDK Logs所有事件通过 /api/event_logging/batch 上报到 Anthropic 的 BigQuery是核心分析管道
  3. GrowthBook实验Feature flag 赋值 + 实验曝光事件,独立上报,用于 A/B 测试结果评估
  4. Customer OTLP客户遥测:可选的企业客户 OTLP 导出metrics/logs/tracesCLAUDE_CODE_ENABLE_TELEMETRY 控制

3. 阴影面

3.1 数据收集的广度

让我们诚实地审视Claude Code 实际收集了什么

每次启动:
  ✓ 操作系统版本、终端类型、包管理器列表
  ✓ Git 仓库远程 URL 的哈希("rh" 字段)
  ✓ 用户订阅级别(免费/Pro/Max/Team/Enterprise
  ✓ 是否为 CI 环境、GitHub Action 类型

每次 API 查询:
  ✓ 使用的模型名称、beta 列表
  ✓ token 消耗量、上下文窗口大小
  ✓ 是否触发了 fallback 模型
  ✓ 查询前后的 attachment 对比

每次工具调用:
  ✓ 工具名称、是否成功
  ✓ 文件扩展名(不是路径,但足以推断工程类型)
  ✓ Bash 命令类型diff/grep/sed 等)
  ✓ 权限决策always allow / reject / ask

每次会话:
  ✓ 启动次数、使用时长
  ✓ 压缩频率、孤儿消息数量
  ✓ KAIROS后台 agent活跃状态

3.2 技术上的透明度

Anthropic 并不是在偷偷做这件事。代码中的设计模式表明:

  1. 所有遥测都在 src/services/analytics/ 下集中管理,模块边界清晰
  2. 隐私分级明确AnalyticsMetadata_I_VERIFIED_... 类型标记)
  3. 提供了 opt-out 机制DISABLE_TELEMETRY / CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC

但从"后门"到"数据工厂"的距离并不远。这一套基础设施如果被滥用(或遭遇供应链攻击),可以轻松变成:

  • 代码片段收集器(绕过文件路径截断,直接上传内容)
  • 用户行为画像(通过 token 消耗模式推断工作习惯)
  • 工程结构嗅探(通过文件扩展名统计推断技术栈)

3.3 我们发现的"异常"

在 CC_Pure 的代码审计中,我们注意到几个不寻常的地方:

  1. USER_TYPE === 'ant' 条件分支: 代码中有 50+ 处检查用户是否为 Anthropic 内部员工。内部版本能看到额外的调试信息、工具ConfigTool, TungstenTool, REPLTool、错误日志。这不是安全问题但说明"内部版本"和"外部版本"的差异比文档披露的更大。

  2. ToolSearchTool 的 RL 评分权重: 12/10/6/5/4/3/2 的精细评分体系不是手工调整的——它暗示着持续的 A/B 实验和 RL 优化在背后运行。

  3. GrowthBook 动态配置的深度: 不仅是 feature flag还包括事件采样率、批处理大小、sink kill switch、甚至 tengu_max_version_config 这种远程杀死特定版本的开关。


4. 解剖:遥测系统的五层架构

第一层事件生成Event Generation

事件在代码各处通过 logEvent('event_name', metadata) 生成。事件名称遵循 tengu_<领域>_<动作> 的命名规范。

// 典型的事件生成点
logEvent('tengu_tool_search_outcome', {
  query, queryType, matchCount, totalDeferredTools, maxResults, hasMatches
})

metadata 的类型约束是 { [key: string]: boolean | number | undefined } —— 禁止传递字符串,避免意外上传代码。

第二层事件增强Event Enrichment

在进入 sink 之前,每个事件被 getEventMetadata() 增强,注入:

  • 会话上下文: sessionId, clientType, isInteractive
  • 环境上下文: 操作系统、终端、包管理器、CI 检测
  • 模型信息: 当前使用的模型、betas、provider
  • 用户信息: userType, subscriptionType, userBucket
  • 进程指标: RSS, heapUsed, cpuUsage仅在 Datadog 路径)

src/services/analytics/metadata.ts 长达 966 行,是这个增强引擎的核心。

第三层采样与过滤Sampling & Filtering

事件在发送前经过多层过滤:

1. isAnalyticsDisabled()  ← 总开关
   ├── NODE_ENV === 'test'?
   ├── 3P provider (Bedrock/Vertex/Foundry)?
   └── isTelemetryDisabled()?
       ├── DISABLE_TELEMETRY?
       └── CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC?

2. shouldSampleEvent()  ← GrowthBook 动态采样
   └── tengu_event_sampling_configJSON 配置,按事件名设置采样率)

3. isSinkKilled('datadog' | 'firstParty')  ← 按 sink 单独杀死
   └── tengu_frond_boric GrowthBook 配置

4. 对 Datadog 额外白名单DATADOG_ALLOWED_EVENTS+ 非生产环境跳过

第四层事件路由Event Routing

logEventImpl()sink.ts 中将事件分发给两个后端:

logEventImpl(eventName, metadata)
  ├── shouldTrackDatadog()? → trackDatadogEvent()
  │     └── POST https://http-intake.logs.datadoghq.com/api/v2/logs
  │         批次大小: 100, 刷新间隔: 15s
  │
  └── logEventTo1P() → FirstPartyEventLoggingExporter
        └── POST https://api.anthropic.com/api/event_logging/batch
            批次大小: 200 (可配置), 刷新间隔: 10s (可配置)

第五层持久化与重试Persistence & Retry

1P 事件导出器(firstPartyEventLoggingExporter.ts806 行)具有工业级可靠性:

  • 磁盘持久化: 发送失败的事件写入 ~/.claude/telemetry/1p_failed_events.{sessionId}.{batchId}.json
  • 二次退避重试: baseDelay * attempts²,最长达 30s最多 8 次
  • 跨进程恢复: 启动时重试之前会话的失败文件
  • 分级失败处理: 一个批次失败 → 短路剩余批次 → 全部入队重试
  • 并发安全: 追加写append而非全量写避免覆盖并发事件

5. 防御:我们做了什么

5.1 纵深防御策略

我们的防御策略不是"关掉遥测"——那样会丢失学习这套系统的机会。而是在遥测管道的最前端插入一个本地分支

                  logEvent()
                      │
    ┌─────────────────┼─────────────────┐
    │                 │                 │
    ▼                 ▼                 ▼
[本地 JSONL]     [Datadog]     [Anthropic 1P]
  永远执行        可被关闭        可被关闭
  自己的数据      运维数据        BigQuery 分析

关键改动(仅 3 个文件,不改任何工具代码):

  1. src/services/analytics/localSink.ts54 行新文件)

    // 将事件追加写入 ~/.claude/local_analytics.jsonl
    export function writeLocalEvent(eventName, metadata) {
      const line = JSON.stringify({
        ts: new Date().toISOString(),
        event: eventName,
        ...metadata,
      }) + '\n'
      fs.appendFileSync(LOCAL_ANALYTICS_FILE, line, 'utf-8')
    }
    
  2. src/services/analytics/index.ts(在 logEvent() 入口处插入 3 行)

    // 在所有上游 sink 之前执行
    const { writeLocalEvent } = require('./localSink.js')
    writeLocalEvent(eventName, metadata)
    
  3. scripts/analyze_analytics.py(分析脚本)

5.2 为什么这个方案优于直接关掉遥测

方案 优点 缺点
DISABLE_TELEMETRY=1 简单,一键关闭 丢失所有数据,学不到东西
直接删除 analytics 代码 彻底 破坏代码结构,每次更新需重新修改
我们的方案:前端分叉 保留完整基础设施,数据归自己 需额外 200 行代码 + 分析工具

5.3 .gitignore 防护

# Local analytics data (never upload)
*.jsonl
.claude/

确保本地遥测数据绝不会被意外提交到仓库。


6. 为己所用

6.1 本地数据文件

~/.claude/local_analytics.jsonl —— 一行一个 JSON 事件:

{"ts":"2026-06-03T10:15:23.456Z","event":"tengu_started","sessionId":"abc123"}
{"ts":"2026-06-03T10:15:24.789Z","event":"tengu_bash_tool_used","toolName":"Bash"}
{"ts":"2026-06-03T10:15:25.012Z","event":"tengu_api_success","model":"claude-sonnet-4-20250514"}

6.2 分析脚本

# 查看事件统计报告
python3 scripts/analyze_analytics.py

# 实时追踪事件流
tail -f ~/.claude/local_analytics.jsonl

# 搜索特定事件
grep "tengu_query_error" ~/.claude/local_analytics.jsonl | python3 -m json.tool

# 按天统计使用次数
grep "tengu_started" ~/.claude/local_analytics.jsonl | wc -l

6.3 你能分析什么

分析维度 数据来源 回答的问题
工具使用频率 tengu_tool_use_* 我最常用什么工具Bash 占比多少?
模型 fallback 率 tengu_model_fallback_triggered 我的 API 稳定性如何?
上下文压缩频率 tengu_auto_compact_succeeded 我的对话是否经常超出窗口?
API 错误类型 tengu_query_error + http_status 什么类型的错误最多?
会话时长/频率 tengu_started / tengu_exit 我每天用多少次?每次多久?
工具搜索行为 tengu_tool_search_outcome 模型是否能正确找到工具?

6.4 进阶:扩展分析

因为本地 JSONL 包含所有事件的完整 metadata你可以构建

  1. 个人使用画像: 统计最常用的模型、工具组合、操作模式
  2. 成本分析: 结合 token 消耗事件,估算每日 API 费用
  3. 效率仪表板: Pandas/Streamlit 可视化,实时监控 CCB 使用
  4. 异常检测: 监控错误率突增、fallback 异常等

6.5 从 Anthropic 学习的最佳实践

这套遥测系统本身就是一个教科书级的案例:

  1. 零依赖入口 + 延迟绑定: logEvent() 无依赖sink 通过 attachAnalyticsSink() 延迟注入 —— 适合任何需要插拔式后端的系统
  2. 多层过滤链: 总开关 → 采样 → sink kill switch —— 灵活且可远程控制
  3. 磁盘兜底 + 指数退避: 即使网络失败也不丢事件
  4. 隐私类型系统: TypeScript 的 never 类型 + 标记模式强制代码审查
  5. GrowthBook 集成模式: 将 feature flag 变成数据采集工具

7. 附录:事件词典

以下是代码审计中发现的全部遥测事件(部分代表性事件):

API & Query

事件名 描述
tengu_query_error API 查询错误
tengu_api_success API 调用成功
tengu_model_fallback_triggered 触发模型降级
tengu_max_tokens_escalate Token 上限触发
tengu_token_budget_completed Token 预算耗尽
tengu_query_before_attachments 查询前 attachment 状态
tengu_query_after_attachments 查询后 attachment 状态
tengu_streaming_tool_execution_used 流式工具执行启用
tengu_streaming_tool_execution_not_used 流式工具执行未启用
tengu_post_autocompact_turn 自动压缩后的对话轮次

工具使用

事件名 描述
tengu_tool_search_outcome 工具搜索结果RL 数据)
tengu_bash_tool_used Bash 工具被调用
tengu_tool_use_success 工具调用成功
tengu_tool_use_error 工具调用错误
tengu_tool_use_granted_in_prompt_permanent 工具权限永久授予
tengu_tool_use_granted_in_prompt_temporary 工具权限临时授予
tengu_tool_use_rejected_in_prompt 工具权限拒绝

会话生命周期

事件名 描述
tengu_started 启动
tengu_init 初始化完成
tengu_exit 退出
tengu_cancel 用户取消
tengu_auto_compact_succeeded 自动压缩成功
tengu_orphaned_messages_tombstoned 孤儿消息清理

OAuth & 认证

事件名 描述
tengu_oauth_success OAuth 登录成功
tengu_oauth_error OAuth 错误
tengu_oauth_token_refresh_failure Token 刷新失败
tengu_oauth_token_refresh_success Token 刷新成功
tengu_oauth_flow_start OAuth 流程启动

遥测自监控

事件名 描述
analytics_sink_attached 遥测 sink 已连接
tengu_bridge_message_received Bridge 消息接收
tengu_ws_transport_reconnected WebSocket 重连

最后的话: 这套遥测系统的存在本身不是问题——问题在于数据的主权归属。我们的改造方案证明:你可以在不破坏基础设施的前提下,将数据的所有权从云端拉回本地。这套代码本身就是最好的教学材料:学习 Anthropic 的工程实践,掌控自己的数据,然后用这些数据来优化自己的工作流。

光明在于工程的精湛,阴影在于主权的缺失。我们选择照亮阴影,而不是关掉灯光。


文档版本v1.0 | 最后更新2026-06-03