SSD Nodes Learn 🎉 VPS $5.50/月起
指南 Matt Connor作者: Matt Connor · 已更新 2026-08-13

為什麼 coding agent 會忽略你的指示?

instruction file 只是 context,不是強制設定。了解 coding agent 忽略規則的 4 個原因,並在重寫規則前先完成診斷。

為什麼 coding agent 會忽略你的指示

coding agent 會因為 4 個原因忽略你的指示,而且原因不是你的語氣太客氣。規則可能根本沒有載入 context window。規則可能過於模糊,無法用來檢查某個動作。context 中可能有其他內容與規則衝突,通常就是 agent 剛讀取的程式碼。規則也可能仍然載入,但位於目前回合之前很遠的位置,導致 agent 依據附近的內容工作。

每個原因都有對應的修正方式,因此第一步是區分這些原因。使用大寫字母和 IMPORTANT 並不能診斷問題。以下說明以 Claude Code 為實例,因為截至 2026 年 8 月,其載入與壓縮行為已有詳細文件。其他工具的細節不同,但整體行為相同。

先說明 2 個術語。context window 是模型在特定回合中看到的文字區塊,包括 system prompt、你的 instruction files、對話內容,以及 agent 讀取的每個檔案。harness 是模型周圍的程式,也就是從磁碟讀取檔案並組合該區塊的程式。這篇文章中幾乎所有抱怨,實際上都是在抱怨 harness,而不是模型。

您的 instruction file 是訊息,不是設定

Instruction file 不是 configuration。執行環境不會讀取 CLAUDE.md 並強制套用其中的內容。harness 會從磁碟讀取該檔案,再將文字貼入對話。在 Claude Code 中,這些內容會以 system prompt 之後的 user message 傳送,因此模型看到這些規則的方式,與看到您輸入的其他內容相同。

這會造成一個令人不安的結果。您的規則會與視窗中的其他文字競爭,彼此具有相同的優先地位。規則是一項主張。agent 剛開啟的檔案則是證據。兩者不一致時,證據往往會勝出,而且不會觸發錯誤,因為從模型的角度來看,沒有任何事情發生異常。

官方文件已清楚說明:instruction file 會被視為 context,而不是受強制執行的 configuration。若要無論模型如何決定都阻止某項操作,就需要使用 hook,而不是寫下一句規則。請記住這一點。本文結尾的大多數修正方式,都是將這項原則套用到特定案例。

載入哪些 instruction 檔案,以及何時載入

Claude Code 會從啟動目錄沿著目錄樹向上搜尋。從檔案系統根目錄到工作目錄之間的每個 CLAUDE.mdCLAUDE.local.md,都會在啟動時完整載入。這些檔案會依該順序串接,因此距離啟動目錄最近的檔案最後讀取;在同一個目錄中,.local 檔案會接在主要檔案之後。

工作目錄下方子目錄中的檔案則不同。這些檔案不會在啟動時載入,而是在 agent 讀取該目錄中的檔案時載入。.claude/rules/ 中帶有 paths: frontmatter 欄位的路徑範圍規則也相同:只有在讀取相符檔案時才會加入 context,而不是每一輪都載入。

這項差異解釋了許多已回報的失敗案例。你將規則放在 packages/api/CLAUDE.md,接著詢問 API,agent 卻從未開啟 packages/api/ 下的任何檔案,因此直接回答。這不是規則被忽略,而是規則根本尚未存在於 context 中。如果你的 repository 將指引分散在 monorepo 中各 package 的 instruction 檔案,每次都應先檢查這一點。

另一個載入陷阱,也是「agent 忽略我的指示」最常見的原因:Claude Code 讀取的是 CLAUDE.md,而不是 AGENTS.md。如果 repository 統一使用 AGENTS.md,卻沒有 CLAUDE.md,Claude Code 完全沒有可載入的內容。支援的銜接方式是建立 CLAUDE.md,其第一行為 @AGENTS.md;Claude Code 會在啟動時透過這一行載入該檔案,下面則可加入 Claude 專用備註。如果沒有其他內容要新增,也可以使用 symlink。至於該檔案本身應放入哪些內容,則是另一個問題,詳見將 agent instruction 與人類文件分開

