entry-header-eye-catch.html
entry-title-container.html

entry-header-author-info.html
Article by

LLMとGitLab CI/CDを活用したdbtコードレビューの自動化

こんにちは、ピクシブのデータ基盤チームのkashiraです。

データ分析基盤の開発は、プロダクト開発と比較して優先度が低く、限られたリソースで進めなければならない場面が少なくありません。各部署やプロダクトが個別にデータ開発環境を構築するのは非常に非効率です。

そこで私たちは、全社共通のデータ基盤を一つのプラットフォームとして整備し、dbtのプロジェクトを1つのリポジトリに集約するモノレポ構成をとっています。このアプローチにより、少ない労力で全社的に広く価値を届けることを目指しています。

しかし、このモノレポジトリが成長するにつれて、いくつかの課題が顕在化してきました。

  • チーム間の品質のばらつき
    • レビューはチームごとに行われているものの、dbtへの習熟度はチームによって様々です。そのため、あるチームではOKとされたコードが、別のチームの基準では修正対象になるなど、リポジトリ全体の品質を一定に保つことが難しくなっていました。
  • 負の遺産の継承
    • 新しくdbtを使い始めるメンバーが、リポジトリ固有の細かいルールや「お作法」を把握しきれないまま既存のコードを参考にすることで、意図せずアンチパターンを再生産してしまうことがありました。
  • 指摘の心理的コスト
    • 細かいタイポや規約違反を人間が指摘するのは、言う側も言われる側も少し気が重いものです。
  • レビュー負担の増加
    • 新しくdbtを使い始める際には、データ基盤チームでレビューをしていますが、レビューが集中して工数が取られたり、他部署特有の事情をキャッチアップするのが大変という事情がありました。また、Cursor等のLLMでのコード生成によってコードが生成される速度が早くなったことで、レビューが速度・工数の面でボトルネックになりそうという見込みもあります。

これらの課題は、開発体験を損なうだけでなく、データ品質の低下を招き、信頼性の高い意思決定やビジネス要求への迅速な対応を妨げる要因にもなりかねません。この状況を解決し、より健全でスケールする開発体制を築くために、私たちはLLM (大規模言語モデル) によるレビューの自動化に取り組みました。

本記事では、GitLab CI/CDとVertex AIのGeminiを使ってどのようにレビューを自動化したのか、そしてどのような成果が得られたかをご紹介します。

なぜLLMレビューを導入しようと考えたか

私たちが目指したのは、単なる静的解析ツールによるチェックではありませんでした。

  1. 知見の共有
    • LLMからの指摘と修正案を通じて、新規参加者が自律的にリポジトリのルールを学べる「生きたドキュメント」のような環境を作る。
  2. ルールチェックの自動化
    • lintやフォーマッターでは指摘しきれない、dbtのテスト品質やモデルのレイヤリング(例: stagingmartsのようなデータの関心事を分離する設計)といった、よりドメインに特化したルールをLLMにチェックさせることで、人間は本質的なロジックレビューに集中できるようにする。
  3. 開発体験の向上
    • レビュアーのレビューを待たずに、Merge Request (MR) を作成してすぐに一次フィードバックを得られるようにする。

これらの目的を達成するには、コードの表面だけでなく、変更の「意図」や「文脈」を理解できるLLMが最適だと考えました。

きっかけはSlackでの雑談から

ここで、この取り組みがどのようにして始まったのか、実際のSlackでのやりとりを少しだけご紹介します。

ucchi-(広告チーム): [雑な思いつき] SQL がコーディング規約に沿って書かれているかをレビューしてくれる君作りたいな… dbt best practice とかを詰め込んで、dbt にコミットしたら自動でレビューが付くと理想。

kashira(データ基盤チーム): 実は簡単にできるんですよ。

(3日後)

kashira: 入れました。 でもルールとかの整備が追いついてないんですよね...

(14日後)

ucchi-: 今までの記事からルールを整備しました!

kashira: 神かな?

(2日後)

dbtモデルの開発者: LLMによって今まで知らなかったベストプラクティスを知れた!

チームの垣根を越えて、素早く形にし、さらに他のメンバーが協力して改善していく、というサイクルが自然に生まれるのがピクシブの良い所だと感じました。

やってみた:GitLab CI/CD と Vertex AI で実現するLLMレビュー

