後編(全 2 編)。 前編「アーキテクチャを理解する」は、Pi のループ、ツール、フック、コンテキストの扱いを説明した。この編では、その柔軟性を信頼でき安全なワークフローに変えるために何を作り保守する必要があるかを扱う。単独でも読めるよう、短い要約を続けて置く。

この記事の読み方。 Pi は変化が速いため、主張にはラベルを付けている。

  • ドキュメント:公式ドキュメント、ソースコード、または作者自身の投稿に記載されている内容。主張のすぐ横にリンクを示す。
  • 観察:私が自分で体験したこと。管理されたテストではない。
  • 意見:私の解釈。
  • 提案:評価に値するアイデア。私がテストしたものでも、Pi が提供しているものでもない。

バージョン。 Pi に関する主張は @earendil-works/pi-coding-agent 1.3.0(2026 年 10 月 20 日に確認した時点の npm の latest タグ)、同日時点の Pi のドキュメントとリポジトリ、そして Claude Code と OpenAI Codex のドキュメント(および Codex のオープンソースリポジトリ、コミット e18a20d)に基づく。これらはいずれも変化が速いため、バージョン固有の記述はスナップショットとして読んでほしい。出力品質のベンチマークは一切行っておらず、本記事のどの記述も、どのエージェントがより良いコードを書くかを述べるものではない。

1. 自由のコスト

前編は一つの主張と一つの問いで終わった。主張はこうである。Pi は、開発者にコーディングエージェントの環境をより強く制御できる自由を与える。その自由は、統合、信頼性、セキュリティ、保守の責任を開発者に移す。 前編はそのドキュメント上の側面を示した。小さなループ、8 つの組み込みツール、すべてのツール呼び出しを検査またはブロックできるフック、ツリーとして保存されるセッション、コンパクション、そして外部からエージェントを動かすためのいくつかのインターフェース(端末、print、JSON、RPC、SDK)である。問いはこうである。それを、信頼できるものに変えるには何が要るのか。

拡張性だけでは、信頼性もセキュリティも保守性も得られない。それらは、その上に何を構築するかで決まる性質である。この編は、その問いを生んだ実験をたどる。順に、オーケストレーションとオブザーバビリティ、実行が止まったときの回復、信頼・パーミッション・分離の違い、プロジェクトへの組み込み、実際に何が確かめられ何が確かめられていないか、そして追加の作業が見合うのはいつか、である。各主張には前編と同じラベル(ドキュメント、観察、意見、提案)を付けている。

2. オーケストレーションとサブエージェント

オーケストレーションは、追加の作業が最初に表れる場所である。単一のエージェントループには、1 つのモデル、1 つのコンテキスト、1 本のツール呼び出しの流れがある。エージェントが別のエージェントに委任するようになると、タスクの分解、コンテキストと結果の受け渡し、エージェントの境界をまたぐ失敗の経路、そして子が何をしているのかを見る必要を引き受けることになる。Pi はこれを要求しないし、すべてのワークフローにサブエージェントが要るわけでもない。以下は、これを作ろうとして私が突き当たったことと、Pi のドキュメントにある部品がどこで終わり、自分の設計がどこから始まるかである。

オーケストレーターを作る

観察 自分が望む形では見つからなかった機能を得るために、拡張機能で実験した。

  • オーケストレーター
  • 長いセッションや大量のコンテキストを伴う作業を扱うサブエージェント
  • パーミッションを制限することを意図した拡張機能
  • サンドボックスとして、Pi を Docker コンテナ内で動かす試み

これらは実装上の困難やエラーに突き当たった。それでも、エージェントが内部でどう動くのかについて、多くのことを教えてくれた。私が最も正確に説明できる困難は、サブエージェントが何をしているのかを見るのが難しかったことで、これは次の小節で掘り下げる。個々のエラーはここでは列挙しない。Docker の試みについても構成や結果は報告しないため、この記事のどの記述も、それを Pi のセキュリティの検証として扱っていない。

順序は、個々のエラーよりも重要である。サブエージェントを試した動機は、長いセッションと大きなコンテキストだった。望む形のものが見つからなかったので、自分で作ってみようとした。作る手間の先に残ったのは、委任をめぐる問いだった。オーケストレーターは何に責任を持つのか、サブエージェントの結果や失敗はどこへ行くのか、そしてそれを誰が見られるのか。この節の残りは、その問いに沿って進む。これは私自身の実験をどう読んだかである。これらの部品を作ったときに何が起きたかについての解釈であり、Pi に委任の機能が一般に欠けているという主張ではない。

ドキュメントが前提としている内容は別の話であり、確認できる。Pi は「サブエージェントなし」を選択として明示している。拡張機能ガイドにもサブエージェントへの言及はないが、拡張機能が ctx.executeTool() で他のツールを実行することは可能であり、そのネストした呼び出しは、モデルが発行した呼び出しと同じ tool_call ハンドラを通る(extensions guide)。つまりオーケストレーターは設定するものではなく、設計するものである。

