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 來說,它可能需要:

  1. 讀取程式碼
  2. 搜尋檔案
  3. 修改內容
  4. 執行測試
  5. 查看錯誤訊息
  6. 根據結果繼續修正

關鍵不只是有沒有工具,也包括工具是否容易被正確選擇。

工具不是越多越好

名稱重疊、功能相似、說明模糊或輸入格式過於複雜,都可能提高 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 做錯時,先別急著換模型。

把以下六個面向拿出來檢查一次:

  1. 指令與脈絡
  2. 工具與執行環境
  3. 狀態與記憶
  4. 權限與行動邊界
  5. 驗證與可觀測性
  6. 反饋與調整

你可能會發現,真正需要升級的不是引擎,而是整台車如何被組裝、駕駛與煞停。

參考資料