確認檔案已載入,再進行改寫

在確認 agent 能讀取檔案之前,不要修改文字。這裡有兩項檢查,先執行成本較低的檢查。

在工作階段中執行 /context。此命令會依類別列出目前的內容,其中 Memory files 清單會列出實際載入的每個指示檔案。檔案若未出現在清單中,就不在目前對話內,因此寫入其中的內容不會產生作用。/memory 會列出檔案位置並開啟檔案供編輯,也會列出尚不存在的檔案。

若要取得更確切的結果,請記錄載入事件。每當 CLAUDE.md 或規則檔案進入內容時,InstructionsLoaded hook event 就會觸發;其中的 matcher 會指出載入原因:session_startnested_traversalpath_glob_matchincludecompact。將以下內容放入 .claude/settings.json

{
  "hooks": {
    "InstructionsLoaded": [
      {
        "matcher": "nested_traversal",
        "hooks": [
          {
            "type": "command",
            "command": "cat >> /tmp/instructions-loaded.log"
          }
        ]
      }
    ]
  }
}

hook 會將其 payload 以 JSON 格式接收於 standard input,因此 cat 會附加完整記錄。工作時使用 tail -f /tmp/instructions-loaded.log 監看記錄。此事件會忽略 exit status,因此 hook 只能觀察,不能阻擋。如果預期會載入巢狀檔案,但該檔案在工作階段中從未出現在記錄裡,請停止改寫文字。問題出在檔案位置。

長時間工作階段對規則的影響

這裡有兩種不同的影響,需要採取不同的因應方式。

距離。 第 1 輪提出的規則到了第 90 輪仍在上下文視窗中,但此時必須與最近 90 輪、且更貼近目前工作內容的文字競爭。無法透過設定消除這種影響,但可以測量。請在新的工作階段中執行相同工作。如果規則在新工作階段中有效,卻在長時間工作階段的後段失效,原因就是距離。

壓縮。 上下文視窗填滿時,harness 會摘要目前為止的對話,然後從該摘要繼續執行。能保留下來的內容,取決於摘要器判定哪些資訊重要;這不一定符合你的判斷。Claude Code 會依機制記錄其結果,而且差異很大。專案根目錄 CLAUDE.md 和未限定範圍的規則,會在壓縮後從磁碟重新注入。Auto memory 也會從磁碟重新注入。含有 paths: frontmatter 的規則會遺失,直到再次讀取相符的檔案為止。子目錄中的巢狀 CLAUDE.md 檔案會遺失,直到再次讀取該子目錄中的檔案為止。

依照該表格排列指示後,規則的脆弱程度順序就很清楚了。只在聊天中輸入的規則,是工作階段中最脆弱的內容:只有摘要碰巧保留該規則時,它才會持續有效。位於 packages/api/CLAUDE.md 的規則次之,因為它只載入過一次,之後可能在摘要時被移除,必須等到該目錄中的檔案下次被讀取時才會恢復。專案根目錄檔案中的規則最持久,因為每次都會從磁碟重新讀取。

因此,如果指示必須在整個工作階段中持續有效,就應放在不含 paths: frontmatter 的專案根目錄檔案中。其他做法都代表取捨,應該基於目的主動選擇。管理哪些內容留在上下文視窗中會說明 /compact 搭配 focus 引數,以及不同工作之間的 /clear;這兩者都會影響摘要器決定你的規則內容的頻率。

為什麼周邊程式碼會勝過規則

這是人們最常描述、卻最少正確診斷的失敗情況。檔案規定資料庫存取必須透過 repository layer。agent 卻撰寫了直接呼叫 ORM(object relational mapper)的 handler。這不是因為風格要求被忽略,而是因為現有證據勝出。

