信任不是模型的屬性:Harness 工程的策略思維

發表於

信任不是模型的屬性,而是它周圍那套系統的屬性。

問錯了問題

當企業開始將 AI coding agent 整合進開發流程時,第一個浮現的問題往往是:我們能信任 AI 產出的程式碼嗎?

這個問題問錯了。

大型語言模型本質上具有非確定性。它們並非真正理解程式碼,而是以統計機率在生成。它們不熟悉你的業務脈絡、團隊慣例,也不具備組織記憶。這不是技術缺陷,而是這項技術的根本特性。去問這樣一個系統能不能被信任,等於一次問錯了兩件事——一次錯在模型,一次錯在信任本身。

軟體工程長期以來就知道,品質不是靠最後一刻的檢查來達成,而是靠系統化的前饋控制與回饋修正。將這個原則應用到 AI agent 上,就是 Harness 工程。我們的工作不是讓模型變得可信,而是在一個不會改變的現實之上,系統性地建立信心。

等式底下的那個迴圈

在 AI agent 的世界裡,有一個簡潔的等式:Agent = 模型 + Harness。

模型是大腦。Harness 則是圍繞它的所有約束、引導與監測——system prompt、程式碼檢索機制、編排系統,以及最重要的:我們為特定系統與情境所建構的外部控制。一個設計良好的外部 Harness 有兩個明確目標:提高 agent 首次產出即正確的機率,以及建立自我修正迴圈,讓最多問題在到達人眼之前就被解決。最終效益有三個:降低人工審查成本、提升系統品質,並減少一路上被浪費的 token 消耗。

它的運作邏輯來自控制理論,分為兩個方向。

指南是前饋控制。架構文件、編碼規範、操作手冊、自訂 skill——它們預先定義期望的行為,讓 agent 第一次就朝正確方向前進。感測器是回饋控制。自動化測試、靜態分析、code review agent、執行時期的監控訊號——它們在 agent 產出的當下就觀察,並遞給它一個訊號讓它自我修正。當感測器產出專為 LLM 消費而最佳化的訊號時,效果特別強大:自訂 linter 訊息中內嵌自我修正指示,本質上就是一種正向的 prompt injection。

關鍵洞見是個老道理:如果只有回饋,agent 會不斷重複相同錯誤;如果只有前饋,你永遠不會知道規則是否真正有效。兩者必須並存。

控制分為兩種執行類型,其策略原則同樣是個老道理:能用計算式解決的,不要用推論式。 計算式控制——linter、型別檢查、結構測試、CLI 腳本——是確定性的、毫秒級的,成本趨近於零,應該無所不在地部署。推論式控制——AI code review、LLM 裁判、語意重複偵測——跑在 GPU/NPU 上,代價較高,本質上具非確定性;它們處理的是需要語意判斷的高價值場景。推論式感測器在使用適合手頭任務的模型時,能顯著提高信賴度。

控制還必須放在生命週期要求它們出現的位置。提交之前是即時感測——linter、快速測試套件、基本的 code review agent——必須在秒級內完成,才撐得住 agent 的自我修正迴圈。整合之後是深度感測,屬於 CI pipeline:突變測試(mutation testing)、能顧及更大系統圖景的廣泛審查、架構適配度檢查。還有一些品質惡化是漸進累積的,需要持續的漂移監控——死碼偵測、測試覆蓋率品質分析、相依性掃描、由 agent 觀察 SLO 的惡化趨勢,或由 AI 裁判抽樣回應品質並標記日誌異常。

人在這個迴圈裡的角色是操控:每當一個問題發生超過一次,就該改進對應的指南或感測器,直到該問題再次發生的機率降低,甚至予以杜絕。值得注意的是,操控迴圈本身也可以由 AI 加速。Coding agent 讓建構更多自訂控制與靜態分析變得更便宜——agent 可以協助撰寫結構測試、從觀察到的模式產生規則草稿、搭建自訂 linter 的雛形,或從程式碼庫考古中建立操作指南。

三個調節維度

Harness 的角色類似一個控制論的調節器(cybernetic governor),結合前饋與回饋將程式碼庫調節到其理想狀態。區分該理想狀態的多個維度,能給我們更精確的技術語言。維度有三個。

可維護性 Harness 調節的是內部程式碼品質。這是目前最容易建構的類型,因為有大量既有工具可以直接使用。計算式感測器可靠地捕捉結構性問題:重複程式碼、環形複雜度(cyclomatic complexity)、測試覆蓋率不足、架構漂移、風格違規——便宜、經證實有效、具確定性。推論式感測器可以部分解決需要語意判斷的問題:語意上重複的程式碼、冗餘的測試、暴力修復、過度設計的解決方案——代價較高、具機率性,因此不適合每個 commit 都跑。還有一類問題兩者都無法可靠捕捉:誤診問題、過度設計、誤解指示。如果人類一開始就沒有清楚說明需求,正確性本身就超出任何感測器的職責範圍。

架構適配度 Harness 調節的是應用程式整體的特性——本質上就是適配度函式(fitness function)的具體實現。效能需求作為前饋 skill;效能回歸測試作為回饋感測器,讓 agent 知道它是改善還是惡化了效能。可觀測性的編碼慣例作為前饋(例如日誌標準),再加上要求 agent 反思其日誌品質的除錯指示。這一層確保 agent 不只是寫出能運作的程式碼,而是寫出符合架構願景的程式碼。

行為 Harness 調節的是應用程式有沒有做到它該做的事。這是最核心也最具挑戰性的領域:如何引導與感測功能行為?目前賦予 coding agent 高度自主權的實務做法大致是這樣:功能規格作為前饋,從簡短 prompt 到多檔案描述;回饋則是檢查 AI 生成的測試套件是否全綠、覆蓋率是否合理,部分團隊再加上突變測試與手動測試。