委任が見えにくくなるとき

観察 サブエージェントを実験しているとき、それらが何をしているのかを見守るのが難しいと感じた。メイン側のエージェントは作業が進行中だと報告し続けられるのに、私にはサブエージェントが実際に何をしているのか、ほとんど、あるいはまったく見えなかった。

この観察が指しているのは、一般的な進捗の信号と、実際の実行を検査できることとの間のギャップである。前者を作って後者を省くのは簡単だ。私の拡張機能に特定の仕組みがあった、あるいはなかったと主張するつもりはない。以下は、委任するシステムを信頼したいなら何が必要か、という話である。

意見 サブエージェントを起動するだけならオーケストレーションにすぎない。それを理解するには、さらに多くが必要になる。

  • ステータスと進捗の違い。 「実行中」はタスクが存在することを示すだけである。ファイルを読んでいるのか、モデルを待っているのか、止まっているのかは分からない。
  • 実行イベント。 子の最終的な答えだけでなく、そのツール呼び出しと中間結果。
  • 階層をまたぐトレース。 子の行動を、それを引き起こした親のリクエストに結びつける方法。
  • 失敗の扱い。 タイムアウト、停滞したタスク、そして沈黙以外の形で親に届くエラー経路。

Pi の構成要素はこの一部をカバーしている。セッションはメッセージ、ツール呼び出しと結果、コンパクションを記録する JSONL ツリーとして保存され、JSON モードと RPC モードはエージェントイベントをストリーミングする(How Pi works)。拡張機能 API はさらに細かいフックを加える。ライフサイクルイベントには agent_start、turn_start、message_update、agent_settled があり、ツール実行には tool_execution_start、tool_execution_update(呼び出し中の進捗)、tool_execution_end がある。ctx.executeTool() を通じて行われるネストした呼び出しでは、これらのイベントが parentToolCallId を持つ(extensions guide)。SDK は、1 つのプロセス内セッションのイベント用に session.subscribe() を公開している(SDK)。これらは構成要素であり、別々の子 Pi プロセスをまたいでどう振る舞うかは検証していない。私が読んだドキュメントには、それ以外のダッシュボード、メトリクス、トレースの仕組みの記述はない。子プロセスがその記録に有用な形で現れるかどうかは、どう起動するかに依存する。それは自分が引き受ける設計上の判断である。

フック自体は、発火順に前編の図(拡張機能フック)で示した。ここで問うのは、それがオーケストレーターに何をもたらすかである。

意見 このセクションの主張に対して、私が見つけた最も具体的な裏づけである。エージェントを見るための継ぎ目は、個々のツール呼び出しやプロバイダイベントに至るまで存在する。ドキュメントが記述していないのは、それらから作られた完成したビューである。つまり問いは、Pi を観察できるかどうかではない。そのビューを誰が作るか、である。

まとめると、3 つの性質は別々のものであり、エージェントは最初の 1 つだけを持って残りを持たないことがありうる。

  • 実行: 行動を実行できる。
  • オブザーバビリティ: 何をしているのか、どこにいるのかが分かる。
  • 制御: 介入し、方針を変え、あるいは停止できる。

オブザーバビリティのない委任は、行動できるのに理解しやすくはないシステムを生む。これは設計についての結論であり、すべてのマルチエージェントシステムがそうなっているという主張ではない。

制御にも、ドキュメントに載っている側面がある。人はステアリング、フォローアップのキュー投入、中断ができ(前編のセクション 3)、プログラムも RPC で同じことができる。それらが作用するのは Pi のセッションである。親エージェントがそれを子にどう適用するか、いつそうすべきか、子がそれをどう扱うかは、私が設計しなければならない判断である。Pi にそれができないと主張しているわけではない。

3. 回復と信頼性:実行が止まるとき

観察 通常の使用中に、予期しない失敗に遭遇した。モデルの応答エラー、誤ったツールの使い方、そしてコンテキストウィンドウの枯渇である。場合によっては、実行は、タスクを続行できる形で自動的に回復することなく止まった。私が介入し、問題を診断し、実行状態や自分のやり方を調整して、再開する方法を見つけなければならなかった。そのやり方で解決できた失敗もあり、その場合は軽微な中断を経てタスクは進んだ。ほかの失敗では、タスクがまったく進まなくなった。

これで 2 つのグループができる。その違いこそが有用な部分である。診断して再開することで私が回復できた中断と、タスクを止めた失敗である。個々の失敗(応答エラー、ツールの誤用、コンテキストの枯渇)をどちらかのグループに割り当てることはしないし、そのどれかが一般に回復不可能だと言うつもりもない。失敗が自力で再開するかどうかは、モデル、プロバイダー、設定、そして拡張機能に依存し、私の記述はそのどれがどれに当たるかを対応づけていない。

