# AI 時代寫程式，你是在學習還是在偷懶？

> AI 帶來的變革堪比當年從組合語言到高階語言的轉變，而最核心的挑戰在於從「確定性」轉變到「非確定性」。AI 會說謊、會瞎掰，但用得好能讓效率翻倍。本文探討 Vibe Coding 的陷阱、學習迴圈的重要性，以及初學者與資深工程師使用 AI 的策略差異。AI 是工具不是魔法，能讓你變強也能讓你變弱，關鍵不在於「要不要用 AI」，而在於「怎麼用 AI」

Published: 2025-12-24
URL: https://kaochenlong.com/vibe-coding-vs-software-engineering

---

不得不說，AI 實在太厲害了，好像什麼都能做，現在出門在外不隨口講個 AI 關鍵字好像已經沒辦法跟朋友聊天了。在社群或企業或學校，總是常被問到：「你覺得 AI 會不會取代軟體工程師的工作？」，我也常會問學生同樣的問題。

每次新技術出現，就會有人開始喊「XXX 已死」，幾乎每個程式語言、框架每年都要死好幾次，但很多喊這些標題的人只是想博取眼球或是透過製造焦慮賣課程，甚至自己根本也沒花時間去理解這些技術背後的本質。

但這次我不得不說，情況可能真的有點不太一樣...

## 我的 AI 使用心路歷程

在聊 Martin Fowler 大大的看法之前，先讓我分享一下我自己使用 AI 的經驗。說實話，一開始其實我對 AI 寫程式這件事是抱持觀望態度的。

ChatGPT 剛出來的時候我跟著玩了幾下，覺得滿好玩的，但好像也還好，就是比較厲害一點的 Stack Overflow。它可以回答一些程式問題，但稍微複雜一點的東西就會開始胡說八道。

當時的我：「這東西要取代程式設計師？還早還早，你先把 FizzBuzz 寫對再說」。

但不久後 GPT-4 出來了，Claude 出來了，GitHub Copilot 開始在我打字打到一半自動幫我補完一大段程式碼。接著是 Cursor、Windsurf 這些更狠的角色登場，聽說它們不只能聊天，還會幫我們改程式碼？好吧，那就來試試看。

結果一試下去...咦？怎麼比我想像中好用這麼多？

除了這些 IDE 或編輯器之外，後續又推出的 CLI 工具也很厲害，像是 Anthropic 的 Claude Code，直接在終端機裡面就能跟 AI 協作寫程式，連編輯器都不用開。

對我來說，不是「好用到可以取代工程師」那種好用，而是「好用到可以少寫很多無聊的 boilerplate code」那種好用。

