【GitLab Duo】AIレビューのノイズを減らす——Custom Review Instructions で「独自レビュー基準」を設計する

1. はじめに:AIレビュー、見落としていませんか?

AI支援開発ツール(Developer Assistance Platform / DAP 等)を導入し、AIにマージリクエスト(MR)のレビューを任せてみたものの、次のような不満はありませんか。テスト

  • 致命的なバグと軽微な指摘が同じトーンで並び、優先度の判断がつかない
  • プロジェクトの方針に合わない、過度に細かい指摘が多い
  • 結局、確認コストが高くなり、AIのコメントを見落としてしまう

導入支援の過程でも、AIレビューを現場に定着させるには機能そのもの以外の設計が必要だという課題が共有されていました。

私たちは、Python(FastAPI)/ TypeScript(React)/ AWS 構成のプロダクトを約4名体制で開発しています。プロダクトオーナー(PO)は顧客側におられ、プロダクトをより価値の高いものとするためにPOと話し合いながら必要な機能を選定し、AIをフル活用して実装しています。

Custom Review Instructions を導入する前、GitLab Duo のレビュー結果は「参考程度」に留まっていました。導入後は、Duo の指摘を潰しておけば一次レビューを通過でき、人間のレビューはそれに補助的に付け加えるだけ——という役割分担に変わりました。

本記事では、GitLab Duo の Custom Review Instructions を活用し、AIレビューを「頼れる同僚」として機能させるために、私たちが実践した設定設計と運用ノウハウを紹介します。

2. 「AIへの丸投げ」が生む Bad 体験(Before)

導入当初、私たちは次のような Instructions を設定していました。

旧 Instructions(抽象的な依頼に留まっていた例)

review_instructions: |
# xxx プロジェクト マージリクエストレビューガイドライン
## 言語
すべてのレビューコメントは日本語で返信してください。
## レビュー時の重要な確認事項
README.mdや設計ドキュメントを参照し、適切に実装されているか確認してください。
コードの品質、セキュリティ、パフォーマンスなどをレビューしてください。

人間同士であれば「ドキュメントを踏まえて適切にレビューしてほしい」という意図は伝わります。しかし、現在の GitLab Duo の場合、この程度の抽象的な指示しか与えないとレビュー結果は安定しません。

旧 Instructions での実際のレビュー例

The updated CASE expression has no ELSE clause, so any DB row with role = 'OWNER' will produce NULL…(中略)

(SQL の CASE 文の考慮漏れによる 500 エラーのリスクを、英語の長文で指摘)

指摘内容自体は有益でした。一方で、現場では次の課題が顕在化しました。

  1. 言語指定が守られない — 「日本語で」と指示しても、文脈によって英語に戻る
  2. 重要度とノイズが混在する — 500 エラーのリスクと、ドキュメント上の軽微な指摘が同じトーンで並ぶ

AIはチームの暗黙知を推測してくれません。「適切にレビューして」という依頼だけでは、一般的な知識をベストエフォートで出力するにとどまり、プロジェクト固有の基準には寄りにくいのです。

3. AIDD Force のアプローチ:「独自のレビュー基準」を言語化する

この課題に対し、社内で開発チームを横断して AI 駆動開発 を推進するチーム「AIDD Force」が、「本当に AI に見てほしい観点」 を洗い出しました。

単なるテキスト(review_instructions)ではなく、GitLab Duo の公式スキーマである instructions / fileFilters を使った設定ファイル(.gitlab/duo/mr-review-instructions.yaml)へ移行しました。

設定ファイルの全体像

現行運用の設定ファイルは、次のような構造です。

# 公式スキーマ: https://docs.gitlab.com/ja-jp/user/gitlab_duo/customize_duo/review_instructions/

instructions:
  - name: AIDD MRレビュー基準          # レビュー基準セットの名前
    fileFilters:
      - "**/*"                         # 対象ファイル(全ファイル)
    instructions: |
      # ここにレビュー基準の本文を記述
      # カテゴリ(バグリスク、セキュリティ、パフォーマンス 等)ごとに
      # [CRITICAL] / [HIGH] / [MEDIUM] / [LOW] 付きのルールを列挙
      # 末尾に出力形式(重要度順・ファイルパス・行番号 等)を定義

ポイントは次の3点です。

