Accueil / Articles / Comprendre les agents d’IA à travers l’analogie cerveau-doigt

Comprendre les agents d’IA à travers l’analogie cerveau-doigt

Apprenez comment les LLM, les outils et leurs exécuteurs interagissent en appliquant l’architecture des agents à une analogie de commande de repas, puis créez une implémentation minimale d’agent.

1513 mots

Aperçu

Analogie

Cela commence par votre cerveau qui indique à votre doigt d’ouvrir l’application de commande de repas afin que vous puissiez consulter les restaurants à proximité. Votre doigt touche l’icône, et une liste de restaurants apparaît à l’écran.

Puis votre cerveau lit les noms des restaurants affichés à l’écran et dirige votre doigt pour qu’il touche un restaurant en particulier afin d’afficher son menu. Ensuite, votre cerveau examine les plats du menu et indique à votre doigt de toucher le bouton « Ajouter » à côté des plats que vous souhaitez, les ajoutant ainsi au panier.

Lorsque c’est fait, votre cerveau vérifie tout ce qui se trouve dans le panier pour s’assurer qu’il n’y a rien d’oublié, puis indique à votre doigt de toucher « Passer commande ».

Finalement, votre cerveau reconnaît que l’objectif a été atteint dès qu’il voit l’écran de confirmation de commande, et à ce moment-là, l’alternance entre le cerveau et le doigt prend fin.

Analogie en langage d’agent

Remarquez quelque chose d’important tout au long de cette séquence : le cerveau lui-même n’a jamais effectué d’action directement — il se contente d’interpréter les informations reçues et de dire au doigt ce qu’il doit faire ensuite. Cela correspond presque exactement à la manière dont un agent IA fonctionne. Le LLM joue le rôle du cerveau ; des actions comme consulter les restaurants, ouvrir un menu, ajouter des articles au panier et passer la commande sont les outils que le cerveau sait utiliser ; et le doigt correspond à l’exécutant de l’outil, la composante qui effectue réellement l’action.

Lorsque vous créez un agent à des fins spécifiques, vous définissez un ensemble d’outils et vous le transmettez à l’LLM, qui agit comme le cerveau chargé de prendre les décisions. (Dorénavant, -> sera utilisé pour indiquer un passage du contrôle à l’étape suivante.) Lorsqu’un utilisateur confie une tâche à l’agent, le flux se déroule comme suit : l’LLM examine l’étape actuelle ou le travail restant et choisit l’outil le plus pertinent –> il transmet cet outil à son exécutant, en lui demandant de le lancer et de rapporter les résultats –> l’LLM lit ces résultats et vérifie s’ils répondent à la demande de l’utilisateur. S’ils le font, le processus s’arrête là ; sinon, l’LLM choisit l’outil approprié suivant en fonction du dernier résultat, et le cycle se répète jusqu’à ce que l’LLM détermine que la tâche est entièrement terminée et qu’aucune autre appel d’outil n’est nécessaire.

Mise en œuvre

Avec le concept établi, l’étape suivante consiste à créer un petit agent fonctionnel capable de passer une commande de nourriture en fonction des demandes de l’utilisateur. Les extraits de code ci-dessous illustrent le parcours d’exécution réel emprunté par l’agent, et un lien vers le dépôt complet est fourni à la fin.

Outils

get_restaurants() {
    // In production, replace with an API call such as GET /api/v1/restaurants
  return list of restaurants;
}

get_menu(restaurantName) {
    // In production, replace with an API call such as GET /api/v1/restaurants/${restaurantName or restaurantId}/menu
  return menuItems;
}

add_to_cart(sessionId, menuItemId) {
  // In production, replace with an API call such as POST /api/v1/cart
  return updatedCart;
}

place_order(sessionId) {
  // In production, replace with an API call such as POST /api/v1/order
  return orderDetails;
}

Remarquez que ces outils ne sont rien de plus que des fonctions ordinaires du type que l’on écrit dans le code d’applications courantes — ils ne contiennent ni cadre d’agent spécial ni logique spécifique aux LLM. Dans une véritable configuration de production, chaque outil disposerait en plus d’un nom, d’une description et d’un schéma d’entrée défini indiquant les données attendues. C’est ce nom et cette description que l’LLM utilise pour déterminer quel outil correspond le mieux à la demande de l’utilisateur.

Exécuteur d’outils

toolExecutor(toolCall) {
  const tool = toolNameMap[toolCall.name];

  return tool.execute(toolCall.arguments);
}

