AIを活用してCIをより厳密で観測可能かつ改善しやすくした方法を、複数リポジトリにわたって解説します。
実装とデリバリーの両方を経験して学んだことは、現在のAI時代において、複雑な要件が必ずしも最大の課題ではないということです。
AIは要件の分解、未知のリポジトリ探索、実装アイデアの生成を支援できます。これにより実装ステップは大幅に容易になります。
しかし、実装はデリバリーの一部に過ぎません。機能は実際のエンジニアリングシステムを通過する必要があります。
リポジトリ、CIルール、レビュー工程、デプロイ経路に適合させる必要があります。
実装が高速化するにつれ、周辺のエンジニアリングシステムがより重要になります。本当の課題は、すべての変更がテストされ、要件に対してレビューされ、マージ可能であることを確実にすることです。
置き換えへの恐れを超えて
AIが開発者を置き換えることに対する恐れは多くあります。
その懸念には合理的な部分もあります。日常的な実装タスクがAI支援で生成・テスト・レビュー可能になると、エントリーレベルの機会は制限される可能性があります。
それは特に、ソフトウェア開発で初めての機会を得ようとしている人々にとって重要な課題です。
しかし、私はこれを開発者役割の終焉とは見なしません。
ソフトウェア開発において最もエキサイティングな時期の一つだと考えています。
価値は移行しています。
定型的なコードを書くことは差別化要因として薄れています。問題を理解し、適切な質問をし、動作を検証し、トレードオフを行い、結果に責任を持つことがより重要になっています。
AIは実装を生み出すことはできますが、ビジネスコンテキスト、隠れた制約、運用リスク、チームに適したソリューションかどうかを自動的に理解することはありません。
それがワークフローの品質が重要である理由です。
最も恩恵を受ける開発者は、AIに最も多くのコード生成を依頼する人々ではありません。規律あるプロセスの中でAIを活用できる人々です:要件を定義し、証拠を検査し、結果をテストし、リスクをレビューし、その周囲のシステムを改善する。
ジュニア開発者にとって道筋は変化するかもしれませんが、消えることはありません。基礎、デバッグ、コミュニケーション、プロダクト理解、AIと効果的に協働する能力は、さらに重要になるでしょう。
この視点の変化は、私たちのCIへの取り組み方を変えました。最初に「より高速に実行するには」と尋ねるのではなく、「より適切な問題を捕捉するには」と尋ねました。
本当の作業はCIワークフローの強化だった
最近、複数の責務を持つGitLab CIワークフローに取り組みました:
- マージリクエスト作成時にリンクされたissueを
Status::In Reviewに移動。 - マージ後にissueを
Status::Doneに移動。 - マージリクエスト全体に対してAIレビューを実行。
- AIレビューで重大または高深刻度の問題が確認された場合、パイプラインをブロック。
- マージリクエストにクロージング参照が含まれていない場合、コメントを残す。
重要なのは、単にCIジョブを追加することではありませんでした。
AIを活用してワークフロー自体を検査し、より良い質問を投げかけました:
Status::In Reviewは、マージリクエストが実際にチケットに接続されていることを証明するか?Status::Doneは、デフォルトブランチへの実際のマージ後にのみ実行されるか?- AIの発見は、具体的な証拠なしにマージをブロックできるか?
- マージリクエストにクロージング参照がない場合はどうなるか?
- どのチェックが汎用ポリシーであり、どのチェックが特定のリポジトリに属するか?
これらの質問により、CIはコマンドの集合から品質管理システムへと変わりました。
目的はCIをより複雑にすることではなく、各判断をより明示的にすることでした:何が自動的にチェックされるか、どのような証拠が必要か、何がマージをブロックすべきか。
パイプラインにおけるAIの実際の活用方法
AIレビューは、開発者が手動で実行する必要のある別ツールではありません。マージリクエストがデフォルトブランチをターゲットにしたときに実行されるGitLab CIジョブです。
セットアップは4つのシンプルな部分から構成されます:
- ピン留めされたAI CLIがCIジョブにインストールされる。
- 小さなリポジトリスクリプトがマージリクエストのコンテキストを収集する。
- AIが構造化されたJSONレポートを返す。
- 別のジョブがそのレポートを評価し、パイプラインの成否を決定する。
このジョブは、最新版をインストールするのではなく、ピン留めされたバージョンのAI CLIを使用します:
ai_review:
image: node:22-bookworm-slim
before_script:
- npm install --global @openai/codex@<pinned-version>
script:
- python scripts/ai_review.py review
Enter fullscreen mode Exit fullscreen mode
この場合、AIはOpenAI Codex CLI経由でアクセスされます。使用するCLIは変わる可能性がありますが、重要なのはバージョンが明示的であり、ジョブが分離されたCI環境で実行されることです。
リポジトリスクリプトは、リポジトリ全体を盲目的にモデルに送信するわけではありません。レビューに必要なコンテキストのみを収集します:
- マージリクエストの説明;
- リンクされたクロージングissueとその要件;
- 変更されたファイルとdiff;
- 変更周辺の関連ファイル内容;
- 現在のコミットSHAとターゲットブランチ。
プロンプトは、AIがどのような結論を導き出せるかを定義します。たとえば、要件はCovered、Partial、Missing、Not verifiableのいずれかにマークされます。発見にはカテゴリ、深刻度、影響を受けるパス、証拠、影響、推奨事項を含める必要があります。
レスポンスは使用前にJSONスキーマに対して検証されます。レポートはCI成果物として保存され、マージリクエストコメントとして投稿されます。これにより推論が可視化され、次のジョブに安定した入力が提供されます。
認証情報は責任ごとに分離されます:
- AIアクセストークンはレビュージョブがAIツールを呼び出すことを許可する;
- GitLabオートメーショントークンはワークフローがマージリクエストデータを読み取り、コメントやラベルを更新することを許可する。
どちらもマスクされたグループレベルCI変数として管理されます。レビュージョブはAIトークンを使用します。ゲートジョブはAIを呼び出す必要がないため、レポート成果物を消費し、環境からAIトークンを削除します。
この分離は2つの理由で有用です。機密認証情報が露出する場所を制限し、最終ゲートがレビュー済みレポートとは異なる結果をもたらす可能性のある別のAIリクエストを行うことを防ぎます。
実際の流れは次のようになります:
Merge request
-> collect GitLab context
-> AI review with structured output
-> report.json artifact and comment
-> deterministic gate
-> pass or block the pipeline
Enter fullscreen mode Exit fullscreen mode
したがってAIは分析と説明のために使用されます。GitLab CIは出力の検証、コミットのチェック、マージリクエストの更新、最終ポリシーの強制を担当します。
リポジトリではなく、改善されたワークフローをパッケージ化する
共有コンポーネントは有用な結果でしたが、主な改善ではありませんでした。主な改善はCIポリシーを明示的かつ強制可能にしたことです。それが明確になった後、再利用可能な部分をパッケージ化できました。
ワークフローを改善した後、次の質問はシンプルでした:
本当にすべてのリポジトリで同じワークフローを手動で設定する必要があるのか?
答えは依然として「いいえ」でした。
改善された.gitlab-ci.ymlロジックをすべてのリポジトリにコピーする代わりに、共有GitLab CIコンポーネントを作成しました。
利用側のリポジトリは共有テンプレートを含めるだけで済みます:
include:
- project: your-group/ci-components
ref: v0.1.0
file: /templates/issue-ai-review.yml
Enter fullscreen mode Exit fullscreen mode
共有コンポーネントは以下を提供します:
issue_status_in_reviewissue_status_doneai_reviewai_review_gate
各リポジトリは依然として独自のビルド、リント、ユニットテスト、E2E、デプロイジョブを所有します。
この分離は重要です。
GoリポジトリにPythonリポジトリ構造を強制すべきではありません。フロントエンドリポジトリにバックエンドのテストコマンドを継承させるべきではありません。
しかし、両方のリポジトリは同じマージリクエストポリシーを必要とする可能性があります。
再利用可能なのは品質ポリシーであり、パイプライン内のすべてのコマンドではありません。
AIレビューには決定論的な境界が必要
AIレビューは有用ですが、AIレスポンスがマージリクエストのマージ可否を直接決定すべきではありません。
AIレビュアーは構造化レポートを生成します。チケットカバレッジ、正確性、リグレッションレスポンス、セキュリティ、パフォーマンス、メンテナンス性、その他のカテゴリを評価します。
CriticalおよびHighの発見は独立して検証されます。
最終ゲートは決定論的な条件をチェックします:
- レポートは現在のコミットに対するものか?
- 発見は独立して確認されたか?
- 深刻度は依然としてブロック条件か?
- レポート生成後に人間によるオーバーライドが追加されたか?
これによりより良い境界が得られます。
AIは大規模なマージリクエストに対する推論に有用です。
パイプラインはポリシーの強制を担当します。
この区別が重要である理由は、AI出力は確率論的である一方、マージゲートは予測可能であるべきだからです。
ワークフローを安全に再利用可能にする
ワークフローの品質はAIステップだけから来るものではありません。オートメーションを予測可能かつ安全に再利用可能にする必要があります。
クロージング参照の欠如が可視化される
マージリクエストにCloses #123のような参照が含まれていない場合、パイプラインは自動的に何が欠けているかを説明するコメントを残します。
ジョブは失敗するため、マージ前に問題が可視化されます。説明が更新された後、パイプラインを再試行できます。
共有コンポーネントをピン留めする
各リポジトリはv0.1.0のような特定のコンポーネントバージョンを使用し、最新の変更にサイレントで追従することはありません。
これにより、共有CIの更新がすべてのリポジトリに予期せず影響を与えることはありません。リポジトリは変更がレビューされた後にバージョンを更新できます。
オートメーション専用のボットを使用する
ワークフローはissueラベルとコメントを更新するための認証情報を必要とします。それらの認証情報はグループレベルで保存され、開発者の個人アカウントではなく専用のCIボットに属します。
これにより所有権がチームに留まり、人員や責任が変わった場合でもオートメーションの保守が容易になります。
リポジトリ固有のチェックはローカルに保持する
共有コンポーネントは共通のマージリクエストポリシーを処理します。各リポジトリは依然として独自のビルド、リント、ユニットテスト、E2E、デプロイジョブを定義します。
ラベルもリポジトリごとに設定可能です。GoプロジェクトとTypeScriptプロジェクトは、同じレビューポリシーを共有しているからといって同じコマンドを使用する必要はありません。
結果として、すべてのリポジトリが同じ構造を持つことを前提とせずに、共通の品質基準を実現できます。
エンジニアリングリーダーシップに何が起こるか?
AIはボトルネックを変化させます。
以前は、要件をコードに翻訳し、CIワークフローが意図したポリシーを捕捉しているかどうかを手動で確認する作業が大きな部分を占めていました。
今ではAIがその実装の摩擦の多くを軽減できます。
エンジニアリングリーダーシップの役割は、より以下に焦点を当てるようになります:
- 再利用可能な境界の定義;
- どのチェックを決定論的に残すかの決定;
- 繰り返されるポリシーのオートメーション化;
- AI出力を検証可能にすること;
- リポジトリ間の柔軟性の維持;および
- 速度がプロセスから証拠を排除しないようにすること。
作業は依然として複雑です。
しかし、その複雑さはより小さく再利用可能なシステムに整理できます。
最終的な要点
複雑な要件には依然として慎重な思考が必要です。
AIはアーキテクチャ、テスト、レビューの必要性を排除するものではありません。
しかし、実用的なことが変化します。
手動検査に依存していたレビュー工程は、自動化された証拠ベースのゲートに変わることができます。
その品質ポリシーが明確になったら、繰り返されるCIロジックはバージョン管理された共有コンポーネントにできます。
最大の改善は単にコードをより速く書くことではありません。
複雑な作業をより調整・検証・再利用しやすくするシステムを構築することです。
それがAIがエンジニアリングチームに最大のレバレッジを生み出す場所です。
0 Comments
Log in to join the conversation.No comments yet. Be the first to share your thoughts.