Harness Engineering:Agent = Model + Harness
AI Agent 做不好,很多人的第一個反應是:
「是不是模型不夠強?要不要換最新版?」
模型能力當然重要。但如果同一個模型換到不同的工具、權限與執行環境,表現可能完全不同,那麼問題就不只在模型本身。
有時候 Agent 不是不夠聰明,而是它拿不到需要的資料、不知道專案規則、選錯工具,或根本沒有機會檢查自己做得對不對。
這篇文章想談的,就是 Harness Engineering。
什麼是 Harness Engineering?
Harness 原意是「馬具」或「安全帶」。放在 AI Agent 的世界裡,可以把它理解成包住模型、讓模型真正完成工作的整套工程系統。
Addy Osmani 在介紹這個概念時,引用了 Viv Trivedy 提出的一個簡單公式:
Agent = Model + Harness
模型之外,還有 prompts、tools、context policies、hooks、sandboxes、orchestration、feedback loops 與 recovery paths 等外圍機制。
換句話說,模型比較像引擎。
Harness 則決定:
- 模型看得到什麼
- 可以使用哪些工具
- 能把事情做到哪一步
- 如何知道自己做錯了
- 出事時能不能安全停下來
引擎再強,如果沒有方向盤、儀表板、安全帶與煞車,也很難放心讓它上路。
為了方便理解與檢查,以下將 Harness Engineering 整理成六個面向。
一、指令與脈絡:Agent 知道該做什麼嗎?🧭
Agent 是否知道任務目標、專案規則、完成條件,以及哪些背景資訊真正重要?
這一層包括:
- System prompt
AGENTS.md- Skills
- 專案文件
- 執行過程中動態載入的 context
很多人遇到 Agent 做錯,第一個動作是把 prompt 寫得更長。
但 prompt 變長,不代表 Agent 得到的資訊更好。如果把所有規格、歷史紀錄、工具說明和參考資料一次塞進去,真正重要的指令反而可能被淹沒。
重點不是提供最多資訊,而是在正確的時間,提供足夠、相關且可信的資訊。
以修改程式為例
Agent 至少要知道:
- 這次要解決什麼問題?
- 哪些檔案不能碰?
- 專案使用什麼測試方式?
- 怎樣才算真正完成?
少了這些背景,Agent 即使產出看似合理的程式碼,也可能不符合專案的實際需求。
二、工具與執行環境:Agent 有能力完成任務嗎?🛠️
Agent 可以讀取哪些檔案、呼叫哪些 API、使用瀏覽器,或執行哪些指令?
只有模型時,它通常只能產生文字。接上工具與執行環境之後,才有機會把「回答問題」變成「完成任務」。
以 Coding Agent 來說,它可能需要:
- 讀取程式碼
- 搜尋檔案
- 修改內容
- 執行測試
- 查看錯誤訊息
- 根據結果繼續修正
關鍵不只是有沒有工具,也包括工具是否容易被正確選擇。
工具不是越多越好
名稱重疊、功能相似、說明模糊或輸入格式過於複雜,都可能提高 Agent 選錯工具的機率。
權限過大的工具,更會放大誤操作造成的影響。
工具真正的價值,不是讓 Agent 看起來無所不能,而是讓它能在清楚的範圍內完成工作。
三、狀態與記憶:Agent 知道自己做到哪裡嗎?🧠
長任務不可能只靠模型在同一段對話裡記住所有事情。
當任務跨越許多步驟,甚至多個工作階段時,Agent 必須知道:
- 目前做到哪裡?
- 已經做過哪些決定?
- 哪些方法試過但失敗了?
- 下一步應該處理什麼?
這些狀態不能只留在愈來愈長的對話紀錄裡。
進度、決策、產出與待辦事項,可以寫進檔案或其他可持續保存的狀態。大型工具輸出也可以先卸下,等真正需要時再讀取,避免占滿 context。
常見的脈絡管理方式
常見做法包括:
- **Compaction:**壓縮過長的對話與任務脈絡。
- **Tool-call offloading:**將大型工具輸出移出主要 context。
- **Progressive disclosure:**只在需要時載入 skills 與工具說明。
這裡的記憶,不是要求 Agent 永遠記住所有內容,而是讓重要狀態可以被保存、查找與交接。
四、權限與行動邊界:Agent 不能做什麼?🔒
Agent 能做什麼之外,更重要的是:它「不能」做什麼?
例如:
- 可以讀取資料,不代表可以修改。
- 可以建立草稿,不代表可以直接發布。
- 可以準備指令,不代表可以刪除資料或推送到正式環境。
如果這些邊界只寫在 prompt 裡,仍然可能被忽略或誤解。
有些限制可以透過指令提醒;有些則必須由 sandbox、allowlist、permission gate 或 hooks 強制執行。
常見的行動邊界設計
例如:
- 限制 Agent 只能在指定工作區修改檔案。
- 高風險指令執行前,必須取得人工確認。
- 禁止直接推送到正式環境。
- 完成草稿後只能進入待審核狀態,不能自動發布。
「✋請不要做」和「🚫系統不允許做」,是兩個不同等級的安全設計。
成熟的 Agent 系統,不只設計 Happy Path,也會預先思考:當 Agent 不知道、做不到或判斷不確定時,應該如何停止、回報,或把決定交還給人。
五、驗證與可觀測性:Agent 真的完成了嗎?🔍
Agent 說「完成了」,不代表真的完成。
如果系統只留下最後的答案,我們很難知道:
- 它讀了哪些資料?
- 呼叫過哪些工具?
- 在哪一步失敗?
- 為什麼得到現在的結果?
- 花了多少時間與成本?
所以,Harness 還需要可觀測性。
除了看見過程,也要有方法驗證結果。
不同任務的驗證方式
- **程式任務:**執行測試、lint 與 typecheck。
- **內容任務:**檢查資料來源、格式與驗收規則。
- **高風險或主觀判斷:**加入人工審核。
Anthropic 的長時間應用開發實驗,進一步把 Planner、Generator 與 Evaluator 分開:
- **Planner:**負責規劃。
- **Generator:**負責執行。
- **Evaluator:**依照事先定義的標準檢查結果。
每個 sprint 開始前,Generator 與 Evaluator 還會先約定「怎樣才算完成」。
這不是所有任務都需要的架構,但它提醒了一件事:
如果沒有明確的完成條件,Agent 很容易在「看起來差不多」的地方停下來。
六、反饋與調整:系統有沒有從失敗中變得更可靠?🔄
真正值得累積的,不是某一次 Agent 剛好成功,而是每次失敗之後,整套系統有沒有變得更可靠。
將失敗轉化成工程改進
- 漏跑測試,就把測試接進完成流程。
- 長任務容易偏離,就增加任務拆解、階段檢查或交接狀態。
- 高風險動作容易誤觸,就把人工確認放進權限邊界。
- 工具失敗後只會重複執行,就提供更清楚的錯誤訊息或有限重試機制。
每次失敗,都可以回到一個更具體的問題:
這次真的是模型能力不足,還是缺少資訊、工具、狀態、限制或驗證?
這也是 Harness Engineering 最有價值的地方。
它把「Agent 今天狀況不好」這類模糊抱怨,轉化成可以觀察、測試與持續改進的工程問題。
Harness 不是越複雜越好
Anthropic 在較早使用 Sonnet 4.5 的長任務實驗中,因為觀察到 context anxiety,採用了 context reset 與 structured handoff。
後來改用 Opus 4.5 時,這個問題大幅減少,因此新的 Harness 移除了 context reset,改由 automatic compaction 處理。
這個例子剛好說明:
每一個 Harness 元件,背後都代表一個對模型能力與失敗模式的假設。
當模型能力改變,原本必要的機制可能變成多餘的成本;新的能力也可能開啟更長、更複雜的任務,進而帶來新的問題。
如何開始設計 Harness?
比較實用的做法,不是先畫出一套最完整的 Agent 架構,而是從真實任務開始。
第一步:定義想要的行為
先說清楚 Agent 應該完成什麼,以及怎樣才算成功。
第二步:記錄實際發生的失敗
觀察 Agent 在哪些環節出錯、卡住或做出不安全的判斷。
第三步:加入對應的工程機制
只加入能處理該失敗的機制,並透過測試確認它真的有效。
結論:需要升級的可能不是模型,而是整台車
下一次 Agent 做錯時,先別急著換模型。
把以下六個面向拿出來檢查一次:
- 指令與脈絡
- 工具與執行環境
- 狀態與記憶
- 權限與行動邊界
- 驗證與可觀測性
- 反饋與調整
你可能會發現,真正需要升級的不是引擎,而是整台車如何被組裝、駕駛與煞停。
參考資料
- Addy Osmani,〈Agent Harness Engineering〉
https://addyosmani.com/blog/agent-harness-engineering/ - Anthropic,〈Harness design for long-running application development〉
https://www.anthropic.com/engineering/harness-design-long-running-apps
