Claude Code 反复问太多问题:权限提示 vs 决策问题,两种修法

Claude Code 每隔几秒就停下来要权限,或者问「TypeScript 还是 JS」——这是两个不同的问题:权限提示用 permission mode 修,决策问题用 CLAUDE.md 默认值 + Proactive 风格修。

你说「加一个 billing API endpoint」。Claude Code 回:「用 TypeScript 还是 JavaScript?文件放哪儿?要不要加测试?你倾向哪种错误格式?REST 还是 GraphQL?」每一条看代码库都明显有答案。或者更糟:Claude 明明知道该怎么做,却在每一次文件编辑、每一条命令前都停下来确认——Allow Claude to edit route.ts? (y/n)——整个 session 九成时间在按 y。

最快修法(两种「问」是两个不同的问题):

  • 它在每次编辑/命令前停下来要权限 → 按 Shift+Tab 切到 ⏵⏵ accept edits on 模式(自动批准编辑 + 常见文件系统命令)。长任务再按一次切到 auto 模式(需 Claude Code v2.1.83+),由后台安全 classifier 把关,一切自动跑。
  • 它要你做决定(「用什么框架?」「文件放哪?」)→ 把答案写进 CLAUDE.md 当显式默认值、prompt 里指一个 canonical example 文件、并打开 Proactive 输出风格,让 Claude 做合理假设而不是停下来问。

本文是这两种修法的耐久版。关键是先分清这两种「问」,因为对应的杠杆完全不同。

先判断:这是哪一种「问」?

