CodeGym /Cours /ChatGPT Apps /Découverte des agents : rôles, cycle d’exécution (run), d...

Découverte des agents : rôles, cycle d’exécution (run), déterminisme, idempotence

ChatGPT Apps
Niveau 12 , Leçon 0
Disponible

1. Qu’est-ce qu’un agent, et pourquoi en avez-vous besoin

Les agents ne sont pas une partie obligatoire de ChatGPT App : on peut créer autant d’applications géniales que l’on veut sans utiliser d’agents LLM. Cependant, j’ai trois bonnes raisons de vous en parler.

Les agents sont un excellent moyen d’ajouter de l’intelligence au backend de votre application. Sélection intelligente de cadeaux, analyse des souhaits textuels de l’utilisateur. Des scénarios complexes de recherche, d’analyse, de traitement et de synthèse — tout cela devient très facile avec des agents LLM.

ChatGPT a publié son AgentsSDK en TS et Python. Il est très bien conçu. L’orchestration des agents est fournie clé en main. Sur une tâche complexe, il n’y travaillera pas un seul agent, mais toute une équipe. C’est une direction très prometteuse.

Il y a aussi un objectif pédagogique. ChatGPT appelle les mcp-tools exactement comme les agents LLM appellent leurs tools. Dès que vous comprenez comment fonctionnent les agents LLM, vous voyez comment, par exemple, réaliser une machine à états côté modèle dans une application. De même, étudier AgentsSDK donne une idée de la manière dont fonctionnera à l’avenir le ChatGPT SDK.

Alors, commençons.

Qu’est-ce qu’un agent LLM

Si ChatGPT App est le « front » élégant et pratique de votre service à l’intérieur de ChatGPT, et si le serveur MCP est le « moteur » avec des outils et de la logique métier, alors l’agent est une sorte de répartiteur intelligent capable de :

  • lire l’objectif ;
  • décider lui-même quels outils appeler et dans quel ordre ;
  • demander des informations complémentaires si nécessaire ;
  • répéter des étapes en cas d’erreurs ;
  • aboutir à un résultat final clair.

Dans une formulation proche de la documentation officielle d’Agents SDK, un agent est un programme. Ayant accès à une LLM et à un ensemble d’outils, il est capable de planifier ses étapes de manière autonome pour atteindre un objectif et de les exécuter via des tool‑calls.

Si l’on fait un parallèle avec ce que vous avez déjà :

  • Dans une ChatGPT App classique, le modèle ChatGPT orchestre directement les appels à vos instruments MCP.
  • Un agent LLM côté backend a aussi une description de tâche, un ensemble d’outils et décide lui-même quels tools appeler, combien d’étapes effectuer, quand s’arrêter et quel résultat renvoyer.

Dans le contexte de notre GiftGenius, cela peut ressembler à ceci :

  • Application sans agent : le modèle appelle directement searchGifts, puis filterByBudget, puis getDetails — en « repensant » chaque fois.
  • Application avec agent : ChatGPT appelle un mcp‑tool, et le backend confie à l’agent la tâche : « Trouve le top 5 des cadeaux pour tel profil ». L’agent effectue plusieurs étapes : collecte des informations supplémentaires, appelle différents outils de recherche, filtre, trie, construit les fiches finales et renvoie une réponse structurée prête à l’emploi.

ChatGPT et un agent LLM côté backend — c’est comme un directeur d’entreprise et un employé. ChatGPT a beaucoup plus de liberté : il communique avec l’utilisateur et décide quelles tâches stratégiques lancer (appeler des mcp tools). L’agent LLM, lui, travaille uniquement sur le backend, n’interagit pas avec l’utilisateur, mais « réfléchit » aussi et peut appeler ses tool. En quelque sorte un ChatGPT en version minimale.

2. De quoi se compose un agent : LLM, instructions, outils et état

Il est pratique de penser à un agent comme à plusieurs couches.

Premièrement, sous le capot, on retrouve toujours une LLM. Cela peut être GPT‑5.1 ou un autre modèle utilisé par Agents SDK. Elle génère du texte, planifie des étapes, choisit des outils — en bref, elle « pense », mais déjà dans votre contexte d’orchestration.

