서버 API

ADK-Rust 서버는 에이전트 실행, 세션 관리 및 아티팩트 접근을 위한 REST API를 제공합니다. 서버 모드에서 Launcher를 사용하여 에이전트를 배포하면, 이러한 엔드포인트와 웹 UI가 노출됩니다.

개요

서버는 Axum을 기반으로 구축되었으며 다음을 제공합니다:

  • REST API: 에이전트 실행 및 세션 관리를 위한 HTTP 엔드포인트
  • Server-Sent Events (SSE): 에이전트 응답의 실시간 스트리밍
  • Web UI: 대화형 브라우저 기반 인터페이스
  • CORS 지원: 교차 출처 요청 활성화
  • Telemetry: 트레이싱을 통한 내장된 관찰 가능성

ServerConfig는 또한 장기 실행 배포를 위한 runner 수준의 passthrough를 노출합니다:

let config = ServerConfig::new(agent_loader, session_service)
    .with_compaction(compaction_config)
    .with_context_cache(context_cache_config, cache_capable_model);

서버 시작

Launcher를 사용하여 서버를 시작합니다:

use adk_rust::prelude::*;
use adk_rust::Launcher;
use std::sync::Arc;

#[tokio::main]
async fn main() -> Result<()> {
    let api_key = std::env::var("GOOGLE_API_KEY")?;
    let model = Arc::new(GeminiModel::new(&api_key, "gemini-2.5-flash")?);
    
    let agent = LlmAgentBuilder::new("my_agent")
        .description("A helpful assistant")
        .instruction("You are a helpful assistant.")
        .model(model)
        .build()?;
    
    Launcher::new(Arc::new(agent)).run().await
}

검증된 API 스캐폴드에서 시작합니다:

cargo adk new my-api --template api
cd my-api
cargo run

REST API 엔드포인트

상태 확인

서버가 실행 중인지 확인합니다:

GET /api/health

응답:

OK

스트리밍으로 Agent 실행

Server-Sent Events를 사용하여 agent를 실행하고 응답을 스트리밍합니다:

POST /api/run_sse

요청 본문:

{
  "appName": "my_agent",
  "userId": "user123",
  "sessionId": "session456",
  "newMessage": {
    "role": "user",
    "parts": [
      {
        "text": "What is the capital of France?"
      }
    ]
  },
  "streaming": true
}

응답:

  • Content-Type: text/event-stream
  • JSON 객체로 이벤트를 스트리밍합니다.

이벤트 형식:

{
  "id": "evt_123",
  "timestamp": 1234567890,
  "author": "my_agent",
  "content": {
    "role": "model",
    "parts": [
      {
        "text": "The capital of France is Paris."
      }
    ]
  },
  "actions": {},
  "llm_response": {
    "content": {
      "role": "model",
      "parts": [
        {
          "text": "The capital of France is Paris."
        }
      ]
    }
  }
}

Session 관리

Session 생성

새로운 session을 생성합니다:

POST /api/sessions

요청 본문:

{
  "appName": "my_agent",
  "userId": "user123",
  "sessionId": "session456"
}

응답:

{
  "id": "session456",
  "appName": "my_agent",
  "userId": "user123",
  "lastUpdateTime": 1234567890,
  "events": [],
  "state": {}
}

Session 가져오기

session 세부 정보를 검색합니다:

GET /api/sessions/:app_name/:user_id/:session_id

응답:

{
  "id": "session456",
  "appName": "my_agent",
  "userId": "user123",
  "lastUpdateTime": 1234567890,
  "events": [],
  "state": {}
}

Session 삭제

session을 삭제합니다:

DELETE /api/sessions/:app_name/:user_id/:session_id

응답:

  • 상태: 204 No Content

Sessions 목록

사용자의 모든 sessions을 나열합니다:

GET /api/apps/:app_name/users/:user_id/sessions

응답:

[
  {
    "id": "session456",
    "appName": "my_agent",
    "userId": "user123",
    "lastUpdateTime": 1234567890,
    "events": [],
    "state": {}
  }
]

아티팩트 관리

아티팩트 목록