規則描述偏好,程式碼則展示實際做法。agent 開啟準備修改的 module 中 3 個檔案,而這 3 個檔案都直接呼叫 ORM 時,context 的一側只有 1 句抽象規則,另一側則有 3 個具體、近期且符合任務的範例。複製本地模式通常是正確行為。這裡之所以錯誤,是因為你知道 context 不知道的事:這些檔案是 legacy code。

因此,請將這項資訊寫入規則。明確說明自身反例的規則,才能在實際 repository 中持續有效。只陳述偏好的規則則無法做到。

新增的資料庫存取都必須透過 app/repositories/app/legacy/ 下的檔案仍會直接呼叫 ORM。那是舊程式碼,不是應遵循的模式。不要複製它。

真正發揮作用的是第二句。它會在 agent 找到這些內容前,先告訴 agent 即將看到什麼,以及應如何解讀。相同的修正也適用於任何 repository 明顯違反的規則:歷程未遵循的 commit style、整個測試套件只有一半遵循的 test layout,或只適用於新程式碼的 import convention。只要程式碼與檔案內容不一致,就應在檔案中明確說明這項不一致。

模糊的規則無法檢查,因此也無法遵循

「撰寫乾淨的程式碼。」「不要過度設計。」「保持簡單。」「小心處理遷移。」這些規則都無法針對特定操作進行測試,無論是由 agent 測試,或由你測試都一樣。當 agent 收到一項無法用來檢查自身輸出的規則時,只能自行猜測,而你也只能憑感覺評分。

請對檔案中的每一行套用以下測試。寫出一個 shell command,在規則遭到違反時以非零狀態結束。如果你無法寫出這個 command,該規則就不可檢查。比較以下配對:

  • 不可檢查:「讓函式保持精簡。」可檢查:「長度超過 60 行的函式,上方必須有註解說明原因。」
  • 不可檢查:「測試你的變更。」可檢查:「執行 npm test,並在宣告 task 完成前貼出失敗計數。」
  • 不可檢查:「保持檔案井然有序。」可檢查:「HTTP handler 存放於 src/api/handlers/。該目錄不得放入其他內容。」
  • 不可檢查:「正確格式化程式碼。」可檢查:「.ts 檔案使用 2 個空格縮排。」

「不要過度設計」是人們最先放棄的規則,因為修正方式不是把句子縮短,而是把句子寫長:明確說明可行的最小變更實際代表什麼,才能讓 agent 依據具體標準檢查自己的 diff。

大小也是相同問題,只是換了個形式。Claude Code 的指引要求每個 instruction file 少於 200 行,並直接指出檔案越長,遵循程度越低。700 行的檔案不代表指示更明確,而是包含 700 行主張,更容易彼此矛盾;此外,每一個 turn 都會將這些內容計入你的 window,並直接反映在 token 使用量中。將檔案分成多個 heading,讓讀者能快速找到各項規則,相關做法請參閱撰寫 agent 能夠執行的 instruction file

十分鐘內完成診斷

請依序執行以下步驟。直接跳到最後一步,通常只會得到一份充滿強硬規則、卻仍然無法運作的長檔案。

  1. 確認檔案已載入。 執行 /context,查看 Memory files 清單。如果找不到該檔案,請修正位置後停止。清單中的其他步驟目前都不適用。
  2. 在全新工作階段重現問題。 啟動新的工作階段,並提供應觸發該規則的最小工作。若在此處遵守規則,但於長時間工作階段中失敗,表示問題可能出在內容距離或壓縮。若在此處也失敗,問題就在規則本身。
  3. 移除競爭因素。 在現有程式碼已遵循該規則的目錄中,要求進行相同變更。如果遵循情況恢復,表示周遭程式碼的指示優先於你的句子。
  4. 搜尋衝突。 兩個檔案對同一行為提供不同指示,便是已知的失敗原因:模型可能任意選擇其中一個,而且不會告訴你它這麼做。
  5. 讓規則可檢查,然後重新測試。 使用具體路徑與條件重寫規則。如果遵循率大幅提升,表示措辭就是原因。

