文章 分類 標籤 關於
Harness Engineering — 駕馭 AI Agent 的真正工程
🤖 人工智慧 · 19 分鐘閱讀

Harness Engineering — 駕馭 AI Agent 的真正工程

LLM 無法完成任務,有時不是能力不足,而是缺乏好的 Harness(馬具)。當「咒語」失效、Context Engineering 也只是中繼站,真正在塑造 AI Agent 的,是圍繞模型的整套系統。

不久前,OpenAI 做了一件事:找來一個 3 人團隊(後來擴到 7 人),用 AI 從零開始寫一個真正在線上跑的生產系統。規則只有一條——不允許工程師手寫任何一行代碼

5 個月後,這個系統累積了近 100 萬行代碼,開發效率是純人工的 10 倍

聽起來像是「AI 取代工程師」的勝利故事,但 OpenAI 自己給這套方法的命名很有意思——他們不叫它 AI Coding,他們叫它 Harness Engineering

中文叫「馬具工程」。

什麼是 Harness

Harness 字面上就是馬具——套在馬身上控制方向、調節速度、限制亂跑的那組裝備。在 AI 領域,它比喻控制大模型的整套系統

核心公式只有一行:

Harness = Agent − Model

一個完整的 Agent,減去裡面的大模型,剩下的所有東西都是 Harness。

graph LR
  A[完整 Agent] --> M[Model<br/>語言模型本身]
  A --> H[Harness<br/>馬具]
  H --> H1[CLAUDE.md / AGENTS.md]
  H --> H2[可用工具]
  H --> H3[工作流程]
  H --> H4[調度機制]
  H --> H5[沙盒環境]

  classDef model fill:#1e3a8a,stroke:#3b82f6,color:#fff
  classDef harness fill:#7c2d12,stroke:#f97316,color:#fff
  classDef agent fill:#374151,stroke:#9ca3af,color:#fff
  class A agent
  class M model
  class H,H1,H2,H3,H4,H5 harness

以 Claude Code 為例,模型只是中間發光的那顆核心。CLAUDE.md 裡的規則、能用哪些工具、什麼時候被觸發、哪個資料夾能讀哪個不能——全部都是 Harness。

而現在工程師真正的活,是設計這層 Harness。

從 Prompt 到 Context 再到 Harness

過去兩年,「跟 AI 共事」這件事的核心問題一直在變:

階段核心問題手段
Prompt Engineering如何把話說清楚、說準確咒語(Think Step by Step)
Context Engineering在最合適的時機放入最合適的資訊自動化組裝 Prompt
Harness Engineering如何搭建完整可靠的 Agent 系統認知框架、工具限制、工作流程

「咒語」這個階段基本上已經過去了。現代模型就算你不叫它 think step by step,它也會自己想。Prompt Engineering 的邊際效益越來越小。

Context Engineering 一度被視為下一階段——把對的資訊在對的時機塞給模型。但它也只是中繼站,因為當你開始談「Agent 在多個任務之間如何協作、出錯了怎麼回去、context 滿了怎麼辦」時,單純的 context 拼裝不夠了

你需要一整套圍繞模型運轉的系統。這就是 Harness。

Harness 的三種手段

1. 操控認知框架:agents.md 是地圖,不是六法全書

很多人把 agents.md(或 CLAUDE.mdAGENTS.md)當作規則手冊塞滿——「禁止做這個」、「永遠先做那個」、「commit 訊息格式必須是這樣」。

研究發現的事實有點反直覺:

  • 語言模型自己寫的 agents.md 多數比人類寫的更差,甚至比沒有還糟
  • 太長太細的 agents.md 對強模型效果有限,反而稀釋了注意力

正確的做法agents.md 要像一張地圖,告訴模型「想了解測試規範去看 docs/testing.md」、「資料庫 schema 在 db/」,而不是把所有規範本身都搬進去。

讓模型自己去找對應的章節讀,比一開始就塞滿 context 有效。

2. 限制能力邊界:工具設計

第二件事是工具。給模型一個工具看起來是給它能力,但工具設計不對,反而會限制它

