我通常很支持 AI,但有一個主要的例外:代理式編碼。

我一貫的印象是,代理式編碼實際上並未提高生產力,反而會損害使用者對程式碼庫的舒適度和熟悉度。

我形成這個印象是基於:

每次使用代理式編碼工具時,我對結果的品質總是感到不滿意。

我面試應徵者的經驗

我允許面試應徵者使用代理式編碼工具,而使用這些工具的應徵者表現總是比其他應徵者差,他們無法完成挑戰或產生錯誤的結果¹。\這起初讓我非常驚訝,因為我原以為代理式編碼會帶來不公平的優勢,但……並不會!

像 Becker 研究和 Shen 研究表明,當以固定結果而非程式碼速度/量來衡量生產力時,代理式編碼的使用者表現沒有更好,有時甚至更差。

我不認為代理式編碼是死路一條,但我確實認為目前形式的代理式編碼對軟體開發弊大於利。\我也認為,持續探討代理式編碼的不足之處仍然是有價值的,以便它能賦予開發者能力並提高程式碼品質。

然而,在這篇文章中,我將採取不同的方法:我想介紹利用 AI 進行軟體開發的其他方式。\我相信代理式編碼已經如此深入人心,以至於人們忽略了其他良好且未被充分探索的 AI 輔助軟體開發解決方案。

我喜歡從第一原理設計工具和介面,而不是對行業趨勢/炒作做出反應,並且我在開發者生產力(DevProd)領域十多年的工作經驗,以及更長期的開源專案和貢獻歷史,為我累積了不少通用設計原則。

其中一個設計原則是我的個人「主提示」,即:

一個好的工具或介面應該讓使用者盡可能長時間地保持在心流狀態。

這個原則甚至不特定於 AI 輔助軟體開發,但它仍然突顯了代理式編碼有時為何會失準。\研究和開發者證詞都表明,代理式編碼會打破心流,讓開發者比普通編碼更常處於閒置/可中斷的等待模式。

例如,Becker 研究透過螢幕錄影發現,閒置時間大約翻倍:

我相信,如果我們將「保持心流狀態」設定為我們的北極星,我們可以改進 AI 輔助編碼工具(無論是否代理式)。

平靜科技(Calm technology)是一門促進工具中心流狀態的設計學科。\與編碼最相關的設計原則是:

工具應盡量減少對我們注意力的要求。

中斷和侵擾我們的注意力會讓我們脫離心流狀態。

工具應被建構成「通道式」(pass-through)。

工具不應成為我們注意力的對象;相反地,工具應揭示我們注意力的真正對象(工具作用的對象),而不是模糊它。我們越使用工具,工具就越融入我們意識的背景,同時仍然支持我們的工作。

工具應創造和增強平靜(因此得名:平靜科技)。

平靜的狀態有助於使用者進入並維持心流狀態。

工程師已經將「平靜」的工具和介面作為我們工作的一部分,這裡有幾個您可能已經熟悉的例子:

IDE(如 VSCode)可以支援內嵌提示,在程式碼中散佈對讀者有用的註釋,例如推斷的類型註釋:

這些內嵌提示類型體現了平靜設計原則,因為:

它們最大限度地減少了對我們注意力的要求。

它們存在於我們注意力的周邊,如果我們感興趣就可以獲得,但不感興趣時也不會打擾。

它們不會取代或替代我們正在編輯的程式碼。它們增強了程式碼編輯體驗,但使用者仍然直接接觸正在編輯的程式碼。我們越使用類型提示,它們就越融入我們意識的背景,程式碼就越成為我們注意力的焦點。

它們透過被動地告知我們對程式碼的理解來促進平靜感。正如「平靜科技」原則之一所說:「科技可以溝通,但不必說話」。

像 VSCode 或 GitHub 的 pull request 檢視器這樣的工具,可以讓您一目了然地預覽檔案樹的變更,如下所示:

您可能會想:「這是一個非常無趣的例子」,但這正是重點。最好的工具(以平靜科技原則設計)是普遍存在且無聊的事物,我們習以為常(就像電燈開關),並且已深深融入我們意識的背景,以至於我們忘記了它們作為我們日常工作流程的一部分(也像電燈開關)。

如果我們需要這些資訊,它們就在那裡,但如果我們不需要,也很容易忽略(甚至忘記它們的存在)。

當我們與檔案樹檢視器互動時,我們直接與檔案系統互動,而表示(檢視器)與現實(檔案系統)之間的互動感覺直接、快速且精確。我們越使用檢視器,表示就越與現實在我们腦海中 indistinguishable。

我們不需要不斷與檔案樹互動來收集關於我們專案結構的最新資訊。當我們對專案進行變更時,它會在背景中被動更新,這些更新不會打擾人且不引人注目。

我們可以從相同的角度思考聊天式代理式編碼工具的限制:

它們對我們的注意力要求很高。

使用者必須坐著等待代理回報,或者做其他事情並以半自主的方式運行 LLM。然而,即使是半自主的會話也會阻止使用者進入心流狀態,因為他們必須保持可中斷的狀態。

它們不是被建構成「通道式」的。

聊天代理是程式碼的高度中介介面,這是間接的(我們與代理的互動比與程式碼的互動多)、緩慢的(我們花費大量時間等待),且不精確的(英語是一種鈍的介面)。

