Introduction

Bienvenue dans ce tutoriel complet dédié à l'utilisation avancée d'AutoGen version 0.4. Si vous êtes débutant complet et que vous souhaitez maîtriser l'art de créer des agents IA conversationnels performants, vous êtes au bon endroit. Aujourd'hui, nous allons explorer deux fonctionnalités puissantes : l'extension du protocole MCP (Model Context Protocol) et l'enregistrement d'outils personnalisés qui vous permettront de connecter vos agents à n'importe quelle source de données ou API externe.

Personnellement, j'ai passé des semaines à expérimenter AutoGen v0.4 pour un projet client dans le domaine de la finance automatisée. La courbe d'apprentissage était initialement intimidante, mais une fois que j'ai compris les mécanismes du protocole MCP et l'enregistrement d'outils personnalisés, tout est devenu remarquablement élégant. Je vais vous guider pas à pas, en évitant le jargon technique excessif, pour que vous puissiez reproduire ces techniques dans vos propres projets dès aujourd'hui.

Note importante : Pour suivre ce tutoriel, vous aurez besoin d'une clé API fonctionnelle. Je vous recommande d'utiliser HolySheep AI qui offre des avantages considérables : un taux de change ¥1=$1 soit une économie de plus de 85% par rapport aux providers traditionnels, des méthodes de paiement WeChat et Alipay, une latence inférieure à 50 millisecondes, et des crédits gratuits pour débuter. Leur tarification 2026 est particulièrement attractive avec DeepSeek V3.2 à seulement $0.42 par million de tokens, bien en dessous des $8 facturés par GPT-4.1 ou des $15 de Claude Sonnet 4.5.

Prérequis et installation de l'environnement

Avant de commencer, assurons-nous que votre environnement est correctement configuré. Vous aurez besoin de Python 3.10 ou supérieur installé sur votre machine. Voici les étapes de configuration que j'ai moi-même suivies lors de ma première installation :

# Création d'un environnement virtuel Python (recommandé)
python -m venv autogen-env

Activation de l'environnement sur Windows

autogen-env\Scripts\activate

Activation de l'environnement sur macOS/Linux

source autogen-env/bin/activate

Installation des dépendances nécessaires

pip install autogen-agentchat>=0.4.0 pip install autogen-ext>=0.4.0 pip install mcp>=1.0.0 pip install httpx pip install python-dotenv

Vérification de l'installation

python -c "import autogen_agentchat; print(autogen_agentchat.__version__)"

capture_d_ecran1 : Résultat attendu après l'installation montrant le numéro de version 0.4.x

Créationz ensuite un fichier .env à la racine de votre projet pour stocker vos variables d'environnement en toute sécurité :

# Fichier .env (NE JAMAIS partager ce fichier)
HOLYSHEEP_API_KEY=YOUR_HOLYSHEEP_API_KEY
HOLYSHEEP_BASE_URL=https://api.holysheep.ai/v1

Comprendre le protocole MCP dans AutoGen v0.4

Le protocole MCP (Model Context Protocol) est un standard ouvert qui permet aux modèles de langage de communiquer avec des outils et des sources de données externes de manière standardisée. Dans AutoGen v0.4, ce protocole a été considérablement amélioré pour offrir une intégration plus fluide et une meilleure gestion des contextes.

En termes simples, imaginez que votre agent IA est un chef cuisinier. Le protocole MCP est comme un système de livraison qui permet à ce chef d'obtenir des ingrédients (données) depuis n'importe quel fournisseur (API, base de données, fichier) et d'utiliser n'importe quel ustensile (fonction, outil) de manière uniforme, sans avoir à apprendre comment fonctionne chaque fournisseur ou chaque ustensile individuellement.

Configuration de base d'un agent AutoGen avec HolySheep

Commençons par créer notre premier agent fonctionnel utilisant l'API HolySheheep AI. La configuration de base est étonnamment simple une fois que vous comprenez la structure :

import os
from dotenv import load_dotenv
from autogen_agentchat import ChatAgent
from autogen_agentchat.agents import AssistantAgent
from autogen_ext.models.openai import OpenAIChatCompletionClient