これはセクション 2 の問題とは別のものである。オブザーバビリティが問うのは、エージェントが何をしているのかが見えるかどうかである。リカバリーが問うのは、その行っていることが壊れたときに何が起きるかである。エージェントがタスクを実行する能力と、実行が失敗したときに回復する能力は別の性質である。システムは前者に非常に優れていても、後者については何も語らないことがありうる。

Pi に欠けているものを誇張すべきではない。Pi にはリカバリーの挙動があり、ドキュメントがそれを記述している。

ドキュメント Pi には “transient failures”(一時的な失敗)に対する、エージェントレベルの自動リトライがあり、デフォルトで有効で、デフォルトは 3 回、指数バックオフは 2 秒から始まり 60 秒で頭打ちになる(Settings)。また自動コンパクションもあり、空きコンテキストが予備量(デフォルトで 16,384 トークン)を下回ると開始される。プロバイダーのオーバーフローまたは長さのエラーが出た場合、Pi はリカバリー用のコンパクションを実行し、そのうえで再試行を新しい実行として開始する。そのリカバリー用コンパクションが失敗またはキャンセルされた場合、Pi は “schedules no internal retry”(内部リトライをスケジュールしない)(Compaction)。ツール自体が失敗した場合、その失敗はモデルへのエラー結果になる(extensions guide)。

したがって、正確な言い方は「Pi は決して回復しない」ではない。一部の失敗には組み込みの経路があり、その経路の一部には上限がある。リトライはデフォルトで 3 回であり、コンパクション自体が失敗した場合は、再試行なしで終わるコンパクションのリカバリー経路である。私が読んだドキュメントには、どのエラーが一時的とみなされるかは列挙されていない。また、ツールを使い続けて誤用するモデルや、再開したい状態で終わった実行に対する組み込みの処理も記述されていない。私の失敗のどれかが組み込みの経路の内側にあったのか外側にあったのかは分からない。それらが Pi の欠落だったと主張するつもりもない。デフォルトを使い果たした、あるいはデフォルトが当てはまらなかったケースかもしれない。

図は、それらの経路と、それぞれが尽きたときに何が起きるかを描いている。実線の枠はドキュメントにある挙動である。破線の行は、私が読んだ範囲の空白であり、Pi についての主張ではない。

TRIGGER BUILT-IN RESPONSE WHEN THAT RUNS OUT Transient provider failure documented as “transient” Agent-level retry on by default, 3 attempts backoff from 2 s, capped at 60 s Attempts used up: the failure is yours to handle Context overflow, or an early length stop Recovery compaction, then one retry as a fresh run Compaction fails or is cancelled: no internal retry Free context below the reserve (16,384 tokens) Auto-compaction checked between turns and before a new prompt The summary is lossy: detail leaves the model's view A tool call fails or a tool_call handler throws Error result to the model a handler failure blocks the call Up to the model whether it changes approach Repeated tool misuse, or a run stuck in a bad state Nothing described in the docs I read You inspect, adjust, resume Dashed: absent from the pages I read, not proof that Pi has nothing here. Solid green: documented behavior.

意見 特定の失敗がひとりでに再開するかどうかよりも、「回復した」が何を意味するかを誰が決めるかの方が重要である。信頼できるリカバリーには、たいてい次についての判断が必要になる。

  • リトライ戦略。 どのエラーをリトライするか、何回行うか、いつリトライをやめてエスカレーションするか。
  • エラー処理。 不正なツール呼び出しを、モデルへのメッセージにするのか、停止にするのか、あなたへの要求にするのか。
  • コンテキスト管理。 ウィンドウがいっぱいになったとき、何が要約され、あるいは捨てられるのか、そしてタスクがそれを乗り越えられるのか。コンパクションは以前の作業を要約するため、要約が何を残すかが、その後のエージェントの知識を形作る。
  • 明示的なリカバリーのワークフロー。 毎回その場しのぎで対応するのではなく、失敗した状態を検査し、調整し、再開するための定められた方法。

ドキュメント その最後の行を外部から組み立てるための部品も、ドキュメントにある。RPC では、制御するプログラムが自動リトライと自動コンパクションのオンとオフを切り替え(set_auto_retry、set_auto_compaction)、進行中のリトライを中断し(abort_retry)、必要に応じてコンパクトし(compact)、compaction_start、compaction_end、summarization_retry_* イベントを監視できる。プロセス内では、session_before_compact が Pi の要約を置き換えられ、session_compact_failed はコンパクションが失敗または中断されたときに発火する。(RPC、Compaction)

提案 RPC 上の小さな監督プロセス。組み込みのリトライを動かし、コンパクションとリトライのイベントを監視し、実行が失敗状態で落ち着いたときに、自分で書いたポリシーを適用する。たとえば明示的な指示つきでコンパクトする、モデルを切り替える、タスクを自分に戻す、といったものだ。これは作っても試してもいない。

