コードエージェントを使ってRonDBにRonSQLサポートを追加
本稿では、AIプログラミングツールClaudeとCodexを活用し、10年以上TODOリストにあったRonDBへの複雑なSQLクエリサポート(CTEとプッシュダウン結合集約)を5か月でベータ版まで実現した経験を共有し、開発モデル、テスト方法、教訓をまとめる。
Hopsworksでは、最新のAIプログラミングツールを活用して、RonDBに複雑なSQLクエリサポートを追加することに成功しました。このRonSQLと呼ばれる機能には、CTE(共通テーブル式)とプッシュダウン結合集約が含まれており、RonDB 26.04.1のベータ版としてリリースされました。
数年前、私たちはChatGPTを使ったコーディングを試みましたが、それは高くつく間違いでした。生成されたコードの書き直しに数か月を費やしたのです。そのため、今年初めに再びAIプログラミングに取り組んだときは、かなりの懐疑心を持っていました。
最初の転機は意外なところから訪れました。マーケティングマネージャーが約2時間でシンプルなRonDBクライアントを作成したのです。これに興味を持った私はコードを引き継ぎ、さらに数時間で大幅に拡張しました。勇気づけられて、私はより本格的なエンジニアリングに挑戦しました。REST APIサーバーを拡張し、バッチキー読み取りだけでなく、バッチキー挿入、書き込み、削除も処理できるようにしたのです。元のコードの作成には多大な労力がかかりましたが、拡張にはたった2日しかかかりませんでした。明らかに、ClaudeとCodexは既存のコードの拡張が得意でした。
これらの成功実験を経て、私はこれらの新しいツールがRonDBの真に新しい機能の開発に極めて有用である可能性があると気づきました。顧客が長い間望んでいたのは、リアルタイムAI推論におけるより複雑なクエリでした。それをサポートするには、CTEとパラレルジョイン集約が必要です。この機能はRonDBのTODOリストに10年以上もの間載っていました。非常に複雑な開発作業であり、従来のコーディングでは少なくとも2年はかかると見積もっていました。
実際には、これはキーバリューストアに複雑なSQLのサブセットを追加することに他なりません。RonDBはRedisやDynamoDBと同じカテゴリに属し、これらは伝統的にこの種のリアルタイム低遅延サービスに使用されていますが、複雑なSQLクエリはまったくサポートしていません。CTEとパラレルジョイン集約をその世界に持ち込むことが、この取り組みを異例で価値あるものにしています。
AIプログラミングでそれが実現可能かどうか、私は確かめることにしました。この記事では、過去5か月間で学んだことを共有します。
開発モデルは初めから明らかでした。実証済みの開発モデルが依然として有効だということです。ハイレベルな計画から始め、詳細な実装計画に移り、その後ステップバイステップで実装します。私たちはこのループを何度も繰り返しました。各計画には少なくとも10~20のフェーズがあり、時にはそれ以上ありました。
ClaudeとCodexの比較では、両者の強みは補完的であるという結論に至りました。Claudeは計画と残りの作業を追跡するのが得意です。Codexは難しい問題を解決するのが得意なことが多いですが、計画の維持がずさんで、次に何をすべきかを見失うことがあります。そのため、私は大部分の時間をClaudeに計画管理とより単純なタスクを任せ、難しいバグはCodexに任せました。
AIプログラミングの直接的な利点は、大規模なユニットテストを生成できることです。分散シナリオであっても、通常はテストが難しいケースも可能です。RonSQLのクエリ実行は、RonDBの4つのレイヤーにまたがります。LDM(ローカルデータマネージャー)、TC(トランザクションコーディネーター)、NDB API、そしてRonSQLです。通常、RonSQLに対してテストプログラムを作成しますが、LDM、TC、NDB APIの各レイヤーに対して手動でプログラムを作成し維持することは非常に困難です。AIプログラミングはそれを変えました。最初にLDMレイヤーを開発・テストし、次にTCレイヤー、そしてNDB APIレイヤーへと進むことが可能になりました。これにより、4つのレイヤーすべてにわたる動作実装に迅速に到達することがはるかに容易になりました。
AIプログラミングは、モデルが訓練で見てきたようなシーケンシャルコードに対して非常にうまく機能します。しかし、RonDBは非同期プログラミングモデルを使用しており、ここではモデルが実際の動作を理解するために明確なガイダンスを必要とすることがありました。私には明らかなことが、モデルにはまったく見えないこともありましたが、プロンプトを通じて教えるのは通常容易でした。逆もまた同様に頻繁に起こりました。モデルは人間が考えるよりもはるかに速く新しいコードを生成します。
生成されたコードが正しいことをどのように検証するか?私が従おうとしているモデルは以下の通りです。
フェーズ1:計画に従って構築する。ハイレベルな計画、次に実装計画、そしてステップバイステップで実装します。このフェーズでは、あなたはアーキテクトです。モデルに何をすべきかをハイレベルで指示し、大部分はその提案を受け入れるオペレーターとして行動します。変更内容と方法を正確に述べずにモデルにコードを変更させないことが不可欠であるとわかりました。Claudeではこれがデフォルトの動作でした。Codexは、正しいかどうかを確認せずに先走ってコードを生成しないように、厳しく制御する必要がありました。すべての差分を見ることで、新しいコードが何をするのか少なくとも作業イメージを得ることができます。そして、これが多くのテストを生成するフェーズです。重要なのは、各ステップに少なくとも1つのテストケースの作成と、次のステップに進む前にそのステップが正常に実行されたことの検証が含まれることです。ステップは、それを証明する合格テストができるまで「完了」とは見なされません。これにより実装が確実なものとなり、計画の多くのフェーズにわたって小さな間違いが積み重なるのを防ぎます。
フェーズ2:レビュー。ステップが完了したら、すべての新しいコードをレビューします。私は主に実際の実行に影響を与えるコードに焦点を当て、テストケースと計画はざっと見るだけにします。モデルを使い、画像やシグナリング図を含むドキュメントを生成して、新しいコードをよりよく理解しました。このフェーズでは、モデルがRonDBのメモリモデルに従い、ノード障害やその他のクエリ実行障害を正しく処理することを確認します。モデルは多くの重複コードを生成する傾向があるため、重複コードパスの削除は不可欠なステップです。これらの削除により、数千行のプロダクションコードが維持対象から外れました。
フェーズ3:テストで機能にストレスをかける。サポートされているかどうかに関係なく、CTEテストケースを作成しました。機能がサポートされていない場合は、修正するか、サポート外としてタグ付けしました。残るのは、クエリレイテンシを最小限に抑え、生成されたコードをレビューし続けることです。
最後の観察点:モデルが考えている間、他の作業に取り組む十分な時間があります。ほとんどの場合、私は2~4のプロジェクトを並行して進めていました。そうして、RonSQLと並行して、RonDBインタプリタ用のJITコンパイラ、RonDBでのファイバーの使用、デッドロック検出のプロトタイプが登場しました。今のところ、デッドロック検出だけがソースツリーにあり、デフォルトでは無効になっています。3つすべてがまだ進行中の作業です。
振り返ってみると、10年以上TODOリストに載っていた機能が、2年かかると見積もっていたものが、5か月でベータ版に達しました。作業は消えたわけではなく、形を変えたのです。私の役割はコードを書くことから、アーキテクチャ設計、モデルの指導、結果のレビュー、そして何よりもテストへと移りました。生のコード生成以上に、ここに新しいAIプログラミングの波が、RonDBの構築方法におけるその地位を築いたのです。