iT邦幫忙

2026 iThome 鐵人賽

0
Software Development

綠燈不等於做對:AI 開發的驗收工程 ——從兩個失敗的案子,到驗收交付系列 第 36 篇

Day 36 - Naur:程式 = 程式碼 + 理論,而理論會跟著人走掉

  • 分享至 

  • xImage
  •  

Part 5 開始。往回走一步。

而這一步接的是 Part 4 的主軸。 前面七天處理的是「以為驗證過了,其實沒有」;接下來四天要處理它的上游版本。

以為理解過了。

前面所有的檢查、規格、閘門,都建立在同一個前提上:你知道要做什麼。 而當你接手的是一套沒有人看得懂的舊系統,那個前提就不成立了。前面三十五天處理的都是「產出」。寫程式、建工廠、驗證。而它們有一個共同的前提:你知道要做什麼。

但很多專案的起點不是這樣。起點是一套跑了十幾年、沒人完整看得懂的系統,而你要接手它。

這四天講那件事。

先講一篇 1985 年的論文

我知道在第三十六天丟一篇四十年前的學術文章有點怪,但它是這一段的地基。論文叫《Programming as Theory Building》,作者是 Peter Naur。它的主張可以濃縮成一句:

程式設計的產物,不是程式碼,而是程式設計者腦中的「理論」。

這裡的「理論」不是學術意義的理論,比較接近一套完整的心智模型:這個系統為什麼長這樣、每個決策當初在解決什麼問題、哪些是刻意的、哪些是妥協的、要改某個東西該從哪裡下手。

而 Naur 用的那個定義更嚴格,而且不是他自己的。他借的是哲學家 Gilbert Ryle 在《The Concept of Mind》(1949) 裡的說法:

理論是「一個人為了不只能夠聰明地做某些事,還能夠解釋它們、回答關於它們的問題、為它們辯護,所必須擁有的知識」。

注意「能夠辯護」那幾個字。 這是我覺得最狠的一個判準:你能不能為一個設計辯護,決定了你到底有沒有真的懂它。(這個歸屬我一開始寫錯了,寫成「Naur 自己給的定義」。是後來回頭核對才發現的。而這正好是後面要講的那種錯:觀察對、詮釋錯。)

而程式碼和文件,都只是這個理論的投影。

Naur 由此推出三件事:

  1. 文件不是理論本身——它是理論在某個時間點、某個角度的紀錄,資訊必然損失
  2. 理論只存在於持有它的人身上——沒辦法完整寫下來,也沒辦法完整傳遞
  3. 團隊解散,理論就消亡——程式還在跑,但已經沒有人能「有把握地」修改它

第三點就是 legacy 的定義。

而這裡有一句話,我認為是整篇論文跟 AI 最直接的接點

Naur 用「腐化」(decay)解釋程式為什麼會越改越爛,而他給的病因非常精確:

腐化來自「在未恰當掌握底層理論的情況下所做的修改」。

拆開來看是這樣:同一個修改需求,通常有很多種寫法都「正確」。都會編譯過、都會通過測試、行為都符合需求。

但放在理論之下看,這些寫法非常不同。 有些是順著既有結構自然延伸的,有些是在主體上打了一塊補丁。

而兩者的差別只有持有理論的人看得出來。

Naur 舉的那個編譯器案例,結局是這樣的:一支結構優雅的編譯器,被沒有原團隊指導的後人持續修改,十年後原作者回頭看,發現「原本強而有力的結構仍隱約可見,卻被各式各樣雜亂無章的添加物弄得完全失效」。

現在把 AI 放進這句話裡:

AI 對「怎麼改最合適」的判斷,
依據的是它從文字表面歸納出來的統計相似性——
而不是 Naur 說的那種「只對理解世界的人才有意義」的相似性。

所以在沒有理論持有者把關的情況下讓 AI 自由修改,等於是給腐化裝了渦輪。這也解釋了前面三十五天講的所有東西為什麼有必要。那些檢查、規格、閘門,本質上都是在替代那個「掌握理論的人」,去判斷這次修改是延伸還是補丁。

而它們只能替代一部分。這是後面要老實面對的事。

一個推論

我以前一直以為 legacy 是技術問題。框架太舊、資料庫太老、沒有測試。做過幾個遷移案之後,我的看法變了:

你的系統不是因為用了十五年前的框架才叫 legacy。
它叫 legacy,是因為當初知道「為什麼要這樣做」的那些人,都離職了。

我遇過技術棧非常舊、但團隊還在、文件也還算完整的系統。那種要遷移其實不難,因為你隨時可以問到「為什麼」。也遇過技術棧不算太舊、但寫的人全走光的系統。那種才真的痛,因為每一行看起來多餘的程式碼,你都不敢刪。

這件事跟 AI 的關係

Naur 這篇寫於 1985 年,這兩年被大量重新提起,我認為原因很直接:

以前產出文件很貴,現在幾乎免費。

過去要產出一份三百頁的規格書,得投入好幾個人月。這個成本本身就是一道天然的過濾器。你不會為了一個你不理解的系統去寫三百頁文件,因為太貴了。

所以「文件很少」是一個看得見的問題,沒有人會誤以為自己懂了。現在不一樣。現在你可以在完全沒有建立任何理論的狀態下,擁有一整櫃看起來很專業的文件。

文件的豐富度和理解的程度,第一次徹底脫鉤。

而且這個脫鉤是不對稱的:文件豐富度看得見(可以量、可以交付、可以報進度),理解程度看不見。所以在專案管理的視角上,前者會被獎勵,後者會被忽略。

這正是 Day 05 那個場景。需求文件十天全部產完,報告寫著「100% 完成」,而所謂完成的定義只是「產出了檔案」。沒有人答得出「這些規格是對的嗎」。