第 4 步只需執行一個命令。請搜尋所有指示來源中的相關主題,不要只搜尋你正在編輯的檔案:

grep -rni "migration" --include="CLAUDE.md" --include="CLAUDE.local.md" .
grep -rni "migration" .claude/rules/ ~/.claude/CLAUDE.md ~/.claude/rules/ 2>/dev/null

如果兩個檔案中的指示不同,這就是問題所在。刪除其中一個。不要試圖用更強烈的措辭排列優先順序,因為沒有可供申訴的排序引擎。

依影響力排序的修正方式

以下各步驟的影響力依序高於前一步驟,但設定成本也更高。規則只需低成本重新措辭時,先從最上方開始。當規則重要到不能接受偶爾遺漏時,立即往下採用更強的方式。

  1. 讓規則具體化。 指定路徑、命令或條件。加入 agent 將在 repository 中找到的反證,如前文所示。這不需額外成本,卻能修正出乎意料多的案例。
  2. 將規則移到管轄對象附近。 可以使用巢狀的 CLAUDE.md、在 .claude/rules/ 中設定作用域限於路徑的規則,或直接在檔案頂端加入註解。如此一來,規則會與適用的程式碼在同一次讀取中載入。必須接受這項取捨:以這種方式載入的內容會在下一次壓縮時移除,並在下一次符合條件的讀取時重新載入。
  3. 將強制執行移入 hook。 文字說明只能提出要求,hook 則會做出決定。hook 會在固定的生命週期事件中以程式碼執行,不論模型得出什麼結論都會套用。
  4. 將規則交給確定性工具,並刪除文字說明。 例如格式化、import 順序、行長度、禁止的 import 及 commit message 格式。使用 ruff formatprettier --writeeslintpre-commit hook。formatter 每次都能正確執行,且不消耗 token。句子大多數時候都能正確發揮作用,但每一輪都會消耗 token。

以下完整說明第 3 步。假設 migration 檔案絕對不能由 agent 編輯。將以下內容放入 .claude/settings.json

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/guard-migrations.sh"
          }
        ]
      }
    ]
  }
}

再將以下內容放入 .claude/hooks/guard-migrations.sh

#!/usr/bin/env bash
set -euo pipefail

path=$(jq -r '.tool_input.file_path // empty')

