# 为什么 Agent 工作台必须有权限、压缩和恢复？

> "权限系统、上下文压缩、会话恢复——这三个听起来像三个不相关的功能。为什么 Claude Code 在这三件事上投入了如此巨大的工程量？它们之间有什么关系？" 本章把这三者统一为 Agent 工作台的"三根安全梁"。

---

## 三根梁，缺一不可

想象你在盖一栋房子。地基打好之后（**"行动闭环"这个概念详见 Q26** ——简单说就是 "AI 能把语言变成动作、动作结果又回到决策"这个最基本的循环能力建立之后），你需要三根梁来支撑整个结构：

| 梁 | 一句话比喻 | 没有它会怎样 |
|---|----------|------------|
| **权限** | 像汽车的**安全带**——让 Agent 不敢乱来 | Agent 变成危险的自动化脚本，随时可能删库跑路 |
| **压缩** | 像汽车的**油箱**——决定 Agent 能跑多远 | Agent 只能短程对话，几轮就撑满 context window（上下文窗口），无法处理大型任务 |
| **恢复** | 像游戏的**存档点**——断电不怕丢进度 | 任何中断都意味着从头开始，之前的工作全部丢失 |

<!-- viz:start:Q27-A -->
[图表预留 Q27-A]
<!-- viz:end:Q27-A -->

> 💡 **通俗理解**：一辆车如果没有安全带，你不敢开快；如果油箱太小，跑不远；如果没有存档，熄火就得重来。Agent 工作台也一样——三者共同决定了"AI 能在真实环境中持续、安全、可靠地工作"。

**对应的 Claude Code 实现**（如果你对技术细节感兴趣，否则可以跳过这段）：

- **权限**的实现是十步权限检查链 + macOS seatbelt / Linux bubblewrap 沙箱 + PreToolUse/PostToolUse hooks + killswitch。源码主要在 `src/utils/permissions/`（24 个文件）、`src/utils/sandbox/`（沙箱配置层）、`services/tools/toolHooks.ts`（hook 调度层）
- **压缩**的实现主要是六层渐进式压缩（详见 Q02 和 Part2 第四章 查询循环）。SessionMemory（Q09）和 `/dream`（Q18 KAIROS 模式）属于**相邻但独立**的系统：前者为压缩链路提供"当前进度快照"作为重入语境，后者在夜间对日志做蒸馏。三者在数据流向上有协作（SessionMemory 的 summary 会被 `services/compact/sessionMemoryCompact.ts` 读取用于压缩决策），但在模块职责上不是同一套压缩实现的并列三件事；不要把 SessionMemory/Dream 和六层压缩直接并列。主要源码在 `compact.ts` / `microCompact` / `autocompact` / `reactiveCompact`
- **恢复**的实现是 JSONL 持久化 + File History + Bridge Pointer + `--continue`（详见 Part3 Ch11 文件历史系统 + Ch12 Bridge 远程架构）

---

## 权限：从"能做"到"安全地做"

### 为什么不是可选的

很多 AI 编码工具的权限是事后补丁——先做出能力，然后加一个确认弹窗。Claude Code 的权限是**架构级的一等公民**。

证据：`checkPermissionsAndCallTool()` 是工具执行链的**必经之路**（`toolExecution.ts`），不存在绕过权限的执行路径。连 `bypass` 模式都不能绕过 `bypass-immune` 规则（企业策略、沙箱限制）。

### 权限解决的核心矛盾

Agent 越自主（`auto` 模式，自动批准大部分操作；注意 `auto` 是源码中的 `InternalPermissionMode`——系统内部分类器状态，用户外部无法直接设置，只会由分类器路径激活），越需要精细的权限——因为用户不再逐个审批每个操作，"安全网"的质量直接决定了系统的可信度。Claude Code 的完整权限模式清单为：`default` / `plan` / `dontAsk` / `acceptEdits` / `bypassPermissions`（用户可设）+ `auto`（内部分类器）。

提一个后面会详细展开的关键词：**BashTool 投机批准**与 **YOLO 分类器批准**——它们是 `auto` 模式下"哪些命令被 AI 先放行、后日志审计"的具体机制，本章此处首次提及，详细定义与触发条件请见 Q05（权限系统如何在灵活性和安全性之间走钢丝）和 Part3 Ch02（投机执行子系统完全解析）。这里只作为定义指针，不展开。

Claude Code 用**十步状态机**解决这个矛盾：一条 10 步的责任链（全局策略 → sandbox → 模型自判断 → 用户确认），从全局策略（企业 IT 级别）到模型自判断（AI 分类器），每一步覆盖不同的风险场景。大部分同类产品只有 2-3 步（允许/拒绝/询问）。