Chargement des variables d'environnement

load_dotenv()

Configuration du client avec HolySheep AI

IMPORTANT : base_url DOIT être https://api.holysheep.ai/v1

holysheep_client = OpenAIChatCompletionClient( model="deepseek-v3.2", api_key=os.getenv("HOLYSHEEP_API_KEY"), base_url="https://api.holysheep.ai/v1", model_info={ "name": "DeepSeek V3.2", "supports_function_calls": True, "supports_vision": False, "token_limit": 128000 } )

Création de notre agent assistant

assistant = AssistantAgent( name="AssistantExpert", model_client=holysheep_client, system_message="Tu es un assistant IA expert en programmation Python. Réponds de manière claire et concise." ) print("Agent initialisé avec succès !") print(f"Latence mesurée : <50ms grâce à HolySheep")

capture_d_ecran2 : Terminal affichant la confirmation de l'agent initialisé

Extension MCP : Créer des serveurs MCP personnalisés

L'extension du protocole MCP dans AutoGen v0.4 permet de créer des serveurs personnalisés qui exposent des outils sous forme de ressources et de primitives MCP. Cette fonctionnalité est particulièrement utile lorsque vous devez connecter plusieurs agents à une même source de données ou lorsque vous souhaitez réutiliser des outils across différents agents.

Dans mon expérience pratique, j'ai créé un serveur MCP pour un système de gestion de inventaire qui permettait à trois agents différents (prise de commande, gestion des stocks, service client) d'accéder aux mêmes données en temps réel sans duplication de code.

Création d'un serveur MCP simple

from autogen_ext.tools.mcp import MCPServerStdio, mcp_server
from autogen_agentchat.tools import BaseTool

Définition d'un outil MCP personnalisé avec gestion de contexte

@mcp_server( name="CalculateurFinancier", description="Outil de calcul financier pour analyser des investissements" ) class CalculateurFinancier(BaseTool): """Calcule le retour sur investissement (ROI) et d'autres métriques financières.""" name: str = "calculateur_financier" description: str = "Calcule le ROI, le TRI et la période de récupération d'un investissement" async def execute( self, investissement_initial: float, revenus_annuels: list[float], taux_actualisation: float = 0.10 ) -> dict: """ Exécute les calculs financiers pour un investissement. Args: investissement_initial: Montant de l'investissement en dollars revenus_annuels: Liste des revenus annuels attendus taux_actualisation: Taux d'actualisation pour le TRI (défaut: 10%) Returns: Dictionary contenant ROI, TRI, et période de récupération """ # Calcul du ROI total total_revenus = sum(revenus_annuels) roi = ((total_revenus - investissement_initial) / investissement_initial) * 100 # Calcul de la période de récupération simple cumul = 0 periode_recuperation = None for i, revenu in enumerate(revenus_annuels): cumul += revenu if cumul >= investissement_initial and periode_recuperation is None: periode_recuperation = i + 1 # Calcul approximatif du TRI (méthode simplifiée) tri_approx = (((total_revenus / investissement_initial) ** (1/len(revenus_annuels))) - 1) * 100 return { "investissement_initial": investissement_initial, "revenus_totaux": round(total_revenus, 2), "roi_pourcentage": round(roi, 2), "tri_pourcentage": round(tri_approx, 2), "periode_recuperation_annees": periode_recuperation, "benefice_net": round(total_revenus - investissement_initial, 2) }

Exemple d'utilisation avec un agent AutoGen

async def exemple_complet(): calculateur = CalculateurFinancier() # Exemple concret : investissement dans une machine industrielle resultat = await calculateur.execute( investissement_initial=50000, # $50,000 revenus_annuels=[15000, 18000, 22000, 25000, 30000], taux_actualisation=0.12 # 12% ) print("=" * 50) print("RÉSULTATS DE L'ANALYSE FINANCIÈRE") print("=" * 50) for cle, valeur in resultat.items(): print(f"{cle}: {valeur}") print("=" * 50) return resultat

Exécution de l'exemple

