💻 Développement

dev-ai-agent-builder

Conception et implémentation d'agents IA autonomes avec outils, mémoire et orchestration.

⚡ Installation & lancement en 1 commande

Copiez-collez dans votre terminal : le skill s'installe dans ~/.claude/skills et Claude Code se lance directement dessus.

macOS / Linux
curl -fsSL https://raw.githubusercontent.com/khalilbenaz/claude-skills-collection/main/install.sh | sh -s -- dev-ai-agent-builder --launch
Windows (PowerShell)
iex "& { $(iwr -useb https://raw.githubusercontent.com/khalilbenaz/claude-skills-collection/main/install.ps1) } dev-ai-agent-builder -Launch"

🚀 Déjà installé ?

claude "/dev-ai-agent-builder"

Ou tapez /dev-ai-agent-builder dans une session Claude Code, ou décrivez simplement votre besoin — le skill se déclenche automatiquement via le skill-router.

🔑 Déclencheurs automatiques

Le skill s'active automatiquement quand votre demande contient :

agent IAAI agentautonomous agenttool usefunction callingagent frameworkLangChain agentCrewAIAutoGenagent loopReAct

📦 Installation manuelle

git clone https://github.com/khalilbenaz/claude-skills-collection.git cp -r claude-skills-collection/skills/dev-ai-agent-builder ~/.claude/skills/

Payload du plugin : skills/dev-ai-agent-builder · source éditable : dev-skills/ai-agent-builder

📖 Manuel

AI Agent Builder

Critères de choix du pattern

ComplexitéPattern recommandéFramework
Tâche unique, 1-5 outilsReAct (Reasoning + Acting)LangChain, SDK natif
Tâche longue multi-étapesPlan-and-ExecuteLangGraph
Exploration de solutions alternativesTree of ThoughtsLangGraph + custom
Équipe de spécialistesMulti-agent orchestréCrewAI, AutoGen, LangGraph
Workflow avec état persistant et branchementsStateful graphLangGraph

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 :

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
        )

        # Arrêt naturel
        if response.stop_reason == "end_turn":
            return next(b.text for b in response.content if hasattr(b, "text"))

        # Exécution des outils
        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

BesoinSolution
Contexte de session (< 200k tokens)Passer tout le fil dans messages
Historique long / multi-sessionRésumé LLM + vector store (pgvector, Chroma)
Faits persistants sur l'utilisateur/projetmem0, Zep, ou table SQL simple
Cache de résultats d'outilsRedis 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:
    # Décompose la tâche en sous-tâches
    plan = decompose_task(state["task"])
    return {"plan": plan}

def worker_node(state: AgentState) -> AgentState:
    # Exécute la prochaine sous-tâche
    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 :

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:
    # Human-in-the-loop pour actions irréversibles
    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"}

    # Rate limiting
    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-patternImpactCorrectif
Pas de max_iterationsBoucle infinie, coût incontrôléToujours borner la boucle
Outil qui lève une exception rawL'agent crashe ou hallucinetry/except systématique, retourner {"success": false}
Trop d'outils (> 15)L'agent choisit malLimiter à 7±2 par rôle, regrouper par domaine
System prompt flou sur la condition d'arrêtL'agent ne sait jamais quand s'arrêterDéfinir explicitement final_answer ou un outil de finalisation
Multi-agent sans protocole de messageMessages incompréhensibles entre agentsDéfinir un format JSON structuré pour chaque échange inter-agent
Mémoire illimitée dans les messagesContext window explosée, coût élevéSliding window + résumé automatique
Outil non-idempotent appelé plusieurs foisEffets de bord multiplesDocumenter, détecter les appels répétés

Bonnes pratiques 2026