Deuxièmement, au-dessus du modèle, il y a les instructions. C’est le prompt système de l’agent, qui définit son rôle, ses limites, son style, et comment utiliser les outils. Vous avez déjà fait quelque chose de similaire pour ChatGPT App, mais maintenant c’est appliqué à un agent distinct.

Troisièmement, il y a un ensemble d’outils de l’agent. Cela peut être :

  • des fonctions TypeScript (function calling classique) ;
  • des outils HTTP/REST ;
  • des wrappers autour de vos MCP‑tools, pour que l’agent puisse accéder au même backend que ChatGPT App ;
  • des outils « hosted » intégrés d’OpenAI (par exemple, la recherche web si vous les activez).

Et enfin, il y a les règles de gestion de l’état et des étapes : comment l’état de session est stocké (session state), comment les résultats intermédiaires sont conservés, comment limiter les boucles. Nous irons plus loin dans le prochain cours sur la mémoire et l’état, mais il est déjà utile de garder à l’esprit qu’un agent n’est pas une « requête jetable », mais potentiellement un processus long avec sauvegarde de la progression.

Si vous regardez cela avec des yeux de développeur TypeScript, vous obtenez mentalement un objet de ce type (pseudo‑code proche d’Agents SDK TS) :

const giftAgent = new Agent({
  model: "gpt-5.1",
  systemPrompt: giftAgentPrompt,
  tools: { searchGifts, filterGifts, checkoutDraft },
  // ici aussi — paramètres de mémoire, limites de pas, etc.
});

Ne nous attardons pas sur les API exactes, l’important est l’image : modèle, instructions, outils et réglages de comportement au même endroit.

3. Rôles des messages : system / user / assistant / tool dans le monde de l’agent

Vous connaissez déjà les rôles classiques system, user, assistant et tool des Chat Completions. Dans Agents SDK, ils restent, mais prennent un sens un peu plus appliqué.

Le rôle system définit la personnalité et la mission de l’agent. Par exemple, pour l’agent GiftGenius : « Tu es un agent de sélection de cadeaux. Ta mission est de proposer, avec un minimum d’étapes, 3 à 7 options pertinentes sur la base du profil du destinataire et du budget, puis de préparer un JSON structuré pour le widget ». C’est aussi ici que vous spécifiez les limites : ce qu’il ne doit pas faire (par exemple, ne pas effectuer d’achats réels sans étape dédiée) et comment il doit travailler avec les outils.

Le rôle user dans le contexte d’un agent n’est pas forcément « une personne ». Le plus souvent, c’est une « mission » pour l’agent : un objectif formulé par votre App, un service ou un autre agent. Par exemple, ChatGPT App peut appeler l’agent avec un message user : « Propose 5 idées de cadeaux pour un collègue développeur, budget 50 $, occasion — anniversaire ».

Le rôle assistant — c’est ce que « dit » le modèle à l’intérieur de l’agent. Cela peut être à la fois des réflexions et plans intermédiaires, et la réponse finale. Votre tâche est de configurer le prompt système de sorte que ces messages soient utiles et, si nécessaire, journalisés.

Le rôle tool (ou ses analogues dans un SDK spécifique) décrit les résultats des appels d’outils : « via MCP, 50 produits ont été trouvés », « l’API a renvoyé un timeout », « la base de données a renvoyé le profil utilisateur ». Ces messages, avec ceux de l’assistant, constituent l’historique du cycle d’exécution (run) de l’agent.

On peut résumer cela dans un petit tableau :

Rôle Qui parle Exemple dans le contexte de GiftGenius
system
Vous (en tant que développeur de l’agent) « Tu es un agent de sélection de cadeaux… »
user
Appel externe (App, autre agent) « Propose 5 cadeaux jusqu’à 50 $… »
assistant
Le modèle à l’intérieur de l’agent « Plan : 1) demander des précisions… »
tool
Résultat de l’outil appelé « searchGifts a renvoyé 20 options… »