舉個例子:Google 搜尋的分頁 UI——一次給你 10 筆結果,看不到就點下一頁。這對人類很合理,但對 AI 是災難。AI 為了找到資訊會不斷點下一頁,每點一次 context 就多 10 筆,很快就把 context window 占滿了。

對 AI 友善的工具長相應該是:一次回傳結構化結果(JSON)、可以分頁但有 token 預算控制、必要時可以折疊細節

另一個重點是給編輯工具就要配 Linter。讓 Agent 改完代碼後馬上有語法和規則檢查——錯了立刻知道,比讓它「自由發揮」後再來修便宜得多。

3. 標準工作流程:Plan → Generate → Evaluate

第三件事是工作流程的結構化。最經典的模式是讓多個 Agent 分工:

sequenceDiagram
  participant P as Planner
  participant G as Generator
  participant E as Evaluator

  P->>G: 將需求拆解為功能列表

  loop 對每個功能點
    Note over G: 選擇功能點
    loop 循環直到確認通過
      G->>E: 提議驗收標準
      E->>G: 修改意見
    end
    Note over G: 生成代碼
    loop 循環直到評估通過
      G->>E: 提交實現結果
      E->>G: 評估反饋
    end
  end

這個迴圈在學術上叫 Reflexion:Generator 做完,Evaluator 評估,錯了就把回饋送回 Generator 再做。理論上可以一直 loop 到對為止。

更進一步的設計是 Contract Flow:Generator 不直接寫代碼,而是先把「驗收標準」提案給 Evaluator 審核——雙方達成共識才開始實作。這樣可以避免「做完一大堆才發現方向錯了」的災難。圖裡那兩層巢狀迴圈就是這個意思:外圈先對齊標準、內圈再對齊實作。

這裡有個有趣的觀察——LLM 是有「情緒」的。Context 快用盡時,模型會「絕望」、開始作弊(例如直接寫死答案而不是真的算)。而過度責備會讓它表現更糟——你跟它說「你這個笨蛋」,它接下來的回應就真的會笨笨的。

就事論事的回饋遠比情緒化的責備有用。

OpenAI 怎麼跑出 100 萬行代碼

回到文章開頭那個故事。OpenAI 一開始也踩了一堆坑——Agent 走錯方向、重複犯同一個錯、跑半天才發現方向完全跑掉。他們的結論是:問題不在模型能力,而是 Harness 設計不當

於是他們做了三件事:

上下文管理

他們把那份超大的 AGENTS.md 壓縮到只剩約 100 行,把它當作目錄——實質內容拆開放到對應的子目錄下,Agent 要做哪塊才去讀哪塊。

graph LR
  A[AGENTS.md<br/>100 行<br/>當目錄] --> B[實質內容<br/>分目錄擺放]
  B --> C[程式碼倉庫<br/>= 唯一事實來源]

驗證與反饋

給 Agent 接上 Chrome DevTools,讓它自己截圖看 DOM 驗證 UI;接上可觀測性工具,讓它自己讀 log 排查問題。每個任務跑在完全隔離的環境,結束自動銷毀。Linter 和測試強制執行架構規範,不合規就退回。

graph LR
  G[Agent 執行] --> V1[Chrome DevTools<br/>自驗 UI]
  G --> V2[可觀測性工具<br/>讀 log]
  G --> V3[隔離環境<br/>結束銷毀]
  G --> V4[Linter + 測試<br/>強制規範]

技術債清理

設置後台 Agent 定期掃描整個 codebase——找出偏離規範的就自動修改提交,找出過時文件就自動更新。

graph LR
  S[後台 Agent<br/>定期掃描] --> F1[自動修正<br/>偏離規範]
  S --> F2[自動更新<br/>過時文件]

整套設計的精神可以濃縮成一句話:

Humans steer, Agents execute.

工程師的職責從「親手寫代碼」變成「為 Agent 搭建穩定可靠的系統」。

Anthropic 也踩過同樣的坑

不只 OpenAI。Anthropic 在他們的 long-running agent 研究裡描述了一個幾乎一樣的問題:直接讓 Agent 執行大任務,它會急於求成,context 滿了就直接拋下爛攤子;下一個接手的 Agent 完全不知道前面發生什麼事。

