您透過 /model 切換模型,再試一次同一項任務,得到的答案卻不一樣。至於 CLAUDE.md,代理讀取的方式沒變;執行指令前照樣詢問權限,hook 也照常觸發。可見,這些東西並不在模型裡。
接下來會說明模型的邊界在哪裡,以及模型外圍的程式從哪裡開始。弄清楚這點,就知道代理出錯時該檢查什麼。
模型與 harness
模型會處理收到的上下文,產生回答或工具呼叫。例如,它會選擇要讀取哪個檔案、執行哪個指令。要完成這些動作,模型需要外圍程式來存取檔案、執行指令,再把結果交還給模型。
英文資料會把這套程式稱為 harness。字面意思是"馬具"(沒錯,就是套在馬身上的那種),中文裡通常直接說 harness,可以理解成代理的執行框架。Anthropic 的文件說得很直接:Claude Code 是 harness,Claude 則是裡面的模型。這個詞也常見於一般代理的文章,記下來會有幫助。
圖中的 harness 會整理上下文、檢查權限,並執行模型提出的工具呼叫。模型下方的箭頭代表迴圈:工具結果會回到上下文,模型再選擇下一步,或完成回答。回答結束不代表任務已解決,成果仍需要確認。
您已經設定過的項目
以下是 harness 在 Claude Code 中的組成。右欄列出檔案和指令,方便您在專案或工作階段中找到各項機制。
| Harness 組成 | 作用 | 查看位置 |
|---|---|---|
| 系統指示 | Claude Code 會在您送出第一則訊息前把它們加入上下文:工作方式、可用工具,以及工作階段所在資料夾 | /context 輸出中的 System prompt 項目 |
CLAUDE.md | 代理在工作階段開始時讀取的專案規則 | 專案根目錄中的檔案 |
| 工具 | 讀取和修改檔案、搜尋,以及在終端機執行指令 | 工作過程中出現的 Read(...) 和 Bash(...) 等項目 |
| Skills | 模型可依任務選用,或由您明確呼叫的指示 | .claude/skills/、/skills |
| MCP | 連接外部服務與即時資料的橋樑 | /mcp |
| 子代理 | 使用獨立上下文的另一個執行者 | .claude/agents/ |
| 權限請求 | Harness 會確認動作是否獲准;必要時會徵求您的同意 | 執行指令或修改前,終端機會詢問 |
| Hooks | 您設定的工作階段事件指令,不需要模型決定就會觸發 | /hooks |
| 上下文與工作階段 | 模型目前能看到的內容,以及可返回的時間點 | /context、/clear、/rewind |
| 代理迴圈 | 把工具結果交還模型,讓它選擇下一步 | 模型收到單一請求後連續採取多個動作 |
CLAUDE.md 和 skills 會提供指示,但模型可能誤解或漏掉規則。權限檢查和已設定的 hooks 指令則由程式執行,結果取決於您設定的條件和指令本身。
表格沒有列出 Plugins,因為它不是單一組成,而是一個套件:可以一次安裝多個 skills、指令或 hooks。
同一個模型,不同的表現
想像一個無法連接您專案和終端機的網頁聊天工具。它也有自己的 harness:對話紀錄、介面,有時還包括網路搜尋或檔案上傳。在這種聊天工具裡,模型可以解釋要怎麼修改並展示程式碼;而 Claude Code 能存取專案,就可以直接把修改寫進檔案。模型相同,能力卻不同,因為外圍程式不同。
/model 的情況正好相反:模型換了,harness 保持不變,所以規則、工具和權限請求都還在。
取決於模型的,是它如何理解任務、選擇工具和評估結果。Harness 則負責整理上下文、提供工具並檢查權限。例如,模型可以要求取得缺少的檔案,harness 會讀取檔案,再把內容交還給模型。
代理很肯定地討論一個專案裡早已不存在的函式?先確認最新程式碼是否已加入上下文。您可以在檔案路徑前加上 @,把程式碼貼進訊息,或透過讀取工具取得。前兩種方式不一定會出現獨立的讀取呼叫。如果有呼叫工具,請查看它回傳的是檔案內容,還是存取或路徑錯誤。若上下文裡沒有程式碼,請提供程式碼或要求它讀取檔案。若程式碼已在上下文中,但結論有誤,就對照具體程式行檢查推理。這時也可以試試另一個模型。
代理出錯時該改什麼
偶爾出錯,直接補一句通常就能修正:"檔案找錯了,請看 src/utils.js。"如果每個工作階段都重複出錯,就該檢查指示和可用資料。也許每次都得重新解釋同一條規則。
實際上可以這樣處理:
- 代理每次開新的工作階段都會忘記專案規則,例如透過
npm test執行測試 - 把規則寫進CLAUDE.md。重要規則明確記在檔案裡,比期待它記得對話中的提醒可靠; - 同一套流程已經解釋第三次了 - 該把它整理成 skill,讓代理依任務載入指示。工作時確認 skill 是否有被呼叫;如果沒有,就用
/skill-name手動呼叫,並換成 skill 的實際名稱; - 代理對它沒有的資料憑空猜測 - 把需要的資料交給它:用
@將檔案加入上下文,或透過 MCP 連接外部服務。光是叫它別猜,並不能解決問題; - 代理沒執行檢查就說"完成了" -
Stop事件的 hook 可以自行執行測試,不必由模型決定。最後仍由您根據指令輸出,而不是根據代理的報告來驗收; - 需要的資料都已提供並讀取,但代理仍在複雜推理上卡住 - 透過
/model試試其他模型,並用同一項任務比較結果。
先確認需要的資料和工具是否都可用。如果問題出在推理,可以直接試試另一個模型。比較結果品質和 /usage 中的用量:反覆嘗試失敗,同樣會消耗額度和您的時間。
GO TO FULL VERSION