case "$path" in
  */migrations/*)
    echo "Files under migrations/ are written by hand. Stop and ask first." >&2
    exit 2
    ;;
esac

exit 0

執行 chmod +x .claude/hooks/guard-migrations.sh,接著啟動新的工作階段,並要求 agent 編輯 migrations/ 下的檔案。編輯會遭到拒絕,且你的訊息會以原因形式傳回。PreToolUse 的結束狀態 2 會在工具呼叫執行前將其阻擋,而 stderr 文字則會以阻擋訊息形式傳給模型。${CLAUDE_PROJECT_DIR} 會解析為 project root,因此無論 agent 位於哪個目錄,hook 都能正常運作。agent 不必同意規則、記住規則,或在目前上下文中仍保留規則。編輯不會發生。

如果只是沒有任何邏輯的單純禁止事項,設定中的 permissions.deny 也能完成相同工作,而且不需要維護 script;權限模式會決定哪些操作可在不先詢問你的情況下執行。如果某項指示確實必須位於 system prompt 層級,而不是 user message 中,--append-system-prompt 可將其放置於該處;但每次 invocation 都必須傳入,因而更適合 script,而非互動式工作。

無法靠指示消除的問題

請清楚區分哪些部分由你負責。放置位置、措辭、檔案之間的衝突,以及檔案大小,都是作者的問題,也應由作者修正。其餘部分屬於模型行為,改善措辭無法消除這些問題。

同意不代表遵循。 Agent 可能會確認規則、正確重述規則,卻在兩次工具呼叫後違反規則。這種確認不需付出任何代價,也無法預測後續行為。不要把它視為修正,也不要把它算作測試。

有些習慣會持續出現。 例如加入註解、加入防禦性錯誤處理、撰寫結尾摘要,或執行下一個顯而易見的命令。即使規則禁止,這些行為仍會再次出現,只是發生率降低而不是降為 0。你可以測量自己的發生率:在全新的 session 中重複執行相同任務 10 次,並計算違規次數。如果某個數值必須是 0,就不應只把規則留在提示中。

你目前的 session 會成為範例。 如果 agent 在第 12 回合違反規則,而你放任不管,該違規行為就會成為 context 中的示範,而且比規則更接近目前內容。看到違規時應立即修正。未修正的違規會教會 agent 在其餘 session 中重複該行為。

指示檔不是安全邊界。 指示檔會影響行為,但不會強制執行。任何遺漏代價高昂的事項,例如 credentials 或具破壞性的命令,都應交由權限或 hook 控制。避免 agent 接觸 secrets 對資料也適用相同原則:不要要求 agent 不讀取檔案,而應安排讓該檔案無法讀取。

簡而言之,先證明檔案已載入,讓規則可檢查,將規則移到其管轄對象旁邊;如果遺漏率仍然重要,就不要再依賴文字說明。Agent 無法忽略的規則,才不是要求 agent 遵守的規則。

FAQ

為什麼 Claude Code 會忽略我的 CLAUDE.md?

先確認它是否已載入,再假設它遭到忽略。執行 /context,查看 Memory files 清單;未列在其中的檔案不在目前對話中。指示檔會在 system prompt 之後以 user message 傳入,並被視為內容,而不是強制執行的設定,因此無法保證嚴格遵循。實際上多半是以下 4 種情況之一:檔案位於 agent 從未讀取的子目錄、兩個檔案內容衝突而模型任意選擇其中一個、規則過於模糊而無法據此檢查操作,或周邊程式碼呈現出與規則相反的做法。

在工作階段中途編輯指示檔會有影響嗎?

不會影響已在對話中的副本。工作目錄上層的檔案會在啟動時完整載入,因此模型持有的是啟動當下的內容。若要載入編輯後的內容,請啟動新的工作階段,或要求 agent 使用一般檔案工具讀取該檔案,讓目前版本以新的訊息加入對話。壓縮內容後,系統會從磁碟重新讀取專案根目錄檔案,因此新版本也會在該時點載入。

根目錄的 CLAUDE.md 與巢狀檔案內容衝突時,哪個檔案優先?

兩者都不具可靠的優先順序。系統會將找到的檔案串接到內容中,而不是彼此覆寫;檔案會依檔案系統根目錄到工作目錄的順序排列,因此距離工作目錄最近的檔案只會最後讀取。系統沒有用來解決矛盾的優先順序引擎,且 Claude Code 文件指出,互相衝突的規則可能會被任意處理。請將巢狀檔案撰寫成增補內容,並明確指定其適用路徑;不要試圖透過提高優先順序來解決衝突,應直接刪除矛盾內容。

我的指示能在 /compact 後保留嗎?

這取決於指示的載入方式。專案根目錄的 CLAUDE.md、未指定範圍的規則及自動記憶內容,會在壓縮內容後從磁碟重新注入。具有 paths: frontmatter 的規則,以及子目錄中的巢狀 CLAUDE.md 檔案,會遺失,直到再次讀取相符的檔案為止。你只在聊天中輸入的內容,只有在摘要器恰好保留時才會繼續存在。若規則必須在整個工作階段中持續有效,請將它放在專案根目錄檔案中,且不要使用 paths: frontmatter。

什麼情況下應將規則改用 hook,而不是文字說明?

當檢查可由確定性邏輯完成,且漏檢的成本高於撰寫小型 script 的成本時,就適合使用 hook。檔案路徑限制、commit 前必須執行的命令,以及禁止的工具呼叫都符合這項條件。若 PreToolUse hook 以 status 2 結束,便會直接阻止工具呼叫,並將 stderr 文字傳回模型作為原因;無論規則是否仍存在於內容中,都能確實執行。凡是 formatter 或 linter 能夠判定的事項,都應交由該工具負責,並從指示檔中完全刪除。