草根AI:超越登月計劃
本文批判了當前AI領域追求完全自主代碼生成的“登月計劃”式目標,回顧了歷史上類似的失敗嘗試(如XML、UML、低代碼/無代碼),指出自然語言規範無法取代代碼作為唯一真理,並警告AI生成規範的方法存在數據到信息再到情報的誤差累積問題。
在人工智能領域,似乎每個人都想追求所謂的“登月計劃”——一種神奇的組合,能讓代碼自主、可靠、可持續且廉價地編寫。這並非新想法,而且它並不奏效。
我理解登月計劃的誘惑:開疆拓土、創造新範式、成為《時代》雜誌封面上的英雄。畢竟,如果你不顛覆一個行業,你還能做什麼?我明白,如果能創建出一個在無人監督下編寫代碼的系統,那將是巨大的勝利。但軟件歷史中的無數警示故事讓我幾乎無法原諒這種嘗試。
“我們不再需要查看代碼”的歷史
XML於1998年首次發佈。當時它被認為是一場革命,帶來了各種工具:XSL、XPath、XSLT……XML文檔本應是可組合的,願景是互聯網上的文檔相互連接,形成互聯的信息景觀。那時我們開始談論語義網。未來是光明的。
事實上,XML很笨重,沒有人真正喜歡它,但這沒關係——因為它不是為人類設計的,而是為機器設計的。你不應該閲讀或編寫XML文檔,只需處理解釋和修改XML內容的圖形界面。幾十年後,XML在很大程度上被JSON和YAML取代,它們對程序員更友好。事實證明,人們確實喜歡直接閲讀和操作文件。
大約在同一時間,出現了KDevelop和Eclipse等最早的圖形化IDE。它們有大量插件和圖形界面,顯示項目的多個視圖:一個面板用於Ant命令,另一個面板用於列出可用方法等。再加上當時較小的屏幕和較低的分辨率,導致代碼面板只是中間的一個小窗口,幾乎只能顯示15-20行代碼;但這沒關係——因為你實際上不需要看代碼,你只與圖形元素交互。創建一個方法意味着File -> Add -> Method(或類似的步驟),然後會彈出一個對話框,你輸入名稱、參數等。向Maven添加依賴項也有自己的對話框。你不與代碼交互——那是為機器準備的。你與UI交互。
早期的Eclipse IDE版本。沒有太多空間留給代碼;但這並不重要。
如今,IDE將代碼面板儘可能放大,甚至並排顯示兩個或更多代碼面板。還有一些極簡主義選項,如Sublime,去掉了所有圖形元素,讓你完全專注於代碼。
那時也是Poseidon出現的時候。UML風靡一時,面向對象編程正在興起,Poseidon將這一切與一個新的承諾結合起來:你使用UML繪製構成程序的實體,指出關係和屬性,它為你生成代碼。因為你是一位高價值的工程師,不應該浪費時間和才能去編寫代碼。不,先生。
海神顯然非常擅長編程。
不用説,這並沒有成功。他們的辯護者會説:“初級工程師讀代碼,高級工程師讀圖。”他們把自己比作處理藍圖而非磚塊的建築師。但最終,我們回到了代碼。
ETL、低代碼、無代碼……我可以一直列舉下去。夢想從未改變:我們不再需要查看代碼。每次像我這樣的末日預言者會咕噥“我們以前試過”。每次我們都會聽到“但這次不同”。每一次,它又變成了另一個破碎的夢。每一次,我們回到了代碼。
事實上,歷史教給我們的不僅是不會放棄直接操作代碼,反而加倍下注!我們將通常通過配置、設置和UI管理的活動也變成了代碼,從而誕生了基礎設施即代碼、GitOps,最終是萬物即代碼。
代碼即規範
在今天“但這次不同”的陣營中,理論是你編寫所需內容的詳細規範,AI創建代碼。以至於人們將AI規範與編譯器相提並論,稱這只是另一個抽象層。他們聲稱AI生成代碼的批評者就像早期不喜歡高級語言而繼續使用匯編的程序員。然而,這一類比經不起推敲。
編程語言通常由BNF文法描述,可用於驗證其語法是否正確。它還有一個編譯器,以數學精度將源語言轉換為目標語言。“數學”一詞在此絕非誇張:編譯器確實可以被描述為一個數學函數,以定義明確且可預測的方式將輸入轉換為輸出。事實上,這種特性從一開始就威脅到了軟件專利的概念:所有軟件都可以使用lambda演算重寫為數學公式,而數學公式不能申請專利。但我説遠了,重點在於,當你編譯源代碼時,你確切知道會得到什麼(或者至少應該得到什麼)。
AI並非如此;或者説,LLM並非如此。自然語言無法被正式定義。自然語言混亂、模稜兩可,最糟糕的是,它的含義隨着時間、地點和文化而變化。或者正如維特根斯坦所説,“一個詞的意義在於它在語言中的用法”。這就是為什麼律師在起草協議時要費盡心思以防日後反噬。理論上,你可以用自然語言編寫一個指示你想要的規範。實際上,該規範有可能被誤解,可能遺漏隱性知識,或者基於未溝通的假設。AI會順從地嘗試生成匹配你的規範的程序,但必然會出現幻覺、遺漏和偏差。此外,考慮到LLM本質上是非確定性的,連續兩次使用相同的輸入調用它會得到不同的輸出。總體行為可能得以保留,但會引入細微的漂移。這與人類期望相沖突:沒有人喜歡按鈕被隨意移動,即使它們功能完全相同。
解決方案據稱非常簡單:確保你的規範包含所有相關細節、所有需求、所有邊緣情況、所有知識。確保它的編寫方式不留歧義。確保它明確排除了任何潛在的誤解。確保所有利益相關者都已審查並批准了它。簡而言之,確保你的規範是良好定義的。好啊,再來一份薯條吧。良好定義的規範自從軟件開發成為一個行業以來就一直是個聖盃。它從未實現過。良好定義的規範是軟件領域的球形奶牛。
但讓我們繼續假設我們可以創建一個包含項目細節的良好定義規範,現在我們發現自己面臨着完美地圖悖論:要毫無錯誤地指定代碼必須做的一切,唯一的方法是以與代碼本身一樣多的細節來指定它。地圖變得和它試圖描述的領土一樣大。規範變得冗餘,因為它不再是代碼的抽象,而是變成了代碼的副本,而對於代碼,我們已經有了實際的代碼。
最終,代碼是唯一的真理源。
畢竟,這是基本熵的問題,完美地體現在柏拉圖的理型論中:你可以從特殊中構想抽象,但從抽象中創造特殊總是有缺陷的。
用AI創建規範
在可預見的“AI萬物化”風格中,新興的規範驅動開發的捍衞者認為,你可以將AI嵌入所有業務交互中,這樣規範就會自動編寫(聽起來耳熟嗎?)。你有一個會議?啓用AI記筆記,會議結論自動可用。你錄製了一次用户研究會議?讓AI提取要點。你現在擁有的文檔多得一輩子都處理不完?使用AI分析並提煉要點。這些信息是否稀疏、矛盾且可能錯誤?AI會為你修復。
此時,我們需要向那些處理潛在不可靠數據數十年的機構——情報界,即CIA、NSA、SIS及其朋友們——學習。首先,我們需要區分三個概念:數據、信息和情報。
數據:事實,不帶任何判斷或分析。例如“伯尼斯説了X”或“三月份售出了200個玩具”。
信息:結構化數據,以在特定上下文或目的下變得相關的方式組織和過濾。例如“玩具銷量持續下降”。
情報:從目標、價值觀和環境的視角分析信息,以生成可操作的指令。例如“由於競爭對手更有效的營銷,他們正在蠶食我們的市場份額”。
AI可以輕鬆提供大量表面數據,其中大部分是正確的。AI可以嘗試從數據中生成信息,但這往往會遺漏重要的細微差別,這些細微差別沒有寫在任何地方,因為它們屬於集體的、不言而喻的知識(共同假設、制度慣性、文化暗示等)。如果你再次嘗試使用AI進入下一步,所有微小的錯誤會累積,產生看似不錯但足夠不準確的情報,使其無法使用。有點像複印件的複印件。
“你們這些信心渺小的人!這有一個簡單的解決方案,只需要讓人審查並在必要時糾正AI生成的所有內容。所以會議後,人們審查並批准會議記錄。然後,在AI整合後,人們審查並批准摘要。然後,當規範被編寫時……”
繼續,我讓你説完,你可以自己寫反駁。
但暗工廠!
啊,是的,暗工廠。如果你還沒聽説過,暗工廠(或熄燈工廠)是高度自動化以至於不再需要人類的工廠。而且,既然不需要人類,他們甚至不需要開燈,所以它們在黑暗中運行。很酷。這個想法讓一些人興奮不已,引發了下一個科幻類比:AI是我們的暗工廠,你釋放一堆代理,它們在沒有人類干預的情況下創建代碼。“我在溜狗時建了一個加密貨幣交易平台。”諸如此類。
讓我們退幾步。首先,時間尺度問題。工業革命開始於大約250年前,直到現在才開始談論完全自動化、沒有人類參與的工廠。整個軟件行業存在時間不超過70年,AI更短;期望在這麼短的時間內將高度手動的工作變成完全自動化是過於樂觀的。
其次,製造業和軟件之間有一個根本區別:在製造業中,你生產多個完全相同的副本。而在軟件中,每次構建都是獨一無二的。