使用者需要不斷刺激聊天以收集新資訊或更新他們對程式碼的理解(聊天代理不會被動或悄悄地告知使用者的理解)。聊天代理也經過微調以最大化參與度。

最早開始模擬平靜設計原則的 AI 編碼助手之一是 OG AI 助手:GitHub Copilot 的內嵌建議支援,但有一些需要注意的細節,我將在後面說明。

它被建構成「通道式」的。

使用者仍然直接與程式碼互動,建議也相當快速。使用者也可以忽略或輸入來接受建議。

然而,預設情況下,這些內嵌建議違反了其他平靜科技原則:

預設情況下,Copilot 會非常頻繁地顯示建議,使用者必須暫停他們正在做的事情來檢查建議的輸出。經過足夠多次後,使用者會習慣性地暫停並等待建議,這會打破他們的心流狀態。現在,使用者不再是主動的,而是被工具訓練成被動的。

GitHub Copilot 的內嵌建議介面在視覺上很雜亂且具侵入性。即使使用者忽略了每一個建議,效果仍然是破壞性的:建議出現在使用者螢幕的視覺焦點中心,使用者必須當場決定是否接受或忽略它們,然後才能繼續。使用者也無法輕鬆地被動吸收以這種方式呈現的資訊:理解每個建議都需要使用者專注的注意力。

……但這些問題可以透過禁用自動建議並要求透過 Alt + \ 來明確觸發來部分解決。然而,不幸的是,這也會禁用我更喜歡的下一個功能:

下一個編輯建議是 GitHub Copilot 的一個相關功能,它會在整個檔案/專案中顯示相關的後續編輯,並讓使用者在它們之間循環,並可能接受每個建議的變更。它們的行為就像一個「超級充電的尋找和替換」:

這些建議在讓使用者保持心流狀態方面做得非常出色:

它們最大限度地減少了對使用者注意力的要求。

使用者認知負載比內嵌建議小,因為建議更有可能是片段式的(因此更容易供人類審查和接受)。

它們被建構成「通道式」的。

就像內嵌建議一樣,下一個編輯建議仍然讓使用者與他們正在修改的程式碼保持緊密聯繫。

建議的呈現方式不具侵入性:它們不會被傾倒在使用者注意力的正中心,也不會要求立即審查。它們存在於使用者注意力的周邊,作為程式碼建議,使用者可以隨時忽略或專注於它們。

我相信 AI 輔助編碼工具還有很多未開發的潛力,在本節中,我將勾勒出一些小範例,說明我們如何在下一代編碼工具的建構中體現平靜科技設計原則。

您可以透過語意化面的樹狀結構瀏覽專案。例如,如果您正在編輯 Dhall 的 Haskell 實現,樹狀檢視器可能會像我駭客攻擊的prototype²一樣:

目標不僅是提供一種透過意圖快速探索專案的方式,而且是隨著使用者使用該功能,也能增強使用者對專案的理解。「字串插值回歸」比 dhall/tests/format/issue2078A.dhall³ 更有資訊量。

此外,上面的影片是基於一個真實的工具,而不僅僅是一個模擬。您可以在這裡找到我用來生成這個語意化面樹的程式碼,我很快會寫另一篇文章詳細介紹該程式碼的工作原理。

您可以將編輯器會話、diff 或 pull request 自動拆分成一系列更專注的提交,讓人類更容易審查。這是 AI 可以減少人類審查勞動的案例之一(大多數代理式編碼工具會產生更多人類審查勞動)。

這裡有一些先前的工作,但這仍然是一個新興的發展領域。

您可以為使用者的工具列或右鍵選單添加兩個新工具:「聚焦於...」和「編輯為...」。

「聚焦於...」允許使用者指定他們感興趣的變更,並且只顯示與他們指定興趣相關的檔案和程式碼行。例如,如果他們想專注於「命令列選項」,那麼只有相關的檔案和程式碼行會顯示在編輯器中,其他程式碼行將被隱藏/摺疊/折疊。這基本上就像「禪模式」,但用於編輯感興趣的功能領域。

「編輯為...」允許使用者將檔案或選定的程式碼編輯為不同的程式語言或檔案格式。例如,一個不熟悉 Haskell 的人可以「像 Python 一樣」編輯 Haskell 檔案,然後在完成編輯後,AI 會嘗試將他們的變更反向傳播回 Haskell。或者,修改命令列解析器的人可以「像 YAML 一樣」編輯檔案,並看到一個簡化的 YAML 表示形式的命令列選項,他們可以修改這些選項來添加新選項。

這顯然不是一個全面的想法列表,但我寫這篇文章是為了鼓勵人們思考更多創新的方法,將 AI 融入人們的工作流程,而不僅僅是建立另一個聊天機器人。我堅信聊天是與 LLM 最不有趣的介面,AI 輔助軟體開發也不例外。

獲得正確的輸出甚至不應該是編碼挑戰的難點。標準的程式碼挑戰為應徵者提供了一個黃金輸出,他們的程式碼需要匹配,儘管如此,代理式編碼者不僅無法匹配黃金輸出,有時甚至沒有意識到他們的程式碼不匹配黃金輸出,因為他們甚至沒有運行他們代理式編碼的解決方案來檢查它是否正確。編碼挑戰的實際難點應該是關於生產之旅的後續問題,而這種氛圍的編碼者表現也更差。↩

叢集標籤器仍需努力,但您懂我的意思。↩

這是我的錯,因為我命名了檔案 😅。↩