Pi はこの一部を提供しており、コンパクション後も元のエントリを保持するセッションツリーは、再開の拠り所となる有用な記録である(How Pi works)。リトライやより安全なコンパクションを加えるパッケージは探していないので、そうしたものが存在するか、どれほどうまく動くかは言えない。統合型の製品では、これらの判断のより多くがすでに下されているかもしれない。Pi では、デフォルトは出発点にすぎず、残りは自分で設計し、テストし、保守するものである。これは前と同じトレードオフを、失敗のケースから見たものである。エージェントをカスタマイズする自由には、うまく回復するという保証は付いてこない。

4. パーミッション、信頼、分離:本当の境界

パーミッションを制限する拡張機能と、セクション 2 の Docker の試みは、エージェントを実際に制限しているものは何か、という問いを提起した。プロンプト、制限されたツール、コンテナは別々のものであり、区別すると見通しがよくなる。

以下のループは概念的なものであり、Pi の内部を示す図ではない。

context → model → tool request → runtime → execution environment → tool result → updated context

5 つの層が、それぞれ「パーミッション」と呼ばれうる。

  1. プロセスの権限。 エージェントを実行している OS ユーザーができること。プロセス内のあらゆるものはこれによって制約される。
  2. アプリケーションレベルのチェック。 ツール呼び出しを検査し、許可・確認・拒否を行う、エージェント内のルール。
  3. プロジェクトディレクトリの境界。 作業ディレクトリが囲いなのか、単なる出発点なのか。
  4. ツールの能力。 構造化された read はパスで囲い込める。シェルは任意のプログラムを実行でき、そのプログラムは任意のファイルを開ける。
  5. 分離。 コンテナ、VM、OS のサンドボックスは、子プロセスを含むプロセス自体を制限する。

ドキュメント Pi のセキュリティページは、Pi が “can read, change, and execute files with the permissions of the account that started it”(起動したアカウントの権限でファイルを読み取り、変更し、実行できる)こと、そして “does not ask for approval before every tool call”(ツール呼び出しのたびに承認を求めることはない)ことを述べている。作業フォルダはリソース探索とデフォルトのツールの場所を決めるが、コマンドが他のパスに到達することを制限しない。トランスクリプトを見ること、プロジェクトを信頼すること、変更をレビューすることはセキュリティ境界ではない。推奨される選択肢は、狭くて短命な認証情報を使い、可能ならネットワークを制限したうえで、Pi 全体をコンテナ、VM、またはサンドボックス内で実行することである。

ドキュメント ソースでは、read.ts は相対パスまたは絶対パスを受け取り、ファイルが読み取り可能かどうかだけをチェックする。それが呼び出すパスのヘルパー(path-utils.ts と utils/paths.ts)は、絶対パスはそのまま保ち、相対パスは作業ディレクトリに結合する。どちらも結果を作業ディレクトリと比較しない。私はこのコードを main ブランチ(パッケージのバージョンは 1.3.0)で読んだが、Pi のツールを実行してはおらず、ファイルが読まれうるすべての経路をたどってもいない。テスト済みの結果として扱わないでほしい。

これはドキュメントと整合する。デフォルトでは、アプリケーションレベルの囲いはない。ただし、プロンプトがないことが、あらゆる構成で無制限のアクセスを証明するわけではない。拡張機能はチェックを追加できる。tool_call イベントは呼び出しを書き換えたりブロックしたりでき、例外を投げたハンドラは呼び出しをフェイルクローズでブロックする(extensions guide)。プロンプトがあることも、包括的なセキュリティを証明するわけではない。Claude Code のドキュメントによれば、Read と Edit の deny ルールは、組み込みのファイルツール、Bash 内で認識するファイルコマンド(cat など)、リダイレクトの対象に適用される。名前を指定せずにファイルを読むコマンド(grep -r pattern . など)や、自分でファイルを開くスクリプトには適用されない。OS レベルの強制については、ドキュメントはそのサンドボックスを挙げ、bypassPermissions モードはコンテナや VM のような隔離された環境でのみ使うべきだとしている(permissions)。つまり、どちらのドキュメントも、本当の境界として隔離を指している。違いは、あなたとその境界の間に置かれるデフォルトにある。Claude Code の Manual モード(設定値 default)では、ファイルの編集、シェルコマンドの実行、ネットワークへのアクセスを伴うほとんどの操作の前に確認を求める(permission modes)。cat や ls のような組み込みの読み取り専用コマンドは、permissions.blockReadsOutsideWorkingDirectories を有効にしない限り、作業ディレクトリ外のパスに対しても確認なしで実行される。ドキュメントはまた、v2.1.283 以降は auto モードがターミナルと VS Code の対話セッションの開始モードで、分類器があなたの代わりに操作を審査すると述べている。Pi は何も求めない。私が比較したのはドキュメントであって挙動ではない。この記事のために Claude Code を実行してはいない。

