Reintentar y reflexionar

El crate adk-retry-reflect proporciona un plugin que intercepta los fallos de las herramientas, inyecta indicaciones de reflexión en el contexto LLM y reintenta con un retroceso exponencial. Esto permite que los agentes se autocorrijan después de errores transitorios o llamadas a herramientas malformadas.

Descripción general

Cuando falla una llamada a una herramienta, el comportamiento predeterminado es devolver el error a LLM y dejar que decida qué hacer. El plugin Retry & Reflect añade una recuperación estructurada:

  1. Intercepta el fallo de la herramienta antes de que llegue a LLM
  2. Inyecta una indicación de reflexión que solicita al modelo analizar qué salió mal
  3. Reintenta la llamada a la herramienta con argumentos corregidos
  4. Aplica un retroceso exponencial si los fallos persisten
  5. Interrumpe el circuito después de fallos repetidos para evitar bucles infinitos

Instalación

[dependencies]
adk-retry-reflect = "2.1.0"

# Or via umbrella crate (included in standard tier)
adk-rust = { version = "2.1.0", features = ["standard"] }

Inicio rápido

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()?;

Configuración

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();

Referencia de configuración

ParámetroPredeterminadoDescripción
max_retries3Máximo de intentos de reintento por llamada a la herramienta
initial_backoff_ms500Retraso antes del primer reintento (milisegundos)
backoff_multiplier2.0Multiplica el retraso por este factor en cada intento
max_backoff_ms30,000Límite máximo del retraso (milisegundos)
circuit_breaker_threshold5Fallos consecutivos antes de que el circuito se abra
circuit_breaker_reset_ms60,000Tiempo antes de que el circuito vuelva a cerrarse
reflection_prompt(incorporado)Plantilla para la inyección de reflexión
include_toolstodasReintentar solo estas herramientas (vacío = todas)
exclude_toolsningunaNo reintentar nunca estas herramientas

Disyuntor

El disyuntor evita los bucles infinitos de reintentos cuando una herramienta falla persistentemente:

Closed (normal) ─── failure count >= threshold ──→ Open (all calls fail fast)
       ↑                                                    │
       └──────── reset_ms elapsed, next call succeeds ──────┘
                              (Half-Open)

Cuando el disyuntor está abierto:

  • Las llamadas a herramientas fallan inmediatamente con un error del disyuntor
  • No se intenta ningún reintento
  • Después de circuit_breaker_reset_ms, se permite la siguiente llamada (semia abierto)
  • Si tiene éxito, el disyuntor se cierra; si falla, el disyuntor permanece abierto

Cómo funciona la reflexión

Cuando falla una llamada a una herramienta, el complemento inyecta una solicitud de reflexión en la conversación:

[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"}

La solicitud de reflexión proporciona a LLM un contexto explícito sobre el fallo para que pueda autocorregirse en lugar de repetir el mismo error.

Cuándo usarlo

Buena opción:

  • Herramientas que llaman a APIs externos con fallos transitorios
  • Herramientas en las que LLM podría proporcionar argumentos ligeramente mal formados
  • Consultas a bases de datos que pueden fallar debido a problemas de conexión
  • Operaciones de archivos en almacenamiento conectado a una red

No es una buena opción:

  • Herramientas que están determinísticamente rotas (corrige la herramienta en su lugar)
  • Herramientas de larga duración en las que los reintentos son costosos
  • Herramientas con efectos secundarios que no son idempotentes (por ejemplo, enviar correos electrónicos)
  • Herramientas de flujo de control como exit_loop

Combinación con otros complementos

Reintentar y reflexionar respeta el orden de prioridad de los complementos:

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()?;

Observabilidad

El complemento emite intervalos de trazado para los intentos de reintento:

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

Anterior: ← ACP Herramientas | Siguiente: Nodos de acción →

Reintentar y reflexionar - Documentación ADK-Rust | ADK-Rust