Runner
adk-runner의 실행 런타임으로, agent 실행을 조율합니다.
개요
Runner는 agent 실행의 전체 라이프사이클을 관리합니다:
- Session 관리 (session 생성/조회)
- Memory 주입 (관련 memory 검색 및 주입)
- Artifact 처리 (범위가 지정된 artifact 접근)
- Event 스트리밍 (event 처리 및 전달)
- Agent 전송 (다중 agent 핸드오프 처리)
설치
[dependencies]
adk-runner = "0.2.0"
RunnerConfig
필수 서비스로 runner를 구성합니다:
use adk_runner::{Runner, RunnerConfig};
use adk_session::InMemorySessionService;
use adk_artifact::InMemoryArtifactService;
use std::sync::Arc;
let config = RunnerConfig {
app_name: "my_app".to_string(),
agent: Arc::new(my_agent),
session_service: Arc::new(InMemorySessionService::new()),
artifact_service: Some(Arc::new(InMemoryArtifactService::new())),
memory_service: None,
run_config: None,
};
let runner = Runner::new(config)?;
구성 필드
| Field | Type | Required | Description |
|---|---|---|---|
app_name | String | 예 | 애플리케이션 식별자 |
agent | Arc<dyn Agent> | 예 | 실행할 루트 agent |
session_service | Arc<dyn SessionService> | 예 | Session 저장 백엔드 |
artifact_service | Option<Arc<dyn ArtifactService>> | 아니요 | Artifact 저장소 |
memory_service | Option<Arc<dyn Memory>> | 아니요 | 장기 memory |
run_config | Option<RunConfig> | 아니요 | 실행 옵션 |
Agent 실행
사용자 입력으로 agent를 실행합니다:
use adk_core::Content;
use futures::StreamExt;
let user_content = Content::new("user").with_text("Hello!");
let mut stream = runner.run(
"user-123".to_string(),
"session-456".to_string(),
user_content,
).await?;
while let Some(event) = stream.next().await {
match event {
Ok(e) => {
if let Some(content) = e.content() {
for part in &content.parts {
if let Some(text) = part.text() {
print!("{}", text);
}
}
}
}
Err(e) => eprintln!("Error: {}", e),
}
}
실행 흐름
┌─────────────────────────────────────────────────────────────┐
│ Runner.run() │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 1. 세션 검색 │
│ │
│ SessionService.get(app_name, user_id, session_id) │
│ → 존재하지 않으면 새 세션을 생성합니다 │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 2. Agent 선택 │
│ │
│ 활성 agent를 위해 세션 상태를 확인합니다 │
│ → root agent 또는 전송된 agent를 사용합니다 │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 3. 컨텍스트 생성 │
│ │
│ InvocationContext 포함: │
│ - Session (가변) │
│ - Artifacts (세션 범위) │
│ - Memory (구성된 경우) │
│ - Run config │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 4. Agent 실행 │
│ │
│ agent.run(ctx) → EventStream │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 5. 이벤트 처리 │
│ │
│ 각 이벤트에 대해: │
│ - 세션 상태 업데이트 │
│ - 전송 처리 │
│ - 호출자에게 전달 │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 6. 세션 저장 │
│ │
│ SessionService.append_event(session, events) │
└─────────────────────────────────────────────────────────────┘
InvocationContext
실행 중에 에이전트에 제공되는 컨텍스트:
pub trait InvocationContext: CallbackContext {
/// The agent being executed
fn agent(&self) -> Arc<dyn Agent>;
/// Memory service (if configured)
fn memory(&self) -> Option<Arc<dyn Memory>>;
/// Current session
fn session(&self) -> &dyn Session;
/// Execution configuration
fn run_config(&self) -> &RunConfig;
/// Signal end of invocation
fn end_invocation(&self);
/// Check if invocation has ended
fn ended(&self) -> bool;
}
RunConfig
실행 옵션:
pub struct RunConfig {
/// Streaming mode for responses
pub streaming_mode: StreamingMode,
}
pub enum StreamingMode {
/// No streaming, return complete response
None,
/// Server-Sent Events (default)
SSE,
/// Bidirectional streaming (realtime)
Bidi,
}
참고:
max_turns및include_history와 같은 추가 필드는 향후 릴리스에서 계획되어 있습니다.
에이전트 전환
Runner는 다중 에이전트 전환을 자동으로 처리합니다:
// In an agent's tool or callback
if should_transfer {
// Set transfer in event actions
ctx.set_actions(EventActions {
transfer_to_agent: Some("specialist_agent".to_string()),
..Default::default()
});
}
Runner는 다음을 수행합니다:
- 이벤트에서 전환 요청을 감지합니다.
sub_agents에서 대상 Agent를 찾습니다.- 새로운 활성 Agent로 세션 상태를 업데이트합니다.
- 새로운 Agent로 실행을 계속합니다.
Launcher와의 통합
Launcher는 내부적으로 Runner를 사용합니다:
// Launcher creates Runner with default services
Launcher::new(agent)
.app_name("my_app")
.run()
.await?;
// Equivalent to:
let runner = Runner::new(RunnerConfig {
app_name: "my_app".to_string(),
agent,
session_service: Arc::new(InMemorySessionService::new()),
artifact_service: Some(Arc::new(FileArtifactService::new("./artifacts")?)),
memory_service: None,
run_config: None,
})?;
사용자 지정 Runner 사용법
고급 시나리오의 경우, Runner를 직접 사용하세요:
use adk_runner::{Runner, RunnerConfig};
use adk_session::DatabaseSessionService;
use adk_artifact::S3ArtifactService;
use adk_memory::QdrantMemoryService;
// Production configuration
let config = RunnerConfig {
app_name: "production_app".to_string(),
agent: my_agent,
session_service: Arc::new(DatabaseSessionService::new(db_pool)),
artifact_service: Some(Arc::new(S3ArtifactService::new(s3_client))),
memory_service: Some(Arc::new(QdrantMemoryService::new(qdrant_client))),
run_config: None, // Uses default SSE streaming
};
let runner = Runner::new(config)?;
// Use in HTTP handler
async fn chat_handler(runner: &Runner, request: ChatRequest) -> Response {
let stream = runner.run(
request.user_id,
request.session_id,
request.content,
).await?;
// Stream events to client
Response::sse(stream)
}
이전: ← 코어 타입 | 다음: Launcher →