コンテンツにスキップ

OpenClawエージェントループの仕組み:実行フローを徹底解説

AI エージェントを開発していると、単なる API コール以上の複雑さに直面することがあります。ユーザーの入力を受け取り、コンテキストを組み立て、モデルの推論を経てツールを実行し、その経過をリアルタイムでユーザーに返す。この一連のプロセスを、セッションの状態を崩さずに一貫して管理するのは、実はかなり骨の折れる作業です。

OpenClaw における「エージェントループ」は、こうした一連の動作を確実に行うための「本番用」実行パスです。この記事では、メッセージがどのようにアクションに変換され、最終的な返答として結実するのか、その仕組みを詳しく解説します。

エージェントループとは、エージェントの「真の」実行サイクルのことです。インテーク(入力)、コンテキストの組み立て、モデルの推論、ツールの実行、返答のストリーミング、そして永続化までを含みます。これは、セッションの状態を一貫させながら、メッセージをアクションと最終的な返答へと変える権威あるパスです。

OpenClaw では、ループはセッションごとにシリアル化された単一の実行単位であり、モデルの思考、ツールの呼び出し、出力のストリーミングに合わせて、ライフサイクルイベントやストリームイベントを発行します。このドキュメントでは、そのエンドツーエンドの仕組みを説明します。

  • Gateway RPC: agent および agent.wait
  • CLI: agent コマンド
  1. agent RPC がパラメータを検証し、Session(sessionKey/sessionId)を解決して、Session のメタデータを保存します。その後、すぐに { runId, acceptedAt } を返します。
  2. agentCommand がエージェントを実行します:
    • モデルや thinking/verbose のデフォルト設定を解決します。
    • スキルのスナップショットをロードします。
    • runEmbeddedPiAgent(pi-agent-core ランタイム)を呼び出します。
    • 埋め込みループがライフサイクルの終了またはエラーイベントを発行しない場合、代わりに発行します。
  3. runEmbeddedPiAgent:
    • セッションごとのキューおよびグローバルキューを介して、実行をシリアル化します。
    • モデルと認証プロファイルを解決し、pi セッションを構築します。
    • pi イベントをサブスクライブし、アシスタントやツールの差分(deltas)をストリーミングします。
    • タイムアウトを監視し、超過した場合は実行を中断(abort)します。
    • ペイロードと使用状況のメタデータを返します。
  4. subscribeEmbeddedPiSession は、pi-agent-core のイベントを OpenClaw の agent ストリームにブリッジします:
    • ツールイベント => stream: "tool"
    • アシスタントの差分 => stream: "assistant"
    • ライフサイクルイベント => stream: "lifecycle" (phase: "start" | "end" | "error")
  5. agent.wait は waitForAgentJob を使用します:
    • 指定された runId のライフサイクル終了またはエラーを待ちます。
    • { status: ok|error|timeout, startedAt, endedAt, error? } を返します。
  • 実行は Session key ごと(セッションレーン)、およびオプションでグローバルレーンを通じてシリアル化されます。
  • これにより、ツールやセッションの競合を防ぎ、セッション履歴の一貫性を保ちます。
  • メッセージングチャネルは、このレーンシステムに供給するキューモード(collect/steer/followup)を選択できます。詳細は Command Queue を参照してください。
  • Workspace が解決・作成されます。サンドボックス化された実行では、サンドボックスの Workspace ルートにリダイレクトされる場合があります。
  • スキルがロード(またはスナップショットから再利用)され、環境変数とプロンプトに注入されます。
  • Bootstrap/コンテキストファイルが解決され、System prompt レポートに注入されます。
  • Session の書き込みロックが取得されます。ストリーミングを開始する前に SessionManager が開かれ、準備が整えられます。
  • System prompt は、OpenClaw のベースプロンプト、スキルプロンプト、Bootstrap コンテキスト、および実行ごとのオーバーライドから構築されます。
  • モデル固有の制限や、Compaction 用の予約トークンが適用されます。
  • モデルが実際に何を見ているかについては、System prompt を参照してください。

Hook ポイント(インターセプト可能な場所)

Section titled “Hook ポイント(インターセプト可能な場所)”

OpenClaw には 2 つの Hook システムがあります。

  • Internal hooks (Gateway hooks): コマンドやライフサイクルイベントに応じたイベント駆動型スクリプト。
  • Plugin hooks: エージェントやツールのライフサイクル、および Gateway パイプライン内の拡張ポイント。
  • agent:bootstrap: System prompt が確定する前に、Bootstrap ファイルを構築している最中に実行されます。Bootstrap コンテキストファイルの追加や削除に使用します。
  • Command hooks: /new, /reset, /stop などのコマンドイベント(Hooks ドキュメントを参照)。

設定と例については Hooks を参照してください。

Plugin hooks (エージェント + Gateway ライフサイクル)

Section titled “Plugin hooks (エージェント + Gateway ライフサイクル)”