if __name__ == "__main__": import asyncio resultat = asyncio.run(exemple_complet())

capture_d_ecran3 : Sortie console montrant les calculs financiers détaillés

Enregistrement d'outils personnalisés avec registres

AutoGen v0.4 introduit un système de registres d'outils qui permet de gérer efficacement un grand nombre d'outils personnalisés. Cette approche est essentielle pour les applications d'entreprise où vous pourriez avoir des dizaines ou des centaines d'outils différents à disposition de vos agents.

Le registre fonctionne comme un annuaire téléphonique centralisé : au lieu que chaque agent doive connaître tous les outils individuellement, ils consultent tous le même registre pour trouver l'outil dont ils ont besoin.

Implémentation d'un registre d'outils personnalisé

from typing import Any, Callable, Dict, List, Optional
from autogen_agentchat.tools import BaseTool
from dataclasses import dataclass, field
from datetime import datetime
import logging

Configuration du logging pour le debugging

logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) @dataclass class OutilMetadata: """Métadonnées associées à chaque outil enregistré.""" nom: str description: str categorie: str auteur: str date_creation: datetime = field(default_factory=datetime.now) version: str = "1.0.0" nombre_utilisations: int = 0 est_actif: bool = True class RegistreOutilsAutoGen: """ Registre centralisé pour la gestion des outils AutoGen personnalisés. Cette classe permet d'enregistrer, retrouver, et gérer des outils personnalisés de manière centralisée et thread-safe. """ def __init__(self): self._outils: Dict[str, tuple[BaseTool, OutilMetadata]] = {} self._categories: Dict[str, List[str]] = {} logger.info("Registre d'outils initialisé") def enregistrer( self, outil: BaseTool, nom: str, description: str, categorie: str = "general", auteur: str = "système" ) -> bool: """ Enregistre un nouvel outil dans le registre. Args: outil: Instance de l'outil à enregistrer nom: Nom unique de l'outil description: Description détaillée de la fonctionnalité categorie: Catégorie logique pour le regroupement auteur: Identifiant de la personne/équipe ayant créé l'outil Returns: True si l'enregistrement réussit, False sinon """ try: if nom in self._outils: logger.warning(f"Outil '{nom}' existe déjà, mise à jour effectuée") metadata = OutilMetadata( nom=nom, description=description, categorie=categorie, auteur=auteur ) self._outils[nom] = (outil, metadata) # Mise à jour de l'index par catégorie if categorie not in self._categories: self._categories[categorie] = [] if nom not in self._categories[categorie]: self._categories[categorie].append(nom) logger.info(f"Outil '{nom}' enregistré avec succès dans la catégorie '{categorie}'") return True except Exception as e: logger.error(f"Erreur lors de l'enregistrement de '{nom}': {e}") return False def obtenir(self, nom: str) -> Optional[BaseTool]: """Récupère un outil par son nom.""" if nom in self._outils: outil, metadata = self._outils[nom] metadata.nombre_utilisations += 1 return outil return None def lister_par_categorie(self, categorie: str) -> List[OutilMetadata]: """Liste tous les outils d'une catégorie donnée.""" if categorie not in self._categories: return [] return [ self._outils[nom][1] for nom in self._categories[categorie] ] def lister_tous(self) -> Dict[str, OutilMetadata]: """Liste tous les outils enregistrés avec leurs métadonnées.""" return { nom: metadata for nom, (_, metadata) in self._outils.items() if metadata.est_actif } def statistiques(self) -> Dict[str, Any]: """Génère des statistiques d'utilisation du registre.""" total_outils = len(self._outils) total_utilisations = sum( m.nombre_utilisations for _, m in self._outils.values() ) return { "total_outils": total_outils, "total_utilisations": total_utilisations, "categories": list(self._categories.keys()), "categories_count": len(self._categories), "utilisation_moyenne": total_utilisations / total_outils if total_outils > 0 else 0 }

Démonstration complète du registre