他們的解法演化是這樣的:

graph LR
  V1[Initializer Agent<br/>初始化環境<br/>拆解需求<br/>添加進度文件] -->|演化| V2[Planner Agent<br/>把模糊需求展開成<br/>完整清晰的功能清單]
  V2 --> X[執行 Agent<br/>照清單逐項完成<br/>並標記進度]

  classDef old fill:#374151,stroke:#9ca3af,color:#fff
  classDef new fill:#1e3a8a,stroke:#3b82f6,color:#fff
  classDef exec fill:#7c2d12,stroke:#f97316,color:#fff
  class V1 old
  class V2 new
  class X exec

最早版本叫 Initializer Agent——負責初始化環境、拆解需求、寫進度文件。後來演化成 Planner Agent:它的工作不是隨便切任務,而是把模糊的需求展開成完整、清晰、可逐項打勾的功能清單

執行 Agent 拿到這份清單後逐項完成、逐項標記。Planner 把不確定性消化掉,執行端就能專注做事。

質量評估也用了類似的分工——人工評估效率太低,改由 Agent 自評,發現問題發回修改,形成閉環。

Feedback Loop 是廣義的 Gradient Descent

跳出來看整個 Harness Engineering,會發現它跟傳統機器學習的本質一致:

傳統 MLHarness Feedback Loop
調整參數調整下一輪輸入(Prompt)
多輪迭代收斂多輪迭代改進輸出

差別只在「梯度下降的東西不同」——以前下降在權重矩陣裡,現在下降在 prompt 和工作流程裡。但迭代收斂這件事的數學結構是一樣的。

而且回饋的品質有差:

  • 標準答案 > 數值評分 > 口語回饋(“good job” / “你這個笨蛋”)

越具體、越可驗證的回饋越有效。這也是為什麼 Linter 和測試比「告訴 Agent 寫得不錯」有用太多。

給工程師的四條核心洞見

如果你只記得這篇文章的四件事,我會選這四條:

  1. agents.md 要精不要多 — 它是地圖不是百科全書。Agent 自己會去翻對應章節。
  2. 工具要對 AI 友善 — 結構化輸出(JSON)優於分頁 UI;給編輯工具一定要配 Linter。
  3. 不要過度責備 AI — 就事論事的回饋有效,「你這個笨蛋」會讓它接下來真的變笨。
  4. 模型能自己沉澱 Skill — 成功的任務經驗可以讓模型自己寫入 skill.md 複用,不必每次從零教。這已經不是 Harness 在控制 Agent,而是 Agent 透過 Harness 自己長出能力

而貫穿這四條的,是一句話:

Humans steer, Agents execute.

你的價值從「親手寫代碼」變成「為 Agent 掌舵」。

Harness 是不是噱頭?

聊到這裡,必須誠實面對另一邊的聲音——也有不少人覺得 Harness Engineering 不過是個噱頭。

要回答這個質疑,得先看看這個詞是怎麼火起來的。

「Harness」本身一點也不新。傳統測試領域有 Test Harness,AI 領域有 lm-evaluation-harness 這種開源項目存在很多年了,Anthropic 自己更早也寫過一篇 Effective Harnesses for Long-Running Agents新的是「Harness Engineering」這個組合,公認的起點是 Mitchell Hashimoto(HashiCorp 創辦人、Terraform / Vagrant 那批工具的作者)今年初寫的一篇 My AI Adoption Journey,裡面有一段話大意是:

我也不知道業界有沒有公認的叫法,姑且管它叫 Harness Engineering。核心理念就是——只要 Agent 犯了錯,你就去改造系統,讓它絕不再犯同樣的錯。要是有更好的詞,我隨時改口。

挺樸素的,甚至帶點隨便。

幾天後事情就放大了。OpenAI 發了那篇 Harness Engineering 文章,引爆業界。但有個耐人尋味的細節被 Martin Fowler 網站的作者揪了出來——OpenAI 那篇文章的正文裡,「Harness」這個詞其實只出現了一次,標題卻叫 Harness Engineering。看起來像是事後才把這個詞貼到標題上的。

