\ ポイント最大11倍! /

GUI 版 Codex でメイン/サブエージェントの状態遷移を追えるようにする観測設計

Some visuals are licensed via Canva Pro (includes commercial rights).
Usage complies with Canva’s license terms at the time of use.
License policy: canva.com/policies/content-license-agreement

X
     この記事はプロモーションを含みます

GUI 版 Codex では、メインエージェントからサブエージェントを生やし、処理が終われば close する流れ自体はすでにあります。
それでも実際の動きが追いにくいのは、操作できることと、途中の 状態 を自然に読めることが別問題だからです。

個人の ローカル 環境で扱うなら、必要なのは大がかりな改造ではありません。
spawn、wait、close のつながりを壊さずに拾い、表示と内部の 同期 が崩れた場所だけを見抜けるようにするほうが、はるかに実用的です。

見た目を派手にするだけでは、観測 しやすくなりません。
必要なのは、どの child が生まれ、どの edge でつながり、どの status に変わったのかを、あとからでも追跡できる 可視化 です。
その観点で設計すると、GUI IPC は公開 API の代わりではなく、壊さずに様子を読むための観測レイヤとして位置付けやすくなります。

前提の置き方

GUI IPC は公式公開 API と同列に扱わず、個人利用の観測レイヤとして使う。OpenAI プロダクトを改変して機能を書き換える話ではなく、表示と実状態の差を切り分けるための設計として整理する。

Content

生成と終了はできるのに、動作状況が直感的に見えない

PCモニターの前で、黒いTシャツとデニムスカート姿の銀髪のアニメ調の人物が椅子に座っている。

メイン/サブエージェントの生成と終了だけなら、それほど迷いません。
迷いやすいのは、その間に何が起きているかを UI から一続きの流れとして読み取れない場面です。
処理が遅いのか、待機に入ったのか、すでに終わっているのに表示だけ残っているのかが分かりにくいと、確認のほうに時間を取られます。

メイン/サブエージェントの流れ自体はある

まず押さえたいのは、流れそのものが欠けているわけではない点です。
親エージェントが spawn し、child が走り、必要なら wait が入り、最後に close されるという筋道は存在します。
問題は、その筋道が利用者の視界では分断されやすいことです。

たとえば child が生成された事実だけを見れば「動いている」と判断できますが、その child が今も実行中なのか、完了済みなのか、すでに close 済みなのかまでは分かりません。
流れがあることと、流れを読めることは別だと切り分けると、違和感の正体がかなり明確になります。

マコト

spawn したのに、いま何をしている child なのか分からない

設計側:操作の成功ではなく、遷移の追跡に必要な情報がまだ表へ出ていない状態です

でも途中状態が追いにくい

途中状態が追いにくい理由は、単発のイベントは拾えても、連続した変化がつながって見えにくいからです。
spawn の瞬間だけ観測しても、その child が wait 後にどう確定したか、close 後にどう扱うべきかまでは読み切れません。

とくに厄介なのは、ラベルの見え方と内部 status がずれる場面です。
表示上はまだ残っているのに、内部では終了していたり、逆にラベルだけ先に出ていて、実体としての child 情報がまだ仮状態だったりします。
このズレを UI の見た目だけで判断すると、誤診しやすくなります。

見えているもの実際に知りたいことずれたときに起きる誤解
label / nicknameどの child を見ているか別 child を同一対象だと思い込む
node の存在まだ生きているか完了済みでも動作中に見える
close 後の表示いつ閉じたかUI の残像を実状態と誤認する

だからビジュアルで見えるようにしたかった

必要だったのは、開発者だけが分かる内部情報の羅列ではありません。
親子関係、遷移順、確定済みか保留中かを直感的に読める観測面です。
どの child が provisional で、どの時点で確定し、どこで close に到達したかが一目で見えれば、バグ修正も説明も同じ基盤で進められます。

何が観測しづらさの原因だったのか

複数モニターのあるデスクで、銀髪のアニメ調の人物が作業画面を見ながら椅子に座っている。

観測しづらさは、単に GUI が簡素だから起きるわけではありません。
生成、待機、終了がそれぞれ別のタイミングで確定し、さらに表示名と内部識別子のズレまで重なるためです。

spawn だけでは child の実態が追えない

