別讓 Claude Code 一直問你"能不能執(zhí)行":權(quán)限配置完全指南

用了 Claude Code 一段時間,有件事讓我很頭疼。

每次讓它幫我寫完一段代碼,它要問我一句"能不能保存文件"。跑個測試,又問一句。創(chuàng)建個目錄,再問一句。本來是來解放雙手的,結(jié)果變成了另一種形式的"人肉確認(rèn)機器"。

直到我徹底搞懂了它的權(quán)限配置系統(tǒng),這個問題才真正解決。


為什么 Claude Code 會不斷打斷你

Claude Code 的設(shè)計哲學(xué)是謹(jǐn)慎優(yōu)先。它默認(rèn)對幾乎所有文件操作、終端命令都會暫停下來問你一句,因為 AI 執(zhí)行出錯的代價,可能比慢一點高得多。

這個設(shè)計是對的。

但問題在于,"謹(jǐn)慎"和"高頻打斷"之間有巨大的差距。git status 這種只讀命令,swift build 這種本地構(gòu)建,根本不需要每次確認(rèn)。真正需要謹(jǐn)慎的,是 git push、npm install、以及任何涉及破壞性的操作。

Claude Code 提供了一套精細的權(quán)限配置機制,讓你自己來劃這條線。


權(quán)限系統(tǒng)的三個層級

配置文件有三層,從全局到局部依次覆蓋:

~/.claude/settings.json              ← 全局,所有項目生效
<項目>/.claude/settings.json         ← 項目級,可提交到 git
<項目>/.claude/settings.local.json   ← 項目本地,加入 .gitignore

優(yōu)先級:項目本地 > 項目級 > 全局。權(quán)限規(guī)則是合并生效的,但 deny 永遠是最高優(yōu)先級,任何地方的 deny 規(guī)則都不會被覆蓋。

實際用法很清晰:

  • 全局配置放通用規(guī)則(git 操作、構(gòu)建工具、讀文件)
  • 項目配置放這個項目專屬的規(guī)則(iOS 項目放 xcodebuild,前端項目放 vite)
  • 本地配置放個人習(xí)慣、或者不適合提交的臨時規(guī)則

權(quán)限配置的結(jié)構(gòu)

settings.json 里的 permissions 字段,包含三個數(shù)組:

{
  "permissions": {
    "allow": [],   // 自動執(zhí)行,不詢問
    "ask":   [],   // 執(zhí)行前暫停,等你確認(rèn)
    "deny":  []    // 完全禁止,拒絕執(zhí)行
  }
}

規(guī)則格式是 操作類型(匹配模式),支持通配符:

操作類型 說明 示例
Bash 終端命令 Bash(git status)
Edit 修改已有文件 Edit(src/**/*.ts)
Write 創(chuàng)建新文件 Write(src/**/*.tsx)
Read 讀取文件 Read(README.md)
WebFetch 抓取網(wǎng)頁 WebFetch(domain:github.com)

冒號在 Bash 規(guī)則里有特殊含義:Bash(git log:*) 表示允許 git log任意參數(shù),而 Bash(git log) 只允許不帶參數(shù)的裸命令。這個細節(jié)很容易忽略,但影響很大。


一份真正好用的全局配置

下面這份配置,是我在 iOS + Vue/TypeScript 的開發(fā)棧上磨合出來的版本。

核心策略:讀操作全放行,源碼編輯按路徑放行,寫操作和構(gòu)建命令按風(fēng)險分級,破壞性操作一律 deny。

{
  "permissions": {
    "allow": [
      "Bash(git status)",
      "Bash(git log:*)",
      "Bash(git diff:*)",
      "Bash(git add:*)",
      "Bash(git stash:*)",
      "Bash(git branch:*)",
      "Bash(git switch:*)",
      "Bash(git checkout:*)",
      "Bash(swift build:*)",
      "Bash(swift test:*)",
      "Bash(swift run:*)",
      "Bash(xcodebuild:*)",
      "Bash(npm test:*)",
      "Bash(npm run lint:*)",
      "Bash(npm run dev:*)",
      "Bash(npm run typecheck:*)",
      "Bash(npx tsc:*)",
      "Bash(bun run:*)",
      "Bash(bun test:*)",
      "Bash(node:*)",
      "Bash(python3:*)",
      "Bash(mkdir -p:*)",
      "Bash(cp:*)",
      "Bash(mv:*)",
      "Bash(cat:*)",
      "Bash(echo:*)",
      "Bash(ls:*)",
      "Bash(find:*)",
      "Bash(grep:*)",
      "Bash(wc:*)",
      "Bash(which:*)",
      "Bash(gh api:*)",
      "Bash(gh repo:*)",
      "Bash(xcodegen generate:*)",
      "WebSearch",
      "WebFetch(domain:developer.apple.com)",
      "WebFetch(domain:developers.figma.com)",
      "WebFetch(domain:github.com)",
      "WebFetch(domain:raw.githubusercontent.com)",
      "Read(**)",
      "Edit(src/**)",
      "Edit(Sources/**)",
      "Edit(Tests/**)",
      "Edit(tests/**)",
      "Write(src/**)",
      "Write(Sources/**)",
      "Write(Tests/**)"
    ],
    "ask": [
      "Bash(git commit:*)",
      "Bash(git push:*)",
      "Bash(git merge:*)",
      "Bash(git rebase:*)",
      "Bash(npm install:*)",
      "Bash(npm run build:*)",
      "Bash(pod install:*)",
      "Bash(brew install:*)",
      "Edit(package.json)",
      "Edit(Package.swift)",
      "Edit(Podfile)",
      "Edit(tsconfig.*)",
      "Edit(vite.config.*)",
      "Write(**)"
    ],
    "deny": [
      "Bash(rm -rf:*)",
      "Bash(sudo:*)",
      "Bash(curl * | *)",
      "Bash(wget * | *)",
      "Write(/Users/changyou/.ssh/*)",
      "Edit(.env.production)",
      "Edit(.env.prod)",
      "Read(.env.production)"
    ]
  }
}