SETUP APPLICATION CHECK OS SANDBOX WHAT THE CALL CAN REACH Pi, default (1.3.0) none (no tool_call gate) none (runs on the host) Everything the OS user can access Pi, hardened (proposal) your extension blocks / confirms container / VM only project mounted The mounted project + scoped credentials Claude Code, Manual mode rules + mode asks: edits, shell, web optional (sandbox setting) OS user's access, filtered by approvals Application checks inspect tool names, paths, and command text. An OS sandbox restricts the process itself, so it also covers child processes and scripts that open files indirectly. The outermost layer that exists is the one that holds when the inner ones are bypassed.

見落としやすい Pi 固有の詳細が 2 つある。

  • プロジェクトトラストはサンドボックスではない。 それが制御するのは、フォルダが提供するものである。プロジェクト設定と MCP サーバー、.pi 以下の拡張機能、スキル、プロンプトテンプレート、テーマ、システムプロンプトファイル、プロジェクトで設定されたパッケージ。それは “prevents a folder from silently loading executable extensions before you approve it”(承認する前にフォルダが実行可能な拡張機能を黙って読み込むのを防ぐ)ものであり、セキュリティページは、それが “does not limit what tool calls can access or affect”(ツール呼び出しがアクセスしたり影響を与えたりできるものを制限しない)と述べている。拡張機能は “inside the Pi process with the same operating-system permissions”(同じ OS 権限で Pi プロセス内)で動くため、信頼された拡張機能はプロンプト、ツール呼び出し、ファイル、セッション履歴を読める(extensions guide)。コンテキストファイル(AGENTS.md、CLAUDE.md)はトラストなしで読み込まれる(Configuration)。クローンしたリポジトリ内の指示は、信頼したかどうかに関係なくモデルに届きうる。特定のモデルが悪意のある指示に従うかどうかは別の問いであり、私はテストしていない。

  • Docker は道具であり、保証ではない。 コンテナが実際に何を分離するかは、何をマウントするか、どの認証情報を渡すか、ネットワークが開いているか、どのユーザーで動くかに依存する。ホームディレクトリと広いスコープの API キーをマウントしたコンテナは、問題を移しただけで、解決してはいない。これは一般的なコンテナのセキュリティの話であり、私の試みから得た結果ではない(Docker security)。

要するに、3 つの問いが混同されている。トラストが問うのは、フォルダ自身のリソースを読み込んでよいかどうかである。パーミッションが問うのは、実行中のプロセスとそのツールが技術的に何をできるかである。分離が問うのは、エージェントや拡張機能が不正に動作しても、何が手の届かないところに残るかである。Pi のドキュメントは 1 つ目を提供し、2 つ目を記述し、3 つ目は利用者に任せている。私は、これらのページと 1 つのツールのソースを読んだ以上に Pi のセキュリティを監査してはいない。

Pi のコンテナ化ガイドが提供するもの

「コンテナを持ち込め」だけでは薄い助言であり、ドキュメントはそれより先まで踏み込んでいる。コンテナ化ガイドは 4 つの選択肢を述べており、それらは境界の内側に何が入るかで異なる。

Whole-process isolation Docker, Docker Sandboxes, OpenShell container / sandbox boundary Pi process agent loop, extensions, and every extension tool Built-in tools and ! commands read, write, edit, bash, grep, find, ls Host only what you mount or pass in crosses over Tool-only isolation Gondolin extension host Pi process extensions and extension tools still run here, unless they delegate local Linux micro-VM Built-in tools and ! commands Same question for both: What did you mount, which credentials did you pass in, and is the network open? Env-var keys are visible inside the container, and may be inside Gondolin's VM. Docker Sandboxes can keep the real key on the host. A read-write mount lets Pi change host files directly.

ドキュメント Plain Docker は Pi プロセス全体をコンテナで動かし(ガイドの Dockerfile は node:24-bookworm-slim が基盤)、作業フォルダを /workspace にマウントし、キーを -e で渡し、設定とセッションを名前付きボリュームに保持する。Docker Sandboxes は管理されたサンドボックスで Pi を動かし、本物の認証情報はホストに残り、プロキシが、設定されたホストへのリクエストでそれを置き換える。OpenShell は、ファイルシステム、プロセス、ネットワーク、認証情報、推論のポリシーを備えたローカルまたはリモートのサンドボックスで Pi を動かす。リモートのものはフォルダをバインドマウントしないので、ファイルは明示的に転送する。Gondolin は、Pi をホストで動かしたまま、組み込みツールと ! コマンドをローカルの Linux マイクロ VM に振り向ける拡張機能である。他の拡張機能のツールは、処理を委譲しない限りホストで動き続ける。ガイドは、アクセスを意図していない限り ~/.pi/agent(認証情報、設定、拡張機能、セッション)をマウントしないよう警告し、コンテナに渡した環境変数は内部から見えること、そして Gondolin のコマンドはホストの環境を継承するため、環境変数で設定したキーが VM 内で見える可能性があることを述べている。さらに、VM の境界を迂回しうるツールを追加する前に、Gondolin の例を確認するよう求めている。(Containerization)

