更新日:2026年5月21日

20分で読めます

CodexとGitLab:コード修正から本番リリースまで

Codexをターミナルで活用する方法、GitLab MCPによるイシュー連携開発、GitLab Duo Agent Platformの外部AIエージェントを使ってバグ報告からレビュー済み変更へ移行する手順を解説します。

Codexはコーディングエージェントとして、ターミナルに集中しているときに真価を発揮します。リポジトリを指定してタスクを与えるだけで、すぐに動き出します。コードを読み込み、修正案を提示し、コマンドを実行して、フローを中断することなくアイデアをコードへと変換します。このような開発者体験こそが、エージェント型コーディングツールの魅力であり、先日公開したClaude Codeチュートリアルが好評を得た理由でもあります。

しかし、コードを書くことはあくまで最初のステップです。その後にも、イシューの作成、マージリクエスト、CI/CDパイプライン、レビュー、そして最終的な人間の判断によるリリースが待っています。コードを書くこととソフトウェアをリリースすることは別物であり、コーディングエージェントが高速化するほど、その差は明確になっていきます。

そこでGitLabの出番です。このチュートリアルでは、CodexとGitLab Duo Agent Platformを組み合わせた次の3つのユースケースを順に紹介します。

  1. Codexを使い始めてRustバックエンドのバグを修正する
  2. GitLab MCPでコンテキストを補完し、イシューの要件に沿ってRustのバグを修正する
  3. GitLab Duo Agent Platformの外部エージェントとしてCodexを活用し、マージリクエストのレビューフィードバックに対応する

3つのユースケースすべてにTanuki IoTプラットフォームプロジェクトを使用します。RustのメトリクスバックエンドにはWebSocketメトリクスフィルターのバグとREST APIバリデーションのバグという、実践的な2つの問題が含まれています。さっそく始めましょう。

