## Plan 模式深度指南

你有没有过这样的经历：让 Claude Code 帮你修改代码，结果它一顿操作猛如虎，改了十几个文件，最后发现方向跑偏了？或者改到一半发现漏考虑了某个依赖，不得不撤销重来？

Plan 模式就是为解决这些问题而生的。它让 Claude 先制定详细的执行计划，你审核通过后再动手，把"先射箭再画靶"变成"谋定而后动"。

## 什么是 Plan 模式

### Plan 模式 vs 普通模式

在普通模式下，Claude Code 会一边思考一边执行：分析代码、编辑文件、运行命令，这些动作是交替进行的。这对简单任务来说非常高效，但对复杂任务可能导致"走一步看一步"的问题。

Plan 模式则完全不同：

| 特性 | 普通模式 | Plan 模式 |
|------|---------|----------|
| 执行方式 | 边思考边执行 | 先规划，审核后再执行 |
| 文件操作 | 会立即读写文件 | **只读不写**，仅分析和搜索 |
| 命令执行 | 可能直接运行命令 | 不执行任何修改性命令 |
| 适合场景 | 简单修改、快速修复 | 多文件重构、复杂功能开发 |
| 风险控制 | 依赖权限系统 | 计划阶段零风险 |

简单来说，Plan 模式下的 Claude 就像一个只带笔记本的建筑师 — 它会仔细勘察现场（读代码、搜索文件），画出详细的施工图纸（执行计划），但绝不会搬一块砖。

### 为什么需要先规划再执行

先规划再执行的好处远不止"安全"这一条：

1. **全局视角**：Claude 会先扫描所有相关文件，建立整体认知，而不是改到一半才发现遗漏
2. **方案可审**：你可以在执行前审查计划，发现潜在问题，提出修改意见
3. **减少返工**：计划阶段就能发现依赖冲突、接口不一致等问题
4. **知识对齐**：通过阅读计划，你能了解 Claude 对项目的理解是否正确
5. **可复用**：好的计划可以保存下来，作为类似任务的参考模板

### 哪些场景适合用 Plan 模式

**强烈建议使用 Plan 模式的场景：**
- 涉及 5 个以上文件的修改
- 需要修改核心模块或公共接口
- 添加新功能（特别是涉及数据库、API 等）
- 重构现有代码结构
- 修复原因不明的 Bug（需要先排查）
- 你对项目还不够熟悉，需要 Claude 先帮你理清结构

**可以直接用普通模式的场景：**
- 修复一个明确的小 Bug
- 修改单个文件的局部内容
- 添加注释或文档
- 简单的格式化或重命名

## 如何使用 Plan 模式

### 用 Shift+Tab 切换模式

启动 Plan 模式非常简单。在 Claude Code 的输入框中，按下 `Shift+Tab` 即可循环切换模式：

```
default → acceptEdits → plan → bypassPermissions → default → ...
```

当你看到输入框左侧的模式指示器显示 **plan** 时，就已经进入 Plan 模式了。

你也可以在输入提示词时直接说明想要规划：

```
请先帮我制定一个计划，不要直接修改代码。我想给用户系统添加邮箱验证功能。
```

> **提示**：按 `Escape` 可以随时退回到默认模式。

### Plan 模式下 Claude 的行为

进入 Plan 模式后，Claude 的能力会受到限制：

**可以做的事：**
- 读取任意文件
- 搜索代码（Grep、Glob）
- 分析项目结构
- 查看 Git 历史
- 搜索网络信息
- 生成详细的执行计划

**不会做的事：**
- 创建或修改文件
- 执行可能产生副作用的命令
- 安装依赖包
- 运行构建或测试

这意味着你可以放心地在 Plan 模式下让 Claude 探索任何代码，完全不用担心它会"手滑"改了什么。

### 查看和编辑计划

Claude 生成的计划通常包含以下结构：

```markdown
## 执行计划：添加邮箱验证功能

### 目标
为用户注册流程添加邮箱验证环节。

### 影响分析
- 需要修改的文件：6 个
- 需要新建的文件：3 个
- 数据库变更：需要新增 1 张表
- 风险点：现有用户不受影响，但需要添加迁移脚本

### 执行步骤

**第一阶段：数据库层**
1. 创建 `email_verifications` 表的迁移脚本
2. 修改 `users` 表，添加 `email_verified` 字段

**第二阶段：后端逻辑**
3. 新建 `email_verification_service.py`
4. 修改 `auth_router.py`，添加验证相关接口
5. 修改 `user_service.py`，注册流程中触发验证邮件

**第三阶段：前端适配**
6. 修改注册页面，添加验证提示
7. 新建邮箱验证页面
8. 修改路由配置

### 风险和注意事项
- SMTP 配置需要预先准备
- 需要考虑验证链接的过期时间
- 已存在的用户需要跳过验证
```