意見 これはパーミッションの話を具体的にし、選択を鋭くする。プロセス全体の分離は、私が読み込む拡張機能も閉じ込める。私の実験が拡張機能だったので、これは重要である。ツールだけの分離は組み込みツールを囲うが、私の拡張機能のコードと、それが登録するツールはホストに残す。どちらも間違いではなく、答えている問いが違う。どちらにしても作業は現実にある。1 つ選び、狭くマウントし、認証情報の範囲を絞り、Pi と拡張機能が変わっても設定が動き続けるようにする。だから下の提案は、プロセス全体の分離に傾いている。

提案 実際の作業で Pi を使うなら、ドキュメントが最も強力な選択肢として挙げているコンテナから始め、プロジェクトだけをマウントし、スコープを絞ったキーを渡す。そのうえで、可視化とミスの検出のために tool_call 拡張機能を追加するが、それは壁としてではない。この構成はテストしていない。

5. Pi をプロジェクトに組み込む:ワークフローと統合

エージェントからワークフローへ

すでに AI 支援開発を使っているプロジェクトで Pi を使うことを考え始めると、別の問題が現れた。能力はワークフローではない。有能なエージェントは、プロジェクトがどうビルドされるか、どの規約に従うか、どのテストが通らなければならないか、いつ作業が完了とみなされるかを知らない。

この節の残りは、エージェントをプロジェクトに組み込むのに何がかかるかの分析である。一般的な推論であり、私の特定のプロジェクトで何かがうまくいかなかったという報告ではない。

意見 能力は、エージェントに何ができるかを述べる。ワークフローは、作業がどう進み、どんな制約のもとにあり、完了がどう確認されるかを述べる。 既存のプロジェクトにエージェントを組み込むと、次のような問いが生じる。

  • コンテキスト。 プロジェクトのルールはどこにあるか。Pi は AGENTS.md と CLAUDE.md をコンテキストファイルとして読み込むので、既存の指示は引き継げる。それでも指示は強制ではない。
  • ツール。 既存のスクリプトは bash を通じて動く。安価だが、モデルは README や --help からそれらを学ばなければならない。
  • 調整。 他の AI 支援プロセスが同じリポジトリに触れるなら、いつ何を実行するかを誰が決めるのか。
  • 検証。 テストとレビューが確実に実行されることを誰が保証するのか。指示は助言にすぎない。チェックを強制できるのは、拡張機能か外部のハーネス(RPC、JSON モード、SDK)である。
  • 引き継ぎ。 エージェントはどうやって完了を伝え、次の人やプロセスはそれをどうやって知るのか。

ここで、これまでの節が交わる。可観測性、回復、パーミッション境界は、突き詰めればどれもワークフローの問いである。システムは何をするのか、誰かがそれを見られるのか、そして何がそれを制約するのか。統合型の製品は、こうした判断の多くをすでに下している。Pi では、あなたが下す。

組み込みの WebUI がないことは、統合の選択肢がないことを意味しない

Pi には統合された Web インターフェースがなく、私はそれを欠落として感じた。しかし、UI がないことと、インターフェースがないことは別である。前編では、同じエージェントを動かす方法として、インタラクティブ、print、JSON、RPC、プロセス内 SDK を挙げた。

したがって、Web フロントエンドが妨げられているわけではない。RPC や SDK の上に構築できる。インターフェースが担わないのは、その周りの作業である。UI の描画、ストリーミング出力の処理、セッション状態の保持、エラー時の動作の決定(セクション 3)、そしてエージェントのライフサイクル管理。SDK のページは、扱わなければならない細かな点にも言及している。agent_end は 1 回の実行の終了を示し、agent_settled は Pi が自動的には続行しないことを知らせる。私はそのようなフロントエンドを作っていないので、これは私の経験ではなく、ドキュメントに記載された範囲の記述である。

作業が潜んでいるのは細部である(RPC)。図は、RPC インターフェース越しの 1 回のプロンプトの形と、素朴なクライアントが間違えやすい部分を示している。

Your client pi --mode rpc prompt {id: “1”} response {id: “1”, success: true} accepted, queued or handled: not finished message_update (repeats while streaming) agent_end one run is over compaction / retry events, maybe another run optional: retry, recovery, steering, follow-up agent_settled Pi will not continue on its own

