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
This commit is contained in:
James Feng 2026-06-04 21:03:57 +08:00
parent f2df2d7d85
commit 7eb5530b2c
2 changed files with 471 additions and 2 deletions

View File

@ -77,6 +77,8 @@ CC Pure 基于 CCB v2.6.6 反编译源码,做了以下核心变更:
| 版本 | 日期 | 合并数 | 说明 |
|------|------|:------:|------|
| v2.2.2 | 2026-06-04 | 16 文件 | **Autonomy 全量合并**f2e9af49 PR #386 源码 + 11 测试文件3699 pass |
| v2.2.1 | 2026-06-04 | 2 | OpenAI fixes backfillc82f5994 (stop_reason/usage/max_tokens) + 901628b4 (MCP 工具可见性) |
| v2.2.0 | 2026-06-04 | 2 | Batch 1a 安全加固 + ad09f38f 斜杠补全 |
| v2.1.0 | 2026-06-04 | 2 | REVIEW 24 执行完毕 |
| v2.0.0 | 2026-06-04 | 12 | P3 A 完成 |
@ -134,7 +136,7 @@ tail -f ~/.claude/local_analytics.jsonl
| 指标 | CCB 基线 | CC Pure 当前 | 提升 |
|------|:--------:|:----------:|:----:|
| tsc 错误 | 62 | **0** | ✅ |
| 测试通过 | 3007 | **3383** | +376 |
| 测试通过 | 3007 | **3699** | +692 |
| 构建 | 不稳定 | **稳定splitting: true** | ✅ |
| 遥测外连 | 有 | **0** | ✅ |
| CodeQL open | 175+ | **0** | ✅ |
@ -161,7 +163,7 @@ tail -f ~/.claude/local_analytics.jsonl
bun install
bun run dev # 开发模式(默认全 feature 开启)
bun run build # 生产构建
bun test # 3383 tests
bun test # 3699 tests
```
---

View File

@ -0,0 +1,467 @@
# Claude Code 的光明和阴影面
> **副标题:** Anthropic 遥测系统的逆向工程、纵深防御与自用改造
>
> **作者:** James Feng基于 CC_Pure 代码库逆向分析2026年6月
>
> **标签:** `逆向工程` `遥测` `隐私` `GrowthBook` `OpenTelemetry` `数据分析`
---
## 目录
1. [前言:为什么要写这篇文章](#1-前言)
2. [光明面:一套工业级的数据工厂](#2-光明面)
3. [阴影面:数据去哪了](#3-阴影面)
4. [解剖:遥测系统的五层架构](#4-解剖)
5. [防御:我们做了什么](#5-防御)
6. [为己所用:如何让这套系统服务于你](#6-为己所用)
7. [附录:事件词典](#7-附录)
---
## 1. 前言
Claude Code内部代号 "tengu")是 Anthropic 的终端 AI 编程助手。它不仅仅是一个命令行工具——它是一套完整的**数据采集和分析基础设施**。每当你输入一个命令、调用一个工具、触发一次 API 请求,几十个遥测事件在后台被捕获、采样、路由和上报。
本文基于对 **CC_Pure**Claude Code 反编译还原项目)的深度代码审计,完整拆解这套遥测系统:
- 它收集了什么?
- 数据流向了哪里?
- 我们如何发现并防御?
- 更重要的是,**我们如何把它变成自己的利器**
> **核心结论:** Anthropic 的遥测基础设施本身就是一套值得学习的工业级数据工程范例。我们不需要摧毁它——我们需要**接管它**。
---
## 2. 光明面
### 2.1 工程设计的精妙之处
Claude Code 的遥测系统不是简单的埋点+上报。它是一套分层架构:
```
logEvent()
├── 本地 JSONL 写入(我们加的防御层)
├── 事件队列sink 未初始化时的缓冲)
├── GrowthBook 动态采样(云端控制的抽样引擎)
├── Datadog 监控(运维告警)
└── 1P 事件上报Anthropic 内部 BigQuery 分析)
```
**亮点 1零依赖入口设计**
`logEvent()` 函数(`src/services/analytics/index.ts`)本身没有任何模块级依赖。所有事件先进入队列,等 `attachAnalyticsSink()` 在应用初始化时被调用后才真正路由到后端。这个设计避免了循环依赖,也让测试变得极其容易。
```typescript
// 精妙:零依赖的入口
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` 不仅是一个工具搜索功能,它是一台**强化学习数据收集机器**
```typescript
// 搜索评分权重(精确调优的参数)
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`:用户的搜索词
- `queryType``select` 或 `keyword`
- `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/traces`CLAUDE_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_<领域>_<动作>` 的命名规范。
```typescript
// 典型的事件生成点
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.ts`**806 行**)具有工业级可靠性:
- **磁盘持久化:** 发送失败的事件写入 `~/.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.ts`**54 行新文件)
```typescript
// 将事件追加写入 ~/.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 行)
```typescript
// 在所有上游 sink 之前执行
const { writeLocalEvent } = require('./localSink.js')
writeLocalEvent(eventName, metadata)
```
3. **`scripts/analyze_analytics.py`**(分析脚本)
### 5.2 为什么这个方案优于直接关掉遥测
| 方案 | 优点 | 缺点 |
|------|------|------|
| `DISABLE_TELEMETRY=1` | 简单,一键关闭 | 丢失所有数据,学不到东西 |
| 直接删除 analytics 代码 | 彻底 | 破坏代码结构,每次更新需重新修改 |
| **我们的方案:前端分叉** | 保留完整基础设施,数据归自己 | 需额外 200 行代码 + 分析工具 |
### 5.3 .gitignore 防护
```gitignore
# Local analytics data (never upload)
*.jsonl
.claude/
```
确保本地遥测数据绝不会被意外提交到仓库。
---
## 6. 为己所用
### 6.1 本地数据文件
`~/.claude/local_analytics.jsonl` —— 一行一个 JSON 事件:
```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 分析脚本
```bash
# 查看事件统计报告
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*