session의 모든 아티팩트를 나열합니다:

GET /api/sessions/:app_name/:user_id/:session_id/artifacts

응답:

[
  "image1.png",
  "document.pdf",
  "data.json"
]

아티팩트 가져오기

아티팩트를 다운로드합니다:

GET /api/sessions/:app_name/:user_id/:session_id/artifacts/:artifact_name

응답:

  • Content-Type: 파일 확장자에 따라 결정됨
  • 본문: 바이너리 또는 텍스트 콘텐츠

애플리케이션 관리

애플리케이션 목록

사용 가능한 모든 agents를 나열합니다:

GET /api/apps
GET /api/list-apps  (legacy compatibility)

응답:

{
  "apps": [
    {
      "name": "my_agent",
      "description": "A helpful assistant"
    }
  ]
}

Web UI

서버에는 다음에서 접근 가능한 내장된 web UI가 포함되어 있습니다:

http://localhost:8080/ui/

기능

  • 대화형 Chat: 메시지를 보내고 스트리밍 응답을 받습니다.
  • Session 관리: sessions을 생성, 보고, 전환합니다.
  • Multi-Agent 지원: agent 전송 및 계층 구조를 시각화합니다.
  • Artifact Viewer: session 아티팩트를 보고 다운로드합니다.
  • 실시간 업데이트: 즉각적인 응답을 위한 SSE 기반 스트리밍