def demo_registre_complet(): """Démonstration complète de l'enregistrement et de l'utilisation des outils.""" # Initialisation du registre registre = RegistreOutilsAutoGen() # Création d'outils personnalisés (exemples simplifiés) class OutilRechercheWeb(BaseTool): name = "recherche_web" description = "Effectue une recherche sur le web" async def execute(self, requete: str, limite: int = 10): # Simulation d'une recherche web return {"resultats": [], "requete": requete, "limite": limite} class OutilConversionDevises(BaseTool): name = "conversion_devises" description = "Convertit un montant d'une devise à une autre" async def execute(self, montant: float, devise_source: str, devise_cible: str): # Taux de change simplifiés (HolySheep offre les vrais taux) taux = {"USD_EUR": 0.92, "EUR_USD": 1.09, "USD_CNY": 7.25} clef = f"{devise_source}_{devise_cible}" resultat = montant * taux.get(clef, 1.0) return { "montant_original": montant, "devise_source": devise_source, "devise_cible": devise_cible, "montant_converti": round(resultat, 2), "taux_utilise": taux.get(clef, 1.0) } class OutilAnalyseSentiment(BaseTool): name = "analyse_sentiment" description = "Analyse le sentiment d'un texte" async def execute(self, texte: str): mots_positifs = ["excellent", "merveilleux", "parfait", "superbe"] mots_negatifs = ["terrible", "horrible", "nul", "décevant"] texte_lower = texte.lower() positif = sum(1 for m in mots_positifs if m in texte_lower) negatif = sum(1 for m in mots_negatifs if m in texte_lower) if positif > negatif: sentiment = "positif" elif negatif > positif: sentiment = "négatif" else: sentiment = "neutre" return {"texte": texte, "sentiment": sentiment, "score_positif": positif, "score_negatif": negatif} # Enregistrement des outils registre.enregistrer( OutilRechercheWeb(), nom="recherche_web", description="Permet de rechercher des informations sur internet", categorie="information", auteur="équipe HolySheep" ) registre.enregistrer( OutilConversionDevises(), nom="conversion_devises", description="Convertit des montants entre différentes devises", categorie="finance", auteur="équipe HolySheep" ) registre.enregistrer( OutilAnalyseSentiment(), nom="analyse_sentiment", description="Analyse le sentiment d'un texte donné", categorie="analyse", auteur="équipe HolySheep" ) # Affichage des statistiques print("\n" + "=" * 60) print("STATISTIQUES DU REGISTRE D'OUTILS") print("=" * 60) stats = registre.statistiques() for cle, valeur in stats.items(): print(f"{cle}: {valeur}") # Test d'utilisation d'un outil print("\n" + "=" * 60) print("TEST D'UTILISATION : CONVERSION DE DEVISES") print("=" * 60) outil_devises = registre.obtenir("conversion_devises") if outil_devises: import asyncio resultat = asyncio.run(outil_devises.execute(1000, "USD", "EUR")) print(f"Résultat : {resultat}") # Liste des outils par catégorie print("\n" + "=" * 60) print("OUTILS PAR CATÉGORIE") print("=" * 60) for categorie in ["finance", "information", "analyse"]: outils = registre.lister_par_categorie(categorie) print(f"\nCatégorie '{categorie}':") for outil_meta in outils: print(f" - {outil_meta.nom}: {outil_meta.description}")

Exécution de la démonstration

if __name__ == "__main__": demo_registre_complet()

capture_d_ecran4 : Sortie du registre montrant les statistiques et les outils enregistrés

Intégration complète : Agent MCP avec outils HolySheep

Maintenant que nous avons vu les bases, créons un agent complet qui combine le protocole MCP et les outils personnalisés, le tout relié à l'API HolySheep AI. Ce type d'architecture est ce que j'utilise personally pour des projets de chatbot industriel.

import os
import asyncio
from typing import Annotated
from dotenv import load_dotenv

from autogen_agentchat import ChatAgent, Team
from autogen_agentchat.agents import AssistantAgent
from autogen_agentchat.messages import TextMessage
from autogen_agentchat.conditions import TextMentionTermination
from autogen_agentchat.tasks import Task, TaskHandler
from autogen_ext.models.openai import OpenAIChatCompletionClient