ドキュメント レコードは LF で終わる JSON オブジェクトで、クライアントは LF だけで分割すべきである。ドキュメントは、Node.js の readline が U+2028 と U+2029 でも分割する点を警告している。これらは JSON 文字列の内部に現れうる。stdout にはプロトコルのレコードだけが流れ、診断は stderr に出る。コマンドは省略可能な id を取り、レスポンスがそれを繰り返すが、レスポンスは順不同で届きうる。成功した prompt のレスポンスは、プロンプトが受理、キュー投入、または処理されたことを意味し、作業が終わったことではない。data.disposition が "handled" なら、実行は始まらず、agent_settled も続かない。クライアントはプロンプトを送る前に購読すべきで、stdin を閉じると整然とした終了が要求される。コマンドセットはセッション(fork、clone、get_tree、export_html)、モデル(set_model、set_thinking_level)、compact を含むため、フロントエンドは TUI が行うことの多くを提供できる。拡張機能のダイアログと通知は RPC 経由で転送されるが、カスタムコンポーネントは転送されない。(RPC、extensions guide)

意見 最初のレスポンスを完了とみなすクライアントや、汎用の行リーダーで読むクライアントは、デモでは動いても、後で誤動作しうる。どれも難しくはないが、WebUI がないことで自分に回ってくるのは、まさにこの種の細部である。

意見 WebUI がないことは、トレードオフ全体の縮図である。既成の体験はなく、独自のものを作ることはできるが、作った人がそれを引き受ける。この省略が思想的な選択だったと主張するつもりはない。私が読んだドキュメントはそれを述べていない。

6. 実際に観察したことと得られた教訓

ここまでの各節は、ドキュメントに書かれた挙動、私の解釈、提案が混ざっている。この節では、私が実際に何をし何を見たか、そしてそこから何が言えるかを取り出す。私の実験は探索的なものであり、バージョン、構成、ログ、再現手順は記録していない。したがって、以下は完全な意味でのケーススタディではない。持っていない詳細を後から再構成するより、そう述べるほうがよいと考える。

ケース 1:委任された作業を見る

  • 目的。 長いセッションと大きなコンテキストを、サブエージェントへの委任で扱うこと。オーケストレーターは拡張機能として自作した。
  • 環境。 自作の拡張機能。Pi のバージョン、拡張機能のコード、設定は記録していない。冒頭の 1.3.0 というスナップショットは、2026 年 10 月 20 日に確認したドキュメントのものであり、実験で実行したバージョンとは限らない。
  • 観察。 観察 メインエージェントは作業が進行中だと報告し続けられる一方で、サブエージェントが実際に何をしているのか、私にはほとんど、あるいはまったく見えなかった。
  • 解釈。 一般的な進捗の信号は、実行を検査できることとは別である。委任するシステムを信頼するには、状態と進捗の区別、実行イベント、階層をまたぐトレース、失敗の扱いが要る。Pi はそのための継ぎ目(ツールとプロバイダーのイベント、parentToolCallId、session.subscribe())をドキュメント化しているが、私が読んだドキュメントには、それらから作られた完成したビューの記述はない。
  • 限界。 作り手は 1 人、構成は 1 つで、統制された比較はない。私の拡張機能に、Pi の部品なら提供できたはずの仕組みが欠けていたかどうかは言えない。別々の子 Pi プロセスをまたいでイベントがどう振る舞うかも確認していない。Pi の委任一般についての主張ではない。

ケース 2:止まった実行

  • 目的。 なし。計画した実験ではなく、通常の利用中に起きたことである。
  • 環境。 記録していない。
  • 観察。 観察 モデルの応答エラー、誤ったツールの使い方、コンテキストウィンドウの枯渇。場合によっては、タスクを続けられる形で回復しないまま実行が止まり、私が原因を調べ、状態や進め方を調整して再開する必要があった。軽い中断のあとで解決した失敗もあれば、タスクがまったく進まなくなったものもあった。
  • 解釈。 タスクを実行する能力と、失敗から回復する能力は別の性質である。Pi は上限付きの自動リトライと回復用のコンパクションをドキュメント化しているので、私が見たことは機能の欠落の証拠ではない。
  • 限界。 個々の失敗を組み込みの経路に対応づけていないため、どれがその内側でどれが外側だったか、既定値を使い切ったのかは言えない。ログも再現手順もない。

Docker の試みが示さないこと

Pi を Docker コンテナの中で動かし、サンドボックスにする試みをした。構成も結果も記録していないため、コンテナによる分離を支持する証拠にも否定する証拠にもならない。セクション 4 のコンテナに関する記述はすべて、Pi のドキュメントと一般的なコンテナセキュリティに基づくもので、私の試みに基づくものではない。

ここから持ち帰ること

  • 提案 委任する前に、子が何をしているかを見るビューを誰が持つのかを決める。
  • 提案 最初の失敗が起きる前に、自分のワークフローにとって「回復した」が何を意味するかを決める。リトライ、不正なツール呼び出しの扱い、コンパクションで何が残るか、いつ止めて人に戻すか。
  • 提案 コンテナを境界として扱い、フックはガードレールとして扱う。
  • 提案 実験するときは、Pi のバージョン、拡張機能のコードと設定、失敗したリクエストやログを記録し、結果を再現し検証できるようにする。

これらの推奨は、上に述べた実験の範囲を超えては、私自身がテストしていない。

7. Pi と統合型コーディングエージェントのどちらを選ぶか

