Agent Harness Engineering

Agent Harness Engineering

@addyosmani
英語5 天前 · 2026年5月09日

AI 功能

798K
3.2K
458
77
7.8K

TL;DR

Harness Engineering 將 AI 模型周圍的架構視為一個動態的產物。透過將每一次 Agent 的失敗轉化為永久性的規則或工具調整,開發者能夠構建出遠超原始模型效能的系統。

一個編碼 Agent 是由模型及其周圍所有建構元素所組成的。Harness 工程將這個框架視為一個有生命的產物,每當 Agent 犯錯時就加以強化。

簡單來說:每當 Agent 失敗時,你就設計一個永久性的解決方案,讓它永遠不會再犯同樣的錯誤。

過去兩年,業界一直在爭論模型:哪個最聰明、哪個寫的 React 最乾淨、哪個幻覺最少。雖然這個討論很重要,但它忽略了系統的另一半。

模型只是運行中 Agent 的一個輸入。其餘的是 harness:圍繞模型構建的提示詞、工具、上下文政策、鉤子、沙盒、子 Agent、反饋迴路和恢復路徑,讓它能夠實際完成任務。

一個不錯的模型搭配一個優秀的 harness,始終勝過一個優秀的模型搭配一個糟糕的 harness。越來越多的有趣工程工作不在於選擇模型,而在於設計圍繞它的框架。

這門學科現在有了名字。@Vtrivedy10 創造了「harness 工程」這個術語,清晰地分解了 harness 的實際構成以及每個部分存在的原因。其他業界聲音,如 @dexhorthy 追蹤新興模式、HumanLayer 將 Agent 失敗視為配置「技能問題」、Anthropic 的工程團隊發布關於長期運行應用設計的指南,以及 Birgitta Böckeler 探索用戶端體驗,都在趨向於同一個想法。

這篇文章將這些線索串聯起來。

Harness 到底是什麼?

Trivedy 的核心定義已經完成了大部分工作:

Agent = 模型 + Harness。如果你不是模型,你就是 harness。

Harness 包含了所有不屬於模型本身的程式碼、配置和執行邏輯。一個原始模型不是 Agent。只有當 harness 為它提供狀態、工具執行、反饋迴路和可執行的約束時,它才成為 Agent。

Addy Osmani - inline image

具體來說,harness 包括:

  • 系統提示詞、CLAUDE.md、AGENTS.md、技能檔案和子 Agent 指令。
  • 工具、技能、MCP 伺服器及其技術描述。
  • 捆綁的基礎設施,例如檔案系統、沙盒和無頭瀏覽器。
  • 用於生成子 Agent、處理交接和路由模型的編排邏輯。
  • 用於確定性執行的鉤子和中介軟體,例如 lint 檢查或上下文壓縮。
  • 用於日誌、追蹤、成本和延遲計量的可觀測性工具。

核心而言,Agent 是一個在循環中執行工具以達成目標的系統。真正的技能在於設計工具和這個循環。

雖然這代表了巨大的表面積,但這是你的表面積,而不是模型提供者的。Claude Code、Cursor、Codex、Aider 和 Cline 都是 harness。底層模型可能跨平台相同,但你體驗到的行為是由 harness 主導的。

讓我們重新定義「技能問題」

當 Agent 做出不合理的事情時,工程師通常會責怪模型,並將問題歸類為「等待下一個版本」來修復。

Harness 工程思維拒絕這種預設。失敗通常在某種程度上是可解的。如果 Agent 忽略了某個慣例,就將其添加到 AGENTS.md。如果它執行了破壞性命令,就編寫一個鉤子來阻止它。如果它在 40 步的任務中迷失了方向,就將架構拆分為規劃者和執行者。如果它總是提交有錯誤的程式碼,就在循環中加入型別檢查的反向壓力信號。

正如 HumanLayer 所說:「這不是模型問題。這是配置問題。」考慮效能基準:一個領先的模型在現成框架中運行,其得分通常遠低於同一個模型在自訂、高度調校的 harness 中運行。將模型移動到具有更好程式碼庫工具、更精確提示詞和更強反向壓力的環境中,可以解鎖原始設定所遺留的能力。