Cette structure est importante, car c’est sur elle que repose le cycle d’exécution (run) — le héros du jour.

4. Comment une LLM appelle des fonctions sur votre backend

Quand on est habitué au mode « question–réponse », on a l’impression que la LLM fonctionne selon un schéma simple : un texte arrive → le modèle répond par un texte. En réalité, sous le capot, c’est un peu plus subtil, et c’est précisément pour cela que le function calling fonctionne.

Le modèle ne reçoit pas une seule question, il reçoit une liste de messages — l’historique du dialogue. On y trouve toutes les répliques précédentes : instructions système (« qui tu es et ce qui est autorisé/interdit »), vos messages, les réponses antérieures du modèle, les résultats des outils. À chaque étape, le modèle regarde tout ce flux, comme un journal de chat, et décide : « Quel est le prochain message à ajouter à la fin ? ».

C’est l’idée clé : une LLM fait toujours une seule étape — elle ajoute le message suivant à la fin de l’historique. Elle ne « change pas le passé » et n’édite pas d’anciens messages, elle se contente de poursuivre la liste. Vous écrivez une question, le modèle répond. Vous ajoutez une deuxième question, le modèle répond de nouveau, mais en tenant compte de tout l’historique du dialogue (de tous les messages).

Le function calling est construit sur le même principe. Au lieu de « lancer une fonction » directement, le modèle fait ceci :

  • voit la liste des outils/tools disponibles et leurs descriptions, avec l’historique du dialogue ;
  • décide : « Il est plus logique maintenant de ne pas répondre en texte, mais d’appeler d’abord tel outil » ;
  • et, comme prochain message, ajoute à l’historique non pas une réponse textuelle, mais un message spécial du format « je veux appeler tel tool avec tels arguments ».

Ensuite, ce n’est plus le modèle, mais votre backend qui lit ce nouveau message à la fin de l’historique, comprend qu’il s’agit d’une demande d’appel de fonction, et appelle l’outil nécessaire. Puis il ajoute à l’historique un autre message — avec le résultat du tool, et renvoie à nouveau la liste complète des messages au modèle. Le modèle regarde à nouveau tout le flux et ajoute l’étape suivante : soit un autre appel, soit déjà une réponse finale lisible par un humain.

Autrement dit :

  • pour une session Q&A classique : « prochain message » = réponse textuelle ;
  • pour le function calling : « prochain message » = instruction d’appeler une fonction ou réponse après utilisation d’une fonction.

Il n’y a aucune « commande magique d’appel de fonction » distincte — c’est simplement un type particulier de prochain message que le modèle ajoute à la fin de la chaîne.

Le modèle n’appelle pas les fonctions de votre backend via un API public. Il « écrit dans le chat » qu’il veut appeler une fonction avec des paramètres. Et c’est votre backend qui appelle la fonction locale, puis ajoute sa réponse dans le chat. Et tout recommence.

5. Cycle d’exécution (run) de l’agent : comment il « réfléchit » étape par étape

En fait, un agent LLM est un objet/algorithme sur votre serveur qui déclenche le cycle d’exécution de l’agent — c’est un cycle étendu « question → réfléchir → éventuellement agir → réfléchir de nouveau → … → réponse finale ». Dans la documentation d’OpenAI, cela s’appelle parfois agent loop ou le pattern ReAct (Reason + Act + Observe).

À un niveau conceptuel, un run d’agent ressemble à ceci :

  1. L’agent reçoit une entrée : instructions système, mission (message user), éventuellement — état courant.
  2. Le modèle génère une étape : soit une réponse textuelle, soit des plans et la décision d’appeler un ou plusieurs outils.
  3. Si le modèle a choisi un tool‑call, l’agent appelle l’outil correspondant dans le code (cela peut être une fonction locale, un MCP‑tool, une requête HTTP, un accès BD, etc.).
  4. Les résultats des outils sont ajoutés à l’historique sous forme de messages tool.
  5. Le cycle revient au modèle avec le nouveau contexte. Le modèle décide de la suite : continuer la planification, appeler un autre outil ou terminer la mission avec une réponse finale.
  6. Quand le modèle termine explicitement ou selon des conditions d’arrêt, l’agent renvoie le résultat final à l’appelant.

