pi-ai、pi-agent-core、pi-tui をどのように統合し、AI エージェント機能を実装しているかを説明します。
概要
OpenClaw は pi SDK を使って、AI コーディングエージェントをメッセージング Gateway アーキテクチャへ組み込みます。pi をサブプロセスとして起動したり、RPC モードを使ったりするのではなく、createAgentSession() を通じて pi の AgentSession を直接 import し、インスタンス化します。この組み込み方式には、次の利点があります。
- セッションのライフサイクルとイベント処理を完全に制御できる
- カスタムツールを注入できる(メッセージング、サンドボックス、チャンネル固有のアクションなど)
- チャンネルやコンテキストごとにシステムプロンプトをカスタマイズできる
- 分岐や compaction を含むセッション永続化をサポートできる
- フェイルオーバー付きのマルチアカウント認証プロファイルローテーションを使える
- プロバイダーに依存しないモデル切り替えができる
パッケージ依存関係
| Package | Purpose |
|---|---|
pi-ai | コア LLM 抽象化: Model、streamSimple、メッセージ型、プロバイダー API |
pi-agent-core | エージェントループ、ツール実行、AgentMessage 型 |
pi-coding-agent | 高レベル SDK: createAgentSession、SessionManager、AuthStorage、ModelRegistry、組み込みツール |
pi-tui | ターミナル UI コンポーネント(OpenClaw のローカル TUI モードで使用) |
ファイル構成
コア統合フロー
1. 組み込みエージェントの実行
メインエントリポイントはpi-embedded-runner/run.ts の runEmbeddedPiAgent() です。
2. セッション作成
runEmbeddedAttempt()(runEmbeddedPiAgent() から呼び出される)の内部では、pi SDK を使用します。
3. イベント購読
subscribeEmbeddedPiSession() は pi の AgentSession イベントを購読します。
message_start/message_end/message_update(ストリーミング中のテキスト/思考)tool_execution_start/tool_execution_update/tool_execution_endturn_start/turn_endagent_start/agent_endauto_compaction_start/auto_compaction_end
4. プロンプト送信
セットアップ後、セッションに対してプロンプトを送ります。images 経由で渡します。過去の履歴ターンを再走査して、画像ペイロードを再注入することはありません。
ツールアーキテクチャ
ツールパイプライン
- ベースツール: pi の
codingTools(read、bash、edit、write) - カスタム置き換え: OpenClaw は bash を
exec/processに置き換え、sandbox 向けに read / edit / write をカスタマイズ - OpenClaw ツール: messaging、browser、canvas、sessions、cron、gateway など
- チャンネルツール: Discord / Telegram / Slack / WhatsApp 固有のアクションツール
- ポリシーフィルタリング: profile、provider、agent、group、sandbox のポリシーでツールを絞り込む
- スキーマ正規化: Gemini / OpenAI の実装上の癖に合わせてスキーマを調整
- AbortSignal ラップ: 中断シグナルを尊重するようにツールをラップ
ツール定義アダプター
pi-agent-core のAgentTool は、pi-coding-agent の ToolDefinition とは異なる execute シグネチャを持ちます。pi-tool-definition-adapter.ts の adapter が、その差分を吸収します。
ツール分割戦略
splitSdkTools() はすべてのツールを customTools 経由で渡します。
システムプロンプトの構築
システムプロンプトはbuildAgentSystemPrompt()(system-prompt.ts)で構築されます。Tooling、Tool Call Style、安全ガードレール、OpenClaw CLI リファレンス、Skills、Docs、Workspace、Sandbox、Messaging、Reply Tags、Voice、Silent Replies、Heartbeats、ランタイムメタデータに加え、有効時には Memory と Reactions、さらに任意の context file や追加 system prompt も含めて、完全なプロンプトを組み立てます。subagent 用の minimal prompt mode では、各セクションを短縮します。
プロンプトは、セッション作成後に applySystemPromptOverrideToSession() を通じて適用されます。
セッション管理
セッションファイル
セッションは、ツリー構造(id / parentId のリンク)を持つ JSONL ファイルです。pi の SessionManager が永続化を処理します。
guardSessionManager() でラップし、tool result の取り扱いを安全側に寄せています。
セッションキャッシュ
session-manager-cache.ts は SessionManager instance をキャッシュし、同じファイルの再解析を避けます。
履歴制限
limitHistoryTurns() は、チャンネル種別(DM 対グループ)に応じて会話履歴を切り詰めます。
Compaction
自動 compaction はコンテキストオーバーフロー時に発動します。compactEmbeddedPiSessionDirect() が手動 compaction を処理します。
認証とモデル解決
認証プロファイル
OpenClaw は、provider ごとに複数の API key を持てる認証 profile store を維持します。モデル解決
フェイルオーバー
FailoverError は、設定されている場合に model fallback を発動します。
Pi 拡張
OpenClaw は、特化した挙動を実現するためにカスタムの pi extension を読み込みます。Compaction Safeguard
src/agents/pi-extensions/compaction-safeguard.ts は、適応的な token budget に加えて、tool failure と file operation の要約を含む compaction の guardrail を追加します。
Context Pruning
src/agents/pi-extensions/context-pruning.ts は、Cache-TTL ベースの context pruning を実装します。
ストリーミングとブロック返信
ブロックチャンク化
EmbeddedBlockChunker は、ストリーミングテキストを個別の返信ブロックへ分割して管理します。
Thinking / Final タグの除去
ストリーミング出力は、<think> / <thinking> ブロックを除去し、<final> の内容を抽出するよう処理されます。
返信ディレクティブ
[[media:url]]、[[voice]]、[[reply:id]] のような返信ディレクティブは、解析されて抽出されます。
エラー処理
エラー分類
pi-embedded-helpers.ts は、後続処理を分岐させるために error を分類します。
Thinking レベルのフォールバック
Thinking level がサポートされていない場合は、fallback します。サンドボックス統合
サンドボックスモードが有効な場合、tool と path には制約が適用されます。プロバイダー別の処理
Anthropic
- Refusal の magic string 除去
- 連続する role に対するターン検証
- Claude Code のパラメーター互換性
Google/Gemini
- ターン順序の修正(
applyGoogleTurnOrderingFix) - ツールスキーマのサニタイズ(
sanitizeToolsForGoogle) - セッション履歴のサニタイズ(
sanitizeSessionHistory)
OpenAI
- Codex モデル向けの
apply_patchツール - Thinking レベルのダウングレード処理
TUI 統合
OpenClaw には、pi-tui の component を直接使うローカル TUI mode もあります。
Pi CLI との主な違い
| Aspect | Pi CLI | OpenClaw Embedded |
|---|---|---|
| Invocation | pi command / RPC | createAgentSession() 経由の SDK |
| Tools | Default coding tools | カスタム OpenClaw ツールスイート |
| System prompt | AGENTS.md + prompts | チャンネル/コンテキストごとに動的 |
| Session storage | ~/.pi/agent/sessions/ | ~/.openclaw/agents/<agentId>/sessions/(または $OPENCLAW_STATE_DIR/agents/<agentId>/sessions/) |
| Auth | Single credential | ローテーション付きマルチプロファイル |
| Extensions | Loaded from disk | プログラム経由 + ディスクパス |
| Event handling | TUI rendering | コールバックベース(onBlockReply など) |
今後の検討事項
今後の再設計候補として、次の領域があります。- ツールシグネチャの整合: 現在は pi-agent-core と pi-coding-agent のシグネチャ差分を吸収している
- セッションマネージャーのラップ:
guardSessionManagerは安全性を高める一方で複雑さも増やす - 拡張の読み込み: pi の
ResourceLoaderをより直接的に使える可能性がある - ストリーミングハンドラーの複雑化:
subscribeEmbeddedPiSessionが大きくなってきている - プロバイダー固有の癖: pi 側で吸収できる可能性のあるプロバイダー別コードパスが多い
テスト
Pi 統合のカバレッジは、次の test suite にまたがっています。src/agents/pi-*.test.tssrc/agents/pi-auth-json.test.tssrc/agents/pi-embedded-*.test.tssrc/agents/pi-embedded-helpers*.test.tssrc/agents/pi-embedded-runner*.test.tssrc/agents/pi-embedded-runner/**/*.test.tssrc/agents/pi-embedded-subscribe*.test.tssrc/agents/pi-tools*.test.tssrc/agents/pi-tool-definition-adapter*.test.tssrc/agents/pi-settings.test.tssrc/agents/pi-extensions/**/*.test.ts
src/agents/pi-embedded-runner-extraparams.live.test.ts(OPENCLAW_LIVE_TEST=1を有効化)