UI 경로

  • / - /ui/로 리디렉션됩니다.
  • /ui/ - 메인 chat 인터페이스
  • /ui/assets/* - 정적 자산 (CSS, JS, 이미지)
  • /ui/assets/config/runtime-config.json - 런타임 구성

클라이언트 예시

JavaScript/TypeScript

Fetch API를 SSE와 함께 사용:

async function runAgent(message) {
  const response = await fetch('http://localhost:8080/api/run_sse', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      appName: 'my_agent',
      userId: 'user123',
      sessionId: 'session456',
      newMessage: {
        role: 'user',
        parts: [{ text: message }]
      },
      streaming: true
    })
  });

  const reader = response.body.getReader();
  const decoder = new TextDecoder();

  while (true) {
    const { done, value } = await reader.read();
    if (done) break;
    
    const chunk = decoder.decode(value);
    const lines = chunk.split('\n');
    
    for (const line of lines) {
      if (line.startsWith('data: ')) {
        const event = JSON.parse(line.slice(6));
        console.log('Event:', event);
      }
    }
  }
}

Python

requests 라이브러리 사용:

import requests
import json

def run_agent(message):
    url = 'http://localhost:8080/api/run_sse'
    payload = {
        'appName': 'my_agent',
        'userId': 'user123',
        'sessionId': 'session456',
        'newMessage': {
            'role': 'user',
            'parts': [{'text': message}]
        },
        'streaming': True
    }
    
    response = requests.post(url, json=payload, stream=True)
    
    for line in response.iter_lines():
        if line:
            line_str = line.decode('utf-8')
            if line_str.startswith('data: '):
                event = json.loads(line_str[6:])
                print('Event:', event)

run_agent('What is the capital of France?')

cURL

# Create session
curl -X POST http://localhost:8080/api/sessions \
  -H "Content-Type: application/json" \
  -d '{
    "appName": "my_agent",
    "userId": "user123",
    "sessionId": "session456"
  }'

# Run agent with streaming
curl -X POST http://localhost:8080/api/run_sse \
  -H "Content-Type: application/json" \
  -d '{
    "appName": "my_agent",
    "userId": "user123",
    "sessionId": "session456",
    "newMessage": {
      "role": "user",
      "parts": [{"text": "What is the capital of France?"}]
    },
    "streaming": true
  }'

서버 구성

사용자 지정 포트

사용자 지정 포트의 경우, 생성된 서버를 시작하기 전에 PORT를 설정합니다:

PORT=3000 cargo run

사용자 지정 Artifact Service

자신만의 artifact service를 제공합니다:

use adk_artifact::InMemoryArtifactService;

let artifact_service = Arc::new(InMemoryArtifactService::new());

Launcher::new(Arc::new(agent))
    .with_artifact_service(artifact_service)
    .run()
    .await

사용자 지정 Session Service

프로덕션 배포의 경우, 영구적인 session service를 사용합니다:

use adk_session::SqliteSessionService;

// Note: This requires implementing a custom server setup
// The Launcher uses InMemorySessionService by default

오류 처리

API는 오류 범주에서 파생된 HTTP 상태 코드를 사용하여 구조화된 오류 응답을 사용합니다:

상태 코드범주의미
200성공
204성공 (콘텐츠 없음)
400invalid_input잘못된 요청 — 유효하지 않은 매개변수 또는 구성
401unauthorized자격 증명 누락 또는 유효하지 않음
403forbidden유효한 자격 증명, 불충분한 권한
404not_found리소스를 찾을 수 없음
408timeout작업 시간 초과
429rate_limited업스트림 속도 제한 초과
500internal내부 서버 오류
501unsupported지원되지 않는 기능
503unavailable업스트림 서비스 사용 불가

오류 응답 형식 (문제 JSON):

{
  "error": {
    "code": "model.openai.rate_limited",
    "message": "OpenAI rate limit exceeded",
    "component": "model",
    "category": "rate_limited",
    "requestId": "req-abc123",
    "retryAfter": 5000,
    "upstreamStatusCode": 429
  }
}

필드 requestId, retryAfter, upstreamStatusCode는 사용 가능한 경우 포함됩니다 (그렇지 않으면 null).

CORS 구성

서버는 기본적으로 허용적인 CORS를 활성화하여 모든 출처의 요청을 허용합니다. 이는 개발에는 적합하지만, 프로덕션에서는 제한되어야 합니다.

텔레메트리

서버는 시작될 때 텔레메트리를 자동으로 초기화합니다. 로그는 구조화된 형식으로 stdout에 출력됩니다.

로그 레벨:

  • ERROR: 치명적인 오류
  • WARN: 경고
  • INFO: 일반 정보 (기본값)
  • DEBUG: 상세 디버깅
  • TRACE: 매우 상세한 추적

로그 레벨은 RUST_LOG 환경 변수로 설정합니다:

RUST_LOG=debug cargo run

모범 사례

  1. 세션 관리: 에이전트를 실행하기 전에 항상 세션을 생성하세요
  2. 오류 처리: HTTP 상태 코드를 확인하고 오류를 적절하게 처리하세요
  3. 스트리밍: 실시간 응답을 위해 SSE를 사용하고, 이벤트를 한 줄씩 파싱하세요
  4. 보안: 프로덕션 환경에서는 인증을 구현하고 CORS를 제한하세요
  5. 영속성: 프로덕션 배포에는 SqliteSessionService 또는 PostgresSessionService를 사용하세요
  6. 모니터링: 텔레메트리를 활성화하고 문제 발생 시 로그를 모니터링하세요

풀스택 예제

완전히 작동하는 서버 스캐폴드를 위해 검증된 cargo-adk API 템플릿을 사용하세요. 이는 다음을 보여줍니다:

  • 프런트엔드: HTML/JavaScript 클라이언트와 실시간 스트리밍
  • 백엔드: ADK 에이전트와 사용자 지정 연구 및 PDF 생성 도구
  • 통합: SSE 스트리밍을 통한 완전한 REST API 사용
  • 아티팩트: PDF 생성 및 다운로드
  • 세션 관리: 자동 세션 생성 및 처리

이 예제는 ADK-Rust를 사용하여 AI 기반 웹 애플리케이션을 구축하기 위한 프로덕션 준비 패턴을 보여줍니다.

빠른 시작:

cargo adk new my-api --template api
cd my-api
cargo run

파일:

  • 백엔드: adk-rust-guide/examples/deployment/full_stack_research.rs
  • 프런트엔드: examples/research_paper/frontend.html
  • 문서: examples/research_paper/README.md
  • 아키텍처: examples/research_paper/architecture.md

이전: ← Launcher | 다음: A2A Protocol →

서버 API - ADK-Rust 문서 | ADK-Rust