- 01Un agent = un LLM dans une boucle observer → décider → agir, jusqu'à résolution.
- 02Trois piliers : un jeu d'outils, une mémoire de travail, et une condition d'arrêt.
- 03Sans garde-fous (limite d'itérations, budget, validation), un agent part en vrille — ils ne sont pas optionnels.
À la fin de ce tuto, tu auras un agent autonome qui tourne : un script Python qui reçoit un objectif, choisit seul quels outils appeler, observe les résultats et recommence jusqu'à avoir terminé — avec les garde-fous qui l'empêchent de partir en vrille. Tu comprendras l'architecture au point de pouvoir y brancher tes propres outils.
Durée : 40 min. Prérequis : avoir fait le tuto function calling (un agent, c'est le function calling mis en boucle), Python, une clé API.
Ce qu'est vraiment un agent
Un agent IA n'est pas un modèle plus intelligent : c'est un LLM placé dans une boucle, équipé d'outils et d'une mémoire, qui itère jusqu'à atteindre un objectif. La différence avec un simple appel d'outil : l'agent décide lui-même de la prochaine action en fonction de ce qu'il vient d'observer.
La boucle agentique
Au cœur de tout agent, le même cycle se répète :
objectif
└─> [le LLM décide] ──> appelle un outil ──> observe le résultat
^ │
└──────────────────────────────────────────┘
jusqu'à : objectif atteint
- On donne un objectif à l'agent.
- Le LLM décide de la prochaine action (appeler un outil, ou conclure).
- Le système exécute l'outil et renvoie le résultat (l'observation).
- Le LLM intègre cette observation et recommence — jusqu'à juger la tâche finie.
Les trois piliers
- Les outils : ce que l'agent peut faire (chercher sur le web, lire un fichier, requêter une base, appeler une API). La qualité d'un agent dépend directement de la clarté de ses outils.
- La mémoire de travail : l'historique des actions et observations, réinjecté à chaque tour pour que l'agent sache où il en est. Dans le code ci-dessous, c'est simplement la liste
messages. - La condition d'arrêt : comment l'agent sait qu'il a terminé. Sans elle, il boucle indéfiniment.
L'agent minimal, en Python
On construit un agent qui répond à des questions en combinant deux outils : une recherche web (simulée ici) et une calculatrice. La boucle gère plusieurs appels d'affilée.
pip install openai
1. Les outils (du Python normal)
import json
from openai import OpenAI
client = OpenAI()
def web_search(query: str) -> str:
# En vrai : un appel à une API de recherche. Ici, simulé.
fake = {"population france": "68 millions (2025)"}
return fake.get(query.lower(), "aucun résultat")
def calculate(expression: str) -> str:
# ⚠️ eval est dangereux — voir le tuto sécurité. Ici borné à l'arithmétique.
allowed = set("0123456789+-*/(). ")
if not set(expression) <= allowed:
return "expression non autorisée"
try:
return str(eval(expression))
except Exception as e:
return f"erreur: {e}"
dispatch = {"web_search": web_search, "calculate": calculate}
2. La description des outils (ce que voit l'agent)
tools = [
{
"type": "function",
"function": {
"name": "web_search",
"description": "Cherche une information factuelle sur le web.",
"parameters": {
"type": "object",
"properties": {"query": {"type": "string"}},
"required": ["query"],
},
},
},
{
"type": "function",
"function": {
"name": "calculate",
"description": "Évalue une expression arithmétique simple.",
"parameters": {
"type": "object",
"properties": {"expression": {"type": "string"}},
"required": ["expression"],
},
},
},
]
3. La boucle agentique, avec garde-fous
MAX_ITERS = 8 # garde-fou : jamais de boucle infinie
def agent(objectif: str) -> str:
messages = [
{"role": "system", "content":
"Tu es un agent. Utilise les outils pas à pas pour atteindre "
"l'objectif, puis donne la réponse finale."},
{"role": "user", "content": objectif},
]
for i in range(MAX_ITERS):
resp = client.chat.completions.create(
model="gpt-4o-mini", messages=messages, tools=tools,
)
msg = resp.choices[0].message
# Condition d'arrêt : plus d'outil demandé → réponse finale
if not msg.tool_calls:
return msg.content
messages.append(msg) # mémoire de travail : on garde la décision
for tc in msg.tool_calls:
args = json.loads(tc.function.arguments)
observation = dispatch[tc.function.name](**args)
print(f" [tour {i+1}] {tc.function.name}({args}) -> {observation}")
messages.append({
"role": "tool",
"tool_call_id": tc.id,
"content": str(observation),
})
return "Limite d'itérations atteinte sans conclusion."
print(agent("Quelle est la population de la France divisée par 2 ?"))
Lance-le : l'agent cherche d'abord la population (web_search), puis calcule la division (calculate), puis conclut — deux outils enchaînés sans que tu lui dises l'ordre. C'est ça, l'autonomie.
Les garde-fous : partie non négociable
Un agent laissé libre peut boucler à l'infini, brûler ton budget ou enchaîner des actions destructrices. Pose-les systématiquement :
- Limite d'itérations (
MAX_ITERSci-dessus) — contre les boucles infinies. - Budget de tokens/coût par exécution, avec arrêt si dépassé. Additionne
resp.usageà chaque tour et coupe au-delà d'un seuil. - Validation humaine sur les actions sensibles ou irréversibles (voir ci-dessous).
- Périmètre d'outils restreint : ne donne accès qu'au strict nécessaire.
- Journal de chaque décision (le
printici) pour pouvoir auditer après coup.
Exemple de barrière sur une action irréversible :
def delete_file(path: str, confirm: bool = False) -> str:
if not confirm:
return "CONFIRMATION REQUISE : rappelle delete_file avec confirm=true"
# suppression réelle seulement après confirmation hors du contrôle du modèle
Le piège du « plus d'outils = mieux »
Donner 30 outils à un agent dégrade ses performances : il se perd dans le choix. Mieux vaut 5 outils bien décrits que 30 vagues. Si le périmètre est large, spécialise plutôt plusieurs agents (sujet du tuto multi-agents) que de surcharger un seul.
Concevoir la boucle, pas seulement le prompt
L'erreur classique est de tout miser sur un prompt parfait. Un bon agent se joue surtout dans l'ingénierie de la boucle : comment tu gères la mémoire (faut-il l'élaguer quand elle gonfle ?), comment tu formates les observations, quand tu coupes. Le prompt compte, mais l'architecture autour compte davantage.
L'adapter à tes besoins
- Remplace les outils par les tiens (
read_file,query_db,send_email…) — du Python normal dansdispatch+ leur description danstools. - Ajoute le suivi du budget : accumule
resp.usage.total_tokenset stoppe au plafond. - Gère la mémoire longue : sur des tâches longues, résume ou élague les vieux tours pour ne pas exploser le contexte (et la facture).
À retenir
Un agent, c'est un LLM dans une boucle observer → décider → agir, porté par trois piliers : des outils, une mémoire de travail, une condition d'arrêt. Les garde-fous (limite d'itérations, budget, validation humaine, périmètre restreint, journal) ne sont pas optionnels — ce sont eux qui séparent un agent utile d'un agent qui part en vrille. Et soigne la boucle autant que le prompt.
Articles liés
Architecturer un système multi-agents : orchestrateur et sous-agents
Quand un agent ne suffit plus : patterns d'orchestration (orchestrateur/sous-agents, pipeline, débat, parallèle), communication par messages structurés, et les deux risques majeurs. Avec un orchestrateur minimal en Python.
Le function calling : laisser une IA déclencher des actions
Construis pas à pas un assistant qui appelle vraiment tes fonctions : on part d'un appel vide, on ajoute un outil, on exécute le code, et on boucle. Script complet et réutilisable à la fin.

En Inde, la demande en mémoire pour l’IA fait grimper les prix des smartphones
L'essor de l'IA dans les smartphones en Inde aggrave les tensions sur les coûts et l'approvisionnement en mémoire.