痛点:Claude 直接乱改一通
你说"把登录模块迁到 JWT",Claude 立刻开始改文件。等你反应过来,十几个文件已经被动过,方向还跟你想的不一样 —— 现在你得一个个 git diff 看它干了什么,再决定 revert 哪些。
问题不在 Claude,而在你没机会在它动手前喊停。两件事能解决:
- 计划模式(plan mode):让 Claude 先只读研究、产出一份计划,你批准后再动手。
- 权限控制:用模式 + allow/ask/deny 规则,精确决定"哪些操作自动放行、哪些必须问你、哪些直接禁止"。
进入计划模式
计划模式下 Claude 会读文件、跑探索性 shell 命令、写出一份计划,但不修改任何源文件,直到你批准。三种进入方式:
# 启动时就进 plan mode
claude --permission-mode plan会话中临时切换,按 Shift+Tab 循环:
default → acceptEdits → plan切进去后状态栏会显示当前模式。再按一次 Shift+Tab 可以在不批准计划的情况下直接退出。
只想让单条提示走计划模式,用 /plan 前缀:
> /plan 把 src/auth 从 session cookie 迁到 JWT注意:plan mode 不是"只读 shell"。它的权限行为跟
default一样 —— Claude 仍可运行 shell 命令探索代码,这些命令照样受权限提示约束。它只是不写源文件。
看计划 → 批准 → 切到执行模式
计划写好后,Claude 把计划呈现给你,并问你怎么继续。批准对话框里的选项决定批准后切到哪个执行模式:
| 选项 | 批准后切换到 |
| --- | --- |
| Approve and start in auto mode | auto 模式 |
| Approve and accept edits | acceptEdits 模式 |
| Approve and review each edit manually | default 模式 |
| Keep planning with feedback | 留在 plan mode 继续迭代 |
典型流程:
> /plan 给 NotificationService 补齐边界条件的测试
[Claude 读完相关文件,输出一份计划:
1. 在 notification.test.ts 新增 5 个用例
2. 覆盖空收件人 / 超长正文 / 重复发送
3. 复用现有 mock,不引入新依赖]
? 如何继续?
> Approve and review each edit manually选 "review each edit manually" 后会话切回 default,Claude 开始按计划改,每个编辑你都过一遍。想再次计划,重新用 /plan 或按 Shift+Tab 切回。
小技巧:呈现计划时按
Ctrl+G可以在你默认的文本编辑器里直接打开并修改计划,再交还给 Claude 执行。
六种权限模式怎么选
权限模式决定"哪些操作不用问你就能跑"。一共六种:
| 模式 | 无需确认就能跑 | 适合 |
| --- | --- | --- |
| default | 只读 | 起步、敏感改动 |
| acceptEdits | 读 + 文件编辑 + 常见文件系统命令(mkdir/mv/cp 等) | 一边写一边 review |
| plan | 只读 | 改之前先摸清代码库 |
| auto | 几乎全部,带后台安全检查 | 长任务、减少打断 |
| dontAsk | 仅预批准的工具 | 锁死的 CI / 脚本 |
| bypassPermissions | 全部 | 仅限隔离容器 / VM |
几条选择经验:
- 日常就用
default,需要连续改多个文件、你会事后看 diff 时切acceptEdits。 dontAsk会自动拒绝一切未预批准的工具(连ask规则都直接拒),适合无人值守的 CI。- 除
bypassPermissions外,所有模式都不会自动放行对受保护路径(.git、.claude等)的写入。
切换方式回顾:Shift+Tab 循环(只在 default/acceptEdits/plan 间)、--permission-mode <mode> 启动参数、或写进 settings 的 defaultMode:
{
"permissions": {
"defaultMode": "acceptEdits"
}
}
auto不在Shift+Tab默认循环里,且把defaultMode: "auto"写进项目级.claude/settings.json会被忽略(防止仓库给自己授权);要让它成默认,得写进用户级~/.claude/settings.json。plan没有这个限制,项目级写defaultMode: "plan"完全有效。
用 allow/ask/deny 规则让弹窗消失
模式定基线,规则做精调。在 settings.json 的 permissions 里写三个列表:
{
"permissions": {
"allow": [
"Bash(npm run test:*)",
"Bash(git commit:*)",
"Read(src/**)"
],
"ask": [
"Bash(git push:*)"
],
"deny": [
"Bash(rm -rf *)",
"Read(./.env)"
]
}
}- allow:匹配的调用直接放行,不再弹窗 —— 这是消灭"每次都问 npm test 行不行"的正解。
- ask:即使在宽松模式下也强制弹一次确认。
- deny:始终拦截,任何模式都不放行。
规则的评估顺序是固定的:
deny → ask → allow第一个匹配的规则说了算,粒度不影响优先级。所以 ask: ["Bash"] 配上 allow: ["Bash(npm test)"] 时,npm test 仍会弹窗 —— 因为 ask 先命中。要避免,就把 ask 也写成带 specifier 的精确形式。
不想手写 JSON?在会话里输入 /permissions 打开交互面板,增删规则、查看每条规则来自哪个 settings 文件,改完即时生效。
路径语法坑:
Read(*.env)/Read(./.env)这种相对写法是相对当前目录(cwd);只有单斜杠Edit(/src/**/*.ts)才相对项目根目录;真要写文件系统绝对路径得用双斜杠Read(//etc/**)。三种锚点别混。
沙箱里放手跑
想让 Claude 在长任务里少打断你,但又不敢用 bypassPermissions?两条路:
一是 auto 模式 —— 几乎不弹窗:只读操作和工作目录内的文件编辑会被直接放行,其余动作才交给一个独立的分类器模型做安全检查,拦截"超出你请求范围""打到陌生基础设施""被恶意内容驱动"的操作(受保护路径的写入即便有 allow 规则也会走分类器)。比 bypassPermissions 安全得多:
claude --permission-mode auto你在对话里立的边界也算数 —— 说一句"先别 push,等我 review",分类器就会拦住匹配的动作,直到你后面解除。
二是用 sandbox 跑 Bash —— 把命令关进文件系统 / 网络隔离的沙箱里,即使放手跑也伤不到宿主。沙箱由会话内的 /sandbox 面板开启(配置写进 .claude/settings.local.json)。它独立于权限模式工作:沙箱内的受限操作可被自动放行,/sandbox 本身不是一种 permission mode,也不靠 defaultMode 调节。
底线:
bypassPermissions跳过几乎所有检查和受保护路径写入,只在没有外网的容器 / VM / dev container里用。它对 prompt injection 毫无防护;想"少弹窗"请优先选auto,而不是 bypass。
回到 示例列表 →