為什麼行為 Harness 才是關鍵

上面那一段值得再看一次,因為整個問題就在裡面。這種方法對 AI 生成的測試投入了大量信任,而這還不夠充分。「已核准的 fixtures 模式」(approved fixtures pattern)在某些領域展現了良好成果,但它不是測試品質問題的全盤解答。那些測試,是由它們本應約束的同一個非確定性系統寫出來的——感測器與被感測的對象共用同一個故障點。

這裡需要誠實以對:找出良好的功能行為 Harness,使其足以減少監督與手動測試,仍是需要大量探索的前沿。可維護性 Harness 與架構適配度 Harness 調節的是程式碼「怎麼被寫出來」;行為 Harness 調節的是程式碼「做了什麼」——而程式碼做了什麼,正是使用者所經驗到的東西。這才是這一切之所以重要的理由。

Harness 可建置性,與 Ashby 定律的啟示

並非每個程式碼庫都同樣適合 Harness。以強型別語言撰寫的程式碼庫,自然擁有型別檢查作為內建感測器;清晰可定義的模組邊界適合架構約束規則;像 Spring 這樣的框架抽象掉了 agent 不需處理的細節,隱含地提高了它成功的機率。缺乏這些特性的系統,這些控制根本無從建構。

有一個概念值得被命名:「環境的隱性可供性」(ambient affordances)——agent 環境中使其更可被 harness 的結構特性。可讀。可導航。可處理。

全新專案與既有系統在此有本質差異。全新專案的團隊可以從第一天就把可建置性內建進去:技術決策與架構選擇,決定了這個程式碼庫未來可被治理的程度。既有系統的團隊,尤其是累積了大量技術債的應用程式,則面臨一個弔詭——harness 最被需要的地方,往往也是最難建構的地方。

Ashby 的必要多樣性定律(Law of Requisite Variety)提供了理論視角:調節器必須至少擁有與被治理系統同等的多樣性,且只能調節它有模型的東西。基於 LLM 的 agent 幾乎可以產生任何程式碼——這個空間極其龐大。採用預定義的拓撲與 Harness 模板,實質上是在策略性地縮小問題空間,讓全面的治理變得可達成。定義拓撲本身就是一種減少多樣性的舉動。

大多數企業的服務拓撲可以歸納為少數幾種模式,涵蓋了 80% 的需求——透過 API 暴露資料的商業服務、事件處理服務、資料儀表板。在成熟的工程組織中,這些早已以服務模板的形式編碼化。下一步演進是 Harness 模板:一捆預先配置的指南與感測器,把 coding agent 拴在特定拓撲的結構、慣例與技術棧上。團隊未來可能部分根據已有哪些可用的 Harness,來選擇技術棧與結構。當然,Harness 模板會面臨與服務模板相同的版本管理挑戰:一旦團隊實例化它們,就開始與上游改進失去同步——而非確定性的指南與感測器使測試更加困難,可能讓這個問題更為嚴峻。

人的角色

作為人類開發者,我們把自身的技能與經驗當成一種隱性的 Harness 帶到每個程式碼庫:吸收慣例與良好實踐、感受複雜性的認知負擔、知道自己的名字在 commit 上。我們還攜帶著組織對齊——知道團隊試圖達成什麼、哪些技術債因商業理由而被容忍、以及在此特定脈絡中「好」看起來是什麼樣子。我們以小步驟、以人類的步調前進,這為經驗被觸發與應用保留了思考空間。

Coding agent 沒有這些。沒有社會問責。對三百行的函式沒有美學上的厭惡。沒有「我們這裡不是這樣做」的直覺。沒有組織記憶。它不知道哪個慣例是承重的(load-bearing),哪個只是習慣,也不知道技術上正確的解決方案是否適合團隊的方向。

Harness 是嘗試把人類開發者經驗所帶來的東西外化並使之明確,但它只能做到某種程度。建立一個連貫的指南、感測器與自我修正迴圈系統是昂貴的,所以必須懷著明確的目標來排定優先順序:一個好的 Harness 不應該以完全消除人類輸入為目標,而是要把它導向最要緊的地方。

邊界正在鬆動,以及接下來會是什麼

本文提出的心智模型描述的是實踐中已經發生的技術,並提供一個框架來討論仍待釐清的事。當前有幾項實踐值得關注:以自訂 linter 與結構測試強制執行分層架構,加上週期性的「垃圾收集」掃描漂移並讓 agent 建議修復;pre-push hook 依啟發式規則執行相關 linter,把回饋盡早引入 agent 工作流程;突變測試與結構測試作為計算式回饋感測器的復興;將 LSP 與程式碼智慧整合到 coding agent 中,作為計算式前饋指南;以計算式與推論式感測器結合 agent 來處理架構漂移。

仍有許多問題有待釐清。當 Harness 成長時,如何保持其連貫性,讓指南與感測器保持同步、不互相矛盾?當指示與回饋訊號指向不同方向時,能在多大程度上信任 agent 做出明智的取捨?如果感測器從未觸發,那是高品質的跡象,還是偵測機制不足的跡象?

我們需要一種類似程式碼覆蓋率與突變測試之於測試那樣的方式,來評估 Harness 的覆蓋率與品質。前饋與回饋控制目前散落在交付步驟各處,而能夠幫助我們把它們當成一個系統來設定、同步與推理的工具,具有真正的潛力。

信任,說到底,不是模型的屬性,而是它周圍那套系統的屬性——而那套系統是建出來的,不是撿到的。 建構這個外部 Harness 正在成為一種持續的工程實踐,而不是一次性的設定。模型是大腦,Harness 是紀律。而信心,正是從紀律裡來的。

回到研究與洞察