你可以对计划提出修改意见：

```
计划总体不错，但有几点调整：
1. 不需要新建验证页面，用现有的 toast 提示就行
2. 验证链接过期时间设为 24 小时
3. 第一阶段先不改 users 表，用 email_verifications 表的状态来判断
请更新计划。
```

Claude 会根据你的反馈修改计划，直到你满意为止。

### 批准计划后开始执行

确认计划无误后，切换回普通模式（按 `Shift+Tab`），然后告诉 Claude 执行计划：

```
计划看起来没问题了，请按照计划开始执行。从第一阶段开始。
```

你也可以选择分阶段执行：

```
先执行第一阶段（数据库层），完成后停下来让我验证。
```

## Plan 模式实战教程

### 示例 1：为现有项目添加用户认证

假设你有一个 FastAPI 项目，目前没有任何认证机制，需要添加 JWT 认证。

**第一步：切换到 Plan 模式，描述需求**

```
我的 FastAPI 项目目前没有用户认证。请帮我制定一个计划，添加基于 JWT 的用户认证系统。
要求：
- 用户注册和登录
- JWT Token 签发和验证
- 路由保护（部分接口需要登录）
- 用 SQLAlchemy 管理用户表
请先分析现有代码结构，然后制定详细的执行计划。
```

**第二步：Claude 分析项目并生成计划**

Claude 会先扫描你的项目结构：

```
我已经分析了你的项目结构。以下是我的发现和执行计划：

## 项目现状分析
- 框架：FastAPI 0.115.x
- 数据库：已有 SQLAlchemy 配置（database.py），使用 PostgreSQL
- 现有模型：Product、Order（在 models/ 目录下）
- 路由：product_router.py、order_router.py（均无认证保护）
- 依赖管理：使用 requirements.txt

## 执行计划

### 第一阶段：基础设施（2 个文件）
1. 在 requirements.txt 中添加 python-jose[cryptography]、passlib[bcrypt]
2. 在 config.py 中添加 JWT 相关配置项（SECRET_KEY、ALGORITHM、TOKEN_EXPIRE）

### 第二阶段：用户模型和数据库（2 个文件）
3. 新建 models/user.py — User 模型
4. 新建 alembic 迁移脚本

### 第三阶段：认证逻辑（3 个文件）
5. 新建 services/auth_service.py — 密码哈希、JWT 签发/验证
6. 新建 schemas/auth.py — 请求/响应模型
7. 新建 routers/auth_router.py — /register、/login、/me 接口

### 第四阶段：路由保护（3 个文件）
8. 新建 dependencies/auth.py — get_current_user 依赖
9. 修改 product_router.py — 写操作需要认证
10. 修改 order_router.py — 所有操作需要认证

### 风险提示
- config.py 中的 SECRET_KEY 必须使用环境变量，不能硬编码
- 现有的 API 客户端需要适配认证头
- 建议先在测试环境验证
```

**第三步：审核并执行**

```
计划很好。两个调整：
1. 不用 alembic，直接用 SQLAlchemy 的 create_all
2. product_router 的读操作不需要认证，只有创建和删除需要
其他没问题，请按计划执行。
```

### 示例 2：重构大型模块

假设你的项目中有一个 3000 行的 `utils.py` 文件，需要拆分重构。

**进入 Plan 模式：**

```
utils.py 已经膨胀到 3000 行了，里面什么都有。请帮我分析这个文件，制定一个重构计划，
把它拆分成多个职责清晰的模块。要求：
1. 分析 utils.py 中所有函数的职责分类
2. 设计新的模块结构
3. 列出所有引用了 utils.py 的文件及其受影响的导入
4. 确保重构后所有现有功能不受影响
```

Claude 会生成类似这样的计划：

```
## utils.py 重构计划

### 现状分析
utils.py 包含 47 个函数，分析其职责后可分为 5 类：

| 类别 | 函数数量 | 示例函数 |
|------|---------|---------|
| 字符串处理 | 12 | slugify, truncate, sanitize_html |
| 日期时间 | 8 | parse_date, format_datetime, get_timezone |
| 文件操作 | 9 | read_file, ensure_dir, get_file_hash |
| 数据验证 | 11 | validate_email, validate_phone, check_url |
| HTTP 工具 | 7 | retry_request, parse_response, build_url |

### 引用分析
共有 23 个文件导入了 utils.py，详细清单如下：
（列出每个文件及其使用的具体函数...）

### 新模块结构
utils/
├── __init__.py      # 保持向后兼容的重导出
├── strings.py       # 字符串处理
├── datetime.py      # 日期时间
├── files.py         # 文件操作
├── validators.py    # 数据验证
└── http.py          # HTTP 工具

### 执行步骤
（分步骤列出...）

### 向后兼容策略
在 utils/__init__.py 中保留所有原有导出：
from .strings import *
from .datetime import *
...
这样即使有未被发现的引用也不会出错。
```

