6月23日、Datadogが「How we migrated a live routing system using AI-assisted refactoring」と題した記事を公開した。この記事では、本番稼働中のルーティングシステムをAI支援リファクタリングによって安全に移行した実践的プロセスについて詳しく紹介されている。移行はストレージ層の再設計とルーティングロジックの刷新を両軸とする取り組みであり、タイトルの「ルーティングシステムの移行」とURLパスの「ai-assisted-storage-migration」はその両側面を反映している。
背景:KVモデルが限界を迎えた
DatadogはStream Routerと呼ぶ社内コントロールプレーンサービスを運用している。このサービスは、1日1兆件超のイベントを処理するメトリクスパイプライン上で、各データポイントをどのKafkaクラスタ・トピック・パーティションに送るかを決定する。ルーティングの誤りはメトリクス基盤全体に波及する、極めて重要なシステムだ。
従来の書き込みパスはFoundationDBを使ったキー・バリュー(KV)モデルで実装されていた。FoundationDBはAppleが開発・オープンソース化した分散KVストアで、強いACIDトランザクション保証を持つ一方、1トランザクションあたりのデータサイズに上限がある。ルーティングテーブルが肥大化するにつれ、FoundationDBのトランザクションサイズ制限に頻繁に抵触するようになった。
明快な近道として「FoundationDBをPostgreSQLに置き換え、KVのアクセスパターンはそのまま」という案も検討された。だがこれも機能しなかった。最も負荷の高い操作では、データベースへの逐次ラウンドトリップが数千回に達するため、推定処理時間が45分にのぼることが判明した。ボトルネックはデータベース自体ではなく、データモデルとその上に積み上がったアプリケーションロジックにあった。
解決策:スキーマの再設計と新ストレージ
チームはまず手作業でスキーマを再設計した。ルート・シャーディング戦略・ルールという3つのドメインエンティティをそれぞれテーブルに対応させ、外部キー制約によってアプリケーション内で再構築していたリレーションを置き換えた。
- 書き込みパス:Datadogが自社で運用するPostgreSQLプラットフォームへ移行。トランザクションモデルとリレーショナルセマンティクスが得られる。
- 読み取りパス:スナップショットをメモリに展開してクエリを処理する構成のため、組み込み可能なDBが必要だった。SQLiteは配列カラムをネイティブサポートしていないため不採用。**DuckDB** を採用した。DuckDBはインプロセスで動作する分析用組み込みDBエンジンで、PostgreSQLと高い互換性を持つSQL方言を持つ。これにより両エンジン間でクエリロジックを共有できる。
このスキーマ設計は人間が担当した。AIが入ってくるのは、その後の「メソッド単位のリファクタリング」からだ。
移行を安全にした3つの前提条件
AIによる実装を信頼できた背景には、すでに整っていた3つの要素がある。
①モジュール化されたコード:ストレージ層はControllerと呼ぶ内部インターフェース越しに操作される。FoundationDB実装の隣にPostgreSQL実装を新設するだけでよく、他のシステムは変更不要だった。
②充実したテストスイート:Controllerの全メソッドに対してE2Eテストが整備されており、操作後のストレージ状態まで検証する。「テストが通るか否か」がAI生成コードの合否基準になった。
③ブルー/グリーン本番環境:ベテランエンジニアのRémi Calixteが構築した独立2系統のインフラ。両者に同じリクエストを流し、バリデータサービスが30秒ごとにルーティング応答を比較してアラートを上げる。これにより、テストフィクスチャではなく実際の本番データで動作を継続検証できた。
AIとの具体的なワークフロー
Phase 1:コードベースのマッピング
リファクタリング開始前に、ClaudeにKV実装の既存コードを渡し、各主要関数の「なぜその処理が存在するのか」をマークダウンドキュメントとして生成させた。行ごとの説明ではなく、意図と保護している挙動に焦点を当てた。
この文書化が後工程のAI精度を大きく改善した。実装フェーズでは新しいセッションを始めるたびにこのドキュメントをコンテキストとして渡すことで、AIは中断した箇所から正確に再開できた。コードへのコメント付与も同様で、「なぜそのロジックが存在するか」を説明するコメントを追加するだけで、AI生成の実装品質が一貫して向上した。
Phase 2:スタブ→テスト失敗→AIで実装→テスト通過のループ
- KVコントローラから1メソッドを選ぶ
- PostgreSQLコントローラに「エラーを返すスタブ」を追加する
- E2Eテストを実行して失敗内容を確認する
- 失敗したテスト出力・旧実装・新スキーマ・Phase 1のドキュメントをClaudeまたはCursorに渡す
- テストが通るまで反復する
「これらのテストを通過するようにこのメソッドを移植せよ」という粒度のタスクはAIが得意とするところで、精度も高かった。
一方でうまくいかなかったのは、粒度の粗いプロンプトだ。複数メソッドを一度に渡したり、広いコンテキストで大きなタスクを与えると、コンテキストオーバーロードが起き、インターフェースを誤生成したり、コンパイルは通るが期待動作と異なるコードが返ってくることが増えた。プロンプトのスコープを1メソッドまたは1つの失敗テストに絞ることが、一貫してよい結果をもたらした。
Phase 3:本番でのブルー/グリーン検証
PostgreSQL実装を「ブルー」としてデプロイし、既存のFoundationDB実装「グリーン」と並走させた。バリデータが継続的に両者の応答を比較し、カットオーバーまで数週間この状態で運用した。
AIが苦手だったこと
ClaudeとCursorは繰り返し性の高い作業——バリデーションロジックの抽出、メソッドの逐次移植、スキーマの配線——では力を発揮した。しかしSQLパフォーマンスの最適化では限界が明確だった。
バッチ処理、UNNESTの活用、共通テーブル式(CTE)といったニッチな最適化は人間が実装する必要があった。AIが生成するクエリは正しい結果を返すものの、ラウンドトリップ回数が多すぎることが多かった。最適化パターンをAIに一度見せると以降は再現できたが、自力で発見することはなかった。
また記事では「AIが生成したコードを人間がレビューせずにマージするのは危険」という点も率直に述べている。テストスイートとバリデータが安全網として機能したからこそ、AIの生成結果を実用に耐えるレベルで信頼できた。
詳細はHow we migrated a live routing system using AI-assisted refactoringを参照していただきたい。