把這份內(nèi)容寫入 ~/.claude/settings.json,對你機器上的所有項目立即生效。


哪些操作留在 ask,不是隨意的

ask 里的每一條規(guī)則都有原因,不是懶得配置:

git commit / git push:提交和推送是有歷史記錄的操作,AI 生成的 commit message 質(zhì)量參差不齊,push 之后改起來麻煩,留一個確認(rèn)節(jié)點是值得的。

npm install / pod install:安裝依賴會修改 lock 文件,引入外部包,需要人工感知,不應(yīng)該靜默發(fā)生。

npm run build:構(gòu)建產(chǎn)物可能直接影響部署,尤其是 CI/CD 流程里,一個無意觸發(fā)的 build 可能帶來副作用。

配置文件(package.json、tsconfig.*vite.config.*:這些文件的改動是全局性的,牽一發(fā)動全身,每次都看一眼沒壞處。


deny 的幾個設(shè)計細節(jié)

Edit(.env.production) 而不是 Edit(.env*)

很多人會把 .env* 全部 deny,然后發(fā)現(xiàn) .env.local 也編輯不了了,開發(fā)寸步難行。只 deny 生產(chǎn)環(huán)境的配置文件,本地開發(fā)的 .env.local.env.development 正常放行。

Write(/Users/changyou/.ssh/*) 用絕對路徑

JSON 文件里的 ~ 不會被展開,~/.ssh/* 這條規(guī)則其實是無效的。用絕對路徑才能真正生效。

Bash(curl * | *)Bash(wget * | *)

攔截的是管道執(zhí)行模式——把下載內(nèi)容直接 pipe 給 shell 執(zhí)行,這是最經(jīng)典的供應(yīng)鏈攻擊手法。單純的 curl 下載文件不受影響。


配置之后的實際變化

一個典型的功能迭代循環(huán),配置前后的體驗差別非常明顯:

配置前:寫代碼 → 問你能不能保存 → 你確認(rèn) → 跑測試 → 問你能不能執(zhí)行 → 你確認(rèn) → 檢查 lint → 問你能不能運行 → 你確認(rèn)。一個來回三次打斷,Claude Code 退化成了一個需要人肉看管的工具。

配置后:Claude Code 獨立完成"修改代碼 → 保存 → 跑測試 → lint 檢查"這整個循環(huán),只在你要 commit 的時候停下來讓你看一眼。你喝杯咖啡回來,任務(wù)已經(jīng)完成了大半。

這才是 agentic 工具該有的樣子。


一個要記住的判斷原則

在決定一條規(guī)則放 allow 還是 ask 時,問自己一個問題:

這個操作如果 AI 執(zhí)行出錯,修復(fù)成本有多高?

  • 讀文件、搜索、查看目錄:成本為零,無腦 allow
  • 編輯源碼:可以 git 回滾,allow 沒問題
  • 安裝依賴、提交代碼:有副作用,放 ask
  • 刪除文件、執(zhí)行 sudo、修改生產(chǎn)配置:不可逆,放 deny

權(quán)限配置不是一次性工作。隨著項目演進,你會遇到新的工具、新的目錄結(jié)構(gòu),規(guī)則也要跟著調(diào)整。每次遇到"這個操作好像不該每次都問我",就是更新配置的信號。


把 AI 工具真正用好,從來不是"開箱即用"的事。

給它一個合理的邊界,它才能在那個邊界里跑得更快。


2026.03.25 17:06
滬 · 趙巷

?? 聲明:本文由 AI 輔助完成

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容