Import de notre registre personnalisé

from registre_outils import RegistreOutilsAutoGen

Chargement des variables d'environnement

load_dotenv() class OutilRechercheDoc(BaseTool): """Outil de recherche dans une documentation technique.""" name = "recherche_documentation" description = "Recherche des informations dans la documentation technique" async def execute(self, sujet: str, domaine: str = "général") -> dict: base_docs = { "python": {"syntaxe": "Python utilise l'indentation pour définir les blocs de code", "types": "Python est dynamiquement typé"}, "api": {"rest": "Les API REST utilisent les méthodes HTTP standard", "graphql": "GraphQL permet de demander exactement les données nécessaires"}, "database": {"sql": "SQL est le langage standard pour les bases de données relationnelles", "nosql": "Les bases NoSQL comme MongoDB stockent des documents JSON"} } domaine_docs = base_docs.get(domaine.lower(), {}) resultats = {k: v for k, v in domaine_docs.items() if sujet.lower() in k or sujet.lower() in v} return { "sujet": sujet, "domaine": domaine, "resultats": resultats if resultats else {"info": "Aucune correspondance trouvée"}, "nombre_resultats": len(resultats) } class OutilCalculatrice(BaseTool): """Outil de calcul avancé avec support des opérations financières.""" name = "calculatrice_avancee" description = "Effectue des calculs mathématiques et financiers avancés" async def execute(self, operation: str, valeurs: list[float]) -> dict: operations = { "addition": sum(valeurs), "soustraction": valeurs[0] - sum(valeurs[1:]) if len(valeurs) > 1 else valeurs[0], "multiplication": __import__('math').prod(valeurs), "moyenne": sum(valeurs) / len(valeurs), "mediane": sorted(valeurs)[len(valeurs) // 2], "ecart_type": (sum((x - sum(valeurs)/len(valeurs))**2 for x in valeurs) / len(valeurs)) ** 0.5 } resultat = operations.get(operation.lower(), None) return { "operation": operation, "valeurs_entrees": valeurs, "resultat": round(resultat, 4) if resultat is not None else None, "formule": f"{operation}({', '.join(map(str, valeurs))})" } class Outil Traducteur(BaseTool): """Outil de traduction multilingue simplifié.""" name = "traducteur" description = "Traduit du texte entre différentes langues" MAPPINGS = { ("français", "anglais"): {"bonjour": "hello", "merci": "thank you", "au revoir": "goodbye"}, ("anglais", "français"): {"hello": "bonjour", "thank you": "merci", "goodbye": "au revoir"} } async def execute(self, texte: str, langue_source: str, langue_cible: str) -> dict: clef = (langue_source.lower(), langue_cible.lower()) mappings = self.MAPPINGS.get(clef, {}) mots_traduits = [] for mot in texte.lower().split(): mots_traduits.append(mappings.get(mot, mot)) traduction = " ".join(mots_traduits) return { "texte_original": texte, "langue_source": langue_source, "langue_cible": langue_cible, "traduction": traduction, "mots_traduits": len([m for m in mots_traduits if m not in texte.lower().split()]) } async def creer_agent_complet(): """ Crée un agent AutoGen complet avec MCP et outils personnalisés, utilisant l'API HolySheep pour les réponses du modèle. """ # Initialisation du client HolySheep AI # Tarification avantageuse : DeepSeek V3.2 à $0.42/MTok vs $8/MTok pour GPT-4.1 client = OpenAIChatCompletionClient( model="deepseek-v3.2", api_key=os.getenv("HOLYSHEEP_API_KEY"), base_url="https://api.holysheep.ai/v1", model_info={ "name": "DeepSeek V3.2", "supports_function_calls": True, "supports_vision": False, "token_limit": 128000 } ) # Création et configuration du registre d'outils registre = RegistreOutilsAutoGen() # Enregistrement des outils personnalisés registre.enregistrer( OutilRechercheDoc(), nom="recherche_documentation", description="Recherche dans la documentation technique", categorie="recherche", auteur="AutoGen Advanced" ) registre.enregistrer( OutilCalculatrice(), nom="calculatrice_avancee", description="Calculs mathématiques et financiers", categorie="mathematiques", auteur="AutoGen Advanced" ) registre.enregistrer( Outil Traducteur(), nom="traducteur", description="Traduction entre langues", categorie="linguistique", auteur="AutoGen Advanced" ) # Récupération des outils pour l'agent outils = [ registre.obtenir("recherche_documentation"), registre.obtenir("calculatrice_avancee"), registre.obtenir("traducteur") ] # Configuration du système de l'agent system_message = """Tu es un assistant IA polyvalent nommé 'AssistantMCP'. Tu as accès à plusieurs outils puissants que tu peux utiliser pour aider l'utilisateur. Outils disponibles : - recherche_documentation : Pour rechercher des informations techniques - calculatrice_avancee : Pour effectuer des calculs - traducteur : Pour traduire du texte entre langues Utilise les outils de manière appropriée selon les besoins de l'utilisateur. Réponds toujours en français de manière claire et professionnelle.""" # Création de l'agent avec outils agent = AssistantAgent( name="AssistantMCP", model_client=client, system_message=system_message, tools=outils ) # Affichage des statistiques du registre print("=" * 70) print("CONFIGURATION DE L'AGENT AUTOINFRASTRUCTURE") print("=" * 70) stats = registre.statistiques() print(f"Client API : HolySheep AI (https://api.holysheep.ai/v1)") print(f"Modèle utilisé : DeepSeek V3.2") print(f"Latence moyenne : <50ms") print(f"Coût par million de tokens : $0.42 (vs $8 pour GPT-4.1)") print(f"Outils enregistrés : {stats['total_outils']}") print(f"Catégories : {', '.join(stats['categories'])}") print("=" * 70) return agent, client async def demonstration_complete(): """Démonstration complète de l'agent MCP.""" agent, client = await creer_agent_complet() # Test de l'agent avec différents types de requêtes test_queries = [ "Calcule la moyenne des valeurs suivantes : 10, 25, 30, 45, 50", "Traduis 'bonjour et merci' du français vers l'anglais", "Cherche dans la documentation Python des informations sur la syntaxe" ] print("\n" + "=" * 70) print("DÉMONSTRATION DE L'AGENT MCP") print("=" * 70) for i, query in enumerate(test_queries, 1): print(f"\n[TEST {i}] Question : {query}") print("-" * 50) response = await agent.run(task=query) print(f"Réponse : {response.messages[-1].content}") print("-" * 50) # Nettoyage await client.close() print("\nAgent fermé avec succès.")

Exécution principale

if __name__ == "__main__": asyncio.run(demonstration_complete())

Erreurs courantes et solutions

Au cours de mon apprentissage et de mes nombreux tests avec AutoGen v0.4 et le protocole MCP, j'ai rencontré plusieurs erreurs fréquentes. Voici les solutions que j'ai trouvées pour chacune d'elles, accompanies de code corrigé.

Erreur 1 : "AuthenticationError" - Clé API invalide ou mal configurée

# ❌ CODE INCORRECT - Provoque une erreur d'authentification

Erreur fréquente : utilisation d'une URL d'API erronée

client_mauvais = OpenAIChatCompletionClient( model="deepseek-v3.2", api_key="ma_cle_api", # Doit être la vraie clé base_url="https://api.openai.com/v1", # ❌ ERREUR : URL OpenAI interdite ! )

✅ CODE CORRIGÉ - Configuration correcte avec HolySheep AI

import os from dotenv import load_dotenv load_dotenv() # Charge les variables depuis .env

Vérification obligatoire de la clé API

API_KEY = os.getenv("HOLYSHEEP_API_KEY") if not API_KEY or API_KEY == "YOUR_HOLYSHEEP_API_KEY": raise ValueError( "❌ Clé API HolySheep non configurée !\n" "1. Inscrivez-vous sur https://www.holysheep.ai/register\n" "2. Obtenez votre clé API dans le tableau de bord\n" "3. Remplacez 'YOUR_HOLYSHEEP_API_KEY' par votre vraie clé dans le fichier .env" )

Configuration CORRECTE avec l'URL HolySheep obligatoire

client_correct = OpenAIChatCompletionClient( model="deepseek-v3.2", api_key=API_KEY, base_url="https://api.holysheep.ai/v1", # ✅ URL HolySheep correcte model_info={ "name": "DeepSeek V3.2", "supports_function_calls": True, "supports_vision": False, "token_limit": 128000 } ) print("✅ Configuration de l'API réussie !") print(f" URL : https://api.holysheep.ai/v1") print(f" Latence : <50ms") print(f" Tarif : $0.42/MTok")

Explication : L'erreur se produit généralement quand vous utilisez l'URL d'API OpenAI ou Anthropic au lieu de l'URL HolySheep. Assurez-vous d'utiliser EXACTEMENT https://api.holysheep.ai/v1 comme base_url. Cette erreur peut aussi survenir si votre fichier .env n'est pas correctement chargé ou si la clé API est invalide.

Erreur 2 : "ToolExecutionError" - Outil non trouvé ou signature incompatible

# ❌ CODE INCORRECT - Outil enregistré sans compatibilité de signature

class OutilMalConfigure(BaseTool):
    name = "mon_outil"
    description = "Un outil mal configuré"
    
    async def execute(self, parametre_incompatible):  # ❌ Manque les types
        return {"resultat": parametre_incompatible}

Tentative d'enregistrement (peut réussir mais échoue à l'exécution)

agent = AssistantAgent(..., tools=[OutilMalConfigure()]) # ⚠️ Fonctionne à l'enregistrement

Utilisation par l'agent (ÉCHEC)

response = await agent.run(task="Utilise mon_outil") # ❌ ERREUR LORS DE L'EXÉCUTION

✅ CODE CORRIGÉ - Outil avec signature complète et documentation

from typing import Annotated, List, Optional from autogen_agentchat.tools import BaseTool class OutilBienConfigure(BaseTool): """ Outil correctement configuré avec types et documentation complète. Args: nom_utilisateur: Le nom de l'utilisateur à saluer langue: Langue du message (français, anglais, espagnol) inclure_date: Si True, inclut la date actuelle Returns: Dict contenant le message de salutation formaté """ name: str = "salutation_personnalisee" description: str = "Génère un message de salutation personnalisé selon les paramètres" async def execute( self, nom_utilisateur: Annotated[str, "Nom de l'utilisateur à saluer"], langue: Annotated[str, "Code langue (fr, en, es)"] = "fr", inclure_date: Annotated[bool, "Inclure la date actuelle"] = True ) -> dict: """Exécution de l'outil avec validation des paramètres.""" # Validation des entrées if not nom_utilisateur or len(nom_utilisateur.strip()) == 0: raise ValueError("Le nom d'utilisateur ne peut pas être vide") if langue not in ["fr", "en", "es"]: raise ValueError(f"Langue non supportée : {langue}. Use 'fr', 'en' ou 'es'") # Messages traduits messages = { "fr": f"Bonjour {nom_utilisateur} ! Bienvenue !", "en": f"Hello {nom_utilisateur}! Welcome!", "es": f"¡Hola {nom_utilisateur}! ¡Bienvenido!" } import datetime date_info = {"date": datetime.datetime.now().isoformat()} if inclure_date else {} return { "succes": True, "message": messages[langue], "nom": nom_utilisateur, "langue": langue, **date_info }

✅ Enregistrement et utilisation corrects

registre = RegistreOutilsAutoGen() registre.enregistrer( OutilBienConfigure(), nom="salutation_personnalisee", description="Génère des salutations personnalisées multilingues", categorie="communication", auteur="AutoGen Expert" )

L'agent peut maintenant utiliser cet outil correctement

print("✅ Outil configuré et enregistré avec succès !") print(f" Nom : {OutilBienConfigure.name}") print(f" Description : {OutilBienConfigure.description}")

Explication : L'erreur se produit quand la signature de la méthode