當今模型理論上能做到的與你實際看到它們做到的之間的差距,很大程度上是 harness 的差距。

棘輪效應:每個錯誤都變成一條規則

Harness 工程中最關鍵的習慣是將 Agent 的錯誤視為永久信號——而不是一次性、重試後就忘記的僥倖事件。

如果一個 Agent 提交了一個帶有被註解掉的測試的 PR,並且意外地被合併了,這就是一個輸入。AGENTS.md 的下一個迭代必須聲明:「永遠不要註解掉測試;刪除或修復它們。」下一個 pre-commit 鉤子應該自動標記 diff 中的 .skip(。審查子 Agent 必須更新以阻止被註解掉的測試。

約束條件應該只在觀察到實際失敗時才添加,並且只在有能力模型使其變得冗餘時才移除。一個好的系統提示詞中的每一行都應該追溯到一個特定的歷史失敗。

正因如此,harness 工程是一門學科,而不是一個通用的框架。特定程式碼庫的正確 harness 完全由其獨特的失敗歷史所塑造。

從行為反向設計

設計 harness 最有效的方法是從期望的行為開始,然後構建實現它的組件:我們想要的行為 → 實現它的 Harness 設計。

Harness 的每個部分都必須有明確的工作。如果你無法說出某個組件存在的具體行為,就應該將其移除。

Addy Osmani - inline image

檔案系統和 Git - 持久狀態

檔案系統是基礎。模型只能操作適合其上下文視窗的內容。檔案系統提供了讀取資料的工作區、卸載中間工作的場所,以及多個 Agent 協調的表面。

加入 Git 提供了免費的版本控制,讓 Agent 可以追蹤進度、分支實驗和回滾錯誤。

Bash 和程式碼執行:通用工具

大多數 Agent 在 ReAct 循環上運行:推理、透過工具呼叫行動、觀察、重複。與其為每個可能的動作預先構建工具,不如讓 Agent 擁有 bash 訪問權限,讓它可以即時構建所需的工具。

Agent 通常擅長 shell 命令,使 bash 和程式碼執行成為自主解決問題的預設策略。

沙盒和預設工具

Bash 只有在安全運行時才有用。沙盒為 Agent 提供了隔離環境來執行程式碼、檢查檔案和驗證工作,而不會危及主機。

一個好的沙盒附帶強大的預設值:預先安裝的語言運行時、測試 CLI 和無頭瀏覽器,讓 Agent 可以觀察自己的工作並閉合自我驗證迴路。

記憶和搜尋:持續學習

模型除了訓練權重和當前上下文之外沒有其他知識。Harness 使用記憶檔案(如 AGENTS.md)來彌補這個差距,將知識注入每個會話。

對於即時資訊,如新的函式庫版本或即時資料,網路搜尋和 MCP 工具直接內建在 harness 中。

對抗上下文腐化

隨著上下文視窗填滿,模型的推理能力會下降。Harness 使用三種主要技術來管理這種稀缺性:

  • 壓縮:智能地總結和卸載較舊的上下文,以防止 API 錯誤。
  • 工具呼叫卸載:將大型工具輸出(如 2000 行的日誌)儲存在檔案系統中,同時僅在上下文中保留必要的標頭和頁尾。
  • 漸進式揭露:僅在任務明確要求時才顯示指令和工具,而不是在啟動時加載所有內容。

長期執行

自主、長期運行的任務會遭受過早停止和問題分解不良的困擾。Harness 透過結構設計來應對:

  • 循環:攔截模型嘗試退出的行為,並強制它在新的上下文視窗中繼續朝著完成目標前進。
  • 規劃:強制模型將目標分解為逐步的計劃檔案,並在每一步之後透過自我驗證鉤子檢查其工作。
  • 拆分:將生成和評估分離到不同的 Agent 中,防止模型在評估自己工作時固有的正向偏差。

鉤子是你的執行層

鉤子彌合了請求動作和執行動作之間的差距。它們在特定的生命週期運行:在工具呼叫之前、在檔案編輯之後、或在提交之前。鉤子阻止破壞性命令、強制自動格式化以節省 token,並執行測試套件。

理想情況下,成功是無聲的,失敗是詳細的。如果型別檢查通過,Agent 什麼也聽不到;如果失敗,錯誤會直接注入回循環中進行自我修正。

這是規則手冊和工具選擇

儲存庫根目錄中的一個純文字 Markdown 檔案仍然是最高槓桿的配置點。然而,它必須像飛行員檢查清單一樣對待,而不是風格指南。保持簡短,並確保每條規則都是透過過去的失敗贏得的。

同樣的紀律也適用於工具。十個高度集中的工具總是勝過五十個重疊的工具。

此外,由於工具描述會填充提示詞,惡意或草率的外部整合(如未經驗證的 MCP 伺服器)可以在 Agent 開始工作之前就將不良提示詞注入其中。

在生產環境中是什麼樣子

我所見過最清晰的成熟 harness 公開圖像是 Fareed Khan 對 Claude Code 架構 的(估計)分解。

Addy Osmani - inline image

上一節的幾乎每個概念都以命名組件的形式出現在這個圖表中。上下文注入是知識層。循環狀態存在於記憶體儲存和工作樹隔離器中。破壞性動作鉤子位於權限閘門之後。子 Agent 上下文防火牆是整個多 Agent 層。工具分發註冊表是 MCP 伺服器和 bash 的接入點。Claude Code 的發展軌跡至少與底層模型一樣關乎 harness。

Harness 不會縮小,只會移動

隨著模型的改進,對 harness 的需求不會消失——它會轉移。

人們很容易認為更好的模型會使框架變得過時。例如,最近的模型升級大大減少了對「上下文焦慮」緩解措施的需求。但隨著下限的提高,上限也在提高。以前無法達到的任務現在變得可行,帶來了全新的失敗模式。

Harness 中的每個組件都編碼了一個關於模型無法自行完成什麼的假設。當模型改進時,過時的框架應該被移除,並且必須建立新的框架以到達下一個地平線。

訓練循環呢?

Harness 設計和模型訓練之間存在著活躍的反饋循環。

當今的模型通常在循環中使用特定的 harness 進行後期訓練,造成一定程度的過擬合。模型變得特別擅長 harness 設計師優先考慮的特定動作(例如,檔案系統操作、bash、子 Agent 分派)。

這使得 harness 成為一個活的系統,而不是靜態的設定檔,並證明了「最佳」harness 是專門為你的特定任務和工作流程優化的那個。

Harness 即服務 (HaaS)

業界正在從基於 LLM API(提供補全)構建轉向基於 Harness API(提供運行時)構建。SDK 現在直接提供了循環、工具、上下文管理、鉤子和沙盒。

現代預設不再是從頭開始構建編排,而是選擇一個 harness 框架,配置其核心支柱,並專注於純領域特定的提示詞和工具設計。

這就是使故障排除可擴展的原因:你正在調整一個結構良好的配置表面,而不是重新發明整個 Agent 架構。

未來發展方向

如果你看看當今頂尖的編碼 Agent,它們看起來比它們底層的模型更相似。模型不同,但 harness 模式正在趨同。業界正在迅速識別將生成文字轉化為可出貨軟體所需的承重框架。

最令人興奮的開放問題正在超越單一 Agent:協調多個 Agent 並行工作、讓 Agent 能夠分析自己的追蹤以修復 harness 層級的失敗,以及構建能夠即時動態組裝工具的環境。

最終,這是 harness 從靜態設定檔開始更像編譯器的階段。

如果你正在尋找一個優秀的 Agent harness 框架,@FredKSchott 寫了 Flue。它很紮實,而且顯然是受到這篇文章早期版本的啟發!

更多可拆解樣本

近期爆款文章

探索更多爆款文章

為創作者而生。

從全球 𝕏 爆款文章裡發現選題,拆解它為什麼能爆,再把可複用的內容結構變成你的下一篇創作靈感。