本教程深入讲解 Claude Code 中用于"先想清楚再动手"的三个核心机制:计划模式(Plan Mode)、任务清单(TodoWrite) 与 结构化提问(AskUserQuestion)。它们共同构成了一个低返工、可审计的任务编排闭环——调研而不改、跟踪而不漏、澄清而不猜。适合已经会用 Claude Code 写代码、但常常遭遇"AI 自作主张改坏文件"或"做到一半发现方向错了"的中级开发者。学完后你将掌握在任意复杂改造前先冻结现场、产出可审批方案、并在执行中保持全可见性。
Shift+Tab 这类快捷键的输入方式很多人误以为 Claude Code 只有"问我"和"不问我"两种状态。实际上它有三种权限模式(permission modes),理解它们的差异是掌握 Plan 模式的前提:
| 模式 | 英文名 | 文件编辑 | 命令执行 | 适用场景 |
|---|---|---|---|---|
| 默认模式 | default |
每次询问 | 每次询问 | 日常小改、不熟悉的代码库 |
| 自动接受 | acceptEdits |
自动接受 | 仍询问 | 信任的批量重构、已审批的计划执行 |
| 计划模式 | plan |
禁止 | 仅只读 | 复杂任务前的调研与方案设计 |
关键认知:Plan 模式是一个只读研究态。进入后,Edit、Write、NotebookEdit 等修改工具被禁用,连 git commit、npm install 这类有副作用的 Bash 命令也会被拦截。Claude 只能 Read、Glob、Grep、LS 以及运行只读 Shell 命令。这种"手脚被绑住"的状态,恰恰逼着它把精力花在阅读和理解上,而不是急着改代码。
方式一:Shift+Tab 循环(最常用)
在交互式 REPL 中,连按 Shift+Tab 在三种模式间循环:
default ⇄ acceptEdits ⇄ plan ⇄ default ...
底部状态栏会实时显示当前模式。一个实战技巧:连按两次 Shift+Tab 可以从默认模式直接跳进 Plan 模式,省去中间的 acceptEdits。
方式二:/permissions 命令
输入 /permissions 可以查看当前模式、权限规则(allow/deny/ask),并在此面板中手动切换默认模式。
方式三:启动参数与配置文件
# 启动时直接进入计划模式
claude --permission-mode plan
# 或在项目 .claude/settings.json 中固化
{
"permissions": {
"defaultMode": "plan"
}
}
把 defaultMode 设为 plan 适合放在关键生产仓库里——团队任何人起会话都先调研、出方案、经评审后才放开执行权限。
按 Shift+Tab 两次进入 Plan 模式(状态栏显示 plan),然后描述你的改造目标。例如:
"把这个 Express 项目里的 JWT 认证中间件,重构成支持 access token + refresh token 的双令牌方案,并补上单元测试。"
Claude 此时会进入调研阶段,你会看到它执行一系列只读动作:
Glob 搜索 **/*auth*、**/*middleware*Read 当前认证中间件源码、路由注册文件、配置文件Grep 搜索 jwt.sign、verify、Bearer 的用法位置git log --oneline -5、cat package.json关键点:它不会改动任何文件。如果它尝试调用 Edit,工具会直接返回错误("Cannot edit in plan mode"),它必须转而继续调研或产出计划。
调研充分后,Claude 会调用 ExitPlanMode 工具,把方案写入一个计划文件(通常位于会话的计划目录),并把这个计划呈现给你审批。一份合格的计划应当包含:
src/middleware/auth.js、新增 src/utils/token.js、tests/auth.test.js)你审阅计划后有三个选择:
acceptEdits 开始执行Q:我在 Plan 模式里,Claude 却报错说不能编辑,是不是卡住了?
A:这不是 bug 而是特性。Plan 模式的目的就是禁止编辑。如果你希望它直接改,按 Shift+Tab 切回 default 或 acceptEdits。
Q:计划太长,审批面板看不完? A:计划会写到磁盘文件,你可以用编辑器打开逐行核对。也可以直接在对话框里说"把计划精简成 5 步以内的要点"。
Q:SDK / -p 无头模式下怎么用 Plan 模式?
A:在编程式调用中,Plan 模式映射为两个工具——EnterPlanMode(进入调研态)和 ExitPlanMode(提交计划)。你的编排脚本需要监听 ExitPlanMode 的调用,把计划文本拿到后再决定是否允许进入执行态。
计划批准后进入执行。复杂任务容易"做着做着忘了第几步",TodoWrite(交互式会话中的任务清单工具,对应 SDK 中的 TaskCreate/TaskUpdate)就是为此而生。
Claude 内部遵循三条硬规则:
in_progress,其余为 pending 或 completed。completed,绝不提前标记——如果测试还没跑通,任务必须停在 in_progress。每个任务项包含:
subject:祈使句标题,如"实现 refresh token 轮换"description:详细要求与验收点activeForm:进行时态的简短描述,显示在加载动画上,如"实现令牌轮换逻辑"status:pending → in_progress → completedaddBlocks / addBlockedBy:任务间依赖(A 完成后 B 才能开始)执行双令牌重构时,你会看到 Claude 创建一个清单:
☐ 1. 抽取 token 工具模块 src/utils/token.js
☐ 2. 重写中间件支持双令牌校验
☐ 3. 实现 refresh token 轮换与吊销
☐ 4. 补充单元测试(覆盖过期、轮换、吊销)
☐ 5. 跑通 npm test 并修复回归
随着推进,状态实时更新:第 1 项变 in_progress,完成后变 completed,第 2 项自动接上 in_progress。你在终端里能直观看到进度条,而不是干等一个黑盒跑完。
Q:清单和计划有什么区别? A:计划是 Plan 模式产出的"待审批方案文档";清单是执行期的"实时进度看板"。计划是事前承诺,清单是事中跟踪。
Q:中途发现计划错了怎么办? A:Claude 应当更新清单(新增、拆分或删除任务项)而不是抛弃它。如果它悄悄删掉了某项,你可以明确说"把第 3 项拆成轮换和吊销两个子任务"。
很多返工源于 Claude 在关键决策点上"猜"。AskUserQuestion(Claude Code v2.0.21 引入)让它在分叉点弹出结构化的多选题,把猜测变成确认。
假设在认证重构中,Claude 遇到"refresh token 存哪"的决策,它会调用 AskUserQuestion:
问题:refresh token 的存储后端选哪个?
选项:
(R) Redis —— 高性能,天然支持 TTL 过期,推荐
( ) 数据库表 —— 持久化,但需手动清理过期记录
( ) 内存 + 持久化日志 —— 简单但不适合多实例
[可选: Other 让你输入自定义]
四个关键约束:
存储后端(Recommended)true 则允许多选应该问: - 架构选型(存储后端、协议、依赖库) - 不可逆操作的确认(删表、改公开 API 签名) - 多个合理方案且影响面大的取舍
不该问:
- 能从代码推断的事实("这个项目用 React 还是 Vue"——自己读 package.json)
- 有常规默认值的琐事("变量名用 camelCase 还是 snake_case"——跟随代码库风格)
- 答案会改变后续动作的重大分叉——这种情况应先用 EnterPlanMode 调研,而不是空手就问
最佳实践是:在 Plan 模式的调研阶段用 AskUserQuestion 澄清歧义,而不是在执行到一半才问。因为 Plan 模式还没动任何文件,此时改方向零成本;执行期才发现选错了存储后端,已经写了一半的代码就得回滚。
把三者串起来,Claude Code 的复杂任务流程是这样的:
Shift+Tab×2 进 Plan 模式 —— 冻结现场,禁止任何修改AskUserQuestion 澄清关键决策 —— 在动笔前锁定存储、协议、范围ExitPlanMode 产出计划文件 —— 提交可审批方案acceptEdits —— 放开执行权限TodoWrite 建清单 —— 把计划拆成可跟踪的任务项这个闭环的核心价值是低返工 + 可审计:每一次文件改动都经过审批,每一个步骤都有进度,每一个决策都有记录。
下面是一个完整可演练的场景。假设有一个 Node.js 项目,认证中间件只支持单一 JWT,现在要升级为双令牌。
# 进入项目,以 Plan 模式启动
cd ~/projects/my-api
claude --permission-mode plan
在 REPL 中输入任务描述:
> 把 src/middleware/auth.js 的单 JWT 认证,升级为 access token(15分钟) +
refresh token(7天) 双令牌方案,refresh token 支持轮换与吊销,补全单测。
老令牌要兼容 30 天过渡期。
auth.js、路由文件、package.json(确认是否已装 jsonwebtoken、是否已有 Redis 客户端)。AskUserQuestion:
- 存储后端 → 你选 Redis
- 老令牌兼容策略 → 你选"双写校验"ExitPlanMode,计划文件包含 6 个步骤、3 个新增文件、2 个修改文件。acceptEdits,创建 TodoWrite 清单:☐ 1. 新建 src/utils/token.js(签发与校验)
☐ 2. 新建 src/utils/refreshStore.js(Redis 轮换/吊销)
☐ 3. 重写 src/middleware/auth.js(双令牌校验 + 老令牌双写)
☐ 4. 新增路由 /auth/refresh 与 /auth/logout
☐ 5. 编写 tests/auth.test.js(过期、轮换、吊销、兼容)
☐ 6. npm test 全绿
Q:执行到一半想改存储后端(从 Redis 换成数据库)怎么办?
A:Shift+Tab 回 Plan 模式,让它重新调研并修订计划,重新审批。已写的代码会被纳入修订评估,而不是盲目覆盖。
Q:清单一直卡在某个 in_progress,它好像死循环了?
A:这通常说明遇到了真问题(测试不过、依赖缺失)。读它的最新输出,明确指令"如果第 4 项依赖外部服务跑不起来,先跳过并标记,继续第 5 项"。
flowchart TD
A[Shift+Tab ×2 进入 Plan 模式] --> B[只读调研: Glob/Grep/Read]
B --> C{有关键决策点?}
C -- 是 --> D[AskUserQuestion 结构化提问]
D --> B
C -- 否 --> E[ExitPlanMode 产出计划文件]
E --> F{用户审批}
F -- 修改/拒绝 --> D
F -- 批准 --> G[切换 acceptEdits 模式]
G --> H[TodoWrite 建立任务清单]
H --> I[逐项执行 + 实时更新状态]
I --> J{遇阻或需改方向?}
J -- 是,需重调研 --> A
J -- 否,全部完成 --> K[任务完成, 全程可审计]
style A fill:#fef3c7,stroke:#92400e
style E fill:#dbeafe,stroke:#1e40af
style H fill:#dcfce7,stroke:#166534
style K fill:#fce7f3,stroke:#9d174d
图中虚线回环体现了三件套最大的优势——任何阶段都可回退到调研态,而不是一条走到黑的直线。
| 机制 | 触发者 | 何时用 | 成本 |
|---|---|---|---|
| 普通对话提问 | Claude 自由文本 | 非关键的小澄清 | 低,但易被忽略 |
AskUserQuestion |
Claude 结构化弹窗 | 关键分叉、方案选型 | 中,强制用户决策 |
EnterPlanMode + 调研 |
用户/Claude 主动 | 复杂任务、不确定现状 | 高,但产出可审批方案 |
记住一个优先级:能用调研解决的,不要靠问;必须问的,用结构化提问而非自由文本;任务一旦复杂到 3 步以上,先 Plan 再 TodoWrite。
| 维度 | 评估 |
|---|---|
| 适合训练营类型 | AI 编程实战营、工程效能训练营、企业 AI 落地训练营(中级班) |
| 学员基础 | 已完成 Claude Code 入门,能独立完成单文件修改 |
| 建议时长 | 2.5–3 小时(含 1 小时三模式理论 + 1.5 小时实战案例 + 0.5 小时答疑) |
| 考核点 | 能否在不改坏文件的前提下产出可审批计划;能否用 TodoWrite 完整跟踪一个 5 步任务 |
| 不适合 | 零基础班(需先掌握基本交互)、纯算法岗(与代码改造关系弱) |
code.claude.com/docs/en/permission-modes —— 三模式的权威定义与 Shift+Tab 说明code.claude.com/docs/en/agent-sdk/subagents —— 编程式集成计划模式的入口masteringai.io/guides/claude-code-plan-mode-guide —— 含 /plan 命令与键盘快捷键全集cuong.io/blog/2025/07/15-claude-code-best-practices-plan-mode —— 三模式的工程化取舍经验github.com/HaKuLax/claude-code-book —— 第 14 章 Plan Mode 与结构化工作流/plan 命令与 SDK 中 EnterPlanMode/ExitPlanMode 映射掌握计划模式与任务编排三件套,本质上是在重塑与 AI 协作的纪律:让它先证明理解、再获得改动权。这种"调研—审批—跟踪"的闭环,是把 Claude Code 从"会写代码的助手"升级为"可信赖的工程协作者"的关键一步。下次面对任何超过三个文件的改造,先连按两次 Shift+Tab,你会发现返工率断崖式下降。
�升级→验证]
D --> E[resume-runner.sh
捕获/持久化 session_id]
E --> F{claude -p --resume
dontAsk 模式}
F -->|PreToolUse 拦截危险命令| G[护栏 deny + reason]
F -->|编辑后 PostToolUse| H[asyncRewake 后台跑测试]
H -->|退出码2| F
F -->|瞬时错误| I[api_retry 自动退避]
F -->|整轮失败| J[StopFailure 留痕]
J --> K[写入 待续跑 标记]
F -->|成功| L[生成变更摘要]
L --> M[状态目录 .claude-state]
K --> M
M --> N[失败回收: 二轮 --resume]
N --> D
style G fill:#fde2e2,stroke:#c0392b
style H fill:#e8f5e9,stroke:#27ae60
style J fill:#fff3cd,stroke:#f39c12
```
--resume 的 session id 是否来自同一目录;--bare 是否误跳了 CLAUDE.md。.*;硬性规则改用 permissions.deny。dontAsk,等一个永远没人按的确认。-P 太高,看 api_retry 的 rate_limit 频率,超阈值降并发。asyncRewake 要求退出码 2 才唤醒;脚本里别用错退出码。code.claude.com/docs/en/hooks-p、--resume、output-format 全谱):code.claude.com/docs/en/headlessdontAsk / acceptEdits 与 allow/deny 规则):code.claude.com/docs/en/permissionscode.claude.com/docs/en/agent-sdk/plans| 维度 | 评估 |
|---|---|
| 适合的训练营类型 | DevOps / 平台工程 / AI 工程化中级营;要求学员先有过 CI/CD 或脚本自动化经验 |
| 不适合 | 零基础入门营(需先掌握 -p 基础、JSON、shell);纯前端/算法营 |
| 建议教学时长 | 4–6 学时(2 学时讲三原语 + 护栏,2 学时动手搭实战 Agent,1–2 学时调参与复盘) |
| 学员产出 | 一套可过夜的无人值守 Agent,含续跑、自愈、护栏、批量调度,可直接接入夜间构建 |
| 考核点 | 能否解释四种自愈层级的分工;能否独立写出带 if 的 PreToolUse 护栏;能否设计并发与限速策略 |
| 风险提示 | 需提前为学员准备独立额度或限额,避免批处理把整月 Agent SDK 额度跑爆 |
-p / --resume / --output-format / api_retry 事件权威说明,本文断点续跑与自愈章节的一手依据。StopFailure / PermissionDenied / PreToolUse 决策字段与 matcher 求值规则。dontAsk / acceptEdits 模式与 permissions.allow / deny 规则,护栏红线设计依据。[!tip] 51学通信知识星球 星主:爱卫生(微信:gprshome201101)——公众号「51学通信」创办者,19 年通信行业运维与讲师经验,著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书(各大电商平台有售)。 星球定位:深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域,主打运维岗位与信令分析。 当前规模:5200 篇主题 / 990 个回答,198 元/年。 加入福利:加入星球后请加爱卫生微信,拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题,另有群内分享。 AI 加持:51学通信知识星球已作为 skill 接入 WorkBuddy,使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例,做总结、找文档和 PPT 等场景全覆盖。
