"The death of a program happens when the programmer team possessing its theory is dissolved."
—— Peter Naur, Programming as Theory Building (1985)
一、馬康多的失憶症與無狀態的 Agent
在《百年孤獨》裏,馬康多小鎮曾遭遇過一場離奇的失眠症。失眠帶來的可怕副產品是不可逆的失憶,人們先是忘記童年,接着忘記日常器物的名字,最後連事物的用途和價值也徹底遺忘。
為了對抗這場危機,他們用蘸着墨水的刷子給萬物貼標籤:桌子、椅子、時鐘、門、牆壁……甚至在母牛頸上掛起牌子,巨細靡遺地寫下使用說明:「這是母牛,每天早晨必須擠奶,才能得到牛奶;牛奶必須煮沸,才能兌上咖啡。」
圖靈獎得主 Peter Naur 在四十年前曾提出一個深刻的洞見:編程的本質不是生產源代碼文本,而是構建一套存在於開發者腦海中的「心智理論(Theory)」。一旦掌握這套理論的團隊解散,哪怕源代碼一行未損,這個程序在實質上也已經死亡。
到了 AI 編程時代,這句工程論斷成了日常現實。
Coding Agent 就像馬康多鎮上不斷失憶的居民。每次開啟新會話(Session),它都是一張白紙;隨着對話拉長,上下文又會被壓縮或遺忘。哪怕在同一個倉庫裏,提示詞稍有偏差,它對領域概念的理解就會飄移:今天把某個實體當作「已結算交易」,明天新開會話,又按字面意思當成了「待處理請求」。
倉庫裏若只有代碼而無外化的文檔與規則,系統很快就會在反覆失憶中走向混亂。
二、文檔:從裝飾品到輸入上下文
在傳統軟件工程中,寫文檔既痛苦,又常遭邊緣化。
敏捷宣言高喊「工作的軟件高於詳盡的文檔」,很多團隊便順理成章地不寫文檔。即使寫了,大部分架構圖和 Wiki 也在寫完的第二周開始過期。在很多工程師眼裏,文檔是做給領導看的、或者應付審計的裝飾品。
「代碼即文檔(Code as documentation)」一度成為主流信條。這在人腦協同的小團隊裏或許勉強能跑,因為人類工程師有口耳相傳的隱性知識(Tacit Knowledge),有同理心,還能拉個會議當面溝通。
但在 AI 時代,「代碼即文檔」行不通。
代碼只記錄**「現在怎麼實現(How)」,無法解釋「為甚麼這麼做(Why)」、「哪些事絕對不能做(Invariants)」以及「業務名詞的邊界在哪裏(Domain Language)」**。
把百萬行代碼的倉庫交給 Agent 而不給文檔,它就只能從現有代碼反推業務邏輯。一旦歷史代碼本身充滿妥協和壞味道,Agent 就會照單全收並繼續放大,寫出能跑但業務邏輯錯誤的代碼。
在 AI 協作中,文檔不再是事後補交的作業,而是直接輸入給 Agent 的前置約束。
三、三類核心工程文檔
工程實踐中最關鍵的文檔只有三類,各自鎖定不同層面的事實。
AI 擅長按通用常識「腦補」。業務概念若未在系統中嚴格界定,它就會自行發揮。
例如金融系統裏「結算(Settlement)」與「清算(Clearing)」制度截然不同,電商系統裏「庫存鎖定」與「庫存扣減」也處於不同生命周期。Agent 一旦混用,底層數據模型就會出錯。
在倉庫根目錄維護一份精簡的領域詞彙表(如 CONTEXT.md),只寫名詞定義與狀態邊界,不寫技術實現。Agent 每次啟動都先讀取這份詞彙表,就不會自行發明平行概念。
大部分糟糕的重構,都源於對歷史背景的無知。
Agent 分析代碼時,常覺得某段設計「不夠優雅」,主動提議用流行模式重寫。它並不知道,那個看似笨拙的設計是三個月前為了解決某處罕見邊界衝突而特意留下的。
架構決策記錄(Architecture Decision Records, ADR)用來記錄歷史取捨。一份合格的 ADR 包含四項內容:
- 當下面臨的上下文與制約;
- 做出的具體決策;
- 放棄的備選方案及原因;
- 帶來的後果與妥協。
這讓 Agent 明白系統的歷史約束,知道有些代碼之所以長成這樣,是權衡後的必然選擇,而非歷史包袱。
向 Agent 開放讀寫文件、執行命令與調用 API 的權限,若不劃清行為邊界,它很容易隨意升級基礎依賴、在主分支強推代碼,或順手改掉全局配置。
針對 Agent 的操作守則,主要規定四類操作邊界:
- 哪些分支和文件夾是唯讀的;
- 遇到失敗時的升級策略;
- 依賴安裝的具體策略(例如禁用浮動版本);
- 每次提交前必須運行的驗證命令。
四、保持文檔與代碼同步
寫文檔容易,維持文檔與代碼一致很難。
過期文檔對 Agent 的誤導比沒有文檔更嚴重。要避免文檔腐爛,需要靠工具強制同步:
- 文檔即單一事實源(Single Source of Truth):接口定義、錯誤碼枚舉與業務規則表直接生成代碼或作為測試輸入,避免手動維護兩份數據。
- CI 一致性檢查(Gate Check):在 CI 中校驗文檔與測試的對應關係。例如需求文檔新增了規則而測試套件缺少對應用例時,直接阻斷構建。
五、小結
在代碼庫中維護領域詞彙、ADR 與操作守則,本質上是在無狀態的會話之間保存系統的「設計意圖」。
測試與 CI 負責攔截明確的對錯,文檔負責統一業務語義。但那些既不觸發編譯錯誤、也不違反業務名詞,卻在持續改動中累積的結構腐敗與架構壞味道,又該如何發現?