spawn はもっとも分かりやすい起点です。
親から child が生まれたことを拾えるため、観測を始める入口としては重要です。
ただし、その時点で得られる情報だけでは、あとで同じ child を安定して追えるとは限りません。

生成直後は、label や nickname が先に見えても、内部の紐付けがまだ provisional なことがあります。
その段階で「もう追跡できた」と扱うと、wait 後の確定情報と食い違い、同じ child を別物として表示したり、逆に別 child を同一扱いしたりします。

spawn 監視の落とし穴

spawn は必要条件だが十分条件ではない。child を一意に追える保証は、wait や close まで含めた後続イベントで補完される。

wait と closeAgent まで含めて状態が確定する

実運用では、child は生まれた瞬間より、その後どう終わったかのほうが重要です。
wait を観測しないと、処理中から完了への切り替わりが取れません。
closeAgent を観測しないと、表示から消えるべき対象がいつ閉じたのか確定できません。

この3つは別イベントですが、観測上はひとつの遷移列として扱うほうが安定します。

  1. spawn で child の出現を拾う
  2. wait で結果と status の変化を拾う
  3. closeAgent で終了確定と表示上の後始末を結び付ける

この流れがつながると、途中で止まって見える child が、本当に停止したのか、単に観測が欠けたのかを判断しやすくなります。

表示名と内部状態のズレが起きやすい

人間はまず label や nickname を見ますが、同期の軸として頼りになるのは status、親子関係、edge のほうです。
見た目の名前は説明には便利でも、状態判定の基準にするとズレに引っ張られます。

そこで有効だったのは、表示系と判定系の役割を分ける考え方です。

項目主な役割優先度
label / nickname人が識別しやすくする
status実行中・完了・保留の判定
edge / child 関係親子の由来を追跡する

見た目の名前はあとから整えても構いません。
先に status と edge を揃えておくと、「表示は正しそうなのに実際は別物だった」という事故を減らしやすくなります。

観測可能性を上げる設計方針

ブラウザ上の暗色 UI に、親ノードから5つの子ノードが点線でつながるエージェントグラフが表示されている。

観測可能性を上げるときに重要なのは、UI を豪華にすることではありません。
何を一次情報として扱い、何を補助表示として扱うかを先に決めることです。

表示より状態同期を優先する

最初に揃えるべきなのは、画面の賑やかさではなく状態同期です。
child が存在するのに edge が欠けている、close 済みなのに node が残る、label だけ更新されて status が古いまま、といった症状はすべて同期不整合として扱えます。

この見方に切り替えると、調整対象がはっきりします。

  • 先に直すものは status と親子関係
  • 後から整えるものは label や色分け
  • 迷ったら表示の便利さより追跡の一貫性を優先する

同期が揃っていれば、見た目が簡素でも原因を追えます。

単発イベントではなく遷移の鎖として見る

spawn、wait、close を独立した通知として扱うと、どこかでイベントを取りこぼした時点で追跡が切れます。
そこで有効だったのが、単発イベントではなく、ひとつの child に紐づく遷移の鎖として扱う設計です。

遷移の見方何が分かるか切り分けやすい不具合
点として見るその瞬間に何が起きたか生成直後の欠落
鎖として見るどこで確定が止まったかwait 未反映、close 未反映

spawn が見えたのに wait が来ないなら、実行停滞か観測欠落を疑えます。
wait は来たのに close が来ないなら、終了後の片付けか描画側の反映漏れを疑えます。
問題を「存在するかしないか」ではなく、「どの段で鎖が切れたか」で見られるようになります。

個人利用前提の線引きを先に決める

この種の設計では、どこまでやるかの線引きも重要です。
公開 API として安定提供されているわけではない領域を、製品機能の延長として扱うと期待値がずれます。
個人利用の観測レイヤと割り切ることで、説明すべきことと伏せるべきことの境界も引きやすくなります。

先に決めておく線引き

  • 目的は内部状態の観測であり、機能改変ではない
  • ローカルで再現できる範囲の説明を優先する
  • ソース非公開でも理解できるロジック説明に寄せる
  • 壊れにくさを優先し、過度な自動化は狙わない

記事として重要なのは「何をフックしたか」そのものより、「なぜその情報を拾う必要があったか」と「どこまでを安全圏として扱う設計なのか」を先に整理することです。

