| name | ai-agent-builder |
| description | Conception et implémentation d'agents IA autonomes avec outils, mémoire et orchestration. Se déclenche avec "agent IA", "AI agent", "autonomous agent", "tool use", "function calling", "agent framework", "LangChain agent", "CrewAI", "AutoGen", "agent loop", "ReAct". |
AI Agent Builder
Critères de choix du pattern
| Complexité | Pattern recommandé | Framework |
|---|
| Tâche unique, 1-5 outils | ReAct (Reasoning + Acting) | LangChain, SDK natif |
| Tâche longue multi-étapes | Plan-and-Execute | LangGraph |
| Exploration de solutions alternatives | Tree of Thoughts | LangGraph + custom |
| Équipe de spécialistes | Multi-agent orchestré | CrewAI, AutoGen, LangGraph |
| Workflow avec état persistant et branchements | Stateful graph | LangGraph |
Règle de base : commencer par ReAct. Passer à Plan-and-Execute si l'agent doit coordonner plus de 5 étapes séquentielles. Passer au multi-agent si les domaines de compétence sont orthogonaux (ex : code + recherche + rédaction).
Workflow en étapes
1. Rédiger le system prompt de l'agent
Structure minimale :
Tu es [RÔLE]. Tu [OBJECTIF PRINCIPAL].
Règles :
- Tu réponds uniquement sur [DOMAINE].
- Tu n'inventes pas de données.
- Si tu manques d'information, utilise l'outil [NOM_OUTIL] avant de répondre.
Finalisation : quand tu as la réponse, utilise l'outil `final_answer`.
Inclure : rôle, périmètre, règles de refus, format de sortie attendu, condition d'arrêt explicite.
2. Définir les outils (tool schemas)
Format Anthropic (compatible aussi OpenAI avec adaptation mineure) :
tools = [
{
"name": "search_web",
"description": "Recherche des informations récentes sur le web. Utiliser si la question porte sur des faits susceptibles d'avoir changé récemment.",
"input_schema": {
"type": "object",
"properties": {
"query": {"type": "string", "description": "Requête de recherche optimisée"}
},
"required": ["query"]
}
},
{
"name": "run_python",
"description": "Exécute du code Python et retourne stdout + stderr. Utiliser pour calculs, transformations de données.",
"input_schema": {
"type": "object",
"properties": {
"code": {"type": "string", "description": "Code Python à exécuter"}
},
"required": ["code"]
}
}
]
Bonnes pratiques outil :
- Description orientée quand utiliser, pas seulement ce que ça fait
- Toujours retourner
{"success": bool, "result": ..., "error": str | None}
- Timeout par outil (ex : 30s web, 10s DB, 60s code)
- Idempotent ou documenté comme non-idempotent
3. Implémenter la boucle agent
Boucle ReAct minimaliste avec Anthropic SDK :
import anthropic
client = anthropic.Anthropic()
async def agent_loop(task: str, tools: list, max_iter: int = 15) -> str:
messages = [{"role": "user", "content": task}]
for iteration in range(max_iter):
response = client.messages.create(
model="claude-sonnet-4-5",
max_tokens=4096,
tools=tools,
messages=messages
)
if response.stop_reason == "end_turn":
return next(b.text for b in response.content if hasattr(b, "text"))
if response.stop_reason == "tool_use":
messages.append({"role": "assistant", "content": response.content})
tool_results = []
for block in response.content:
if block.type == "tool_use":
result = await execute_tool(block.name, block.input)
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": str(result)
})
messages.append({"role": "user", "content": tool_results})
return f"[TIMEOUT] Max itérations ({max_iter}) atteintes sans réponse finale."
async def execute_tool(name: str, args: dict) -> dict:
try:
handler = TOOL_REGISTRY[name]
return {"success": True, "result": await handler(**args)}
except Exception as e:
return {"success": False, "result": None, "error": str(e)}
4. Mémoire — choisir la couche adaptée
| Besoin | Solution |
|---|
| Contexte de session (< 200k tokens) | Passer tout le fil dans messages |
| Historique long / multi-session | Résumé LLM + vector store (pgvector, Chroma) |
| Faits persistants sur l'utilisateur/projet | mem0, Zep, ou table SQL simple |
| Cache de résultats d'outils | Redis avec TTL |
Mémoire avec résumé automatique (LangChain) :
from langchain.memory import ConversationSummaryBufferMemory
from langchain_anthropic import ChatAnthropic
llm = ChatAnthropic(model="claude-sonnet-4-5")
memory = ConversationSummaryBufferMemory(
llm=llm,
max_token_limit=3000,
return_messages=True
)
5. Multi-agent avec LangGraph
from langgraph.graph import StateGraph, END
from typing import TypedDict, Annotated
import operator
class AgentState(TypedDict):
task: str
plan: list[str]
results: Annotated[list, operator.add]
final_answer: str
def orchestrator_node(state: AgentState) -> AgentState:
plan = decompose_task(state["task"])
return {"plan": plan}
def worker_node(state: AgentState) -> AgentState:
result = execute_subtask(state["plan"][0])
return {"results": [result], "plan": state["plan"][1:]}
def should_continue(state: AgentState) -> str:
return "worker" if state["plan"] else "synthesizer"
graph = StateGraph(AgentState)
graph.add_node("orchestrator", orchestrator_node)
graph.add_node("worker", worker_node)
graph.add_conditional_edges("worker", should_continue, {"worker": "worker", "synthesizer": END})
6. Monitoring et observabilité
LangSmith (tracing complet) :
export LANGCHAIN_TRACING_V2=true
export LANGCHAIN_API_KEY=ls__...
export LANGCHAIN_PROJECT=mon-agent-prod
Avec le décorateur @traceable :
from langsmith import traceable
@traceable(run_type="chain", name="agent_loop")
async def run_agent(task: str) -> str:
return await agent_loop(task, tools)
Métriques à tracker :
- Taux de succès des tâches (objectif : > 90%)
- Itérations moyennes par tâche (signal de complexité ou de boucle)
- Coût moyen par tâche (tokens * prix modèle)
- Taux d'erreur par outil (identifier les outils fragiles)
- Latence P95 (pour les agents synchrones)
Garde-fous et sécurité
HIGH_RISK_TOOLS = {"send_email", "delete_file", "execute_sql_write", "deploy"}
async def safe_execute_tool(name: str, args: dict) -> dict:
if name in HIGH_RISK_TOOLS:
confirmation = await ask_human(
f"L'agent veut exécuter `{name}` avec les args : {args}\nConfirmer ? [o/N]"
)
if not confirmation:
return {"success": False, "error": "Action refusée par l'opérateur"}
if rate_limiter.is_exceeded(name):
return {"success": False, "error": "Rate limit dépassé pour cet outil"}
return await execute_tool(name, args)
Checklist sécurité avant mise en prod :
Anti-patterns à éviter
| Anti-pattern | Impact | Correctif |
|---|
Pas de max_iterations | Boucle infinie, coût incontrôlé | Toujours borner la boucle |
| Outil qui lève une exception raw | L'agent crashe ou hallucine | try/except systématique, retourner {"success": false} |
| Trop d'outils (> 15) | L'agent choisit mal | Limiter à 7±2 par rôle, regrouper par domaine |
| System prompt flou sur la condition d'arrêt | L'agent ne sait jamais quand s'arrêter | Définir explicitement final_answer ou un outil de finalisation |
| Multi-agent sans protocole de message | Messages incompréhensibles entre agents | Définir un format JSON structuré pour chaque échange inter-agent |
| Mémoire illimitée dans les messages | Context window explosée, coût élevé | Sliding window + résumé automatique |
| Outil non-idempotent appelé plusieurs fois | Effets de bord multiples | Documenter, détecter les appels répétés |
Bonnes pratiques 2026
- Prefer native SDK over framework : pour les agents simples, l'Anthropic SDK directement est plus maintenable que LangChain. Utiliser LangGraph uniquement si le workflow est un graphe réel.
- Structured outputs : forcer le format de réponse finale avec un tool
final_answer plutôt que de parser du texte libre.
- Prompt caching : utiliser
cache_control: {"type": "ephemeral"} sur les blocs statiques (system prompt, tools) pour réduire les coûts de 70-90% sur les agents longue durée.
- Model routing : utiliser
claude-haiku-3-5 pour les sous-tâches de classification/routing, claude-sonnet-4-5 pour le raisonnement principal.
- Parallel tool calls : Anthropic retourne plusieurs
tool_use dans un seul message — les exécuter en parallèle avec asyncio.gather().
- Eval-driven development : créer un dataset de 20-50 cas de test représentatifs avant de déployer. Relancer les evals à chaque modification du system prompt ou des outils.