这"十步"的展开顺序与每步具体编号（例如"第 3 步：bypass 免疫规则评估"，其中 `bypass-immune` 是源码里的关键字之一，用来表达"即使用户选了 bypass 模式也不得绕过"的规则类别，本章在 Q05 与 Part3 Ch01 权限系统完全解析中有精确命名、对应源码位置与每一步的入口函数）不在本章展开——本章只承担"三根梁"结构对比的职责。如果你需要对照源码复核这 10 步，请直接读 Part3 Ch01。

> 💡 **通俗理解**：Claude Code 的权限系统像**机场国际航班的安检流程**——你不是走一扇门就过关，而是要依次通过：查护照（企业策略）→ 过 X 光机（沙箱）→ 金属探测器（权限规则）→ 人工抽查（AI 分类器）→ 登机口最后确认（用户 Ask 模式）。大部分产品就像"小区门禁"——刷卡进就完事了，一层护栏。10 步不是冗余，是**每层防不同级别的风险**：护照防非法入境者，X 光防禁带物品，人工抽查防流程遗漏。

> 💡 **通俗理解**：权限就像高速公路的**多层护栏**——最外面是水泥隔离带（企业策略，不可翻越），中间是钢护栏（沙箱，防止冲出道路），里面是减速带（Hooks，提醒你减速）。不是一层就够——每层防的是不同级别的风险。

### 权限机制的 trade-off（同样不只有好处）

> **为了结构对称，权限也需要讨论代价**——任何安全机制都是"安全 vs 便利"的权衡，权限系统也不例外：

| 维度 | 权限越严的好处 | 权限越严的代价 |
|------|-------------|-------------|
| **用户体验** | 减少误操作 / 降低 Agent 跑飞风险 | 每次工具调用都弹窗 → 用户被打断 → 效率下降 |
| **开发调试** | 敏感操作都有审计痕迹 | 调试时反复 Ask 模式让迭代变慢 |
| **bypass 模式的诱惑** | 紧急场景可以一次性放行 | bypass 列表一旦加多 → 用户习惯点"全部允许" → 权限系统形同虚设 |
| **分类器（Auto 模式）** | AI 自判断减少用户打扰 | 分类器误判高风险操作 → 静默执行 → 事后才发现 |
| **killswitch 机制** | Anthropic 可以紧急关闭某个工具 | 中心化控制 → 单点信任锚 → 不适合完全离线场景 |

Claude Code 选择"默认相对严格 + Auto 模式智能兜底 + bypass 显式风险告知"的折中，这是一条经过权衡的中间路线——不是"越严越好"，而是"让用户在效率和安全之间有明确的 opt-in 选项"。

---

## 压缩：从"短程工具"到"长程助手"

### 为什么不是可选的

没有压缩的 AI 对话系统，context window 就是硬上限。这里的"约 200K token"是对当前 Claude Code 常用主力模型（`opus-4-6` / `sonnet-4-6` 在 first-party API 上的公开上下文窗口）的一个**数量级参照**，不同模型/不同入口的具体额度可能更高（例如 1M 上下文预览版）或更低；本章不把 200K 当严格上限，只用作"为什么需要压缩"的量级感说明。一个中等复杂的编程任务可能涉及数十个文件、数百次工具调用——即便按 200K 这个保守基线也很容易撑爆。

如果不压缩，Claude Code 就只能处理"改一个小 bug"级别的任务，而不是"重构整个模块"这种真正需要 Agent 的大型任务。

### 压缩解决的核心矛盾

压缩和 Prompt Cache 是**互相矛盾**的——压缩改写了消息历史（破坏缓存前缀），Prompt Cache 要求前缀稳定（避免 **cache miss / 未命中**，即下一次请求匹配不到之前缓存的前缀，就只能把"本该走缓存单价的历史 token"按普通单价重新计费 + 重新推理）。

Claude Code 的解决方案是**分层**：轻量压缩（`toolResultBudget` 预算裁剪、`snip` 内容剪裁）尽量不动前缀，只在后面截；重量压缩（`autocompact`）才会重写整个历史。六层从轻到重依次执行，只有前面不够用时才触发后面的——这样大部分时间 Prompt Cache 不受影响。具体"六层"包括（由轻到重示意，准确名称与边界以 Q02 / Part2 第四章为准）：`toolResultBudget` 预算裁剪、`snip` 内容剪裁、`microCompact` 局部压缩、`reactiveCompact`（按触发条件响应）、`autocompact` 自动压缩、以及用户显式触发的 `/compact` 重度压缩——本章只做索引，每一层的具体阈值与实现细节请见 **Part2 第四章 查询循环** 和 **Q02** 上下文压缩为什么需要六套机制。

