ADK-Rust エージェントを ACP 経由で公開する

エディターまたは別の ACP クライアントから ADK-Rust バイナリを起動し、コーディングインターフェース内でそのエージェントを使用する場合は、サーバー方式を使用します。Rust プロセスがエージェント、モデル、ツール、ワークフロー、セッション、メモリ、運用ポリシーを所有します。クライアントから見えるのは、ACP を通じて公開される機能とセッションのライフサイクルだけです。

サーバー機能をインストールする

[dependencies]
adk-acp = { version = "2.1.0", features = ["server"] }

エージェントをビルドして提供する

use adk_acp::server::{AcpServer, AcpServerConfigBuilder};
use adk_session::InMemorySessionService;
use std::sync::Arc;

let config = AcpServerConfigBuilder::new()
    .agent(Arc::new(repository_agent))
    .session_service(Arc::new(InMemorySessionService::new()))
    .agent_name("repository-guide")
    .agent_description("Explains and improves this Rust workspace")
    .max_sessions(16)
    .build()?;

let handle = AcpServer::run(config).await?;
handle.wait().await?;

サーバーは公式の SDK Agent ビルダーと stdio トランスポートを使用します。プロトコルのトラフィックのみが stdout に書き込まれるため、トレーシングと診断は stderr を使用するように設定してください。

ランタイムマッピング

Rendering architecture…

ハンドラーは絶対 cwd を検証し、セッションの容量を確保し、ADK セッションを作成または再開して、設定されたエージェントを実行します。入力がアクティブな間、型付き ADK イベントは ACP session/update 通知に変換されます。

実装済みのライフサイクル

ACP 操作ADK-Rust 動作
initializeプロトコル v1 をネゴシエートし、正確な実装および機能メタデータを返します
session/newワークスペースのパスを検証し、永続化された ADK セッションを 1 つ作成します
session/prompt対応するコンテンツブロック(テキスト、リソースリンク、埋め込みリソース、画像、音声)を変換し、Runner をストリーミングします
session/load永続化されたセッションを再アクティブ化し(cwd を検証)、完了前に保存された会話を順序付けられた session/update 通知として再生します
session/cancelアクティブな Runner の呼び出しをキャンセルし、キャンセルされた停止理由を返します
$/cancel_requestセッションを破損させずに、一致する JSON-RPC リクエストをキャンセルします
session/closeアクティブな処理をキャンセルし、セッション所有のプロセスを解放します
session/list永続化された ACP から参照可能なセッションを一覧表示します
session/resume元のセッションとワークスペースに再接続します
session/fork永続化されたセッションを新しいセッション ID に分岐し、その履歴と関連する状態をコピーして、ソースは変更しません
session/set_modeエージェントのSessionControlsで宣言されたセッションモードを検証して記録し、CurrentModeUpdateを発行します
session/set_config_optionエージェントのSessionControlsで宣言された設定値を検証して記録し、ConfigOptionUpdateを発行します
session/delete永続化された履歴を削除し、アクティブなリソースを解放します

1 つのセッションで同時に実行できるプロンプトは 1 つだけです。異なるセッションは、最大 max_sessions まで並行して実行できます。

イベントマッピング

  • モデルのテキストは agent_message_chunk になります。
  • モデルの思考内容は agent_thought_chunk になります。
  • 埋め込みリソースの内容は ACP 埋め込みリソース agent_message_chunk になります。
  • ADK 関数呼び出しは、推論されたツール kind を伴う ACP ツール開始更新になります。
  • 関数のレスポンスは、結果の内容と影響を受けたファイルの場所で補足されたツール完了更新になり、元のツール呼び出しに対応付けられます。
  • 使用量メタデータを含むイベントは UsageUpdate 通知(トークン数、および報告される場合は米ドルでのコスト)になります。
  • エージェントが宣言したコマンドは、セッションがアクティブになると AvailableCommandsUpdate になり、記録されたセッションタイトルは SessionInfoUpdate になります。
  • 計画エントリは Plan 更新になります。このマッピングは存在しますが、ADK 計画プリミティブによって計画エントリが公開されるまで休止状態です。
  • キャンセルは StopReason::Cancelled になります。
  • 正常な完了は StopReason::EndTurn になります。

共有コンテンツモジュールは、ContentBlockadk_core::Part のマッピングを双方向で管理します。埋め込みリソースのプロンプトコンテンツは Part::EmbeddedResource にマッピングされ、元の URI、任意の MIME タイプ、コンテンツが保持されます。テキストリソースはそのまま保持され、バイナリリソースは通信時に base64 エンコードされ、内部では生のバイト列にデコードされます。画像および音声のプロンプトコンテンツは Part::InlineData にマッピングされ、MIME タイプ、デコードされたバイト列、アノテーション、画像の任意のソース URI が保持されます。これらのフィールドはセッション JSON に残り、session/load によって復元されます。プロンプトハンドラーは埋め込みリソース、画像、音声のコンテンツを受け付けるため、サーバーは embedded_contextimageaudio のプロンプト機能を通知します。サーバーが通知していないコンテンツタイプを含むプロンプトは、部分的に処理されるのではなく、説明的なエラーとともに拒否されます。

読み込みと履歴の再生

session/load は、クライアントが再接続した際に、永続化されたセッションの表示可能な履歴を復元します。ハンドラーは session/resume と同じ方法でセッションを再アクティブ化します。つまり、呼び出し元が元の cwd を提供したことを検証し、不明な識別子に対してセッションが見つからないエラーを返します。その後、再生パスを実行します。セッションサービスを通じて永続化されたイベントを読み取り、保存されている各ユーザー、エージェント、思考、ツールのイベントを、それぞれ対応する session/update 通知に元の時系列順でマッピングしてから、読み込みリクエストを完了します。サーバーは load_session 機能を通知するため、クライアントは再接続して会話ビューを再構築できることを認識できます。

セッションモード、設定オプション、フォーク

エージェントは、AcpServerConfigBuilder::session_controls を通じて SessionControls プロバイダーを提供することで、対話型セッション制御を有効にします。プロバイダーは、 利用可能なモード(SessionModeState)、設定オプション(選択項目と 切り替え項目)、および ACP スラッシュコマンドを宣言します。サーバーはプロバイダーが 宣言した内容をそのまま通知します。つまり、プロバイダーのないエージェントはモードもオプションも通知せず、 それらを session/newsession/loadsession/resume、および session/fork レスポンスで提供します。

session/set_mode は要求されたモード ID を通知済みの集合と照合して検証し、 それを記録して CurrentModeUpdate を発行します。不明な ID は拒否され、 現在のモードは変更されません。session/set_config_option は値をオプションに 宣言された選択肢と照合して検証し、それを記録して ConfigOptionUpdate を発行します。不明なオプションや無効な値は拒否されます。どちらの 選択も ADK セッション状態内の acp:mode および acp:config:<id> に保持されるため、読み込み、再開、フォークの後も維持されます。

session/fork は保持されたセッションを分岐します。元のセッションを読み込み、 新しいセッション ID を作成し、保存されたイベントと関連する状態(cwd、追加の ディレクトリ、モード、設定)を新しいセッションにコピーして、新しい ID を返します。元の セッションの保持された履歴は、バイト単位で変更されません。不明なセッション識別子を指定した フォークは、セッションが見つからないエラーを返します。ハンドラーが登録されているため、サーバーは fork セッション機能を通知します。

セッションのアクティベーション時に、サーバーはプロバイダーが宣言したコマンドごとに AvailableCommandsUpdate も発行します(コマンドを何も宣言していない場合は発行しません)。また、 acp:title にセッションタイトルが記録されている場合(set_session_title で設定)、 そのタイトルを含む SessionInfoUpdate を発行します。Plan 更新マッピングも 存在しますが、ADK プランプリミティブがプラン項目を提供するまで休止状態です。

クライアントが提供する MCP サーバー

クライアントは stdio MCP サーバーを session/new または session/resume に含めることができます。 サーバーはプロセスを起動する前に、名前、コマンド、引数、環境エントリを検証します。その後、次の処理を行います。

  1. 各子プロセスをセッションワークスペースで起動する;
  2. 制限付きの起動ハンドシェイクを適用する;
  3. 接続を ADK McpToolset としてラップする;
  4. その Runner 呼び出しにツールセットを注入する;
  5. 終了、削除、起動失敗、またはサーバーのシャットダウン時に MCP サービスをキャンセルする。

呼び出しスコープのツールセットは現在、LlmAgent および CodeActAgent によって解決されます。オプションの HTTP および SSE MCP トランスポートは、サーバーによって通知されません。

永続化に関する判断

InMemorySessionService は、ローカルエディタプロセスやテストに適しています。セッションをプロセスの再起動後も維持する必要がある場合は、永続的なサービスを使用してください。再開時には、呼び出し元が元の cwd を提供することが検証されます。セッションを別のプロジェクトに黙って再接続することはできません。

ツール承認の境界

サーバーは ADK のツール確認をネイティブの ACP 権限リクエストに橋渡しします。設定された agent がプロンプトターン中に ToolConfirmationRequest で一時停止した場合 — agent がツール呼び出しに対する人間の承認を待機しているときに event.actions.tool_confirmation で通知されます — サーバーはツールとその引数を記述した session/request_permission リクエストを送信し、クライアントの結果を待機してから、対応する判断で実行を再開します。承認は許可に、拒否またはキャンセルはいずれも拒否にマッピングされるため、キャンセルされたリクエストによってツールが実行されることはありません。各結果はその関数呼び出し識別子によって正確な呼び出しと関連付けられ、RunConfig::tool_confirmation_decisions を通じて runner に返されます。

ネストされた session/request_permission は、外側の session/prompt をすでに処理しているタスクから、ConnectionTo::spawn を通じて生成されます。そのため接続のディスパッチループをブロックせず、外側のプロンプト応答も完了します。公式の Rust SDK では、ネストされた双方向リクエストの後に外側のプロンプト応答が失われるという以前の懸念は、この一時停止・再開フローでは再現しません。このことはインメモリ相互運用性テストで確認されています。

サーバー所有のツール認可、読み取り専用ツール、RBAC、ガードレール、ワークフロー割り込みは、承認を完全に ADK-Rust プロセス内で行う必要がある場合でも引き続き利用できます。外部の ACP エージェント向けのクライアント側権限パスも完全に実装されています。

安全にデプロイする

  • 意図したプロジェクトワークスペースでバイナリを起動します。
  • cwd と追加のルートは、OS の分離ではなくコンテキストとして扱います。
  • 信頼できないプロンプトやコマンドには、adk-sandbox、コンテナ、または別のプロセス境界を適用します。
  • モデルと MCP の認証情報は、クライアントのシークレットストアまたはプロセス環境に保持します。
  • バナー、デバッグオブジェクト、ログをプロトコルの標準出力に書き込まないでください。
  • 再開をプロセスの再起動後も維持する必要がある場合は、永続的な SessionService を使用します。
  • 有限のセッション制限を設定し、非アクティブなセッションを終了します。

実行可能な acp_server crate には、Gemini ベースのエージェント、ワークスペース内に制限された読み取りツール、標準エラー出力へのトレース、エディタープロセスの設定が含まれています。

次のステップ