你看到的类型主要杠杆
每个文件都弹 Do you want to make this edit? (y/n)权限提示Permission mode(Shift+Tab)或 permissions.allow
Allow Claude to run \npm test`? (y/n)`权限提示Permission mode 或 allow 规则
「用 TypeScript 还是 JavaScript?」决策问题CLAUDE.md 默认值 + Proactive 风格
「这个文件放哪儿?」决策问题prompt 里指 canonical example;CLAUDE.md
「我看到 findUsergetUser 都有,用哪个?」决策问题(真歧义)收敛 repo 不一致,钦定 canonical
一个编号的 plan 在问「approve this plan?」Plan 模式退出 plan 模式(Shift+Tab

权限提示是关于运行工具;决策问题是关于做选择。如果你只修一边,另一边还在弹,你会以为啥都没变。

权限提示:换 mode 就是修法

Claude Code 在每次编辑、命令、网络请求前确认,是因为默认 mode(default)只自动批准读操作。截至 2026 年 6 月共有六种 mode,session 中用 Shift+Tab 切换——当前 mode 显示在状态栏。

Mode不问就跑的范围适用
default只读敏感工作、刚上手
acceptEdits读 + 文件编辑 + 工作目录内 mkdir/touch/rm/mv/cp/sed边写边事后审
plan只读(完全不编辑)改动前先探索
auto一切,背后有 classifier 把关长任务、被弹烦了
dontAsk只跑预批准的工具(其余一律拒)锁死的 CI
bypassPermissions一切,无任何检查只用于隔离容器/VM

Shift+Tab 循环 default → acceptEdits → plan。账号符合条件后 auto 排在 plan 之后;dontAskbypassPermissions 只在用对应 flag 启动时才出现。

日常答案:accept-edits 模式

从默认按一次 Shift+Tab,状态栏显示 ⏵⏵ accept edits on。Claude 现在在工作目录内创建/编辑文件不再问,并自动批准常见文件系统命令(mkdirtouchrmrmdirmvcpsed)。工作目录之外、写入受保护路径(.git.env 一类、.claude 等)、以及其他所有 Bash 命令仍然会弹确认。事后用 git diff 复核。

想每个 session 都从这里开始,写进 .claude/settings.json

{
  "permissions": {
    "defaultMode": "acceptEdits"
  }
}

长时间自主跑:auto 模式

如果一个任务你信任大方向、不想盯着,切到 auto(需 Claude Code v2.1.83+ 和较新模型;在 Anthropic API 上需 Opus 4.6 或更新、或 Sonnet 4.6)。Auto 模式一切自动跑,但有一个独立的 classifier 模型先审每个动作,拦掉超出你请求范围的——curl | bash、生产部署、force-push、批量删除、直接推 main。重点是:auto 模式同时会推动 Claude 不要停下来问澄清问题,所以它能一次缓解两种「问」。

两个要知道的细节:

  • 如果 classifier 连续拦 3 次、或累计拦 20 次,auto 模式暂停、Claude Code 恢复弹确认。批准那个被弹的动作后会恢复 auto。
  • defaultMode: "auto" 只在 ~/.claude/settings.json(用户设置)里生效。Claude Code v2.1.142+ 会忽略项目 .claude/settings.json 里的 auto,这样 repo 没法擅自给自己开 auto。

Auto 模式是 research preview——它减少提示,但不保证安全。bypassPermissions 留给一次性容器就好。

精准做法:预批准特定工具

如果你不想用一整个 mode,只是少数几条命令老弹,就在 settings.json 里精确放行。规则按 deny → ask → allow 求值(命中 deny 永远赢):

{
  "permissions": {
    "allow": ["Bash(npm test)", "Bash(npm run:*)", "Bash(git status)", "Bash(git diff:*)"],
    "ask": ["Bash(git push:*)"],
    "deny": ["Bash(rm -rf:*)"]
  }
}

模式写法:Bash(npm test) 是精确命令,Bash(npm run:*) 匹配各种变体,单独 Bash 放行所有 Bash。这相当于点「Yes, and don’t ask again」的耐久版——而且 check 进 repo,全队受益。

决策问题:把答案写明白

这些是「TypeScript 还是 JavaScript」类问题。Claude 之所以问,是 prompt 模糊代码库没明显约定,于是它用「问」换「安全」。修法绝不是「叫它别问」——那太脆。把默认值做成真的。

常见原因(按命中率从高到低)

1. CLAUDE.md 没 Defaults 段。 没写默认值,每个隐式选择都需要确认。判断:grep -i default CLAUDE.md 没结果。

2. Prompt 把明显决定留隐式了。 「加一个 endpoint」没说什么风格、放哪、什么框架。判断:prompt 不到 30 字、不指 canonical example。

3. 没有自主授权。 Claude Code 内建策略遇歧义偏向问。破坏性操作这对;可逆编辑就是噪音。判断:问的是可逆决定(文件位置、命名),不是破坏性的。

4. 代码库本身就不一致。 repo 一半 findUser 一半 getUser。Claude 读到两种、看到代码从没做过的真实选择,就问。判断:那个问题对应的歧义,你在 src/ 里真能找到两边。

5. Task 真的歧义。 有些问题合理:有 5 个合理位置时「文件放哪」就是真问题。判断:打开 codebase 你也答不出来——那就是有效问题,回答它。

6. Plan 模式开着。 Plan 模式设计成每步前问。你没打算进却进了,就感觉它问太多。判断:每个「问题」都是个编号步骤在等 plan 批准——按 Shift+Tab 退出 plan 模式。

Step 1:CLAUDE.md 加 Defaults 段

单杠杆最高的一步。auto 模式的 classifier 和 Claude 本身都读 CLAUDE.md,所以这一步处处见效:

## Defaults(不要问,直接用)

- 语言:TypeScript(strict)
- 测试框架:vitest
- 测试位置:紧挨源文件,`*.test.ts`
- 包管理:pnpm
- API 响应形状:`{ data: T | null, error: string | null }`
- 错误类:extend `src/lib/errors.ts``AppError`
- 新组件:arrow function、props 解构、export default
- 命名:`findX` 可空查找,`getX` 必有查找(缺则 throw)

## 这些事必须先问:

- 删 task 直接范围外的文件
- 在生产跑数据库 migration
-`.env``package.json` engines、CI 配置
- 改公开 API 合同
- 强推或 `git reset --hard`

「必须先问」让「其他时候别问」变安全。

Step 2:打开 Proactive 输出风格

这是专为这个问题做的杠杆。Proactive 输出风格把 Claude Code 的系统 prompt 换成另一套:立刻执行、对例行决定做合理假设而不停下来、行动优先于规划——同时工具运行前仍然弹权限提示。官方文档明确推荐它用于「想要更少澄清问题、但仍想亲自批准实际编辑」的场景。

通过 /config 在里面选输出风格,或直接在设置里写 outputStyle(独立的 /output-style 命令在 v2.1.91 已移除)。你的选择保存在 .claude/settings.local.json

Step 3:Prompt 里指 canonical example

不要写「加一个 endpoint」,写:

加 `GET /api/orgs/:id`。
完全照 `src/app/api/users/[id]/route.ts`——同结构、同错误格式、同测试布局。
位置、命名、框架不要问,照这个文件。

一个 canonical 指针,一句话消掉五个问题。

Step 4:用「decisive mode」prompt 前缀

执行模式工作,把这段存成 slash command,不要每次重打:

模式:执行,不咨询。
读 CLAUDE.md 取默认值,基于现有代码做合理决定。
只在以下情况问:
1. 决定是破坏性的(删数据 / 破坏 API 合同)
2. 决定和 CLAUDE.md 冲突
3. 多种模式共存且你判定不出 canonical

Step 5:在 prompt 里提前回答常见问题

重复工作流,前置 agent 本会问的:

加测试:是,vitest,紧挨源。
文件位置:src/services/billing/。
命名:camelCase,interface 不要 I 前缀。
文档:JSDoc 只在 export 上。

Step 6:消除 repo 内不一致

Claude 之所以问,是 repo 没选——修 repo:

# 数对立模式
grep -rc "findUser" src/ | awk -F: '{s+=$2} END {print "find:", s}'
grep -rc "getUser" src/ | awk -F: '{s+=$2} END {print "get:", s}'

CLAUDE.md 钦定一个,少数派迁移(这本身可以是 Claude 的活儿)。未来 task 不再撞这个歧义。

Step 7:把每个问题当文档缺口

Claude 一问,先判断:真空缺,还是它本该知道的默认?无论哪种,答案都进 CLAUDE.md,不再问第二次。

Q:「新 endpoint 要 auth 吗?」
→ 真问题。回答 + 加进 CLAUDE.md:「所有 /api/* 需 auth,除了 /api/public/*」

Q:「TypeScript 还是 JS?」
→ 默认问题。回答 + 加进:「永远 TypeScript strict」

怎么确认修好了

  • 权限侧:状态栏显示 ⏵⏵ accept edits on(或 auto),一次例行编辑直接落地、没有 (y/n)。用 git diff 复核落了什么。
  • 决策侧:重跑同类任务(照 canonical 文件加一个小 endpoint)。如果 Claude 直接走、只在真正破坏性或真正歧义处停,说明默认值起效了。如果它还问「TypeScript 还是 JS?」,说明这条答案还没进 CLAUDE.md——补上。

常见问题

accept-edits 模式和 auto 模式有什么区别? acceptEdits 只自动批准工作目录内的文件编辑和一小串文件系统命令;其余(其他 Bash 命令、网络请求、目录外写入)仍然弹确认。auto 一切自动跑、但每个动作经过后台安全 classifier,而且会推动 Claude 别问澄清问题。日常你要事后审的编码用 accept-edits;信任的长时间放手跑用 auto。

--dangerously-skip-permissions(YOLO 模式)来停掉提示行吗? 能停(bypassPermissions 模式跳过所有检查),但它对 prompt injection 和模型误操作毫无防护,而且以 root 身份时 Claude Code 拒绝以该模式启动。只在一次性容器或 VM 里用。日常工作,acceptEditsauto 给你大部分速度、同时留着安全护栏。

我设了 defaultMode: "auto",session 还是从 default 模式启动,为什么? auto 只在用户设置(~/.claude/settings.json)里生效。从 v2.1.142 起,Claude Code 忽略项目 .claude/settings.jsonsettings.local.json 里的 defaultMode: "auto",这样 repo 没法擅自给自己开 auto。把这条挪到你的 home 设置文件。

Claude 不再问权限了,但还在问「用哪个框架?」——是模式没起作用吗? 那是两回事。Permission mode 消掉的是工具批准提示;它不教 Claude 你的约定。决策问题要靠 CLAUDE.md 默认值、prompt 里的 canonical example,最好再加上 Proactive 输出风格。那一侧单独修。

有些问题确实是好问题,怎么保留? 在 CLAUDE.md 里留一个「必须先问」段(破坏性操作、生产 migration、公开 API 改动),并在对话里声明边界——auto 模式下,一句「don’t push until I review」会被 classifier 当作硬阻断,直到你解除为止。这样噪音被消、真正要紧的事会停。

accept-edits 会删掉我没想动的文件吗? 它只对工作目录或 additionalDirectories 内的 rm/rmdir/mv 自动批准,对 .git.env 这类受保护路径从不批准。范围外的写入仍然弹确认。想要硬保证,在 settings.json 加一条 deny 规则如 Bash(rm -rf:*)——deny 规则在任何 mode 都赢。

相关阅读

标签: #排查 #Claude Code #排查 #交互问询