### 示例 3：修复跨多文件的 Bug

用户反馈"订单金额偶尔会计算错误"，但你不确定问题在哪。

**进入 Plan 模式：**

```
用户反馈订单金额偶尔计算错误，但不是每次都错。请帮我排查这个问题：
1. 找到所有涉及金额计算的代码
2. 分析可能导致偶发性错误的原因
3. 制定修复计划
```

Claude 会在 Plan 模式下深入分析：

```
## Bug 排查报告

### 金额计算相关代码
经过全面搜索，涉及金额计算的代码分布在 4 个文件中：
- order_service.py:calculate_total() — 主要计算逻辑
- discount_service.py:apply_discount() — 折扣计算
- tax_service.py:calculate_tax() — 税费计算
- cart_service.py:get_cart_total() — 购物车合计

### 发现的问题
**根本原因：浮点数精度问题**

在 order_service.py 第 127 行：
  total = sum(item.price * item.quantity for item in items)

Python 的浮点数运算存在精度问题：
  >>> 0.1 + 0.2
  0.30000000000000004

当订单包含多个小数金额的商品时，累积误差可能导致最终金额偏差 1 分钱。

**次要问题：折扣计算顺序**
discount_service.py 的折扣计算在 tax_service.py 的税费计算之后执行，
但在某些并发场景下，顺序可能颠倒（因为两者是异步调用的）。

### 修复计划
1. 将所有金额计算改为 Decimal 类型
2. 修改 discount 和 tax 的调用顺序为同步串行
3. 添加金额一致性的单元测试
```

这个例子展示了 Plan 模式在 Bug 排查中的价值 — Claude 不会急着改代码，而是先做彻底的分析。

## Plan 模式最佳实践

### 1. 描述"为什么"而不是"怎么做"

**不推荐的写法：**

```
请在 user.py 中添加一个 verify_email 方法，接受 token 参数，
查询 email_verifications 表，如果 token 匹配且未过期就把
user.email_verified 设为 True。
```

**推荐的写法：**

```
我们需要让用户能够验证自己的邮箱地址。用户注册后会收到一封
包含验证链接的邮件，点击链接后邮箱状态变为已验证。请帮我
规划实现方案。
```

为什么？因为当你描述"为什么"时，Claude 有更大的空间来设计最优方案。也许它会发现你没想到的边界情况，或者提出更优雅的实现方式。如果你把具体实现都写好了，那 Plan 模式的价值就大打折扣了。

### 2. 在计划中要求 Claude 识别风险点

主动要求 Claude 分析风险：

```
请在计划中特别关注：
1. 这次修改可能破坏哪些现有功能？
2. 有没有需要同步修改的配置文件？
3. 数据库变更是否需要迁移脚本？
4. 是否有并发安全的考虑？
```

### 3. 分阶段执行复杂计划

对于大型任务，不要一口气执行整个计划。把它拆成可独立验证的阶段：

```
这个计划有 4 个阶段，请按以下方式执行：
- 每完成一个阶段就停下来
- 告诉我该阶段的完成情况
- 等我确认后再继续下一阶段
```

这样做的好处是：如果某个阶段出了问题，你可以及时纠正，不用回滚大量改动。

### 4. 计划与 Git 分支结合

最佳工作流是：**Plan 模式制定计划 → 创建新分支 → 在新分支上执行 → 代码审查 → 合并**

```
# 先在 Plan 模式下制定计划
（切换到 Plan 模式，描述需求，审核计划）

# 满意后，切换回普通模式
请先创建一个新分支 feature/email-verification，然后按计划执行。
```

如果执行过程中发现计划不对，你随时可以回到 main 分支重来。

## Plan 模式 vs 直接编码

### 什么时候不需要 Plan 模式

- 修改一两个文件的简单任务
- 明确知道要改哪里、怎么改
- 添加注释、修改文案等非功能性改动
- 运行命令（如安装依赖、运行测试）

### 什么时候必须用 Plan 模式