これらはエージェントループ内、または Gateway パイプライン内で実行されます。

  • before_model_resolve: Session 開始前(messages なし)に実行され、モデル解決の前に Provider やモデルを決定論的にオーバーライドします。
  • before_prompt_build: Session ロード後(messages あり)に実行され、プロンプト送信前に prependContext, systemPrompt, prependSystemContext, appendSystemContext を注入します。ターンごとの動的なテキストには prependContext を、System prompt 領域に配置すべき安定したガイダンスには system-context フィールドを使用してください。
  • before_agent_start: レガシー互換用の Hook です。上記の明示的な Hook の使用を推奨します。
  • before_agent_reply: インラインアクションの後、LLM コールの前に実行されます。プラグインがターンを乗っ取り、合成された返答を返したり、ターンを完全に消音したりできます。
  • agent_end: 完了後に最終的なメッセージリストと実行メタデータを検査します。
  • before_compaction / after_compaction: Compaction サイクルを観察またはアノテーションします。
  • before_tool_call / after_tool_call: ツールのパラメータや結果をインターセプトします。
  • before_install: ビルトインのスキャン結果を検査し、オプションでスキルやプラグインのインストールをブロックします。
  • tool_result_persist: ツールの結果が Session のトランスクリプトに書き込まれる前に、同期的に変換します。
  • message_received / message_sending / message_sent: インバウンドおよびアウトバウンドのメッセージ Hook です。
  • session_start / session_end: Session のライフサイクルの境界です。
  • gateway_start / gateway_stop: Gateway のライフサイクルイベントです。

アウトバウンドやツールのガードに関する Hook の決定ルール:

  • before_tool_call: { block: true } は終端となり、優先度の低いハンドラーを停止させます。
  • before_tool_call: { block: false } は何もしません(以前のブロックを解除しません)。
  • before_install: { block: true } は終端となり、優先度の低いハンドラーを停止させます。
  • before_install: { block: false } は何もしません。
  • message_sending: { cancel: true } は終端となり、優先度の低いハンドラーを停止させます。
  • message_sending: { cancel: false } は何もしません。

Hook API と登録の詳細は Plugin hooks を参照してください。

  • アシスタントの差分は pi-agent-core からストリーミングされ、assistant イベントとして発行されます。
  • ブロックストリーミングでは、text_end または message_end のタイミングで部分的な返答を発行できます。
  • 推論(Reasoning)のストリーミングは、別のストリームとして、またはブロック返答として発行可能です。
  • チャンク化とブロック返答の挙動については Streaming を参照してください。

Tool の実行とメッセージング Tool

Section titled “Tool の実行とメッセージング Tool”
  • ツールの開始、更新、終了イベントは tool ストリームで発行されます。
  • ツールの結果は、ログ記録や発行の前に、サイズや画像ペイロードがサニタイズされます。
  • メッセージングツールの送信は、アシスタントによる重複した確認を抑制するために追跡されます。
  • 最終的なペイロードは以下から組み立てられます:
    • アシスタントのテキスト(およびオプションの推論)
    • インラインツールの要約(verbose 設定が許可されている場合)
    • モデルエラー時のアシスタントエラーテキスト
  • NO_REPLY はサイレントトークンとして扱われ、送信ペイロードからフィルタリングされます。
  • メッセージングツールの重複は、最終的なペイロードリストから削除されます。
  • レンダリング可能なペイロードが残っておらず、かつツールがエラーになった場合は、フォールバックとしてツールのエラー返答が発行されます(メッセージングツールが既にユーザーに見える返答を送信している場合を除きます)。
  • 自動 Compaction は compaction ストリームイベントを発行し、リトライをトリガーすることがあります。
  • リトライ時には、重複出力を避けるためにインメモリバッファとツールの要約がリセットされます。
  • 詳細は Compaction を参照してください。
  • lifecycle: subscribeEmbeddedPiSession によって発行されます(agentCommand によるフォールバックもあります)。
  • assistant: pi-agent-core からのストリーミング差分です。
  • tool: pi-agent-core からのストリーミングツールイベントです。
  • アシスタントの差分は、チャットの delta メッセージにバッファリングされます。
  • ライフサイクルの終了またはエラー時に、チャットの final が発行されます。
  • agent.wait のデフォルト:30秒(待機時間のみ)。timeoutMs パラメータで上書き可能です。
  • エージェントランタイム:agents.defaults.timeoutSeconds のデフォルトは 172800秒(48時間)です。runEmbeddedPiAgent の中断タイマーによって強制されます。
  • エージェントのタイムアウト(中断)
  • AbortSignal(キャンセル)
  • Gateway の切断または RPC タイムアウト
  • agent.wait のタイムアウト(待機のみを終了し、エージェント自体は停止しません)
  • Tools — 利用可能なエージェントツール
  • Hooks — ライフサイクルイベントによってトリガーされるスクリプト
  • Compaction — 会話の要約方法
  • Exec Approvals — シェルコマンドの承認ゲート
  • Thinking — 思考/推論レベルの設定

さらに詳しい設定やカスタマイズについては、AI Setup Assistant で直接質問してみてください。

OpenClaw

OpenClaw Expert

まだ解決しませんか?

このページで解決しない場合は、OpenClaw Expertに直接質問してください。