基本
エージェントループ
エージェントループとは、エージェントの完全な「実際の」実行のことです:インテーク → コンテキスト構築 → モデル推論 → ツール実行 → ストリーミング応答 → 永続化。これは、メッセージをアクションと最終応答に変換し、セッション状態を一貫して保つ権威あるパスです。OpenClawでは、ループはセッションごとの単一の直列化された実行であり、モデルが思考し、ツールを呼び出し、出力をストリーミングする際にライフサイクルイベントとストリームイベントを発行します。このドキュメントでは、その本物のループがエンドツーエンドでどのように配線されているかを説明します。
エントリーポイント
- Gateway RPC:
agentおよびagent.wait。 - CLI:
agentコマンド。
仕組み(概要)
agentRPCはパラメータを検証し、セッション(sessionKey/sessionId)を解決し、セッションメタデータを永続化し、直ちに{ runId, acceptedAt }を返します。agentCommandがエージェントを実行します:- モデル + 思考/詳細表示のデフォルトを解決
- スキルスナップショットをロード
runEmbeddedPiAgent(pi-agent-coreランタイム) を呼び出し- 埋め込みループが発行しない場合、ライフサイクル終了/エラーを発行
runEmbeddedPiAgent:- セッションごとおよびグローバルキューを介して実行を直列化
- モデル + 認証プロファイルを解決し、piセッションを構築
- piイベントを購読し、アシスタント/ツール差分をストリーミング
- タイムアウトを強制 -> 超過した場合実行を中止
- ペイロード + 使用量メタデータを返す
subscribeEmbeddedPiSessionはpi-agent-coreイベントをOpenClawagentストリームにブリッジします:- ツールイベント =>
stream: "tool" - アシスタント差分 =>
stream: "assistant" - ライフサイクルイベント =>
stream: "lifecycle"(phase: "start" | "end" | "error")
- ツールイベント =>
agent.waitはwaitForAgentJobを使用します:runIdの ライフサイクル終了/エラー を待機{ status: ok|error|timeout, startedAt, endedAt, error? }を返す
キューイング + 並行性
- 実行はセッションキー(セッションレーン)ごとに直列化され、オプションでグローバルレーンを通じて直列化されます。
- これにより、ツール/セッションの競合を防ぎ、セッション履歴の一貫性を保ちます。
- メッセージングチャネルは、このレーンシステムに供給するキュー・モード(collect/steer/followup)を選択できます。詳細はコマンドキューを参照してください。
セッション + ワークスペースの準備
- ワークスペースが解決され作成されます。サンドボックス化された実行は、サンドボックスワークスペースルートにリダイレクトされる場合があります。
- スキルがロード(またはスナップショットから再利用)され、環境とプロンプトに注入されます。
- ブートストラップ/コンテキストファイルが解決され、システムプロンプトレポートに注入されます。
- セッション書き込みロックが取得されます。
SessionManagerはストリーミング前に開かれ準備されます。
プロンプト構築 + システムプロンプト
- システムプロンプトは、OpenClawのベースプロンプト、スキルプロンプト、ブートストラップコンテキスト、および実行ごとのオーバーライドから構築されます。
- モデル固有の制限と圧縮予備トークンが適用されます。
- モデルが何を見るかについてはシステムプロンプトを参照してください。
フックポイント(インターセプト可能な場所)
OpenClawには2つのフックシステムがあります:
- 内部フック (Gatewayフック): コマンドおよびライフサイクルイベントのためのイベント駆動型スクリプト。
- プラグインフック: エージェント/ツールライフサイクルおよびゲートウェイパイプライン内の拡張ポイント。
内部フック (Gatewayフック)
agent:bootstrap: システムプロンプトが最終決定される前にブートストラップファイルを構築中に実行されます。これを使用してブートストラップコンテキストファイルを追加/削除します。- コマンドフック:
/new,/reset,/stopおよびその他のコマンドイベント(フックドキュメントを参照)。
設定と例についてはフックを参照してください。
プラグインフック (エージェント + ゲートウェイライフサイクル)
これらはエージェントループまたはゲートウェイパイプライン内で実行されます:
before_model_resolve: モデル解決前にプロバイダー/モデルを決定論的にオーバーライドするために、セッション前(messagesなし)で実行されます。before_prompt_build: プロンプト送信前にprependContext,systemPrompt,prependSystemContext, またはappendSystemContextを注入するために、セッションロード後(messagesあり)で実行されます。ターンごとの動的テキストにはprependContextを、システムプロンプト空間に配置すべき安定したガイダンスにはシステムコンテキストフィールドを使用します。before_agent_start: どちらのフェーズでも実行される可能性のあるレガシー互換性フック。上記の明示的なフックを優先してください。agent_end: 完了後の最終メッセージリストと実行メタデータを検査します。before_compaction/after_compaction: 圧縮サイクルを観察または注釈付けします。before_tool_call/after_tool_call: ツールパラメータ/結果をインターセプトします。tool_result_persist: ツール結果がセッショントランスクリプトに書き込まれる前に、同期的に変換します。message_received/message_sending/message_sent: 受信 + 送信メッセージフック。session_start/session_end: セッションライフサイクルの境界。gateway_start/gateway_stop: ゲートウェイライフサイクルイベント。
フックAPIと登録の詳細についてはプラグインを参照してください。
ストリーミング + 部分応答
- アシスタント差分はpi-agent-coreからストリーミングされ、
assistantイベントとして発行されます。 - ブロックストリーミングは、
text_endまたはmessage_endで部分応答を発行できます。 - 推論ストリーミングは、別のストリームとして、またはブロック応答として発行できます。
- チャンキングとブロック応答の動作についてはストリーミングを参照してください。
ツール実行 + メッセージングツール
- ツール開始/更新/終了イベントは
toolストリームで発行されます。 - ツール結果は、ロギング/発行前にサイズと画像ペイロードに対してサニタイズされます。
- メッセージングツールの送信は追跡され、重複するアシスタント確認を抑制します。
応答整形 + 抑制
- 最終ペイロードは以下から組み立てられます:
- アシスタントテキスト(およびオプションの推論)
- インラインツール要約(詳細表示 + 許可された場合)
- モデルエラー時のアシスタントエラーテキスト
NO_REPLYはサイレントトークンとして扱われ、送信ペイロードからフィルタリングされます。- メッセージングツールの重複は最終ペイロードリストから削除されます。
- レンダリング可能なペイロードが残らず、ツールがエラーを起こした場合、フォールバックのツールエラー応答が発行されます(メッセージングツールが既にユーザーに表示可能な応答を送信していない限り)。
圧縮 + リトライ
- 自動圧縮は
compactionストリームイベントを発行し、リトライをトリガーできます。 - リトライ時、メモリ内バッファとツール要約は重複出力を避けるためにリセットされます。
- 圧縮パイプラインについては圧縮を参照してください。
イベントストリーム(現在)
lifecycle:subscribeEmbeddedPiSessionによって発行(およびagentCommandによるフォールバックとして)assistant: pi-agent-coreからのストリーミング差分tool: pi-agent-coreからのストリーミングツールイベント
チャットチャネル処理
- アシスタント差分はチャット
deltaメッセージにバッファリングされます。 - チャット
finalは ライフサイクル終了/エラー 時に発行されます。
タイムアウト
agent.waitデフォルト: 30秒(待機のみ)。timeoutMsパラメータでオーバーライド。- エージェントランタイム:
agents.defaults.timeoutSecondsデフォルト600秒。runEmbeddedPiAgent中止タイマーで強制されます。
早期終了が発生する可能性のある場所
- エージェントタイムアウト(中止)
- AbortSignal(キャンセル)
- ゲートウェイ切断またはRPCタイムアウト
agent.waitタイムアウト(待機のみ、エージェントは停止しない)