要素役割
nameレビュー基準セットを識別する名前。Duo のコメントに表示される
fileFiltersルールを適用するファイルの glob パターン。現状は */** で全ファイル対象
instructionsカテゴリ別の判定ルールと出力形式を記述する本文

instructions 本文は、バグリスク ソフトウェア品質 セキュリティ パフォーマンス リグレッションリスク アーキテクチャ コード品質 テスト品質 トレーサビリティ の9カテゴリに分かれ、合計30以上のルールで構成されています。

新 Instructions に組み込んだ 3 つの必須要素 を、実際の設定例とともに紹介します。

3-1. カテゴリごとに、機械的に判定できる条件を書く

「バグを見つけて」「複雑なコードを指摘して」といった主観的な指示は、AIには十分伝わりません。観点をカテゴリ分けし、判定可能なルール として定義しました。

設定例(バグリスク・セキュリティ・ソフトウェア品質)

## バグリスク

- [HIGH] error-handling: 外部API呼び出し・DB操作・ファイルI/Oの例外が try-catch 等で処理されているか確認すること。async/await 呼び出しも対象。
- [HIGH] null-guard: null・undefined・空文字・範囲外の入力が使用前にガードされているか確認すること(オプショナルチェイン・早期リターン・バリデーション等)。

## セキュリティ

- [CRITICAL] hardcoded-secrets: ソースコード内のAPIキー・パスワード・トークン・接続文字列はCRITICAL。環境変数またはシークレットマネージャーへの移行を即座に求めること。
- [CRITICAL] injection: ユーザー入力がSQLクエリ・シェルコマンド・HTML出力に直接使用されていないか確認すること。

## ソフトウェア品質

- [MEDIUM] cyclomatic-complexity: 条件分岐のネストが4段階を超えるか、関数が約50行を超える場合に指摘すること。ガード節や関数分割を提案すること。
- [LOW] dead-code: 未使用の変数・インポート・到達不能なコードブロック・不要なコメントアウトを検出すること。

「ネスト 4 段階」「関数 50 行」といった具体的な基準を入れることで、指摘のブレが減り、優先度の低い指摘も整理しやすくなりました。

3-2. 指摘に重要度(Severity)を付与する

すべてのルール冒頭に [CRITICAL] [HIGH] [MEDIUM] [LOW] を付け、出力時も重要度順にグループ化するよう指示しました。

  • CRITICAL / HIGH — マージ前に必ず修正
  • MEDIUM / LOW — 必要に応じて対応

開発者は重要度ラベルを見るだけで、短時間でトリアージできます。

3-3. 出力フォーマットを明示する

「日本語で」だけでなく、出力形式も定義します。

  • 重要度(CRITICAL → HIGH → MEDIUM → LOW)の順にグループ化する
  • 各指摘にファイルパスと行番号を含める
  • 問題がある項目のみ報告し、問題のない項目は省略する
  • レビューコメント本文は日本語で記述する(重要度ラベル CRITICAL / HIGH / MEDIUM / LOW は英語のまま)

設定ファイル内には、次の出力例を記載しています。

**CRITICAL**
- [セキュリティ] `src/config.ts:8` にトークンのハードコードを検出 — 環境変数に移行すること。

**HIGH**
- [バグリスク] `src/utils/format.ts:21` で `user.address.city` へのアクセス前にNullチェックがない。

**MEDIUM**
- [パフォーマンス] `src/components/Cart.tsx:45` で `calculateTotal` が毎レンダリング呼び出されている — メモ化を検討。

**LOW**
- [コード品質] `src/handlers/event.ts:12` の変数 `d` はより明確な名前にすべき。

4. 実際のレビューはこう変わった(After)

独自の「AIDD MR レビュー基準」を導入した結果、レビュー体験は次のように改善しました。

新 Instructions での実際のレビュー例

[HIGH] [パフォーマンス / blocking-io] src/services/folder_service.py:142 — paginator.paginate() および for page in pages: ループは同期ブロッキング呼び出しです。大規模フォルダの場合、イベントループを長時間ブロックする可能性があります。asyncio.to_thread でラップするか、設計上の制約としてコメントで明示することを検討してください。

※ Duo のコメント冒頭には According to custom instructions in 'AIDD MRレビュー基準' (blocking-io: …) のような英語のメタ情報が付くことがありますが、指摘本文は日本語で出力されるよう安定しました。

現場では次の好循環が生まれています。

  • トリアージが速い[HIGH][CRITICAL] を見れば優先対応を即判断できる
  • 修正理由が理解しやすい — カテゴリ名(例: blocking-io)で指摘の意図が把握できる
  • レビューへの信頼が高まる — CRITICAL / HIGH の指摘を潰せば、一次レビューは通過できるという認識が定着

人間同士のレビューは、細かいコードチェックから解放され、設計・要件の議論に集中できるようになっています。

ただし、設定を整えても GitLab Duo のレビュー会話機能には制約があり、返信への応答精度にばらつきが出ることがあります。運用上の回避策については、次章で詳述します。

5. 現場での運用Tips:AIが期待どおり動かないときに有効な豆知識

MR コメントへの返信(「直しました」「ここは意図的です」など)に対し、最新コミットを反映せず、古いコードを前提に応答する ことがあります。

試行錯誤の結果、次のような工夫が有効であることを見出しました。最終的には Duo 側の改善または custom instructions による根本対処が望ましいのですが、現在のところ私たちはこの運用方法を適用しています。

① 返信には必ずコミットハッシュを添える

「直しました」だけではなく、最新のコミット番号を明記します。

@GitLabDuo 以下で対応しました。 570a553d

② 1件ずつ返信せず、下書き保存して一括送信する

コメント1件ごとに「返信」ボタンを押して Duo と会話しようとすると、Duo が混乱して見落としが発生することがあります。

  1. 指摘に対する修正をすべてコミットする
  2. 各コメントに @GitLabDuo 以下で対応しました。[ハッシュ]Draft(下書き) で返信を書く
  3. 最後に Submit review で一括送信する

この手順により、Duo が最新コードを参照し、応答精度が上がるケースが増えました。

6. おわりに

AIレビューに不満を感じたとき、「AIの性能不足」と考えがちです。しかし多くの場合、プロジェクトに必要な品質基準を AI に十分伝えられていない ことが原因です。

4 名のチームで観点を整理し、設定ファイル 1 つで基準を共有するだけで、GitLab Duo は実用的なレビュー支援に変わります。本記事が、皆さんの現場での AI レビュー設計の参考になれば幸いです。

Author

観葉植物とハムスターを育てる Neo4j エンジニア。
得意分野は Python と 自然言語処理。

Hajime ARAIの記事一覧

新規CTA