どうデバッグしたか

机に向かった銀髪のアニメ調の人物が、明るい部屋でキーボードに手を置いている。

観測面を整える作業では、見えないものを当て勘で決めるより、拾える情報を少しずつ増やして矛盾を潰すほうが安定します。
とくに child、edge、status の3点がつながるまでは、異常と断定せず保留を残す考え方が役に立ちます。

分類仕様補足
アプリの用途Codex Desktop のスレッド状態ビューア親エージェント / サブエージェントの関係、実行状態、最新メッセージを可視化
フロントエンド言語TypeScript / TSXsrc/*.ts, src/*.tsx で実装
フロントエンド基盤React 19react, react-dom を使用
ビルド基盤Vite 8開発サーバーと本番ビルドに使用
UI 表示純 CSSsrc/App.css, src/index.css を使用
Markdown 表示react-markdown + remark-gfmMarkdown と GFM を描画
バックエンド言語Node.js の JavaScript(ESM, .mjsserver/*.mjs で実装
バックエンド方式Node 標準 http サーバーExpress などは未使用
通信方式REST + SSE/api/bootstrap/api/events を使用
開発時プロキシVite の /api プロキシhttp://127.0.0.1:4317 に転送
データ参照Codex Desktop の状態 DB~/.codex/state_5.sqlite を前提
必要ツールsqlite3 CLIREADME で前提条件として記載
パッケージ管理npmpackage-lock.json あり
型チェックTypeScript project referencestsconfig.json から各設定を参照
LintESLint 9React Hooks / React Refresh プラグインあり
テストNode 標準テストnode --test を使用
開発起動npm run devVite と Node サーバーを並列起動
本番起動npm run build && npm run startdist を Node サーバーで配信
既定ホスト127.0.0.1ローカル専用構成
開発ポート5173 / 43175173 がフロント、4317 がバックエンド
実行時前提Codex Desktop 利用環境GUI IPC / desktop probe 連携を前提

GUI IPC のパッチで child と edge を拾う

最初の改善点は、child の存在だけでなく、どの親から派生したかを edge として拾えるようにしたことです。
child 単体しか見えないと、同時に複数の spawn が起きたときに由来が追えません。
edge を取れるようになると、Agent Graph 上で親子の連鎖が初めて意味を持ちます。

ここで大切なのは、表示用データを直接信じすぎないことです。
GUI IPC から拾う情報は観測材料として使い、確定判定は後続イベントで補います。

provisional child を wait / closeAgent で確定化する

spawn 直後の child を provisional として保持し、wait や closeAgent を受けてから確定情報に寄せる設計はかなり効きます。
このやり方なら、生成直後に情報が足りない child を無理に完成形として描かなくて済みます。

実際の流れは次のように考えると整理しやすくなります。

  1. spawn 時点では child 候補として登録する
  2. wait 到着時に結果と status を反映する
  3. closeAgent 到着時に終了済みとして扱い、必要なら表示も閉じる

この順序を守ると、「早く見せたい」という理由で未確定情報を本採用してしまう事故を減らせます。

壊れた状態を異常ではなく保留として扱う

観測系でつまずきやすいのは、中間状態をすぐ異常扱いしてしまうことです。
spawn だけ見えて wait がまだ来ていない child は、壊れているのではなく未確定なだけかもしれません。
close が遅れている表示も、片付け待ちの保留と考えたほうが実態に合う場合があります。

この考え方に変えると、デバッグの姿勢も穏やかになります。

  • 情報不足の段階では provisional を維持する
  • 確定イベント不足と本当の不整合を分けて扱う
  • 保留時間が長すぎる対象だけを異常候補として見る

保留という状態を設けると、観測面が実態より先走りしにくくなります。

実際に何が見えるようになったか

窓際でスマートフォンの一覧画面を指し示す銀髪のアニメ調の人物が、椅子に座っている。

観測設計が効いてくると、単に node が増えるだけでは終わりません。
どの child がどの親から生まれ、どの status を経て、どこで close されたかまで一本の線で追えるようになります。

child の生成から完了、close までを追える

もっとも大きい変化は、child が「出た」「消えた」だけでなく、その間の流れごと追えるようになることです。
生成直後の provisional、wait 後の確定、close 後の終了が分かれるだけで、表示の意味が大きく変わります。

追える段階判断しやすくなること
生成どの親から child が生えたか
実行中まだ待つべき対象か
完了処理は終わったが表示が残っているだけか
close 後UI の残像か、本当に閉じていないのか

この粒度で追えると、待つべき child と放置してよい残像を区別しやすくなります。

Agent Graph がデバッグ UI から観測装置に変わる

Agent Graph の価値は、グラフっぽく見えることではありません。
親子関係、時系列、確定度をまとめて読めることで、デバッグ用の断片表示から、継続的な観測装置へ役割が変わる点にあります。

じぴ子

観測したい側:派手な見た目より、今どこで止まっているかが一目で分かるほうが助かる

マコト

設計側:だから node を増やすより、edge と status の整合を優先します

この変化があると、表示は説明の補助ではなく、切り分けそのものになります。

どこを見ればズレの原因を切り分けられるか

観測面が整ったあとでも、毎回全部を見る必要はありません。
ズレを切り分けるなら、確認点はある程度固定できます。

  1. child が spawn で登録されているか
  2. edge が親と正しく結び付いているか
  3. wait で status が更新されたか
  4. closeAgent 後に終了扱いへ切り替わったか
  5. label / nickname が実体と食い違っていないか

label の違和感だけを先に追うと泥沼になりがちですが、親子関係と status から詰めると、表示ズレなのか実体ズレなのかを短時間で分けられます。

まとめ

白い椅子に座った銀髪のアニメ調の人物が、左のモニターとキーボードに向かって手を伸ばしている。

GUI 版 Codex でメイン/サブエージェントの動作状況が追いにくいのは、生成や終了の機能が足りないからではありません。
spawn、wait、close のあいだにある遷移が、利用者の目には鎖として見えにくいからです。

そのため、改善の中心は UI 演出ではなく観測設計になります。
GUI IPC を個人利用の観測レイヤとして扱い、child、edge、status の同期を優先し、未確定なものは provisional として保留する。
この方針にすると、壊れたように見える状態と、本当に壊れている状態を切り分けやすくなります。

この観点で見ると、spawn が見えた時点で追跡できたと判断するのは早すぎます。
wait と close まで含めて 1 本の遷移として扱ってはじめて、child の実体と表示の意味が安定します。

また、label や nickname は見やすさのために有効でも、切り分けの基準としては補助情報にとどまります。
観測設計の中心に置くべきなのは status と edge の整合であり、その順序を守ることで、GUI 上の違和感は「何となくおかしい表示」ではなく、「どこで同期が崩れたかを追える問題」として扱えるようになります。

よくある質問

GUI IPC を観測に使うのは危険ではないのか

公開 API と同じ前提で扱うのは危ういですが、個人利用の観測レイヤとして線引きし、機能改変ではなく状態把握に限定するなら扱い方はかなり明確になります。

spawn だけ追えば child の動作状況は分かるのか

十分ではありません。child の実体が安定するのは wait や closeAgent まで含めた遷移列で見たときなので、spawn だけでは表示と実状態のズレを取りこぼしやすくなります。

label や nickname を主軸に見てもよいのか

見やすさの補助としては有効ですが、同期判定の主軸には向きません。観測設計の中心は status と edge の整合に置くほうが、切り分けが安定します。

Agent Graph は見た目のための UI なのか

本質は装飾ではなく観測です。親子関係、遷移順、確定状態をまとめて見られるようになると、どこで同期が崩れたかを切り分けるための装置として機能します。

  • URLをコピーしました!

この記事を書いた人

makotoのアバター makoto Blogger&YouTuber

サーバー管理者として17年ほど仕事でサーバー触ってました。
www,mail,dns,sql各鯖をすべてFreeBSDで運用してましたが現世ではかなりレアなタイプになるみたいですね笑

viやシェルスクリプトとかperlとかgccとかFreeBSDとか実はbashよりtcshが好きとか時々寝ぼけるのは
その名残でしょう。

今まで縁の下の力持ち的な他人のためにプログラムを書き他人のためにサーバー構築し他人のためにWEBサイトを創る的な世界から
自分の好きなことに集中できる環境は実に気持ち良いですね。
現役は引退済みなので難しいことはやりませんしやれません。

現在 ほぼ自由人。

Content