Coding with LLMs in the summer of 2025 (an update)

Salvatore Sanfilippo

2025 年夏天與 LLM 一起寫程式(更新版)

原文由 Salvatore Sanfilippo 發布,訂閱此部落格

像 Gemini 2.5 PRO 這類最前線的 LLM,憑藉其對眾多主題的廣博理解,以及在幾秒鐘內掌握數千行程式碼的能力,能夠延伸並放大程式設計師的能力。如果你能清楚地描述問題,並且願意接受與 LLM 協作所需的一來一往,就能達到以下令人驚豔的成果:

  1. 在程式碼接觸到任何使用者之前就消滅你寫進去的 bug:我在實作 Redis 的 Vector Sets 時就深有體會。這些 bug 我最終本來也會全部修掉,但有許多是在 Gemini / Claude 的程式碼審閱下立刻就被揪出來並排除了。
  2. 更快地探索某個想法是否可行,讓 LLM 撰寫用完即丟的測試程式碼,盡快驗證某個解法是否真的更高效、是否夠好等等。
  3. 進行結對設計,你的直覺、經驗與設計品味,可以和 LLM 內建的博士級知識相互融合。在這個過程中,LLM 有時會提出愚蠢的方向,有時卻能給出極為出色的點子:而你,身為人類的角色,就是要幫助跳脫局部最佳解與錯誤,並善用這位數位夥伴在某些領域無人能及的廣博知識。
  4. 在你明確的規格指示下,讓 LLM 代為撰寫部分程式碼以加速工作進度。
  5. 借助 LLM 作為你心智特定部分的延伸,來處理那些離你的專業有段距離、卻又與你的能力相鄰的技術(例如:為 Amiga demo 寫 68000 組合語言?),補足你所欠缺的知識。

一年半前,我寫了一篇名為「LLMs and programming in the first days of 2024」的部落格文章。當時我就覺得 LLM 已經相當實用,但在這一年半裡,它們的進步徹底改變了局勢。然而,要真正發揮它們的能力,與 LLM 互動的人必須具備某些特質並遵循特定的實踐方式。接下來就來談談這些要點。

多數時候請拒絕 vibe coding

在這個歷史時刻,LLM 是優秀的放大器,卻是糟糕的單人樂隊。對於一些小型的用完即丟的專案,讓 LLM 寫完整份程式碼仍是合理的,例如測試、小型工具這類幾百行程式碼的東西。但雖然 LLM 能在你的嚴格監督下成功撰寫程式碼庫的一部分(詳見後述),並帶來顯著的開發加速(或者說,在相同的時間內能開發出更多、更好的東西——這就是我的做法),當你把它們單獨丟去處理不簡單的目標時,它們往往會產出脆弱、過於龐大、複雜、充滿局部最佳解選擇、處處不夠理想的程式碼庫。而且,當任務複雜度超過一定門檻時,它們甚至會徹底失敗。明天這一切或許都會改變,但就目前與 LLM 每天一起寫程式的經驗而言,我堅信最高的工作品質來自「人類 + LLM」的組合。我相信人類與 LLM 合作會比單靠人類更有生產力,但這有個很大的前提——那就是人必須具備強大的溝通能力與豐富的 LLM 使用經驗:能否高效溝通,是運用 LLM 的關鍵因素。

提供充足的上下文

當你的目標是與 LLM 一起推敲如何實作或修復某段程式碼時,你必須提供大量的資訊給 LLM:相關論文、目標程式碼庫的很大一部分(如果可能的話就提供整個程式碼庫,除非那會讓上下文視窗大到影響 LLM 的效能),以及你對該做什麼的所有理解的一次性傾倒。這份 brain dump 尤其應該包含以下內容:

  • 關於那些看似不錯、實則不佳的解法的提示,以及它們為何可能不夠理想的原因。
  • 關於極具潛力的優秀解法的提示,即使人類尚未完全想清楚也沒關係:LLM 往往能藉此找到正確的路徑。
  • 明確的目標、我們要求的不變量,甚至是程式碼應有的風格。舉例來說,LLM 寫的 Python 程式碼往往充滿不必要的相依套件,但透過適當的提示可以減輕這個問題。就我的經驗而言,C 語言的程式碼通常要好得多。

在處理那些不那麼普及或顯而易見的特定技術時,通常把相關文件也一起放進上下文視窗是個好主意。例如在為 vector sets(一種新到 LLM 還不認識的 Redis 資料型別)撰寫測試時,我會把 README 檔案放進上下文:就靠這樣一個簡單的小技巧,LLM 馬上就能以專家等級來運用 vector sets。

選對 LLM

最有名的 LLM 並非最好的。寫程式主要應該使用:

  • Gemini 2.5 PRO
  • Claude Opus 4

以我的經驗,Gemini 2.5 PRO 在語意理解上更強大。能發現更複雜的 bug,也能推理更複雜的問題。Claude Opus 有時在撰寫新程式碼上可能更勝一籌(有時則不然),使用者介面也更舒適,而且一般來說,面對複雜問題時,你至少需要兩個 LLM 來回對照,才能擴展你(人類)對設計空間的理解。如果只能選一個,那就選 Gemini 2.5 PRO。

對所使用的 LLM 的基本要求是:不要使用代理(agent)或像是整合了 coding agent 的編輯器之類的東西。你會想要:

  • 永遠把東西直接交給最強大的模型,也就是最前線的 LLM 本身。
  • 避免任何只會讓 LLM 看到部分程式碼/上下文的 RAG。這會摧毀 LLM 的表現。你必須掌控 LLM 在回覆時能看到什麼。
  • 始終讓自己留在迴圈中,手動把程式碼從你的終端機搬到 LLM 的網頁介面上:這能確保你跟上每一個過程。你依然是寫程式的人,只是被增強了。

結論

儘管大家對能獨立寫程式的 agent 抱有高度興趣,但就目前而言,身為軟體開發者,你可以透過明確地使用 LLM、並讓自己留在迴圈中,來最大化你的影響力。未來這一點無可避免會改變,隨著 AI 進步,最終許多寫程式的任務將更適合完全交給 AI:到了那個未來,人類將決定「做什麼」與「怎麼做」,這依然至關重要。但我們還沒到那裡。在當下這個時刻,掌控主導權才能讓你用 LLM 產出最精煉的程式碼:需要精簡時就精簡,需要複雜概念時就運用複雜概念。

你將能夠做到那些原本位在你知識/專業邊界上的事,同時在過程中學到很多(是的,你可以向 LLM 學習,就像你可以向書本或同事學習一樣:這是一種新的、可能的教育形式)。然而,所有產出的東西都將遵循你對程式碼與產品的理念,保持高品質,不會因為 LLM 引入的錯誤與缺陷而隨機失效。你也將對所有撰寫的程式碼及其設計保持深刻的理解。

不時測試一下 agent 能做到什麼程度是明智的。但每當你覺得它們做得不如你好時,就回到你的終端機,在 AI 的協助下寫程式(當你覺得它能提升你的產出時;有些時候你獨自一人反而做得更好)。當 agent 真的能做出卓越成果的那一天到來時,我會第一個轉向,到那時我自己寫程式就純粹是出於熱情。但就現在,讓我們跳過炒作,以最好的方式使用 AI,也就是:保有主導權。然而,還有另一種風險:出於意識形態或心理上的抗拒而迴避 LLM,進而累積劣勢(並且無法培養出一整套——難以言喻——與 LLM 協作所需的技能)。或許這真的就是所謂的「中庸即美德」(In medio stat virtus)。

本文章由 muse-spark-1.2-contributor 進行翻譯

留言