AI 時代寫程式,你是在學習還是在偷懶?
不得不說,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,目前程式碼的行數已經超過 30 萬行,這個專案從資料庫設計、CRUD、到金流串接,那些重複性高的程式碼 AI 都能幫忙生出來,我只需要專注在比較重要的邏輯和一些特殊的需求上就好。我大概花了一個週末就有個雛形(當然後續還是花了不少時間調整細節啦),這效率有點驚人。不是說 AI 幫我「寫完」了這個系統,而是它讓我可以把時間花在更有價值的地方,例如打魔物獵人遊戲。有興趣的話可以參考宅宅的浪漫:用 AI 為自己的研討會寫一個售票系統這篇文章。
我現在的使用習慣大概是這樣:
- 寫一些重複性高的程式碼時,讓 AI 幫我生成初版
- 遇到不熟悉的功能,先跟 AI 討論有哪些做法,AI 可能會給我幾個答案,然後我再從中挑選我認為比較合適的
- 寫測試的時候,讓 AI 幫我生成 test case,然後我會仔細看過一遍,沒問題再請 AI 實作內容。
- 除錯的時候,把錯誤訊息丟給 AI,看看它有什麼想法
同時,我也很清楚目前 AI 的限制:
- AI 會說謊(或說是瞎掰),而且說得理直氣壯!
- AI 給的程式碼可能可以跑,但未必是好的解法
- AI 不會幫你思考架構,你得自己思考
所以我現在的態度,既不是「AI 萬歲!以後都不用自己寫程式了!」那種狂熱擁抱,也不是「AI 就是垃圾!程式設計師的尊嚴不容侵犯!」。AI 是一個強大的工具這已經不用懷疑了,用得好可以讓效率翻倍,用得不好可能會讓人變成一個只會按 Tab 鍵或 Enter 鍵接受建議的人。
關鍵不在於「要不要用 AI」,而在於「怎麼用 AI」。
比從組合語言到高階語言還大的事
寫過《重構》的業界大神 Martin Fowler,最近有一場很值得看的訪談:
https://www.youtube.com/watch?v=CQmI4XKTa0U
在這場訪談中 Martin 被問到一個很有意思的問題:「在你的職業生涯中,有什麼變革可以跟 AI 相比?」
The comparable thing would be the shift from assembly language to the very first high-level languages.
「唯一可以相比的,就是從組合語言轉變到第一批高階語言的那個時代。」這不只是語法變簡單,而是根本性地改變了開發者思考問題的方式。你不再需要想「這個資料要放在哪個暫存器(Register)」,你可以開始用更接近人類語言的方式思考問題。這表示因為技術的進步,我們可以在更高的抽象層次上工作。問題是,AI 帶來的改變,真的只是「提高抽象層次」這麼單純嗎?
最核心的轉變:從確定性到非確定性
Martin 認為,AI 帶來的最關鍵改變,其實不是「讓你可以用自然語言寫程式」這件事。真正關鍵的是另一個東西:
The biggest part of it is the shift from determinism to non-determinism.
「最大的部分是從確定性轉變到非確定性」這句話,我覺得是整段訪談最重要的觀點。傳統的程式設計是「確定性的(deterministic)」。什麼意思?就是給定相同的輸入,你永遠會得到相同的輸出。你寫 1 + 1,它永遠會回傳 2。例如寫了一個排序演算法,給它同樣的陣列,它永遠會回傳同樣的結果。程式會照著我們寫的邏輯,一步一步執行下去,不會有意外。
這是我們這些軟體工程師從第一天開始就被訓練的思考模式,程式永遠會照著「某種方式」執行,而這種方式是可以被追蹤、被理解、被除錯的。
但 AI 不是這樣運作的...
給它相同的 prompt,它可能會給你不同的回應。它可能這次寫對,下次寫錯。它可能今天很聰明,明天就開始胡說八道。即使是同一個問題、同一個 prompt,每次的答案都可能有微妙的差異。這是一個根本性的思維轉變,很多人還沒有意識到這件事可能帶來的衝擊或挑戰。
在訪談中 Martin 以他太太的工作為例,他太太是一位建築結構工程師,她設計樑柱的時候,數學會告訴她樑柱需要多粗才能支撐特定的重量。但她不會只用數學算出最低標準,她會加上額外的安全係數。為什麼?因為實際的木材、混凝土、鋼材,它們的特性會有變異。同一批混凝土,這塊可能比那塊脆一點點。同一批鋼材,這根可能比那根軟一點點。
所以結構工程師從來不會「剛剛好」設計。他們永遠會留容錯空間。
We need probably some of that kind of thinking ourselves. What are the tolerances of the non-determinism that we have to deal with?
「我們可能需要一些這樣的思維。非確定性的容錯範圍是什麼?」更重要的是下一句:
We can't skate too close to the edge, because otherwise we're going to have some bridges collapsing.
「我們不能太靠近邊緣,否則會有橋梁倒塌。」在軟體產業一直以來我們都很習慣確定性的世界,我們寫的測試之所以有意義,是因為程式碼是確定性的,如果測試通過了,它就應該一直通過。但當你的工具本身是非確定性的,傳統的測試方法夠用嗎?當你用 AI 寫程式,你怎麼知道它這次寫對了,下次還會寫對?你怎麼知道它在這個情況下正確,在那個情況下也正確?你怎麼建立對一個「可能會說謊」的工具的信任?
這些問題,目前整個產業可能都還在摸索中。
非確定性對程式教育和團隊協作的衝擊
這個「非確定性」的問題,讓我想到兩個很實際的場景。
第一個場景是教學現場。
我在五倍學院教程式設計十多年,一直以來的教學方法都是建立在「確定性」之上的。我會告訴學生:「你輸入這段程式碼,就會得到這個結果。」或是「這個函數接收這些參數,然後就會回傳這個值。」
學生可以自己驗證,看到結果跟我說的一樣,就會建立起對程式設計的信心。但現在呢?如果學生問 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 說:「抱歉,讓我改正」
然後它改成了昨天的日期!
You need to get this experience to see that it can gaslight you for a simple thing of today'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 上的一則推文提到的。他提出的這個概念意思是:你完全不看 AI 產生的程式碼,只管它能不能跑、有沒有達到你要的效果。
這聽起來很美好,你只要用自然語言描述你要什麼,AI 就會幫你生出來。不用管什麼變數命名、函數設計、程式架構,反正那些程式碼你也不會看(可能也看不懂),反正能動就好。Martin 對此的看法:
I think it's good for explorations, it's good for throwaways, disposable stuff, but you don't want to be using it for anything that's going to have any long-term capability.
「我認為它適合用來探索、適合用來做拋棄式的東西,但你不會想把它用在任何需要長期維護的專案上」
他舉了一個例子,他的同事要在部落格文章中放一張示意圖,就請 AI 幫忙生成一個 SVG 圖片。產出的圖看起來還可以。但當 Martin 想要微調一下,例如把標籤移近一點,當他打開那個 SVG 檔案的時候...
「天啊!」那個 SVG 有夠複雜!明明只是幾條曲線和標籤,卻寫成了一堆難以理解的座標點和路徑。想要手動調整幾乎不可能。這就是 Vibe Coding 的問題。當你不看程式碼的時候,你放棄了理解它的能力。而當你不理解一段程式碼,你就無法修改它。
你唯一能做的就是...呃,重新來過。
All you can do is nuke it from orbit and start again.
「你唯一能做的就是從軌道上核爆它,然後重新開始」每次你要改什麼東西,都要重新說一次需求,然後開始祈禱 AI 這次能猜對。如果它還是沒猜對呢?再一次、再一次、再一次,反正累的又不是你。對於一個週末的 side project 可能還可以接受,但對於一個可能維護好幾年的系統呢?
學習迴圈:你以為你在用工具,但你可能正在斷送自己的成長
這裡我想特別花一些篇幅來討論一個概念,我認為這是整場訪談中很重要的觀點,特別對於正在學習程式設計的人來說。Martin 的同事提出了一個觀察:
When you're using vibe coding, you're actually removing a very important part of something, which is the learning loop.
「當你使用 Vibe Coding 時,你實際上拿掉了一個非常重要的東西,那就是『學習迴圈』。」
什麼是「學習迴圈(Learning Loop)」?想像你在學一個新的程式語言或框架,在腦中可能有個想法:「我要來做一個待辦事項清單的 App」,然後打開編輯器開始寫程式。寫了一段程式碼,執行之後發現結果不對,接著回去看程式碼想想可能是哪裡寫錯了。然後查文件、查 Google、翻 Stack Overflow 上的答案,相信大家對於開發過程中,瀏覽器分頁開滿了捨不得關掉的 Stack Overflow 這種場景都不陌生。接著再繼續修改程式碼,再跑一次。這次對了,但網頁打開的速度有點慢。你開始思考為什麼慢,怎麼最佳化...
這個過程,從想法到程式碼再從程式碼到結果,最後再從結果到理解,就是學習迴圈。這是人類學習新事物的基本方式,這麼多年來一直都沒什麼改變。在這個過程中累積經驗、建立直覺、學習什麼做法是好的、什麼做法是壞的。
If you're not looking at the output, you'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。
什麼是 Smoke Test?這個名字聽起來很酷,其實概念很簡單。想像你修好一台電視,如果插上電源之後就開始冒煙,那就不用再測其他功能了。Smoke Test 大概就是這個意思,先測最基本、最核心的功能有沒有在運作。
以我的售票平台來說,Smoke Test 大概就是:能不能開啟首頁?能不能看到活動列表?能不能走完結帳流程?這些如果壞掉,其他功能再完美都沒有意義。
IDE vs AI:不是所有釘子都要用 AI 這把鐵鎚
在訪談中,Martin 的同事 James Lewis 分享了一個有趣的實驗。他想用 Cursor 來改一個類別的名稱。這個操作,在傳統的 IDE 裡面只要右鍵點一下「Rename」,然後輸入新名字,一秒鐘就完成了。IDE 會自動找到所有引用這個類別的地方,全部更新。
結果用 Cursor 呢?他等了一個半小時,用掉了當月 10% 的 token 額度。而且還不一定改對,可能漏掉了一些地方,或是改到不該改的東西。
We've had this technology for a long time. So it'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。
比較年輕的工程師可能沒有經歷過這段故事。在 Stack Overflow 之前,在網路上查詢程式相關的問題,你很有可能被導到一個叫 Experts Exchange 的網站。這個網站上的答案得要課金才能看,大部分的人可能不會付錢,因為就算付了,裡面也可能找不到答案。
然後 Stack Overflow 出現了。突然之間,你可以找到免費的程式碼片段,直接複製貼上。很多初學者就這樣複製、貼上、看看能不能跑。不管它在做什麼,不管為什麼這樣寫。能跑就好。
資深工程師會跟他們說:「你要先理解這段程式碼在做什麼。」「就算它能跑,你也要知道為什麼能跑。」
I feel we'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 年出了第二版。可以說,「重構」這個概念能在業界廣為流傳,有很大一部分要歸功於這本書。他說了一句我很喜歡的話:
Each step is so small, but it's not worth doing, but you string them together and you can really do amazing things.
「每一步都小到不值得做,但當你把它們串起來,你可以做到驚人的事情。」重構的精髓就是這樣,每一步都小到看起來沒什麼意義,但累積起來的效果是驚人的。那在 AI 時代,重構還重要嗎?Martin 認為不只重要,可能更重要了:
If you'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 在訪談的最後說了一句話,我覺得很適合作為這篇文章的結尾:
I don't think AI is going to wipe out software development. I think it'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 能讓你變強,也可以讓你變弱。選擇在你 :)