Codex CLIのsubagentsを使って並列コードレビューを試す

Codex CLIで正式にsubagentsが使えるようになったので、実際のPRレビューで試してみました。

題材は拙作site2skill PR #7で、実装をPythonからRustへ完全書き換えたブランチで、56ファイル変更、diff 9185行のPRです。このPRは新興モデルのQwen3.5+Qwen Codeで生成したもので、指摘すべきアラが多いと想定して選びました。

筆者の環境はgpt-5.4(reasoning medium)の無料プランで、計測とログ分析はClaude Codeで行いました。

subagentsとは

Codex CLIが並列でエージェントをspawnしてタスクを分担する機能です。~/.codex/agents/にTOMLファイルを置くとカスタムエージェントを定義できます。

Subagents – Codex | OpenAI Developers
Use subagents and custom agents in Codex

内部の動きはセッションログ(~/.codex/sessions/以下のJSONL形式ファイル)で確認できます。spawn_agentイベントのagent_typeフィールドに、どのエージェントが使われたか記録されています。

何を試したか

Step1: 単一エージェント(ベースライン)

まずはカスタムエージェント定義なしで、普通にレビューを頼みました。

Review https://github.com/laiso/site2skill/pull/7 thoroughly.
This PR rewrites a Python CLI tool in Rust with PyPI binary distribution.
Focus on: security issues, performance claims validity, Rust best practices, and test coverage.
Provide a prioritized list of findings.

Step2: 並列subagents(最小限の指示)

次にカスタムエージェント定義なしのまま、「3つに分けて並列で」とだけ指示しました。

Review https://github.com/laiso/site2skill/pull/7 (Python to Rust rewrite).
Spawn 3 subagents in parallel:
- one for security review
- one for performance review
- one for code quality review
Wait for all, then summarize top findings from each with priority.

Step3: カスタムエージェント

最後に~/.codex/agents/に以下の3ファイルを配置してからセッションを起動しました。各エージェントに専門領域だけを見るようdeveloper_instructionsで絞っています。

# ~/.codex/agents/security-reviewer.toml
name = "security-reviewer"
description = "Rust code security reviewer focused on path traversal, zip-slip, and input sanitization."
model = "gpt-5.4-mini"
model_reasoning_effort = "high"
sandbox_mode = "read-only"
developer_instructions = """
You are a strict security reviewer for Rust code.
Focus ONLY on: path traversal, zip-slip, URL validation, sandbox escapes, input sanitization, unsafe blocks.
Ignore code style. Output: numbered list with severity (Critical/High/Medium/Low) and file:line references.
"""
# ~/.codex/agents/perf-analyst.toml
name = "perf-analyst"
description = "Performance analyst for Rust async code and benchmark validation."
model = "gpt-5.4-mini"
developer_instructions = """
You analyze performance characteristics of Rust async code.
Focus on: tokio patterns, memory leaks, regex caching, concurrency limits, benchmark methodology.
Output: numbered findings with evidence from the code.
"""
# ~/.codex/agents/rust-quality.toml
name = "rust-quality"
description = "Rust code quality reviewer for idioms, error handling, and module organization."
model = "gpt-5.4-mini"
developer_instructions = """
You review Rust code quality and idioms.
Focus on: error handling patterns, module organization, test coverage, dependency choices, clippy-level issues.
Output: ranked suggestions by impact.
"""

投入プロンプトはこれだけです:

Review PR #7 using Security Reviewer, Performance Analyst, and Rust Quality agents in parallel.
Merge findings into a single report with priorities.

計測方法

Codex CLIには非インタラクティブなExecモードもありますが、subagentsの動作観察や途中の許可ダイアログ操作が必要なため、今回はインタラクティブモード(TUI)で実行しました。そのため外部からtimeコマンド等で実行時間を計測できません。所要時間はセッションログのJSONLファイルから先頭/末尾のタイムスタンプの差分をClaude Codeでパースして算出しました。トークン(LLMの処理単位)消費とweekly limit(無料プランの週次利用上限)は、各Step実行前後にCodex CLIの/statusコマンドで定点観測しています。subagentの動作もセッションログのspawn_agentイベントをClaude Codeで抽出して確認しました。

数値結果

3つのStepの計測結果をまとめます。

Step1(単一) Step2(並列) Step3(カスタムエージェント)
所要時間 6分1秒 3分4秒 4分20秒
tokens 78.5K 62.3K 80.4K
weekly limit消費 4% 12% 12%
指摘数 5 9 11