ここまでの分析は、いくつかの観点にまとめられる。下の表は、それぞれの選択が合いやすい場面を示す。順位づけではなく、コーディングの品質については何も述べない。それは私がテストしていないことである。

観点 Pi が合いやすいのは… 統合型エージェントが合いやすいのは…
カスタマイズの必要性 エージェント環境の形そのものが要件であるとき。独自のツール、フック、コンテキストの扱い、プロバイダー。 同梱のツール、プラグイン、フックで必要なことがすでに足りているとき。
組み込みの統合度 計画、委任、承認を自分で組み立てる用意があるとき。 それらの判断を代わりに下し、保守してほしいとき。
ツールと実行の制御 モデルに何を見せるかを正確に選び(--tools、exposure)、すべての呼び出しにフックをかけたいとき。 パーミッションルールとモードで十分な制御が得られるとき。
セキュリティとデプロイ 境界を自分で用意するとき。マウントを絞り、認証情報のスコープを限定したコンテナ、VM、サンドボックス。Pi はこれらの選択肢をドキュメント化しているが、強制はしない。 Codex がドキュメント化しているような、承認ポリシーや OS レベルのサンドボックスが製品に付属していてほしいとき。
オブザーバビリティとデバッグ イベントとセッションツリーから必要なビューを作れるとき。 形を変えられることより、完成したビューが重要なとき。(統合型製品に組み込まれたビューは比較していない。)
エンジニアリングと保守のコスト 拡張機能のコードを所有し、Pi の変化に合わせて動かし続けられるとき。パッケージ名の変更が一例である。 誰かに保守を任せたいとき。
ワークフローの複雑さ ワークフローが特殊で、既成のものだと回り道が要るとき。 一般的なワークフロー(計画、委任、承認)で足りるとき。

意見 注意点が 2 つある。第一に、列は排他的ではない。Claude Code にはフック、スキル、サブエージェント、プラグイン、MCP があり、Pi には MCP とスクリプト用のツールがあるため、両者は近づきつつある(各製品が何を同梱しているかは前編で比べた)。第二に、正しい選択は、普遍的な順位ではなく、チームの要件と制約による。左の列の要件を挙げられないなら、セットアップと保守のコストが低い統合型のほうが、おそらく妥当な既定の選択である。

8. 結論:自由は、いつ責任に見合うのか

意見 すぐに使えるエージェント以上のものが欲しいときに、Pi を使う。エージェントがどう動くのかを理解し、そのワークフローを作り変え、能力を拡張し、その周りに構築するシステムに責任を持ちたいときに使う。上の各節は、その責任が私の実験でどのようなものだったかを示している。委任を設計すること、それを観測可能にすること、実行が失敗したときに回復が何を意味するかを決めること、パーミッション境界をどこに置くかを決めること、そしてエージェントをプロジェクトのワークフローに合わせることである。

セットアップと保守をできるだけ少なくして作業を進めることが優先なら、より統合された製品の方が良い選択かもしれない。制御より利便性を選ぶことに本質的な間違いはなく、すべてを自分で作ることが本質的に優れているわけでもない。

Pi を使ったことで、見過ごしやすいトレードオフをより意識するようになった。自由は責任を移す。 システムに対する制御が大きいほど、その制御を信頼できる作業体験に変えるために下すべき判断も増える。Pi 自身のドキュメントも、パーミッションについて同じことを述べている。コンテナを持ち込め、と述べ、そのやり方を 4 通り示している。

したがって、問いは Pi が他のコーディングエージェントより優れているかどうかではない。それは私がテストしていないことであり、この記事はそれについて何も主張しない。問いは、Pi が提供する自由が、引き受けてもよいと思う追加の作業に見合うかどうかである。前編は、強力なモデルと薄い環境という話から始めた。薄い環境こそが提供されるものであり、それを埋める作業が代価である。

自由は、自分の望むシステムを構築する能力を与える。利便性は、そもそもシステムを構築するのに費やす時間を減らしてくれる。

意見 私は今、コーディングエージェントを、生成するコードの品質だけで評価してはいない。パーミッション境界がどこにあるか、どう失敗しどう回復するか、何をしているのかを見られるか、そしてプロジェクトのワークフローに組み込むのに何がかかるかも見ている。それらは、ここまでの節が繰り返し戻ってきた問いである。

実際には:

  • 提案 要件から始める。エージェント環境を形作ること(ツール、フック、コンテキスト、動かし方)そのものが要件なら、Pi は候補になる。そうでないなら、統合型エージェントから始める。
  • 提案 始める前に、オブザーバビリティ、回復、境界を誰が所有するかを決め、その答えを書き留める。壁として扱うのはフックではなくコンテナである。
  • 提案 範囲を絞った 1 つのワークフローで Pi を試し、結果を再現し評価できるよう、バージョンと構成を記録する。

参考文献

Pi:公式ドキュメントとソース

比較と背景