はじめに
OpenClaw と Pi プログラミングエージェントの統合方式は、システムアーキテクチャ全体を理解する上で鍵となります。多くのプロジェクトがサブプロセスやRPC呼び出しで外部AIエージェントを利用するのとは異なり、OpenClawはPiプログラミングエージェントSDKを自身のプロセスに直接組み込んでいます。この設計により、より低いレイテンシ、よりきめ細かい制御、そしてより柔軟な拡張性を実現しています。
本記事では、エントリ関数から始めて、セッション管理、ツールチェーン処理パイプライン、システムプロンプト構築、マルチプロバイダー認証メカニズムを段階的に解説します。
コア依存パッケージ
OpenClaw の Pi Agent 統合は以下の4つのコアパッケージ(現在のバージョン 0.49.3)に依存しています。
| パッケージ名 | 役割 |
|---|---|
pi-ai |
低レベルAI通信層、モデルプロバイダーのAPI通信を処理 |
pi-agent-core |
エージェントのコアロジック、メッセージループ・ツール呼び出し・コンテキスト管理を含む |
pi-coding-agent |
コーディングシナリオ特化層、コード関連ツールと戦略を提供 |
pi-tui |
ターミナルUI層、OpenClawはセッションシリアライズ機能のみ使用 |
重要なのは、OpenClawがこれらのパッケージをライブラリとして取り込んでいることです。同じNode.jsプロセス内で実行され、メモリ空間を共有します。つまりOpenClawはエージェントの内部状態を直接操作でき、シリアライズ/デシリアライズを介してデータを受け渡す必要がありません。
エントリ関数:runEmbeddedPiAgent()
統合全体の中心となるのが runEmbeddedPiAgent() 関数です。エージェントの実行動作を設定するためのパラメータを受け取ります。
const result = await runEmbeddedPiAgent({
sessionId: "session_abc123",
sessionKey: "key_xyz",
workspaceDir: "/home/user/project",
prompt: "帮我重构这个函数,提取公共逻辑",
provider: "anthropic",
model: "claude-sonnet-4-20250514",
timeout: 120000,
callbacks: {
onMessage: (msg) => handleAgentMessage(msg),
onToolUse: (tool, input) => logToolUsage(tool, input),
onError: (err) => handleAgentError(err),
onComplete: (result) => sendToChannel(result),
},
});
主要なパラメータの意味:
- sessionId / sessionKey:既存のセッションを特定して復元するためのもので、会話の継続性を実現
- workspaceDir:エージェントの作業ディレクトリ、ファイル操作のルートパスを決定
- provider / model:プロバイダー非依存のモデル切り替え、Anthropic、OpenAIなどの間で自由に切り替え可能
- callbacks:イベントコールバック、OpenClawがエージェントのメッセージ、ツール呼び出し、エラーをリアルタイムで処理可能に
セッション管理と永続化
JSONLツリー型ストレージ
OpenClaw のセッションはJSONL形式で保存され、各行が会話内の1つのメッセージを表すJSONオブジェクトです。単純な線形リストとは異なり、各メッセージには id と parentId フィールドがあり、ツリー構造を形成します。
{"id":"msg_001","parentId":null,"role":"user","content":"分析这段代码的性能问题"}
{"id":"msg_002","parentId":"msg_001","role":"assistant","content":"我来检查一下..."}
{"id":"msg_003","parentId":"msg_002","role":"assistant","content":"[tool_use: read_file]"}
{"id":"msg_004","parentId":"msg_002","role":"assistant","content":"发现了两个问题..."}
{"id":"msg_005","parentId":"msg_001","role":"assistant","content":"(分支) 换个角度分析..."}
上記の例では、msg_004 と msg_005 はどちらも msg_001 の後続ブランチです。これがセッションブランチ機能です。エージェントが異なる解決アプローチを試す必要がある場合、会話ツリーの任意のノードから新しいブランチを作成でき、既存の探索パスを失うことはありません。
セッションファイルの保存場所:
~/.openclaw/agents/<agentId>/sessions/
自動圧縮
会話コンテキストがモデルのトークンウィンドウを超えそうになると、OpenClawは**自動圧縮(auto-compaction)**をトリガーします。圧縮戦略は最近の重要なメッセージとツール呼び出し結果を保持し、古い会話内容を要約化します。このプロセスはユーザーに対して透過的です。エージェントはコンテキストのオーバーフローによってクラッシュすることなく、優雅に動作を続けます。
同時に、OpenClawはチャンネルタイプに応じて履歴メッセージの読み込み量も制限します。DM(ダイレクトメッセージ)はより多くの履歴を読み込んで深い会話の一貫性を維持し、グループ会話はより積極的に履歴を削除して、無関係なメッセージがトークン予算を消費するのを防ぎます。
ツールチェーンの7段階処理パイプライン
ツール(Tools)はエージェントが外部世界とインタラクションするためのインターフェースです。OpenClawはツールインジェクションのために7段階の処理パイプラインを設計しており、各段階に明確な責務があります。
基本ツール → カスタム置換 → OpenClawツール → チャンネルツール → ポリシーフィルタ → Schema正規化 → AbortSignalラップ
各段階の詳細:
- 基本ツール(Base Tools):Pi Agent SDKに付属する標準ツールセット(ファイル読み書き、コマンド実行、コード検索など)
- カスタム置換(Custom Replacements):基本ツールの動作を置換またはオーバーライド可能(例:デフォルトのファイル書き込みツールを権限チェック付きバージョンに置換)
- OpenClawツール(OpenClaw Tools):OpenClawプラットフォーム自体が提供するツール(ナレッジベースクエリ、メモリ検索など)
- チャンネルツール(Channel Tools):現在のメッセージソースのチャンネルに応じた特定ツールのインジェクション(Discordチャンネルにはメッセージ管理ツール、Telegramチャンネルにはメディア処理ツールなど)
- ポリシーフィルタ(Policy Filtering):セキュリティポリシーとユーザー権限に基づいて、使用が許可されないツールをフィルタリング
- Schema正規化(Schema Normalization):すべてのツールのパラメータSchema形式を統一し、異なるソースのツールがモデルに一貫したインターフェースを提示
- AbortSignalラップ(AbortSignal Wrapping):各ツール呼び出しにキャンセルシグナルをラップし、タイムアウト中断やユーザーによる能動的なキャンセルをサポート
このパイプライン設計の利点は関心の分離にあります。各段階は1つの次元のロジックのみを処理し、新しいチャンネルやセキュリティポリシーを追加する際に他の段階のコードを修正する必要がありません。
動的システムプロンプト構築
システムプロンプトはエージェントの動作モードを決定します。OpenClawは静的なプロンプトテンプレートを使用せず、buildAgentSystemPrompt() 関数で動的に構築します。
function buildAgentSystemPrompt(context: PromptContext): string {
const sections = [
coreIdentitySection(context.agentConfig),
channelBehaviorSection(context.channelType),
availableSkillsSection(context.skills),
memorySection(context.relevantMemories),
userPreferencesSection(context.userProfile),
safetyGuidelinesSection(context.policies),
];
return sections.filter(Boolean).join("\n\n");
}
プロンプトは以下の次元に応じて動的に変化します。
- チャンネルタイプ:Discordグループではエージェントはより簡潔に、DMではより詳細に
- 利用可能なSkill:現在ロードされているSkillがプロンプトに注入され、エージェントが自身の拡張能力を認識
- ユーザーメモリ:現在のユーザーに関連する履歴の好みやメモリが注入され、パーソナライズされた応答を実現
- セキュリティポリシー:異なるデプロイ環境には異なるコンテンツセキュリティ要件
マルチアカウント認証とフェイルオーバー
OpenClaw は複数のモデルプロバイダーアカウントの設定をサポートし、実行時に自動的にフェイルオーバーを行います。メインアカウントが以下の状況に遭遇した場合、システムは自動的にバックアップアカウントに切り替えます。
- 認証エラー:APIキーの期限切れまたは失効
- レート制限:プロバイダーのAPI呼び出し頻度制限のトリガー
- コンテキストオーバーフロー:現在のモデルのコンテキストウィンドウがリクエストを処理するのに不十分
切り替えプロセスはユーザーに対して完全に透過的です。エージェントは次のAPI呼び出しでバックアップアカウントを使用し、現在のセッションを中断しません。
Pi CLIとのアーキテクチャ比較
OpenClawの統合方式を理解するために、Pi CLI(公式コマンドラインツール)のアーキテクチャと比較するとより明確になります。
| 次元 | Pi CLI | OpenClaw |
|---|---|---|
| 統合方式 | 独立プロセス、ターミナルインタラクション | SDKの直接組み込み、プロセス内呼び出し |
| ツールセット | 標準プログラミングツール | カスタムツールスイート + チャンネル専用ツール |
| システムプロンプト | 静的/設定ファイル | 動的構築、チャンネルとコンテキストに応じて変化 |
| 認証管理 | 単一アカウントOAuth | マルチProfile認証 + 自動フェイルオーバー |
| セッション復元 | ローカルターミナルセッション | クロスチャンネル永続化 + ブランチ/圧縮 |
| コンテキスト管理 | 手動管理 | 自動圧縮 + チャンネルタイプ別の履歴制限 |
核心的な違いは、Pi CLIが単一ユーザーのターミナルシナリオ向けに設計されているのに対し、OpenClawは同時に複数のユーザーと複数のチャンネルにサービスを提供する必要があるため、セッション管理、ツールインジェクション、認証において大量のマルチテナント対応作業が行われている点です。
まとめ
OpenClaw の Pi Agent 統合アーキテクチャには、いくつかの重要な設計決定が反映されています。
- 呼び出しではなく組み込み:SDK直接統合によるパフォーマンス上の利点とよりきめ細かい制御能力
- パイプライン式ツール処理:7段階パイプラインによる関心の分離で、拡張が容易
- 動的プロンプト:コンテキストに応じてリアルタイムでプロンプトを構築し、同じエージェントが異なるシナリオで異なる振る舞いを示す
- 弾力的認証:マルチアカウントフェイルオーバーによるサービスの高可用性の確保
これらのアーキテクチャ設計を理解することは、OpenClawのカスタムSkill開発、エージェント動作のデバッグ、マルチチャンネルデプロイの最適化に直接役立ちます。