# 附录 II:后台智能与持续学习
> 真正优秀的工具会悄悄变得更懂你——不是因为它在监视你,而是因为它在陪你工作。
---
## 附录 II-A:Magic Docs(活文档自动维护)
### 功能描述
标记了特殊头部的 Markdown 文件会被 Claude Code **自动维护更新**。每次主循环结束后(Agent 产生最终回复时),系统在后台悄悄用 forked subagent 将最新的对话洞察写回文档——无需任何人工干预。
### 触发机制
```
用户读取文件(FileReadTool)
│
├─ detectMagicDocHeader() 检测文件首行是否为:
│ # MAGIC DOC: <title>
│
├─ 是 Magic Doc → 注册到 trackedMagicDocs(Map<path, MagicDocInfo>)
│
└─ 每次主循环产生最终响应后(无工具调用)
↓
registerPostSamplingHook 触发
↓
对每个 trackedMagicDocs 中的文件,派生 subagent 执行更新
```
**Magic Doc 头部格式**(文件首行):
```markdown
# MAGIC DOC: Architecture Overview
_This document tracks the evolving architecture decisions._
## 概念层
...(文档正文)
```
- 第一行:`# MAGIC DOC: <title>`
- 第二行(可选):斜体文字作为更新指令(告诉 subagent 如何更新)
### 核心文件
| 文件 | 作用 |
|------|------|
| `src/services/MagicDocs/magicDocs.ts` | 主逻辑:检测 + 注册 + 触发更新 |
| `src/services/MagicDocs/prompts.ts` | `buildMagicDocsUpdatePrompt()`:构建发给 subagent 的更新提示词 |
### 关键设计
**只读检测,不主动写入**:`registerFileReadListener` 监听 `FileReadTool`,只记录"这个文件是 Magic Doc",实际更新由 `registerPostSamplingHook` 在对话轮次结束后异步触发。
**串行更新防冲突**:多个 Magic Doc 文件用 `sequential()` 依次更新,避免并发写入冲突。
**subagent 权限**:更新 subagent 只有 `FILE_EDIT_TOOL_NAME` + `FileReadTool` 权限——能读写文档,但无法执行 bash 或修改其他文件。
**典型用途**:`ARCHITECTURE.md`、`API.md`、`DECISIONS.md` 等随开发节奏同步更新的活文档。
---
## 附录 II-B:Away Summary(离开摘要)
### 功能描述
用户离开后再回来(如重新聚焦终端窗口),Claude Code 展示一张"您离开时的进展"卡片:1-3 句话概括当前任务状态和下一步行动。
### 实现细节
**核心文件**:`src/services/awaySummary.ts`
```typescript
// 只看最近 30 条消息,避免超长 session 出现 "prompt too long" 错误
const RECENT_MESSAGE_WINDOW = 30
// 使用小型快速模型生成,避免阻塞用户输入
const model = getSmallFastModel() // Haiku 级别
// Prompt 约束(硬编码在 buildAwaySummaryPrompt()):
// - 写 1-3 句话
// - 先说"在做什么"(高层任务),再说"下一步"
// - 禁止状态报告和 commit 摘要
```
**输入来源**:
- 最近 `RECENT_MESSAGE_WINDOW = 30` 条对话消息
- Session Memory 内容(`getSessionMemoryContent()`),提供更宏观的任务背景
**触发条件**:用户离开超过阈值时间后首次输入时触发(具体阈值由调用方控制,`awaySummary.ts` 本身只负责生成内容)。
**摘要格式(Prompt 约束)**:
```
正确示例:
"You're building a REST API for user authentication.
Next: implement the JWT refresh token endpoint."
错误示例(被 Prompt 明确禁止):
"Status: Completed task 3. Committed: a1b2c3d." ← 禁止状态报告
"You ran npm install and edited package.json." ← 禁止实现细节
```
---
## 附录 II-C:Prompt Suggestion + Speculation(预测执行)
### 功能描述
两层"预测"机制,在用户思考下一步时提前计算,目标是**减少等待时间(TTFT)**:
- **Prompt Suggestion**:主 Agent 回复后,立即预测"用户下一条消息",作为输入框建议展示
- **Speculation(推测执行)**:如果预测置信度够高,提前用只读工具预跑文件读取,用户确认发送后直接复用结果
### 架构图
```
主 Agent 产生响应
│
├─ [Prompt Suggestion]
│ runForkedAgent(只读模式)
│ 预测"用户下一步会说什么"
│ → 结果存入 AppState.promptSuggestion
│ → UI 在输入框展示建议
│
└─ [Speculation]
用户开始输入(输入内容与预测匹配)
│
├─ 对 SAFE_READ_ONLY_TOOLS(Read/Glob/Grep/LSP/TaskList)提前执行
├─ 结果写入 overlay 目录(getOverlayPath(id))
│
├─ 用户确认发送 → 合并 overlay 文件缓存到真实 messages → 节省 TTFT
└─ 预测失败(输入不匹配)→ safeRemoveOverlay() 丢弃,重新执行
```
### 核心文件
| 文件 | 作用 |
|------|------|
| `src/services/PromptSuggestion/promptSuggestion.ts` | Prompt Suggestion 主逻辑,`generateSuggestion()`、`shouldEnablePromptSuggestion()` |
| `src/services/PromptSuggestion/speculation.ts` | Speculation 主逻辑:overlay 创建/合并/清理 |
### 关键常量与限制
```typescript
// speculation.ts
const MAX_SPECULATION_TURNS = 20 // 最多推测 20 轮工具调用
const MAX_SPECULATION_MESSAGES = 100 // 最多产生 100 条消息
// Speculation 只对以下只读工具有效:
const SAFE_READ_ONLY_TOOLS = [
FileReadTool, GlobTool, GrepTool, LSPTool, TaskListTool
]
// BashTool 等有副作用的工具在 Speculation 阶段被明确禁止
```
### 特性门控
- Prompt Suggestion:环境变量 `CLAUDE_CODE_ENABLE_PROMPT_SUGGESTION`,或 Statsig 特性 `tengu_chomp_inflection`
- Speculation:由 `isSpeculationEnabled()` 检查,在 Swarm 模式的 Teammate 中自动禁用(避免干扰协调逻辑)
---
## 附录 II-D:Settings Sync & Team Memory Sync
### 功能描述
两个独立的云同步机制:
- **Settings Sync**:在多台机器间同步用户的 Claude Code 配置
- **Team Memory Sync**:在同一 git 仓库的团队成员间共享 `team-memory/` 目录(MEMORY.md、记忆文件等)
### Settings Sync
**核心文件**:`src/services/settingsSync/index.ts`、`types.ts`
**特性门控**:`feature('UPLOAD_USER_SETTINGS')` / `feature('DOWNLOAD_USER_SETTINGS')`
**工作流程**:
```
上传(UPLOAD_USER_SETTINGS):
读取本地 ~/.claude/settings.json
对比 serverChecksums(只上传内容有变更的 key)
→ POST /api/settings (delta 上传,节省带宽)
下载(DOWNLOAD_USER_SETTINGS):
→ GET /api/settings
合并到本地 settings(服务端内容覆盖本地)
常见场景:IDE 插件首次安装,先拉取云端配置再启动
```
### Team Memory Sync
**核心文件**:`src/services/teamMemorySync/`(5 个文件)
**特性门控**:`feature('TEAMMEM')`
**工作流程**:
```
标识仓库:
SHA256(git remote URL) → 仓库唯一 ID
上传(watcher.ts 监听 team-memory/ 目录变化):
1. secretScanner.ts 扫描内容(见下方密钥检测)
2. 对比 serverChecksums → 只上传有变更的 key(delta 上传)
3. POST /api/team-memory/<repo-id>
拉取:
GET /api/team-memory/<repo-id>
服务端内容覆盖本地(server wins)
本地删除的文件不会同步到服务端(非破坏性)
文件监听(watcher.ts):
chokidar 监听 team-memory/ 目录
文件变化 → 防抖 → 触发上传
```
**Secret Scanner(`teamMemSecretGuard.ts`)**:
上传前用高置信度规则扫描文件内容,发现以下密钥时**拒绝上传**并提示用户:
- Anthropic API key
- AWS access token / secret key
- GitHub Personal Access Token (PAT)
- GCP Service Account key
- Slack token
此外,`FileWriteTool` / `FileEditTool` 在 `validateInput` 阶段也会调用 `checkTeamMemSecrets()`,在 Agent 写入 `team-memory/` 前拦截密钥——双重防护。
---
## 附录 II-E:Commit Attribution(提交归因)
### 功能描述
追踪 git commit 中哪些代码行是由 Claude Code 生成的,并在 commit message 尾部添加标准 trailer 标注来源。
**特性门控**:`feature('COMMIT_ATTRIBUTION')`
**核心文件**:`src/utils/commitAttribution.ts`
### 工作流程
```
Agent 修改/创建文件(FileEditTool / FileWriteTool)
│
├─ 记录 AttributionSnapshot:
│ { filePath, lineRanges, sessionId, timestamp }
│
└─ 用户(或 Agent)执行 git commit
│
├─ calculateCommitAttribution() 计算 AI 生成比例
│
└─ 在 commit message 末尾追加 trailer:
Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Code-Session: <session-uuid>
```
**内部仓库额外追加**(仅 `INTERNAL_MODEL_REPOS` allowlist 中的私有仓库):
```
Claude-Code-Model: <internal-codename>
```
### Undercover 模式(内部仓库保护)
```typescript
// commitAttribution.ts 中 INTERNAL_MODEL_REPOS 的注释说明:
// NOTE: This is intentionally a repo allowlist, not an org-wide check.
// The anthropics and anthropic-experimental orgs contain PUBLIC repos
// (e.g. anthropics/claude-code, anthropics-experimental/sandbox-runtime).
// Undercover mode must stay ON in those to prevent codename leaks.
// Only add repos here that are confirmed PRIVATE.
```
公开仓库(包括 `anthropics/claude-code` 本身)保持"undercover 模式",不在 commit message 中暴露内部模型代号。
---
## 附录 II 源码快速导航
```
后台智能与持续学习
├── Magic Docs(活文档)
│ └── src/services/MagicDocs/
│ ├── magicDocs.ts ← 检测 MAGIC DOC 头、注册、触发后台更新
│ └── prompts.ts ← buildMagicDocsUpdatePrompt()
│
├── Away Summary(离开摘要)
│ └── src/services/awaySummary.ts
│ └── generateAwaySummary() ← 小模型生成 1-3 句摘要
│
├── Prompt Suggestion + Speculation(预测执行)
│ └── src/services/PromptSuggestion/
│ ├── promptSuggestion.ts ← 预测用户下一步意图
│ └── speculation.ts ← 只读工具提前执行 + overlay 管理
│
├── Settings Sync(配置云同步)
│ └── src/services/settingsSync/
│ ├── index.ts ← 上传/下载 settings
│ └── types.ts ← 同步协议类型
│
├── Team Memory Sync(团队记忆同步)
│ └── src/services/teamMemorySync/
│ ├── index.ts ← 同步核心逻辑(delta 上传/拉取)
│ ├── watcher.ts ← 文件变化监听 + 防抖触发
│ ├── teamMemSecretGuard.ts ← 写入拦截(tool 层防护)
│ └── secretScanner.ts ← 密钥扫描(gitleaks 规则子集)
│
└── Commit Attribution(提交归因)
└── src/utils/commitAttribution.ts
├── calculateCommitAttribution() ← AI 行比例计算
└── INTERNAL_MODEL_REPOS ← 允许暴露内部代号的私有仓库白名单
```
---
→ [附录 III:运行时安全与治理](appendix-III-security)