讀完 Harness Engineering 那篇我才發現——軟體工程沒被淘汰,只是搬家了

你有沒有過那種,看完一篇技術文章之後,整個下午看自己的 codebase 都覺得不對勁的經驗?我前幾天就是。起因是被人塞了一篇 HackMD——〈Harness Engineering 完全解析〉,本來想說又一個 AI buzzword,划個五分鐘交差,結果一路讀到底,讀完之後我第一件事是打開自己手上專案的根目錄,看一眼,然後嘆了一口氣。

我那個 AGENTS.md 是空的啦。準確地說,是有寫,但寫得跟廢話文學差不多——「請遵守專案規範」「請使用 TypeScript」這種等於沒寫的句子。

那篇文章的主軸我就不全部複述了——簡單講就是把這四年 AI 工程實踐切成三代:Prompt → Context → Harness,然後說 2026 年的護城河不在模型,在環境。Birgitta Böckeler 在 Martin Fowler 網站上提的 Guides × Sensors 2×2 矩陣是骨架:Guides 是前饋(AGENTS.md、架構文件、Skills),Sensors 是回饋(lint、type checker、test、AI review)。前者告訴 Agent「好的長什麼樣」,後者驗證它有沒有照做。

聽起來很合理對吧。但我讀完最有感的不是那個矩陣——是 Chad Fowler 那句「嚴謹性的遷移(Relocating Rigor)」。工程紀律從來沒消失,只是不斷搬家。從 prompt 搬到 context,從 context 搬到 harness。

我為什麼會被這句話戳到?因為我自己最近就在不知不覺地經歷這個搬家過程,只是我沒意識到而已。

講兩個我自己踩過的雷,你就懂了。

第一個是「沒有架構文件,Agent 自己發明一套」。前陣子我開一個小專案,懶得寫 CLAUDE.md,反正 codebase 才一兩千行,模型自己看就好啦——我那時是這樣想的。然後 Claude Code 幫我加新 feature,加得很順、很快,測試也過,type 也過,我看了一眼就 merge 了。三天後我自己再回去看那段,發現它把 service 層的東西直接寫在 API route handler 裡,然後又自己抽了一個「helper」資料夾把另一半邏輯塞進去——一個專案兩種架構風格,左半 codebase 跟右半 codebase 講的是不同方言。整坨翻車。我得花一個下午把它整理成同一種寫法。

那段時間我以為是模型不夠聰明。讀完這篇我才驚覺——模型沒問題,是我前饋給得太少。Agent 不是我同事,它不會在茶水間聽到「我們這個專案 service layer 是怎麼切的」。它只能看到檔案。我什麼都不寫,它就只好自己猜。它猜得不錯,但它每次都猜得不一樣,這就是災難。

第二個是 Agent 在迴圈裡無限重試。某次我讓 Claude Code 修一個 flaky test。它跑了一次測試,失敗;改一下,再跑,又失敗;又改,又失敗——我隔壁開了個會回來,發現它已經來回改了大概八次,token 燒掉一大把,而且每次改的方向完全不一樣,有一次甚至把測試本身改掉了想繞過去。我那時是手動把它停掉的,滿慘的。

Stripe Minions 那段就是在講這個——Harness 需要有明確的退出條件。他們直接設一個迭代上限(3-5 次),過了就升級給人類,不讓 Agent 永動機式地燒錢。這個觀念聽起來很基本,但我之前真的沒想過要在自己的工作流裡明確設這個 budget。我那時候的「Harness」就是個無腦的「請繼續」按鈕。

讀完整篇之後,有一段話我抄下來貼在桌子上了——OpenAI 那邊講的:

當 Agent 犯錯時,把它當作信號:找出缺少什麼——工具、護欄、文檔——然後補回去。

這句話最狠的點在於,它把「Agent 犯錯」從一個情緒事件(嘆氣、手動修、繼續)變成一個工程訊號(看缺什麼、補上、下次不會再犯)。這跟我們做 prod incident 之後寫 postmortem 是一模一樣的肌肉啊——只是對象從同事變成 Agent 而已。

所以這幾天我打算做的事情,按優先順序:

先寫一份真的有用的 AGENTS.md。不是「請遵守規範」這種廢話,是把我腦子裡那種「我跟新人一定會講」的事情寫下來:service layer 在哪、API route 不能直接碰 DB、檔名是 kebab 還是 camel、測試放哪、commit message 用什麼格式。我會寫得跟 onboarding doc 一樣具體,因為 Agent 就是我招進來的那個永遠記不住的菜鳥。

第二,把 lint 的錯誤訊息寫成修復指示。這招我覺得是整篇文章最巧妙的設計——OpenAI 那邊把自定義 linter 的 message 寫成「請改成 X,因為本專案是 Y」。等於把前饋直接埋進回饋裡,Agent 一觸發錯誤就同時拿到診斷跟處方。我以前寫 ESLint rule 都是站在「人類工程師會 google」的假設上寫的,現在要切換到「Agent 只看你給的字串」的假設來重寫。

第三,給 Agent 設 budget。簡單到不行——在我的 workflow 裡設一個「迭代三次還沒過就 stop」的硬規則,stop 之後我自己接手診斷。不要再讓它變永動機。

第四,把 CLAUDE.md 跟 AGENTS.md 用 symlink 串起來。我用 Claude Code,但我也想保留切到 Codex 或 Cursor 的彈性。同一份文件多個 agent 都能讀——這個小工程的投資報酬率高得不合理。

至於那個 2×2 矩陣本身,老實說我覺得概念上不算新——它就是「程式設計合約 × 自動化測試」這條軸線往 AI 時代延伸的結果。但這篇文章把它整理成一個有名字、有框架、有實踐案例的東西,讓我可以拿它去說服自己(跟未來說服團隊)為什麼要花一個下午寫 AGENTS.md,而不是直接 ship feature。

最有共鳴的還是結語那句——寫程式碼的活兒在被 Agent 接管,但設計那個讓 Agent 能寫出好程式碼的世界,依然是我們的工作。我以前一直在想 staff engineer 的價值在 AI 時代會怎麼變,這篇給了我一個還算可信的答案:我們的工作從「親手蓋房子」變成「設計工地的安全規範跟驗收標準」。聽起來不那麼浪漫,但其實更接近我這幾年實際在做的事——架構決策、code review 標準、CI 設計,這些事情本來就是我七成的時間。差別只在於以前的 audience 是人類同事,現在多了一個 Agent。

而 Agent 比人類更需要明確的規則,因為它沒有「在電梯裡聽到八卦」這個 channel。

先不說了啦,我得去把 AGENTS.md 補完。順便去看一下我這週前面的 commits 有沒有哪幾條 Agent 寫的東西已經偏離我心目中的架構——如果有,那就是 Harness 的下一個 backlog 項目。

這些觀察進行於 2026 年 5 月,文章整理於 2026 年 5 月 29 日。