L’exécuteur d’outil n’est en réalité qu’une fonction ordinaire. Son argument toolCall contient des informations sur l’outil qui est appelé — son nom ainsi que ses arguments — et ces éléments varient en fonction de l’outil utilisé, qu’il s’agisse du nom d’un restaurant, d’un ID d’élément de menu ou de tout autre élément. L’essentiel est que lorsque le LLM indique à l’exécuteur quel outil doit être lancé, il fournit des détails précis et structurés, tels que le nom de l’outil get_menu avec l’argument {restaurantName: "Spicy Pizza"}. Il n’est pas nécessaire d’extraire ou de parser manuellement ces informations à partir du texte brut généré par le LLM.

Agent

// Give all the tools to the LLM
llm = OpenAILLM.bindTools([get_restaurants, get_menu, add_to_cart, place_order])

// Take the user query to run the agent loop
reactAgent(userInput) {
  while (true) {
    response = llm(userInput);

    if (response.isFinalAnswer) {
      return response.answer;
    }

    result = toolExecutor(response.toolCall);

    userInput = response + result;
  }
}

Points à observer dans le pseudocode

  1. reactAgent fait référence au modèle de prompting ReAct (Reason and Act), dans lequel le LLM choisit l’outil à appeler, observe le résultat de cet appel, puis détermine s’il faut exécuter un autre outil ou si la tâche est terminée et que le cycle peut s’arrêter.
  2. while(true). C’est précisément ici que les agents diffèrent de la logique conditionnelle que l’on écrit habituellement dans des langages comme Java ou Python. Au lieu de coder directement les appels de fonction à l’intérieur de branches if-else ou de boucles for, on expose un ensemble d’outils au LLM — chacun ayant un nom et une description — et on laisse le LMM lui-même décider, en temps de exécution, quel outil invoquer ensuite, quels arguments transmettre, et quand le travail est terminé et que le cycle doit s’arrêter.
  • Cela dit, les systèmes de production ne reposent pas réellement sur une boucle brute while(true) ; elle est utilisée ici uniquement pour illustrer le comportement agentiel sous-jacent dans un code simple. En pratique, on recourt à un framework d’orchestration tel que LangGraph. Même avec un tel framework, il est de coutume de limiter la profondeur de récursivité afin que l’LLM ne puisse pas être appelé indéfiniment — une boucle sans limite entraîne des bugs, un gaspillage de tokens et des coûts inutiles.
  • Vérification response.isFinalAnswer dans le pseudocode indique que l’agent a abouti à une réponse complète et qu’aucune autre appel d’outil n’est nécessaire. Une fois cela fait, l’agent renvoie une réponse résumée à l’utilisateur au lieu de déclencher un autre outil.
  • Vous avez peut-être également remarqué la ligne userInput = response + result, où la sortie combinée est renvoyée à l’LLM sous forme de response = llm(userInput) lors de l’itération suivante. Cela se produit parce que chaque appel à l’LLM est sans état : il ne conserve aucune mémoire des échanges précédents, même au sein de la même session ou interaction utilisateur. Par conséquent, chaque fois qu’une outil termine son exécution, il faut réenvoyer l’ensemble de l’historique de la conversation : le prompt système décrivant le comportement attendu de l’agent, la requête initiale de l’utilisateur, la réponse précédente de l’IA suggérant un appel à outil, ainsi que le résultat généré par cet outil. L’LLM traite ensuite toute cette séquence pour déterminer si l’objectif a été atteint ou s’il est nécessaire d’exécuter davantage d’appels à outil.
  • Diagramme de séquence entre l’LLM et l’exécution des outils

    Le diagramme ci-dessous illustre comment le LLM choisit l’outil suivant, comment son exécuteur le met en œuvre, et comment ce cycle se répète jusqu’à ce que le LLM conclue que la tâche est terminée et qu’aucune exécution d’outil supplémentaire n’est nécessaire.

    Le flux décrit montre clairement les allers-retours : le LLM propose une action, l’exécuteur la réalise, le résultat revient au LLM, qui propose alors une autre action ou termine la boucle par une réponse finale.

    Code GitHub

    Un repositoire contenant du code de départ est disponible si vous souhaitez exécuter cet exemple vous-même et observer le fonctionnement de l’agent en temps réel.

    Lectures complémentaires

  • Découverte progressive d’outils pour les agents IA à grande échelle — Explique pourquoi de grands catalogues d’outils détériorent les performances des agents IA et comment une découverte progressive via des manifestes et des schémas just-in-time résout ce problème.
  • Appeler Claude, GPT et Gemini via des points d’entrée compatibles OpenAI — Découvrez ce que les couches compatibles OpenAI d’Anthropic et Gemini prennent en charge, où elles suppriment silencieusement certaines fonctionnalités, et quand il est judicieux de rediriger les trois via un même gateway.