AI 領域精選文章翻譯
by Lalit Maganti

原文連結: Eight years of wanting, three months of building with AI
對很多人來說,SQLite 只是資料庫;對 Lalit Maganti 來說,它是八年來一直卡在腦子裡的一個願望。
他在 Perfetto 的工作裡長期接觸 PerfettoSQL——一種建立在 SQLite 上、用來查性能 trace 的語言。這種語言一旦開始被團隊大量使用,使用者自然就會期待格式化器、linter、編輯器整合這些基本配套。但他翻遍現成工具後發現,不是解析不夠準,就是速度不夠快,不然就是沒辦法靈活地適應 PerfettoSQL 的擴充語法。做一套自己的工具,變成一個很合理、卻又一直被擱著的念頭。
問題不在於這件事不重要,而在於它太硬、太瑣碎。
如果只看 Perfetto,這套工具看起來像是一個很有價值但不算最優先的工程工作。可是 Lalit 想做的不是只服務 Perfetto,而是要讓任何 SQLite 使用者都能受惠。
這代表一件事:你得讓 parser 跟 SQLite 本身一模一樣。
對語言型 devtools 來說,parser 是核心。它負責把原始碼轉成 parse tree,後面的 formatter、linter、分析器全都建立在這個基礎上。如果 parser 不準,後面全部一起歪掉。他看到的不少工具,問題都出在這裡:它們大多只是「近似」SQLite,而不是精準重現 SQLite 的語法。
更麻煩的是,SQLite 本身沒有正式規格文件,也沒有穩定 parser API。甚至在它的實作裡,根本不會建出 parse tree。你想做這件事,最合理的路徑只有一條:從 SQLite 的原始碼裡把關鍵部分一段段拆出來,再改造成你要的 parser。
而 SQLite 的原始碼本身又是出了名難啃。整個專案是 C 寫的,風格極度濃縮、密集,光是理解 virtual table API 與其實作就夠費工。更不用說 parser stack 本身。
除此之外,SQLite 的語法規則超過 400 條。每一條 grammar rule 都得告訴系統:這段語法要對應到 parse tree 裡的哪個節點。這是高度重複的工作;每條都差不多,但每條又都不一樣。
而且不只是寫規則而已,還得配套測試、除錯、處理使用者回報的 bug。這就是這個想法多年來一直死掉的原因:太難、太無聊、太容易做一半就沒動力。
Lalit 從 2025 年初開始用 coding agents:Aider、Roo Code,到了 7 月才轉向 Claude Code。這些工具一直有幫助,但他從來沒覺得它們已經可靠到可以扛一個真正重要的專案。
直到 2025 年底,模型品質出現明顯躍升;同時他在 Perfetto 工作中持續碰到一些問題,如果有可靠的 parser,本來可以輕鬆解掉。這些 workaround 一次次提醒他:也許現在真的是把這個東西做出來的時候了。
他在聖誕節前後騰出一些空檔思考,然後做了一個很激進的實驗:能不能直接用 Claude Code Max 計畫(每月 £200)把整個專案 vibe-code 出來?
一月的大部分時間,他都把自己當成半技術主管在用:設計幾乎全交給 Claude,實作也幾乎全交給 Claude。結果是,他真的做出了一個可用版本:
看起來像是成功了。
但等他在一月底仔細回頭檢查 codebase,問題立刻浮現:整個專案已經變成一團亂麻。他有很多 Python 抽取流程的細節根本看不懂,函式散落在不同檔案裡,幾個檔案還長到幾千行。它非常脆弱,只解了眼前的問題,卻完全撐不起他更大的願景,更別說整合進 Perfetto 的整體工具鏈。
好消息是,這個實驗至少證明路線可行,而且還生出 500+ 個測試,很多都可以重用。
所以他做了最痛但最正確的決定:整個砍掉重練,同時把大部分 codebase 改成 Rust。
這不是因為他突然討厭 C,而是因為 C 讓高階元件——像 validator 跟 language server——很難做得優雅。換成同一門語言,也讓抽取層和執行層不必拆得四分五裂。
更重要的是,他完全改變了自己在專案裡的角色。他不再把自己當成「半放手的管理者」,而是掌握所有決策,並把 AI 當成「超強自動補全」來用:先把設計想清楚、每次改動都仔細審、看到問題就立刻修,並且投入更多 scaffolding,例如 linting、驗證與更複雜的測試,讓 AI 產出的東西能被自動檢查。
最後,核心功能在二月完成,三月初完成上游測試驗證、編輯器 extension、打包與文件,0.1 版在三月中旬釋出。
對他來說,時間線本身不是故事的重點。真正重要的是:如果沒有 AI,這個專案根本不會存在;但如果沒有人的設計與判斷,它也不會長成現在這樣。
Lalit 一直有個毛病:面對大型新專案時容易拖延。只是當年他沒意識到,這毛病剛好完美對應到 syntaqlite。
AI 幫他做的第一件事,不是寫大量程式碼,而是讓他跨過「我到底要怎麼開始」這一關。原本卡住他的問題是「我要怎麼理解 SQLite parser?」;有了 AI 之後,問題變成「我要怎麼逼 AI 先給我一個可拆解的方案,再把它推翻,做出更好的版本?」
對他來說,這種具體、可操作的小目標,遠比在腦袋裡空轉設計更有效。只要先踏出第一步,後面每一步都順多了。
在「程式碼本身很明確」的前提下,AI 的寫碼速度比他自己快得多。當任務可以被拆成「寫一個滿足這些參數與行為的函式」或「寫一個符合這個介面的 class」時,AI 不只快,還常常會用一種未來讀者更容易理解的標準寫法把東西補齊。
它會補文件、排版也更一致,整體很像語言的「標準方言」——大多數情況下,這正是你想要的。
但標準化也是雙面刃。對大部分程式來說,標準、可預測、好讀是最好的;可是一個專案裡總會有邊界地帶,那些價值來自非顯然設計的部分。對 syntaqlite 來說,那就是抽取流程與 parser 架構。AI 天生傾向把東西弄得更平均、更常規,這在這些地方反而有害;那些部分最後還是得他自己深入設計。
不過同樣的速度,也讓 AI 在重構上非常強。如果你用 AI 大量產碼,就一定要持續重構,不然程式碼很快就會失控。這是他在 vibe-coding 月份學到的核心教訓:當時他沒有及時重構,最後整個 codebase 變成自己無法理解的東西,只好全砍重來。
重寫之後,重構變成工作流程的核心。每次 AI 生出一大批東西,他都會停下來問自己:這東西 ugly 嗎?有時 AI 可以幫忙修;有時候是他看得出來,這裡其實需要一個更大的抽象,而 AI 看不到。那時他就會先給方向,再讓 AI 去執行。
如果你有 taste,選錯方向的成本會低很多,因為你可以很快重組。
在他實際使用 AI 的方式裡,研究的價值密度最高。
他以前雖然碰過 interpreter 和 parser,但從沒聽過 Wadler-Lindig pretty printing。當他需要做 formatter 時,AI 不只給了他一個可以直接操作的方向,還把背後的論文與原理一起講給他聽。這種學習速度,是他自己慢慢摸索很難達到的。
這個優勢也延伸到他不熟的領域。他對 C++ 與 Android performance 很熟,但 Rust 工具鏈和 editor extension API 幾乎沒碰過。AI 幫他跨過了那道學習門檻:基本概念都類似,術語也相近,AI 在中間把差距補起來了。原本可能要花一兩天先搞懂 VS Code extension API,他靠 AI 一小時就做出 working version。
它還能幫他重新接回幾天前沒碰過的程式碼。他可以用不同深度問問題:
當你一直切換 context 時,腦中的脈絡很容易掉光。AI 讓你可以隨時重新抓回來。
除了讓專案「做得出來」,AI 也讓這個專案「做得更完整」。
每個開源專案都有一堆長尾功能,它們重要,但不是最優先:你明知道該做,卻總會先被核心工作壓住。對 syntaqlite 而言,這些長尾包括:
AI 讓這些東西便宜到一個程度,讓他覺得「不做」反而是錯的取捨。
它也釋放了他的腦力,讓他可以多想 UX:使用者第一次接觸這個工具時要感受到什麼?錯誤訊息怎樣才真的能幫人修 SQL?formatter 的預設輸出應該長怎樣?CLI 參數是不是直覺?
這些東西,才是決定一個工具會不會被長期使用的關鍵。
沒有 AI,他可能只會做出一個很小的版本,甚至不會有 editor extensions 和文件站。AI 不只是讓同一個專案更快,它直接改變了專案本身的形狀。
用 AI 寫 code 跟拉霸機有種不舒服的相似性。你送出 prompt,等一下,然後得到一個很棒的東西,或是一坨沒用的東西。
他發現自己會半夜忍不住想「再試一次就好」,明明已經知道這次大概不會成功,還是會想賭賭看。沉沒成本也會跟著上來:總覺得「這次換個問法,也許就行了」。
疲倦還會把這個循環放大。精神好的時候,他可以寫出精準、範圍清楚的 prompt,效率很高;一旦累了,prompt 就變模糊,輸出變差,他又會想再試一次,結果越試越累。這種情況下,AI 其實可能比自己直接寫還慢,但要跳出那個循環很難。
在專案過程中,他好幾次失去了對 codebase 的 mental model。不是整體架構不見了,而是那些日常層面的細節:哪個東西放哪裡、哪些函式怎麼互相呼叫、各個小決策怎麼堆成一個可以運作的系統。
一旦這種掌握感消失,奇怪的問題就會出現,然後他會完全不知道到底哪裡壞掉。他很討厭那種感覺。
更深的問題是,這會直接破壞溝通。當你腦中的脈絡斷掉後,就很難跟 agent 有效對話。每一輪都會變得更長、更囉唆。你不再能說「把 FooClass 改成這樣」,而會變成「改那個做 Bar 的東西」。接著 agent 還要自己猜 Bar 是什麼、怎麼對應到 FooClass,然後有時候還會猜錯。
這很像工程師過去抱怨過很多次的問題:不懂 code 的主管提出荒謬要求。只是現在,你自己變成了那個主管。
他的修正方式很直接:實作完就立刻回頭讀 code,並且主動問自己「如果是我來寫,會不會不同?」
當然,某種程度上,這件事對人類自己寫幾個月前的 code 也一樣成立;只是 AI 讓這種 drift 發生得更快,因為你沒有親手一路寫到尾,肌肉記憶會少很多。
還有一些問題,是他在三個月裡慢慢才發現的。
AI 會讓他拖延關鍵設計決策。因為重構成本低,他總可以告訴自己「之後再處理」。但問題是,這個「之後」並沒有真的便宜:決策一直被延後,會讓 codebase 持續處於難以理解的狀態,反過來腐蝕你的判斷力。vibe-coding 的那個月最嚴重;他不是不懂問題,而是如果早一點做出硬決定,可能會更快收斂到正確架構。
測試也有類似的假安全感。500+ tests 看起來很安心,AI 又很容易幫你一直補測試。但人類和 AI 都不可能預見未來所有 edge case;在 vibe-coding 階段,他好幾次寫出新的 test case 才發現,某些元件的設計其實從根上就錯了,得整個重做。這也是他最後不信任那個版本、決定從頭來過的重要原因。
簡單講,AI 時代的軟體,照樣逃不開老規則:如果沒有紮實的底座——清楚的架構、清楚的邊界——你最後只會一直追著 bug 跑。
他反覆感受到的一件事,是 AI 幾乎不理解時間。
它看到的是 codebase 目前的狀態,但它不會像人一樣感受到時間流逝。他可以告訴你一個 API 是怎麼被使用、怎麼在幾個月或幾年裡演變、為什麼某些決策先出現、後來又被推翻。
而 AI 的缺點,正是缺少這種歷史感。它可能讓你重複犯之前犯過的錯,或是掉進前一次曾被避開的陷阱,長期來說反而會拖慢你。
理論上,你可以靠 specs 和 docs 把 context 留下來;但這也是為什麼以前沒人把這件事做得太徹底:把隱含的設計決策完整寫下來,太昂貴、太耗時。AI 可以幫你起草文件,但沒有辦法自動驗證它真的抓到重點,所以最後還是得人類手動審核。
還有一個問題是 context pollution。你永遠不知道 API A 的設計筆記,會不會在 API B 上出現回聲。讓 codebase 保持一致,本來就需要大量判斷;而那種判斷,正是 institutional knowledge 的價值所在。
回頭看下來,AI 什麼時候有幫助、什麼時候有傷害,其實很一致。
當他做的是自己已經非常理解的東西時,AI 很強。他可以快速審 code,立刻抓錯,速度比一個人單打獨鬥快太多。parser 規則生成就是最好例子:他知道每條規則應該產生什麼,所以能在一兩分鐘內判斷 AI 產出的對不對,然後快速迭代。
當他做的是「知道自己想要什麼,但還不完全懂」的東西時,AI 也不錯,但得更小心。formatter 裡的 Wadler-Lindig 學習就是這種情況:他能說出想要什麼,也能判斷輸出有沒有往正確方向走,但還是得保持高度投入,不能全盤接受。
可是一旦他面對的是「連自己都還不知道想要什麼」的問題,AI 就會從有幫助變成有害。專案架構就是最典型的例子:他一開始跟著 AI 走了好幾週,追逐那些當下看起來很有產出的設計路線,但回頭一看全都站不住腳。事後他甚至會懷疑:如果當初完全不用 AI,單靠自己把架構想清楚,會不會反而更快?
但即使他很懂一個問題,AI 仍然會在「沒有客觀答案」的任務上出問題。實作有局部正解:能不能編譯、測試會不會過、輸出有沒有對。設計沒有。OOP 的爭論都打了幾十年,還沒完。
他最深刻感受到這點的地方,是 syntaqlite 的 public API。那幾天他花了很多時間做 API refactoring,手動修掉一些有經驗工程師一眼就會避免、但 AI 卻會弄亂的地方。因為「這個 API 好不好用」、「能不能真的幫到使用者」這類問題,沒有測試可以直接判定。
這也讓他想到相對論:在小範圍裡,物理定律看起來簡單又牛頓式;但拉遠一看,時空會彎曲,整體行為不是局部直覺能推得出來的。程式也一樣:函式、class 的層級通常有明確答案,而 AI 在那裡表現最好;可是 architecture 是所有局部元件互相作用後的結果,不能只靠一堆局部正確的零件拼出全域良好。
知道自己現在站在哪一軸上,我想,這大概就是有效使用 AI 的核心技能。
這篇最有趣的地方,不是 syntaqlite 做得有多猛,而是它把一件很多人不想面對的事講得很清楚:AI 真的能把「寫出來」這件事變便宜,但它同時也會把「想清楚」這件事凸顯成唯一值錢的地方。
Lalit 最後的結論很實際:實作層面可以外包給 AI,設計層面不能。這跟很多人現在的用法正好相反——先丟給 AI 做一大坨,再想辦法補救。那種方式短期很爽,長期常常會付出架構和心智模型的利息。
如果把這篇放回 Kuma 現在的工作脈絡,它其實很像一個提醒:不管是 ai-articles、OpenClaw 的 workflow,還是任何要長期維護的專案,真正需要保護的不是產碼速度,而是「你還看得懂自己在做什麼」這件事。
所以最值得帶走的不是「多用 AI」,而是先做兩件事:先定好架構,再決定 AI 可以幫你哪一段;然後每次 AI 幫完,都要回頭確認自己還握有整個系統的脈絡。