On peut le schématiser ainsi :

flowchart TD
    A[Début du run : objectif + system] --> B[Appel du modèle]
    B --> C{Le modèle veut‑il
répondre par du texte
ou appeler un tool ?} C --> D["Réponse textuelle
(assistant)"] D --> E{La tâche est‑elle terminée ?} E -->|Oui| F[Résultat final] E -->|Non| B C --> G["Appel de tool
(description de l’appel)"] G --> H[Appel de fonction / MCP / HTTP] H --> I["Résultat du tool
(message tool)"] I --> B

Si l’on traduit cela en pseudo‑code TypeScript simplifié (loin d’une API réelle, mais logiquement correct), on obtient quelque chose comme :

async function runAgent(goal: string) {
  let context = buildInitialContext(goal);

  while (!isFinished(context)) {
    const decision = await callLLM(context); // étape de l’agent

    if (decision.type === "tool_call") {		// appeler une fonction ?
      const toolResult = await callTool(decision.tool, decision.args);	// nous appelons la fonction locale
      context = appendToolResult(context, toolResult);		// nous ajoutons le résultat à la fin de la liste
    } else {
      context = appendAssistantMessage(context, decision.message); 
    }

    enforceLimits(context); // limites de pas/temps/boucles
  }

  return extractFinalResult(context);
}

Agents SDK prend en charge la majeure partie de cette routine : stockage de l’historique, marshalling des tool‑calls, logique de répétitions, etc. Il vous reste à configurer et à implémenter les outils eux‑mêmes.

Run vs step

Il est important de distinguer deux notions :

  • run — un lancement de l’agent pour un objectif : « proposer des cadeaux pour ce cas » ;
  • step — une étape du cycle : un appel du modèle qui peut conduire à une réponse textuelle ou à un tool‑call.

Dans la supervision, vous verrez précisément de multiples étapes au sein d’un run, et les limites de sécurité et de coût sont souvent définies soit « par run », soit « par étape ».

Maintenant que le fonctionnement interne d’un run et du cycle est clair, voyons où tout cela a du sens, et où de simples tools suffisent.

5. Où un agent est utile dans GiftGenius, et où il est superflu

Avant de se précipiter à écrire un agent pour tout, il est utile de se poser la question honnête : « Est‑il vraiment nécessaire ici ? ».

Un bon scénario pour un agent — une tâche multi‑étapes avec embranchements, répétitions et logique qu’il est peu pratique de maintenir uniquement dans des prompts.

Dans GiftGenius, une telle tâche peut être un « assistant de sélection intelligente de cadeaux » qui :

  • sait demander des détails importants (sexe du destinataire, hobbies, niveau de proximité) ;
  • peut consulter plusieurs sources de produits (différents vendeurs via des MCP‑tools) ;
  • filtre et classe les résultats ;
  • en cas d’erreurs des sources, retente ou suit une voie de secours ;
  • renvoie non pas une simple liste de textes, mais une liste structurée de candidats avec explications et liens vers des SKU du product feed.

Ici, l’agent sera réellement utile comme « orchestrateur », surtout si vous souhaitez ensuite compléter cela par un scénario voice/Realtime ou une partie commerce complexe (ACP).

En revanche, pour un simple appel à getGiftDetails(giftId), un agent n’est pas nécessaire : un MCP‑tool classique, appelé directement depuis ChatGPT, couvre entièrement le cas. Idem pour les scénarios « mono‑étape » comme « décris ce cadeau à partir du texte de la fiche produit ».

La règle de bon sens : si le scénario peut être décrit comme « un seul tool correct », il n’y a probablement pas besoin d’agent. Si vous commencez à détailler un workflow multi‑étapes avec vérifications et tentatives répétées, il y a de grandes chances que l’agent vous enchante.

6. Déterminisme : comment rendre le comportement de l’agent prévisible

Le déterminisme dans le monde des agents LLM est subtil. Théoriquement, pour la même entrée et les mêmes réglages, vous voulez obtenir le même plan d’action et la même séquence de tool‑calls. En pratique, le modèle reste stochastique, mais vous avez plusieurs leviers pour piloter la prédictibilité.

D’abord, les classiques : la température et autres paramètres de génération. Plus la température est basse, moins il y a de créativité et plus le modèle est « obéissant ». Pour un agent de sélection de cadeaux, vous voudrez sans doute un niveau de liberté non nul, mais pas trop élevé, sinon le modèle inventera chaque matin une nouvelle façon d’appeler le même outil.

Ensuite, des instructions système claires. Si vous décrivez de manière floue un comportement du type « tu peux appeler différents outils et faire ce que tu veux », ne vous étonnez pas que l’agent saute parfois d’une API à l’autre ou tente de répondre « au hasard ». Il est bien mieux de préciser explicitement quand appeler un outil, quels paramètres sont autorisés, comment interpréter les erreurs et dans quels cas terminer la tâche.

Par exemple, le prompt système de l’agent GiftGenius peut inclure :

Si tu n’as pas un profil complet du destinataire (âge, sexe, occasion, budget approximatif),
pose d’abord des questions de clarification via le canal orienté utilisateur et attends les réponses.
Ce n’est qu’ensuite que tu appelleras l’outil search_gifts avec un profil rempli.
N’invente pas de produits, appuie-toi toujours sur les résultats des outils.

De telles consignes réduisent la variabilité des décisions et rendent le comportement plus déterministe.

Troisièmement, la conception des outils eux‑mêmes. Si vous avez trois outils qui recherchent « à peu près la même chose », le modèle choisira inévitablement tantôt l’un, tantôt l’autre. Il vaut mieux concevoir des outils avec des responsabilités claires, non superposées, et le préciser dans leurs descriptions.

Enfin, vous pouvez utiliser des guardrails — des règles et schémas qui vérifient les actions de l’agent et les résultats du modèle. Dans Agents SDK, il existe un support intégré pour des vérifications et des contraintes, y compris sur la structure de la sortie. Si le modèle essaie de générer quelque chose qui ne respecte pas le schéma, vous pouvez le corriger en douceur ou même répéter l’étape.

Mini‑exemple : figer le format du résultat

Supposons que vous ayez besoin que l’agent renvoie toujours un JSON avec le champ gifts, contenant des objets avec id, title et score. Vous pouvez :

  • décrire ce schéma au niveau de l’agent ;
  • indiquer que la sortie finale doit s’y conformer ;
  • en cas de violation — répéter l’étape ou renvoyer une erreur sûre.

Pseudo‑code :

const giftResultSchema = z.object({
  gifts: z.array(z.object({
    id: z.string(),
    title: z.string(),
    score: z.number().min(0).max(1),
  }))
});

// Dans la configuration de l’agent
const agent = new Agent({
  /* ... */
  outputSchema: giftResultSchema,
});

Quand le modèle tentera de renvoyer quelque chose d’étrange, le runner signalera une erreur de validation ; vous pourrez alors soit relancer le modèle, soit journaliser l’incident.

7. Idempotence : pourquoi votre agent peut appeler votre API deux fois

Si le déterminisme concerne « le même plan pour les mêmes entrées », l’idempotence concerne la sécurité des répétitions. Dans le contexte des agents, elle est cruciale pour deux raisons.

Premièrement, vous avez un niveau de retry supplémentaire : non seulement les clients HTTP et load‑balancers, mais l’agent lui‑même peut décider de répéter l’appel d’un outil en cas d’erreur ou de résultat incomplet. Deuxièmement, dans des scénarios de production réels, s’ajoutent webhooks, files, canaux de streaming — et vous pouvez traiter par inadvertance la même étape logique plusieurs fois.

Vous avez déjà abordé l’idempotence au niveau des MCP‑tools : ne pas débiter deux fois, ne pas créer deux fois la même commande, utiliser des idempotency keys dans les requêtes. C’est la même chose ici, multipliée par la nature multi‑étapes de l’agent.

Imaginons que GiftGenius dispose d’un outil create_checkout_session, qui crée un brouillon de checkout (draft) dans ACP/Stripe à partir d’une liste de cadeaux choisis. Si l’agent décide de répéter cet appel à cause d’une erreur réseau, vous ne voulez surtout pas deux commandes distinctes et deux débits.

Il faut donc :

  • concevoir une idempotency key externe pour chaque action logique (par exemple, runId + stepIndex ou un checkoutDraftId explicitement généré) ;
  • la transmettre à votre backend/endpoint ACP ;
  • côté backend, vérifier si vous avez déjà traité cette clé, et renvoyer le résultat enregistré au lieu d’exécutions répétées.

Pseudo‑exemple en TypeScript :

async function createCheckoutDraft(runId: string, payload: DraftPayload) {
  const key = `gift-checkout-${runId}`;

  const existing = await findDraftByKey(key);
  if (existing) return existing;

  const draft = await stripe.checkout.sessions.create({
    /* ... */,
    idempotencyKey: key, // ou votre propre couche par‑dessus
  });

  await saveDraftWithKey(key, draft);
  return draft;
}

Ainsi, même si l’agent appelle cet outil deux fois avec le même runId, votre code restera idempotent : une même étape logique → un même résultat effectif.

« D’abord vérifier, ensuite agir »

Deuxième pattern d’idempotence courant — vérifier d’abord l’état, puis agir. Par exemple, avant de créer une commande, vérifier qu’il n’existe pas déjà une commande avec ce clientReferenceId ou avec le même jeu de paramètres. C’est particulièrement pratique dans des workflows longs, où l’agent peut « oublier » qu’il a déjà fait quelque chose à l’étape précédente.

Safe‑mode/Fake‑mode

En phase de développement, il est utile d’avoir un « mode sûr » pour les outils dangereux : au lieu d’agir réellement, ils se contentent de journaliser ce qui aurait été fait, et renvoient un pseudo‑résultat. Pour les agents, c’est un moyen pratique de faire tourner le cycle d’exécution en environnement réel, sans risques pour l’argent ou les données.

8. Mini‑pratique : décrire l’agent GiftGenius en langage naturel

Nous avons déjà parlé du cycle d’exécution, du déterminisme et de l’idempotence des outils. Faisons une minute de pause sans code et voyons comment tout cela s’assemble dans un scénario vivant.

Il est utile de faire maintenant un petit exercice sur papier (ou mentalement), sans code.

Imaginez que vous décrivez un agent simple :

  • system
    : tu es un assistant de sélection de cadeaux ; tu demandes toujours les détails importants, tu n’inventes pas de produits et tu utilises uniquement les résultats des outils.
  • user
    : je veux un cadeau pour un collègue jusqu’à 50 $.

Décrivez en mots les étapes que cet agent doit effectuer.

Un scénario typique peut ressembler à ceci.

  1. L’agent commence par vérifier si l’information est suffisante. Sinon, il pose des questions de clarification : que fait à peu près le collègue (designer, développeur, manager), y a‑t‑il des tabous (alcool, cadeaux humoristiques), des contraintes de livraison. Les réponses vont soit dans le session state, soit dans les paramètres d’appel de l’outil.
  2. Ensuite, l’agent appelle l’outil search_gifts avec un profil rempli : « collègue développeur, budget 50, catégorie — gadgets et bureau ». L’outil renvoie une liste de candidats avec prix, catégories et ID produits.
  3. L’agent peut ensuite appeler un outil supplémentaire filter_gifts_by_constraints si l’on découvre que certains produits ne peuvent pas être livrés dans la région souhaitée, ou filtrer « à la main » dans son prompt. Après cela, il classe les options par pertinence et prix, en ajoutant éventuellement ses commentaires (« convient si le collègue aime le café », « bon choix pour le télétravail »).
  4. Enfin, l’agent prépare la réponse finale structurée pour ChatGPT App : une liste de 5 à 7 cadeaux avec brèves descriptions, suggestions d’usage et liens vers le Checkout (ou l’étape suivante — création d’un brouillon de checkout).

Où des tool‑calls sont‑ils nécessaires ? Évidemment, dans la recherche et le filtrage des produits, la vérification de disponibilité et la création du brouillon de checkout. Quelles étapes doivent être idempotentes ? En premier lieu toutes les opérations liées aux commandes et à l’argent — création du brouillon de checkout, éventuelle écriture de l’historique en base.

9. Erreurs typiques lors des premiers pas avec les agents

Erreur n°1 : l’agent comme « un deuxième ChatGPT sans contraintes ».
On a parfois envie de donner au modèle un prompt supplémentaire et d’appeler cela un « agent ». Il en résulte quelque chose qui génère beaucoup de texte, appelle des outils de façon chaotique et se contrôle mal. Pour éviter cela, il est important de décrire clairement le rôle de l’agent dans le system, de restreindre la liste des outils et de le considérer comme un orchestrateur avec une mission concrète, et non comme une « deuxième galaxie de génération de texte ».

Erreur n°2 : absence d’idempotence dans les outils.
Les développeurs transfèrent souvent leurs anciens handlers HTTP vers l’agent « tels quels », sans tenir compte du fait que désormais le runner peut relancer automatiquement les appels. Dans le cas des paiements et commandes, cela peut avoir des conséquences très désagréables. La bonne approche — concevoir immédiatement les outils de sorte qu’un nouvel appel avec la même clé logique ne mène pas à une action répétée.

Erreur n°3 : réglages trop créatifs du modèle.
Une température élevée convient très bien pour écrire des toasts et des poèmes, mais pour un agent qui doit orchestrer de manière fiable des processus multi‑étapes, c’est la voie vers un comportement imprévisible : le modèle choisira à chaque fois des outils différents, générera des plans divergents et parfois « oubliera » qu’il dispose de tools. Traitez les agents comme des entités « de service » et gardez‑les en mode plus strict.

Erreur n°4 : un outil « passe‑partout ».
Parfois on veut créer un tool universel comme execute_any_sql ou do_anything_with_orders, puis le mettre entre les mains de l’agent. Combiné à la créativité d’une LLM, c’est presque une menace de sécurité garantie. Il vaut bien mieux disposer de plusieurs outils spécialisés avec des contrats et droits clairs, qu’un « divin » avec tous les droits sur tout.

Erreur n°5 : absence de critères explicites de fin de run.
Si vous n’expliquez pas à l’agent quand il doit s’arrêter, il peut entrer dans des boucles infinies ou semi‑infinies : re‑vérifier, re‑interroger l’utilisateur, re‑essayer d’appeler l’outil avec la même erreur. Cela se manifeste souvent uniquement sous charge, quand l’une des dépendances est instable. La bonne méthode — définir des limites sur le nombre d’étapes, le temps du run, le nombre de répétitions pour la même erreur, et décrire dans le system que l’agent doit « abandonner honnêtement » quand des options raisonnables sont épuisées.

Erreur n°6 : tout stocker dans l’état de l’agent.
Puisque Agents SDK simplifie la gestion du session state, la tentation est grande d’y mettre tout et n’importe quoi : gros documents, logs bruts, données sensibles. Cela gonfle le contexte, augmente le coût et crée des risques de sécurité. L’état de l’agent ne doit contenir que ce qui est nécessaire à la poursuite du travail ; le reste — en base, dans les logs et autres couches, en tenant compte de la confidentialité.

Erreur n°7 : essayer d’utiliser un agent là où un simple MCP‑tool suffit.
Parfois les développeurs commencent par un agent, alors que la tâche consiste simplement à appeler une fonction et renvoyer un résultat. Cela ajoute de la complexité là où elle n’est pas nécessaire : cycle d’exécution, état, logs supplémentaires et points de défaillance potentiels. Si le scénario tient dans un seul tool‑call sans workflow complexe, mieux vaut le laisser ainsi, et n’introduire un agent que lorsqu’une vraie multi‑étape apparaît.

Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION