Patterns d'Évaluation Agentic
Patterns pour l'auto-amélioration à travers l'évaluation itérative et le perfectionnement.
Aperçu
Les patterns d'évaluation permettent aux agents d'évaluer et d'améliorer leurs propres outputs, allant au-delà de la génération unique vers des boucles de perfectionnement itérative.
Générer → Évaluer → Critiquer → Affiner → Output
↑ │
└──────────────────────────────┘
Quand utiliser
- Génération critique en qualité : Code, rapports, analyses nécessitant une haute précision
- Tâches avec des critères d'évaluation clairs : Métriques de succès définies
- Contenu nécessitant des standards spécifiques : Guides de style, conformité, formatage
Pattern 1 : Réflexion basique
L'agent évalue et améliore son propre output à travers l'auto-critique.
def reflect_and_refine(task: str, criteria: list[str], max_iterations: int = 3) -> str:
"""Generate with reflection loop."""
output = llm(f"Complete this task:\n{task}")
for i in range(max_iterations):
# Self-critique
critique = llm(f"""
Evaluate this output against criteria: {criteria}
Output: {output}
Rate each: PASS/FAIL with feedback as JSON.
""")
critique_data = json.loads(critique)
all_pass = all(c["status"] == "PASS" for c in critique_data.values())
if all_pass:
return output
# Refine based on critique
failed = {k: v["feedback"] for k, v in critique_data.items() if v["status"] == "FAIL"}
output = llm(f"Improve to address: {failed}\nOriginal: {output}")
return output
Insight clé : Utilisez un output JSON structuré pour l'analyse fiable des résultats de critique.
Pattern 2 : Évaluateur-Optimiseur
Séparez la génération et l'évaluation en composants distincts pour des responsabilités plus claires.
class EvaluatorOptimizer:
def __init__(self, score_threshold: float = 0.8):
self.score_threshold = score_threshold
def generate(self, task: str) -> str:
return llm(f"Complete: {task}")
def evaluate(self, output: str, task: str) -> dict:
return json.loads(llm(f"""
Evaluate output for task: {task}
Output: {output}
Return JSON: {{"overall_score": 0-1, "dimensions": {{"accuracy": ..., "clarity": ...}}}}
"""))
def optimize(self, output: str, feedback: dict) -> str:
return llm(f"Improve based on feedback: {feedback}\nOutput: {output}")
def run(self, task: str, max_iterations: int = 3) -> str:
output = self.generate(task)
for _ in range(max_iterations):
evaluation = self.evaluate(output, task)
if evaluation["overall_score"] >= self.score_threshold:
break
output = self.optimize(output, evaluation)
return output
Pattern 3 : Réflexion spécifique au code
Boucle de perfectionnement pilotée par les tests pour la génération de code.
class CodeReflector:
def reflect_and_fix(self, spec: str, max_iterations: int = 3) -> str:
code = llm(f"Write Python code for: {spec}")
tests = llm(f"Generate pytest tests for: {spec}\nCode: {code}")
for _ in range(max_iterations):
result = run_tests(code, tests)
if result["success"]:
return code
code = llm(f"Fix error: {result['error']}\nCode: {code}")
return code
Stratégies d'évaluation
Basée sur les résultats
Évaluez si l'output atteint le résultat attendu.
def evaluate_outcome(task: str, output: str, expected: str) -> str:
return llm(f"Does output achieve expected outcome? Task: {task}, Expected: {expected}, Output: {output}")
LLM comme juge
Utilisez le LLM pour comparer et classer les outputs.
def llm_judge(output_a: str, output_b: str, criteria: str) -> str:
return llm(f"Compare outputs A and B for {criteria}. Which is better and why?")
Basée sur une grille d'évaluation
Notez les outputs contre des dimensions pondérées.
RUBRIC = {
"accuracy": {"weight": 0.4},
"clarity": {"weight": 0.3},
"completeness": {"weight": 0.3}
}
def evaluate_with_rubric(output: str, rubric: dict) -> float:
scores = json.loads(llm(f"Rate 1-5 for each dimension: {list(rubric.keys())}\nOutput: {output}"))
return sum(scores[d] * rubric[d]["weight"] for d in rubric) / 5
Bonnes pratiques
| Pratique | Justification |
|---|---|
| Critères clairs | Définir des critères d'évaluation spécifiques et mesurables dès le départ |
| Limites d'itération | Fixer un nombre max d'itérations (3-5) pour éviter les boucles infinies |
| Vérification de convergence | S'arrêter si le score de l'output ne s'améliore pas entre les itérations |
| Historique journalisé | Garder la trajectoire complète pour le débogage et l'analyse |
| Output structuré | Utiliser JSON pour l'analyse fiable des résultats d'évaluation |
Liste de contrôle de démarrage rapide
## Checklist de mise en œuvre de l'évaluation
### Configuration
- [ ] Définir les critères d'évaluation/grille d'évaluation
- [ ] Fixer le seuil de score pour « suffisamment bon »
- [ ] Configurer le nombre max d'itérations (par défaut : 3)
### Mise en œuvre
- [ ] Implémenter la fonction generate()
- [ ] Implémenter la fonction evaluate() avec output structuré
- [ ] Implémenter la fonction optimize()
- [ ] Câbler la boucle de perfectionnement
### Sécurité
- [ ] Ajouter la détection de convergence
- [ ] Journaliser toutes les itérations pour le débogage
- [ ] Gérer les erreurs d'analyse d'évaluation gracieusement