Résumé IA
Ce tutoriel présente la construction d'un agent IA avancé intégrant un système de critique interne et d'estimation de l'incertitude pour améliorer la fiabilité des décisions. L'agent simule plusieurs inférences en parallèle, évalue chaque réponse candidate selon des critères de précision, cohérence et sécurité, puis quantifie l'incertitude via l'entropie, la variance et des mesures de consistance. Des stratégies de sélection sensibles au risque permettent ainsi d'équilibrer confiance et incertitude pour des comportements plus robustes et prévisibles.
In this tutorial, we build an advanced agent system that goes beyond simple response generation by integrating an internal critic and uncertainty estimation framework. We simulate multi-sample inference, evaluate candidate responses across accuracy, coherence, and safety dimensions, and quantify predictive uncertainty using entropy, variance, and consistency measures. We implement risk-sensitive selection strategies to balance confidence and uncertainty in decision-making. Through structured experiments and visualizations, we explore how self-consistent reasoning and uncertainty-aware selection improve reliability and robustness in agent behavior. Copy Code Copied Use a different Browser import numpy as np import matplotlib.pyplot as plt import seaborn as sns from typing import List, Dict, Tuple, Optional from dataclasses import dataclass from collections import Counter import warnings warnings.filterwarnings('ignore') np.random.seed(42) print("=" * 80) print(" AGENT WITH INTERNAL CRITIC + UNCERTAINTY ESTIMATION") print("=" * 80) print() @dataclass class Response: content: str confidence: float reasoning: str token_logprobs: List[float] def __repr__(self): return f"Response(content='{self.content[:50]}...', confidence={self.confidence:.3f})" @dataclass class CriticScore: accuracy_score: float coherence_score: float safety_score: float overall_score: float feedback: str def __repr__(self): return f"CriticScore(overall={self.overall_score:.3f})" @dataclass class UncertaintyEstimate: entropy: float variance: float consistency_score: float epistemic_uncertainty: float aleatoric_uncertainty: float def risk_level(self) -> str: if self.entropy < 0.5 and self.consistency_score > 0.8: return "LOW" elif self.entropy < 1.0 and self.consistency_score > 0.5: return "MEDIUM" else: return "HIGH" We define the foundational data structures that power our agent system. We create structured containers for responses, critic scores, and uncertainty estimates using dataclasses. We establish reproducibility and initialize the core components that allow us to quantify risk and model confidence. Copy Code Copied Use a different Browser class SimulatedLLM: def __init__(self, model_quality: float = 0.8): self.model_quality = model_quality self.response_templates = { "math": [ "The answer is {answer}. This is calculated by {reasoning}.", "{answer} is the result when you {reasoning}.", "By {reasoning}, we get {answer}.", "The solution is {answer} because {reasoning}.", ], "factual": [ "The answer is {answer}. {reasoning}", "Based on the facts, {answer}. {reasoning}", "{answer} is correct. {reasoning}", "The factual answer is {answer}. {reasoning}", ] } def generate_response(self, prompt: str, temperature: float = 0.7) -> Response: noise = np.random.randn() * temperature quality = np.clip(self.model_quality + noise * 0.2, 0.1, 1.0) if "What is" in prompt and "+" in prompt: parts = prompt.split() try: num1 = int(parts[parts.index("is") + 1]) num2 = int(parts[parts.index("+") + 1].rstrip("?")) correct_answer = num1 + num2 if np.random.rand() > quality: answer = correct_answer + np.random.randint(-3, 4) else: answer = correct_answer template = np.random.choice(self.response_templates["math"]) reasoning = f"adding {num1} and {num2}" content = template.format(answer=answer, reasoning=reasoning) token_logprobs = list(np.random.randn(10) - (1 - quality) * 2) confidence = quality + np.random.randn() * 0.1 confidence = np.clip(confidence, 0.1, 0.99) return Response( content=content, confidence=confidence, reasoning=reasoning, token_logprobs=token_logprobs ) except: pass template = np.random.choice(self.response_templates["factual"]) answer = "unknown" reasoning = "insufficient information to determine" content = template.format(answer=answer, reasoning=reasoning) token_logprobs = list(np.random.randn(10) - 1) confidence = 0.5 + np.random.randn() * 0.1 return Response( content=content, confidence=np.clip(confidence, 0.1, 0.99), reasoning=reasoning, token_logprobs=token_logprobs ) def generate_multiple(self, prompt: str, n: int = 5, temperature: float = 0.7) -> List[Response]: return [self.generate_response(prompt, temperature) for _ in range(n)] We simulate a language model that generates multiple candidate responses of varying quality. We introduce temperature-based variability and controlled noise to mimic realistic sampling behavior. We enable multi-sample generation to support self-consistency reasoning and uncertainty estimation. Copy Code Copied Use a different Browser class InternalCritic: def __init__(self, strict_mode: bool = False): self.strict_mode = strict_mode def evaluate_response(self, response: Response, prompt: str, ground_truth: Optional[str] = None) -> CriticScore: accuracy = self._evaluate_accuracy(response, ground_truth) coherence = self._evaluate_coherence(response) safety = self._evaluate_safety(response) weights = {'accuracy': 0.4, 'coherence': 0.3, 'safety': 0.3} overall = (weights['accuracy'] * accuracy +