> 💡 **通俗理解**：压缩就像**行李打包术**——出差一周和出差一个月，行李箱都是同一个大小（context window）。一周的量轻松装下（不需要压缩）。一个月的量就得用真空压缩袋（轻量压缩）、甚至把衣服换成一套多穿的搭配（重量压缩/autocompact）。关键是：先试轻量方案，不够再上重量方案。

---

## 恢复：从"一次性执行"到"可断点续传"

### 为什么不是可选的

现实中的 AI 编程工作不可能一口气跑完：
- 笔记本合上了（sleep）
- 网络断了
- 用户需要离开去开会
- 进程被 kill
- 机器重启

没有恢复机制，每次中断都意味着从头开始——之前做的所有工作、修改的所有文件、积累的所有上下文，全部丢失。

### 恢复解决的核心矛盾

快速恢复和完整恢复是矛盾的——完整恢复（重建整个执行状态）慢但精确，快速恢复（只恢复最近的 checkpoint）快但可能丢失中间状态。

Claude Code 的解决方案是**多层恢复**：
- **JSONL 会话**：完整的对话历史持久化（最完整但最大）
- **File History**：每轮修改前的文件快照（硬链接复用，节省空间）
- **Bridge Pointer**：crash 后的轻量级恢复指针（约 4 小时 TTL；准确时长以源码当前设置为准——本书写作时观察到的数量级即 "小时级而非分钟或天级"，具体数字的来源请在 Part3 Ch12 Bridge 远程架构对应实现中以常量名定位，本章不硬承诺 4 小时）
- **`--continue`**：先检查 live session，再查 transcript（live truth 优先）

> 💡 **通俗理解**：恢复就像游戏的**存档系统**——有自动存档（JSONL，每轮自动保存）、有快照存档（File History，修改前自动截图）、还有断点续传指针（Bridge Pointer，让 bridge 在 crash 后能接着上次的位置继续）。需要注意：Bridge Pointer 的本质是**项目目录下的一个本地 `bridge-pointer.json` 文件**（用于这台机器上 bridge 进程的断点续传），不是 Anthropic 云端的跨设备"云存档"——下方"恢复机制的 trade-off"表里也有对它"本地文件权限"的分析。把它想成"在本地桌面留一张便签提醒 bridge 上次跑到哪"更准确。

### 恢复机制的 trade-off（不能只讲好处）

> **读到这里请先停一下**：前面讲的都是恢复机制的**好处**——能保存、能回放、能续跑。但**所有技术选择都有代价**，恢复机制也不例外。接下来要讲的是它需要付出的代价。这不是在否定恢复机制，而是让你了解"为了获得这些好处，系统同时承担了哪些风险"——这是成熟工程师看系统的方式，也是本书的写作纪律（每个设计都要同时讨论好处和代价）。

恢复能力的每一层都有对应的代价，Agent 工作台必须同时管理这些代价：

| 恢复机制 | 价值 | 代价 |
|---------|------|------|
| **JSONL 会话持久化** | 完整对话可回溯 | **敏感信息落盘**：会话日志里可能包含 API key 片段、模型看过的 secrets、工具调用返回的敏感文件内容。JSONL 文件（实际路径一般在 `~/.claude/projects/<sanitized-project-path>/<session-id>.jsonl`——此前本章引用的 `~/.claude/logs/session_*.jsonl` 与常见实际布局不一致，以 `projects/` 目录为准；其它可能存在的 log 目录请以当前版本 `~/.claude/` 下的实际目录为准）本质上是 persistent secret exposure——任何有本地读权限的进程都能扫这些日志找敏感信息 |
| **File History 快照** | `/rewind` 可回滚任意修改 | **硬链接 + 权限语义要理清**：硬链接的原始含义是"两个路径指向同一个 inode"——这让"快照"和"原文件"共享**同一份内容**；严格地讲，只要其中一方被"同地修改"（in-place edit，如 `sed -i`），另一方看到的内容也会变，这就与"快照可回滚"的语义发生冲突。Claude Code 依赖**编辑工具的写策略**（例如先写到临时文件再 rename / 原子替换）来保证两个 inode 解耦，从而让硬链接既节省空间又维持快照语义。这套依赖关系意味着：如果某条 sudo 命令绕过 Claude Code 的编辑链路、直接在原文件上 in-place 覆盖，快照也会同步被改动，语义就不再成立——这是"硬链接快照"这一设计要留心的边界 |
| **Bridge Pointer** | crash 后快速恢复 | **pointer 文件权限与身份核验**：pointer 文件在 crash 后残留在项目目录，如果权限设置过宽，其他本地进程可以读到并"接管"该会话。本章建议生产部署时核对 `bridge-pointer.json` 的文件权限——**理想值是 `0600`（只有所有者可读写），而非 `0644`（组与其他用户可读）**。这里的 `0600` / `0644` 是对"正确 vs 错误的权限模式"的推荐数字，而**非**本章已验证过的源码常量：本书未在 bridge 相关实现里直接定位到 chmod 的具体位数，请在生产部署前以 `ls -l bridge-pointer.json` 实际核验为准 |
| **`--continue` 的 live truth** | 先信活的不信故纸堆 | **本地多实例识别的攻击面**：本地进程可以伪装成 live session 欺骗 `--continue`。如果 PID registry 的写入权限过宽，一个恶意进程可以注册一个假 session 让用户的 `--continue` 误入 |

