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에 기록되며, tracing 및 진단은 stderr를 사용하도록 구성합니다.
런타임 매핑
핸들러는 절대 cwd를 검증하고, 세션 용량을 예약하며, ADK 세션을
생성하거나 재개한 다음 구성된 에이전트를 실행합니다. 프롬프트가 활성화된 동안
형식화된 ADK 이벤트는 ACP session/update 알림으로 변환됩니다.
구현된 수명 주기
| ACP 작업 | ADK-Rust 동작 |
|---|---|
initialize | 프로토콜 v1을 협상하고 정확한 구현 및 기능 메타데이터를 반환합니다 |
session/new | 작업 공간 경로의 유효성을 검사하고 하나의 영구 ADK 세션을 생성합니다 |
session/prompt | 지원되는 콘텐츠 블록(text, resource-link, embedded-resource, image, audio)을 변환하고 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 | 저장된 기록을 제거하고 활성 리소스를 해제합니다 |
세션당 하나의 프롬프트만 실행할 수 있습니다. 서로 다른 세션은 max_sessions까지 동시에 실행할 수 있습니다.
이벤트 매핑
- 모델 텍스트는
agent_message_chunk이 됩니다. - 모델 사고 콘텐츠는
agent_thought_chunk이 됩니다. - 포함된 리소스 콘텐츠는 ACP 포함된 리소스
agent_message_chunk이 됩니다. - ADK 함수 호출은 추론된 도구
kind가 포함된 ACP 도구 시작 업데이트가 됩니다. - 함수 응답은 결과 콘텐츠와 영향을 받은 파일 위치로 보강된 도구 완료 업데이트가 되며, 시작된 도구 호출을 기준으로 연결됩니다.
- 사용량 메타데이터를 전달하는 이벤트는
UsageUpdate알림이 됩니다(토큰 수와 보고된 경우 USD 기준 비용 포함). - 에이전트가 선언한 명령은 세션이 활성화될 때
AvailableCommandsUpdate이 되며, 기록된 세션 제목은SessionInfoUpdate가 됩니다. - 계획 항목은
Plan업데이트가 됩니다. 이 매핑은 존재하지만 ADK 계획 기본 요소가 계획 항목을 표시할 때까지 비활성 상태로 유지됩니다. - 취소는
StopReason::Cancelled가 됩니다. - 정상 완료는
StopReason::EndTurn가 됩니다.
공유 콘텐츠 모듈은 양방향으로 ContentBlock ↔ adk_core::Part 매핑을 관리합니다. 임베디드 리소스 프롬프트 콘텐츠는 Part::EmbeddedResource에 매핑되며, 원본 URI, 선택적 MIME 유형 및 콘텐츠를 보존합니다. 텍스트 리소스는 있는 그대로 보존되는 반면, 바이너리 리소스는 전송 시 base64로 인코딩되고 내부적으로 원시 바이트로 디코딩됩니다. 이미지 및 오디오 프롬프트 콘텐츠는 Part::InlineData에 매핑되며, MIME 유형, 디코딩된 바이트, 주석 및 이미지의 선택적 소스 URI를 보존합니다. 이러한 필드는 세션 JSON에 유지되며 session/load에 의해 복원됩니다. 프롬프트 핸들러는 임베디드 리소스, 이미지 및 오디오 콘텐츠를 허용하므로 서버는 embedded_context, image 및 audio 프롬프트 기능을 광고합니다. 서버가 광고하지 않은 콘텐츠 유형을 포함하는 프롬프트는 부분적으로 처리되는 대신 설명적인 오류와 함께 거부됩니다.
로드 및 기록 재생
session/load는 클라이언트가 다시 연결할 때 영속화된 세션의 표시 가능한 기록을 복원합니다. 핸들러는 session/resume와 동일한 방식으로 세션을 다시 활성화합니다. 즉, 호출자가 원래 cwd을 제공했는지 검증하고, 알 수 없는 식별자에 대해서는 세션을 찾을 수 없음 오류를 반환한 다음 재생 단계를 수행합니다. 세션 서비스를 통해 영속화된 이벤트를 읽고 저장된 각 사용자, 에이전트, 사고 및 도구 이벤트를 해당 session/update 알림에 매핑하며, 로드 요청이 완료되기 전에 원래의 시간순으로 처리합니다. 서버는 load_session 기능을 광고하므로 클라이언트는 다시 연결하여 대화 보기를 재구성할 수 있습니다.
세션 모드, 구성 옵션 및 포크
에이전트는 AcpServerConfigBuilder::session_controls을 통해 SessionControls
provider를 제공하여 대화형 세션 제어 기능을 선택적으로 활성화합니다. provider는
사용 가능한 모드(SessionModeState), 구성 옵션(선택 항목 및
토글), 그리고 ACP 슬래시 명령을 선언합니다. 서버는 provider가
선언한 내용을 정확히 광고합니다. 즉, provider가 없는 에이전트는 모드도 옵션도 광고하지 않으며,
이를 session/new, session/load, session/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 세션 기능을 광고합니다.
세션이 활성화되면 서버는 provider가 선언한 모든 명령에 대해
AvailableCommandsUpdate도 발생시킵니다(아무것도 선언하지 않은 경우에는 발생시키지 않음). 또한
acp:title 아래에 세션 제목이 기록되어 있는 경우(set_session_title을 통해
설정됨) 해당 제목을 담은 SessionInfoUpdate을 발생시킵니다. Plan 업데이트 매핑은
존재하지만, ADK 계획 프리미티브가 계획 항목을 표시할 때까지는
비활성 상태로 유지됩니다.
클라이언트가 제공하는 MCP 서버
클라이언트는 session/new 또는 session/resume에 stdio MCP 서버를 포함할 수 있습니다.
서버는 프로세스를 시작하기 전에 이름, 명령, 인수 및 환경 항목을 검증합니다. 그런 다음:
- 각 자식을 세션 작업 공간에서 시작합니다.
- 제한된 시작 핸드셰이크를 적용합니다.
- 연결을 ADK
McpToolset로 래핑합니다. - 해당 Runner 호출에 도구 세트를 주입합니다.
- 종료, 삭제, 시작 실패 또는 서버 종료 시 MCP 서비스를 취소합니다.
호출 범위 도구 세트는 현재 LlmAgent 및
CodeActAgent에 의해 확인됩니다. 선택적 HTTP 및 SSE MCP 전송은 서버에서
광고되지 않습니다.
지속성 결정
InMemorySessionService은 로컬 편집기 프로세스와 테스트에 적합합니다. 세션이 프로세스 재시작 후에도
유지되어야 한다면 내구성 있는 서비스를 사용합니다. 재개 시 호출자가 원래의 cwd을
제공하는지 검증합니다. 세션을 다른 프로젝트에 자동으로 다시 연결할 수는 없습니다.
도구 승인 경계
서버는 ADK 도구 확인을 기본 ACP 권한 요청으로 연결합니다.
구성된 에이전트가 프롬프트 턴 중 ToolConfirmationRequest에서 일시 중지되면 — 에이전트가 도구 호출에 대한
사람의 승인을 기다릴 때 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 크레이트에는 Gemini 기반 에이전트, 작업 공간으로 범위가 제한된 읽기 도구, stderr 추적 및 편집기 프로세스 구성이 포함되어 있습니다.