[{"data":1,"prerenderedAt":2636},["ShallowReactive",2],{"/ja-jp/blog/fix-bugs-with-codex-and-gitlab":3,"navigation-ja-jp":1881,"banner-ja-jp":2304,"footer-ja-jp":2314,"blog-post-authors-ja-jp-Michael Friedrich":2558,"blog-related-posts-ja-jp-fix-bugs-with-codex-and-gitlab":2573,"blog-promotions-ja-jp":2574,"next-steps-ja-jp":2627},{"id":4,"title":5,"authors":6,"body":8,"category":1858,"date":1859,"description":1860,"extension":1861,"externalUrl":1862,"featured":161,"heroImage":1863,"meta":1864,"navigation":161,"path":1865,"seo":1866,"slug":1871,"stem":1872,"tags":1873,"template":1878,"updatedDate":1879,"__hash__":1880},"blogPosts/ja-jp/blog/fix-bugs-with-codex-and-gitlab.md","CodexとGitLab：コード修正から本番リリースまで",[7],"Michael Friedrich",{"type":9,"value":10,"toc":1843},"minimark",[11,22,25,28,41,50,54,94,99,102,121,169,172,184,191,195,204,207,236,243,256,263,342,352,360,363,372,381,387,394,397,403,417,423,426,432,435,438,451,455,458,465,473,479,483,492,504,510,534,553,566,619,629,647,650,669,673,680,689,696,703,710,718,725,738,745,748,751,757,760,766,770,773,794,797,817,823,862,871,877,884,892,898,916,922,925,928,937,943,952,958,964,976,983,998,1001,1007,1011,1015,1020,1157,1171,1770,1779,1782,1785,1788,1791,1794,1797,1800,1803,1839],[12,13,14,15,21],"p",{},"Codexはコーディングエージェントとして、ターミナルに集中しているときに真価を発揮します。リポジトリを指定してタスクを与えるだけで、すぐに動き出します。コードを読み込み、修正案を提示し、コマンドを実行して、フローを中断することなくアイデアをコードへと変換します。このような開発者体験こそが、エージェント型コーディングツールの魅力であり、先日公開した",[16,17,20],"a",{"href":18,"rel":19},"https://about.gitlab.com/ja-jp/blog/claude-code-and-gitlab/",[],"Claude Codeチュートリアル","が好評を得た理由でもあります。",[12,23,24],{},"しかし、コードを書くことはあくまで最初のステップです。その後にも、イシューの作成、マージリクエスト、CI/CDパイプライン、レビュー、そして最終的な人間の判断によるリリースが待っています。コードを書くこととソフトウェアをリリースすることは別物であり、コーディングエージェントが高速化するほど、その差は明確になっていきます。",[12,26,27],{},"そこでGitLabの出番です。このチュートリアルでは、CodexとGitLab Duo Agent Platformを組み合わせた次の3つのユースケースを順に紹介します。",[29,30,31,35,38],"ol",{},[32,33,34],"li",{},"Codexを使い始めてRustバックエンドのバグを修正する",[32,36,37],{},"GitLab MCPでコンテキストを補完し、イシューの要件に沿ってRustのバグを修正する",[32,39,40],{},"GitLab Duo Agent Platformの外部エージェントとしてCodexを活用し、マージリクエストのレビューフィードバックに対応する",[12,42,43,44,49],{},"3つのユースケースすべてに",[16,45,48],{"href":46,"rel":47},"https://gitlab.com/gitlab-da/use-cases/ai/gitlab-duo-agent-platform/demo-environments/tanuki-iot-platform",[],"Tanuki IoTプラットフォームプロジェクト","を使用します。RustのメトリクスバックエンドにはWebSocketメトリクスフィルターのバグとREST APIバリデーションのバグという、実践的な2つの問題が含まれています。さっそく始めましょう。",[51,52,53],"h2",{"id":53},"前提条件",[29,55,56,64,71,86],{},[32,57,58,59],{},"ターミナルで設定・起動済みの",[16,60,63],{"href":61,"rel":62},"https://developers.openai.com/codex",[],"Codex",[32,65,66,67,70],{},"バグレポートや機能提案のイシューが登録されたGitLabプロジェクト（例：",[16,68,48],{"href":46,"rel":69},[],"）",[32,72,73,74,79,80,85],{},"特定のユースケース向け：",[16,75,78],{"href":76,"rel":77},"https://docs.gitlab.com/ja-jp/user/gitlab_duo/model_context_protocol/mcp_server/",[],"GitLab MCPサーバー","と、",[16,81,84],{"href":82,"rel":83},"https://docs.gitlab.com/ja-jp/user/duo_agent_platform/agents/external/",[],"外部エージェント","を有効化したGitLab Duo Agent Platform",[32,87,88,89,70],{},"コードのビルド用：CargoおよびRustコンパイラ（例：",[16,90,93],{"href":91,"rel":92},"https://rustup.rs/",[],"rustup",[95,96,98],"h3",{"id":97},"gitlabプロジェクトの準備","GitLabプロジェクトの準備",[12,100,101],{},"自分の環境でワークフローを再現する場合は、まずプロジェクトをインポートしてクローンし、リポジトリルートでCodexを起動します。",[29,103,104,110,113],{},[32,105,106,109],{},[16,107,48],{"href":46,"rel":108},[],"をGitLab環境にインポートし、すべてのオープンイシューも含めて取り込みます。",[32,111,112],{},"プロジェクトをローカル環境にクローンし、ディレクトリに移動します。",[32,114,115,116,120],{},"ターミナルを開き、",[117,118,119],"code",{},"codex","でCodexを起動します。",[122,123,128],"pre",{"className":124,"code":125,"language":126,"meta":127,"style":127},"language-bash shiki shiki-themes github-light","git clone https://gitlab.example.com/examplegroup/tanuki-iot-platform.git\ncd tanuki-iot-platform\n\ncodex\n","bash","",[117,129,130,146,156,163],{"__ignoreMap":127},[131,132,135,139,143],"span",{"class":133,"line":134},"line",1,[131,136,138],{"class":137},"s7eDp","git",[131,140,142],{"class":141},"sYBdl"," clone",[131,144,145],{"class":141}," https://gitlab.example.com/examplegroup/tanuki-iot-platform.git\n",[131,147,149,153],{"class":133,"line":148},2,[131,150,152],{"class":151},"sYu0t","cd",[131,154,155],{"class":141}," tanuki-iot-platform\n",[131,157,159],{"class":133,"line":158},3,[131,160,162],{"emptyLinePlaceholder":161},true,"\n",[131,164,166],{"class":133,"line":165},4,[131,167,168],{"class":137},"codex\n",[12,170,171],{},"プロンプトでプロジェクトの概要を確認します。",[122,173,177],{"className":174,"code":175,"language":176,"meta":127,"style":127},"language-markdown shiki shiki-themes github-light","What is this project about?\n","markdown",[117,178,179],{"__ignoreMap":127},[131,180,181],{"class":133,"line":134},[131,182,175],{"class":183},"sgsFI",[12,185,186,187,190],{},"このチュートリアルで扱うのは、",[117,188,189],{},"backend/","ディレクトリにあるRustのメトリクスストアです。センサーがREST APIを通じて計測値を送信し、ダッシュボードがWebSocketストリームでリアルタイムデータを受信する仕組みです。問題点と修正内容がわかりやすい構成になっています。",[51,192,194],{"id":193},"codexとgitlabを使い始めてrustバックエンドのバグを修正する","CodexとGitLabを使い始めてRustバックエンドのバグを修正する",[12,196,197,198,203],{},"このシナリオでは、ライブWebSocketストリームに",[16,199,202],{"href":200,"rel":201},"https://gitlab.com/gitlab-da/use-cases/ai/gitlab-duo-agent-platform/demo-environments/tanuki-iot-platform/-/work_items/32",[],"バグ","が存在します。バックエンドはREST API側ではすでにメトリクスフィルタリングをサポートしていますが、WebSocketストリームではメトリクスによる絞り込みが正しく機能していません。試しに1つのセンサーと1つのメトリクスをサブスクライブしても、他のメトリクスのデータまで返ってきます。ターミナルで問題を確認してみましょう。",[12,205,206],{},"ターミナル1でバックエンドを起動し、ポート9090でリッスンします。",[122,208,210],{"className":124,"code":209,"language":126,"meta":127,"style":127},"PORT=9090 cargo run --manifest-path backend/rust-metrics-store/Cargo.toml\n",[117,211,212],{"__ignoreMap":127},[131,213,214,217,221,224,227,230,233],{"class":133,"line":134},[131,215,216],{"class":183},"PORT",[131,218,220],{"class":219},"sD7c4","=",[131,222,223],{"class":141},"9090",[131,225,226],{"class":137}," cargo",[131,228,229],{"class":141}," run",[131,231,232],{"class":151}," --manifest-path",[131,234,235],{"class":141}," backend/rust-metrics-store/Cargo.toml\n",[12,237,238,239,242],{},"ターミナル2でWebSocketクライアントを開きます。macOSの場合、websocat はHomebrewで入手できます：",[117,240,241],{},"brew install websocat","。",[122,244,246],{"className":124,"code":245,"language":126,"meta":127,"style":127},"websocat 'ws://localhost:9090/ws?sensor=arduino-iot-collector&metric=temperature_celsius'\n",[117,247,248],{"__ignoreMap":127},[131,249,250,253],{"class":133,"line":134},[131,251,252],{"class":137},"websocat",[131,254,255],{"class":141}," 'ws://localhost:9090/ws?sensor=arduino-iot-collector&metric=temperature_celsius'\n",[12,257,258,259,262],{},"次に、",[117,260,261],{},"arduino-iot-collector","センサーに対して2種類のメトリクスを送信します。",[122,264,266],{"className":124,"code":265,"language":126,"meta":127,"style":127},"curl -s -X POST http://localhost:9090/api/metrics \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"sensor\":\"arduino-iot-collector\",\"metric\":\"temperature_celsius\",\"value\":23.5}'\n\ncurl -s -X POST http://localhost:9090/api/metrics \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"sensor\":\"arduino-iot-collector\",\"metric\":\"humidity_percent\",\"value\":61.2}'\n",[117,267,268,288,298,306,310,325,334],{"__ignoreMap":127},[131,269,270,273,276,279,282,285],{"class":133,"line":134},[131,271,272],{"class":137},"curl",[131,274,275],{"class":151}," -s",[131,277,278],{"class":151}," -X",[131,280,281],{"class":141}," POST",[131,283,284],{"class":141}," http://localhost:9090/api/metrics",[131,286,287],{"class":151}," \\\n",[131,289,290,293,296],{"class":133,"line":148},[131,291,292],{"class":151},"  -H",[131,294,295],{"class":141}," 'Content-Type: application/json'",[131,297,287],{"class":151},[131,299,300,303],{"class":133,"line":158},[131,301,302],{"class":151},"  -d",[131,304,305],{"class":141}," '{\"sensor\":\"arduino-iot-collector\",\"metric\":\"temperature_celsius\",\"value\":23.5}'\n",[131,307,308],{"class":133,"line":165},[131,309,162],{"emptyLinePlaceholder":161},[131,311,313,315,317,319,321,323],{"class":133,"line":312},5,[131,314,272],{"class":137},[131,316,275],{"class":151},[131,318,278],{"class":151},[131,320,281],{"class":141},[131,322,284],{"class":141},[131,324,287],{"class":151},[131,326,328,330,332],{"class":133,"line":327},6,[131,329,292],{"class":151},[131,331,295],{"class":141},[131,333,287],{"class":151},[131,335,337,339],{"class":133,"line":336},7,[131,338,302],{"class":151},[131,340,341],{"class":141}," '{\"sensor\":\"arduino-iot-collector\",\"metric\":\"humidity_percent\",\"value\":61.2}'\n",[12,343,344,347,348,351],{},[117,345,346],{},"temperature_celsius","だけが表示されるはずですが、ストリームには",[117,349,350],{},"humidity_percent","も表示されます。バグが確認できました。",[12,353,354],{},[355,356],"img",{"alt":357,"src":358,"title":359},"3つのターミナルセッション：メトリクスバックエンドの実行、websocatによるWebSocketストリームの読み取り、curlによるテストメトリクスの送信。","https://res.cloudinary.com/about-gitlab-com/image/upload/v1779101134/codexgitlabimage1.png","3つのターミナルセッション：メトリクスバックエンドの実行、`websocat`によるWebSocketストリームの読み取り、curlによるテストメトリクスの送信。",[12,361,362],{},"この問題をCodexに渡します。",[122,364,366],{"className":174,"code":365,"language":176,"meta":127,"style":127},"I need help with a backend change to add metric filtering to /ws so live streams can be narrowed to one metric.\n",[117,367,368],{"__ignoreMap":127},[131,369,370],{"class":133,"line":134},[131,371,365],{"class":183},[12,373,374,375,380],{},"GitLabプロジェクト内の",[16,376,379],{"href":377,"rel":378},"https://gitlab.com/gitlab-da/use-cases/ai/gitlab-duo-agent-platform/demo-environments/tanuki-iot-platform/-/blob/main/backend/rust-metrics-store/AGENTS.md?ref_type=heads#build-commands",[],"AGENTS.md","ファイルのおかげで、CodexはRustバックエンドの構成、実行すべきコマンド、コード品質の基準を把握しています。",[12,382,383],{},[355,384],{"alt":385,"src":386,"title":385},"Rustツールチェーンのセットアップとエージェントのビルドコマンドが記載されたAGENTS.md。","https://res.cloudinary.com/about-gitlab-com/image/upload/v1779101171/codexgitlabimage2.png",[12,388,389,390,393],{},"CodexはRustのソースコードを調べ、不足している部分を特定します。",[117,391,392],{},"/ws","エンドポイントはすでにsensorクエリパラメーターを受け付けていますが、オプションのmetricパラメーターも必要です。Codexはハンドラーロジックの更新、テストの追加、ドキュメントとコードの同期を行います。",[12,395,396],{},"コード変更後、Codexはフォーマット、テスト、ビルドを実行します。その後、Gitに触れる前に最終確認を行い、ブランチの作成、コミット、プッシュまで対応します。",[12,398,399],{},[355,400],{"alt":401,"src":402,"title":401},"バグを修正するCodex。差分の編集内容を表示。","https://res.cloudinary.com/about-gitlab-com/image/upload/v1779101152/codexgitlabimage3.png",[12,404,405,410,411,416],{},[16,406,409],{"href":407,"rel":408},"https://gitlab.com/gitlab-da/use-cases/ai/gitlab-duo-agent-platform/demo-environments/tanuki-iot-platform/-/merge_requests/88",[],"マージリクエスト","が作成されると、GitLabがソフトウェアライフサイクルの次のステージを担います。CI/CDパイプラインが起動し、セキュリティスキャンが実行され、GitLab Duo Code Reviewが",[16,412,415],{"href":413,"rel":414},"https://gitlab.com/gitlab-da/use-cases/ai/gitlab-duo-agent-platform/demo-environments/tanuki-iot-platform/-/blob/main/.gitlab/duo/mr-review-instructions.yaml?ref_type=heads#L202",[],"Rustコードスタイル要件","に照らして変更内容を検証します。",[12,418,419],{},[355,420],{"alt":421,"src":422,"title":421},"RustコードのためのGitLab Duo Code Reviewの設定。","https://res.cloudinary.com/about-gitlab-com/image/upload/v1779101180/codexgitlabimage4.png",[12,424,425],{},"デプロイ後にローカルテストを再実行すると、センサーとメトリクスの両方を指定した場合、WebSocketストリームが要求されたメトリクスのみを返すようになったことを確認できます。結果はマージリクエストにコメントとして投稿します。",[12,427,428],{},[355,429],{"alt":430,"src":431,"title":430},"GitLab Duo Code Reviewのフィードバックと、開発者がローカルテスト結果を共有しているMRコメント。","https://res.cloudinary.com/about-gitlab-com/image/upload/v1779101160/codexgitlabimage5.png",[12,433,434],{},"この最初のユースケースが基本形です。Codexがコードのそばにいてパッチをマージリクエストのライフサイクルに渡すと、GitLabがそこから作業を引き継ぎます。",[12,436,437],{},"Codex、GitLab CI/CD、GitLab Duo Agent Platformの動作を収録したデモ動画をご覧ください。",[439,440,443,444],"figure",{"className":441},[442],"video_container","\n  ",[445,446,450],"iframe",{"src":447,"frameBorder":448,"allowFullScreen":449},"https://www.youtube.com/embed/IQxrwvzLai4","0","true"," ",[51,452,454],{"id":453},"gitlab-mcpと開発ライフサイクルのコンテキストを使ってwebsocketメトリクスフィルターを修正する","GitLab MCPと開発ライフサイクルのコンテキストを使ってWebSocketメトリクスフィルターを修正する",[12,456,457],{},"最初のユースケースでは、Codexはプロジェクトリポジトリを参照できていましたが、GitLabのイシュー、合意された要件、実装メモ、マージリクエストやパイプラインの状態といったコンテキストは見えていませんでした。そのコンテキストはGitLabの中にあり、ローカルファイルには存在しません。",[12,459,460,461,464],{},"そこで登場するのが",[16,462,78],{"href":76,"rel":463},[],"です。",[12,466,467,468,472],{},"このユースケースでは、",[16,469,471],{"href":200,"rel":470},[],"イシュー","がすでに詳細に記述された状態で存在しています。問題の説明、機能要件・非機能要件、テスト、README.mdおよびAGENTS.mdの更新が明示されています。Codexはそれらをプロンプトに貼り付ける必要なく、イシューを直接取得して開発者が参照するのと同じ情報源から作業を進めることができます。",[12,474,475],{},[355,476],{"alt":477,"src":478,"title":477},"提案、機能要件、動作、非機能要件、実装メモを含むGitLabのイシュー。","https://res.cloudinary.com/about-gitlab-com/image/upload/v1779101184/codexgitlabimage6.png",[95,480,482],{"id":481},"gitlab-mcpサーバーの設定","GitLab MCPサーバーの設定",[12,484,485,486,491],{},"次に、GitLab MCPサーバーをCodexに追加します。インスタンスまたは最上位グループで",[16,487,490],{"href":488,"rel":489},"https://docs.gitlab.com/ja-jp/user/gitlab_duo/model_context_protocol/mcp_server/#prerequisites",[],"有効化","されていることを確認してください。",[12,493,494,495,498,499,503],{},"新しいターミナルを開き、",[117,496,497],{},"http","トランスポートタイプを使って",[16,500,78],{"href":501,"rel":502},"https://docs.gitlab.com/ja-jp/user/gitlab_duo/model_context_protocol/mcp_server/#connect-openai-codex-to-the-gitlab-mcp-server",[],"をCodexに追加します。",[12,505,506,509],{},[117,507,508],{},"gitlab.example.com","を使用するGitLabインスタンスのアドレスに変更します。",[122,511,513],{"className":124,"code":512,"language":126,"meta":127,"style":127},"codex mcp add --url \"https://\u003Cgitlab.example.com>/api/v4/mcp\" GitLab\n",[117,514,515],{"__ignoreMap":127},[131,516,517,519,522,525,528,531],{"class":133,"line":134},[131,518,119],{"class":137},[131,520,521],{"class":141}," mcp",[131,523,524],{"class":141}," add",[131,526,527],{"class":151}," --url",[131,529,530],{"class":141}," \"https://\u003Cgitlab.example.com>/api/v4/mcp\"",[131,532,533],{"class":141}," GitLab\n",[12,535,536,537,540,541,544,545,548,549,552],{},"CodexのMCPクライアントでは、Rustの",[117,538,539],{},"rmcp_client","にフィーチャーフラグが必要な場合があります。",[117,542,543],{},"~/.codex/config.toml","を開いて",[117,546,547],{},"[features]","セクションを追加します。",[117,550,551],{},"mcp_servers.","セクションでGitLab MCPサーバーが追加されていることも確認できます。",[122,554,556],{"className":124,"code":555,"language":126,"meta":127,"style":127},"vim ~/.codex/config.toml\n",[117,557,558],{"__ignoreMap":127},[131,559,560,563],{"class":133,"line":134},[131,561,562],{"class":137},"vim",[131,564,565],{"class":141}," ~/.codex/config.toml\n",[122,567,571],{"className":568,"code":569,"language":570,"meta":127,"style":127},"language-toml shiki shiki-themes github-light","[features]\n\"rmcp_client\" = true\n\n[mcp_servers.GitLab]\nurl = \"https://\u003Cgitlab.example.com>/api/v4/mcp\"\n","toml",[117,572,573,584,592,596,611],{"__ignoreMap":127},[131,574,575,578,581],{"class":133,"line":134},[131,576,577],{"class":183},"[",[131,579,580],{"class":137},"features",[131,582,583],{"class":183},"]\n",[131,585,586,589],{"class":133,"line":148},[131,587,588],{"class":183},"\"rmcp_client\" = ",[131,590,591],{"class":151},"true\n",[131,593,594],{"class":133,"line":158},[131,595,162],{"emptyLinePlaceholder":161},[131,597,598,600,603,606,609],{"class":133,"line":165},[131,599,577],{"class":183},[131,601,602],{"class":137},"mcp_servers",[131,604,605],{"class":183},".",[131,607,608],{"class":137},"GitLab",[131,610,583],{"class":183},[131,612,613,616],{"class":133,"line":312},[131,614,615],{"class":183},"url = ",[131,617,618],{"class":141},"\"https://\u003Cgitlab.example.com>/api/v4/mcp\"\n",[12,620,621,622,624,625,628],{},"新しいターミナルで",[117,623,119],{},"を実行し、",[117,626,627],{},"/mcp","と入力してGitLab MCPサーバーの認証を行います（追加時に自動的に行われなかった場合）。",[122,630,632],{"className":124,"code":631,"language":126,"meta":127,"style":127},"codex\n\n/mcp\n",[117,633,634,638,642],{"__ignoreMap":127},[131,635,636],{"class":133,"line":134},[131,637,168],{"class":137},[131,639,640],{"class":133,"line":148},[131,641,162],{"emptyLinePlaceholder":161},[131,643,644],{"class":133,"line":158},[131,645,646],{"class":137},"/mcp\n",[12,648,649],{},"接続を確認するには、Codexに次のように尋ねます。",[122,651,653],{"className":174,"code":652,"language":176,"meta":127,"style":127},"Which GitLab MCP tools are available to you?\n\nShow the GitLab MCP Server version.\n",[117,654,655,660,664],{"__ignoreMap":127},[131,656,657],{"class":133,"line":134},[131,658,659],{"class":183},"Which GitLab MCP tools are available to you?\n",[131,661,662],{"class":133,"line":148},[131,663,162],{"emptyLinePlaceholder":161},[131,665,666],{"class":133,"line":158},[131,667,668],{"class":183},"Show the GitLab MCP Server version.\n",[95,670,672],{"id":671},"codexにwebsocketフィルターのイシュー実装を依頼する","CodexにWebSocketフィルターのイシュー実装を依頼する",[12,674,675,676,679],{},"Codexを開き、",[16,677,471],{"href":200,"rel":678},[],"への対応を依頼します。",[122,681,683],{"className":174,"code":682,"language":176,"meta":127,"style":127},"Can you help me implement issue 32?\n",[117,684,685],{"__ignoreMap":127},[131,686,687],{"class":133,"line":134},[131,688,682],{"class":183},[12,690,691,692,695],{},"ここでワークフローが変わります。このシナリオでは、CodexはMCPの",[117,693,694],{},"get_issue","ツールを呼び出し、コードを変更する前にイシューの詳細をセッションに取り込みます。要件、ラベル、ノート、作業の全体的なスコープを把握した上で実装に取り組みます。",[12,697,698],{},[355,699],{"alt":700,"src":701,"title":702},"GitLab MCPサーバーツールのget_issueを呼び出し、ターミナルにイシューの詳細を表示するCodex。","https://res.cloudinary.com/about-gitlab-com/image/upload/v1779101166/codexgitlabimage7.png","GitLab MCPサーバーツールの`get_issue`を呼び出し、ターミナルにイシューの詳細を表示するCodex。",[12,704,705,706,709],{},"修正の内容は同じです。オプションの",[117,707,708],{},"metric","パラメーターの追加、マッチングロジックの更新、テストとドキュメントの更新。ただし、情報源が異なります。最初のユースケースではリポジトリとプロンプトが情報源でしたが、このユースケースではイシューとリポジトリが一緒に機能します。",[12,711,712,713,717],{},"ローカル検証後、CodexはMCPツール呼び出しを通じてブランチを作成し、作業をコミットし、",[16,714,409],{"href":715,"rel":716},"https://gitlab.com/gitlab-da/use-cases/ai/gitlab-duo-agent-platform/demo-environments/tanuki-iot-platform/-/merge_requests/89",[],"を作成します。Gitプッシュオプションやブラウザの操作は不要です。",[12,719,720],{},[355,721],{"alt":722,"src":723,"title":724},"GitLab MCPサーバーツールのcreate_merge_requestを使用してマージリクエストを作成するCodex。","https://res.cloudinary.com/about-gitlab-com/image/upload/v1779101144/codexgitlabimage8.png","GitLab MCPサーバーツールの`create_merge_request`を使用してマージリクエストを作成するCodex。",[12,726,727,728,731,732,737],{},"イシューのコンテキストを把握しているため、Codexはマージリクエストの説明に",[117,729,730],{},"closes 32","も追加します。これにより、",[16,733,736],{"href":734,"rel":735},"https://docs.gitlab.com/ja-jp/user/project/issues/managing_issues/#closing-issues-automatically",[],"マージ時にイシューが自動的にクローズ","されます。",[12,739,740],{},[355,741],{"alt":742,"src":743,"title":744},"マージ後にクローズされることを示すCloses #32をDescriptionに追加したCodex。","https://res.cloudinary.com/about-gitlab-com/image/upload/v1779101188/codexgitlabimage9.png","マージ後にクローズされることを示す`Closes #32`をDescriptionに追加したCodex。",[12,746,747],{},"このワークフローの意義は想像以上に大きなものです。エージェントは単にコードを書くだけでなく、イシュー、マージリクエスト、パイプラインのコンテキストを踏まえてソフトウェアデリバリーに参加しています。これがGitLab MCPがエンドツーエンドの開発ワークフローにもたらす価値です。",[12,749,750],{},"GitLab Duo Code ReviewとテストがGOサインを出した段階で、最終レビューとマージの準備が整います。",[12,752,753],{},[355,754],{"alt":755,"src":756,"title":755},"GitLab Duo Code Reviewとローカルテストのスクリーンショットを含むマージリクエストのコメント。","https://res.cloudinary.com/about-gitlab-com/image/upload/v1779101130/codexgitlabimage10.png",[12,758,759],{},"GitLab MCPサーバーを活用してCodexが問題を解決する様子を動画でご確認ください。",[439,761,443,763],{"className":762},[442],[445,764,450],{"src":765,"frameBorder":448,"allowFullScreen":449},"https://www.youtube.com/embed/okx4cw2p-3I",[51,767,769],{"id":768},"外部エージェントとしてのcodexでレビューフィードバックと要件を検証する","外部エージェントとしてのCodexでレビューフィードバックと要件を検証する",[12,771,772],{},"3つ目のユースケースはさらに興味深い内容です。Codexがマージリクエストをオープンできるかどうかではなく、より実践的な問いに答えます。マージリクエスト作成後に、マージリクエスト内のレビューフィードバックへの対応を支援できるのでしょうか？",[12,774,775,776,781,782,785,786,789,790,793],{},"このユースケースでは、別の",[16,777,780],{"href":778,"rel":779},"https://gitlab.com/gitlab-da/use-cases/ai/gitlab-duo-agent-platform/demo-environments/tanuki-iot-platform/-/work_items/33",[],"REST APIバリデーションのバグ","に切り替えます。このバグが示す問題は次のとおりです。",[117,783,784],{},"POST /api/metrics","が無効な入力を受け付けても",[117,787,788],{},"201 Created","を返してしまいます。空のメトリクスなど無効なペイロードの場合は",[117,791,792],{},"400 Bad Request","を返すべきです。",[12,795,796],{},"2つのターミナルで動作を確認します。ターミナル1でポート9090のメトリクスストアサーバーを起動します。",[122,798,799],{"className":124,"code":209,"language":126,"meta":127,"style":127},[117,800,801],{"__ignoreMap":127},[131,802,803,805,807,809,811,813,815],{"class":133,"line":134},[131,804,216],{"class":183},[131,806,220],{"class":219},[131,808,223],{"class":141},[131,810,226],{"class":137},[131,812,229],{"class":141},[131,814,232],{"class":151},[131,816,235],{"class":141},[12,818,819,820,822],{},"ターミナル2で、空のメトリクス値を含む特定のREST APIリクエストを",[117,821,272],{},"で送信してエラーを発生させます。",[122,824,826],{"className":124,"code":825,"language":126,"meta":127,"style":127},"curl -w \"\\nHTTP %{http_code}\\n\" -X POST http://localhost:9090/api/metrics \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"sensor\": \"sensor-a\", \"metric\": \"  \", \"value\": 23.5, \"labels\": {}}'\n",[117,827,828,846,855],{"__ignoreMap":127},[131,829,830,832,835,838,840,842,844],{"class":133,"line":134},[131,831,272],{"class":137},[131,833,834],{"class":151}," -w",[131,836,837],{"class":141}," \"\\nHTTP %{http_code}\\n\"",[131,839,278],{"class":151},[131,841,281],{"class":141},[131,843,284],{"class":141},[131,845,287],{"class":151},[131,847,848,850,853],{"class":133,"line":148},[131,849,292],{"class":151},[131,851,852],{"class":141}," \"Content-Type: application/json\"",[131,854,287],{"class":151},[131,856,857,859],{"class":133,"line":158},[131,858,302],{"class":151},[131,860,861],{"class":141}," '{\"sensor\": \"sensor-a\", \"metric\": \"  \", \"value\": 23.5, \"labels\": {}}'\n",[12,863,864,865,870],{},"Codexはすでに主要な修正を加えた最初の",[16,866,869],{"href":867,"rel":868},"https://gitlab.com/gitlab-da/use-cases/ai/gitlab-duo-agent-platform/demo-environments/tanuki-iot-platform/-/merge_requests/92",[],"ドラフトマージリクエスト","を作成しています。ローカルで再テストすると、コアの動作が改善され、無効な入力に対して400が返るようになっています。",[12,872,873],{},[355,874],{"alt":875,"src":876,"title":875},"バグがある状態と修正後の2つのcurl呼び出しの比較。","https://res.cloudinary.com/about-gitlab-com/image/upload/v1779101190/codexgitlabimage11.png",[12,878,879,880,883],{},"しかし、まだ完了ではありません。GitLab Duo Code Reviewが",[16,881,415],{"href":413,"rel":882},[],"に基づいて2つの不足点を指摘します。",[29,885,886,889],{},[32,887,888],{},"公開アイテムにドキュメントコメントが必要。",[32,890,891],{},"API変更にはサクセスパスとフェイルパスのハンドラーテストが必要だが、バリデーションテストが1つ欠けている。",[12,893,894],{},[355,895],{"alt":896,"src":897,"title":896},"RustコードへのGitLab Duo Code Reviewのフィードバック。","https://res.cloudinary.com/about-gitlab-com/image/upload/v1779101149/Blog/Imported/sandy-s-test/image12.png",[12,899,900,901,905,906,911,912,915],{},"ここでローカルターミナルからGitLab UIに移ります。",[902,903,904],"strong",{},"AI > Agents","メニューの",[16,907,910],{"href":908,"rel":909},"https://docs.gitlab.com/ja-jp/user/duo_agent_platform/ai_catalog/",[],"GitLab AIカタログ","からCodexエージェントを有効化します。",[117,913,914],{},"@ai-codex-agent","で始まるサービスアカウントハンドルを確認し、マージリクエストのディスカッションでエージェントを直接メンションしてレビューフィードバックへの対応を依頼します。",[12,917,918],{},[355,919],{"alt":920,"src":921,"title":920},"プロジェクトで有効化されたCodex Agent by GitLab。","https://res.cloudinary.com/about-gitlab-com/image/upload/v1779101175/codexgitlabimage13.png",[12,923,924],{},"マージリクエストがCodexエージェントの作業領域となります。コードの差分、レビューコメント、CI/CDパイプライン、セキュリティスキャン結果、承認ルールすべてが揃っています。Codexはコラボレーションがすでに行われている場所で、フォローアップ作業を進めることができます。",[12,926,927],{},"修正をマージリクエストに直接プッシュするよう指示しながら、新しいコメントで支援を依頼します。",[122,929,931],{"className":174,"code":930,"language":176,"meta":127,"style":127},"Please help address the review feedback, and push a fix.\n",[117,932,933],{"__ignoreMap":127},[131,934,935],{"class":133,"line":134},[131,936,930],{"class":183},[12,938,939],{},[355,940],{"alt":941,"src":942,"title":941},"マージリクエストのフィードバックコメントでCodexエージェントをメンション。","https://res.cloudinary.com/about-gitlab-com/image/upload/v1779101156/codexgitlabimage14.png",[12,944,945,946,951],{},"Codexはフィードバックに対応し、欠けていたバリデーションテストを追加してコミットし、",[16,947,950],{"href":948,"rel":949},"https://docs.gitlab.com/ja-jp/user/duo_agent_platform/sessions/",[],"Agent Session","内で独自の実行コンテキストでチェックを再実行し、マージリクエストにサマリーコメントを投稿します。",[12,953,954],{},[355,955],{"alt":956,"src":957,"title":956},"新しいGitコミットによってCI/CDパイプラインが自動的にトリガーされた様子。","https://res.cloudinary.com/about-gitlab-com/image/upload/v1779101192/codexgitlabimage15.png",[12,959,960],{},[355,961],{"alt":962,"src":963,"title":962},"Codex Agent by GitLabが新しいCI/CDパイプラインをトリガーした様子。","https://res.cloudinary.com/about-gitlab-com/image/upload/v1779101140/codexgitlabimage16.png",[12,965,966,971,972,975],{},[16,967,970],{"href":968,"rel":969},"https://gitlab.com/gitlab-da/use-cases/ai/gitlab-duo-agent-platform/demo-environments/tanuki-iot-platform/-/jobs/14375432932",[],"ジョブログ","で新しく追加された",[117,973,974],{},"ingest_rejects_blank_metric","テスト関数も確認できます。",[12,977,978],{},[355,979],{"alt":980,"src":981,"title":982},"ingest_rejects_blank_metricを検索したCI/CDジョブログ。","https://res.cloudinary.com/about-gitlab-com/image/upload/v1779101126/codexgitlabmage17.png","`ingest_rejects_blank_metric`を検索したCI/CDジョブログ。",[12,984,985,986,991,992,997],{},"外部エージェントモデルが実際に役立つのはこの点です。外部エージェントはレビューの代替として面白いのではなく、マージリクエスト、承認、最終的な人間の判断を適切な場所に保ちながら、レビューフィードバックと次のリビジョンの間のギャップを縮めるために有用です。また、",[16,987,990],{"href":988,"rel":989},"https://docs.gitlab.com/ja-jp/user/duo_agent_platform/triggers/",[],"イベントトリガー","や",[16,993,996],{"href":994,"rel":995},"https://docs.gitlab.com/ja-jp/user/duo_agent_platform/flows/custom/",[],"カスタムフロー","を通じて、GitLab Duo Agent Platformにさらに深く統合することも可能です。",[12,999,1000],{},"GitLab Duo Agent PlatformでCodexが外部エージェントとしてレビューを支援する様子を動画でご確認ください。",[439,1002,443,1004],{"className":1003},[442],[445,1005,450],{"src":1006,"frameBorder":448,"allowFullScreen":449},"https://www.youtube.com/embed/BapLAKxeomI",[51,1008,1010],{"id":1009},"codexとgitlabを活用するためのヒント","CodexとGitLabを活用するためのヒント",[95,1012,1014],{"id":1013},"agentsmdによるカスタムインストラクション","AGENTS.mdによるカスタムインストラクション",[12,1016,1017,1019],{},[117,1018,379],{},"のエントリーを使うことで、コミット前にコードのビルドとテストを行う、変更を最小限に保つ、プロジェクトアーキテクチャをより深く理解するといった指示をエージェントに与えることができます。Tanuki IoTプラットフォームはルートレベルのファイルに加え、センサーとバックエンド向けのサブディレクトリごとのファイルと指示を使用しています。",[122,1021,1023],{"className":124,"code":1022,"language":126,"meta":127,"style":127},"tree -P AGENTS.md --prune\n.\n├── AGENTS.md\n├── backend\n│   └── rust-metrics-store\n│       └── AGENTS.md\n└── sensors\n    ├── arduino-iot-collector\n    │   └── AGENTS.md\n    ├── c-file-monitor\n    │   └── AGENTS.md\n    ├── cobol-mainframe-bridge\n    │   └── AGENTS.md\n    └── java-http-metrics-collector\n        └── AGENTS.md\n",[117,1024,1025,1039,1044,1052,1059,1070,1079,1087,1096,1106,1114,1123,1131,1140,1149],{"__ignoreMap":127},[131,1026,1027,1030,1033,1036],{"class":133,"line":134},[131,1028,1029],{"class":137},"tree",[131,1031,1032],{"class":151}," -P",[131,1034,1035],{"class":141}," AGENTS.md",[131,1037,1038],{"class":151}," --prune\n",[131,1040,1041],{"class":133,"line":148},[131,1042,1043],{"class":151},".\n",[131,1045,1046,1049],{"class":133,"line":158},[131,1047,1048],{"class":137},"├──",[131,1050,1051],{"class":141}," AGENTS.md\n",[131,1053,1054,1056],{"class":133,"line":165},[131,1055,1048],{"class":137},[131,1057,1058],{"class":141}," backend\n",[131,1060,1061,1064,1067],{"class":133,"line":312},[131,1062,1063],{"class":137},"│",[131,1065,1066],{"class":141},"   └──",[131,1068,1069],{"class":141}," rust-metrics-store\n",[131,1071,1072,1074,1077],{"class":133,"line":327},[131,1073,1063],{"class":137},[131,1075,1076],{"class":141},"       └──",[131,1078,1051],{"class":141},[131,1080,1081,1084],{"class":133,"line":336},[131,1082,1083],{"class":137},"└──",[131,1085,1086],{"class":141}," sensors\n",[131,1088,1090,1093],{"class":133,"line":1089},8,[131,1091,1092],{"class":137},"    ├──",[131,1094,1095],{"class":141}," arduino-iot-collector\n",[131,1097,1099,1102,1104],{"class":133,"line":1098},9,[131,1100,1101],{"class":137},"    │",[131,1103,1066],{"class":141},[131,1105,1051],{"class":141},[131,1107,1109,1111],{"class":133,"line":1108},10,[131,1110,1092],{"class":137},[131,1112,1113],{"class":141}," c-file-monitor\n",[131,1115,1117,1119,1121],{"class":133,"line":1116},11,[131,1118,1101],{"class":137},[131,1120,1066],{"class":141},[131,1122,1051],{"class":141},[131,1124,1126,1128],{"class":133,"line":1125},12,[131,1127,1092],{"class":137},[131,1129,1130],{"class":141}," cobol-mainframe-bridge\n",[131,1132,1134,1136,1138],{"class":133,"line":1133},13,[131,1135,1101],{"class":137},[131,1137,1066],{"class":141},[131,1139,1051],{"class":141},[131,1141,1143,1146],{"class":133,"line":1142},14,[131,1144,1145],{"class":137},"    └──",[131,1147,1148],{"class":141}," java-http-metrics-collector\n",[131,1150,1152,1155],{"class":133,"line":1151},15,[131,1153,1154],{"class":137},"        └──",[131,1156,1051],{"class":141},[12,1158,1159,1160,1167,1168,1170],{},"Rustバックエンド向けには、",[16,1161,1164],{"href":1162,"rel":1163},"https://gitlab.com/gitlab-da/use-cases/ai/gitlab-duo-agent-platform/demo-environments/tanuki-iot-platform/-/blob/main/backend/rust-metrics-store/AGENTS.md?ref_type=heads",[],[117,1165,1166],{},"backend/rust-metric-store/AGENTS.md","にディレクトリレベルの",[117,1169,379],{},"が用意されています。Rustのコードスタイルと標準、ドキュメント、ファイル構成、エラーハンドリング、非同期プログラミング、コンテナ化とCI/CD、利用可能なツールチェーン（Cargo）でのビルドと実行方法が定義されています。詳細はGitLabプロジェクトのリンク先ファイルを参照してください。",[122,1172,1174],{"className":174,"code":1173,"language":176,"meta":127,"style":127},"# rust-metrics-store - Agent Instructions\n\n## Overview\n\nThe `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.\n\n## Code Style and Standards\n\n### Rust Standards\n\n- Use Rust 2021 edition idioms\n- Run `cargo fmt` before committing\n- Run `cargo clippy -- -D warnings` and resolve all warnings\n- Prefer `Arc\u003CT>` + `RwLock\u003CT>` for shared state; avoid `Mutex` unless write-heavy\n- Use `?` for error propagation in fallible functions; only `unwrap()` on truly unrecoverable states (e.g., lock poisoning)\n- Derive `Debug`, `Clone`, `Serialize`, `Deserialize` only where needed\n- Keep `pub` visibility minimal — expose only what callers need\n\n### Documentation\n\n- Public types and functions must have a doc comment\n- Include `# Errors` section in doc comments for fallible functions\n- Document env vars and their defaults in `README.md`, not in code\n\n### File Organization\n\n- **`src/main.rs`** — router wiring and `tokio::main`; no business logic\n- **`src/store.rs`** — `MetricsStore` and data types; no HTTP concerns\n- **`src/handlers.rs`** — Axum extractors and response types; thin layer over the store\n\n### Error Handling\n\n- HTTP handlers should return meaningful status codes (201 for ingest, 404 for unknown sensor)\n- Log warnings for recoverable issues (e.g., lagging WebSocket clients) with `tracing::warn!`\n- Never silently swallow errors\n\n### Async and Concurrency\n\n- Use `tokio::sync::broadcast` for the live-stream fan-out; `RwLock` for the ring-buffer map\n- WebSocket handlers must break cleanly on send errors — do not loop after a closed socket\n- Handle `RecvError::Lagged` by logging and continuing, not by disconnecting\n\n### Containerization\n\n- Use a multi-stage Dockerfile: `rust:1.95-slim` builder, `debian:bookworm-slim` runtime\n- Always run the container as a non-root user — create `appuser` with `addgroup`/`adduser` and set `USER appuser` before `CMD`\n- Include a `.dockerignore` that excludes `target/` and `.git/` to keep build context small\n- Use specific image tags — never `latest` in Dockerfile or CI base templates\n\n### CI/CD\n\n- Pin all CI images to specific tags (e.g., `rust:1.95`) — never use `rust:latest` or `debian:latest`\n- The `.rust_base` template in `.gitlab-ci.yml` must match the Dockerfile builder image version\n\n## Local Toolchain Setup\n\n// More instructions in the file\n",[117,1175,1176,1182,1186,1191,1195,1206,1210,1215,1219,1224,1228,1237,1250,1262,1287,1306,1336,1350,1355,1361,1366,1374,1388,1402,1407,1413,1418,1442,1463,1478,1483,1489,1494,1502,1513,1521,1526,1532,1537,1556,1564,1578,1583,1589,1594,1614,1649,1675,1689,1694,1700,1705,1728,1748,1753,1759,1764],{"__ignoreMap":127},[131,1177,1178],{"class":133,"line":134},[131,1179,1181],{"class":1180},"surfw","# rust-metrics-store - Agent Instructions\n",[131,1183,1184],{"class":133,"line":148},[131,1185,162],{"emptyLinePlaceholder":161},[131,1187,1188],{"class":133,"line":158},[131,1189,1190],{"class":1180},"## Overview\n",[131,1192,1193],{"class":133,"line":165},[131,1194,162],{"emptyLinePlaceholder":161},[131,1196,1197,1200,1203],{"class":133,"line":312},[131,1198,1199],{"class":183},"The ",[131,1201,1202],{"class":151},"`rust-metrics-store`",[131,1204,1205],{"class":183}," 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.\n",[131,1207,1208],{"class":133,"line":327},[131,1209,162],{"emptyLinePlaceholder":161},[131,1211,1212],{"class":133,"line":336},[131,1213,1214],{"class":1180},"## Code Style and Standards\n",[131,1216,1217],{"class":133,"line":1089},[131,1218,162],{"emptyLinePlaceholder":161},[131,1220,1221],{"class":133,"line":1098},[131,1222,1223],{"class":1180},"### Rust Standards\n",[131,1225,1226],{"class":133,"line":1108},[131,1227,162],{"emptyLinePlaceholder":161},[131,1229,1230,1234],{"class":133,"line":1116},[131,1231,1233],{"class":1232},"sqxcx","-",[131,1235,1236],{"class":183}," Use Rust 2021 edition idioms\n",[131,1238,1239,1241,1244,1247],{"class":133,"line":1125},[131,1240,1233],{"class":1232},[131,1242,1243],{"class":183}," Run ",[131,1245,1246],{"class":151},"`cargo fmt`",[131,1248,1249],{"class":183}," before committing\n",[131,1251,1252,1254,1256,1259],{"class":133,"line":1133},[131,1253,1233],{"class":1232},[131,1255,1243],{"class":183},[131,1257,1258],{"class":151},"`cargo clippy -- -D warnings`",[131,1260,1261],{"class":183}," and resolve all warnings\n",[131,1263,1264,1266,1269,1272,1275,1278,1281,1284],{"class":133,"line":1142},[131,1265,1233],{"class":1232},[131,1267,1268],{"class":183}," Prefer ",[131,1270,1271],{"class":151},"`Arc\u003CT>`",[131,1273,1274],{"class":183}," + ",[131,1276,1277],{"class":151},"`RwLock\u003CT>`",[131,1279,1280],{"class":183}," for shared state; avoid ",[131,1282,1283],{"class":151},"`Mutex`",[131,1285,1286],{"class":183}," unless write-heavy\n",[131,1288,1289,1291,1294,1297,1300,1303],{"class":133,"line":1151},[131,1290,1233],{"class":1232},[131,1292,1293],{"class":183}," Use ",[131,1295,1296],{"class":151},"`?`",[131,1298,1299],{"class":183}," for error propagation in fallible functions; only ",[131,1301,1302],{"class":151},"`unwrap()`",[131,1304,1305],{"class":183}," on truly unrecoverable states (e.g., lock poisoning)\n",[131,1307,1309,1311,1314,1317,1320,1323,1325,1328,1330,1333],{"class":133,"line":1308},16,[131,1310,1233],{"class":1232},[131,1312,1313],{"class":183}," Derive ",[131,1315,1316],{"class":151},"`Debug`",[131,1318,1319],{"class":183},", ",[131,1321,1322],{"class":151},"`Clone`",[131,1324,1319],{"class":183},[131,1326,1327],{"class":151},"`Serialize`",[131,1329,1319],{"class":183},[131,1331,1332],{"class":151},"`Deserialize`",[131,1334,1335],{"class":183}," only where needed\n",[131,1337,1339,1341,1344,1347],{"class":133,"line":1338},17,[131,1340,1233],{"class":1232},[131,1342,1343],{"class":183}," Keep ",[131,1345,1346],{"class":151},"`pub`",[131,1348,1349],{"class":183}," visibility minimal — expose only what callers need\n",[131,1351,1353],{"class":133,"line":1352},18,[131,1354,162],{"emptyLinePlaceholder":161},[131,1356,1358],{"class":133,"line":1357},19,[131,1359,1360],{"class":1180},"### Documentation\n",[131,1362,1364],{"class":133,"line":1363},20,[131,1365,162],{"emptyLinePlaceholder":161},[131,1367,1369,1371],{"class":133,"line":1368},21,[131,1370,1233],{"class":1232},[131,1372,1373],{"class":183}," Public types and functions must have a doc comment\n",[131,1375,1377,1379,1382,1385],{"class":133,"line":1376},22,[131,1378,1233],{"class":1232},[131,1380,1381],{"class":183}," Include ",[131,1383,1384],{"class":151},"`# Errors`",[131,1386,1387],{"class":183}," section in doc comments for fallible functions\n",[131,1389,1391,1393,1396,1399],{"class":133,"line":1390},23,[131,1392,1233],{"class":1232},[131,1394,1395],{"class":183}," Document env vars and their defaults in ",[131,1397,1398],{"class":151},"`README.md`",[131,1400,1401],{"class":183},", not in code\n",[131,1403,1405],{"class":133,"line":1404},24,[131,1406,162],{"emptyLinePlaceholder":161},[131,1408,1410],{"class":133,"line":1409},25,[131,1411,1412],{"class":1180},"### File Organization\n",[131,1414,1416],{"class":133,"line":1415},26,[131,1417,162],{"emptyLinePlaceholder":161},[131,1419,1421,1423,1427,1430,1433,1436,1439],{"class":133,"line":1420},27,[131,1422,1233],{"class":1232},[131,1424,1426],{"class":1425},"sbYKK"," **",[131,1428,1429],{"class":1180},"`src/main.rs`",[131,1431,1432],{"class":1425},"**",[131,1434,1435],{"class":183}," — router wiring and ",[131,1437,1438],{"class":151},"`tokio::main`",[131,1440,1441],{"class":183},"; no business logic\n",[131,1443,1445,1447,1449,1452,1454,1457,1460],{"class":133,"line":1444},28,[131,1446,1233],{"class":1232},[131,1448,1426],{"class":1425},[131,1450,1451],{"class":1180},"`src/store.rs`",[131,1453,1432],{"class":1425},[131,1455,1456],{"class":183}," — ",[131,1458,1459],{"class":151},"`MetricsStore`",[131,1461,1462],{"class":183}," and data types; no HTTP concerns\n",[131,1464,1466,1468,1470,1473,1475],{"class":133,"line":1465},29,[131,1467,1233],{"class":1232},[131,1469,1426],{"class":1425},[131,1471,1472],{"class":1180},"`src/handlers.rs`",[131,1474,1432],{"class":1425},[131,1476,1477],{"class":183}," — Axum extractors and response types; thin layer over the store\n",[131,1479,1481],{"class":133,"line":1480},30,[131,1482,162],{"emptyLinePlaceholder":161},[131,1484,1486],{"class":133,"line":1485},31,[131,1487,1488],{"class":1180},"### Error Handling\n",[131,1490,1492],{"class":133,"line":1491},32,[131,1493,162],{"emptyLinePlaceholder":161},[131,1495,1497,1499],{"class":133,"line":1496},33,[131,1498,1233],{"class":1232},[131,1500,1501],{"class":183}," HTTP handlers should return meaningful status codes (201 for ingest, 404 for unknown sensor)\n",[131,1503,1505,1507,1510],{"class":133,"line":1504},34,[131,1506,1233],{"class":1232},[131,1508,1509],{"class":183}," Log warnings for recoverable issues (e.g., lagging WebSocket clients) with ",[131,1511,1512],{"class":151},"`tracing::warn!`\n",[131,1514,1516,1518],{"class":133,"line":1515},35,[131,1517,1233],{"class":1232},[131,1519,1520],{"class":183}," Never silently swallow errors\n",[131,1522,1524],{"class":133,"line":1523},36,[131,1525,162],{"emptyLinePlaceholder":161},[131,1527,1529],{"class":133,"line":1528},37,[131,1530,1531],{"class":1180},"### Async and Concurrency\n",[131,1533,1535],{"class":133,"line":1534},38,[131,1536,162],{"emptyLinePlaceholder":161},[131,1538,1540,1542,1544,1547,1550,1553],{"class":133,"line":1539},39,[131,1541,1233],{"class":1232},[131,1543,1293],{"class":183},[131,1545,1546],{"class":151},"`tokio::sync::broadcast`",[131,1548,1549],{"class":183}," for the live-stream fan-out; ",[131,1551,1552],{"class":151},"`RwLock`",[131,1554,1555],{"class":183}," for the ring-buffer map\n",[131,1557,1559,1561],{"class":133,"line":1558},40,[131,1560,1233],{"class":1232},[131,1562,1563],{"class":183}," WebSocket handlers must break cleanly on send errors — do not loop after a closed socket\n",[131,1565,1567,1569,1572,1575],{"class":133,"line":1566},41,[131,1568,1233],{"class":1232},[131,1570,1571],{"class":183}," Handle ",[131,1573,1574],{"class":151},"`RecvError::Lagged`",[131,1576,1577],{"class":183}," by logging and continuing, not by disconnecting\n",[131,1579,1581],{"class":133,"line":1580},42,[131,1582,162],{"emptyLinePlaceholder":161},[131,1584,1586],{"class":133,"line":1585},43,[131,1587,1588],{"class":1180},"### Containerization\n",[131,1590,1592],{"class":133,"line":1591},44,[131,1593,162],{"emptyLinePlaceholder":161},[131,1595,1597,1599,1602,1605,1608,1611],{"class":133,"line":1596},45,[131,1598,1233],{"class":1232},[131,1600,1601],{"class":183}," Use a multi-stage Dockerfile: ",[131,1603,1604],{"class":151},"`rust:1.95-slim`",[131,1606,1607],{"class":183}," builder, ",[131,1609,1610],{"class":151},"`debian:bookworm-slim`",[131,1612,1613],{"class":183}," runtime\n",[131,1615,1617,1619,1622,1625,1628,1631,1634,1637,1640,1643,1646],{"class":133,"line":1616},46,[131,1618,1233],{"class":1232},[131,1620,1621],{"class":183}," Always run the container as a non-root user — create ",[131,1623,1624],{"class":151},"`appuser`",[131,1626,1627],{"class":183}," with ",[131,1629,1630],{"class":151},"`addgroup`",[131,1632,1633],{"class":183},"/",[131,1635,1636],{"class":151},"`adduser`",[131,1638,1639],{"class":183}," and set ",[131,1641,1642],{"class":151},"`USER appuser`",[131,1644,1645],{"class":183}," before ",[131,1647,1648],{"class":151},"`CMD`\n",[131,1650,1652,1654,1657,1660,1663,1666,1669,1672],{"class":133,"line":1651},47,[131,1653,1233],{"class":1232},[131,1655,1656],{"class":183}," Include a ",[131,1658,1659],{"class":151},"`.dockerignore`",[131,1661,1662],{"class":183}," that excludes ",[131,1664,1665],{"class":151},"`target/`",[131,1667,1668],{"class":183}," and ",[131,1670,1671],{"class":151},"`.git/`",[131,1673,1674],{"class":183}," to keep build context small\n",[131,1676,1678,1680,1683,1686],{"class":133,"line":1677},48,[131,1679,1233],{"class":1232},[131,1681,1682],{"class":183}," Use specific image tags — never ",[131,1684,1685],{"class":151},"`latest`",[131,1687,1688],{"class":183}," in Dockerfile or CI base templates\n",[131,1690,1692],{"class":133,"line":1691},49,[131,1693,162],{"emptyLinePlaceholder":161},[131,1695,1697],{"class":133,"line":1696},50,[131,1698,1699],{"class":1180},"### CI/CD\n",[131,1701,1703],{"class":133,"line":1702},51,[131,1704,162],{"emptyLinePlaceholder":161},[131,1706,1708,1710,1713,1716,1719,1722,1725],{"class":133,"line":1707},52,[131,1709,1233],{"class":1232},[131,1711,1712],{"class":183}," Pin all CI images to specific tags (e.g., ",[131,1714,1715],{"class":151},"`rust:1.95`",[131,1717,1718],{"class":183},") — never use ",[131,1720,1721],{"class":151},"`rust:latest`",[131,1723,1724],{"class":183}," or ",[131,1726,1727],{"class":151},"`debian:latest`\n",[131,1729,1731,1733,1736,1739,1742,1745],{"class":133,"line":1730},53,[131,1732,1233],{"class":1232},[131,1734,1735],{"class":183}," The ",[131,1737,1738],{"class":151},"`.rust_base`",[131,1740,1741],{"class":183}," template in ",[131,1743,1744],{"class":151},"`.gitlab-ci.yml`",[131,1746,1747],{"class":183}," must match the Dockerfile builder image version\n",[131,1749,1751],{"class":133,"line":1750},54,[131,1752,162],{"emptyLinePlaceholder":161},[131,1754,1756],{"class":133,"line":1755},55,[131,1757,1758],{"class":1180},"## Local Toolchain Setup\n",[131,1760,1762],{"class":133,"line":1761},56,[131,1763,162],{"emptyLinePlaceholder":161},[131,1765,1767],{"class":133,"line":1766},57,[131,1768,1769],{"class":183},"// More instructions in the file\n",[12,1771,1772,1773,1778],{},"これらの",[16,1774,1777],{"href":1775,"rel":1776},"https://docs.gitlab.com/ja-jp/user/duo_agent_platform/customize/agents_md/",[],"カスタムインストラクション","は、GitLab Duo Agent Platform上のエージェントとフローにも適用されます。",[12,1780,1781],{},"コーディングエージェントからより良い結果を得たいなら、まずここから始めましょう。リポジトリの仕組み、重要なコマンド、触れてはいけない箇所、良い変更の定義を書き記すことで、ローカルのコーディングツール、GitLab MCP、外部エージェントすべてに効果が生まれます。",[51,1783,1784],{"id":1784},"まとめ",[12,1786,1787],{},"このチュートリアルの3つのユースケースは互いに発展していますが、より大きなポイントも示しています。",[12,1789,1790],{},"Codexは問題の記述からコードへと素早く移行する点で優れています。GitLabはそのコードを、理解・検証・レビュー・自信を持ってリリースできる変更へと変えるためのソフトウェアデリバリーコンテキストを提供します。",[12,1792,1793],{},"最初のユースケースではコードのそばにとどまり、リポジトリとローカルのエージェントインストラクションをもとにCodexを活用しました。2つ目のユースケースでは、GitLab MCPがイシュー、要件、マージリクエストのワークフローをターミナルセッションに直接取り込みました。3つ目のユースケースでは、Codexがマージリクエストそのものにアクセスしてレビューフィードバックと次のリビジョンの間のギャップを縮めました。",[12,1795,1796],{},"この発展こそが、組み合わせを説得力あるものにします。コーディングツールとDevSecOpsプラットフォームのどちらかを選ぶのではありません。エージェント型コーディングのスピードをソフトウェアライフサイクル全体へと拡張するのです。多くのプロジェクト、多くのリリースマイルストーン、多くのチームにわたって規模を拡大しながら。",[12,1798,1799],{},"すでにCodexを使用している場合、GitLabはコーディングのスピードとパッチが存在した後に重要となるコンテキスト・コラボレーションをつなぐ実用的な方法を提供します。GitLab Duo Agent Platformをすでに使用している場合、外部エージェントによってマージリクエストの監査証跡や最終的な人間の意思決定を失わずに、サードパーティのコーディングツールをGitLabに取り込む新しい方法が生まれます。",[12,1801,1802],{},"ぜひ小さく始めてみてください。目に見えるバグを1つ選び、イシューで期待される動作を定義し、ここで紹介した流れを順に試してみます。ローカルコーディング、イシュー連携での実装、マージリクエストでのコラボレーション。そこで、この組み合わせが単なる高速なパッチをはるかに超えたものになります。",[1804,1805,1806,1815,1824],"blockquote",{},[12,1807,1808,1809,1814],{},"GitLab Duo Agent Platformをまだご利用でない場合は、",[16,1810,1813],{"href":1811,"rel":1812},"https://about.gitlab.com/ja-jp/gitlab-duo-agent-platform/",[],"無料トライアル","からお試しください。",[12,1816,1817,1818,1823],{},"GitLabの無料プランをご利用の場合は、",[16,1819,1822],{"href":1820,"rel":1821},"https://docs.gitlab.com/ja-jp/subscriptions/gitlab_credits/#for-the-free-tier-on-gitlabcom",[],"簡単な手順","に従ってGitLab Duo Agent Platformにサインアップできます。",[12,1825,1826,1827,1832,1833,1838],{},"GitLab PremiumまたはUltimateをご契約中の場合は、",[16,1828,1831],{"href":1829,"rel":1830},"https://docs.gitlab.com/ja-jp/user/duo_agent_platform/turn_on_off/",[],"Duo Agent Platformをオンにする","だけで利用開始でき、サブスクリプションに",[16,1834,1837],{"href":1835,"rel":1836},"https://docs.gitlab.com/ja-jp/subscriptions/gitlab_credits/#included-credits",[],"含まれている","GitLabクレジットをすぐにご活用いただけます。",[1840,1841,1842],"style",{},"html pre.shiki code .s7eDp, html code.shiki .s7eDp{--shiki-default:#6F42C1}html pre.shiki code .sYBdl, html code.shiki .sYBdl{--shiki-default:#032F62}html pre.shiki code .sYu0t, html code.shiki .sYu0t{--shiki-default:#005CC5}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sgsFI, html code.shiki .sgsFI{--shiki-default:#24292E}html pre.shiki code .sD7c4, html code.shiki .sD7c4{--shiki-default:#D73A49}html pre.shiki code .surfw, html code.shiki .surfw{--shiki-default:#005CC5;--shiki-default-font-weight:bold}html pre.shiki code .sqxcx, html code.shiki .sqxcx{--shiki-default:#E36209}html pre.shiki code .sbYKK, html code.shiki .sbYKK{--shiki-default:#24292E;--shiki-default-font-weight:bold}",{"title":127,"searchDepth":148,"depth":148,"links":1844},[1845,1848,1849,1853,1854,1857],{"id":53,"depth":148,"text":53,"children":1846},[1847],{"id":97,"depth":158,"text":98},{"id":193,"depth":148,"text":194},{"id":453,"depth":148,"text":454,"children":1850},[1851,1852],{"id":481,"depth":158,"text":482},{"id":671,"depth":158,"text":672},{"id":768,"depth":148,"text":769},{"id":1009,"depth":148,"text":1010,"children":1855},[1856],{"id":1013,"depth":158,"text":1014},{"id":1784,"depth":148,"text":1784},"AI","2026-05-18","Codexをターミナルで活用する方法、GitLab MCPによるイシュー連携開発、GitLab Duo Agent Platformの外部AIエージェントを使ってバグ報告からレビュー済み変更へ移行する手順を解説します。","md",null,"https://res.cloudinary.com/about-gitlab-com/image/upload/v1776457632/llddiylsgwuze0u1rjks.png",{},"/ja-jp/blog/fix-bugs-with-codex-and-gitlab",{"ogTitle":1867,"ogImage":1863,"ogDescription":1860,"ogSiteName":608,"ogType":1868,"ogUrl":1869,"title":1867,"canonicalUrls":1869,"description":1870},"CodexとGitLabでバグを修正する","article","https://about.gitlab.com/blog/fix-bugs-with-codex-and-gitlab","Codexをターミナルで活用する方法、GitLab MCPを使ったイシュー連携開発、そしてGitLab Duo Agent Platformの外部エージェントを活用してバグ報告からレビュー済みの変更へスムーズに移行する手順をステップごとに解説します。","fix-bugs-with-codex-and-gitlab","ja-jp/blog/fix-bugs-with-codex-and-gitlab",[1858,1874,1875,1876,1877],"product","DevSecOps platform","tutorial","workflow","BlogPost","2026-05-21","tWi9vRBORtZ2W5kHQ3gvV6xurfOcu7PN-VBKK_aEQkI",{"logo":1882,"freeTrial":1887,"sales":1892,"login":1897,"items":1902,"search":2224,"minimal":2257,"duo":2274,"switchNav":2283,"pricingDeployment":2294},{"config":1883},{"href":1884,"dataGaName":1885,"dataGaLocation":1886},"/ja-jp/","gitlab logo","header",{"text":1888,"config":1889},"無料トライアルを開始",{"href":1890,"dataGaName":1891,"dataGaLocation":1886},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/ja-jp&glm_content=default-saas-trial/","free trial",{"text":1893,"config":1894},"お問い合わせはこちら",{"href":1895,"dataGaName":1896,"dataGaLocation":1886},"/ja-jp/sales/","sales",{"text":1898,"config":1899},"サインイン",{"href":1900,"dataGaName":1901,"dataGaLocation":1886},"https://gitlab.com/users/sign_in/","sign in",[1903,1932,2034,2039,2143,2204],{"text":1904,"config":1905,"menu":1907},"プラットフォーム",{"dataNavLevelOne":1906},"platform",{"type":1908,"columns":1909},"cards",[1910,1916,1924],{"title":1904,"description":1911,"link":1912},"DevSecOpsに特化したインテリジェントオーケストレーションプラットフォーム",{"text":1913,"config":1914},"プラットフォームの詳細はこちら",{"href":1915,"dataGaName":1906,"dataGaLocation":1886},"/ja-jp/platform/",{"title":1917,"description":1918,"link":1919},"GitLab Duo Agent Platform","ソフトウェアライフサイクル全体を支えるエージェント型AI",{"text":1920,"config":1921},"GitLab Duoのご紹介",{"href":1922,"dataGaName":1923,"dataGaLocation":1886},"/ja-jp/gitlab-duo-agent-platform/","gitlab duo agent platform",{"title":1925,"description":1926,"link":1927},"GitLabが選ばれる理由","エンタープライズがGitLabを選ぶ主な理由をご覧ください",{"text":1928,"config":1929},"詳細はこちら",{"href":1930,"dataGaName":1931,"dataGaLocation":1886},"/ja-jp/why-gitlab/","why gitlab",{"text":1933,"left":161,"config":1934,"menu":1936},"製品",{"dataNavLevelOne":1935},"solutions",{"type":1937,"link":1938,"columns":1942,"feature":2013},"lists",{"text":1939,"config":1940},"すべてのソリューションを表示",{"href":1941,"dataGaName":1935,"dataGaLocation":1886},"/ja-jp/solutions/",[1943,1968,1991],{"title":1944,"description":1945,"link":1946,"items":1951},"自動化","CI/CDと自動化でデプロイを加速",{"config":1947},{"icon":1948,"href":1949,"dataGaName":1950,"dataGaLocation":1886},"AutomatedCodeAlt","/ja-jp/solutions/delivery-automation/","automated software delivery",[1952,1956,1959,1964],{"text":1953,"config":1954},"CI/CD",{"href":1955,"dataGaLocation":1886,"dataGaName":1953},"/ja-jp/solutions/continuous-integration/",{"text":1917,"config":1957},{"href":1922,"dataGaLocation":1886,"dataGaName":1958},"gitlab duo agent platform - product menu",{"text":1960,"config":1961},"ソースコード管理",{"href":1962,"dataGaLocation":1886,"dataGaName":1963},"/ja-jp/solutions/source-code-management/","Source Code Management",{"text":1965,"config":1966},"自動化されたソフトウェアデリバリー",{"href":1949,"dataGaLocation":1886,"dataGaName":1967},"Automated software delivery",{"title":1969,"description":1970,"link":1971,"items":1976},"セキュリティ","セキュリティを犠牲にすることなくコード作成を高速化",{"config":1972},{"href":1973,"dataGaName":1974,"dataGaLocation":1886,"icon":1975},"/ja-jp/solutions/application-security-testing/","security and compliance","ShieldCheckLight",[1977,1981,1986],{"text":1978,"config":1979},"アプリケーションセキュリティテスト",{"href":1973,"dataGaName":1980,"dataGaLocation":1886},"Application security testing",{"text":1982,"config":1983},"ソフトウェアサプライチェーンセキュリティ",{"href":1984,"dataGaLocation":1886,"dataGaName":1985},"/ja-jp/solutions/supply-chain/","Software supply chain security",{"text":1987,"config":1988},"ソフトウェアコンプライアンス",{"href":1989,"dataGaName":1990,"dataGaLocation":1886},"/ja-jp/solutions/software-compliance/","software compliance",{"title":1992,"link":1993,"items":1998},"測定",{"config":1994},{"icon":1995,"href":1996,"dataGaName":1997,"dataGaLocation":1886},"DigitalTransformation","/ja-jp/solutions/visibility-measurement/","visibility and measurement",[1999,2003,2008],{"text":2000,"config":2001},"可視性と測定",{"href":1996,"dataGaLocation":1886,"dataGaName":2002},"Visibility and Measurement",{"text":2004,"config":2005},"バリューストリーム管理",{"href":2006,"dataGaLocation":1886,"dataGaName":2007},"/ja-jp/solutions/value-stream-management/","Value Stream Management",{"text":2009,"config":2010},"分析とインサイト",{"href":2011,"dataGaLocation":1886,"dataGaName":2012},"/ja-jp/solutions/analytics-and-insights/","Analytics and insights",{"title":2014,"type":1937,"items":2015},"GitLabが活躍する場所",[2016,2022,2028],{"text":2017,"config":2018},"大企業",{"icon":2019,"href":2020,"dataGaLocation":1886,"dataGaName":2021},"Building","/ja-jp/enterprise/","enterprise",{"text":2023,"config":2024},"スモールビジネス",{"icon":2025,"href":2026,"dataGaLocation":1886,"dataGaName":2027},"Work","/ja-jp/small-business/","small business",{"text":2029,"config":2030},"公共部門",{"icon":2031,"href":2032,"dataGaLocation":1886,"dataGaName":2033},"Organization","/ja-jp/solutions/public-sector/","public sector",{"text":2035,"config":2036},"価格",{"href":2037,"dataGaName":2038,"dataGaLocation":1886,"dataNavLevelOne":2038},"/ja-jp/pricing/","pricing",{"text":2040,"config":2041,"menu":2043},"関連リソース",{"dataNavLevelOne":2042},"resources",{"type":1937,"link":2044,"columns":2048,"feature":2132},{"text":2045,"config":2046},"すべてのリソースを表示",{"href":2047,"dataGaName":2042,"dataGaLocation":1886},"/ja-jp/resources/",[2049,2082,2104],{"title":2050,"items":2051},"はじめに",[2052,2057,2062,2067,2072,2077],{"text":2053,"config":2054},"インストール",{"href":2055,"dataGaName":2056,"dataGaLocation":1886},"/ja-jp/install/","install",{"text":2058,"config":2059},"クイックスタートガイド",{"href":2060,"dataGaName":2061,"dataGaLocation":1886},"/ja-jp/get-started/","quick setup checklists",{"text":2063,"config":2064},"学ぶ",{"href":2065,"dataGaLocation":1886,"dataGaName":2066},"https://university.gitlab.com/","learn",{"text":2068,"config":2069},"製品ドキュメント",{"href":2070,"dataGaName":2071,"dataGaLocation":1886},"https://docs.gitlab.com/","product documentation",{"text":2073,"config":2074},"ベストプラクティスビデオ",{"href":2075,"dataGaName":2076,"dataGaLocation":1886},"/ja-jp/getting-started-videos/","best practice videos",{"text":2078,"config":2079},"インテグレーション",{"href":2080,"dataGaName":2081,"dataGaLocation":1886},"/ja-jp/integrations/","integrations",{"title":2083,"items":2084},"検索する",[2085,2090,2095,2099],{"text":2086,"config":2087},"お客様成功事例",{"href":2088,"dataGaName":2089,"dataGaLocation":1886},"/ja-jp/customers/","customer success stories",{"text":2091,"config":2092},"ブログ",{"href":2093,"dataGaName":2094,"dataGaLocation":1886},"/ja-jp/blog/","blog",{"text":2096,"config":2097},"The Source",{"href":2098,"dataGaName":2094,"dataGaLocation":1886},"/ja-jp/the-source/",{"text":2100,"config":2101},"リモート",{"href":2102,"dataGaName":2103,"dataGaLocation":1886},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"title":2105,"items":2106},"つなげる",[2107,2112,2117,2122,2127],{"text":2108,"config":2109},"GitLabサービス",{"href":2110,"dataGaName":2111,"dataGaLocation":1886},"/ja-jp/services/","services",{"text":2113,"config":2114},"コミュニティ",{"href":2115,"dataGaName":2116,"dataGaLocation":1886},"/community/","community",{"text":2118,"config":2119},"フォーラム",{"href":2120,"dataGaName":2121,"dataGaLocation":1886},"https://forum.gitlab.com/","forum",{"text":2123,"config":2124},"イベント",{"href":2125,"dataGaName":2126,"dataGaLocation":1886},"/events/","events",{"text":2128,"config":2129},"パートナー",{"href":2130,"dataGaName":2131,"dataGaLocation":1886},"/ja-jp/partners/","partners",{"config":2133,"title":2136,"text":2137,"link":2138},{"background":2134,"textColor":2135},"url('https://res.cloudinary.com/about-gitlab-com/image/upload/v1777322348/qpq8yrgn8knii57omj0c.png')","#000","GitLabの最新情報","最新の機能と改善点に関する情報をお届けします。",{"text":2139,"config":2140},"最新情報を読む",{"href":2141,"dataGaName":2142,"dataGaLocation":1886},"/ja-jp/releases/whats-new/","whats new",{"text":2144,"config":2145,"menu":2147},"企業情報",{"dataNavLevelOne":2146},"company",{"type":1937,"columns":2148},[2149],{"items":2150},[2151,2156,2162,2164,2169,2174,2179,2184,2189,2194,2199],{"text":2152,"config":2153},"GitLabについて",{"href":2154,"dataGaName":2155,"dataGaLocation":1886},"/ja-jp/company/","about",{"text":2157,"config":2158,"footerGa":2161},"採用情報",{"href":2159,"dataGaName":2160,"dataGaLocation":1886},"/jobs/","jobs",{"dataGaName":2160},{"text":2123,"config":2163},{"href":2125,"dataGaName":2126,"dataGaLocation":1886},{"text":2165,"config":2166},"経営陣",{"href":2167,"dataGaName":2168,"dataGaLocation":1886},"/company/team/e-group/","leadership",{"text":2170,"config":2171},"チーム",{"href":2172,"dataGaName":2173,"dataGaLocation":1886},"/company/team/","team",{"text":2175,"config":2176},"ハンドブック",{"href":2177,"dataGaName":2178,"dataGaLocation":1886},"https://handbook.gitlab.com/","handbook",{"text":2180,"config":2181},"投資家向け情報",{"href":2182,"dataGaName":2183,"dataGaLocation":1886},"https://ir.gitlab.com/","investor relations",{"text":2185,"config":2186},"トラストセンター",{"href":2187,"dataGaName":2188,"dataGaLocation":1886},"/ja-jp/security/","trust center",{"text":2190,"config":2191},"AI Transparency Center",{"href":2192,"dataGaName":2193,"dataGaLocation":1886},"/ja-jp/ai-transparency-center/","ai transparency center",{"text":2195,"config":2196},"ニュースレター",{"href":2197,"dataGaName":2198,"dataGaLocation":1886},"/company/contact/#contact-forms","newsletter",{"text":2200,"config":2201},"プレス",{"href":2202,"dataGaName":2203,"dataGaLocation":1886},"/press/","press",{"text":2205,"config":2206,"menu":2207},"お問い合わせ",{"dataNavLevelOne":2146},{"type":1937,"columns":2208},[2209],{"items":2210},[2211,2214,2219],{"text":1893,"config":2212},{"href":1895,"dataGaName":2213,"dataGaLocation":1886},"talk to sales",{"text":2215,"config":2216},"サポートを受ける",{"href":2217,"dataGaName":2218,"dataGaLocation":1886},"https://support.gitlab.com","support portal",{"text":2220,"config":2221},"カスタマーポータル",{"href":2222,"dataGaName":2223,"dataGaLocation":1886},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":2225,"login":2226,"suggestions":2233},"閉じる",{"text":2227,"link":2228},"リポジトリとプロジェクトを検索するには、次にログインします",{"text":2229,"config":2230},"GitLab.com",{"href":1900,"dataGaName":2231,"dataGaLocation":2232},"search login","search",{"text":2234,"default":2235},"提案",[2236,2238,2243,2245,2249,2253],{"text":1917,"config":2237},{"href":1922,"dataGaName":1917,"dataGaLocation":2232},{"text":2239,"config":2240},"コード提案（AI）",{"href":2241,"dataGaName":2242,"dataGaLocation":2232},"/ja-jp/solutions/code-suggestions/","Code Suggestions (AI)",{"text":1953,"config":2244},{"href":1955,"dataGaName":1953,"dataGaLocation":2232},{"text":2246,"config":2247},"GitLab on AWS",{"href":2248,"dataGaName":2246,"dataGaLocation":2232},"/ja-jp/partners/technology-partners/aws/",{"text":2250,"config":2251},"GitLab on Google Cloud",{"href":2252,"dataGaName":2250,"dataGaLocation":2232},"/ja-jp/partners/technology-partners/google-cloud-platform/",{"text":2254,"config":2255},"GitLabを選ぶ理由",{"href":1930,"dataGaName":2256,"dataGaLocation":2232},"Why GitLab?",{"freeTrial":2258,"mobileIcon":2262,"desktopIcon":2267,"secondaryButton":2270},{"text":1888,"config":2259},{"href":2260,"dataGaName":1891,"dataGaLocation":2261},"https://gitlab.com/-/trials/new/","nav",{"altText":2263,"config":2264},"GitLabアイコン",{"src":2265,"dataGaName":2266,"dataGaLocation":2261},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203874/jypbw1jx72aexsoohd7x.svg","gitlab icon",{"altText":2263,"config":2268},{"src":2269,"dataGaName":2266,"dataGaLocation":2261},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203875/gs4c8p8opsgvflgkswz9.svg",{"text":2050,"config":2271},{"href":2272,"dataGaName":2273,"dataGaLocation":2261},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/ja-jp/get-started/","get started",{"freeTrial":2275,"mobileIcon":2279,"desktopIcon":2281},{"text":2276,"config":2277},"GitLab Duoの詳細について",{"href":1922,"dataGaName":2278,"dataGaLocation":2261},"gitlab duo",{"altText":2263,"config":2280},{"src":2265,"dataGaName":2266,"dataGaLocation":2261},{"altText":2263,"config":2282},{"src":2269,"dataGaName":2266,"dataGaLocation":2261},{"button":2284,"mobileIcon":2289,"desktopIcon":2291},{"text":2285,"config":2286},"/switch",{"href":2287,"dataGaName":2288,"dataGaLocation":2261},"#contact","switch",{"altText":2263,"config":2290},{"src":2265,"dataGaName":2266,"dataGaLocation":2261},{"altText":2263,"config":2292},{"src":2293,"dataGaName":2266,"dataGaLocation":2261},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1773335277/ohhpiuoxoldryzrnhfrh.png",{"freeTrial":2295,"mobileIcon":2300,"desktopIcon":2302},{"text":2296,"config":2297},"料金ページに戻る",{"href":2037,"dataGaName":2298,"dataGaLocation":2261,"icon":2299},"back to pricing","GoBack",{"altText":2263,"config":2301},{"src":2265,"dataGaName":2266,"dataGaLocation":2261},{"altText":2263,"config":2303},{"src":2269,"dataGaName":2266,"dataGaLocation":2261},{"title":2305,"button":2306,"config":2311},"エージェント型AIがソフトウェアデリバリーをどのように変革するかをご覧ください",{"text":2307,"config":2308},"6月18日のGitLab Transcend日本開催版に申し込む",{"href":2309,"dataGaName":2310,"dataGaLocation":1886},"/ja-jp/events/transcend/virtual/","transcend event",{"layout":2312,"disabled":2313},"release",false,{"data":2315},{"text":2316,"source":2317,"edit":2323,"contribute":2328,"config":2333,"items":2338,"minimal":2549},"GitはSoftware Freedom Conservancyの商標です。当社は「GitLab」をライセンスに基づいて使用しています",{"text":2318,"config":2319},"ページのソースを表示",{"href":2320,"dataGaName":2321,"dataGaLocation":2322},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":2324,"config":2325},"このページを編集",{"href":2326,"dataGaName":2327,"dataGaLocation":2322},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":2329,"config":2330},"ご協力をお願いします",{"href":2331,"dataGaName":2332,"dataGaLocation":2322},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":2334,"facebook":2335,"youtube":2336,"linkedin":2337},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[2339,2384,2437,2481,2514],{"title":2035,"links":2340,"subMenu":2355},[2341,2345,2350],{"text":2342,"config":2343},"プランの表示",{"href":2037,"dataGaName":2344,"dataGaLocation":2322},"view plans",{"text":2346,"config":2347},"Premiumを選ぶ理由",{"href":2348,"dataGaName":2349,"dataGaLocation":2322},"/ja-jp/pricing/premium/","why premium",{"text":2351,"config":2352},"Ultimateを選ぶ理由",{"href":2353,"dataGaName":2354,"dataGaLocation":2322},"/ja-jp/pricing/ultimate/","why ultimate",[2356],{"title":2205,"links":2357},[2358,2360,2362,2364,2369,2374,2379],{"text":2205,"config":2359},{"href":1895,"dataGaName":1896,"dataGaLocation":2322},{"text":2215,"config":2361},{"href":2217,"dataGaName":2218,"dataGaLocation":2322},{"text":2220,"config":2363},{"href":2222,"dataGaName":2223,"dataGaLocation":2322},{"text":2365,"config":2366},"ステータス",{"href":2367,"dataGaName":2368,"dataGaLocation":2322},"https://status.gitlab.com/","status",{"text":2370,"config":2371},"利用規約",{"href":2372,"dataGaName":2373,"dataGaLocation":2322},"/terms/","terms of use",{"text":2375,"config":2376},"プライバシーに関する声明",{"href":2377,"dataGaName":2378,"dataGaLocation":2322},"/ja-jp/privacy/","privacy statement",{"text":2380,"config":2381},"Cookie 優先設定",{"dataGaName":2382,"dataGaLocation":2322,"id":2383,"isOneTrustButton":161},"cookie preferences","ot-sdk-btn",{"title":1933,"links":2385,"subMenu":2394},[2386,2390],{"text":2387,"config":2388},"DevSecOpsプラットフォーム",{"href":1915,"dataGaName":2389,"dataGaLocation":2322},"devsecops platform",{"text":2391,"config":2392},"AI支援開発",{"href":1922,"dataGaName":2393,"dataGaLocation":2322},"ai-assisted development",[2395],{"title":2396,"links":2397},"トピック",[2398,2402,2407,2412,2417,2422,2427,2432],{"text":1953,"config":2399},{"href":2400,"dataGaName":2401,"dataGaLocation":2322},"/ja-jp/topics/ci-cd/","cicd",{"text":2403,"config":2404},"GitOps",{"href":2405,"dataGaName":2406,"dataGaLocation":2322},"/ja-jp/topics/gitops/","gitops",{"text":2408,"config":2409},"DevOps",{"href":2410,"dataGaName":2411,"dataGaLocation":2322},"/ja-jp/topics/devops/","devops",{"text":2413,"config":2414},"バージョン管理",{"href":2415,"dataGaName":2416,"dataGaLocation":2322},"/ja-jp/topics/version-control/","version control",{"text":2418,"config":2419},"DevSecOps",{"href":2420,"dataGaName":2421,"dataGaLocation":2322},"/ja-jp/topics/devsecops/","devsecops",{"text":2423,"config":2424},"クラウドネイティブ",{"href":2425,"dataGaName":2426,"dataGaLocation":2322},"/ja-jp/topics/cloud-native/","cloud native",{"text":2428,"config":2429},"コーディングのためのAI",{"href":2430,"dataGaName":2431,"dataGaLocation":2322},"/ja-jp/topics/devops/ai-for-coding/","ai for coding",{"text":2433,"config":2434},"エージェント型AI",{"href":2435,"dataGaName":2436,"dataGaLocation":2322},"/ja-jp/topics/agentic-ai/","agentic ai",{"title":2438,"links":2439},"ソリューション",[2440,2443,2445,2450,2454,2457,2460,2463,2466,2468,2471,2476],{"text":1978,"config":2441},{"href":1973,"dataGaName":2442,"dataGaLocation":2322},"Application Security Testing",{"text":1965,"config":2444},{"href":1949,"dataGaName":1950,"dataGaLocation":2322},{"text":2446,"config":2447},"アジャイル開発",{"href":2448,"dataGaName":2449,"dataGaLocation":2322},"/ja-jp/solutions/agile-delivery/","agile delivery",{"text":2451,"config":2452},"SCM",{"href":1962,"dataGaName":2453,"dataGaLocation":2322},"source code management",{"text":1953,"config":2455},{"href":1955,"dataGaName":2456,"dataGaLocation":2322},"continuous integration & delivery",{"text":2004,"config":2458},{"href":2006,"dataGaName":2459,"dataGaLocation":2322},"value stream management",{"text":2403,"config":2461},{"href":2462,"dataGaName":2406,"dataGaLocation":2322},"/ja-jp/solutions/gitops/",{"text":2464,"config":2465},"エンタープライズ",{"href":2020,"dataGaName":2021,"dataGaLocation":2322},{"text":2023,"config":2467},{"href":2026,"dataGaName":2027,"dataGaLocation":2322},{"text":2469,"config":2470},"公共機関",{"href":2032,"dataGaName":2033,"dataGaLocation":2322},{"text":2472,"config":2473},"教育",{"href":2474,"dataGaName":2475,"dataGaLocation":2322},"/ja-jp/solutions/education/","education",{"text":2477,"config":2478},"金融サービス",{"href":2479,"dataGaName":2480,"dataGaLocation":2322},"/ja-jp/solutions/finance/","financial services",{"title":2482,"links":2483},"リソース",[2484,2486,2488,2490,2494,2496,2500,2502,2504,2506,2508,2510,2512],{"text":2053,"config":2485},{"href":2055,"dataGaName":2056,"dataGaLocation":2322},{"text":2058,"config":2487},{"href":2060,"dataGaName":2061,"dataGaLocation":2322},{"text":2063,"config":2489},{"href":2065,"dataGaName":2066,"dataGaLocation":2322},{"text":2068,"config":2491},{"href":2492,"dataGaName":2493,"dataGaLocation":2322},"https://docs.gitlab.com/ja-jp/","docs",{"text":2091,"config":2495},{"href":2093,"dataGaName":2094,"dataGaLocation":2322},{"text":2497,"config":2498},"新着情報",{"href":2499,"dataGaName":2142,"dataGaLocation":2322},"/ja-jp/whats-new/",{"text":2086,"config":2501},{"href":2088,"dataGaName":2089,"dataGaLocation":2322},{"text":2100,"config":2503},{"href":2102,"dataGaName":2103,"dataGaLocation":2322},{"text":2108,"config":2505},{"href":2110,"dataGaName":2111,"dataGaLocation":2322},{"text":2113,"config":2507},{"href":2115,"dataGaName":2116,"dataGaLocation":2322},{"text":2118,"config":2509},{"href":2120,"dataGaName":2121,"dataGaLocation":2322},{"text":2123,"config":2511},{"href":2125,"dataGaName":2126,"dataGaLocation":2322},{"text":2128,"config":2513},{"href":2130,"dataGaName":2131,"dataGaLocation":2322},{"title":2515,"links":2516},"会社情報",[2517,2519,2521,2523,2525,2527,2529,2533,2538,2540,2542,2544],{"text":2152,"config":2518},{"href":2154,"dataGaName":2146,"dataGaLocation":2322},{"text":2157,"config":2520},{"href":2159,"dataGaName":2160,"dataGaLocation":2322},{"text":2165,"config":2522},{"href":2167,"dataGaName":2168,"dataGaLocation":2322},{"text":2170,"config":2524},{"href":2172,"dataGaName":2173,"dataGaLocation":2322},{"text":2175,"config":2526},{"href":2177,"dataGaName":2178,"dataGaLocation":2322},{"text":2180,"config":2528},{"href":2182,"dataGaName":2183,"dataGaLocation":2322},{"text":2530,"config":2531},"Sustainability",{"href":2532,"dataGaName":2530,"dataGaLocation":2322},"/sustainability/",{"text":2534,"config":2535},"ダイバーシティ、インクルージョン、ビロンギング（DIB）",{"href":2536,"dataGaName":2537,"dataGaLocation":2322},"/ja-jp/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":2185,"config":2539},{"href":2187,"dataGaName":2188,"dataGaLocation":2322},{"text":2195,"config":2541},{"href":2197,"dataGaName":2198,"dataGaLocation":2322},{"text":2200,"config":2543},{"href":2202,"dataGaName":2203,"dataGaLocation":2322},{"text":2545,"config":2546},"現代奴隷制の透明性に関する声明",{"href":2547,"dataGaName":2548,"dataGaLocation":2322},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"items":2550},[2551,2553,2556],{"text":2370,"config":2552},{"href":2372,"dataGaName":2373,"dataGaLocation":2322},{"text":2554,"config":2555},"Cookieの設定",{"dataGaName":2382,"dataGaLocation":2322,"id":2383,"isOneTrustButton":161},{"text":2375,"config":2557},{"href":2377,"dataGaName":2378,"dataGaLocation":2322},[2559],{"id":2560,"title":7,"body":1862,"config":2561,"content":2563,"description":1862,"extension":2567,"meta":2568,"navigation":161,"path":2569,"seo":2570,"stem":2571,"__hash__":2572},"blogAuthors/en-us/blog/authors/michael-friedrich.yml",{"template":2562},"BlogAuthor",{"name":7,"config":2564},{"headshot":2565,"ctfId":2566},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749659879/Blog/Author%20Headshots/dnsmichi-headshot.jpg","dnsmichi","yml",{},"/en-us/blog/authors/michael-friedrich",{},"en-us/blog/authors/michael-friedrich","lJ-nfRIhdG49Arfrxdn1Vv4UppwD51BB13S3HwIswt4",[],{"promotions":2575},[2576,2590,2601,2613],{"id":2577,"categories":2578,"header":2580,"text":2581,"button":2582,"image":2587},"ai-modernization",[2579],"ai","AIの真価、組織全体で発揮できていますか？","所要時間は5分以内です",{"text":2583,"config":2584},"AI成熟度スコアを確認する",{"href":2585,"dataGaName":2586,"dataGaLocation":2094},"/ja-jp/assessments/ai-modernization-assessment/","modernization assessment",{"config":2588},{"src":2589},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/qix0m7kwnd8x2fh1zq49.png",{"id":2591,"categories":2592,"header":2593,"text":2581,"button":2594,"image":2598},"devops-modernization",[1874,2421],"単にツールを管理するだけでなく、イノベーションを提供していますか？",{"text":2595,"config":2596},"DevOps成熟度スコアを確認しましょう",{"href":2597,"dataGaName":2586,"dataGaLocation":2094},"/ja-jp/assessments/devops-modernization-assessment/",{"config":2599},{"src":2600},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138785/eg818fmakweyuznttgid.png",{"id":2602,"categories":2603,"header":2605,"text":2581,"button":2606,"image":2610},"security-modernization",[2604],"security","スピードのためにセキュリティを犠牲にしていませんか？",{"text":2607,"config":2608},"セキュリティ成熟度スコアを確認しましょう",{"href":2609,"dataGaName":2586,"dataGaLocation":2094},"/ja-jp/assessments/security-modernization-assessment/",{"config":2611},{"src":2612},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/p4pbqd9nnjejg5ds6mdk.png",{"id":2614,"paths":2615,"header":2618,"text":2619,"button":2620,"image":2625},"github-azure-migration",[2616,2617],"migration-from-azure-devops-to-gitlab","integrating-azure-devops-scm-and-gitlab","チームはGitHubのAzure移行に対応できていますか？","GitHubはすでにAzureを基盤として再構築を進めています。それがあなたのチームにとって何を意味するのか、ご確認ください。",{"text":2621,"config":2622},"GitLabとGitHubの比較を見る",{"href":2623,"dataGaName":2624,"dataGaLocation":2094},"/ja-jp/compare/gitlab-vs-github/github-azure-migration/","github azure migration",{"config":2626},{"src":2600},{"header":2628,"blurb":2629,"button":2630,"secondaryButton":2634},"今すぐ開発をスピードアップ","DevSecOpsに特化したインテリジェントオーケストレーションプラットフォームで実現できることをご確認ください。\n",{"text":1888,"config":2631},{"href":2632,"dataGaName":1891,"dataGaLocation":2633},"https://gitlab.com/-/trial_registrations/new?glm_content=default-saas-trial&glm_source=about.gitlab.com/ja-jp/","feature",{"text":2205,"config":2635},{"href":1895,"dataGaName":1896,"dataGaLocation":2633},1779746102564]