import warnings
warnings.filterwarnings('ignore', category=DeprecationWarning)
from langchain_openai import ChatOpenAI
# Assurez-vous d'avoir défini votre clé OPENAI_API_KEY dans vos variables d'environnement
llm = ChatOpenAI(model="gpt-5-mini", temperature=0)Lab 6 - Anatomie de votre premier Agent d’IA
Navigation : Lab 5 << | Index | Lab 7 >>
Objectifs d’apprentissage
A la fin de ce laboratoire, vous saurez : 1. Assembler les 4 composants fondamentaux d’un agent LangChain/LangGraph 2. Créer un outil personnalise avec le decorateur @tool 3. Configurer un prompt template pour agent REACT 4. Orchestrer l’exécution avec create_react_agent de LangGraph
Prerequis
- Avoir complete le Lab 5 (ML de base)
- Cle API OpenAI configuree (
OPENAI_API_KEY) - Comprehension de base des fonctions Python
Duree estimee : 30-40 minutes
Un agent est un programme qui utilise un LLM pour raisonner, choisir des actions (outils) et atteindre un objectif. Dans ce lab, nous allons construire les 4 piliers d’un agent LangChain.
- Étape 1 : Le “Cerveau” - Le LLM
Le LLM (Large Language Model) est le moteur de raisonnement de notre agent. Nous utiliserons ChatOpenAI, qui nécessite une clé API OpenAI.
- Étape 2 : Les “Mains” - Les Outils (Tools)
Les outils sont des fonctions que l’agent peut appeler pour interagir avec le monde extérieur. La docstring de la fonction est cruciale, car c’est ce que le LLM lit pour comprendre l’utilité de l’outil.
Référence — outil-augmentation. La capacité pour un LLM à décider d’appeler un outil, quand l’appeler et avec quels arguments constitue le paradigme des LLMs tool-augmented (ou function calling). Son fondement académique est Toolformer (Schick et al., 2023), qui montre qu’un modèle peut apprendre par lui-même à insérer des appels d’API. Le décorateur
@toolde LangChain expose précisément cette interface : la docstring devient la description que le LLM utilise pour choisir l’outil.
from langchain_core.tools import tool
import math
@tool
def calculer_racine_carree(nombre: float) -> float:
"""Calcule la racine carrée d'un nombre."""
return math.sqrt(nombre)- Étape 3 : Les “Instructions” - Le Prompt
Le prompt est le modèle d’instructions qui guide le raisonnement de l’agent. Pour commencer, nous allons utiliser un prompt pré-construit et éprouvé depuis le LangChain Hub.
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
# Creer le prompt template pour l'agent REACT
# LangGraph utilise un format base sur les messages
prompt = ChatPromptTemplate.from_messages([
("system", "You are a helpful assistant. Use the tools available to help the user."),
MessagesPlaceholder("messages"),
])
print("Prompt REACT configure avec ChatPromptTemplate")Prompt REACT configure avec ChatPromptTemplate
Lecture ancrée : Le template, verbatim du code : ("system", "You are a helpful assistant. Use the tools available to help the user.") puis MessagesPlaceholder("messages") — la sortie confirme « Prompt REACT configure avec ChatPromptTemplate ». Structure fixe (le rôle système, qui ordonne d’utiliser les outils) + slot variable (l’historique des messages) : LangGraph injectera la conversation dans le slot à chaque tour de la boucle REACT.
- Étape 4 : L’ “Orchestrateur” - L’Agent et son Exécuteur
Nous assemblons maintenant tous les composants pour créer l’agent avec create_react_agent de LangGraph. Cette fonction créé un graphe qui gere la boucle Pensee -> Action -> Observation automatiquement.
Référence — ReAct. La boucle Pensée → Action → Observation est le paradigme ReAct (Reasoning + Acting) formalisé par Yao et al. (2023) : l’agent alterne un pas de raisonnement (pensée), l’appel d’un outil (action), puis l’intégration du résultat (observation), jusqu’à produire la réponse finale.
create_react_agentde LangGraph implémente directement cette boucle. Le prolongement multi-agent (boucle Planner-Coder-Verifier) est abordé au Lab 11 (Track2-GoogleADK).
from langgraph.prebuilt import create_react_agent
tools = [calculer_racine_carree]
graph = create_react_agent(model=llm, tools=tools, prompt=prompt)
print("Agent REACT cree avec LangGraph")Agent REACT cree avec LangGraph
Lecture ancree : la cellule imprime « Agent REACT cree avec LangGraph » — et rien d’autre. Plus de LangGraphDeprecatedSinceV10 : le filtre warnings.filterwarnings('ignore', category=DeprecationWarning) pose plus haut dans le notebook etouffe l’avertissement avant l’impression. L’appel create_react_agent(model=llm, tools=tools, prompt=prompt) porte trois arguments nommes, trois roles — le modele decide, la liste d’outils agit, le prompt cadre. La boucle REACT n’est pas ecrite a la main : elle est COMPILEE par cet appel, c’est ce que « prebuilt » annonce dans from langgraph.prebuilt import create_react_agent. L’avertissement reste reel meme silencieux : cet import migre en v1.0 (from langchain.agents import create_agent) et disparaitra en v2.0 — le filtre ne change pas l’horizon de migration, il l’ote seulement de la sortie.
Mise en Action
result = graph.invoke({"messages": [("user", "Quelle est la racine carree de 256 ?")]})
print(result["messages"][-1].content)La racine carrée de 256 est 16, car 16 × 16 = 256.
Lecture : verbatim de la sortie — « La racine carrée de 256 est 16. » Le climax du lab : un seul graph.invoke et le graphe orchestre la boucle jusqu’à la réponse finale en langage naturel. La trajectoire complète (messages successifs de l’agent, appel de l’outil calculer_racine_carree) est conservée dans result["messages"] — on affiche ici le dernier message, celui de la réponse.
Exercice 1 : Ajouter un outil de conversion de temperature
Les agents deviennent utiles quand ils disposent de plusieurs outils complementaires. Vous allez créer un outil qui convertit une temperature de Celsius en Fahrenheit (et inversement), puis l’integrer dans un agent multi-outils.
Objectif : Créer un outil convertir_temperature avec le decorateur @tool et l’ajouter a l’agent.
Indices : - Formule Celsius vers Fahrenheit : F = C * 9/5 + 32 - Le decorateur @tool requiert une docstring descriptive (le LLM l’utilise pour choisir l’outil) - Ajoutez un paramètre sens (string: “C2F” ou “F2C”) pour specifier la direction de conversion - Créez un nouvel agent avec la liste tools augmentee
# Exercice 1 : Outil de conversion de temperature
# Creez un outil qui convertit les temperatures et ajoutez-le a l'agent
# Etape 1: Definissez l'outil avec le decorateur @tool
# Indice: la fonction prend (valeur: float, sens: str) et retourne un float
# N'oubliez pas la docstring qui explique C2F et F2C
@tool
def convertir_temperature(valeur: float, sens: str) -> float:
"""Convertit une temperature. sens='C2F' pour Celsius vers Fahrenheit, 'F2C' pour l'inverse."""
pass # Exercice: implementez la conversion avec un if/elif sur sens
# Etape 2: Creez un agent avec les deux outils (racine carree + temperature)
# Indice: tools_temp = [calculer_racine_carree, convertir_temperature]
tools_temp = None # Remplacez None
graph_temp = None # Remplacez None (create_react_agent(...))
# Etape 3: Testez avec une question de conversion
# Indice: graph_temp.invoke({"messages": [("user", "Combien font 100 degres Celsius en Fahrenheit ?")]})})
print("Exercice 1 a completer : outil de conversion de temperature")Exercice 1 a completer : outil de conversion de temperature
Exercice 2 : Outil de calcul statistique
Un agent destine a l’analyse de données doit pouvoir realiser des calculs statistiques de base. Vous allez créer un outil qui prend une liste de nombres et retourne les statistiques descriptives (moyenne, mediane, ecart-type).
Objectif : Créer un outil calculer_statistiques qui retourne un dictionnaire contenant les statistiques d’une liste de nombres.
Indices : - Utilisez le module statistics de Python (pas besoin d’import supplementaire) - statistics.mean(), statistics.median(), statistics.stdev() pour les calculs - L’outil prend une liste de floats en entree et retourne une string formattee (le LLM ne sait pas lire les dicts directement) - La docstring doit mentionner les metriques calculees pour que le LLM sache quand utiliser cet outil
# Exercice 2 : Outil de calcul statistique
# Creez un outil qui calcule les statistiques descriptives d'une liste de nombres
import statistics
# Etape 1: Definissez l'outil
@tool
def calculer_statistiques(nombres: list) -> str:
"""
Calcule les statistiques descriptives (moyenne, mediane, ecart-type, min, max)
d'une liste de nombres. Retourne un resume textuel.
"""
pass # Exercice: calculez mean, median, stdev, min, max et retournez une string
# Etape 2: Creez un agent avec 3 outils (racine carree + temperature + stats)
# Indice: tools_stats = [calculer_racine_carree, convertir_temperature, calculer_statistiques]
# Attention: convertir_temperature doit etre definie dans l'Exercice 1 pour etre utilisee ici
tools_stats = None # Remplacez None
graph_stats = None # Remplacez None
# Etape 3: Testez avec une question combinant plusieurs outils
# Indice: "Quelle est la racine carree de la moyenne de [10, 20, 30, 40, 50] ?"
# result_stats = graph_stats.invoke({"messages": [("user", "...")]})
print("Exercice 2 a completer : outil de calcul statistique")Exercice 2 a completer : outil de calcul statistique
Exercice 3 : Personnaliser le prompt système
Le prompt système définit la personnalite et le comportement de l’agent. Vous allez modifier le prompt pour créer un agent specialise en mathematiques qui explique ses raisonnements étape par étape.
Objectif : Créer un nouveau prompt système qui guide l’agent a adopter un style pedagogique et a detailler ses calculs.
Indices : - Modifiez le message "system" dans le ChatPromptTemplate.from_messages() - Ajoutez des instructions comme “Explique chaque étape de ton raisonnement” et “Affiche les calculs intermediaires” - Recreez l’agent avec le nouveau prompt et testez-le sur un problème a plusieurs étapes
# Exercice 3 : Prompt systeme personnalise
# Creez un agent avec un prompt systeme pedagogique
# Etape 1: Definissez un nouveau prompt systeme
# Indice: remplacez le message systeme par des instructions detaillees
# prompt_pedagogique = ChatPromptTemplate.from_messages([
# ("system", "Vos instructions pedagogiques ici"), # Remplacez par vos instructions
# MessagesPlaceholder("messages"),
# ])
prompt_pedagogique = None # TODO etudiant
# Etape 2: Creez l'agent avec le nouveau prompt
# Indice: create_react_agent(model=llm, tools=[calculer_racine_carree], prompt=prompt_pedagogique)
graph_pedago = None # TODO etudiant
# Etape 3: Testez avec une question qui necessite plusieurs etapes
# Indice: "Calcule la racine carree de 144, puis dis-moi si le resultat est un nombre premier"
# result_pedago = graph_pedago.invoke({"messages": [("user", "...")]})
print("Exercice 3 a completer : personnalisation du prompt systeme")Exercice 3 a completer : personnalisation du prompt systeme
Exercice 4 : Étendre l’agent avec un outil de puissance
L’agent ne vaut que par ses outils. À vous d’étendre l’agent en lui ajoutant un nouvel outil mathématique : calculer_puissance, puis de reconstruire l’agent avec les DEUX outils et de le tester sur une question qui exige la puissance.
Objectif : un agent multi-outils qui choisit seul entre racine carrée et puissance.
# Exercice 4 : Ajoutez un nouvel outil a l'agent
# Creez un outil qui calcule la puissance d'un nombre
# Exercice: Creez un outil 'calculer_puissance' avec le decorateur @tool
# L'outil prend deux parametres: nombre (float) et exposant (float)
# Indice: utilisez le meme pattern que 'calculer_racine_carree' ci-dessus
# N'oubliez pas la docstring (le LLM l'utilise pour comprendre l'outil)
@tool
def calculer_puissance(nombre: float, exposant: float) -> float:
"""Calcule la puissance d'un nombre (nombre^exposant)."""
pass # Exercice: retournez nombre ** exposant
# Exercice: Creez un nouvel agent avec les deux outils
# Indice: tools_exo = [calculer_racine_carree, calculer_puissance]
# puis create_react_agent(model=llm, tools=tools_exo, prompt=prompt) comme dans l'etape 4
tools_exo = None # Remplacez None
graph_exo = None # Remplacez None
# Exercice: Testez l'agent avec une question necessitant la puissance
# result_exo = graph_exo.invoke({"messages": [("user", "Quelle est la puissance de 5 eleve au carre ?")]})Conclusion
Felicitations ! Vous avez assemble les 4 composants fondamentaux d’un agent : un LLM pour raisonner, un Outil pour agir, un Prompt pour guider, et un Graphe LangGraph pour orchestrer.
Maintenant que nous savons construire un agent et lui donner un outil simple, nous sommes prets pour la prochaine étape : lui donner des outils puissants pour interagir avec des DataFrames Pandas et devenir un veritable assistant d’analyse de données. C’est l’objet du Lab 7 !
References
- S. Yao, J. Zhao, D. Yu, et al., ReAct: Synergizing Reasoning and Acting in Language Models, ICLR 2023, arXiv:2210.03629. Paradigme Reasoning+Acting (boucle Pensée → Action → Observation) implémenté par
create_react_agent(Étape 4) — concept central de ce laboratoire. - T. Schick, J. Dwivedi-Yu, R. Dessì, et al., Toolformer: Language Models Can Teach Themselves to Use Tools, NeurIPS 2023, arXiv:2302.04761. Fondement académique des LLMs tool-augmented (décider/quand/arguments d’un appel d’outil) sous-jacent au décorateur
@tool(Étape 2). - H. Chase, LangChain, 2022 ; LangGraph,
langchain-ai/langgraph. Framework d’orchestration d’agents (graphe d’états) utilisé tout au long du laboratoire — référence bibliographique détaillée au Lab 8.