Claude Code 剛裝好的時候,設定這件事簡單到你不會多想:一個檔案,~/.claude/settings.json,你要改什麼都往裡面丟。改個預設模型、加幾條權限、設個環境變數,存檔,搞定。

然後有一天,你在 settings.json 裡明明白白寫了一條規則——比方說禁止某個危險指令——結果 Claude Code 完全當它不存在。你檢查了三遍,拼字沒錯、括號沒漏、JSON 也合法。它就是不甩你。

大部分人這時候的第一反應是「壞了」。但九成九的情況,它沒壞。你那條規則好端端地在那裡,只是被另一個地方的設定給蓋掉了。而「另一個地方」有幾個,這就得從設定檔怎麼一路長成今天這副模樣講起。

一個檔案不夠用的那一天

先回到最單純的狀態:全世界只有你一個人用 Claude Code,所有設定放在 ~/.claude/settings.json。這個檔在你的家目錄底下,跟著你這個「使用者」走,所以官方叫它 User 層。你開任何專案,它都在。

這套在你單打獨鬥時完美無缺。問題出在你把 Claude Code 帶進團隊的那一刻。

你替專案調了一組很順手的權限規則——哪些指令可以自動跑、哪些目錄能讀能寫——然後你想讓隊友也用同一套。總不能叫每個人手動抄一遍你家目錄裡的檔案吧?而且這套規則是「這個專案」的,不該污染你在別的專案的設定。

於是有了第二層:Project 層,放在專案根目錄的 .claude/settings.json。它跟著專案走,會被你 commit 進 git,clone 下來的人自動吃到同一套規則。這裡最適合放團隊共識——這個專案允許跑哪些指令、擋掉哪些操作。

1
2
3
4
5
6
7
// .claude/settings.json(Project 層,進 git 給整隊共用)
{
"permissions": {
"allow": ["Bash(npm run *)", "Read(./src/**)", "Write(./src/**)"],
"deny": ["Bash(rm -rf *)", "Read(./.env.*)"]
}
}

到這裡先停一下,因為一個關鍵的觀念在這一層冒出來了:當 User 層和 Project 層都對同一件事有意見,聽誰的?

疊在一起,不是換一張

這裡最容易誤會的地方是,很多人以為專案設定會「取代」個人設定,像換一張全新的紙。不是這樣。

比較準的畫面是這樣:把所有層的設定當成一疊透明片,一張一張疊起來,光從上面打下去,你看到的是它們合起來的樣子。權限規則是合併的——你 User 層的 allow 加上 Project 層的 allow,兩邊的規則同時生效,不是後者洗掉前者。只有當兩層對「同一個鍵」給了不同的值,才需要分高下,這時候比較靠近專案、比較具體的那一層贏。

這個設計其實很符合直覺,只要你換個日常的類比就懂了:它跟公司的規章制度是同一套邏輯。你個人有自己的工作習慣,團隊有團隊的約定,部門有部門的規定。這些多半不衝突,各自生效、疊在一起;真的撞到一起時,範圍大的那條壓過範圍小的那條。沒有哪一層「取代」哪一層,它們是層層相疊的關係。

搞懂這件事,你就解掉了文章開頭那個謎題的一半:你的規則沒消失,它還在那疊透明片裡,只是被上面某一張蓋住了你要的那個值。

為了藏私和臨時起意,又多了兩層

團隊共用解決了,新的尷尬又來了。

有些設定是你純個人的偏好——比方你習慣用 vim 模式編輯、或你本機才需要的某個環境變數、又或某條只對你有意義的權限。這些東西放進 Project 層會被 commit,等於強迫全隊跟你一起用 vim,還可能不小心把本機的機密路徑推上 git。放進 User 層又不對,因為它只跟這個專案有關,不該跟著你到別的專案去。

這個縫隙,就是 Local 層 補上的:.claude/settings.local.json。它跟 Project 層一樣待在專案目錄裡,但預設被 gitignore,不會進版控。專案專屬、又不想給別人看到、或不想強加給隊友的東西,都塞這裡。它比 Project 層更貼近「此時此地的你」,所以優先序也更高。

還有一種更短命的需求:你這一次啟動 Claude Code,臨時想覆蓋某個設定,用完就算。為這種事去改檔案太重了。所以還有命令列旗標——啟動時直接帶參數,只對這一次 session 有效,優先序壓過所有寫在檔案裡的設定。它像是你今天出門前臨時決定「今天不走平常那條路」,只管今天,不動你長期的習慣。

數一數,現在已經四層了:User、Project、Local,加上臨時的命令列旗標。順序由低到高,越靠近「當下、具體、貼近你」的,話語權越大。

最後一層,是不讓你放寬的那層

前面四層有個共通點:它們全都是「你」在做主,差別只在範圍和時效。但當 Claude Code 進了公司、由 IT 統一部署,就出現一個前四層都滿足不了的需求——有些規則,公司需要它鎖死,不准任何員工在自己的層級偷偷放寬。

這就是最高的 Managed 層,由企業或 IT 部門部署(例如放在 /Library/Application Support/ClaudeCode/managed-settings.json,或 macOS 的 plist、Windows 的登錄檔)。它的特別之處不只是「優先序最高」,而是一條硬規矩:managed 層不能被下層放寬。公司在這裡擋掉某個指令,你在 User、Project、Local 任何一層想把它 allow 回來,都沒用。甚至有個 allowManagedPermissionRulesOnly 開關,能讓 Claude Code 只認 managed 的權限規則,其他層的權限一律無視。

到這裡,這條演化線就完整了,五層由高到低排下來是這樣:

  1. Managed — 公司 IT 部署,最高,且不可被下層放寬
  2. 命令列旗標 — 這一次 session 的臨時覆蓋
  3. Local.claude/settings.local.json,個人專案偏好,不進 git
  4. Project.claude/settings.json,團隊共用,進 git
  5. User~/.claude/settings.json,你跨專案的個人預設

回頭看文章開頭那條「沒生效」的規則:現在你有地圖了。它多半是被上面某一層蓋掉——可能是 Local 層有個更具體的值、也可能是公司的 Managed 層直接把你這條擋在門外。順著這五層由高往低查一遍,失蹤的規則幾乎都能找回來。

順手記幾個鍵,還有一個免開檔的捷徑

既然講到設定檔,幾個你八成會用到、但不一定知道的鍵值放在這,都寫在 User 層當個人跨專案預設最合適:

1
2
3
4
5
6
7
8
9
10
// ~/.claude/settings.json(User 層)
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"model": "claude-sonnet-5",
"editorMode": "vim", // 編輯模式,normal 或 vim
"autoMemoryEnabled": true, // 跨 session 自動記憶
"fileCheckpointingEnabled": true, // /rewind 檢查點開關
"outputStyle": "Explanatory",
"env": { "DEBUG": "1" }
}

不同鍵的重載時機不一樣,這點值得記:permissionshooksenvoutputStyle 改完免重啟就生效;model 這類要嘛下次啟動、要嘛在 session 裡用 /model 現場切。還有個容易踩的細節——User、Project、Local 這三個檔是嚴格解析的,只要壞了一個地方,整個檔會被拒收;而 Managed 層是寬容解析,壞的那條會被剔掉、其餘照用。設定改完覺得哪裡怪怪的,先下一個 claude doctor,它會把無效的項目列給你看。

最後補一個能省掉開檔的捷徑。改單一設定其實不必真的去編輯 JSON:在 prompt 裡直接下 /config 會開一個分頁式的互動介面,即時改;更快的是 /config key=value(v2.1.181 之後才有的功能,照官方文件是這個版本開始能用在 prompt 和 -p 模式裡),一行搞定:

1
2
/config editorMode=vim
/config autoMemoryEnabled=false

設定檔會不會再繼續長?大概會。這條演化線的每一節都是同一個劇本——先有一個新的使用情境擠不進現有的層,痛久了,就長出新的一層來接。所以與其把那張五層優先序表背起來,不如記住它背後的那條線:每一層的存在,都是為了回答一個「這個設定該歸誰管、管多久、能不能被別人改」的問題。下次你的設定又莫名其妙沒生效,你要問的就不再是「哪裡壞了」,而是「這一次,是哪一層在做主」。