Netflix Staff 工程師 Jake Nations 在演講中坦承自己曾交付不完全理解的 AI 生成程式碼,並指出這不是個人問題,而是整個產業面臨的新一輪軟體危機。他從軟體工程歷史出發,剖析「簡單」與「容易」的根本差異,提出三階段方法(研究、規劃、實作)來對抗 AI 帶來的無限複雜度,強調在 AI 時代,思考與理解才是工程師最不可替代的能力。
原影片連結:https://www.youtube.com/watch?v=eIoohUmYpGI
影片重點
- AI 程式碼生成的加速是真實的,但理解速度跟不上生成速度,形成知識鴻溝
- 軟體複雜度危機不是新問題,每一代工程師都曾面對,只是 AI 讓規模變成無限
- Fred Brooks 在 1986 年就指出:沒有銀彈,真正困難的是理解問題本身而非打字
- Rich Hickey 區分的「Simple vs Easy」是理解 AI 陷阱的關鍵框架
- AI 是終極的「Easy Button」,讓人不再思考架構就直接產出程式碼
- AI 無法區分「本質複雜度」與「意外複雜度」,會把技術債當成模式保留
- 三階段方法:Research → Plan → Implement,讓思考成為主要工作
- 有時必須先手動完成一次遷移,才能建立足夠理解讓 AI 接手
- 軟體是人類的事業,真正的難點從來不是寫程式碼,而是知道該寫什麼
詳細內容
[00:20] 開場坦白:我們都交付了不理解的程式碼
Jake Nations 以一段坦白開場:他曾用 AI 生成程式碼,測試通過、部署上線,但自己無法解釋它是怎麼運作的。他打賭在場每個人都做過一樣的事。這段坦白引起了全場掌聲。
他在 Netflix 負責推動 AI 工具的採用,親眼見證了加速效果:過去需要數天的 backlog 項目現在只要幾小時,擱置多年的大型重構終於得以完成。但他也看到了問題的另一面——大型生產系統總是以意想不到的方式失敗,當它們失敗時,你最好能理解你正在除錯的程式碼。
[01:48] 歷史的循環:軟體危機不是新鮮事
Jake 回顧了軟體工程的歷史,指出每一代工程師都曾面對軟體複雜度超越管理能力的時刻。1960 年代末到 1970 年代初,一群電腦科學家聚在一起宣告「我們正處於軟體危機」。Dijkstra 說過一句話:當我們只有幾台弱小的電腦時,程式設計只是個小問題;現在我們有了巨型電腦,程式設計也變成了巨大的問題。
這個循環不斷重複:70 年代的 C 語言讓我們能寫更大的系統;80 年代個人電腦讓每個人都能寫程式;90 年代物件導向帶來了「繼承地獄」;2000 年代敏捷開發和 Scrum;2010 年代雲端、行動、DevOps——軟體真的吃掉了世界。而今天,我們有了 AI:Copilot、Cursor、Claude、Codex、Gemini,我們能以描述的速度生成程式碼。模式延續了,但規模真正變成了無限。
[03:25] Fred Brooks 的「No Silver Bullet」
Jake 引用了 Fred Brooks 1986 年的經典論文《No Silver Bullet》。Brooks 論證不會有任何單一創新能讓軟體生產力提升一個數量級。原因在於——真正困難的部分從來不是編碼的機械動作(語法、打字、樣板程式碼),而是理解實際問題並設計解決方案。沒有任何工具能消除這個根本難度。
迄今為止,我們創造的每一個工具和技術都讓機械動作變得更容易,但核心挑戰——理解該建造什麼、它應該如何運作——仍然一樣困難。
[04:22] Simple vs Easy:我們混淆的兩個詞
如果問題不在機械動作上,為什麼我們一直在為它最佳化?Jake 引用了 Clojure 程式語言創造者 Rich Hickey 在 2011 年的經典演講《Simple Made Easy》。
Rich Hickey 定義了兩個關鍵概念:
- Simple(簡單):意味著「一折、一縷、不糾纏」。每個部件只做一件事,不與其他部件交織。簡單關乎的是結構。
- Easy(容易):意味著「鄰近的」。觸手可及的東西,不費力就能使用。複製、貼上、交付。容易關乎的是接近性。
我們無法靠許願讓事物變簡單——簡單需要思考、設計和解糾纏。但我們總是能讓事物變得更容易——只要把它放得更近:安裝一個套件、用 AI 生成、從 Stack Overflow 複製。
每次我們選擇「容易」,我們選擇的是現在的速度、之後的複雜度。以前這個取捨是可控的,因為複雜度累積得夠慢,我們有時間重構。但 AI 摧毀了這個平衡——它是終極的「Easy Button」,讓容易的路徑如此無摩擦,我們甚至不再考慮簡單的那條路。
[06:10] 示範:一個簡單任務如何演變成複雜的混亂
Jake 用一個虛構的例子示範了這個過程。從一個簡單的應用開始,你要求 AI 加上認證功能,得到一個乾淨的 auth.js 檔案。接著迭代幾次、加上 OAuth,然後發現 session 壞了、出現衝突。到了第 20 輪對話,你已經不是在討論了,而是在管理一個複雜到連自己都不記得所有限制條件的 context。
遺留下來的是:被放棄的方法留下的死程式碼、靠著「讓測試通過就好」修復的測試、三個不同解決方案的碎片。每一條新指令都在覆寫架構模式。AI 對糟糕的架構決策毫無抵抗——程式碼只是不斷變形來滿足你最新的要求。
[07:41] 本質複雜度 vs 意外複雜度
回到 Fred Brooks 的論文,Jake 解釋了兩種複雜度:
- 本質複雜度(Essential Complexity):你試圖解決的實際問題的根本難度。用戶需要付款、訂單必須被履行——這是你的軟體系統存在的原因。
- 意外複雜度(Accidental Complexity):我們一路上添加的其他一切。繞路方案、防禦性程式碼、曾經有道理的框架和抽象層。
在真實的程式碼庫中,這兩種複雜度無處不在且糾纏在一起,分離它們需要 context、歷史和經驗。但 AI 生成的程式碼不做這樣的區分——每一個模式都被同樣保留。技術債不會被識別為債務,它只是更多的程式碼。
[08:30] Netflix 的真實案例:授權重構
Jake 分享了一個 Netflix 的真實案例。他們有一個抽象層介於舊的授權程式碼和新的集中式授權系統之間——一個五年前寫的 shim。現在有了 AI,理應是重構的好時機。
結果呢?舊程式碼與授權模式緊密耦合:權限檢查穿插在業務邏輯中、角色假設烘焙在資料模型裡、授權呼叫散布在數百個檔案中。AI 代理開始重構,處理了幾個檔案後就碰到無法解開的依賴關係,要不是失控放棄,就是更糟——試圖用新系統重建舊系統的邏輯。
AI 看不到接縫。它無法辨識業務邏輯在哪裡結束、授權邏輯在哪裡開始。當意外複雜度糾纏到這種程度,AI 不是最好的幫手,它只會在上面再加更多層。
[10:27] Context Compression:三階段方法
Jake 介紹了他的方法,他稱之為「Context Compression」(也被稱為 Context Engineering 或 Spec-Driven Development)。核心理念是:思考和規劃成為工作的主體。
Netflix 的主要程式碼庫有約一百萬行 Java,主服務大約五百萬 tokens——沒有任何 context window 能裝下。他一開始試著把大量程式碼塞進 context,但輸出同樣迷失在自身的複雜度中。於是他被迫做不一樣的事:精心選擇要納入的內容——設計文件、架構圖、關鍵介面,並花時間寫出元件應如何互動的需求。五百萬 tokens 被壓縮成 2,000 字的規格說明。
[11:10] 第一階段:Research(研究)
把所有相關資訊前置提供給 AI:架構圖、文件、Slack 討論串。然後用代理分析程式碼庫,映射出元件和依賴關係。
這不應該是一次性的過程。Jake 會持續追問:快取怎麼處理?故障時怎麼辦?當 AI 的分析有誤,他會糾正;當缺少 context,他會補充。每次迭代都在精煉分析。
輸出是一份單一的研究文件:這裡有什麼、什麼連接到什麼、你的變更會影響什麼。數小時的探索被壓縮成幾分鐘的閱讀。這裡的人工檢查點至關重要——這是你在這裡抓住錯誤、預防後續災難的最高槓桿時刻。
[12:19] 第二階段:Plan(規劃)
基於驗證過的研究,創建詳細的實作計畫:真正的程式碼結構、函式簽名、型別定義、資料流向。這個計畫要詳細到任何開發者都能照做——就像按數字填色一樣,交給最資淺的工程師,逐行照做就能運作。
這一步是做出重要架構決策的地方:確保複雜邏輯正確、業務需求遵循好的實踐、服務邊界清晰、防止不必要的耦合。我們能在問題發生前發現它們,因為我們經歷過它們。AI 沒有這個選項——它把每個模式都當成需求。
真正神奇的是審查速度:我們能在幾分鐘內驗證計畫,確切知道將要建造什麼。
[13:17] 第三階段:Implement(實作)
有了清晰的計畫和經過驗證的研究,實作階段應該相當簡單——這正是重點。當 AI 有清晰的規格可遵循,context 保持乾淨和聚焦。我們防止了長對話的複雜度螺旋。
與其 50 條訊息的演化式程式碼,我們有三個聚焦的輸出,每個在進入下一步前都經過驗證。沒有被放棄的方法、沒有衝突的模式、沒有留下死程式碼的「等等,其實…」時刻。
真正的回報是可以用背景代理執行實作——因為你已經提前完成了所有思考和困難的工作。它可以開始實作,你去做別的事,回來審查時只需要驗證它是否符合你的計畫,而不是試圖理解它是否發明了什麼新東西。
[14:45] 回到授權重構:手動遷移的必要性
回到那個 AI 處理不了的授權重構。Jake 的團隊發現他們甚至不能直接跳入研究、規劃、實作的流程。他們必須先親手完成一次遷移——沒有 AI,只有閱讀程式碼、理解依賴關係、做出改動看什麼會壞掉。
這次手動遷移很痛苦,但至關重要。它揭示了所有隱藏的限制條件:哪些不變量必須保持為真、哪些服務會在授權改變時崩潰——這些是再多的程式碼分析都無法浮現的東西。
然後他們把這個手動遷移的 Pull Request 餵入研究流程,作為後續研究的種子。AI 終於能看到一個乾淨的遷移長什麼樣。即便如此,每個實體都略有不同,仍然需要不斷追問和提供額外 context。三階段方法不是魔法——它之所以能運作,是因為他們先手動完成了一次遷移,在能把理解編碼進流程之前,必須先贏得那份理解。
[16:02] 不存在銀彈
Jake 認為不存在銀彈——不是更好的 prompt、更好的模型,甚至不是寫更好的 spec。真正必要的工作是深入理解你的系統,深到你能安全地對它做出改變。
「它能用」是不夠的。通過測試的程式碼和能在生產環境存活的程式碼之間有差距。今天能運作的系統和未來別人能修改的系統之間有差距。
[16:37] 知識鴻溝與能力萎縮
當 AI 能在幾秒內生成數千行程式碼,理解它可能需要數小時,甚至數天。更令人擔憂的是——每次我們跳過思考來跟上生成速度,我們不只是在添加不理解的程式碼,我們正在失去辨識問題的能力。
那種「嘿,這正在變得複雜」的直覺,在你不理解自己的系統時會萎縮。模式辨識來自經驗——Jake 能識別危險的架構,是因為他是那個凌晨三點起來處理問題的人;他推動更簡單的解決方案,是因為他維護過別人留下的替代方案。AI 生成你要求的東西,但它不編碼過去失敗的教訓。
[17:27] 結語:軟體是人類的事業
AI 改變了我們寫程式碼的一切方式,但它沒有改變軟體本身為什麼會失敗的任何原因。每一代人都面對過自己的軟體危機:Dijkstra 那一代用創造軟體工程這門學科來應對,而我們面對的是無限程式碼生成的危機。
Jake 不認為解決方案是另一個工具或方法論。而是記住我們一直都知道的事:軟體是人類的事業。困難的部分從來不是打字寫程式碼,而是知道該寫什麼。
能蓬勃發展的開發者不只是生成最多程式碼的人,而是那些理解自己在建造什麼的人——那些仍然能看到接縫、能辨認出自己在解決錯誤問題的人。那仍然是我們,也只能是我們。
他最後留下一個問題:問題不是我們是否會使用 AI——那已成定局。問題是:當 AI 在撰寫我們大部分程式碼時,我們是否仍然能理解自己的系統?
我的想法
這場演講最有價值的觀點不是「AI 不好」或「不要用 AI」,而是精準地指出了問題所在:我們混淆了「容易」和「簡單」。Rich Hickey 的 Simple vs Easy 框架在 2011 年用來批評框架膨脹,放到 AI 時代竟然更加貼切。AI 把「容易」推到了邏輯極限——生成程式碼的摩擦趨近於零,但程式碼的複雜度不會自動趨近於零。
三階段方法(Research → Plan → Implement)本質上就是在 AI 工作流中重新引入「思考」這個步驟。這和 Context Engineering 的理念完全一致——與其讓 AI 在龐大的程式碼庫中盲目摸索,不如先由人類壓縮 context、定義邊界,再讓 AI 在清晰的框架內執行。
Netflix 授權重構的案例特別有啟發性:即使有了方法論,有些工作必須先手動完成一次。這提醒我們,AI 輔助開發不是從零開始的魔法,而是建立在人類理解之上的加速器。你必須先「贏得」那份理解,AI 才能有效地幫助你擴展它。
對於日常開發者的實際建議是:不要在 AI 對話中迭代 20 輪來解決問題。停下來,花時間寫一份規格說明,然後讓 AI 按照規格執行。前期多花的思考時間,會在後期省下十倍的除錯時間。
進階測驗:AI 時代的軟體複雜度與工程思維
共 5 題,包含情境題與錯誤診斷題。



