재시도 및 성찰
adk-retry-reflect 크레이트는 도구 실패를 가로채고, LLM 컨텍스트에 성찰 프롬프트를 주입하며, 지수 백오프를 적용해 재시도하는 플러그인을 제공합니다. 이를 통해 에이전트는 일시적인 오류나 잘못 구성된 도구 호출 이후 스스로 수정할 수 있습니다.
개요
도구 호출이 실패하면 기본 동작은 오류를 LLM에 반환하고 무엇을 할지 결정하도록 하는 것입니다. Retry & Reflect 플러그인은 구조화된 복구 기능을 추가합니다.
- 도구 실패가 LLM에 도달하기 전에 가로챕니다
- 모델에 무엇이 잘못되었는지 분석하도록 요청하는 성찰 프롬프트를 주입합니다
- 수정된 인수로 도구 호출을 재시도합니다
- 실패가 지속되면 지수적으로 백오프합니다
- 무한 루프를 방지하기 위해 반복된 실패 후 회로를 차단합니다
설치
[dependencies]
adk-retry-reflect = "2.1.0"
# Or via umbrella crate (included in standard tier)
adk-rust = { version = "2.1.0", features = ["standard"] }
빠른 시작
use adk_retry_reflect::RetryReflectPlugin;
use adk_agent::LlmAgentBuilder;
use std::sync::Arc;
let plugin = RetryReflectPlugin::builder()
.max_retries(3)
.initial_backoff_ms(500)
.backoff_multiplier(2.0)
.build();
let agent = LlmAgentBuilder::new("resilient_agent")
.model(model)
.instruction("You are a helpful assistant with access to external APIs.")
.tool(Arc::new(flaky_api_tool))
.plugin(Arc::new(plugin))
.build()?;
구성
use adk_retry_reflect::{RetryReflectPlugin, RetryReflectConfig};
let plugin = RetryReflectPlugin::builder()
// Retry settings
.max_retries(3) // Maximum retry attempts [default: 3]
.initial_backoff_ms(500) // First retry delay in ms [default: 500]
.backoff_multiplier(2.0) // Multiply delay each retry [default: 2.0]
.max_backoff_ms(30_000) // Cap delay at this value [default: 30000]
// Circuit breaker
.circuit_breaker_threshold(5) // Open circuit after N failures [default: 5]
.circuit_breaker_reset_ms(60_000) // Reset circuit after this duration [default: 60000]
// Reflection
.reflection_prompt( // Custom reflection prompt template
"The tool '{tool_name}' failed with: {error}. \
Analyze what went wrong and provide corrected arguments."
)
// Scope
.include_tools(&["api_call", "db_query"]) // Only retry these tools
.exclude_tools(&["exit_loop"]) // Never retry these tools
.build();
구성 참조
| 매개변수 | 기본값 | 설명 |
|---|---|---|
max_retries | 3 | 도구 호출당 최대 재시도 횟수 |
initial_backoff_ms | 500 | 첫 번째 재시도 전 지연 시간(밀리초) |
backoff_multiplier | 2.0 | 각 시도마다 지연 시간을 이 배수만큼 늘림 |
max_backoff_ms | 30,000 | 최대 지연 한도(밀리초) |
circuit_breaker_threshold | 5 | 회로가 열리기 전 연속 실패 횟수 |
circuit_breaker_reset_ms | 60,000 | 회로가 닫힌 상태로 재설정되기까지의 시간 |
reflection_prompt | (내장) | 성찰 주입을 위한 템플릿 |
include_tools | 모두 | 이러한 도구만 재시도(비어 있음 = 모두) |
exclude_tools | 없음 | 이러한 도구는 재시도하지 않음 |
회로 차단기
회로 차단기는 도구가 지속적으로 실패할 때 무한 재시도 루프를 방지합니다.
Closed (normal) ─── failure count >= threshold ──→ Open (all calls fail fast)
↑ │
└──────── reset_ms elapsed, next call succeeds ──────┘
(Half-Open)
회로가 열려 있을 때:
- 도구 호출은 회로 차단기 오류와 함께 즉시 실패합니다
- 재시도가 수행되지 않습니다
circuit_breaker_reset_ms후 다음 호출이 허용됩니다(반개방)- 성공하면 회로가 닫히고, 실패하면 회로가 열린 상태로 유지됩니다
Reflection 작동 방식
도구 호출이 실패하면 플러그인이 대화에 Reflection 프롬프트를 삽입합니다.
[User]: What's the weather in NYC?
[Model]: *calls get_weather({"city": "nyc", "units": "kelvin"})*
[Tool Error]: Invalid units. Supported: celsius, fahrenheit
[Plugin injects]: The tool 'get_weather' failed with: "Invalid units.
Supported: celsius, fahrenheit". Analyze what went wrong and provide
corrected arguments.
[Model]: *calls get_weather({"city": "NYC", "units": "celsius"})*
[Tool Success]: {"temperature": 22, "condition": "sunny"}
Reflection 프롬프트는 LLM에 실패에 대한 명시적인 컨텍스트를 제공하므로, 동일한 실수를 반복하는 대신 스스로 수정할 수 있습니다.
사용 시점
적합한 경우:
- 일시적인 오류가 발생하는 외부 APIs를 호출하는 도구
- LLM가 약간 잘못된 인수를 제공할 수 있는 도구
- 연결 문제로 인해 실패할 수 있는 데이터베이스 쿼리
- 네트워크 스토리지에서 수행하는 파일 작업
적합하지 않은 경우:
- 결정적으로 손상된 도구(대신 도구를 수정하세요)
- 재시도 비용이 높은 장시간 실행 도구
- 멱등적이지 않은 부작용이 있는 도구(예: 이메일 전송)
exit_loop와 같은 제어 흐름 도구
다른 플러그인과 함께 사용
Retry & Reflect는 플러그인 우선순위 순서를 따릅니다.
use adk_plugin::PluginManager;
let agent = LlmAgentBuilder::new("agent")
.model(model)
.plugin(Arc::new(logging_plugin)) // Priority 1 (runs first)
.plugin(Arc::new(retry_reflect_plugin)) // Priority 2
.plugin(Arc::new(guardrail_plugin)) // Priority 3 (runs last)
.build()?;
관측 가능성
플러그인은 재시도 시도에 대한 추적 스팬을 생성합니다.
WARN adk_retry_reflect: tool call failed, retrying
tool_name=get_weather attempt=1 max=3 backoff_ms=500
error="Invalid units"
INFO adk_retry_reflect: retry succeeded
tool_name=get_weather attempt=2
WARN adk_retry_reflect: circuit breaker opened
tool_name=broken_api failures=5 reset_ms=60000