OpenAI Codex CLIの内部動作を分析:エージェントループとプロンプトキャッシュ戦略
(openai.com)要約:
- エージェントループ(Agent Loop)の構造: Codex CLIがユーザー入力、モデル推論、ツール実行を調整しながら実際の作業を行う循環的プロセスを詳しく説明します。
- プロンプト構成とResponses API: システム命令、ツール定義、ローカル環境コンテキストが
Responses APIのJSONペイロードへ変換される過程と、データフローを分析します。 - 性能最適化と状態管理: プロンプトキャッシュ(Prompt Caching)を最大化するための戦略、コンテキストウィンドウ制限を克服するための会話圧縮(Compaction)技術、そしてZDR(Zero Data Retention)のためのステートレス設計原則を扱います。
詳細要約:
OpenAIのエンジニアリングチームは、ローカルソフトウェアエージェントであるCodex CLIの中核ロジック「エージェントループ(Agent Loop)」の動作原理を深く分析した技術記事を公開しました。この記事は、ユーザーの命令を受け取り、モデルと相互作用し、ツールを実行し、結果を返すまでのライフサイクル全体を技術的観点から説明しています。
1. エージェントループ(The Agent Loop)
エージェントループは、ユーザーの入力を受け取り、作業を完了するまでモデルと相互作用する循環構造です。
- プロセス: ユーザー入力 -> プロンプト生成 -> モデル推論(Inference) -> (ツール呼び出し要求 -> ツール実行 -> 結果を添付 -> 再推論)の反復 -> 最終応答。
- ターン(Turn): ユーザーの入力から、モデルが最終的にユーザーへメッセージ(Assistant Message)を送るまでの過程を1つの「ターン」と呼びます。この過程でエージェントは数百回のツール呼び出し(例:
lsの実行、ファイル修正など)を行うことがあります。
2. モデル推論とResponses API
Codex CLIはResponses APIを通じてモデルと通信します。このAPIはhttps://chatgpt.com/backend-api/codex/responses、https://api.openai.com/v1/responses、またはローカルホスト(Ollamaなど)に設定できます。
初期プロンプトの構成(Building the Initial Prompt)
プロンプトは単なるテキストではなく、instructions、tools、inputなどで構成された構造化データです。
- Instructions: システムまたは開発者メッセージとして、モデルの行動指針を定義します。(例:
~/.codex/config.toml設定ファイルを参照) - Tools: モデルが利用できるツール定義の一覧です。シェル(shell)実行、計画更新(update_plan)、Web検索、そしてユーザー定義のMCP(Model Context Protocol)サーバーツールなどが含まれます。
- Input: モデルに渡される実際のデータ一覧です。ここにはサンドボックス権限設定、プロジェクトごとの指示、そして現在の作業ディレクトリ(cwd)やシェル種類のような**環境コンテキスト(Environment Context)**が含まれます。
JSONペイロード例:
{
"type": "message",
"role": "user",
"content": [
{
"type": "input_text",
"text": "README.mdにアーキテクチャ図を追加して"
}
]
// ... 事前に定義された環境コンテキストや権限設定なども一緒に送信される
}
3. ツール実行とデータフロー
モデルがツール呼び出し(Function Call)を要求すると、エージェントはそれを実行し、結果を会話履歴に追加して再びモデルを呼び出します。
ツール実行後の再リクエストJSON例:
[
/* ... 以前の入力項目 ... */
{
"type": "reasoning", // モデルの推論過程(CoT)
"summary": [...],
"encrypted_content": "gAAAAABpaDW..." // 暗号化された推論内容
},
{
"type": "function_call",
"name": "shell",
"arguments": "{\"command\":\"cat README.md\",\"workdir\":\"/Users/mbolin/code/codex5\"}",
"call_id": "call_8675309..."
},
{
"type": "function_call_output", // ツール実行結果
"call_id": "call_8675309...",
"output": "<p align=\"center\"><code>npm i -g @openai/codex</code>..."
}
]
以前のプロンプトが新しいプロンプトの**正確な接頭辞(Prefix)**になるように構成することが重要です。これは後述するプロンプトキャッシュ効率を左右します。
4. 性能上の考慮事項: キャッシュとZDR
会話が長くなるほどプロンプトサイズは線形に増加し、コストとレイテンシが高まります。
-
プロンプトキャッシュ(Prompt Caching): OpenAIモデルは、プロンプト前半が一致した場合(Prefix Match)、以前の計算結果を再利用して高速化します。
-
キャッシュミス(Cache Miss)の防止: ツール一覧の変更やサンドボックス設定の変更などが会話途中で発生するとキャッシュが壊れる可能性があります。これを防ぐため、Codexは設定変更を既存メッセージの修正ではなく、**新しいメッセージの追加(Append)**方式で処理します。
-
ステートレス(Stateless)とZDR:
previous_response_idのようなパラメータを使わず、毎回全文脈を送信します。これはサーバーにデータを保存しない**Zero Data Retention(ZDR)**ポリシーを順守するためです。暗号化された推論内容(encrypted_content)をクライアントが受け取り、それを再度サーバーへ送る方式によって、サーバーは状態を保存せずに過去の推論コンテキストを復元できます。
5. コンテキストウィンドウ管理(Compaction)
トークン制限を超えないようにするため、Codexは/responses/compactエンドポイントを使って会話履歴を圧縮します。単なる要約ではなく、モデルの潜在的理解(Latent understanding)を保持するencrypted_contentを含む圧縮済み項目リストを返し、既存の入力を置き換えます.
2件のコメント
Claude Codeは最初から公式ドキュメントにあったのに…
https://code.claude.com/docs/en/how-claude-code-works