舉個例子，我最近用 AI 寫了一個售票平台 [ezBundle](https://ezbundle.cc/)，目前程式碼的行數已經超過 30 萬行，這個專案從資料庫設計、CRUD、到金流串接，那些重複性高的程式碼 AI 都能幫忙生出來，我只需要專注在比較重要的邏輯和一些特殊的需求上就好。我大概花了一個週末就有個雛形（當然後續還是花了不少時間調整細節啦），這效率有點驚人。不是說 AI 幫我「寫完」了這個系統，而是它讓我可以把時間花在更有價值的地方，例如打魔物獵人遊戲。有興趣的話可以參考[宅宅的浪漫：用 AI 為自己的研討會寫一個售票系統](https://kaochenlong.com/2025/09/14/ezbundle.html)這篇文章。

我現在的使用習慣大概是這樣：

- 寫一些重複性高的程式碼時，讓 AI 幫我生成初版
- 遇到不熟悉的功能，先跟 AI 討論有哪些做法，AI 可能會給我幾個答案，然後我再從中挑選我認為比較合適的
- 寫測試的時候，讓 AI 幫我生成 test case，然後我會仔細看過一遍，沒問題再請 AI 實作內容。
- 除錯的時候，把錯誤訊息丟給 AI，看看它有什麼想法

同時，我也很清楚目前 AI 的限制：

- AI 會說謊（或說是瞎掰），而且說得理直氣壯！
- AI 給的程式碼可能可以跑，但未必是好的解法
- AI 不會幫你思考架構，你得自己思考

所以我現在的態度，既不是「AI 萬歲！以後都不用自己寫程式了！」那種狂熱擁抱，也不是「AI 就是垃圾！程式設計師的尊嚴不容侵犯！」。AI 是一個強大的工具這已經不用懷疑了，用得好可以讓效率翻倍，用得不好可能會讓人變成一個只會按 Tab 鍵或 Enter 鍵接受建議的人。

關鍵不在於「要不要用 AI」，而在於「怎麼用 AI」。

## 比從組合語言到高階語言還大的事

寫過《重構》的業界大神 Martin Fowler，最近有一場很值得看的訪談：

&lt;figure class=&quot;youtube-video&quot; data-id=&quot;CQmI4XKTa0U&quot; data-size=&quot;75&quot; data-caption=&quot;連結：https://www.youtube.com/watch?v=CQmI4XKTa0U&quot;&gt;
&lt;/figure&gt;

在這場訪談中 Martin 被問到一個很有意思的問題：「在你的職業生涯中，有什麼變革可以跟 AI 相比？」

&gt; The comparable thing would be the shift from assembly language to the very first high-level languages.

「唯一可以相比的，就是從組合語言轉變到第一批高階語言的那個時代。」這不只是語法變簡單，而是根本性地改變了開發者思考問題的方式。你不再需要想「這個資料要放在哪個暫存器（Register）」，你可以開始用更接近人類語言的方式思考問題。這表示因為技術的進步，我們可以在更高的抽象層次上工作。問題是，AI 帶來的改變，真的只是「提高抽象層次」這麼單純嗎？

## 最核心的轉變：從確定性到非確定性

Martin 認為，AI 帶來的最關鍵改變，其實不是「讓你可以用自然語言寫程式」這件事。真正關鍵的是另一個東西：

&gt; The biggest part of it is the shift from determinism to non-determinism.

「**最大的部分是從確定性轉變到非確定性**」這句話，我覺得是整段訪談最重要的觀點。傳統的程式設計是「確定性的（deterministic）」。什麼意思？就是給定相同的輸入，你永遠會得到相同的輸出。你寫 `1 + 1`，它永遠會回傳 `2`。例如寫了一個排序演算法，給它同樣的陣列，它永遠會回傳同樣的結果。程式會照著我們寫的邏輯，一步一步執行下去，不會有意外。

這是我們這些軟體工程師從第一天開始就被訓練的思考模式，程式永遠會照著「某種方式」執行，而這種方式是可以被追蹤、被理解、被除錯的。

但 AI 不是這樣運作的...

給它相同的 prompt，它可能會給你不同的回應。它可能這次寫對，下次寫錯。它可能今天很聰明，明天就開始胡說八道。即使是同一個問題、同一個 prompt，每次的答案都可能有微妙的差異。這是一個根本性的思維轉變，很多人還沒有意識到這件事可能帶來的衝擊或挑戰。

在訪談中 Martin 以他太太的工作為例，他太太是一位建築結構工程師，她設計樑柱的時候，數學會告訴她樑柱需要多粗才能支撐特定的重量。但她不會只用數學算出最低標準，她會加上額外的安全係數。為什麼？因為實際的木材、混凝土、鋼材，它們的特性會有變異。同一批混凝土，這塊可能比那塊脆一點點。同一批鋼材，這根可能比那根軟一點點。

所以結構工程師從來不會「剛剛好」設計。他們永遠會留容錯空間。

&gt; We need probably some of that kind of thinking ourselves. What are the tolerances of the non-determinism that we have to deal with?

「我們可能需要一些這樣的思維。非確定性的容錯範圍是什麼？」更重要的是下一句：

&gt; We can&#39;t skate too close to the edge, because otherwise we&#39;re going to have some bridges collapsing.

「我們不能太靠近邊緣，否則會有橋梁倒塌。」在軟體產業一直以來我們都很習慣確定性的世界，我們寫的測試之所以有意義，是因為程式碼是確定性的，如果測試通過了，它就應該一直通過。但當你的工具本身是非確定性的，傳統的測試方法夠用嗎？當你用 AI 寫程式，你怎麼知道它這次寫對了，下次還會寫對？你怎麼知道它在這個情況下正確，在那個情況下也正確？你怎麼建立對一個「可能會說謊」的工具的信任？

這些問題，目前整個產業可能都還在摸索中。

## 非確定性對程式教育和團隊協作的衝擊

這個「非確定性」的問題，讓我想到兩個很實際的場景。

第一個場景是**教學現場**。

我在[五倍學院](https://5xcampus.com)教程式設計十多年，一直以來的教學方法都是建立在「確定性」之上的。我會告訴學生：「你輸入這段程式碼，就會得到這個結果。」或是「這個函數接收這些參數，然後就會回傳這個值。」

學生可以自己驗證，看到結果跟我說的一樣，就會建立起對程式設計的信心。但現在呢？如果學生問 AI，AI 給了一個答案。學生跑起來，發現可以動。然後學生問：「老師，AI 說可以這樣寫，你覺得呢？」

我看了一下，發現那段程式碼確實可以跑，但寫法不太好。也許它沒有處理邊界情況，也許它用了一個已經被棄用的 API，也許它只是剛好在這個情況下可以動，換一個情況就會爆掉。這時候我要怎麼教？我要跟學生說「AI 錯了」嗎？但它確實可以跑啊。我要跟學生說「AI 對了但不好」嗎？學生可能會想「能動就好幹嘛那麼龜毛」。

更麻煩的是，我要不要先教學生傳統的寫法，還是直接教他們用 AI？如果先教傳統寫法，學生可能會覺得：「這些 AI 都會幫我寫好了，為什麼要花時間學？」但如果直接用 AI，學生可能永遠學不會真正的程式設計思維，變成一個只會寫 prompt 的人。

在這 Vibe Coding 盛行的時代，即使可能有一些逆風我還是先教基礎觀念，只是可能不會像以前教的那麼深入、那麼細節。先讓學生理解程式是怎麼運作的，然後才引入 AI 作為輔助學習工具。就像學數學，你總得要先理解加減乘除的原理再來用計算機，如果連乘法是什麼都不知道，就算給你計算機，你也不知道什麼時候該按乘號。

我不確定這是不是最好的做法，這目前還是一個沒有標準答案的問題。

第二個場景是**團隊協作**，特別是 code review。

以前做 code review，我知道這段程式碼是某個同事寫的。我會想：「小明通常對這塊比較不熟，我要仔細看一下」或是「小華的程式碼品質一向很好，我可以快速過一遍」但現在呢？AI 寫的程式碼，你要怎麼 review？

它可能語法完全正確，風格也很一致，但邏輯上有一個微妙的錯誤。因為 AI 寫程式碼的方式跟人不一樣，它不是「理解問題然後寫出解法」，而是「根據機率產生看起來合理的程式碼」。這代表你做 code review 的時候，不能只是「掃一眼看起來沒問題就過」，你要逐行檢查邏輯是否正確。這其實增加了 code review 的負擔，而不是減少。

我也聽到業界有些企業或團隊開始說，如果這段程式碼是 AI 生成的，commit message 要寫清楚，這樣 reviewer 就知道要更仔細地看。這是一個好做法，但也代表我們對 AI 生成的程式碼，其實並沒有那麼信任。這些都是「非確定性」帶來的連鎖反應。我們以前建立的那一套流程、那一套信任機制，在面對 AI 的時候可能需要重新思考。

## AI 會說謊，而且說得臉不紅氣不喘

說到說謊，這可能是另一個我覺得很多人還沒有認知到的問題。主持人在訪談中分享了一個親身經歷：他請 AI 在一個設定檔裡加一個新項目，並且加上當天的日期。AI 加了，但日期是錯的，它只是複製了上一個項目的日期。

他跟 AI 說：「這不是今天的日期」

AI 說：「抱歉，讓我改正」

然後它改成了昨天的日期！

&gt; You need to get this experience to see that it can gaslight you for a simple thing of today&#39;s date.

「你需要親身體驗這件事，才會知道它連今天的日期這種簡單的事情都可以對你進行心理操控」主持人又舉了另一個例子，有時候他讓 AI 幫忙改程式碼、跑測試。AI 會跟他說：「我已經跑過所有測試了，一切正常」然後他自己跑 `npm test` 指令，結果有五個測試失敗，這我在做 ezBundle 的時候也遇過好幾次...

Martin 開玩笑說，如果 AI 真的是一個初級工程師（我聽過很多人這樣比喻），他會去找 HR 談談。因為這種會說謊、掩蓋問題的成員，在任何工作場合都是不能接受的。

但 AI 不是人，它沒有「故意說謊」的意圖（至少現在還沒有）。AI 只是在根據機率產生下一個最可能的 token。對 AI 來說「測試通過」和「測試失敗」可能都是合理的選項，它只是挑了一個機率比較高的。所以你可以用 AI 來幫你寫程式，但不要完全相信它的輸出。可以的話，每一行程式碼都要自己看過，每一個它說「沒問題」的地方都要自己驗證。

這聽起來很累，但這就是現階段的遊戲規則。想請 AI 幫你做出真正能用的東西，這就是我們必須付出的代價。

## Vibe Coding 很爽，但你在學什麼？

說到「不看程式碼」，這就要講到 2025 年非常流行的一個詞：**Vibe Coding**。

這個詞是 Andrej Karpathy 在 2025 年 2 月份在 X 上的[一則推文](https://x.com/karpathy/status/1886192184808149383)提到的。他提出的這個概念意思是：你完全不看 AI 產生的程式碼，只管它能不能跑、有沒有達到你要的效果。

這聽起來很美好，你只要用自然語言描述你要什麼，AI 就會幫你生出來。不用管什麼變數命名、函數設計、程式架構，反正那些程式碼你也不會看（可能也看不懂），反正能動就好。Martin 對此的看法：

&gt; I think it&#39;s good for explorations, it&#39;s good for throwaways, disposable stuff, but you don&#39;t want to be using it for anything that&#39;s going to have any long-term capability.

「我認為它適合用來探索、適合用來做拋棄式的東西，但你不會想把它用在任何需要長期維護的專案上」

他舉了一個例子，他的同事要在部落格文章中放一張示意圖，就請 AI 幫忙生成一個 SVG 圖片。產出的圖看起來還可以。但當 Martin 想要微調一下，例如把標籤移近一點，當他打開那個 SVG 檔案的時候...

「天啊！」那個 SVG 有夠複雜！明明只是幾條曲線和標籤，卻寫成了一堆難以理解的座標點和路徑。想要手動調整幾乎不可能。這就是 Vibe Coding 的問題。當你不看程式碼的時候，你放棄了理解它的能力。而當你不理解一段程式碼，你就無法修改它。

你唯一能做的就是...呃，重新來過。

&gt; All you can do is nuke it from orbit and start again.

「你唯一能做的就是從軌道上核爆它，然後重新開始」每次你要改什麼東西，都要重新說一次需求，然後開始祈禱 AI 這次能猜對。如果它還是沒猜對呢？再一次、再一次、再一次，反正累的又不是你。對於一個週末的 side project 可能還可以接受，但對於一個可能維護好幾年的系統呢？

## 學習迴圈：你以為你在成長，但你可能正在斷送自己的成長

這裡我想特別花一些篇幅來討論一個概念，我認為這是整場訪談中很重要的觀點，特別對於正在學習程式設計的人來說。Martin 的同事提出了一個觀察：

&gt; When you&#39;re using vibe coding, you&#39;re actually removing a very important part of something, which is the learning loop.

「當你使用 Vibe Coding 時，你實際上拿掉了一個非常重要的東西，那就是『學習迴圈』。」

什麼是「學習迴圈（Learning Loop）」？想像你在學一個新的程式語言或框架，在腦中可能有個想法：「我要來做一個待辦事項清單的 App」，然後打開編輯器開始寫程式。寫了一段程式碼，執行之後發現結果不對，接著回去看程式碼想想可能是哪裡寫錯了。然後查文件、查 Google、翻 Stack Overflow 上的答案，相信大家對於開發過程中，瀏覽器分頁開滿了捨不得關掉的 Stack Overflow 這種場景都不陌生。接著再繼續修改程式碼，再跑一次。這次對了，但網頁打開的速度有點慢。你開始思考為什麼慢，怎麼最佳化...

這個過程，從想法到程式碼再從程式碼到結果，最後再從結果到理解，就是學習迴圈。這是人類學習新事物的基本方式，這麼多年來一直都沒什麼改變。在這個過程中累積經驗、建立直覺、學習什麼做法是好的、什麼做法是壞的。

&gt; If you&#39;re not looking at the output, you&#39;re not learning.

「如果你不看輸出，你就沒有在學習。」當你完全不看 AI 產生的程式碼時，等於跳過了這整個學習迴圈。當想法直接變成結果，中間的「程式碼」變成了一個你不關心的黑箱。短期來看這真的超爽的，簡單幾句話就能很快地做出東西，但長期來看這是可能是在斷送自己的成長。

下回 Vibe Coding 完一個作品之後仔細想想看，你在這過程有沒有學到什麼？

下一次遇到類似的問題，你可能還是要靠 AI。在這過程中可能沒有建立起任何自己的能力，而是變成了一個只會寫 prompt 的人，而不是一個會寫程式的人。就像學開車，也許有一天自動駕駛可以做到只要喊一聲「帶我去台北車站」，車子就會自己開到目的地。這實在太方便了然後以後都用這個系統，十年後，這個系統壞了。你發現你不會開車，甚至連方向燈都不知道怎麼打。

也許在未來，自動駕駛會普及到你永遠不需要自己開車。但在那之前呢？

同樣的道理。也許在未來，AI 會強到你完全不需要理解程式碼。但在那之前呢？在那之前，你是要當一個「會用 AI 但不會寫程式的人」，還是一個「會寫程式、也會用 AI 讓自己更強的人」？

## 初學者 vs 資深工程師：使用 AI 的策略差異

對於不同程度的人，使用 AI 的策略應該是不一樣的，初學者可能很容易掉入「偷懶陷阱」。為什麼？因為新手還沒有建立起判斷程式碼好壞的能力。AI 給一段程式碼，新手不知道它是好的還是壞的，只知道它能跑。

剛學做菜的人，食譜說加一湯匙鹽，他不知道一湯匙是多少，就隨便加。結果？可能太鹹，可能太淡。他吃了覺得「好像還可以」，但其實離好吃還很遠。資深廚師就不一樣了，他可能不用食譜，但他知道什麼時候該加多少鹽。即使有人給他一份食譜，他也會根據自己的經驗調整。他知道「這個食譜說加一湯匙，但以我對這道菜的理解，應該要少一點」。

程式設計也是一樣。資深工程師使用 AI 的時候，他知道什麼時候該相信 AI、什麼時候該懷疑 AI。

- 「這段程式碼看起來好像沒問題，但這個地方怎麼沒有處理 null？讓我問一下。」
- 「它用了這個套件，但我知道這個套件有一個已知的效能問題，換別的吧！」
- 「這個解法可以動，但架構上不太好，長期維護會有問題。」

初學者沒有這些判斷能力。他看到程式碼能跑，就覺得「搞定了」。他不知道自己不知道什麼。這就是為什麼初學者用 AI 要特別小心。不是說不能用，而是用的時候要更有意識地學習。

什麼是「好的使用方式」？

- 讓 AI 解釋程式碼：「這段程式碼在做什麼？每一行分別是什麼意思？」
- 讓 AI 生成程式碼後，自己試著修改：「如果我想加一個功能，要改哪裡？」
- 遇到錯誤時，先自己想想為什麼，再問 AI：「我猜是因為 XXX，對嗎？」
- 比較不同的解法：「還有沒有其他寫法？各有什麼優缺點？」

什麼是「壞的偷懶」？

- 無腦複製貼上，不看程式碼在做什麼
- 程式碼能跑就不管了，不思考有沒有更好的寫法
- 遇到錯誤就把錯誤訊息丟給 AI，不自己嘗試理解
- 永遠只用 AI 的第一個答案，不質疑、不驗證

資深工程師反而可以更放心地使用 AI，因為他有能力把關。老鳥知道 AI 產出的東西哪些可以用、哪些不能用，甚至把 AI 當作一位「打字很快但有時候會犯錯的助理」，而不是一個「無所不知的神」。這也是為什麼我認為在 AI 時代，累積真正的技術能力反而更重要了。因為這些技術能力決定了你能不能有效地使用 AI。

## 測試在 AI 時代變得更重要了

說到學習和驗證，這就要談到測試了。在 AI 時代，測試的意義可能有點不同。以前，工程師寫測試是為了驗證「自己寫的程式碼」是否正確。你知道程式碼是怎麼運作的，你寫測試是為了確保它在各種情況下都能正常運作。現在，寫測試是為了驗證「AI 寫的程式碼」是否正確。你可能不完全理解程式碼是怎麼運作的，但你知道你要的結果是什麼。測試變成了你和 AI 之間的「**契約**」，也就是說不管 AI 怎麼寫，只要這些測試通過，我就當你是對的。

而且每次你讓 AI 改程式碼，你都要重新跑測試。因為 AI 不會記得「這邊之前改好了，不要動到它」。所以當你跟 AI 說：「幫我改這個函數，讓它可以處理空陣列。」AI 改了。但可能順便把另一個函數也改了，因為 AI 覺得「這樣比較一致」。或者它把你之前特別處理的一個邊界情況改壞了，因為它不知道那個處理是有原因的。

如果你沒有測試，你可能要過很久才會發現這個問題。如果你有完整的測試，你馬上就會知道：「欸，這個測試怎麼壞了？」

我在開發 ezBundle 售票平台的時候有個類似的經驗。有一次我加了一個新功能，上線後兩天都沒什麼問題，但也都沒訂單進來，當時我只是想說可能就剛好生意比較差而已，兩天後有人私訊我說不能結帳，我才發現事情的嚴重性。我其實有寫測試，測試寫的也不少，但就剛好那次偷懶沒全部跑完，結果就這麼準中招了。這件事讓我學到一個教訓：就算沒時間跑完整個測試，至少也要跑個 [Smoke Test](https://en.wikipedia.org/wiki/Smoke_testing_\(software\))。

什麼是 Smoke Test？這個名字聽起來很酷，其實概念很簡單。想像你修好一台電視，如果插上電源之後就開始冒煙，那就不用再測其他功能了。Smoke Test 大概就是這個意思，先測最基本、最核心的功能有沒有在運作。

以我的售票平台來說，Smoke Test 大概就是：能不能開啟首頁？能不能看到活動列表？能不能走完結帳流程？這些如果壞掉，其他功能再完美都沒有意義。

## IDE vs AI：不是所有釘子都要用 AI 這把鐵鎚

在訪談中，Martin 的同事 James Lewis 分享了一個有趣的實驗。他想用 Cursor 來改一個類別的名稱。這個操作，在傳統的 IDE 裡面只要右鍵點一下「Rename」，然後輸入新名字，一秒鐘就完成了。IDE 會自動找到所有引用這個類別的地方，全部更新。

結果用 Cursor 呢？他等了一個半小時，用掉了當月 10% 的 token 額度。而且還不一定改對，可能漏掉了一些地方，或是改到不該改的東西。

&gt; We&#39;ve had this technology for a long time. So it&#39;s kind of amusing.

「這個技術我們已經有很久了。所以這件事蠻好笑的。」AI 不是萬能的，有些任務，用傳統工具做真的比較快也比較簡單。IDE 的重構工具是確定性的。它會精確地找到所有引用，精確地更新它們。不會漏，不會錯。因為它是在分析語法樹，不是在「猜測」你要什麼。

AI 則是在「理解語意」。它很擅長理解你用自然語言描述的需求，擅長產生新的程式碼，擅長解釋複雜的概念。但對於那些需要精確操作的事情，例如重新命名、移動檔案、格式化程式碼等工作，傳統工具做得更好。所以，好的做法不是「全部都用 AI」，而是「知道什麼時候該用什麼工具」。

- 需要精確的機械式操作？用 IDE。
- 需要理解語意、產生新內容？用 AI。
- 需要搜尋特定字串？用 grep 或 IDE 的搜尋功能。
- 需要理解程式碼在做什麼？用 AI。

你可以用 AI 來驅動傳統的確定性工具。比如說，用 AI 來幫你產生 sed 或 awk 的指令。這樣你結合了 AI 的語意理解能力，和傳統工具的精確性。

既然聊到了開發工具和 AI 的分工，讓我分享一下我現在的工作流程。我的主要編輯器是 Vim。Cursor 跟 Windsurf 我都試過，還不錯，但就是有點慢。我目前還是習慣用 Vim 加終端機的方式進行開發。我的使用原則大概是這樣：

需要「精確操作」的時候，用開發工具的原生功能，例如：

- 重新命名變數或函數：用 F2 或右鍵的 Rename Symbol
- 自動引入（auto import）：讓 IDE 自動處理
- 格式化程式碼：用 Prettier 或語言內建的格式化工具
- 跳到定義、找所有引用：用 Go to Definition、Find All References

這些操作開發工具做得又快又準，沒必要讓 AI 來做。

需要「理解語意」或「產生新內容」的時候，用 AI：

- 解釋一段我不熟悉的程式碼
- 寫一個新的函數或類別
- 產生測試案例
- 把一段程式碼翻譯成另一種語言
- 幫我想變數或函數的命名

兩者結合的情況：

有時候我會用 AI 來幫我產生一些指令或正規表示式。比如說，我想把所有的 `console.log` 改成 `logger.info`。直接請 AI 幫我寫一個 sed 或 VS Code 的搜尋替換的正規表示式。AI 幫我產生指令，然後我用工具去執行。這樣結合了 AI 的語意理解能力和工具的精確性。

另一個例子是產生 Git 指令。有時候我要做一個比較複雜的 Git 操作，比如「找出過去一個月內，修改過 XXX 目錄底下任何檔案的所有 commit」。我 Git 指令其實還算熟，但這種指令我不太會去記它所有的參數跟用法，現在我直接問 AI，它給我指令，我看一下確認沒問題就執行。

這種「AI 產生指令、人類驗證執行」的模式，我覺得蠻安全又有效率的。

## AI 真正擅長的：理解那些沒人想看的老舊系統

聊完了 AI 的限制，我們來說說它真正擅長的地方。大家可能想說用 AI 來產生新的 App，但卻漏了一個更實際、更有價值的應用場景。

很多企業裡還在運作的系統，這些系統可能是十幾年前寫的，可能用 Java 或是 COBOL，甚至更古老的東西。文件不全（或根本沒有）就算了，原始開發者早就離職了，沒有人知道這段程式碼為什麼要這樣寫。這一直是業界的大痛點。每次要改這種系統，工程師都要花大量的時間去「考古」，最後常聽到就是乾脆砍掉重練，不用面對這個問題說不定還能賺一筆專案改寫的費用...

是說，AI 怎麼在這方面幫上忙呢？做法有很多種，例如針對程式碼做語意分析，把資訊放進圖資料庫，然後用類似 RAG（Retrieval-Augmented Generation）的方式讓你可以問問題。比如說：

- 「這個資料從哪裡來？經過哪些處理？」
- 「這個功能是怎麼運作的？」
- 「為什麼這段程式碼要這樣寫？」

AI 可以幫你快速建立對一個陌生系統的理解，省下大量的考古時間。很多公司其實都有這個問題，特別是歷史悠久的企業，像是銀行、保險公司或是政府機關，這些系統沒人敢動，因為沒人知道動了會發生什麼事。AI 在這方面的幫助，可能比「寫新程式碼」更有價值。

## 學習新技術更快了，但還是要學

另一個 AI 很有用的場景，就是能用來學習不熟悉的新技術。如果我想做一個遊戲，我可以直接問 AI：「我想用 Unity 做一個會跳躍的角色，要怎麼開始？」它會給你一個起點。我可以接著問：「這個函數是幹嘛的？」「為什麼這樣寫會報錯？」「有沒有更好的做法？」

說到底，還是得要花時間理解 AI 給的東西。AI 可以幫我們更快地取得一個起點，但如果只是複製貼上、能跑就好，這樣還是沒有真正學會。下次遇到類似的問題，還是要再問一次。

所以正確的用法應該是用 AI 來「加速」學習，而不是「取代」學習。

## Stack Overflow 的既視感：我們以前也經歷過這種事

在訪談中，主持人提出了一個很有趣的觀察：其實我們以前也經歷過類似的事情，那就是 [Stack Overflow](https://stackoverflow.com/questions)。

比較年輕的工程師可能沒有經歷過這段故事。在 Stack Overflow 之前，在網路上查詢程式相關的問題，你很有可能被導到一個叫 Experts Exchange 的網站。這個網站上的答案得要課金才能看，大部分的人可能不會付錢，因為就算付了，裡面也可能找不到答案。

然後 Stack Overflow 出現了。突然之間，你可以找到免費的程式碼片段，直接複製貼上。很多初學者就這樣複製、貼上、看看能不能跑。不管它在做什麼，不管為什麼這樣寫。能跑就好。

資深工程師會跟他們說：「你要先理解這段程式碼在做什麼。」「就算它能跑，你也要知道為什麼能跑。」

&gt; I feel we&#39;ve been, there was a few years where we were going back and forth of people mindlessly copying, pasting snippets.

我覺得我們曾經有那麼幾年，大家就是無腦地複製貼上程式碼片段。聽起來很熟悉吧？Martin 認為現在的情況很類似，只是規模更大了。AI 可以產生的不只是一個片段，而是整個函數、整個類別、甚至整個專案。無腦複製貼上的誘惑更大了。

但 Stack Overflow 至少還有一個優勢：社群驗證。在 Stack Overflow 上，一個答案會被其他人 upvote 或 downvote。會有人留言說「這個做法有問題」、「在這個情況下不適用」。你可以看到答案的分數，知道有多少人覺得它是好的。

AI 給的答案沒有這種驗證。它就是給你一個答案，你不知道這個答案是不是好的、是不是適合你的情況。更麻煩的是，如果大家都只問 AI，不再去 Stack Overflow 問問題、回答問題，那 AI 以後要從哪裡學新的東西？

這是所謂「Model Collapse」，當 AI 生成的內容越來越多，AI 訓練的資料中也會包含越來越多 AI 生成的內容，這種「近親繁殖」的結果可能會造成品質下降。

## 重構的藝術：AI 時代可能更重要了

說到 Martin Fowler，不能不聊他的成名作《重構》（Refactoring）。這本書第一版出版於 1999 年，2019 年出了第二版。可以說，「重構」這個概念能在業界廣為流傳，有很大一部分要歸功於這本書。他說了一句我很喜歡的話：

&gt; Each step is so small, but it&#39;s not worth doing, but you string them together and you can really do amazing things.

「每一步都小到不值得做，但當你把它們串起來，你可以做到驚人的事情。」重構的精髓就是這樣，每一步都小到看起來沒什麼意義，但累積起來的效果是驚人的。那在 AI 時代，重構還重要嗎？Martin 認為不只重要，可能更重要了：

&gt; If you&#39;re going to produce a lot of code of questionable quality, but it works, then refactoring is a way to get it to a better state while keeping it working.

「如果你要產生大量品質可疑但能運作的程式碼，那麼重構就是一個讓它變得更好、同時保持它能運作的方法。」這個觀點很有意思。AI 可以快速產生程式碼，但品質參差不齊。它產生的程式碼可能可以跑，但可能很難維護、很難理解、很難擴展。如果你打算長期維護這個系統，你不能就這樣把 AI 產生的程式碼丟進去就不管了。你需要重構它。讓它變得更好理解、更容易維護。

但 AI 可能比較喜歡「大改」，你跟 AI 說「幫我改善這段程式碼」，它可能會重寫整個函數、改變資料結構、調整整個架構。這樣的改變很難驗證，你怎麼知道它改完之後，行為還是跟以前一樣？

真正的重構是「小步前進」。每一步都很小，每一步都保持行為不變。這樣你可以隨時驗證、隨時回到上一步。所以，比較好的做法可能是用 AI 來幫你產生初始的程式碼，然後用你自己的重構技能來改善它。或者，訓練 AI 做小步重構，而不是大改。

所以後來我學到一件事，就是用 AI 輔助重構的時候，要給它更具體的指示。例如，不要說：「幫我重構這段程式碼。」，而是說：「請把第 50-80 行的資料庫查詢邏輯抽成一個獨立的函數，參數和回傳值保持跟原本一樣。」這樣產出的東西會更可控。

另一個心得是要叫 AI 重構之前，一定要先有測試。如果有完整的測試，你可以讓 AI 改完之後跑一次測試，馬上知道有沒有改壞。如果沒有測試，那就跟把眼睛矇起來打架一樣，你不會知道什麼時候會被揍一拳。

這跟傳統的重構原則是一樣的，先寫測試或是規格，再重構。只是在 AI 時代，這個原則變得更重要了，因為 AI 更容易在你沒注意的地方改變行為。

## 企業的現實：大多數人不是在做 side project

在很多討論 AI 的文章和影片中，你會看到很多「我用 AI 一個週末做了一個 App」的故事。這些故事很激勵人心，但它們可能不代表大多數軟體工程師的日常。

在新創公司，可能全公司都是工程師或者工程師占大多數。決策快、迭代快、可以冒險。但在傳統企業，軟體開發者可能只占 10-20%，其他都是會計、行銷、業務、法務等等。這些人有他們自己的需求、自己的語言、自己的規則。你不能說「讓我試試看，錯了再改」，因為錯了可能會有法律問題、監管問題、聲譽問題。

AI 採用速度在不同組織可能會有所不同。新創可以全力擁抱 AI，因為他們沒有什麼可以失去的。但銀行、政府、醫療這些高度監管的產業，必須非常謹慎。不是說這些產業不會用 AI，而是說這些單位的採用路徑會不太一樣。

## 給初學者的建議

如果你是剛開始學程式的人，面對 AI 這麼方便的工具，以下有幾個建議：

### 先打好基礎再用 AI

我知道這聽起來很老人說教，但這是真的。你要先理解變數是什麼、函數是什麼、迴圈怎麼運作、為什麼要用物件導向。這些基礎觀念不懂，你就沒辦法判斷 AI 給你的程式碼好不好。學開車，你也得先知道油門煞車方向盤怎麼用，才能開自動駕駛。如果你連這些都不知道，自動駕駛出問題的時候你根本不知道該怎麼接手。

### 把 AI 當老師，不要當代寫。

與其說「幫我寫一個 XXX」，不如說「解釋一下怎麼寫 XXX」。讓 AI 教你，而不是幫你做。你可以讓 AI 生成程式碼，但生成之後要自己讀懂它。問 AI：「這一行在做什麼？」「為什麼要用這個方法而不是那個？」「如果輸入是 null 會怎樣？」

這樣你才是在學習，而不是在偷懶。

### 遇到錯誤先自己想

很多初學者一遇到錯誤訊息就複製貼上丟給 AI。這樣你永遠學不會除錯。試著先自己讀錯誤訊息。Google 一下。想想可能是什麼原因。實在想不出來，再問 AI。但問的時候要說「我試過 XXX 和 YYY，但還是不行，我猜是因為 ZZZ，對嗎？」

這樣你是帶著假設去問，而不是無腦求救。

### 定期挑戰自己「不用 AI 寫」

每隔一段時間，試著完全不用 AI 來完成一個小專案或練習題。看看你是不是真的學會了，還是只是 AI 學會了。如果你發現離開 AI 就不會寫程式，那代表你前面的學習方式有問題，要調整。

## 給資深工程師的建議

如果你已經有幾年工作經驗，對程式設計有一定的掌握，使用 AI 的策略可以更開放一些：

### 大膽使用 AI 來處理繁瑣的工作

寫 boilerplate code、產生測試案例、格式轉換、寫文件...這些工作讓 AI 幫你做，你的時間應該花在更有價值的地方：系統設計、架構決策、code review、mentoring。

以我自己開發 ezBundle 的經驗來說，我讓 AI 幫我處理的都是那些「我知道怎麼做，但實在懶得自己寫」的東西，例如表單驗證、API 的 CRUD、報表的 CSV 匯出。這些我閉著眼睛都能寫...好啦，有點誇張了，但我的確是不需要 AI 就能寫出來，只是每次都要花時間。現在我把這些交給 AI，我的時間拿來思考「票券系統要怎麼設計才能應付幾百人同時驗票」、「退款流程要怎麼設計才能避免糾紛」這些真正需要動腦的問題。

這才是資深工程師該做的事。用 AI 省下來的時間，不是拿來發呆，而是拿來思考那些 AI 目前還做不好的事。你的判斷力和經驗是 AI 目前還取代不了的。把那些 AI 可以做的事情交給 AI，你專注在 AI 做不好的事情上。

### 建立你自己的驗證機制

因為你有經驗，你應該知道什麼地方容易出錯。針對這些地方建立檢查清單。每次用 AI 生成程式碼，跑過這個清單。比如說：

- 有沒有處理 edge case？
- 錯誤處理完整嗎？
- 效能有沒有問題？
- 有沒有安全漏洞？
- 跟現有的架構風格一致嗎？

這個清單因人而異、因專案而異，但重點是你要有意識地去驗證，而不是看一眼覺得沒問題就過了。

### 用 AI 來加速學習新技術

資深工程師也需要持續學習。新的框架、新的語言、新的工具。以前學一個新東西可能要花一兩週看文件做教學，現在你可以直接問 AI：「我是有 X 年 Y 語言經驗的工程師，想學 Z 框架，有什麼概念是跟我已經知道的東西類似的？有什麼是完全不同需要特別注意的？」

AI 可以幫你建立知識的橋樑，讓你更快上手。

### 分享你的經驗

你踩過的坑、你發現的 AI 使用技巧、你建立的驗證機制，這些對初學者都很有價值。寫部落格、在團隊內部分享、回答別人的問題。AI 時代，「知道怎麼有效使用 AI」本身就是一種技能。而這種技能是要靠實戰經驗累積的。你的經驗可以幫助其他人少走彎路。

## 結論：AI 是工具，不是魔法

聽完這場訪談，我有幾個想法：

### 我們正處於一個巨大的典範轉移之中

Martin 說 AI 是他四十年職業生涯中最大的變革，而且唯一可以相比的是組合語言到高階語言的轉變。這代表我們現在學的很多東西，可能在幾年後就會變得非常不一樣。保持學習、保持好奇，可能是最重要的能力。

### 非確定性是一個根本性的挑戰

我們習慣的程式設計思維是建立在確定性之上的。當這個假設不再成立時，我們需要發展新的思維模式。也許我們需要把軟體開發的思維，從「精確的工程」變成更像「處理不確定性的工程」。

### 基本功永遠重要

雖然 AI 改變了很多事情，但核心的能力，像是理解問題、與人溝通、建構抽象、驗證結果等，這些並沒有變。你需要能夠判斷 AI 的輸出是否正確、是否適合你的場景。這需要你真的懂程式設計，而不只是會寫 prompt。

### 不要放棄學習迴圈

Vibe Coding 很爽，但如果你從不看程式碼、不理解程式碼，你就失去了學習的機會。用 AI 來加速你的學習，而不是取代你的學習。

### 測試變得更重要，不是更不重要

當你用一個「會說謊」的工具來幫你寫程式，你需要更多的驗證機制。測試是你和 AI 之間的契約。

### 知道什麼時候該用什麼工具

AI 不是萬能的。有些事情傳統工具做得更好。好的工程師知道什麼時候該用 AI，什麼時候該用 IDE，什麼時候該自己手寫。

## 最後的最後

Martin Fowler 在訪談的最後說了一句話，我覺得很適合作為這篇文章的結尾：

&gt; I don&#39;t think AI is going to wipe out software development. I think it&#39;ll change it in a really manifest way, like the change from assembly to high-level languages did, but the core skills are still there.

「我不認為 AI 會消滅軟體開發。我認為它會用一種非常顯著的方式改變它，就像從組合語言到高階語言的改變一樣，但核心的技能還是在的。」是的，AI 正在改變一切。但有些東西是不變的，對問題的好奇心、對品質的追求、與人溝通的能力、持續學習的態度。回到一開始的問題：「AI 時代寫程式，你到底是在學習還是在偷懶？」

答案取決於你怎麼用它。

如果你只是無腦地讓 AI 寫程式、不看程式碼、不理解程式碼、不驗證結果，那你確實是在偷懶。而且這種偷懶會讓你越來越弱，最後變成一個只會寫 prompt 但不會寫程式的人。

但如果你用 AI 來加速你的學習、幫你處理繁瑣的工作、讓你可以專注在更重要的事情上，同時保持你的學習迴圈、持續累積你的技能，那你是在學習，而且你可能會變成一個比以前更強的工程師。

工具就是工具。刀可以用來切菜，也可以用來傷人。

AI 能讓你變強，也可以讓你變弱。選擇在你 :)