この仕組みは、GitLab CI/CD と Google Cloud の Vertex AI (Gemini) を組み合わせて実現しました。開発当時、GitLab Duoの類似機能はまだベータ版だったこと、そして何より早期に価値検証とルール整備を進めたいというモチベーションが強く、今回の構成を選択しました。そのため、作り込みすぎず、将来的にはGitLab Duoへ移行することを強く視野に入れつつ実装しました。

全体像

MR(Githubでのプルリクエスト相当)が作成・更新されるたびにGitLab CI/CDのパイプラインが起動し、MRの関連情報をVertex AIに送信します。そして、Geminiが生成したレビューをMRのスレッドコメントとして投稿する、というシンプルな構成です。

レビューの精度を高める「コンテキスト」の渡し方

Geminiに的確なレビューをしてもらう上で最も重要なのが、どのような情報を「コンテキスト(文脈)」として与えるかです。私たちのパイプラインでは、以下の4つの情報をインプットとして渡しています。

  1. MRの差分(diff)

    言わずもがな、レビュー対象の最も重要な情報です。どのファイルがどのように変更されたのかを伝えます。

  2. MRのdescription

    開発者自身が書いた「このMRの目的」や「変更の背景」です。これを読ませることで、Geminiは「なぜこの変更が必要なのか」を理解し、意図を汲んだレビューができるようになります。

  3. MRの既存コメント

    すでに人間や他のLLMが指摘した内容を重複して指摘しないように、既存のディスカッション内容もインプットに含めています。「空気を読む」LLMには必須の情報です。

  4. リポジトリのルールセット(doc/ディレクトリ)

    ここが私たちの工夫の核心です。 リポジトリ内のdoc/ディレクトリに配置したルールファイルを読み込ませ、「あなたはこのルールブックに従ってレビューしてください」と明確に指示します。これにより、プロジェクト固有の細かい規約やベストプラクティスに基づいた、一貫性のあるレビューが実現できました。

    レビュー用の文章は、cursorのruleのようなコーディングLLMのコンテキストとして併用することでコード生成の精度を上げるなどのレバレッジも効きます。

ルールファイルの具体例

doc/ディレクトリには、チェックしたいルールを記述したファイルを配置します。以下に具体例を紹介します。

例:Import CTEsでカラムを明示するルール

'(Import) CTEs (Common Table Expressions、SQLの with句のこと)' では、特別な理由がない限り select * を避け、必要なカラムを明示的にリストします。現代のシステムでは select * を最適化できますが、人間がどのデータがインポートされているかを理解しやすくなります。また、where句を使用して、CTEsによってスキャンされるデータを可能な限り制限します。

  • 従わない場合 (Import CTEsでselect *)
    with fct_event as (
        select * from {{ ref('fct_event') }} -- 全カラムを選択
    ),
    ...
    
  • 修正後 (必要なカラムのみ選択)
    with fct_event as (
        select
            id, -- 必要なカラムを明記
            event_name,
            event_timestamp
        from {{ ref('fct_event') }}
        where event_date >= '2023-01-01' -- 必要ならフィルタリング
    ),
    ...
    

参考)このルールはこちらの記事を参考に作られています zenn.dev

プロンプトの例

実際にVertex AIへリクエストを送る際のプロンプトは、以下のような構造になっています。

- あなたはシニアデータアナリティクスエンジニアとしてメンテしやすく、使いやすいデータを作るパイプラインのレビューをしなさい
- @dbt_coding_manual.mdc に沿って、モデルのレイヤリングや、命名規則が行われているかをチェックしてください
- @sql_best_practices.mdc を参考にsqlのスタイルが準拠しているかレビューしてください
- @metadata_guideline.mdc を参考にメタデータのルールが準拠しているかレビューしてください
- @dbt_test_guideline.mdc を参考にテストの過不足をチェックしてください

# ルール
{ doc/ ディレクトリ内のルールファイル群の内容をここに展開 }

# MRのタイトルと説明
{ MRのタイトルとdescriptionの内容をここに展開 }

# 既存のコメント
{ MRの既存コメントをここに展開 }

# コードの差分
{ git diff の内容をここに展開 }

結果:LLMレビューがもたらした2つの大きなメリット

導入後、チームの開発プロセスには明確な変化がありました。

1. リポジトリのルール指摘がしやすくなった

これまで見逃されがちだったり、レビュアーが指摘するのに少し躊躇していたような細かい規約違反を、Geminiが機械的かつ即座に指摘してくれるようになりました。

これにより、レビュアーは「このSQLのパフォーマンスは大丈夫か」「このテーブル設計で将来の問題は起きないか」といった、より本質的な議論に時間を使えるようになりました。

