Tu as lu que les agents allaient tout changer. Tu as peut-être vu passer une infographie « construis ton agent en 10 minutes ». Et tu as un collaborateur qui passe deux heures par jour à qualifier des leads, trier des tickets ou compiler un rapport hebdo. La question n'est pas si tu peux automatiser ça avec un agent — c'est comment le faire sans y laisser un trimestre, une facture surprise et la confiance de l'équipe.
Ce guide est le barreau manquant entre notre article conceptuel sur les agents et la formation avancée sur l'architecture des systèmes agentiques. Il construit un agent, sur une tâche, en une journée de travail réaliste. La moitié du contenu est du code que tu peux exécuter ; l'autre moitié est ce qui fait qu'un agent qui marche sur trois exemples continue de marcher sur le trois-centième.
1. Faut-il un agent ? La question que l'infographie ne pose pas
Le mot « agent » est devenu un fourre-tout. Distinguons trois choses qui n'ont pas le même coût, le même risque, ni la même valeur.
Un prompt transforme une entrée en sortie en un appel. Résumer un document, classer un email, extraire des champs : pas d'outil, pas de boucle.
Un workflow enchaîne plusieurs appels dans un ordre fixé par toi : extraire → vérifier en base → rédiger → envoyer. Le modèle intervient à certaines étapes, mais c'est ton code qui décide de la séquence. Chaque étape est testable isolément, le coût est borné, le comportement est prévisible.
Un agent reçoit un objectif et des outils, et décide lui-même de la séquence : quel outil appeler, avec quels arguments, combien de fois, quand s'arrêter. Il gère les cas où le chemin n'est pas connu à l'avance. En échange, son coût et son comportement sont moins prévisibles.
Trois exemples pour calibrer :
« Résumer les tickets de la semaine dans un rapport. » Lire les tickets, les regrouper, rédiger. La séquence est toujours la même : c'est un workflow. Un agent ici coûterait plus cher pour un résultat moins prévisible.
« Qualifier les leads entrants. » Selon le lead, il faut chercher l'entreprise, vérifier si elle est déjà cliente, regarder le secteur, parfois demander une précision. Le chemin dépend de ce qu'on trouve. Une erreur est rattrapable (le lead est marqué « à revoir », pas supprimé). Les outils existent (CRM, recherche web). C'est un agent.
« Répondre aux clients par email avec engagement contractuel. » Chemin variable, oui — mais une erreur n'est pas rattrapable (un email parti avec une promesse fausse). Pas maintenant : un workflow qui prépare un brouillon qu'un humain valide, et on y reviendra quand l'agent aura prouvé son taux d'erreur.
2. Choisir la tâche avec une grille, pas au feeling
Le premier agent ne doit pas être le plus impressionnant. Il doit être celui qui a le plus de chances de réussir et de rester en production. Quatre critères, notés de 1 à 5, et on multiplie.
Fréquence. Un agent coûte à construire et à maintenir ; il faut qu'il tourne souvent pour rembourser. Quotidien = 5, hebdomadaire = 3, mensuel = 1.
Coût manuel. Le temps humain que chaque exécution remplace. C'est ce qui fait la valeur — et c'est ce que tu mesureras en section 8.
Tolérance à l'erreur. Le critère que l'infographie oublie et qui décide de tout. Une erreur de l'agent est-elle visible, réversible, rattrapable par un humain avant qu'elle ait des conséquences ? Un lead mal qualifié se revoit ; un virement mal validé, non.
Accès aux données. L'agent a besoin d'outils. Si les données sont dans un CRM avec une API, c'est 5. Si elles sont dans des PDF scannés et trois boîtes mail, c'est 1 — et le projet devient un projet d'intégration, pas un projet d'agent.
3. L'architecture d'un agent : une boucle et trois familles d'outils
Voici ce qu'est réellement un agent, débarrassé du vocabulaire. Un modèle reçoit une fiche de poste (prompt système), un objectif (le lead à qualifier), et une liste d'outils qu'il a le droit d'appeler. Il réfléchit, appelle un outil, reçoit le résultat, réfléchit à nouveau, et ainsi de suite jusqu'à ce qu'il décide qu'il a fini. Ton code fait tourner cette boucle et exécute les outils. C'est tout.
Lire : chercher un contact dans le CRM, récupérer l'historique, lire une page web. Aucun effet de bord, l'agent peut appeler ces outils librement.
Agir : mettre à jour un champ, créer une tâche, envoyer un email. Chaque outil d'action porte un niveau d'approbation (section 6). Un premier agent en a peu, et aucun irréversible.
Notifier : poster un message dans un canal Slack, ouvrir un ticket. Risque faible, mais avec un quota — un agent qui poste 400 messages à cause d'une boucle est une nuisance, pas un incident.
4. La boucle en code
Voici l'agent complet, hors outils. Quarante lignes qui font tout ce qui est décrit au-dessus, avec les plafonds intégrés dès la première version.
import json, time
from anthropic import Anthropic
client = Anthropic()
MODEL = "claude-sonnet-4-5"
def run_agent(system: str, tools: list[dict], handlers: dict, goal: str,
max_turns: int = 12, max_cost_eur: float = 0.10, log=print) -> dict:
"""Boucle d'agent minimale. handlers = {nom_outil: fonction(**args) -> str}."""
messages = [{"role": "user", "content": goal}]
cost, turns = 0.0, 0
while True:
turns += 1
if turns > max_turns:
return {"status": "stopped", "reason": f"max_turns ({max_turns})", "messages": messages}
resp = client.messages.create(
model=MODEL, max_tokens=1500,
system=[{"type": "text", "text": system, "cache_control": {"type": "ephemeral"}}],
tools=tools, messages=messages,
)
cost += estimate_cost(resp.usage)
if cost > max_cost_eur:
return {"status": "stopped", "reason": f"max_cost ({max_cost_eur} €)", "messages": messages}
messages.append({"role": "assistant", "content": resp.content})
if resp.stop_reason == "end_turn":
final = next((b.text for b in resp.content if b.type == "text"), "")
return {"status": "done", "answer": final, "turns": turns, "cost_eur": round(cost, 4)}
# Le modèle demande un ou plusieurs outils : on les exécute et on renvoie les résultats
results = []
for block in resp.content:
if block.type != "tool_use":
continue
t0 = time.perf_counter()
try:
output = handlers[block.name](**block.input)
except Exception as e: # l'erreur est renvoyée au modèle, pas levée
output = f"ERREUR: {type(e).__name__}: {e}"
log({"turn": turns, "tool": block.name, "args": block.input,
"ms": round((time.perf_counter() - t0) * 1000), "ok": not output.startswith("ERREUR")})
results.append({"type": "tool_result", "tool_use_id": block.id, "content": str(output)[:4000]})
messages.append({"role": "user", "content": results})Quatre détails qui font la différence entre une démo et un agent de production :
- Les erreurs d'outil sont renvoyées au modèle, pas levées. Un CRM qui répond 404 est une information : l'agent peut essayer une autre recherche ou conclure « entreprise inconnue ». Une exception non capturée tue la boucle.
- Le résultat d'outil est tronqué (4 000 caractères). Un outil qui renvoie 50 Ko de JSON fait exploser le contexte et la facture pour rien.
- Les plafonds sont dans la boucle, pas dans un wrapper qu'on ajoutera « après ». Douze tours et dix centimes suffisent à qualifier n'importe quel lead ; au-delà, quelque chose ne va pas et il vaut mieux s'arrêter.
- Chaque appel d'outil est journalisé avec ses arguments et sa durée. C'est ce que tu liras quand un utilisateur dira « l'agent a fait n'importe quoi sur le lead 4821 ».
Les outils, maintenant. Chacun est une définition JSON (ce que le modèle voit) et une fonction Python (ce que ton code exécute).
TOOLS = [
{
"name": "crm_search_company",
"description": "Cherche une entreprise dans le CRM par nom ou domaine. Renvoie fiche + statut client.",
"input_schema": {"type": "object",
"properties": {"query": {"type": "string"}},
"required": ["query"]},
},
{
"name": "web_lookup",
"description": "Recherche web courte sur une entreprise : secteur, taille, actualité. Max 5 résultats.",
"input_schema": {"type": "object",
"properties": {"query": {"type": "string"}},
"required": ["query"]},
},
{
"name": "crm_update_lead",
"description": "Met à jour le lead : score (1-5), raison, prochaine action. Action, niveau 'revue'.",
"input_schema": {"type": "object",
"properties": {"lead_id": {"type": "string"},
"score": {"type": "integer", "minimum": 1, "maximum": 5},
"reason": {"type": "string", "maxLength": 300},
"next_action": {"type": "string",
"enum": ["call_today", "nurture", "disqualify", "needs_human"]}},
"required": ["lead_id", "score", "reason", "next_action"]},
},
{
"name": "notify_sales",
"description": "Poste un message court dans le canal Slack #leads. Max 1 par lead.",
"input_schema": {"type": "object",
"properties": {"text": {"type": "string", "maxLength": 500}},
"required": ["text"]},
},
]
HANDLERS = {
"crm_search_company": lambda query: json.dumps(crm.search(query)[:3], ensure_ascii=False),
"web_lookup": lambda query: json.dumps(search.top(query, n=5), ensure_ascii=False),
"crm_update_lead": guarded("revue", lambda **a: crm.update_lead(**a)),
"notify_sales": quota(1, lambda text: slack.post("#leads", text)),
}La description d'un outil est un prompt. « Renvoie fiche + statut client » dit au modèle ce qu'il obtiendra ; « Max 1 par lead » lui dit comment se comporter. Un outil mal décrit est un outil mal utilisé. Les enums et les maxLength dans les schémas valent mieux que des consignes dans le prompt : le modèle ne peut pas les violer.
5. La fiche de poste : le prompt système avant le code
L'infographie a raison sur un point : le prompt système est une fiche de poste. Elle a tort de la mettre en étape 5. C'est la première chose à écrire, avec l'utilisateur métier, avant la première ligne de Python — parce que c'est là qu'on découvre les cas limites, les règles implicites et les « ah oui, sauf si ».
Quatre sections, dans cet ordre :
Rôle — qui est l'agent, pour qui il travaille, ce qu'il produit. Une phrase.
Procédure — comment il s'y prend, dans l'ordre normal. C'est la partie que le métier dicte.
Limites — ce qu'il ne fait jamais, et ce qu'il fait quand il ne sait pas. C'est la partie la plus importante et la plus courte.
Format — la structure exacte de sa sortie finale. Idéalement un outil de sortie structurée plutôt que du texte libre.
SYSTEM = """Tu es l'assistant de qualification des leads entrants de l'équipe commerciale de Digimoove.
Pour chaque lead reçu, tu produis un score de 1 à 5, une raison en une phrase, et une prochaine action.
## Procédure
1. Cherche l'entreprise dans le CRM (crm_search_company). Si elle est déjà cliente ou en cours de négociation, score 5, next_action = call_today, et arrête-toi.
2. Sinon, fais UNE recherche web (web_lookup) pour identifier le secteur et la taille approximative.
3. Applique la grille :
- Secteur cible (industrie, santé, collectivités, ETI de services) ET > 50 salariés → 4 ou 5
- Secteur cible mais < 50 salariés → 3, next_action = nurture
- Hors secteur cible, ou étudiant / particulier / concurrent → 1 ou 2, next_action = disqualify
4. Enregistre avec crm_update_lead, puis notifie #leads uniquement si score ≥ 4.
## Limites
- Tu ne contactes jamais le lead. Tu ne modifies rien d'autre que le lead concerné.
- Une seule recherche web par lead. Si elle ne donne rien d'exploitable, score 3 et next_action = needs_human.
- Si le message du lead mentionne un budget, un appel d'offres ou une échéance, next_action = call_today quel que soit le score.
- N'invente jamais une information sur l'entreprise. Si tu ne sais pas, dis-le dans la raison.
## Format
Termine toujours par crm_update_lead. Ta réponse finale est une ligne : "Lead {id} : score {n} — {raison}".
## Exemples
Lead : "Bonjour, je suis DSI d'un groupe hospitalier (1 200 personnes), on cherche un accompagnement AI Act."
→ CRM : inconnu. Web : CHU, secteur santé. Score 5, call_today, raison "Santé, 1 200 pers., demande AI Act explicite".
Lead : "Étudiant en master cyber, je voudrais un stage."
→ Pas de recherche nécessaire. Score 1, disqualify, raison "Candidature stage, pas un prospect".
"""Deux exemples suffisent pour un premier agent. Ils calibrent le ton et montrent le chemin normal ; au-delà, chaque exemple supplémentaire coûte des tokens à chaque tour et rigidifie le comportement. Les cas difficiles vont dans les tests (section 7), pas dans le prompt.
6. Les garde-fous avant l'intelligence
On serait tenté de faire marcher l'agent d'abord et de sécuriser après. C'est l'inverse : les garde-fous sont ce qui permet de tester sur des cas réels sans risque, donc de faire marcher l'agent. Quatre mécanismes, tous dans le code de la section 4.
Plafond de tours et de dépense. Déjà dans la boucle. Douze tours et dix centimes pour un lead. Quand le plafond est atteint, l'agent s'arrête proprement avec status: stopped et le lead passe en needs_human. Ce n'est pas un échec, c'est le système qui fonctionne.
Niveaux d'approbation. Chaque outil d'action est enveloppé. « Auto » exécute. « Revue » exécute et pousse dans une file que le commercial parcourt en fin de journée — ou, pour une action irréversible, met en attente jusqu'à validation. « Jamais » n'est pas un niveau : c'est un outil qu'on ne donne pas.
Quotas. Un outil de notification a un quota par exécution (1 message par lead) et par jour (200). Un agent qui boucle ne peut pas spammer.
Journal. Chaque tour, chaque appel d'outil, ses arguments, sa durée, son succès. Dans une table, pas dans un fichier. C'est l'observabilité minimale, et c'est ce qui rend les tests de la section 7 possibles.
from collections import defaultdict
REVIEW_QUEUE = [] # en prod : une table
_daily_counts = defaultdict(int)
def guarded(level: str, fn):
"""Enveloppe un outil d'action avec son niveau d'approbation."""
def wrapper(**args):
if level == "revue":
result = fn(**args)
REVIEW_QUEUE.append({"tool": fn.__name__, "args": args, "result": result})
return f"{result} (en file de revue)"
if level == "attente": # irréversible : on n'exécute pas, on demande
REVIEW_QUEUE.append({"tool": fn.__name__, "args": args, "pending": True})
return "Action mise en attente de validation humaine. Continue sans."
return fn(**args) # auto
return wrapper
def quota(per_run: int, fn, per_day: int = 200):
calls = {"n": 0}
def wrapper(**args):
if calls["n"] >= per_run:
return "Quota atteint pour cette exécution : notification ignorée."
if _daily_counts[fn.__name__] >= per_day:
return "Quota journalier atteint : notification ignorée."
calls["n"] += 1; _daily_counts[fn.__name__] += 1
return fn(**args)
return wrapperNote que les refus de quota sont renvoyés au modèle comme du texte : il apprend dans le tour suivant que la notification n'est pas partie, et il conclut sans. C'est le même principe que pour les erreurs d'outil.
7. Mémoire : le strict nécessaire pour une v1
L'infographie propose trois niveaux de mémoire. Pour un premier agent, un seul suffit : l'historique de la session, c'est-à-dire la liste messages de la boucle. L'agent se souvient de ce qu'il a fait sur ce lead parce que tous les tours sont dans le contexte. Quand le lead est traité, la session est jetée.
Les deux autres niveaux viennent quand le besoin apparaît, pas avant :
La mémoire de tâche (variables persistantes entre exécutions : « ce lead a déjà été vu il y a 3 jours ») se résout sans agent : c'est une colonne en base que l'outil crm_search_company renvoie. Pas de mémoire magique, une donnée.
La mémoire de connaissances (documents cherchables par le modèle) est un RAG, avec tout ce que ça implique. Notre formation « RAG en production » traite ça en détail. Pour qualifier des leads, on n'en a pas besoin ; pour répondre à des questions sur une base documentaire, c'est un autre projet.
8. Tester sur cinq cas réels
C'est l'étape qui décide de la mise en production, et c'est celle que les démos sautent. Cinq cas — pas cinquante, on est au premier jour — choisis avec le métier, dont au moins un facile, un difficile, un ambigu, un piège, et un cas hors périmètre.
Le harnais de test tient en quelques lignes et reste en place après la mise en prod : chaque modification du prompt ou d'un outil le fait tourner.
CASES = [ # rédigés avec le commercial senior AVANT de lancer l'agent
{"id": "L-001", "goal": "Lead 4821 : 'DSI d'un groupe hospitalier (1 200 pers.), accompagnement AI Act'",
"expect": {"score": 5, "next_action": "call_today"}},
{"id": "L-002", "goal": "Lead 4822 : 'PME industrielle 30 salariés, appel d'offres cyber en cours'",
"expect": {"score": 3, "next_action": "call_today"}},
{"id": "L-003", "goal": "Lead 4823 : 'Consultant indépendant, projet IA pour un client industriel'",
"expect": {"score": 3, "next_action": "needs_human"}},
{"id": "L-004", "goal": "Lead 4824 : 'Responsable offre chez <concurrent>, curieux de vos tarifs'",
"expect": {"score": 1, "next_action": "disqualify"}},
{"id": "L-005", "goal": "Lead 4825 : 'Candidature spontanée, poste de consultant'",
"expect": {"score": 1, "next_action": "disqualify"}},
]
def run_tests(threshold: int = 4) -> bool:
passed, log = 0, []
for case in CASES:
crm.reset_fake(case["id"]) # outils en mode bac à sable
out = run_agent(SYSTEM, TOOLS, HANDLERS, case["goal"], log=log.append)
got = crm.last_update(case["id"]) # ce que l'agent a réellement écrit
ok = got and all(got.get(k) == v for k, v in case["expect"].items())
passed += bool(ok)
print(f"{'✓' if ok else '✗'} {case['id']} attendu {case['expect']} obtenu {got} "
f"· {out.get('turns', '-')} tours · {out.get('cost_eur', '-')} €")
print(f"\n{passed}/{len(CASES)} — seuil {threshold} → {'PROD' if passed >= threshold else 'PAS ENCORE'}")
return passed >= thresholdTrois métriques et pas plus :
Exactitude — le résultat écrit par l'agent correspond-il à ce que le métier aurait écrit ? On compare l'action, pas le raisonnement.
Tours — combien d'appels pour y arriver ? Un agent qui met 11 tours pour un cas facile a un problème de prompt ou d'outil, même s'il finit par avoir raison.
Temps gagné — la seule métrique que la direction comprend. Elle se mesure avec un chronomètre, sur le temps de relecture humaine après l'agent, comparé au temps de traitement avant.
9. Exposer : Slack d'abord, la web app jamais le premier jour
Un agent que personne n'utilise n'existe pas. Le premier jour, il faut le mettre là où le métier travaille déjà — et c'est presque toujours Slack ou Teams. Une commande, une réponse dans le fil, la file de revue dans un canal dédié.
from fastapi import FastAPI, BackgroundTasks, Form
app = FastAPI()
@app.post("/slack/qualify")
async def slack_qualify(background: BackgroundTasks, text: str = Form(...),
response_url: str = Form(...), user_name: str = Form(...)):
lead_id = text.strip()
background.add_task(qualify_and_reply, lead_id, response_url, user_name)
return {"response_type": "ephemeral", "text": f"Qualification du lead {lead_id} en cours…"}
def qualify_and_reply(lead_id: str, response_url: str, user_name: str):
out = run_agent(SYSTEM, TOOLS, HANDLERS, goal=f"Qualifie le lead {lead_id}.",
log=lambda r: db.insert("agent_log", {"lead_id": lead_id, "user": user_name, **r}))
if out["status"] == "done":
text = f"{out['answer']} _( {out['turns']} tours · {out['cost_eur']} € )_"
else:
text = f"⚠️ Arrêt : {out['reason']}. Lead {lead_id} passé en *needs_human*."
crm.update_lead(lead_id=lead_id, next_action="needs_human")
slack.respond(response_url, text)Le déclenchement automatique (« à chaque nouveau lead dans le CRM ») est la même fonction appelée par un webhook du CRM au lieu d'une commande. On commence par la commande manuelle : le commercial garde la main, voit l'agent travailler, et c'est lui qui demandera le mode automatique quand il aura confiance.
#leads-revue où chaque action de niveau « Revue » apparaît avec deux boutons — valider, corriger. Le commercial y passe cinq minutes en fin de journée. Chaque « corriger » est un futur cas de test. Tu n'as pas besoin d'un tableau de bord avant d'avoir cent leads traités.10. La journée, heure par heure
Si la journée déborde, c'est presque toujours sur un point : les outils. Une API CRM sans documentation, une authentification à négocier, un champ qui n'existe pas. C'est pour ça que « accès aux données » est dans la grille de sélection — et pour ça qu'on vérifie la veille qu'on peut appeler l'API du CRM depuis un script de dix lignes.
11. Le fil rouge, chiffré
Récapitulons ce que donne l'agent de qualification de leads après sa première semaine, sur la base des chiffres du test et de cinq jours en mode manuel.
Avant. 60 leads par jour, 8 minutes chacun pour le commercial senior : 8 heures par jour de qualification, soit un temps plein. La moitié des leads était qualifiée avec plus de 24 h de retard, et les leads chauds attendaient dans la file avec les autres.
Après. L'agent traite chaque lead en 4 tours et 40 secondes pour 0,03 € (1,80 € par jour). Le commercial relit la file de revue en 45 secondes par lead, soit 45 minutes par jour. Il a récupéré sept heures. Les leads à call_today sont notifiés dans la minute. Sur 300 leads en une semaine, 11 corrections en file de revue, dont 6 relevant de la même règle manquante (ajoutée le mardi) — le taux d'accord avec le senior est passé de 80 % au test à 96 % en fin de semaine.
Ce qui n'est pas dans ce calcul. Le développeur a passé une journée, plus deux heures dans la semaine pour les corrections. L'agent n'a pas d'outil d'envoi vers l'extérieur et n'en aura pas avant que la file de revue soit vide trois semaines de suite. Et le prochain agent (tri des tickets, score 300 dans la grille) réutilise la boucle, les enveloppes de garde-fous et le harnais de test : il coûtera une demi-journée.
12. Teste ta compréhension
« Chaque lundi, compiler les tickets de la semaine en un rapport pour la direction. » Prompt, workflow ou agent ?
📚Lexique technique (déroulez)
Agent — Modèle dans une boucle : il choisit des outils, reçoit leurs résultats, recommence jusqu'à décider qu'il a fini. La séquence n'est pas fixée à l'avance.
Workflow — Enchaînement d'appels LLM et de code dans un ordre fixé par le développeur. Prévisible, borné, testable par étape.
Tool use (appel d'outil) — Mécanisme par lequel le modèle demande l'exécution d'une fonction avec des arguments structurés. Le code exécute et renvoie le résultat.
Boucle agentique — Le while qui appelle le modèle, exécute les outils demandés, renvoie les résultats, jusqu'à end_turn ou plafond.
stop_reason — Champ de la réponse indiquant pourquoi le modèle s'est arrêté : end_turn (fini), tool_use (demande d'outil), max_tokens (coupé).
Fiche de poste (prompt système) — Rôle, procédure, limites et format de l'agent. Écrite avec le métier, avant le code.
Outil de lecture / d'action / de notification — Les trois familles d'outils, par niveau de risque : sans effet de bord, avec effet de bord, avec effet de bord faible.
Niveau d'approbation — Auto (exécuté), Revue (exécuté et signalé, ou mis en attente si irréversible), Jamais (l'outil n'est pas fourni).
Plafond de tours / de dépense — Limites intégrées à la boucle qui arrêtent l'agent proprement. Un arrêt sur plafond n'est pas un échec.
Quota — Limite d'appels d'un outil par exécution et par jour. Empêche un agent qui boucle de spammer.
File de revue — Liste des actions de niveau Revue, validées ou corrigées par un humain. Chaque correction devient un cas de test.
Journal (log) — Enregistrement de chaque tour et de chaque appel d'outil, avec arguments et durée. L'observabilité minimale.
Bac à sable (sandbox) — Mode des outils pendant les tests : lectures réelles, écritures simulées.
Harnais de test — Script qui rejoue les cas de référence et compare le résultat de l'agent à l'attendu du métier.
Seuil de mise en prod — Nombre de cas à réussir, fixé avant le test.
Mémoire de session — L'historique messages de la boucle en cours. Suffisant pour un premier agent.
Grille de sélection — Fréquence × coût manuel × tolérance à l'erreur × accès aux données. Un critère à 1 disqualifie.
Description d'outil — Texte que le modèle voit pour décider quand et comment appeler un outil. C'est un prompt.
Enum / maxLength — Contraintes de schéma qui limitent ce que le modèle peut passer en argument. Plus fiables qu'une consigne.
Questions fréquentes
Faut-il un framework d'agents ? Pas pour le premier. La boucle fait 40 lignes et tu dois la comprendre. Les frameworks apportent de la valeur sur le multi-agents, la persistance, l'observabilité intégrée — quand tu as trois agents en prod, pas avant.
Quel modèle ? Un modèle de classe Sonnet pour la boucle (raisonnement sur plusieurs tours, usage fiable des outils). Un modèle de classe Haiku si la tâche est simple et les outils peu nombreux — teste sur les cinq cas. Notre formation sur les coûts LLM détaille le routing.
Combien ça coûte en prod ? Pour le fil rouge, 0,03 € par lead, 1,80 € par jour. Le plafond de dépense par exécution empêche toute dérive. L'observabilité par agent est le sujet de la section 4.1 de la formation coûts.
Et si l'API du CRM n'existe pas ? Alors ce n'est pas un projet d'agent, c'est un projet d'intégration. Fais-le d'abord, ou choisis une autre tâche avec la grille.
Quand passer à un deuxième agent ? Quand le premier tourne en automatique depuis deux semaines avec une file de revue quasi vide. Le deuxième réutilise la boucle, les enveloppes et le harnais : une demi-journée.
Pour aller plus loin
Le « pourquoi » des agents est dans « Agents IA : la prochaine révolution ». Quand le premier agent tourne et que tu veux en coordonner plusieurs, gérer une mémoire persistante ou un orchestrateur, c'est la formation sur l'architecture des systèmes agentiques. Pour la chaîne d'attaque complète et les contrôles par étape dès que l'agent touche des systèmes réels, la fiche sur la sécurité des agents. Et pour le coût par agent et le routing entre modèles, la formation sur l'optimisation des coûts LLM.
Ce guide est, à peu de chose près, le déroulé d'un Sprint d'Automatisation : une tâche choisie avec la grille, une fiche de poste écrite avec ton métier, un agent avec ses garde-fous et son harnais de test, exposé là où ton équipe travaille — livré en production, pas en démo.