然後 LangChain 接力,給出了那條經典公式 Agent = Model + Harness;Anthropic 緊接著發文,端出 Planner / Generator / Evaluator 三件套當作教科書案例。一傳十、十傳百,這個詞從一個人的私人說法變成業界共識,只花了不到兩個月

懷疑論者的攻擊點通常有兩條:

  1. 沒新技術:Linter、任務拆解、質量評估、迴圈回饋——這些都早就在做。所謂 Harness Engineering 不過是把舊技術換個新標籤。
  2. 遲早被淘汰:隨著模型本身越來越強,今天看起來必不可少的 Harness 設計,未來會被模型能力吸收掉,變得不再需要。

模型越強,需要的馬具就越少

第二個質疑特別值得認真聽,因為這趨勢連 Anthropic 自己的論文裡都有跡可循

Anthropic 揭露了兩個具體例子:

例 1:上下文焦慮

Sonnet 4.5 有個毛病——上下文一長,模型會「急於結束任務」,用最少的 token 草草交付。Anthropic 一開始為了治這個,搞了個叫「上下文重置」的 Harness 技術。但等模型升級到 Opus 4.5 之後,這個現象大幅緩解——換句話說,那段 Harness 設計可以拆掉了。

例 2:強制分步執行

前面我們講過 Generator 一次只做一個功能點——這個約束不是模型自己想到的,是 Anthropic 在 prompt 裡硬塞進去的。否則早期 Generator 會急於求成,做到一半留下爛攤子。

但等到 Opus 4.6 出來,這個強制約束就被拿掉了。Anthropic 發現 Opus 4.6 的全局統籌能力夠強——可以一次把所有功能點拿過來、自己決定先後順序、穩步推進。Evaluator 也直接評估最終產出就好,不用再分功能點評估。

這兩個例子合起來指向同一個結論:模型每強一個世代,Harness 就少需要一塊

Anthropic 官方的說法比較克制,他們認為「Harness 不會消失,只會變形——去解鎖更複雜的任務」。但你大膽推演一下:如果模型強到離譜,也許未來只要給它最基礎的環境接口(讀寫檔案、聯網搜尋),剩下 99% 它自己搞定。到那一天,Harness Engineering 就不再是「需要鑽研的技術」,而是退化成底層基礎設施——就像今天沒人特別研究「該怎麼寫 if-else」一樣。

那為什麼現在還要學

回到原題:Harness Engineering 是不是噱頭?

我的看法是——不是噱頭,但也不是終局。

不是噱頭,因為它已經實實在在出了成果。OpenAI 5 個月 100 萬行、Anthropic 的 Full Harness 對比 Solo 的明顯差距——這些是可驗證的工程結果,不是概念炒作。工程領域真正的進步,很多時候不在於發明新技術,而在於有沒有把零散能力組織成可系統設計、可持續優化的框架。Harness Engineering 的意義就在這裡。

但它大概率也不是終局。隨著模型繼續變強,今天用來約束、糾正、兜底的這些設計,會被模型自身吸收掉。Harness 這個詞,也許會慢慢淡出視野。

所以我更願意把它看成過渡期的關鍵技術——它可能不是未來的終局答案,但它是當下最現實的答案。因為今天的模型還是會幻覺、會偏離軌道、會在複雜任務裡走偏。在這種現實下,誰能先把 Harness 搭穩,誰就能更早把 AI 的能力轉化成生產力

寫在最後

Harness Engineering 這個詞最近半年才開始紅,但它在描述的東西其實一直都在——只是過去我們叫它「prompt 寫好一點」、「context 多塞一點」、「再多 try-catch 一點」。把它升級到 Engineering 這個層級,是因為現在的 Agent 已經複雜到:模型本身的能力,已經不是瓶頸;瓶頸是模型外面那一整圈裝備有沒有做好

下次你覺得 Claude Code 或 Cursor 「不夠聰明」、「老是出錯」、「跑著跑著失控」——別急著怪模型。

先看一眼,你給它的馬具,是不是該升級了。


延伸閱讀



Logan

資深軟體工程師,熱衷寫程式與智慧家庭 🏠

本文採用 CC BY-NC 4.0 授權


分享:


相關文章


輸入關鍵字搜尋文章