LLMによるレビューコメントの例:

## {ファイル名}

### モデル全体

* **Import CTEs での `select *` の使用について (Severity: High)**
    * `import_tableA`, `import_tableB`, `import_tableC`, `import_tableD` の各CTEで `select *` が使用されています。
    * プロジェクトのSQLベストプラクティス (`doc/sql_best_practices.md`) にもある通り、Import CTEsでは、参照するモデルのスキーマ変更による意図しない影響を避け、クエリの可読性と依存関係の明確性を高めるために、必要なカラムを明示的にリストすることが推奨されます。
    * 例えば、`import_tableA` であれば、実際に後続の処理で利用する `date`, `session_id`, `user_id` のみを指定するなど、利用するカラムに絞って記述することを検討いただけないでしょうか?

2. メンバーへの知見共有が進んだ

メンバーがMRを作成すると、即座にLLMから「なぜこの書き方ではいけないのか」「推奨される書き方はこうだ」というフィードバックが返ってきます。これが、実践的なオンボーディング教材として機能し始めました。

レビュアーを待つことなく、自分のペースで試行錯誤しながらリポジトリの「お作法」を学べるため、メンバーの心理的安全性と学習効率が大きく向上したと感じています。

メンバーからの声の例:

llm-reviewに指摘されて知ったけど今のImport CTEは * 避けてカラム明示するほうが推奨なのか (自分自身はそっちのほうが好きではある)

LLMのMRレビューでtypoが見つかった。ありがたい。

レビュー内容もなかなか面白くて見るの楽しい

課題と今後の展望

もちろん、まだ課題はあります。

  • ハルシネーション(幻覚)と指摘の安定性
    • LLMは時に文脈を誤解して的外れな指摘をしてしまうことがあります。この問題への対策として、LLMによる柔軟なレビューと並行して、LLMに頼らない独自の静的解析ツール(lint拡張)を導入することで、レビューの安定性と信頼性を高めるハイブリッドなアプローチを進めています
  • ルール(プロンプト)のメンテナンス
    • ルールをdoc/ディレクトリで管理する際、情報の一貫性を保つのが難しいという課題があります。例えば、同じベストプラクティスが複数のファイルで少しずつ違う表現で書かれていたり、Notionのようなドキュメントツールと比べて可読性が低かったりします。一方で、ルールをコードと同じGitリポジトリで管理することで、コードとドキュメントが常に同期され、LLMがレビュー時に具体的なルールを引用して指摘しやすくなるという大きなメリットもあります。このトレードオフをどう管理していくかは、今後の改善点です。
  • コストと実行時間
    • MRごとにAPIを呼び出すため、CIの実行時間とコストは常に意識する必要があります。
  • 人間とLLMの両方で使いやすい文章
    • ルールの文章は、人間にオンボーディングとして読ませる使い方もあります。実際、いくつかのルールは当初人間向けに書かれたものです。「なぜそのルールが必要か」「良い例と悪い例」を明確に示すことで、LLMが指摘しやすくなり、同時に新メンバーの学習効率も高まります。今後は「人間にもLLMにも使いやすい文章の育て方」を意識したドキュメント改善も進めていきたいと考えています。

今後は、これらの課題を改善しつつ、指摘の精度をさらに高めていく予定です。また、このAIレビューの仕組みをdbtリポジトリだけでなく、他のプロジェクトへ横展開することも検討しています。特に、dbtと同じくモノレポジトリとして全社的に利用されているLooker(LookML)のリポジトリは次の有力な候補です。LookMLにも独自のベストプラクティスや規約が存在するため、同様の効果が期待できると考えています。

まとめ

dbtモノレポジトリのCI/CDにLLMレビューを導入したことで、私たちはレビューの効率化だけでなく、ルールの民主化自律的な学習の促進という大きな価値を得ることができました。

セルフサーブなデータ開発基盤を運用する上で、今回のようなコード品質チェックの自動化や開発基盤のルール明文化は、データ品質と開発速度の向上に直結します。

引き続きデータ基盤チームでは全社向けデータ開発基盤整備を通して、より信頼性の高い意思決定やビジネス要求への迅速な対応が可能な環境づくりに注力していきます。

最後に、この取り組みのきっかけをくれたucchi-さん、たくさんレビューしてくれたoystersukiさん、そして共に改善を進めてくれたすべてのメンバーに感謝します。

kashira
2021年11月に中途入社。全社データ基盤の整備とデータマネジメントをしています。最近の趣味はマンガとPokemon UNITEとバッティングセンター。