前提条件

  1. ターミナルで設定・起動済みのCodex
  2. バグレポートや機能提案のイシューが登録されたGitLabプロジェクト(例:Tanuki IoTプラットフォームプロジェクト
  3. 特定のユースケース向け:GitLab MCPサーバーと、外部エージェントを有効化したGitLab Duo Agent Platform
  4. コードのビルド用:CargoおよびRustコンパイラ(例:rustup

GitLabプロジェクトの準備

自分の環境でワークフローを再現する場合は、まずプロジェクトをインポートしてクローンし、リポジトリルートでCodexを起動します。

  1. Tanuki IoTプラットフォームプロジェクトをGitLab環境にインポートし、すべてのオープンイシューも含めて取り込みます。
  2. プロジェクトをローカル環境にクローンし、ディレクトリに移動します。
  3. ターミナルを開き、codexでCodexを起動します。
      git clone https://gitlab.example.com/examplegroup/tanuki-iot-platform.git
cd tanuki-iot-platform

codex

    

プロンプトでプロジェクトの概要を確認します。

      What is this project about?

    

このチュートリアルで扱うのは、backend/ディレクトリにあるRustのメトリクスストアです。センサーがREST APIを通じて計測値を送信し、ダッシュボードがWebSocketストリームでリアルタイムデータを受信する仕組みです。問題点と修正内容がわかりやすい構成になっています。

CodexとGitLabを使い始めてRustバックエンドのバグを修正する

このシナリオでは、ライブWebSocketストリームにバグが存在します。バックエンドはREST API側ではすでにメトリクスフィルタリングをサポートしていますが、WebSocketストリームではメトリクスによる絞り込みが正しく機能していません。試しに1つのセンサーと1つのメトリクスをサブスクライブしても、他のメトリクスのデータまで返ってきます。ターミナルで問題を確認してみましょう。

ターミナル1でバックエンドを起動し、ポート9090でリッスンします。

      PORT=9090 cargo run --manifest-path backend/rust-metrics-store/Cargo.toml

    

ターミナル2でWebSocketクライアントを開きます。macOSの場合、websocat はHomebrewで入手できます:brew install websocat

      websocat 'ws://localhost:9090/ws?sensor=arduino-iot-collector&metric=temperature_celsius'

    

次に、arduino-iot-collectorセンサーに対して2種類のメトリクスを送信します。

      curl -s -X POST http://localhost:9090/api/metrics \
  -H 'Content-Type: application/json' \
  -d '{"sensor":"arduino-iot-collector","metric":"temperature_celsius","value":23.5}'

curl -s -X POST http://localhost:9090/api/metrics \
  -H 'Content-Type: application/json' \
  -d '{"sensor":"arduino-iot-collector","metric":"humidity_percent","value":61.2}'

    

temperature_celsiusだけが表示されるはずですが、ストリームにはhumidity_percentも表示されます。バグが確認できました。

3つのターミナルセッション:メトリクスバックエンドの実行、websocatによるWebSocketストリームの読み取り、curlによるテストメトリクスの送信。3つのターミナルセッション:メトリクスバックエンドの実行、`websocat`によるWebSocketストリームの読み取り、curlによるテストメトリクスの送信。

この問題をCodexに渡します。

      I need help with a backend change to add metric filtering to /ws so live streams can be narrowed to one metric.

    

GitLabプロジェクト内のAGENTS.mdファイルのおかげで、CodexはRustバックエンドの構成、実行すべきコマンド、コード品質の基準を把握しています。

Rustツールチェーンのセットアップとエージェントのビルドコマンドが記載されたAGENTS.md。Rustツールチェーンのセットアップとエージェントのビルドコマンドが記載されたAGENTS.md。

CodexはRustのソースコードを調べ、不足している部分を特定します。/wsエンドポイントはすでにsensorクエリパラメーターを受け付けていますが、オプションのmetricパラメーターも必要です。Codexはハンドラーロジックの更新、テストの追加、ドキュメントとコードの同期を行います。

コード変更後、Codexはフォーマット、テスト、ビルドを実行します。その後、Gitに触れる前に最終確認を行い、ブランチの作成、コミット、プッシュまで対応します。

バグを修正するCodex。差分の編集内容を表示。バグを修正するCodex。差分の編集内容を表示。

マージリクエストが作成されると、GitLabがソフトウェアライフサイクルの次のステージを担います。CI/CDパイプラインが起動し、セキュリティスキャンが実行され、GitLab Duo Code ReviewがRustコードスタイル要件に照らして変更内容を検証します。

RustコードのためのGitLab Duo Code Reviewの設定。RustコードのためのGitLab Duo Code Reviewの設定。

デプロイ後にローカルテストを再実行すると、センサーとメトリクスの両方を指定した場合、WebSocketストリームが要求されたメトリクスのみを返すようになったことを確認できます。結果はマージリクエストにコメントとして投稿します。

GitLab Duo Code Reviewのフィードバックと、開発者がローカルテスト結果を共有しているMRコメント。GitLab Duo Code Reviewのフィードバックと、開発者がローカルテスト結果を共有しているMRコメント。

この最初のユースケースが基本形です。Codexがコードのそばにいてパッチをマージリクエストのライフサイクルに渡すと、GitLabがそこから作業を引き継ぎます。

Codex、GitLab CI/CD、GitLab Duo Agent Platformの動作を収録したデモ動画をご覧ください。

GitLab MCPと開発ライフサイクルのコンテキストを使ってWebSocketメトリクスフィルターを修正する

最初のユースケースでは、Codexはプロジェクトリポジトリを参照できていましたが、GitLabのイシュー、合意された要件、実装メモ、マージリクエストやパイプラインの状態といったコンテキストは見えていませんでした。そのコンテキストはGitLabの中にあり、ローカルファイルには存在しません。

そこで登場するのがGitLab MCPサーバーです。

このユースケースでは、イシューがすでに詳細に記述された状態で存在しています。問題の説明、機能要件・非機能要件、テスト、README.mdおよびAGENTS.mdの更新が明示されています。Codexはそれらをプロンプトに貼り付ける必要なく、イシューを直接取得して開発者が参照するのと同じ情報源から作業を進めることができます。

提案、機能要件、動作、非機能要件、実装メモを含むGitLabのイシュー。提案、機能要件、動作、非機能要件、実装メモを含むGitLabのイシュー。

GitLab MCPサーバーの設定

次に、GitLab MCPサーバーをCodexに追加します。インスタンスまたは最上位グループで有効化されていることを確認してください。

新しいターミナルを開き、httpトランスポートタイプを使ってGitLab MCPサーバーをCodexに追加します。

gitlab.example.comを使用するGitLabインスタンスのアドレスに変更します。

      codex mcp add --url "https://<gitlab.example.com>/api/v4/mcp" GitLab

    

CodexのMCPクライアントでは、Rustのrmcp_clientにフィーチャーフラグが必要な場合があります。~/.codex/config.tomlを開いて[features]セクションを追加します。mcp_servers.セクションでGitLab MCPサーバーが追加されていることも確認できます。

      vim ~/.codex/config.toml

    
      [features]
"rmcp_client" = true

[mcp_servers.GitLab]
url = "https://<gitlab.example.com>/api/v4/mcp"

    

新しいターミナルでcodexを実行し、/mcpと入力してGitLab MCPサーバーの認証を行います(追加時に自動的に行われなかった場合)。

      codex

/mcp

    

接続を確認するには、Codexに次のように尋ねます。

      Which GitLab MCP tools are available to you?

Show the GitLab MCP Server version.

    

CodexにWebSocketフィルターのイシュー実装を依頼する

Codexを開き、イシューへの対応を依頼します。

      Can you help me implement issue 32?

    

ここでワークフローが変わります。このシナリオでは、CodexはMCPのget_issueツールを呼び出し、コードを変更する前にイシューの詳細をセッションに取り込みます。要件、ラベル、ノート、作業の全体的なスコープを把握した上で実装に取り組みます。

GitLab MCPサーバーツールのget_issueを呼び出し、ターミナルにイシューの詳細を表示するCodex。GitLab MCPサーバーツールの`get_issue`を呼び出し、ターミナルにイシューの詳細を表示するCodex。

修正の内容は同じです。オプションのmetricパラメーターの追加、マッチングロジックの更新、テストとドキュメントの更新。ただし、情報源が異なります。最初のユースケースではリポジトリとプロンプトが情報源でしたが、このユースケースではイシューとリポジトリが一緒に機能します。

ローカル検証後、CodexはMCPツール呼び出しを通じてブランチを作成し、作業をコミットし、マージリクエストを作成します。Gitプッシュオプションやブラウザの操作は不要です。

GitLab MCPサーバーツールのcreate_merge_requestを使用してマージリクエストを作成するCodex。GitLab MCPサーバーツールの`create_merge_request`を使用してマージリクエストを作成するCodex。

イシューのコンテキストを把握しているため、Codexはマージリクエストの説明にcloses 32も追加します。これにより、マージ時にイシューが自動的にクローズされます。

マージ後にクローズされることを示すCloses #32をDescriptionに追加したCodex。マージ後にクローズされることを示す`Closes #32`をDescriptionに追加したCodex。

このワークフローの意義は想像以上に大きなものです。エージェントは単にコードを書くだけでなく、イシュー、マージリクエスト、パイプラインのコンテキストを踏まえてソフトウェアデリバリーに参加しています。これがGitLab MCPがエンドツーエンドの開発ワークフローにもたらす価値です。

GitLab Duo Code ReviewとテストがGOサインを出した段階で、最終レビューとマージの準備が整います。

GitLab Duo Code Reviewとローカルテストのスクリーンショットを含むマージリクエストのコメント。GitLab Duo Code Reviewとローカルテストのスクリーンショットを含むマージリクエストのコメント。

GitLab MCPサーバーを活用してCodexが問題を解決する様子を動画でご確認ください。

外部エージェントとしてのCodexでレビューフィードバックと要件を検証する

3つ目のユースケースはさらに興味深い内容です。Codexがマージリクエストをオープンできるかどうかではなく、より実践的な問いに答えます。マージリクエスト作成後に、マージリクエスト内のレビューフィードバックへの対応を支援できるのでしょうか?

このユースケースでは、別のREST APIバリデーションのバグに切り替えます。このバグが示す問題は次のとおりです。POST /api/metricsが無効な入力を受け付けても201 Createdを返してしまいます。空のメトリクスなど無効なペイロードの場合は400 Bad Requestを返すべきです。

2つのターミナルで動作を確認します。ターミナル1でポート9090のメトリクスストアサーバーを起動します。

      PORT=9090 cargo run --manifest-path backend/rust-metrics-store/Cargo.toml

    

ターミナル2で、空のメトリクス値を含む特定のREST APIリクエストをcurlで送信してエラーを発生させます。

      curl -w "\nHTTP %{http_code}\n" -X POST http://localhost:9090/api/metrics \
  -H "Content-Type: application/json" \
  -d '{"sensor": "sensor-a", "metric": "  ", "value": 23.5, "labels": {}}'

    

Codexはすでに主要な修正を加えた最初のドラフトマージリクエストを作成しています。ローカルで再テストすると、コアの動作が改善され、無効な入力に対して400が返るようになっています。

バグがある状態と修正後の2つのcurl呼び出しの比較。バグがある状態と修正後の2つのcurl呼び出しの比較。

しかし、まだ完了ではありません。GitLab Duo Code ReviewがRustコードスタイル要件に基づいて2つの不足点を指摘します。

  1. 公開アイテムにドキュメントコメントが必要。
  2. API変更にはサクセスパスとフェイルパスのハンドラーテストが必要だが、バリデーションテストが1つ欠けている。

RustコードへのGitLab Duo Code Reviewのフィードバック。RustコードへのGitLab Duo Code Reviewのフィードバック。

ここでローカルターミナルからGitLab UIに移ります。AI > AgentsメニューのGitLab AIカタログからCodexエージェントを有効化します。@ai-codex-agentで始まるサービスアカウントハンドルを確認し、マージリクエストのディスカッションでエージェントを直接メンションしてレビューフィードバックへの対応を依頼します。

プロジェクトで有効化されたCodex Agent by GitLab。プロジェクトで有効化されたCodex Agent by GitLab。

マージリクエストがCodexエージェントの作業領域となります。コードの差分、レビューコメント、CI/CDパイプライン、セキュリティスキャン結果、承認ルールすべてが揃っています。Codexはコラボレーションがすでに行われている場所で、フォローアップ作業を進めることができます。

修正をマージリクエストに直接プッシュするよう指示しながら、新しいコメントで支援を依頼します。

      Please help address the review feedback, and push a fix.

    

マージリクエストのフィードバックコメントでCodexエージェントをメンション。マージリクエストのフィードバックコメントでCodexエージェントをメンション。

Codexはフィードバックに対応し、欠けていたバリデーションテストを追加してコミットし、Agent Session内で独自の実行コンテキストでチェックを再実行し、マージリクエストにサマリーコメントを投稿します。

新しいGitコミットによってCI/CDパイプラインが自動的にトリガーされた様子。新しいGitコミットによってCI/CDパイプラインが自動的にトリガーされた様子。

Codex Agent by GitLabが新しいCI/CDパイプラインをトリガーした様子。Codex Agent by GitLabが新しいCI/CDパイプラインをトリガーした様子。

ジョブログで新しく追加されたingest_rejects_blank_metricテスト関数も確認できます。

ingest_rejects_blank_metricを検索したCI/CDジョブログ。`ingest_rejects_blank_metric`を検索したCI/CDジョブログ。

外部エージェントモデルが実際に役立つのはこの点です。外部エージェントはレビューの代替として面白いのではなく、マージリクエスト、承認、最終的な人間の判断を適切な場所に保ちながら、レビューフィードバックと次のリビジョンの間のギャップを縮めるために有用です。また、イベントトリガーカスタムフローを通じて、GitLab Duo Agent Platformにさらに深く統合することも可能です。

GitLab Duo Agent PlatformでCodexが外部エージェントとしてレビューを支援する様子を動画でご確認ください。

CodexとGitLabを活用するためのヒント

AGENTS.mdによるカスタムインストラクション

AGENTS.mdのエントリーを使うことで、コミット前にコードのビルドとテストを行う、変更を最小限に保つ、プロジェクトアーキテクチャをより深く理解するといった指示をエージェントに与えることができます。Tanuki IoTプラットフォームはルートレベルのファイルに加え、センサーとバックエンド向けのサブディレクトリごとのファイルと指示を使用しています。

      tree -P AGENTS.md --prune
.
├── AGENTS.md
├── backend
   └── rust-metrics-store
       └── AGENTS.md
└── sensors
    ├── arduino-iot-collector
   └── AGENTS.md
    ├── c-file-monitor
   └── AGENTS.md
    ├── cobol-mainframe-bridge
   └── AGENTS.md
    └── java-http-metrics-collector
        └── AGENTS.md

    

Rustバックエンド向けには、backend/rust-metric-store/AGENTS.mdにディレクトリレベルのAGENTS.mdが用意されています。Rustのコードスタイルと標準、ドキュメント、ファイル構成、エラーハンドリング、非同期プログラミング、コンテナ化とCI/CD、利用可能なツールチェーン(Cargo)でのビルドと実行方法が定義されています。詳細はGitLabプロジェクトのリンク先ファイルを参照してください。

      # rust-metrics-store - Agent Instructions

## Overview

The `rust-metrics-store` is a lightweight, standalone time-series metrics backend for the Tanuki IoT Platform. It accepts metrics from all sensors via a simple REST API and streams live data to frontend clients over WebSocket. No external dependencies — a single binary with in-memory ring buffers.

## Code Style and Standards

### Rust Standards

- Use Rust 2021 edition idioms
- Run `cargo fmt` before committing
- Run `cargo clippy -- -D warnings` and resolve all warnings
- Prefer `Arc<T>` + `RwLock<T>` for shared state; avoid `Mutex` unless write-heavy
- Use `?` for error propagation in fallible functions; only `unwrap()` on truly unrecoverable states (e.g., lock poisoning)
- Derive `Debug`, `Clone`, `Serialize`, `Deserialize` only where needed
- Keep `pub` visibility minimal — expose only what callers need

### Documentation

- Public types and functions must have a doc comment
- Include `# Errors` section in doc comments for fallible functions
- Document env vars and their defaults in `README.md`, not in code

### File Organization

- **`src/main.rs`** — router wiring and `tokio::main`; no business logic
- **`src/store.rs`**`MetricsStore` and data types; no HTTP concerns
- **`src/handlers.rs`** — Axum extractors and response types; thin layer over the store

### Error Handling

- HTTP handlers should return meaningful status codes (201 for ingest, 404 for unknown sensor)
- Log warnings for recoverable issues (e.g., lagging WebSocket clients) with `tracing::warn!`
- Never silently swallow errors

### Async and Concurrency

- Use `tokio::sync::broadcast` for the live-stream fan-out; `RwLock` for the ring-buffer map
- WebSocket handlers must break cleanly on send errors — do not loop after a closed socket
- Handle `RecvError::Lagged` by logging and continuing, not by disconnecting

### Containerization

- Use a multi-stage Dockerfile: `rust:1.95-slim` builder, `debian:bookworm-slim` runtime
- Always run the container as a non-root user — create `appuser` with `addgroup`/`adduser` and set `USER appuser` before `CMD`
- Include a `.dockerignore` that excludes `target/` and `.git/` to keep build context small
- Use specific image tags — never `latest` in Dockerfile or CI base templates

### CI/CD

- Pin all CI images to specific tags (e.g., `rust:1.95`) — never use `rust:latest` or `debian:latest`
- The `.rust_base` template in `.gitlab-ci.yml` must match the Dockerfile builder image version

## Local Toolchain Setup

// More instructions in the file

    

これらのカスタムインストラクションは、GitLab Duo Agent Platform上のエージェントとフローにも適用されます。

コーディングエージェントからより良い結果を得たいなら、まずここから始めましょう。リポジトリの仕組み、重要なコマンド、触れてはいけない箇所、良い変更の定義を書き記すことで、ローカルのコーディングツール、GitLab MCP、外部エージェントすべてに効果が生まれます。

まとめ

このチュートリアルの3つのユースケースは互いに発展していますが、より大きなポイントも示しています。

Codexは問題の記述からコードへと素早く移行する点で優れています。GitLabはそのコードを、理解・検証・レビュー・自信を持ってリリースできる変更へと変えるためのソフトウェアデリバリーコンテキストを提供します。

最初のユースケースではコードのそばにとどまり、リポジトリとローカルのエージェントインストラクションをもとにCodexを活用しました。2つ目のユースケースでは、GitLab MCPがイシュー、要件、マージリクエストのワークフローをターミナルセッションに直接取り込みました。3つ目のユースケースでは、Codexがマージリクエストそのものにアクセスしてレビューフィードバックと次のリビジョンの間のギャップを縮めました。

この発展こそが、組み合わせを説得力あるものにします。コーディングツールとDevSecOpsプラットフォームのどちらかを選ぶのではありません。エージェント型コーディングのスピードをソフトウェアライフサイクル全体へと拡張するのです。多くのプロジェクト、多くのリリースマイルストーン、多くのチームにわたって規模を拡大しながら。

すでにCodexを使用している場合、GitLabはコーディングのスピードとパッチが存在した後に重要となるコンテキスト・コラボレーションをつなぐ実用的な方法を提供します。GitLab Duo Agent Platformをすでに使用している場合、外部エージェントによってマージリクエストの監査証跡や最終的な人間の意思決定を失わずに、サードパーティのコーディングツールをGitLabに取り込む新しい方法が生まれます。

ぜひ小さく始めてみてください。目に見えるバグを1つ選び、イシューで期待される動作を定義し、ここで紹介した流れを順に試してみます。ローカルコーディング、イシュー連携での実装、マージリクエストでのコラボレーション。そこで、この組み合わせが単なる高速なパッチをはるかに超えたものになります。

GitLab Duo Agent Platformをまだご利用でない場合は、無料トライアルからお試しください。

GitLabの無料プランをご利用の場合は、簡単な手順に従ってGitLab Duo Agent Platformにサインアップできます。

GitLab PremiumまたはUltimateをご契約中の場合は、Duo Agent Platformをオンにするだけで利用開始でき、サブスクリプションに含まれているGitLabクレジットをすぐにご活用いただけます。

現在、関連する投稿はありません。新しいコンテンツが追加されたら、またご確認ください。

ご意見をお寄せください

このブログ記事を楽しんでいただけましたか?ご質問やフィードバックがあればお知らせください。GitLabコミュニティフォーラムで新しいトピックを作成してあなたの声を届けましょう。

フィードバックを共有する

今すぐ開発をスピードアップ

DevSecOpsに特化したインテリジェントオーケストレーションプラットフォームで実現できることをご確認ください。