https://ithelp.ithome.com.tw/upload/images/20261101/20178262rc693S17vf.png

但 Naur 本人不會同意我剛剛那句話

這一段一定要寫,因為不寫就是選擇性引用。Naur 對「復原理論」的立場比我強硬得多:

僅憑文件重建一支程式的理論,嚴格來說是不可能的(strictly impossible)。

注意措辭。不是「困難」、不是「不划算」,是「嚴格不可能」。

而且他給的建議更狠。與其復活,不如把既有程式碼丟掉,讓新團隊重新面對問題。理由是:「為了契合並支撐一份既有程式碼而去建立理論,是困難、令人挫折且耗時的」,而重新解題「更可能產出一支可存續的程式,成本不會更高、甚至可能更低」。

如果照這句話走,這一整段就不必寫了。答案是「別逆向,重寫」。

所以我要說清楚差別在哪。

一、我做的不是「僅憑文件」。

Naur 那句話的限定詞是 merely from the documentation。而後面幾天講的做法。執行切片、七觀點、來源行號綁定。輸入不只是文件,還包括跑得起來的舊系統,以及還在的業務方。

這三者的可信度完全不同,分清楚它們是整套做法的地基:

來源 是什麼 能回答
規格與文件 待驗證的假設 「當初宣稱要做什麼」
跑得起來的系統 事實 「它實際上做了什麼」
還握有理論的人 真相 「為什麼要這樣做」

文件會過時、會從沒實作過、會是一廂情願。而跑起來的系統不會騙人。但它也不會告訴你為什麼。

所以做法是:拿到規格不要直接照做,往下一層去驗;驗到了「做什麼」還缺「為什麼」,就得去找人。這就是 Naur 說的 work in close contact,只是換成了工程實作的形式。

二、我沒有宣稱能復原完整的理論。

能復原的是行為的完整覆蓋加上一份誠實的未知清單。而「為什麼」那一塊,如果沒有人能回答,正確的處理是登記成「無法考證」,不是讓 AI 填一個看起來合理的理由。

三、而「丟掉重寫」在現實中常常不是選項。跑著真實的錢、有法遵要求、有一百個在用的使用者,你不能跟客戶說「Naur 說應該丟掉重來」。

但他那句話仍然有用,用法是當成本校準:

如果逆向做到一半,發現「為什麼」幾乎每一條都答不出來——
那不是要更努力逆向,是該回頭認真評估重寫。

Naur 給的不是禁令,是一個該被放上天平的選項。而多數專案從來沒有把它放上去過。

四、還有一件事他大概也不會喜歡:我一直在用「工廠」這個詞。

因為 Naur 在同一篇裡明白批判過「生產觀點」。把工程師當成「產出活動裡容易被替換的元件」,把設計當成能沿著輸送帶組裝、打包外送的貨物。

我的辯解是 Day 19 那個二分:**我工業化的是工站,不是閘門。**規格產出、跑檢查、比對、量測。那些可以放上輸送帶。而「這個欄位該不該必填」「這道檢查該抓什麼」「這條規則為什麼存在」。那些從第一天就不在輸送帶上。

如果哪一天連閘門也自動化了,那就真的是 Naur 批判的那個東西了。 而且它的下場會很具體:新系統上線第一天,行為全對,但沒有任何人持有它的理論。出生即死亡。

明天

理論講完了,明天處理它的實務面:既然逆向出來的東西只是假設,那要怎麼做、分工怎麼切、產出該長什麼樣、什麼情況下不能只靠它。

參考文獻

  1. Naur, P.(1985)。Programming as Theory Building。Microprocessing and Microprogramming, 15(5), 253–261。
    後收錄於 Naur, P.(1992)。Computing: A Human Activity。ACM Press/Addison-Wesley,頁 227–240。
    全文 PDF(威斯康辛大學公開放置):https://pages.cs.wisc.edu/~remzi/Naur.pdf
    — 本文引用到的四處,對應原文位置如下(頁碼依 1992 年書中版):
     理論優先於文件(頁 228)/文件做不到的三件事(頁 231)/腐化來自未掌握理論的修改(頁 233–234)/生、死、復活與 strictly impossible(頁 234–235)。
  2. Ryle, G.(1949)。The Concept of Mind。Hutchinson。
    — 文中那個「不只能做,還能解釋、回答提問、為它辯護」的理論定義出自 Ryle,不是 Naur 自創,Naur 是借用它來刻畫工程師持有的知識。
    我初稿寫成「Naur 自己給的定義」,是核對後才更正的。
  3. Cockburn, A.(2006)。Agile Software Development: The Cooperative Game(2nd ed.)。Addison-Wesley,附錄 B。
    — 完整重印 Naur 原文(頁 393–405)並附 Cockburn 的評註(頁 405–406)。Day 13 用到的「文件該放什麼」出自這裡。
  4. 這篇論文從未真正「冷門」過——1985 年發表後在軟體工程領域一直有引用,2011 年有一篇 Springer 的論文把它重新用在企業架構建模上;2022 年前後因為討論「人員流動導致的知識流失」而在實務社群再度被大量轉貼;2023 年之後才因為 AI 協作的討論被推到現在的能見度。
    所以「Naur 最近很紅」這個說法並不準確。比較準確的是:它被重新提起的理由換了。

上一篇
Day 35 - 誤診防線:把「不要先懷疑什麼」寫下來
下一篇
Day 37 - 逆向工程不是翻譯:忠實翻譯會把缺陷一起搬過去
系列文
綠燈不等於做對:AI 開發的驗收工程 ——從兩個失敗的案子,到驗收交付 共 38 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言