エージェントループ(OpenClaw)
エージェントループは、エージェントの完全な「実際の」実行全体です。取り込み → コンテキスト構築 → モデル推論 → ツール実行 → ストリーミング返信 → 永続化、という流れになります。これは、セッション状態の整合性を保ちながら、 メッセージをアクションと最終返信へ変換する、信頼できる正規の経路です。 OpenClaw では、ループはセッションごとに直列化された単一の実行であり、モデルが思考し、ツールを呼び出し、出力をストリーミングする間に、 ライフサイクルイベントとストリームイベントを発行します。このドキュメントでは、その正規のループがエンドツーエンドでどのように配線されているかを説明します。エントリーポイント
- Gateway RPC:
agentとagent.wait - CLI:
agentコマンド
仕組み(概要)
agentRPC はパラメータを検証し、セッション(sessionKey/sessionId)を解決し、セッションメタデータを永続化し、即座に{ runId, acceptedAt }を返します。agentCommandがエージェントを実行します:- モデルと thinking/verbose/trace のデフォルト値を解決する
- Skills スナップショットを読み込む
runEmbeddedPiAgent(pi-agent-core ランタイム)を呼び出す- 埋め込みループが発行しない場合は ライフサイクル end/error を発行する
runEmbeddedPiAgent:- セッションごと + グローバルキューを介して実行を直列化する
- モデル + 認証プロファイルを解決し、Pi セッションを構築する
- pi イベントを購読し、assistant/tool の差分をストリーミングする
- タイムアウトを強制し、超過時は実行を中断する
- ペイロード + 使用量メタデータを返す
subscribeEmbeddedPiSessionは pi-agent-core のイベントを OpenClaw のagentストリームに橋渡しします:- ツールイベント =>
stream: "tool" - assistant の差分 =>
stream: "assistant" - ライフサイクルイベント =>
stream: "lifecycle"(phase: "start" | "end" | "error")
- ツールイベント =>
agent.waitはwaitForAgentRunを使用します:runIdに対する ライフサイクル end/error を待機する{ status: ok|error|timeout, startedAt, endedAt, error? }を返す
キューイング + 並行性
- 実行はセッションキーごと(セッションレーン)に直列化され、必要に応じてグローバルレーンも通ります。
- これにより、ツール/セッションの競合を防ぎ、セッション履歴の整合性を維持します。
- メッセージングチャネルは、このレーンシステムに流し込まれるキューモード(collect/steer/followup)を選択できます。 詳しくは Command Queue を参照してください。
セッション + ワークスペースの準備
- ワークスペースは解決されて作成されます。サンドボックス実行では、サンドボックスのワークスペースルートにリダイレクトされる場合があります。
- Skills は読み込まれ(またはスナップショットから再利用され)、環境変数とプロンプトに注入されます。
- ブートストラップ/コンテキストファイルが解決され、システムプロンプトレポートに注入されます。
- セッション書き込みロックが取得され、
SessionManagerがストリーミング前にオープンおよび準備されます。
プロンプト構築 + システムプロンプト
- システムプロンプトは、OpenClaw のベースプロンプト、Skills プロンプト、ブートストラップコンテキスト、および実行ごとのオーバーライドから構築されます。
- モデル固有の制限と Compaction 用の予備トークンが強制されます。
- モデルが何を見るかについては、System prompt を参照してください。
フックポイント(介入できる場所)
OpenClaw には 2 つのフックシステムがあります。- 内部フック(Gateway hooks): コマンドとライフサイクルイベント用のイベント駆動スクリプト。
- Plugin フック: エージェント/ツールのライフサイクルおよび Gateway パイプライン内の拡張ポイント。
内部フック(Gateway hooks)
agent:bootstrap: システムプロンプトが確定する前に、ブートストラップファイルを構築している間に実行されます。 これを使ってブートストラップコンテキストファイルを追加/削除します。- コマンドフック:
/new、/reset、/stop、およびその他のコマンドイベント(Hooks ドキュメントを参照)。
Plugin フック(エージェント + Gateway ライフサイクル)
これらはエージェントループ内または Gateway パイプライン内で実行されます。before_model_resolve: モデル解決の前に、provider/model を決定論的に上書きするために、セッション前(messagesなし)で実行されます。before_prompt_build: セッション読み込み後(messagesあり)に実行され、プロンプト送信前にprependContext、systemPrompt、prependSystemContext、またはappendSystemContextを注入します。ターンごとの動的テキストにはprependContextを使用し、システムプロンプト空間に配置すべき安定したガイダンスには system-context フィールドを使用してください。before_agent_start: 後方互換性のためのレガシーフックで、どちらのフェーズでも実行される場合があります。明示的な上記フックを優先してください。before_agent_reply: インラインアクションの後、LLM 呼び出しの前に実行され、Plugin がそのターンを引き受けて合成返信を返したり、ターン全体を無音にしたりできます。agent_end: 完了後に最終メッセージリストと実行メタデータを検査します。before_compaction/after_compaction: Compaction サイクルを監視または注釈付けします。before_tool_call/after_tool_call: ツールのパラメータ/結果に介入します。before_install: 組み込みスキャンの検出結果を検査し、必要に応じて skill または Plugin のインストールをブロックします。tool_result_persist: ツール結果がセッショントランスクリプトに書き込まれる前に、同期的に変換します。message_received/message_sending/message_sent: 受信 + 送信メッセージフック。session_start/session_end: セッションライフサイクルの境界。gateway_start/gateway_stop: Gateway ライフサイクルイベント。
before_tool_call:{ block: true }は終端的であり、優先度の低いハンドラを停止します。before_tool_call:{ block: false }は no-op であり、以前の block を解除しません。before_install:{ block: true }は終端的であり、優先度の低いハンドラを停止します。before_install:{ block: false }は no-op であり、以前の block を解除しません。message_sending:{ cancel: true }は終端的であり、優先度の低いハンドラを停止します。message_sending:{ cancel: false }は no-op であり、以前の cancel を解除しません。
ストリーミング + 部分返信
- assistant の差分は pi-agent-core からストリーミングされ、
assistantイベントとして発行されます。 - ブロックストリーミングは、
text_endまたはmessage_endのいずれかで部分返信を発行できます。 - reasoning ストリーミングは、別のストリームとして、またはブロック返信として発行できます。
- チャンク分割とブロック返信の挙動については、Streaming を参照してください。
ツール実行 + メッセージングツール
- ツールの start/update/end イベントは
toolストリーム上で発行されます。 - ツール結果は、ログ記録/発行の前に、サイズと画像ペイロードについてサニタイズされます。
- メッセージングツールによる送信は追跡され、assistant による重複確認を抑止します。
返信の整形 + 抑止
- 最終ペイロードは次から組み立てられます:
- assistant テキスト(および任意の reasoning)
- インラインツール要約(verbose かつ許可されている場合)
- モデルでエラーが発生した場合の assistant エラーテキスト
- 正確なサイレントトークン
NO_REPLY/no_replyは送信ペイロードから フィルタリングされます。 - メッセージングツールの重複は最終ペイロードリストから削除されます。
- レンダリング可能なペイロードが何も残らず、かつツールがエラーになった場合は、フォールバックのツールエラー返信が発行されます (メッセージングツールがすでにユーザー向けの返信を送信している場合を除く)。
Compaction + リトライ
- 自動 Compaction は
compactionストリームイベントを発行し、リトライを引き起こす場合があります。 - リトライ時には、重複出力を避けるために、インメモリバッファとツール要約がリセットされます。
- Compaction パイプラインについては、Compaction を参照してください。
イベントストリーム(現時点)
lifecycle:subscribeEmbeddedPiSessionによって発行される(およびフォールバックとしてagentCommandからも発行される)assistant: pi-agent-core からストリーミングされる差分tool: pi-agent-core からストリーミングされるツールイベント
チャットチャネルの処理
- assistant の差分はチャット
deltaメッセージにバッファリングされます。 - チャット
finalは ライフサイクル end/error 時に発行されます。
タイムアウト
agent.waitのデフォルト: 30 秒(待機のみ)。timeoutMsパラメータで上書きします。- エージェントランタイム:
agents.defaults.timeoutSecondsのデフォルトは 172800 秒(48 時間)で、runEmbeddedPiAgentの中断タイマーで強制されます。 - LLM アイドルタイムアウト:
agents.defaults.llm.idleTimeoutSecondsは、アイドル時間の枠内で応答チャンクが届かない場合にモデルリクエストを中断します。遅いローカルモデルや reasoning/ツールコール provider では、これを明示的に設定してください。無効にするには 0 に設定します。未設定の場合、OpenClaw はagents.defaults.timeoutSecondsが設定されていればそれを使用し、そうでなければ 120 秒を使用します。明示的な LLM またはエージェントタイムアウトがない Cron トリガー実行では、アイドルウォッチドッグは無効化され、Cron 外側のタイムアウトに依存します。
途中で終了する可能性がある場所
- エージェントタイムアウト(中断)
- AbortSignal(キャンセル)
- Gateway 切断または RPC タイムアウト
agent.waitタイムアウト(待機のみであり、エージェント自体は停止しない)
関連
- Tools — 利用可能なエージェントツール
- Hooks — エージェントライフサイクルイベントによってトリガーされるイベント駆動スクリプト
- Compaction — 長い会話がどのように要約されるか
- Exec Approvals — シェルコマンドの承認ゲート
- Thinking — thinking/reasoning レベル設定