Agent 工作台不是"恢复能力越多越好"——而是要同时管理好**恢复价值**和**暴露代价**。本书在源码层面只能看到机制存在，具体的权限/审计参数需要读者在生产部署时独立核验。

---

## 三者的协同关系

三根梁不是各自独立的——它们之间有精确的协同关系：

| 协同 | 说明 |
|------|------|
| 权限 + 压缩 | 压缩会让很多启发式缓存失效（BashTool 投机批准、YOLO 分类器批准、memory file 缓存、session message 缓存等）。`postCompactCleanup.ts` 负责在压缩后**清理这些被失效的追踪型缓存**，防止旧的决策结论被错误地应用到新的消息历史上 |
| 权限 + 恢复 | 用户在会话中设置的权限模式（`acceptEdits` / `bypassPermissions` / `plan` / `dontAsk`）需要在恢复时被正确处理。注：源码中 `auto` 是 InternalPermissionMode，属于系统内部分类器状态而非用户可设置的外部模式 |
| 压缩 + 恢复 | autocompact 成功后，压缩后的消息通过 `buildPostCompactMessages()` 直接拼回当前 turn——不需要重建会话 |
| 三者共同 | 它们共同定义了"Agent 的工作续航能力"——权限决定能走多远（安全边界内），压缩决定能跑多久（context 不溢出），恢复决定能断几次（中断不丢失） |

---

## 行业对比

> ⚠️ **对比口径说明**：下表为本文截至 2026-04 的定性归纳，仅反映**各产品公开文档/开源仓库能直接读到的架构层面能力**，不等价于严格的功能级 benchmark。"步数" 仅统计产品默认流程中"权限分支判断点"的量级（非精确数字）；"无" 指公开资料中未见到独立设计的对应模块，并非否认产品的任何确认/回滚能力（例如 Aider 具备 `y/n` 基础确认和 `--auto-commits` 等）。竞品实际行为随版本变化，详情以官方最新文档为准。

| 维度 | Claude Code | Cursor | Aider | OpenCode |
|------|-------------|--------|-------|----------|
| 权限检查步数 | **10 步状态机** | 2-3 步 | 基础 y/n 确认 | 1 步 |
| 压缩策略 | **6 层渐进** | context 截断 | repo map 替代 | 简单截断 |
| 恢复机制 | **JSONL + Pointer + --continue** | Composer 级别 checkpoint | 依赖 Git 历史（未见独立恢复模块） | 未见独立恢复模块 |
| 综合续航 | 长程复杂任务 | 中程编辑任务 | 短程修改 | 短程修改 |

> 💡 **通俗理解**：Claude Code 是装甲越野车（权限厚、油箱大、有存档），Cursor 是城市 SUV（权限够用、油箱适中、没存档），Aider 是轻便摩托车（没权限、省油但跑不远、摔了就摔了）。选哪个取决于你要跑什么路——城市通勤（简单编辑）还是穿越沙漠（长程复杂任务）。

---

### 本章的意义

Q26 回答的是"**Claude Code 为什么能像 Agent**"——给出六个结构条件。Q27 回答的是"**Agent 工作台为什么必须同时有权限、压缩和恢复**"——给出三根梁的必要性。这两个问题合在一起，构成了**对 Agent 工作台完整性**的论证：

- 如果只有行动闭环没有治理（只有 Q26 的条件 1，没有 Q27 的权限梁），Agent 就是不安全的
- 如果只有治理没有续航（没有 Q27 的压缩梁），Agent 就是短命的
- 如果只有续航没有恢复（没有 Q27 的恢复梁），Agent 就是脆弱的

这是 Claude Code 与其他同类产品最核心的设计哲学差异——**它不是在"让 AI 更智能"，而是在"让 AI 能可靠地持续工作"**。
