我們使用編碼代理為RonDB添加RonSQL支持
本文分享了作者利用AI編程工具Claude和Codex,在五個月內將一個十年前的待辦功能——為RonDB添加複雜SQL查詢支持(CTE和並行連接聚合)——從計劃推進到Beta發佈的過程,並總結了AI編程的開發模式、測試方法和經驗教訓。
在Hopsworks,我們最近利用新一代AI編程工具,成功為RonDB添加了複雜的SQL查詢支持。這個名為RonSQL的功能,包括CTE(公用表表達式)和推送連接聚合,已經在RonDB 26.04.1中以Beta形式發佈。
幾年前,我們曾嘗試使用ChatGPT進行編碼,但那次嘗試被證明是一個昂貴的錯誤——生成的代碼花費了幾個月的時間重寫。因此,今年年初我再次嘗試AI編程時,抱持着相當多的懷疑態度。
最初的轉機來自一個意想不到的地方:我們的營銷經理在大約兩小時內構建了一個簡單的RonDB客户端。這引起了我的興趣,我接手代碼後,又在幾個小時內對其進行了顯著擴展。受到鼓舞,我嘗試了更接近真實工程的任務:擴展REST API服務器,使其不僅能處理批量鍵讀取,還能處理批量鍵插入、寫入和刪除。原始代碼編寫耗費了大量精力,而擴展只用了兩天。顯然,Claude和Codex在擴展現有代碼方面表現出色。
有了這些成功實驗後,我意識到這些新工具可能對開發RonDB真正的新功能極為有用。客户長期以來一直渴望在實時AI推理中實現更復雜的查詢。支持這一點需要CTE和並行連接聚合——這個功能在RonDB的待辦清單上已經躺了十多年。它是一項非常複雜的開發工作;用傳統編碼,我估計至少需要兩年時間。
實際上,這相當於在鍵值存儲中添加複雜SQL子集的支持。RonDB與Redis和DynamoDB屬於同一類別,這些存儲傳統上用於這種實時、低延遲的服務,但完全不支持複雜SQL查詢。將CTE和並行連接聚合引入這個領域,使得這項工作既非比尋常又值得。
我決定看看AI編程是否能讓它變得可行。本文分享了我在過去五個月中的經驗。
開發模式從一開始就清晰:有效的開發模式依然適用。從高層次計劃開始,轉向詳細實現計劃,然後逐步實現。我們多次經歷了這個循環。每個計劃至少包含10到20個階段,有時更多。
在Claude和Codex之間,我的結論是它們的優勢互補。Claude更擅長跟蹤計劃和剩餘工作。Codex通常更擅長解決難題,但它在維護計劃方面較為馬虎,可能會忘記下一步該做什麼。因此,大部分時間我讓Claude負責計劃維護和較簡單的任務,而將難題交給Codex。
AI編程的一個直接好處是能夠生成大量的單元測試——即使是通常難以測試的分佈式場景。RonSQL查詢執行跨越RonDB的四個層:LDM(本地數據管理器)、TC(事務協調器)、NDB API和RonSQL。通常,你需要針對RonSQL編寫測試程序,因為手動針對LDM、TC和NDB API層編寫和維護程序非常困難。AI編程改變了這一點:變得可以先開發和測試LDM層,然後再接觸TC層,最後是NDB API層。這大大加快了在所有四個層上快速實現工作版本的速度。
AI編程在模型訓練中見過的順序代碼上效果很好。但RonDB使用異步編程模型,有時模型需要明確的指導才能理解實際工作方式。對我來説顯而易見的事情,模型可能完全看不見——但通過提示通常很容易教會它。反過來也經常發生:模型生成新代碼的速度遠超人類思考。
如何驗證生成的代碼是否正確?我遵循以下模式:
第一階段:按計劃構建。遵循高層次計劃,然後是實施計劃,最後逐步實施。在這個階段,你是架構師:告訴模型做什麼,大部分情況下你作為操作者接受它的建議。我發現至關重要的一點是,不讓模型在未明確説明更改內容和方式的情況下修改任何代碼。Claude默認就是這樣;而Codex需要嚴格約束,以防止它擅自生成代碼而不檢查正確性。查看每個差異能讓你至少對新代碼的作用有一個概念——這也是生成大量測試的階段。關鍵的是,每一步都包括編寫至少一個測試用例,並在進入下一步之前驗證該步驟已成功執行。步驟只有在有通過測試證明時才視為“完成”。這保持了實現的基礎,防止小錯誤在計劃的多個階段中累積。
第二階段:審查。步驟完成後,審查所有新代碼。我主要關注影響實際執行的代碼,只瀏覽測試用例和計劃。我使用模型生成文檔——包括圖片和信令圖——以更好地理解新代碼。這個階段確保模型遵循RonDB的內存模型,並正確處理節點故障和其他查詢執行中的故障。模型也傾向於生成大量重複代碼,因此刪除重複代碼路徑是必不可少的步驟——有些刪除掉了數千行需要維護的生產代碼。
第三階段:用測試壓力測試功能。我們編寫了CTE測試用例,不考慮它們是否被支持。當一個功能不被支持時,我們要麼修復它,要麼將其標記為不支持。剩下的是儘可能減少查詢延遲,並繼續審查生成的代碼。
最後一點觀察:當模型思考時,有足夠的時間做其他事情。大部分時間我同時運行兩到四個項目。因此,在RonSQL之外,還出現了RonDB解釋器的JIT編譯器、在RonDB中使用纖程以及死鎖檢測的原型。目前只有死鎖檢測在源代碼樹中,且默認禁用。這三個都還在進行中。
回顧過去,一個在待辦清單上超過十年的功能——我原本預估需要兩年時間——在五個月內達到了Beta。工作並沒有消失,而是改變了形態。我的角色從編寫代碼轉變為架構設計、指導模型、審查結果,以及最重要的測試。這,遠超原始代碼生成,是新一代AI編程在我們構建RonDB中贏得一席之地的原因。