ACP エージェント
Agent Client Protocol (ACP) セッションを使うと、ACP バックエンドプラグイン経由で外部コーディングハーネス(Pi、Claude Code、Codex、OpenCode、Gemini CLI など)を OpenClaw から実行できます。
OpenClaw に「これを Codex で実行して」「Claude Code をスレッドで開始して」と自然言語で依頼すると、OpenClaw はそのリクエストを(ネイティブサブエージェントランタイムではなく)ACP ランタイムにルーティングします。
簡単なオペレーターフロー
実用的な /acp 手順が必要な場合に使用:
- セッションを生成:
/acp spawn codex --mode persistent --thread auto
- バインドされたスレッドで作業(またはセッションキーを明示的に指定)。
- ランタイム状態を確認:
/acp status
- 必要に応じてランタイムオプションを調整:
/acp model <provider/model>/acp permissions <profile>/acp timeout <seconds>
- コンテキストを置き換えずにアクティブセッションを誘導:
/acp steer tighten logging and continue
- 作業を停止:
/acp cancel(現在のターンを停止)、または/acp close(セッションを閉じてバインディングを削除)
ヒューマン向けクイックスタート
自然言語リクエストの例:
- 「ここのスレッドで永続的な Codex セッションを開始して、集中させて。」
- 「これをワンショット Claude Code ACP セッションとして実行し、結果をまとめて。」
- 「このタスクにスレッドで Gemini CLI を使い、フォローアップは同じスレッドで続けて。」
OpenClaw が行うこと:
runtime: "acp"を選択。- 要求されたハーネスターゲット(
agentId、例:codex)を解決。 - スレッドバインディングが要求され、現在のチャンネルがサポートしている場合、ACP セッションをスレッドにバインド。
- アンフォーカス/クローズ/期限切れまで、同じ ACP セッションにフォローアップスレッドメッセージをルーティング。
ACP とサブエージェントの違い
外部ハーネスランタイムが必要な場合は ACP を使用。OpenClaw ネイティブの委任実行が必要な場合はサブエージェントを使用。
| 領域 | ACP セッション | サブエージェント実行 |
|---|---|---|
| ランタイム | ACP バックエンドプラグイン(例: acpx) | OpenClaw ネイティブサブエージェントランタイム |
| セッションキー | agent:<agentId>:acp:<uuid> | agent:<agentId>:subagent:<uuid> |
| 主なコマンド | /acp ... | /subagents ... |
| 生成ツール | sessions_spawn で runtime:"acp" | sessions_spawn(デフォルトランタイム) |
サブエージェント も参照。
スレッドバインドセッション(チャンネル非依存)
チャンネルアダプターでスレッドバインディングが有効な場合、ACP セッションをスレッドにバインドできます:
- OpenClaw がスレッドを対象の ACP セッションにバインド。
- そのスレッド内のフォローアップメッセージがバインドされた ACP セッションにルーティング。
- ACP 出力は同じスレッドに配信。
- アンフォーカス/クローズ/アーカイブ/アイドルタイムアウトまたは最大期限の期限切れでバインディングが解除。
スレッドバインディングのサポートはアダプター固有です。アクティブなチャンネルアダプターがスレッドバインディングをサポートしていない場合、OpenClaw は明確な未サポート/利用不可メッセージを返します。
スレッドバインド ACP に必要な機能フラグ:
acp.enabled=trueacp.dispatch.enabledはデフォルトで有効(ACP ディスパッチを一時停止するにはfalseに設定)- チャンネルアダプターの ACP スレッド生成フラグ有効化(アダプター固有)
- Discord:
channels.discord.threadBindings.spawnAcpSessions=true - Telegram:
channels.telegram.threadBindings.spawnAcpSessions=true
- Discord:
スレッドサポートチャンネル
- セッション/スレッドバインディング機能を公開するチャンネルアダプター。
- 現在の組み込みサポート:
- Discord スレッド/チャンネル
- Telegram トピック(グループ/スーパーグループのフォーラムトピックと DM トピック)
- プラグインチャンネルは同じバインディングインターフェースを通じてサポートを追加可能。
チャンネル固有の設定
非エフェメラルワークフローでは、トップレベルの bindings[] エントリに永続的な ACP バインディングを設定します。
バインディングモデル
bindings[].type="acp"で永続的な ACP 会話バインディングを指定。bindings[].matchでターゲット会話を識別:- Discord チャンネルまたはスレッド:
match.channel="discord"+match.peer.id="<channelOrThreadId>" - Telegram フォーラムトピック:
match.channel="telegram"+match.peer.id="<chatId>:topic:<topicId>"
- Discord チャンネルまたはスレッド:
bindings[].agentIdは所有する OpenClaw エージェント ID。- ACP オーバーライドは
bindings[].acp配下(任意):mode(persistentまたはoneshot)labelcwdbackend
エージェントごとのランタイムデフォルト
agents.list[].runtime でエージェントごとに ACP デフォルトを一度定義:
agents.list[].runtime.type="acp"agents.list[].runtime.acp.agent(ハーネス ID、例:codexまたはclaude)agents.list[].runtime.acp.backendagents.list[].runtime.acp.modeagents.list[].runtime.acp.cwd
ACP バインドセッションのオーバーライド優先順位:
bindings[].acp.*agents.list[].runtime.acp.*- グローバル ACP デフォルト(例:
acp.backend)
例:
{
agents: {
list: [
{
id: "codex",
runtime: {
type: "acp",
acp: {
agent: "codex",
backend: "acpx",
mode: "persistent",
cwd: "/workspace/openclaw",
},
},
},
{
id: "claude",
runtime: {
type: "acp",
acp: { agent: "claude", backend: "acpx", mode: "persistent" },
},
},
],
},
bindings: [
{
type: "acp",
agentId: "codex",
match: {
channel: "discord",
accountId: "default",
peer: { kind: "channel", id: "222222222222222222" },
},
acp: { label: "codex-main" },
},
{
type: "acp",
agentId: "claude",
match: {
channel: "telegram",
accountId: "default",
peer: { kind: "group", id: "-1001234567890:topic:42" },
},
acp: { cwd: "/workspace/repo-b" },
},
{
type: "route",
agentId: "main",
match: { channel: "discord", accountId: "default" },
},
{
type: "route",
agentId: "main",
match: { channel: "telegram", accountId: "default" },
},
],
channels: {
discord: {
guilds: {
"111111111111111111": {
channels: {
"222222222222222222": { requireMention: false },
},
},
},
},
telegram: {
groups: {
"-1001234567890": {
topics: { "42": { requireMention: false } },
},
},
},
},
}
動作:
- OpenClaw は使用前に設定された ACP セッションの存在を確認。
- そのチャンネルまたはトピック内のメッセージは設定された ACP セッションにルーティング。
- バインドされた会話では、
/newと/resetは同じ ACP セッションキーをその場でリセット。 - 一時的なランタイムバインディング(例: スレッドフォーカスフローで作成されたもの)は存在する場合に引き続き適用。
ACP セッションの開始(インターフェース)
sessions_spawn から
エージェントターンまたはツール呼び出しから ACP セッションを開始するには runtime: "acp" を使用。
{
"task": "Open the repo and summarize failing tests",
"runtime": "acp",
"agentId": "codex",
"thread": true,
"mode": "session"
}
補足:
runtimeのデフォルトはsubagentなので、ACP セッションにはruntime: "acp"を明示的に設定。agentIdを省略すると、設定されている場合はacp.defaultAgentを使用。mode: "session"にはthread: trueが必要(永続的なバインド会話を維持するため)。
インターフェースの詳細:
task(必須): ACP セッションに送信される初期プロンプト。runtime(ACP では必須):"acp"でなければならない。agentId(任意): ACP ターゲットハーネス ID。設定されている場合はacp.defaultAgentにフォールバック。thread(任意、デフォルトfalse): サポートされている場合にスレッドバインディングフローを要求。mode(任意):run(ワンショット)またはsession(永続的)。- デフォルトは
run thread: trueで mode を省略した場合、ランタイムパスに応じて OpenClaw が永続的動作をデフォルトにする場合ありmode: "session"にはthread: trueが必要
- デフォルトは
cwd(任意): 要求されたランタイム作業ディレクトリ(バックエンド/ランタイムポリシーによりバリデーション)。label(任意): セッション/バナーテキストで使用されるオペレーター向けラベル。resumeSessionId(任意): 新規作成の代わりに既存の ACP セッションを再開。エージェントがsession/loadで会話履歴を再生。runtime: "acp"が必要。streamTo(任意):"parent"を指定すると、初期 ACP 実行の進捗サマリーをシステムイベントとしてリクエスターセッションにストリーム。- 利用可能な場合、受理レスポンスには完全なリレー履歴を tail できるセッションスコープ JSONL ログ(
<sessionId>.acp-stream.jsonl)を指すstreamLogPathが含まれる。
- 利用可能な場合、受理レスポンスには完全なリレー履歴を tail できるセッションスコープ JSONL ログ(
既存セッションの再開
新規開始の代わりに前の ACP セッションを続行するには resumeSessionId を使用。エージェントが session/load で会話履歴を再生するため、それまでのフルコンテキストを持って再開します。
{
"task": "Continue where we left off — fix the remaining test failures",
"runtime": "acp",
"agentId": "codex",
"resumeSessionId": "<previous-session-id>"
}
主な使用例:
- Codex セッションをノート PC からスマートフォンに引き継ぐ — エージェントに中断した場所から再開させる
- CLI でインタラクティブに開始したコーディングセッションを、エージェント経由でヘッドレスに続行
- Gateway の再起動やアイドルタイムアウトで中断された作業を再開
補足:
resumeSessionIdにはruntime: "acp"が必要 — サブエージェントランタイムで使用するとエラー。resumeSessionIdは上流の ACP 会話履歴を復元。threadとmodeは作成する新しい OpenClaw セッションに対して通常通り適用されるため、mode: "session"には引き続きthread: trueが必要。- ターゲットエージェントが
session/loadをサポートしている必要あり(Codex と Claude Code は対応)。 - セッション ID が見つからない場合、spawn は明確なエラーで失敗 — 新規セッションへのサイレントフォールバックなし。
オペレータースモークテスト
Gateway デプロイ後に ACP spawn がエンドツーエンドで実際に動作していることを素早く確認したい場合に使用。ユニットテストに合格するだけでなく、実際に動くことを確認します。
推奨ゲート:
- ターゲットホスト上のデプロイ済み Gateway バージョン/コミットを確認。
- デプロイ済みソースに
src/gateway/sessions-patch.tsの ACP リネージ受理(subagent:* or acp:* sessions)が含まれていることを確認。 - ライブエージェント(例:
jpclawhq上のrazor(main))への一時的な ACPX ブリッジセッションを開く。 - そのエージェントに以下で
sessions_spawnを呼び出させる:runtime: "acp"agentId: "codex"mode: "run"- task:
Reply with exactly LIVE-ACP-SPAWN-OK
- エージェントが以下を報告することを確認:
accepted=yes- 実際の
childSessionKey - バリデーターエラーなし
- 一時的な ACPX ブリッジセッションをクリーンアップ。
ライブエージェントへのプロンプト例:
Use the sessions_spawn tool now with runtime: "acp", agentId: "codex", and mode: "run".
Set the task to: "Reply with exactly LIVE-ACP-SPAWN-OK".
Then report only: accepted=<yes/no>; childSessionKey=<value or none>; error=<exact text or none>.
補足:
- 基本的なゲートでは
mode: "run"を維持。意図的にスレッドバインド永続 ACP セッションをテストする場合を除く。 - 基本的なゲートでは
streamTo: "parent"を要求しない。そのパスはリクエスター/セッション機能に依存し、別の統合チェック。 - スレッドバインドの
mode: "session"テストは、実際の Discord スレッドまたは Telegram トピックからの 2 番目のより詳細な統合パスとして扱う。
サンドボックスの互換性
ACP セッションは現在ホストランタイム上で実行され、OpenClaw サンドボックス内では実行されません。
現在の制限:
- リクエスターセッションがサンドボックス化されている場合、
sessions_spawn({ runtime: "acp" })と/acp spawnの両方で ACP spawn がブロック。- エラー:
Sandboxed sessions cannot spawn ACP sessions because runtime="acp" runs on the host. Use runtime="subagent" from sandboxed sessions.
- エラー:
sessions_spawnでruntime: "acp"はsandbox: "require"をサポートしない。- エラー:
sessions_spawn sandbox="require" is unsupported for runtime="acp" because ACP sessions run outside the sandbox. Use runtime="subagent" or sandbox="inherit".
- エラー:
サンドボックス強制実行が必要な場合は runtime: "subagent" を使用してください。
/acp コマンドから
チャットからの明示的なオペレーター制御が必要な場合は /acp spawn を使用。
/acp spawn codex --mode persistent --thread auto
/acp spawn codex --mode oneshot --thread off
/acp spawn codex --thread here
主なフラグ:
--mode persistent|oneshot--thread auto|here|off--cwd <absolute-path>--label <name>
スラッシュコマンド を参照。
セッションターゲットの解決
ほとんどの /acp アクションは任意のセッションターゲット(session-key、session-id、session-label)を受け付けます。
解決順序:
- 明示的なターゲット引数(または
/acp steerの--session)- キーを試行
- 次に UUID 形式のセッション ID
- 次にラベル
- 現在のスレッドバインディング(この会話/スレッドが ACP セッションにバインドされている場合)
- 現在のリクエスターセッションフォールバック
ターゲットが解決できない場合、OpenClaw は明確なエラーを返します(Unable to resolve session target: ...)。
スポーンスレッドモード
/acp spawn は --thread auto|here|off をサポート。
| モード | 動作 |
|---|---|
auto | アクティブスレッド内: そのスレッドをバインド。スレッド外: サポートされている場合に子スレッドを作成/バインド。 |
here | 現在のアクティブスレッドを要求。スレッド内でない場合は失敗。 |
off | バインディングなし。セッションはアンバインドで開始。 |
補足:
- 非スレッドバインディングサーフェスでは、デフォルト動作は実質的に
off。 - スレッドバインドスポーンにはチャンネルポリシーのサポートが必要:
- Discord:
channels.discord.threadBindings.spawnAcpSessions=true - Telegram:
channels.telegram.threadBindings.spawnAcpSessions=true
- Discord:
ACP コントロール
利用可能なコマンドファミリー:
/acp spawn/acp cancel/acp steer/acp close/acp status/acp set-mode/acp set/acp cwd/acp permissions/acp timeout/acp model/acp reset-options/acp sessions/acp doctor/acp install
/acp status は有効なランタイムオプションと、利用可能な場合はランタイムレベルおよびバックエンドレベルの両方のセッション識別子を表示します。
一部のコントロールはバックエンドの機能に依存します。バックエンドがコントロールをサポートしていない場合、OpenClaw は明確な未サポートコントロールエラーを返します。
ACP コマンドクックブック
| コマンド | 機能 | 例 |
|---|---|---|
/acp spawn | ACP セッション作成。スレッドバインド任意。 | /acp spawn codex --mode persistent --thread auto --cwd /repo |
/acp cancel | ターゲットセッションの実行中ターンをキャンセル。 | /acp cancel agent:codex:acp:<uuid> |
/acp steer | 実行中セッションにステア指示を送信。 | /acp steer --session support inbox prioritize failing tests |
/acp close | セッションを閉じてスレッドターゲットのバインドを解除。 | /acp close |
/acp status | バックエンド、モード、状態、ランタイムオプション、機能を表示。 | /acp status |
/acp set-mode | ターゲットセッションのランタイムモードを設定。 | /acp set-mode plan |
/acp set | 汎用ランタイム設定オプションの書き込み。 | /acp set model openai/gpt-5.2 |
/acp cwd | ランタイム作業ディレクトリオーバーライドを設定。 | /acp cwd /Users/user/Projects/repo |
/acp permissions | 承認ポリシープロファイルを設定。 | /acp permissions strict |
/acp timeout | ランタイムタイムアウト(秒)を設定。 | /acp timeout 120 |
/acp model | ランタイムモデルオーバーライドを設定。 | /acp model anthropic/claude-opus-4-5 |
/acp reset-options | セッションランタイムオプションオーバーライドを削除。 | /acp reset-options |
/acp sessions | ストアから最近の ACP セッションを一覧表示。 | /acp sessions |
/acp doctor | バックエンドヘルス、機能、修正可能な問題を表示。 | /acp doctor |
/acp install | 決定論的なインストールと有効化手順を表示。 | /acp install |
/acp sessions は現在のバインドまたはリクエスターセッションのストアを読み取ります。session-key、session-id、session-label トークンを受け付けるコマンドは、カスタムエージェントごとの session.store ルートを含む Gateway セッション検出を通じてターゲットを解決します。
ランタイムオプションのマッピング
/acp には便利コマンドと汎用セッターがあります。
等価な操作:
/acp model <id>はランタイム設定キーmodelにマップ。/acp permissions <profile>はランタイム設定キーapproval_policyにマップ。/acp timeout <seconds>はランタイム設定キーtimeoutにマップ。/acp cwd <path>はランタイム cwd オーバーライドを直接更新。/acp set <key> <value>は汎用パス。- 特殊ケース:
key=cwdは cwd オーバーライドパスを使用。
- 特殊ケース:
/acp reset-optionsはターゲットセッションのすべてのランタイムオーバーライドをクリア。
acpx ハーネスサポート(現在)
現在の acpx 組み込みハーネスエイリアス:
piclaudecodexopencodegeminikimi
OpenClaw が acpx バックエンドを使用する場合、acpx 設定でカスタムエージェントエイリアスを定義していない限り、agentId にはこれらの値を推奨します。
acpx CLI での直接使用では --agent <command> で任意のアダプターを指定することもできますが、これは acpx CLI の機能(通常の OpenClaw agentId パスではない)です。
必須設定
ACP のコアベースライン:
{
acp: {
enabled: true,
// 任意。デフォルトは true。/acp コントロールを維持しつつ ACP ディスパッチを一時停止するには false に設定。
dispatch: { enabled: true },
backend: "acpx",
defaultAgent: "codex",
allowedAgents: ["pi", "claude", "codex", "opencode", "gemini", "kimi"],
maxConcurrentSessions: 8,
stream: {
coalesceIdleMs: 300,
maxChunkChars: 1200,
},
runtime: {
ttlMinutes: 120,
},
},
}
スレッドバインディング設定はチャンネルアダプター固有です。Discord の例:
{
session: {
threadBindings: {
enabled: true,
idleHours: 24,
maxAgeHours: 0,
},
},
channels: {
discord: {
threadBindings: {
enabled: true,
spawnAcpSessions: true,
},
},
},
}
スレッドバインド ACP spawn が動作しない場合は、まずアダプター機能フラグを確認:
- Discord:
channels.discord.threadBindings.spawnAcpSessions=true
設定リファレンス を参照。
acpx バックエンドのプラグインセットアップ
プラグインのインストールと有効化:
openclaw plugins install acpx
openclaw config set plugins.entries.acpx.enabled true
開発中のローカルワークスペースインストール:
openclaw plugins install ./extensions/acpx
バックエンドヘルスを確認:
/acp doctor
acpx のコマンドとバージョン設定
デフォルトでは、acpx プラグイン(@openclaw/acpx として公開)はプラグインローカルのピン留めバイナリを使用:
- コマンドのデフォルトは
extensions/acpx/node_modules/.bin/acpx。 - 期待バージョンのデフォルトはエクステンションのピン。
- 起動時に ACP バックエンドを未準備として即座に登録。
- バックグラウンド確認ジョブが
acpx --versionを検証。 - プラグインローカルバイナリが欠落またはバージョン不一致の場合、
npm install --omit=dev --no-save acpx@<pinned>を実行して再検証。
プラグイン設定でコマンド/バージョンをオーバーライド可能:
{
"plugins": {
"entries": {
"acpx": {
"enabled": true,
"config": {
"command": "../acpx/dist/cli.js",
"expectedVersion": "any"
}
}
}
}
}
補足:
commandは絶対パス、相対パス、コマンド名(acpx)を受け付ける。- 相対パスは OpenClaw ワークスペースディレクトリから解決。
expectedVersion: "any"で厳密なバージョンマッチを無効化。commandがカスタムバイナリ/パスを指す場合、プラグインローカルの自動インストールは無効。- バックエンドヘルスチェックの実行中も OpenClaw の起動はブロックされない。
プラグイン を参照。
パーミッション設定
ACP セッションは非対話的に実行されます — ファイル書き込みやシェル実行のパーミッションプロンプトを承認/拒否する TTY がありません。acpx プラグインはパーミッションの扱いを制御する 2 つの設定キーを提供します:
permissionMode
ハーネスエージェントがプロンプトなしで実行できる操作を制御。
| 値 | 動作 |
|---|---|
approve-all | すべてのファイル書き込みとシェルコマンドを自動承認。 |
approve-reads | 読み取りのみ自動承認。書き込みと exec にはプロンプトが必要。 |
deny-all | すべてのパーミッションプロンプトを拒否。 |
nonInteractivePermissions
パーミッションプロンプトが表示されるはずだが対話的 TTY がない場合(ACP セッションでは常にこのケース)の動作を制御。
| 値 | 動作 |
|---|---|
fail | AcpRuntimeError でセッションを中止。(デフォルト) |
deny | パーミッションをサイレントに拒否して続行(グレースフルデグラデーション)。 |
設定方法
プラグイン設定で設定:
openclaw config set plugins.entries.acpx.config.permissionMode approve-all
openclaw config set plugins.entries.acpx.config.nonInteractivePermissions fail
これらの値を変更した後は Gateway を再起動してください。
重要: OpenClaw は現在
permissionMode=approve-readsとnonInteractivePermissions=failがデフォルトです。非対話的な ACP セッションでは、パーミッションプロンプトをトリガーする書き込みや exec はAcpRuntimeError: Permission prompt unavailable in non-interactive modeで失敗する可能性があります。パーミッションを制限する必要がある場合は、
nonInteractivePermissionsをdenyに設定して、クラッシュの代わりにグレースフルに機能低下するようにしてください。
トラブルシューティング
| 症状 | 考えられる原因 | 修正方法 |
|---|---|---|
ACP runtime backend is not configured | バックエンドプラグインが欠落または無効。 | バックエンドプラグインをインストール・有効化し、/acp doctor を実行。 |
ACP is disabled by policy (acp.enabled=false) | ACP がグローバルで無効。 | acp.enabled=true に設定。 |
ACP dispatch is disabled by policy (acp.dispatch.enabled=false) | 通常のスレッドメッセージからのディスパッチが無効。 | acp.dispatch.enabled=true に設定。 |
ACP agent "<id>" is not allowed by policy | エージェントがアローリストに未登録。 | 許可された agentId を使用するか acp.allowedAgents を更新。 |
Unable to resolve session target: ... | 不正なキー/ID/ラベルトークン。 | /acp sessions を実行し、正確なキー/ラベルをコピーしてリトライ。 |
--thread here requires running /acp spawn inside an active ... thread | --thread here がスレッドコンテキスト外で使用された。 | ターゲットスレッドに移動するか --thread auto/off を使用。 |
Only <user-id> can rebind this thread. | 別のユーザーがスレッドバインディングを所有。 | オーナーとしてリバインドするか別のスレッドを使用。 |
Thread bindings are unavailable for <channel>. | アダプターにスレッドバインディング機能がない。 | --thread off を使用するかサポートされたアダプター/チャンネルに移動。 |
Sandboxed sessions cannot spawn ACP sessions ... | ACP ランタイムはホスト側。リクエスターセッションがサンドボックス化されている。 | サンドボックスセッションからは runtime="subagent" を使用するか、非サンドボックスセッションから ACP spawn を実行。 |
sessions_spawn sandbox="require" is unsupported for runtime="acp" ... | ACP ランタイムに sandbox="require" が要求された。 | 必須サンドボックスには runtime="subagent" を使用するか、非サンドボックスセッションから sandbox="inherit" で ACP を使用。 |
| バインドセッションの ACP メタデータが欠落 | 古い/削除された ACP セッションメタデータ。 | /acp spawn で再作成し、スレッドをリバインド/フォーカス。 |
AcpRuntimeError: Permission prompt unavailable in non-interactive mode | permissionMode が非対話的 ACP セッションで書き込み/exec をブロック。 | plugins.entries.acpx.config.permissionMode を approve-all に設定し Gateway を再起動。パーミッション設定 を参照。 |
| ACP セッションが出力少なく早期に失敗 | パーミッションプロンプトが permissionMode/nonInteractivePermissions でブロック。 | Gateway ログで AcpRuntimeError を確認。フルパーミッションには permissionMode=approve-all。グレースフルデグラデーションには nonInteractivePermissions=deny。 |
| ACP セッションが作業完了後に無期限にストール | ハーネスプロセスが終了したが ACP セッションが完了を報告していない。 | ps aux | grep acpx で監視。古いプロセスを手動で kill。 |