程式碼誤解的流行病學 - 減法開發

現在每個人都可以在幾個提示詞內就產出數千行程式,一天產出量連頂尖工程師都未必讀得完,程式碼從原本「資產+負債」的雙重屬性,逐漸傾向「純技術債」這一側。

程式碼(技術債)呈指數上升,因此帶來的維護成本浮上檯面,已經是現代軟體開發最大的問題。

雖然製造技術債的速度呈指數上升,但解決技術債的速度可能只有線性的提升,這是因為重構(Refactoring)、資料遷移(Data Migration)等重要工作經常隱含了大量沒有寫在程式碼與文件內的地雷,對相關技術棧不夠有經驗的工程師都很容易出錯,何況是缺乏歷史上下文的 AI。

好處是團隊規模逐漸變小,以前解決技術債需要一大堆會議討論的冗長過程,現在可能只需要跟一兩個架構師討論,但遠比不上程式碼增加的速度。

過多無用的功能與程式碼會在 AI 時代帶來很高的維護成本,任何會沿著誤解樹傳播的東西都會呈 O(k^N) 成長。

  • error propagation in complex systems, e.g.: - API semantic drift - database schema corruption

k 的決定因素:誤解的繁殖力

k 取決於一個誤解在這個領域裡「能感染多少個相鄰的地方」。

程式碼維度的 k,也就是一個誤解在技術上能傳播多遠,由耦合度、隱蔽性、可複製性決定。

組織維度的 k,也就是一個誤解在現實中會被多少人觸及,由工作邊界、團隊規模、和現在的 AI 普及程度決定。

傳統開發裡 k 的天然上限來自的不是社交接觸,而是工作邊界。每個工程師有負責的領域,前端工程師不太會動資料庫 schema,後端工程師不太會動 iOS 程式碼。這個邊界不是技術限制,而是組織和專業分工造成的隔離,它讓誤解的傳播範圍自然被限縮在某個領域內。


AI 做的事是消除了這個隔離

現在一個不懂資料庫的人可以用 AI 寫 migration,一個不懂 iOS 的人可以用 AI 寫 Swift。專業邊界作為天然防火牆的功能消失了。一個誤解不再被限制在某個人的工作範圍內,而是可以隨著「任何人都可以做任何事」這個新現實,擴散到整個 codebase 的任何角落。


這讓 k 的性質從領域邊界變成了 codebase 的連通性

一個模組被誤解之後,它能感染的節點數不再取決於「誰負責這個領域」,而是取決於「這個模組和多少其他模組有耦合」。耦合度愈高,k 愈大。這也再次回到了減法開發的核心——低耦合不只是好的工程實踐,在這個框架下它是直接壓低 k 的手段。


流行病學裡有一個 SIR 的變體叫 SIRD,多了一個 D(Death)狀態。感染者不只可以康復,也可以死亡。對應到程式碼生態:

S 是還沒被誤解污染的程式碼或模組,I 是帶有誤解的程式碼正在繁殖,R 在這裡幾乎不存在(如前面討論),D 是產品被放棄、公司倒閉、或系統被完全重寫。

N 的決定因素:誤解的世代數

N 取決於誤解在被發現之前能走多深,影響 N 大小的因素有:

  • 回饋延遲:多久之後才會知道出錯了
  • 攔截密度:中間有多少自然的檢查點(測試、review、報錯)
  • 人類介入的頻率:這個領域有多少機會讓人重新檢視前提

最危險的是 k 高且 N 高的項目——安全性、除錯、schema——因為它們的指數底數大,而且指數的上限也高。CI/CD 是裡面最接近線性的,因為兩者都低。

因此我們已經不問「能做什麼?」而是問「該做什麼?」

  • 不需要的產品/功能(產品/市場經驗)
  • 不需要的架構(工程經驗)
  • 不需要的程式碼(AI)

在這個漏斗中,更有效率的是在頂端兩層就減少程式碼,而不是修復,因為修復不再那麼有效,因此判斷「這個功能根本不需要存在」的產品人,以及有架構經驗的工程人,甚至決定讓宿主死亡的決策者,才能一起設計出低耦合的系統讓誤解難以跨模組傳播。

而另一方面比較隱晦的是,比起單純的技術能力,結合領域知識、系統思維、和對人類認知偏誤的理解的人(像是流行病學裡的接觸追蹤員(contact tracer)——能從一個症狀往回找到感染源,再往前預測傳播路徑)需要高度對複雜度傳播的直覺。

看到一個奇怪的 workaround,能問出「這裡為什麼要這樣寫」,然後順著答案往回挖,最後發現三個月前某個需求決策留下的假設,現在已經在五個地方各自長出了不同的補丁。 普通的工程師看到 bug 會問「怎麼修」。資深工程師會問「為什麼會發生」。接觸追蹤員會問「如果不改架構,下一個類似的 bug 會在哪裡、大概什麼時候出現」。 或者說,是一個習慣問「下一個案發現場在哪裡」,而不只是「這個案子怎麼發生的」的偵探。

  • 今天老婆想吃的是裡面有小熱狗的爛可頌