Réessayer et réfléchir
La crate adk-retry-reflect fournit un plugin qui intercepte les échecs des outils, injecte des invites de réflexion dans le contexte LLM et réessaie avec une temporisation exponentielle. Cela permet aux agents de s’auto-corriger après des erreurs transitoires ou des appels d’outils mal formés.
Vue d’ensemble
Lorsqu’un appel d’outil échoue, le comportement par défaut consiste à renvoyer l’erreur à LLM et à le laisser décider de la marche à suivre. Le plugin Retry & Reflect ajoute une récupération structurée :
- Intercepte l’échec de l’outil avant qu’il n’atteigne LLM
- Injecte une invite de réflexion demandant au modèle d’analyser ce qui s’est mal passé
- Réessaie l’appel de l’outil avec des arguments corrigés
- Applique une temporisation exponentielle si les échecs persistent
- Déclenche l’ouverture du circuit après des échecs répétés afin d’éviter les boucles infinies
Installation
[dependencies]
adk-retry-reflect = "2.1.0"
# Or via umbrella crate (included in standard tier)
adk-rust = { version = "2.1.0", features = ["standard"] }
Démarrage rapide
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()?;
Configuration
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();
Référence de configuration
| Paramètre | Par défaut | Description |
|---|---|---|
max_retries | 3 | Nombre maximal de tentatives par appel d’outil |
initial_backoff_ms | 500 | Délai avant la première nouvelle tentative (millisecondes) |
backoff_multiplier | 2.0 | Multiplier le délai par ce facteur à chaque tentative |
max_backoff_ms | 30,000 | Délai maximal (millisecondes) |
circuit_breaker_threshold | 5 | Nombre d’échecs consécutifs avant l’ouverture du circuit |
circuit_breaker_reset_ms | 60,000 | Délai avant la réinitialisation du circuit à l’état fermé |
reflection_prompt | (intégré) | Modèle pour l’injection de réflexion |
include_tools | tous | Réessayer uniquement ces outils (vide = tous) |
exclude_tools | aucun | Ne jamais réessayer ces outils |
Disjoncteur
Le disjoncteur empêche les boucles de nouvelle tentative infinies lorsqu’un outil échoue de manière persistante :
Closed (normal) ─── failure count >= threshold ──→ Open (all calls fail fast)
↑ │
└──────── reset_ms elapsed, next call succeeds ──────┘
(Half-Open)
Lorsque le circuit est ouvert :
- Les appels d’outils échouent immédiatement avec une erreur de disjoncteur
- Aucune nouvelle tentative n’est effectuée
- Après
circuit_breaker_reset_ms, l’appel suivant est autorisé (semi-ouvert) - S’il réussit, le circuit se ferme ; s’il échoue, le circuit reste ouvert
Fonctionnement de la réflexion
Lorsqu’un appel d’outil échoue, le plugin injecte une invite de réflexion dans la conversation :
[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"}
L’invite de réflexion fournit à LLM un contexte explicite sur l’échec afin qu’il puisse se corriger lui-même plutôt que de répéter la même erreur.
Quand l’utiliser
Bon choix :
- Outils qui appellent des APIs externes avec des échecs transitoires
- Outils pour lesquels LLM peut fournir des arguments légèrement mal formés
- Requêtes de base de données pouvant échouer en raison de problèmes de connexion
- Opérations sur des fichiers stockés sur un réseau
Moins adapté :
- Outils défaillants de manière déterministe (corrigez plutôt l’outil)
- Outils à longue durée d’exécution pour lesquels les nouvelles tentatives sont coûteuses
- Outils ayant des effets secondaires qui ne sont pas idempotents (par exemple, l’envoi d’e-mails)
- Outils de contrôle du flux tels que
exit_loop
Combinaison avec d’autres plugins
Retry & Reflect respecte l’ordre de priorité des plugins :
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()?;
Observabilité
Le plugin émet des spans de traçage pour les tentatives :
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
Voir aussi
- Plugins — Architecture du système de plugins
- Outils de fonction — Créer des outils
- Évaluation — Tester la résilience de l’agent
Précédent : ← ACP Tools | Suivant : Nœuds d’action →