Agents et outils LangChain : Construire des IA autonomes capables d'agir
Les agents représentent l’évolution naturelle des systèmes IA : au lieu de suivre un workflow prédéfini, ils décident autonomiquement quelles actions entreprendre pour atteindre un objectif. Avec LangChain, créer des agents capables d’utiliser des outils (recherche web, calculs, APIs, bases de données) devient accessible. Dans cet article, nous explorons en profondeur comment construire des agents intelligents, de la théorie à la pratique avancée.

Qu’est-ce qu’un agent IA ?
Un agent est un système qui :
- Reçoit un objectif de l’utilisateur
- Raisonne sur les étapes nécessaires
- Sélectionne et utilise des outils de manière autonome
- Observe les résultats et ajuste sa stratégie
- Itère jusqu’à atteindre l’objectif
Différence entre Chain et Agent
| Aspect | Chain (Chaîne) | Agent |
|---|---|---|
| Workflow | Prédéfini et fixe | Décidé dynamiquement |
| Logique | Séquentielle (A→B→C) | Conditionnelle (si X alors Y) |
| Outils | Tous utilisés systématiquement | Sélection intelligente |
| Flexibilité | Faible | Élevée |
| Complexité | Simple | Modérée à élevée |
| Cas d’usage | Tâches répétitives | Tâches exploratoires |
Exemple concret :
- Chain : “Traduis ce texte EN→FR, puis résume en 3 phrases”
- Agent : “Trouve des informations sur le sujet X et crée un rapport” (l’agent décide s’il faut chercher sur le web, dans une base de données, calculer des statistiques, etc.)
Le pattern ReAct : Reasoning + Acting
Les agents LangChain utilisent principalement le pattern ReAct, publié par Google Research en 2022. Ce pattern alterne entre raisonnement (thinking) et action (doing).
Cycle ReAct
1. Thought (Pensée) : "Je dois chercher des informations sur X"
2. Action (Action) : Utiliser l'outil "Search"
3. Observation : Résultat de la recherche
4. Thought : "J'ai trouvé Y, maintenant je dois calculer Z"
5. Action : Utiliser l'outil "Calculator"
6. Observation : Résultat du calcul
7. Thought : "J'ai toutes les informations, je peux répondre"
8. Final Answer : Réponse complète
Exemple de trace ReAct
User: Quelle est la racine carrée de l'âge du président français actuel ?
Thought: Je dois d'abord trouver qui est le président et son âge
Action: Search
Action Input: "président français 2025 âge"
Observation: Emmanuel Macron, né en 1977, a 48 ans en 2025
Thought: Maintenant je dois calculer la racine carrée de 48
Action: Calculator
Action Input: sqrt(48)
Observation: 6.928
Thought: J'ai la réponse finale
Final Answer: La racine carrée de l'âge d'Emmanuel Macron (48 ans) est environ 6.93.
Anatomie d’un agent LangChain
Composants essentiels
- LLM : Le “cerveau” qui raisonne et décide
- Tools : Les capacités d’action (recherche, calcul, APIs)
- Agent Type : La stratégie de décision (ReAct, Plan-and-Execute, etc.)
- Memory : Le contexte conversationnel (optionnel)
Création d’un agent simple
from langchain_openai import ChatOpenAI
from langchain.agents import AgentExecutor, create_react_agent
from langchain.tools import Tool
from langchain.prompts import PromptTemplate
# 1. LLM (le cerveau)
llm = ChatOpenAI(model="gpt-4", temperature=0)
# 2. Définition des outils
def search_web(query: str) -> str:
"""Recherche sur le web"""
# Implémentation réelle avec une API de recherche
return f"Résultats pour '{query}': ..."
def calculate(expression: str) -> str:
"""Calcule une expression mathématique de manière sécurisée"""
import ast
import operator
# Opérateurs autorisés
operators = {
ast.Add: operator.add,
ast.Sub: operator.sub,
ast.Mult: operator.mul,
ast.Div: operator.truediv,
ast.Pow: operator.pow,
ast.USub: operator.neg,
}
def eval_expr(node):
if isinstance(node, ast.Num): # Nombre
return node.n
elif isinstance(node, ast.BinOp): # Opération binaire
return operators[type(node.op)](eval_expr(node.left), eval_expr(node.right))
elif isinstance(node, ast.UnaryOp): # Opération unaire
return operators[type(node.op)](eval_expr(node.operand))
else:
raise ValueError(f"Expression non autorisée: {node}")
try:
node = ast.parse(expression, mode='eval')
return str(eval_expr(node.body))
except Exception as e:
return f"Erreur de calcul: {str(e)}"
tools = [
Tool(
name="Search",
func=search_web,
description="Utile pour rechercher des informations actuelles sur le web. Input: une requête de recherche."
),
Tool(
name="Calculator",
func=calculate,
description="Utile pour effectuer des calculs mathématiques. Input: une expression Python (ex: '2+2' ou 'sqrt(16)')."
)
]
# 3. Prompt ReAct standard
prompt = PromptTemplate.from_template("""
Answer the following questions as best you can. You have access to the following tools:
{tools}
Use the following format:
Question: the input question you must answer
Thought: you should always think about what to do
Action: the action to take, should be one of [{tool_names}]
Action Input: the input to the action
Observation: the result of the action
... (this Thought/Action/Action Input/Observation can repeat N times)
Thought: I now know the final answer
Final Answer: the final answer to the original input question
Question: {input}
{agent_scratchpad}
""")
# 4. Création de l'agent
agent = create_react_agent(llm, tools, prompt)
# 5. Executor (gère l'exécution)
agent_executor = AgentExecutor(
agent=agent,
tools=tools,
verbose=True, # Affiche les traces
max_iterations=5, # Limite de sécurité
handle_parsing_errors=True # Gestion des erreurs
)
# 6. Utilisation
result = agent_executor.invoke({
"input": "Quelle est la racine carrée de 144 et qui a inventé les mathématiques ?"
})
print(result["output"])
Sortie (avec verbose=True) :
> Entering new AgentExecutor chain...
Thought: I need to calculate the square root of 144 and find who invented mathematics
Action: Calculator
Action Input: sqrt(144)
Observation: 12.0
Thought: Now I need to find who invented mathematics
Action: Search
Action Input: who invented mathematics
Observation: Mathematics wasn't "invented" by one person, but developed over millennia...
Thought: I now have all the information needed
Final Answer: La racine carrée de 144 est 12. Les mathématiques n'ont pas été inventées par une seule personne, mais se sont développées au fil des millénaires...
Outils intégrés dans LangChain
LangChain propose des dizaines d’outils prêts à l’emploi.
Outils de recherche
from langchain_community.tools import DuckDuckGoSearchRun, WikipediaQueryRun
from langchain_community.utilities import WikipediaAPIWrapper
# Recherche web avec DuckDuckGo
search = DuckDuckGoSearchRun()
# Wikipedia
wikipedia = WikipediaQueryRun(api_wrapper=WikipediaAPIWrapper())
tools = [
Tool(
name="WebSearch",
func=search.run,
description="Recherche sur le web pour des informations actuelles"
),
Tool(
name="Wikipedia",
func=wikipedia.run,
description="Recherche sur Wikipedia pour des informations encyclopédiques"
)
]
Outils de calcul et code
from langchain_experimental.tools import PythonREPLTool
from langchain.tools import ShellTool
# Exécution de code Python
python_repl = PythonREPLTool()
# Exécution de commandes shell
shell = ShellTool()
tools = [
Tool(
name="Python",
func=python_repl.run,
description="Exécute du code Python. Utile pour calculs, data science, graphiques."
),
Tool(
name="Shell",
func=shell.run,
description="Exécute des commandes système. ATTENTION: dangereux en production."
)
]
🔒 Sécurité critique : PythonREPLTool et ShellTool peuvent exécuter du code arbitraire ! Ne les utilisez JAMAIS avec des inputs utilisateurs non validés. Réservez-les aux environnements de développement isolés.
Outils de données structurées
from langchain.agents import create_sql_agent
from langchain.sql_database import SQLDatabase
# Connexion à une base de données
db = SQLDatabase.from_uri("sqlite:///mydatabase.db")
# Agent SQL automatique
sql_agent = create_sql_agent(
llm=llm,
db=db,
agent_type="openai-tools",
verbose=True
)
# L'agent génère automatiquement les requêtes SQL
result = sql_agent.run("Combien d'utilisateurs ont plus de 30 ans ?")
Outils API personnalisés
import requests
def get_weather(city: str) -> str:
"""Récupère la météo d'une ville"""
api_key = "YOUR_API_KEY"
url = f"https://api.openweathermap.org/data/2.5/weather?q={city}&appid={api_key}"
response = requests.get(url)
data = response.json()
temp = data["main"]["temp"] - 273.15 # Kelvin vers Celsius
description = data["weather"][0]["description"]
return f"À {city}: {temp:.1f}°C, {description}"
weather_tool = Tool(
name="Weather",
func=get_weather,
description="Donne la météo actuelle d'une ville. Input: nom de la ville en anglais."
)
Outils RAG
from langchain.tools.retriever import create_retriever_tool
# Supposons que vous avez un retriever RAG configuré
retriever = vectorstore.as_retriever()
# Transformer le retriever en outil d'agent
retriever_tool = create_retriever_tool(
retriever,
name="DocumentSearch",
description="Recherche dans la documentation interne de l'entreprise. Utile pour les questions sur les procédures, politiques, et produits."
)
tools = [search, calculator, retriever_tool]
Types d’agents disponibles
LangChain propose plusieurs architectures d’agents selon vos besoins.
ReAct Agent (recommandé)
Utilisation : Cas général, bon équilibre flexibilité/fiabilité
from langchain.agents import create_react_agent
agent = create_react_agent(llm, tools, prompt)
Avantages : Traçabilité, robuste, bien documenté Limites : Peut être verbeux
OpenAI Functions Agent
Utilisation : Avec OpenAI/GPT-4 pour plus de fiabilité
from langchain.agents import create_openai_functions_agent
agent = create_openai_functions_agent(llm, tools, prompt)
Avantages : Meilleure sélection d’outils, moins d’erreurs de parsing Limites : Uniquement compatible OpenAI/Azure
Structured Chat Agent
Utilisation : Outils avec inputs complexes (JSON)
from langchain.agents import create_structured_chat_agent
agent = create_structured_chat_agent(llm, tools, prompt)
Avantages : Supporte des outils avec multiples paramètres
Exemple : send_email(to: str, subject: str, body: str)
Self-Ask with Search
Utilisation : Questions nécessitant plusieurs recherches successives
from langchain.agents import create_self_ask_with_search_agent
agent = create_self_ask_with_search_agent(llm, [search_tool], prompt)
Pattern : L’agent se pose des sous-questions avant de répondre
Plan-and-Execute Agent
Utilisation : Tâches complexes nécessitant une planification
from langchain.agents import PlanAndExecute
from langchain_experimental.plan_and_execute import load_agent_executor
agent_executor = load_agent_executor(llm, tools, verbose=True)
Pattern :
- Planifie toutes les étapes
- Exécute chaque étape
- Révise le plan si nécessaire
Comparaison des types d’agents
| Type | Complexité | Fiabilité | Performance | Meilleur pour |
|---|---|---|---|---|
| ReAct | ⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ | Usage général |
| OpenAI Functions | ⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | Production avec OpenAI |
| Structured Chat | ⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ | Outils complexes |
| Self-Ask | ⭐⭐ | ⭐⭐⭐ | ⭐⭐ | Recherche approfondie |
| Plan-and-Execute | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐ | Tâches multi-étapes |
Cas d’usage avancés
Agent de recherche et d’analyse de données
from langchain.agents import AgentExecutor, create_openai_functions_agent
from langchain_community.tools import DuckDuckGoSearchRun
from langchain_experimental.tools import PythonREPLTool
from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder
# Outils
search = DuckDuckGoSearchRun()
python = PythonREPLTool()
tools = [
Tool(name="Search", func=search.run, description="Recherche web"),
Tool(name="Python", func=python.run, description="Exécute du Python pour calculs et visualisations")
]
# Prompt spécialisé
prompt = ChatPromptTemplate.from_messages([
("system", """Tu es un analyste de données expert. Tu peux:
1. Rechercher des informations sur le web
2. Effectuer des calculs et créer des graphiques avec Python
Réponds de manière structurée avec des chiffres précis."""),
("human", "{input}"),
MessagesPlaceholder("agent_scratchpad")
])
# LLM configuré une seule fois
llm = ChatOpenAI(model="gpt-4", temperature=0)
# Agent
agent = create_openai_functions_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
# Utilisation
result = agent_executor.invoke({
"input": """
Recherche les revenus 2024 d'Apple, Google et Microsoft.
Calcule la moyenne et crée un graphique en barres comparatif.
Sauvegarde le graphique dans 'comparison.png'.
"""
})
Comportement :
- Recherche les revenus sur le web (3 recherches)
- Extrait les chiffres
- Génère le code Python pour le graphique
- Exécute le code
- Confirme la création du fichier
Agent de support client avec RAG
from langchain.tools.retriever import create_retriever_tool
from langchain.agents import create_openai_functions_agent
from langchain.memory import ConversationBufferMemory
# Outil RAG sur la documentation produit
doc_retriever = vectorstore.as_retriever()
doc_tool = create_retriever_tool(
doc_retriever,
"ProductDocs",
"Recherche dans la documentation produit et les FAQs"
)
# Outil de ticket
def create_ticket(issue: str) -> str:
"""Crée un ticket de support"""
ticket_id = generate_ticket_id()
save_to_database(ticket_id, issue)
return f"Ticket #{ticket_id} créé avec succès"
ticket_tool = Tool(
name="CreateTicket",
func=create_ticket,
description="Crée un ticket si le problème ne peut pas être résolu immédiatement"
)
tools = [doc_tool, ticket_tool]
# Mémoire conversationnelle
memory = ConversationBufferMemory(
memory_key="chat_history",
return_messages=True
)
# Agent avec mémoire
prompt = ChatPromptTemplate.from_messages([
("system", """Tu es un assistant support client.
1. Cherche d'abord dans la documentation
2. Si tu ne trouves pas de solution, crée un ticket
3. Sois courtois et professionnel"""),
MessagesPlaceholder("chat_history"),
("human", "{input}"),
MessagesPlaceholder("agent_scratchpad")
])
agent = create_openai_functions_agent(llm, tools, prompt)
agent_executor = AgentExecutor(
agent=agent,
tools=tools,
memory=memory,
verbose=True
)
# Conversation
agent_executor.invoke({"input": "Comment réinitialiser mon mot de passe ?"})
# → Recherche dans la doc, trouve la procédure, explique
agent_executor.invoke({"input": "Ça ne fonctionne toujours pas"})
# → Utilise le contexte précédent, crée un ticket
Agent de veille automatisée
from langchain.tools import Tool
from datetime import datetime
def fetch_rss_feeds(topics: str) -> str:
"""Récupère les derniers articles RSS"""
# Implémentation avec feedparser
return "Articles récents sur ..."
def summarize_article(url: str) -> str:
"""Résume un article web"""
# Implémentation avec BeautifulSoup + LLM
return "Résumé: ..."
def save_to_notion(content: str) -> str:
"""Sauvegarde dans Notion"""
# Implémentation avec l'API Notion
return "Sauvegardé dans Notion"
tools = [
Tool(name="FetchNews", func=fetch_rss_feeds, description="Récupère les dernières actualités"),
Tool(name="Summarize", func=summarize_article, description="Résume un article"),
Tool(name="SaveNotion", func=save_to_notion, description="Sauvegarde dans Notion")
]
# Agent de veille
prompt = ChatPromptTemplate.from_messages([
("system", """Tu es un agent de veille technologique.
Tâches quotidiennes:
1. Chercher les actualités sur {topics}
2. Résumer les 5 articles les plus importants
3. Sauvegarder dans Notion avec tags appropriés"""),
("human", "Effectue la veille du jour"),
MessagesPlaceholder("agent_scratchpad")
])
agent = create_react_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
# Exécution automatique (via cron ou scheduler)
result = agent_executor.invoke({
"input": f"Effectue la veille pour {datetime.now().strftime('%Y-%m-%d')}"
})
CAgent multi-agents (orchestration)
from langchain.agents import AgentExecutor
# Agent 1 : Recherche
research_agent = create_react_agent(llm, [search_tool], research_prompt)
research_executor = AgentExecutor(agent=research_agent, tools=[search_tool])
# Agent 2 : Analyse
analysis_agent = create_react_agent(llm, [python_tool], analysis_prompt)
analysis_executor = AgentExecutor(agent=analysis_agent, tools=[python_tool])
# Agent 3 : Rédaction
writing_agent = create_react_agent(llm, [], writing_prompt)
writing_executor = AgentExecutor(agent=writing_agent, tools=[])
# Orchestrateur (meta-agent)
def delegate_to_research(query: str) -> str:
return research_executor.invoke({"input": query})["output"]
def delegate_to_analysis(data: str) -> str:
return analysis_executor.invoke({"input": data})["output"]
def delegate_to_writing(outline: str) -> str:
return writing_executor.invoke({"input": outline})["output"]
meta_tools = [
Tool(name="Research", func=delegate_to_research, description="Agent de recherche"),
Tool(name="Analysis", func=delegate_to_analysis, description="Agent d'analyse"),
Tool(name="Writing", func=delegate_to_writing, description="Agent de rédaction")
]
# Meta-agent qui coordonne
meta_agent = create_react_agent(llm, meta_tools, meta_prompt)
meta_executor = AgentExecutor(agent=meta_agent, tools=meta_tools, verbose=True)
# Utilisation
result = meta_executor.invoke({
"input": "Crée un rapport complet sur les tendances IA 2025"
})
# → Délègue la recherche, puis l'analyse, puis la rédaction
Patterns avancés et optimisations
Retry automatique avec fallback
from langchain.agents import AgentExecutor
agent_executor = AgentExecutor(
agent=agent,
tools=tools,
max_iterations=10,
max_execution_time=60, # Timeout après 60s
early_stopping_method="generate", # Génère une réponse même si incomplet
handle_parsing_errors=True, # Gère les erreurs de parsing
return_intermediate_steps=True # Retourne tous les steps pour debugging
)
# Avec retry manuel
from tenacity import retry, stop_after_attempt, wait_exponential
@retry(
stop=stop_after_attempt(3),
wait=wait_exponential(multiplier=1, min=2, max=10)
)
def run_agent_with_retry(query):
return agent_executor.invoke({"input": query})
result = run_agent_with_retry("Question complexe")
Validation des outputs d’outils
from pydantic import BaseModel, Field, validator
class WeatherOutput(BaseModel):
"""Modèle validé pour la météo"""
temperature: float = Field(..., ge=-50, le=60, description="Température en °C")
description: str = Field(..., min_length=3)
@validator('temperature')
def temp_must_be_reasonable(cls, v):
if not -50 <= v <= 60:
raise ValueError('Température hors limites')
return v
def safe_weather_tool(city: str) -> str:
"""Outil météo avec validation"""
raw_data = get_weather_api(city)
validated = WeatherOutput(**raw_data) # Pydantic valide
return f"{validated.temperature}°C, {validated.description}"
Caching des résultats d’outils
from functools import lru_cache
from datetime import datetime, timedelta
# Cache simple avec TTL
cache = {}
cache_ttl = {}
def cached_tool(func):
def wrapper(query: str) -> str:
# Vérifie le cache
if query in cache:
if datetime.now() - cache_ttl[query] < timedelta(hours=1):
print(f"[CACHE HIT] {query}")
return cache[query]
# Exécute et cache
result = func(query)
cache[query] = result
cache_ttl[query] = datetime.now()
return result
return wrapper
@cached_tool
def expensive_search(query: str) -> str:
"""Recherche coûteuse avec cache"""
return search_api(query)
Streaming des réponses
from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler
# LLM avec streaming
llm = ChatOpenAI(
model="gpt-4",
streaming=True,
callbacks=[StreamingStdOutCallbackHandler()]
)
# Agent avec streaming
agent = create_react_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools)
# Les réponses s'affichent token par token
result = agent_executor.invoke({"input": "Question longue..."})
Rate limiting et quotas
from ratelimit import limits, sleep_and_retry
import time
# Limite : 10 appels par minute
@sleep_and_retry
@limits(calls=10, period=60)
def rate_limited_tool(query: str) -> str:
"""Outil avec rate limiting"""
return expensive_api_call(query)
# Compteur de tokens/coût
class CostTracker:
def __init__(self, budget_usd=10):
self.total_tokens = 0
self.total_cost = 0
self.budget = budget_usd
def track(self, tokens: int, cost_per_1k: float = 0.03):
self.total_tokens += tokens
self.total_cost += (tokens / 1000) * cost_per_1k
if self.total_cost > self.budget:
raise Exception(f"Budget dépassé : ${self.total_cost:.2f}")
print(f"Coût actuel : ${self.total_cost:.2f}/{self.budget}")
tracker = CostTracker(budget_usd=5)
# Callback personnalisé
class CostTrackingCallback:
def on_llm_end(self, response, **kwargs):
tokens = response.llm_output.get('token_usage', {}).get('total_tokens', 0)
tracker.track(tokens)
agent_executor = AgentExecutor(
agent=agent,
tools=tools,
callbacks=[CostTrackingCallback()]
)
Debugging et monitoring
Activer les logs détaillés
import logging
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger("langchain.agents")
# Ou avec LangSmith (recommandé)
import os
os.environ["LANGCHAIN_TRACING_V2"] = "true"
os.environ["LANGCHAIN_API_KEY"] = "your-api-key"
os.environ["LANGCHAIN_PROJECT"] = "mon-projet-agents"
Callback personnalisé pour debugging
from langchain.callbacks.base import BaseCallbackHandler
class DebugCallback(BaseCallbackHandler):
def on_agent_action(self, action, **kwargs):
print(f"\n🤖 Action: {action.tool}")
print(f"📝 Input: {action.tool_input}")
def on_tool_start(self, serialized, input_str, **kwargs):
print(f"\n🔧 Outil lancé: {serialized.get('name', 'unknown')}")
def on_tool_end(self, output, **kwargs):
print(f"✅ Résultat: {output[:100]}...")
def on_tool_error(self, error, **kwargs):
print(f"❌ Erreur: {error}")
def on_agent_finish(self, finish, **kwargs):
print(f"\n🏁 Agent terminé")
print(f"📊 Iterations: {finish.return_values}")
agent_executor = AgentExecutor(
agent=agent,
tools=tools,
callbacks=[DebugCallback()],
verbose=True
)
Analyse des traces
result = agent_executor.invoke(
{"input": "Question"},
return_intermediate_steps=True
)
# Afficher toutes les étapes
for i, (action, observation) in enumerate(result["intermediate_steps"]):
print(f"\n--- Étape {i+1} ---")
print(f"Outil: {action.tool}")
print(f"Input: {action.tool_input}")
print(f"Output: {observation[:200]}")
# Compter les appels par outil
from collections import Counter
tool_usage = Counter([action.tool for action, _ in result["intermediate_steps"]])
print(f"\nUtilisation des outils: {tool_usage}")
Limites et pièges à éviter
Boucles infinies
Problème : L’agent répète les mêmes actions indéfiniment
Solution :
agent_executor = AgentExecutor(
agent=agent,
tools=tools,
max_iterations=10, # Force l'arrêt après 10 itérations
max_execution_time=60 # Timeout après 60 secondes
)
Hallucinations d’outils
Problème : L’agent invente des outils qui n’existent pas
Solution : Descriptions précises et prompt explicite
Tool(
name="Weather", # Nom court et clair
func=get_weather,
description="""Donne la météo ACTUELLE d'une ville.
Input: Nom de la ville en anglais (ex: 'Paris', 'London').
Ne PAS utiliser pour des prévisions ou des données historiques."""
)
# Prompt strict
prompt = PromptTemplate.from_template("""
Tu dois UNIQUEMENT utiliser les outils listés ci-dessous.
N'invente JAMAIS un outil qui n'est pas dans cette liste.
Outils disponibles:
{tools}
...
""")
Coûts élevés
Problème : Les agents font de nombreux appels LLM
Solutions :
# 1. Utiliser un modèle moins cher pour le raisonnement
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0) # 60x moins cher que GPT-4
# 2. Limiter les itérations
agent_executor = AgentExecutor(agent=agent, tools=tools, max_iterations=5)
# 3. Caching agressif
from langchain.cache import SQLiteCache
from langchain.globals import set_llm_cache
set_llm_cache(SQLiteCache(database_path=".langchain.db"))
# 4. Budget hard limit
class BudgetExceededError(Exception):
pass
class BudgetCallback(BaseCallbackHandler):
def __init__(self, max_usd=5):
self.total_cost = 0
self.max_cost = max_usd
def on_llm_end(self, response, **kwargs):
tokens = response.llm_output.get('token_usage', {}).get('total_tokens', 0)
self.total_cost += (tokens / 1000) * 0.03 # $0.03 per 1K tokens
if self.total_cost > self.max_cost:
raise BudgetExceededError(f"Budget dépassé: ${self.total_cost:.2f}")
💰 Astuce coûts : Un agent peut consommer 5-10× plus de tokens qu’une chaîne simple ! Utilisez gpt-4o-mini pour le raisonnement (60× moins cher que GPT-4) et réservez les modèles puissants aux tâches complexes.
Erreurs de parsing
Problème : L’agent génère un format invalide
Solution :
agent_executor = AgentExecutor(
agent=agent,
tools=tools,
handle_parsing_errors=True, # Gère automatiquement
# Ou message personnalisé:
handle_parsing_errors="Vérifie ton format de réponse et réessaie."
)
Sécurité
Problème : Outils dangereux (Shell, Python REPL)
Solutions :
# 1. Environnement sandboxé
from langchain_experimental.tools import PythonREPLTool
python = PythonREPLTool()
python.globals = {"__builtins__": {}} # Désactive les built-ins dangereux
# 2. Validation des inputs
def safe_shell(command: str) -> str:
"""Shell avec whitelist"""
allowed_commands = ["ls", "pwd", "date", "whoami"]
cmd = command.split()[0]
if cmd not in allowed_commands:
return f"Commande '{cmd}' non autorisée"
# Exécute seulement si autorisé
return subprocess.check_output(command, shell=True).decode()
# 3. Audit logging
class SecurityCallback(BaseCallbackHandler):
def on_tool_start(self, serialized, input_str, **kwargs):
tool_name = serialized.get("name")
if tool_name in ["Shell", "Python"]:
log_security_event(f"Execution: {tool_name} - {input_str}")
Exercices pratiques
Exercice 1 : Agent de veille technologique
Objectif : Créer un agent qui surveille l’actualité tech et génère un résumé quotidien.
Spécifications :
- Recherche automatique sur des sites tech (DuckDuckGo)
- Extraction des tendances principales
- Génération d’un résumé structuré avec bullet points
- Sauvegarde du résumé dans un fichier Markdown
Outils à implémenter :
DuckDuckGoSearchRunpour la recherche- Outil personnalisé pour sauvegarder en Markdown
- Optionnel : Outil de scraping pour extraire le contenu complet
Points clés :
- Limiter les itérations pour contrôler les coûts
- Gérer les erreurs de réseau avec retry
- Structurer le prompt pour obtenir des résumés concis
Exercice 2 : Agent SQL conversationnel
Objectif : Construire un agent qui répond à des questions en langage naturel sur une base de données.
Spécifications :
- Connexion à une base de données SQLite (ou PostgreSQL)
- Compréhension de questions complexes (“Quels sont les 5 meilleurs clients du mois dernier ?”)
- Génération automatique de requêtes SQL optimisées
- Retour des résultats sous forme de tableaux ou graphiques
Outils à implémenter :
create_sql_agentavec un schéma de base de données- Validation des requêtes avant exécution (read-only)
- Outil de visualisation avec matplotlib/plotly
Extensions :
- Ajout d’un cache pour les requêtes fréquentes
- Support de plusieurs bases de données
- Génération d’insights automatiques (“Cette tendance est inhabituelle…”)
Exercice 3 : Agent multi-outils de productivité
Objectif : Créer un assistant personnel qui combine plusieurs outils.
Spécifications :
- Recherche web (actualités, informations)
- Calculs mathématiques et conversions
- Gestion d’une todo-list (ajout, lecture, suppression)
- Envoi d’emails ou notifications Slack
Outils à implémenter :
- Recherche :
DuckDuckGoSearchRun - Calcul : Outil personnalisé avec
sympyounumpy - Todo-list : Outil CRUD avec stockage JSON
- Communication : API Slack ou SMTP
Points clés :
- L’agent doit décider intelligemment quel outil utiliser
- Gestion de la mémoire pour le contexte conversationnel
- Confirmation utilisateur avant actions critiques (envoi email)
Extensions :
- Intégration calendrier (Google Calendar API)
- Rappels automatiques
- Résumés de fin de journée
Conclusion
Les agents LangChain représentent un saut qualitatif dans les capacités des systèmes IA : de simples générateurs de texte à des assistants autonomes capables d’actions concrètes. En maîtrisant les concepts de ce guide, vous pouvez construire :
✅ Agents de recherche qui collectent et analysent des données automatiquement
✅ Assistants de support qui consultent vos docs et créent des tickets
✅ Systèmes de veille qui surveillent et résument l’actualité
✅ Workflows complexes avec orchestration multi-agents
✅ Outils métiers intégrant vos APIs et bases de données
Checklist avant de déployer un agent
- Outils bien définis : Descriptions claires, validations des inputs
- Limites configurées :
max_iterations,max_execution_time - Gestion d’erreurs :
handle_parsing_errors=True - Monitoring : LangSmith ou callbacks personnalisés
- Budget contrôlé : Rate limiting, caching, modèle optimisé
- Sécurité : Outils dangereux sandboxés ou désactivés
- Tests : Dataset de cas d’usage avec résultats attendus
- Logs : Audit trail pour les actions critiques
Évolutions futures
- LangGraph : Framework avancé pour agents avec graphes d’états complexes
- Multi-agent orchestration : Équipes d’agents spécialisés collaborant
- Agents multimodaux : Utilisation d’images, audio, vidéo
- Apprentissage continu : Agents qui s’améliorent au fil des interactions
Pour aller plus loin :
- Commencez par notre introduction à LangChain
- Implémentez un système RAG avec LangChain
- Comprenez les embeddings pour les outils de recherche
- Découvrez les Transformers qui alimentent les LLMs
- Maîtrisez les tokens pour optimiser les coûts
- Explorez les frameworks open source
- Apprenez le fine-tuning pour personnaliser les agents
- Assurez la sécurité et l’éthique de vos agents
- Comparez les modèles et acteurs pour choisir le meilleur LLM
- Optimisez avec les vecteurs pour la recherche sémantique
Navigation
← Retour à la Formation LangChain | Module suivant : Guide Pratique et Cookbook →