並列レビュー時の動作(セッションログから抜粋)

Step2の実行ログを整形したものです。メインエージェントがPRを読んだ後、3つのsubagentを同時にspawnして、結果が返ってきたら統合しています。約3分で完了しました。

11:27:46  main   3観点で並列レビューを走らせます
11:27:50  main   PR メタデータ取得、3本のレビュータスクに必要な文脈を揃えます
11:28:05  spawn  agent_type=default (セキュリティ)
11:28:05  spawn  agent_type=default (パフォーマンス)
11:28:05  spawn  agent_type=default (品質)
11:29:13  done   subagent 1 完了
11:29:55  done   subagent 2 完了
11:30:09  done   subagent 3 完了
11:30:43  main   レビュー結果を統合して出力

Step3(カスタムエージェント定義あり)ではログのagent_typeが変わります。TOMLで定義した名前がそのまま使われています。

spawn  agent_type=security-reviewer
spawn  agent_type=perf-analyst
spawn  agent_type=rust-quality

並列化の効果

数値結果から、並列化によって何が変わったかを整理します。

所要時間は半減(6分→3分)、指摘数は倍増(5→9〜11)しました。一方でweekly limit消費は3倍に増加しています(4%→12%)。subagentごとにコンテキスト(会話履歴)をforkするため、API呼び出し総量が増えます。メインセッションのコンテキストウィンドウ使用量はむしろ減りました。結果の要約だけがメインに返るためです。

カスタムエージェント定義なしでも、Codexが自動でプロンプトを生成してビルトイン型(default/explorer等)にsubagentを分配します。並列化自体の効果は、カスタム定義なしでも得られます。

カスタムエージェントの効果

並列化自体の効果はStep2で確認できました。では、カスタムエージェント定義を加えたStep3にはさらに効果があるのか。切り分けるために、カスタムエージェント定義なしの並列実行も別途2回やって比較しました。定義なし版はweekly消費18〜21%で指摘7〜8件、カスタムエージェント版はweekly消費12%で指摘11件でした。数字だけ見ると改善していますが、N=1なのでばらつきと区別がつきません。

明確な差が出たのはセキュリティagentの未完了問題の解消です。

セキュリティagentの未完了問題

カスタムエージェントの効果が最も明確に現れたのは、この未完了問題の解消です。

並列subagentsは全agentの完了を待つので、一番遅いagentがボトルネックになります。今回セキュリティレビューが2回タイムアウトで未完了になりました。コード全体を横断的に読む必要があり、処理時間が他のagentより長くなります。メインエージェントは「応答待ちが続いているので要点出力に切り替えさせます」と出力して打ち切りました。

カスタムエージェント版では完了しました。developer_instructionsでスコープを絞ったことが寄与した可能性はありますが、実行ごとのばらつきで説明できる範囲でもあります。

運用Tips

実験中に気づいた運用上の注意点です。

  • カスタムエージェントはセッション起動時に読み込まれます。途中で~/.codex/agents/に追加しても認識されません。再起動が必要です。最初これにハマりました
  • セッションログ(~/.codex/sessions/)のタイムスタンプから所要時間を算出できます。Claude Codeに「ログからtimestamp抜いて」と頼めば一発です
  • /statusでコンテキストウィンドウ使用量とweekly limitを確認できます。これを細かく記録することで本記事にしました

検出の限界

ここまでsubagentsの利点を見てきましたが、限界もあります。

zip-slip(ZIPアーカイブ展開時にパスを細工して任意の場所にファイルを書き込む脆弱性)は全ステップで見逃しました。事後にClaude Codeでコードを読んで確認したら実際に脆弱性がありました。subagentsを何段重ねにしても見つけられない問題はあります。

まとめ

並列化自体は自動プロンプトで十分効果があります(時間半減、指摘倍増)。カスタムエージェント定義の追加効果は示唆的ですが、N=1では確定できません。

カスタムエージェント定義が効果を発揮したのは、スコープの広いタスク(セキュリティレビュー)の未完了を防げた点です。ただしzip-slipのように全ステップで見逃す問題もあります。

Codex CLIのsubagents機能は他のエージェントと比較すると、Rust実装による真のスレッドを使っているためか、OpenAIの最適化されたResponses APIのおかげなのか、並列処理はキビキビ動いて素早く終わる印象がありました(プラシーボの可能性もあります)。

Subscribe to laiso

Sign up now to get access to the library of members-only issues.
Jamie Larson
Subscribe