幾天前,我寫了這篇文章:「Understanding Over Origin」,它得到了很多互動,我真的很高興,因為這代表大家花時間閱讀、理解我的觀點,而我也能在留言裡和每一位交流。當然,不是每個人都同意,但那並不重要,重點是來自世界各地不同開發者之間,能有一場健康的討論。
但有一件事我沒有告訴任何人:我互動得越多,就越意識到一件我自己仍然在做的事。我依然有很多程式碼是手寫的,而那些部分也是我最引以為傲的。
這不是把關,不是我懷舊,也不是在捍衛身分認同——好吧,有一點懷舊——這其實是在承認我發表的那篇文章 不完整。
有些對話不會在回覆停止時結束。我和 @darkwiiplayer 的討論大概是我最喜歡的一場,因為我們談得越多,我就越發現自己在和一個不願意保持未完成狀態的不完整想法搏鬥,而這篇文章就是結果。
首先,我要感謝那些真的針對核心論點進行討論的人。
@unitbuilds 提出了他的看法,把一切串聯起來,並點出現代軟體工程的核心概念:「如果它能在標準化的基準測試套件中與競品比較,那它就是可證明且可重現的。若這對科學發現來說已經夠好,那對程式設計也夠好。」他們不是在替 AI 辯護,而是在說:既然有更好的標準,我們就不該選擇忽視它們。他也指出了我漏掉的一點:正確性的責任,從來都落在簽核 PR 的開發者身上。
@madsendev 寫了引發這整場討論的原始文章,他表現得非常有風度。他回來說,這個論點已經「延伸得更遠」了,並提出一個我一直記在心上的想法:如果 AI 協作專案也納入一種標準,要求你針對自己的儲存庫進行自我測驗,會怎麼樣?不是為了證明你沒用 AI,而是為了證明你真的理解自己做了什麼。
@Komo 提出了很重要的一點,而我覺得這也是這場討論中我最喜歡的結論:「維護紀錄很難造假。」 這一句話就足以重新定義整場辯論。測試、修補漏洞、正式環境事故、回應 issue、重構。每一項都會留下證據,證明一個人不只是做出這個專案,還持續理解它、改進它,並為它負責。這才是有意義的 ownership。它是時間累積出來的,也比在面試中解釋程式碼、或聲稱自己每一行都是親手寫的,更難造假。
我非常感謝大家願意分享想法,但一場好的討論,永遠少不了反對意見 ⚔️
反駁,永遠是任何技術討論中我最喜歡的部分。
@darkwiiplayer 出現後說了類似這樣的話:「在未經同意的情況下,用偷來的程式碼訓練 AI,就是偷竊。任何用 AI 做出來的東西,都帶著這種偷竊的 DNA。你忽略了這件事。」
她不是在修辭,她是真的在提出一個關於訓練資料、同意,以及當『學習』是在沒有授權的大規模環境下進行時到底代表什麼的哲學問題。
我們來回討論。我主張訓練資料和生成結果不應該自動等同於抄襲;她則反問,如果把訓練資料中所有偷來的程式碼都移除,這些模型根本不會以現在的樣子存在。這……大概是真的?而這件事很重要。
我不認為這會否定 工程面 的論點。但它確實表示這場對話有兩個層次:
那串留言裡大多數人都在辯論第一層,而她把我拉進了第二層。兩者都是真實存在的。彼此都不會否定對方。
但這也讓我意識到,我原本那篇文章 沒有回答 為什麼手寫程式碼對我來說感覺不一樣,因為老實說?它就是不一樣。
我提出的論點是:來源不決定品質。理解、測試、可維護性、可問責性,這些才重要。
我的實際經驗也確實如此。我大概是從 2018 年開始寫程式,那時候我們大多數人唯一知道的 AI,大概就是來自香港的類人機器人 Sophia。我是用傳統方式學的:自己把一切寫出來。就算是今天,當我手寫程式碼時,我對它的理解也不同了。更深了。如果我先用 AI 產生初稿,我可能會忽略一些邊界情況。寫完之後,我也真的會對自己做出的東西更有成就感。
如果你想太多,這些說法其實彼此並不相容。
不是就是:
@fromzerotoship 幫我把第三種情況看得很清楚。他們不是開發者,但他們已經用 AI 交付了 20 多個可運作的內部工具。這些工具在一家醫院裡運作。按照我的標準,他們會在理解測試中「不及格」,因為他們系統中有些部分無法逐行解釋。
但接著他們說了一句完全改變一切的話:「在刻意失敗下可觀察到的行為,也是建立信任的一種方式,而且這是我唯一能做到的方式。這也更難造假。」
種下缺陷、看守門員把它抓出來、恢復守門員,看到它們變回綠燈,然後部署,再在幾秒後檢查網址。
他們證明了自己能讓它持續活著。
這讓我意識到,真正的差異不在於誰打了程式碼,而在於 摩擦。
在我幾週前寫的另一篇文章裡,我描述過這樣一件事:我明明可以完美審查某段邏輯,卻無法從零把它寫出來。那不只是技能退化,而是證明我跳過了建立真正理解所需要的摩擦。
當我手寫程式碼時,我會即時遇到問題。
我會碰壁。我的方法行不通。我會重構。我透過限制與失敗去發現問題空間。我做的是「關於決策的決策」,不只是打字,而是在我實際探索過的路徑之間做選擇。這就是我每次手寫程式碼時,不知不覺經歷的學習路徑,而 Wii 讓我重新想起了這件事。
當我使用 AI 時,我描述我想要什麼。我得到一些選項。我挑看起來對的那一個。我是在篩選,不是在探索。
兩者都能產生好程式碼,但通往理解的路徑,本質上是不同的。
手寫程式碼:摩擦、洞察、更好的下一個決策
AI 協作:選擇、實作、驗證
摩擦,就是學習機制。
所以當我說我更以手寫程式碼為傲時?我不是在浪漫化痛苦。我只是在指出,我最引以為傲的程式碼,是那些我努力爭取來的程式碼,而手寫會迫使你去努力。
如果摩擦是機制,那麼 摩擦的種類 比起 誰負責打字 更重要。
你可以寫出 AI 協作的程式碼,然後:
那一樣有摩擦,也一樣能建立理解。
反過來,你也可以手寫程式碼,然後:
那就沒有摩擦,也什麼都建立不起來。
所以誠實一點地說,我的立場不是「手寫程式碼比較好」。而是:「摩擦會建立理解,而手寫 通常 會產生摩擦,因為你被迫思考每一行。」
但那是依情況而定的真理,不是絕對真理。
那些批評者(把關者,不過我們之後就這樣稱呼他們)有一部分是對的,而我在原本的立場裡太寬容了。
不是說把關本身,沒有,那仍然是錯的。但就 傾向 而言:AI 確實 讓人更容易產生低理解度的程式碼。不是因為 AI 很糟,而是因為 消除摩擦,正是 AI 的功能;而摩擦,正是建立理解的東西。
答案不是「少用 AI」或「永遠不要用 AI」。而是「如果你使用 AI 只是為了跳過與問題的接觸——不管是程式碼、失敗模式,還是維護——你就會做出更差的系統。」
這一點對人類也適用,但人類本身就有摩擦成本:我們會無聊、我們討厭打字、我們會犯錯。那種摩擦很煩,但它逼我們保持投入。
原本的論點沒有 錯。但我把「理解 + 可問責性」當成只是你最後可以檢查的勾選專案。
它們不是。
理解不是一個可以被檢查的屬性,它是一個 過程,而這個過程需要摩擦。需要真正投入問題。需要從錯誤中學習。
我之所以更以手寫程式碼為傲,是因為我以一種更難偽造的方式,爭取得到了 那份理解。
這是否代表每一行都應該手寫?不是。樣板程式就是樣板程式。有些摩擦只是噪音。
但核心邏輯呢?架構決策呢?那些「真正需要理解這段程式碼」的地方呢?對,我希望自己是為它們奮戰過的。
而我也希望任何在部署重要程式碼的人,都有同樣的態度。
我的結論是這樣:
對批評者: 你們用錯了篩選標準。「有沒有用 AI」其實什麼都看不出來,但你們碰巧說對了一件事:真正該擔心的是 AI 所促成的 懶惰,不是工具本身。
對 AI 愛好者: 是的,你們的工具很厲害。但值得想一想,你是在用它讓自己更會思考,還是思考得更少。這兩者在六個月後維護程式碼時,感覺完全不同。
對我自己: 我對手寫程式碼的自豪感不是自尊心作祟,這是合理的。每一行我親手打出來的字,並不是什麼魔法獨角獸神話般的神聖字句,但它代表的是伴隨而來的摩擦,以及我因此建立的學習。
有時候,答案需要承認你跳過了某些步驟,而有時候那對例行工作來說沒問題。但如果你在做的是重要的東西,你就應該希望自己曾為它奮戰過。
我還是會手寫很多程式碼,我也還是每天都在用 AI。這兩者現在不再矛盾了。
原本那篇文章說得沒錯:來源不決定品質。它沒說到的是,理解不是你最後勾選的核取方塊,而是你透過摩擦換來的東西。手寫往往會產生那種摩擦,AI 則往往會移除它。兩者本身都沒有絕對的好壞。兩者都是你如何與問題互動的選擇。
所以我現在不再問「你有沒有用 AI?」
我問的是:你有沒有為那些重要的部分奮戰過?
如果工具已經替你回答了這個問題,那麼下一次出錯時,你就會知道了。
原文出處:https://dev.to/adamthedeveloper/understanding-over-origin-the-missing-friction-55ag