- 涉及 5 个以上文件的变更
- 修改公共接口或核心模块
- 你对项目结构还不够了解
- Bug 原因不明，需要先排查
- 需要评估多种方案的取舍

### 决策参考

```
你的任务是什么？
│
├─ 简单修改（1-2 个文件，方向明确）
│   → 普通模式，直接开始
│
├─ 中等任务（3-5 个文件，逻辑清晰）
│   → 可以先用 Plan 模式快速扫描，确认思路后切换执行
│
└─ 复杂任务（多文件、不确定方案、风险较高）
    → 必须用 Plan 模式，详细规划后再执行
```

## 高级技巧

### 1. 通过 CLAUDE.md 自定义 Plan 模板

你可以在项目的 `CLAUDE.md` 中定义规划要求，让每次 Plan 模式都遵循统一格式：

```markdown
## Plan 模式要求

当进入 Plan 模式时，请按以下模板生成计划：

### 必须包含的章节
1. **现状分析**：当前代码结构和相关文件
2. **方案设计**：具体的实现方案，包含备选方案
3. **影响范围**：会修改哪些文件，影响哪些功能
4. **风险评估**：可能的问题和应对措施
5. **执行步骤**：按顺序排列，每步可独立验证
6. **测试计划**：如何验证修改的正确性

### 格式要求
- 每个执行步骤标明涉及的文件
- 新建的文件用 [新建] 标记
- 修改的文件用 [修改] 标记
- 风险点用高/中/低标记严重程度
```

把这段加入 `CLAUDE.md` 后，每次使用 Plan 模式，Claude 都会按照这个模板来组织计划。

### 2. Plan 模式中使用子代理探索

在 Plan 模式下，你可以请 Claude 使用子代理（Agent 工具）来做更深入的探索：

```
在制定计划之前，请先帮我搞清楚以下问题：
1. 当前的数据库 schema 是什么样的？用子代理去分析所有 model 文件
2. 现有的 API 接口列表是什么？用子代理去扫描所有 router 文件
3. 项目用了哪些第三方库？检查 requirements.txt 或 pyproject.toml
```

子代理会在独立的上下文中执行这些探索任务，然后把结果汇总给主会话，帮助 Claude 制定更准确的计划。

### 3. 保存和复用计划

好的计划可以保存为参考模板。你可以请 Claude 把计划导出为 Markdown 文件：

```
请把刚才制定的计划保存到 docs/plans/add-email-verification.md，
以后做类似功能时可以参考。
```

下次遇到类似需求，可以直接引用：

```
请参考 docs/plans/add-email-verification.md 中的计划结构，
为短信验证功能制定一个类似的计划。
```

### 4. 用 Plan 模式做代码审查

Plan 模式的只读特性使它非常适合做代码审查：

```
（进入 Plan 模式）

请审查 src/services/ 目录下的所有服务文件，重点关注：
1. 错误处理是否完善
2. 是否有 SQL 注入风险
3. 是否有未关闭的资源（数据库连接、文件句柄）
4. 异步代码是否有竞态条件
请给出详细的审查报告和改进建议。
```

由于 Plan 模式不会修改任何文件，你可以放心让 Claude 审查生产代码，不用担心它会"顺手"改了什么。

### 5. 结合 /compact 管理长计划会话

Plan 模式的探索过程可能消耗大量上下文（特别是分析了很多文件之后）。如果你觉得上下文快满了，可以在计划完成后、执行之前使用 `/compact`：

```
/compact 保留完整的执行计划和影响分析，压缩中间的探索过程
```

这样在执行阶段就有充足的上下文空间。

## 常见问题

**Q：Plan 模式下 Claude 会不会意外修改文件？**

A：不会。Plan 模式在系统层面禁止了所有写操作。Claude 可以读取任何文件，但无法创建、修改或删除任何内容。

**Q：计划做好后，切换到普通模式执行时，Claude 还记得计划吗？**

A：记得。只要你没有使用 `/clear` 清除历史，切换模式不会丢失上下文。计划仍然在对话历史中，Claude 可以直接按计划执行。

**Q：Plan 模式下可以使用 MCP 工具吗？**

A：可以使用只读类型的 MCP 工具（如搜索、查询文档），但不能使用会产生副作用的工具。

**Q：如果我觉得计划不好，可以让 Claude 重新规划吗？**

A：当然可以。你可以反复要求 Claude 修改计划，直到满意为止。Plan 模式的零风险特性意味着你可以尽情探索和调整。

**Q：团队协作中如何共享计划？**

A：可以让 Claude 把计划保存为 Markdown 文件，提交到 Git 仓库。也可以直接在 PR 描述中附上计划内容，方便代码审查。