---
title: "La plupart des agents IA ne devraient pas être des agents"
description: "En quelques mois, j'ai réduit d'environ cinq le nombre d'agents dans mes workflows de production. Ce qui les a remplacés: un modèle minuscule pour router la requête, des étapes définies à l'avance plutôt que décidées à l'exécution, et une mémoire de conversation chargée et stockée manuellement. Voici le schéma."
date: 2025-10-29
language: fr
canonical: https://gduv.club/fr/articles/ai-workflows-instead-of-agents
source: gduv.club
---
Lorsque les agents sont arrivés dans n8n, j’en ai créé beaucoup. On glisse un nœud d’agent, on y rattache trois outils, et il détermine lequel appeler. On avait l’impression que tout était devenu simple.

Au cours des mois suivants, je les ai retirés pour la plupart. Dans les workflows qui devaient passer à l’échelle et tourner réellement en production, je n’ai plus qu’environ un cinquième des agents que j’avais.

Non pas parce que les agents sont mauvais. Mais parce que pour la majorité de mes tâches, l’agent décidait à l’exécution de choses que je connaissais déjà à la conception, et me facturait ce privilège à chaque interaction.

[99% AI Agents Shouldn’t Exist. Do This Instead (+ reliable, faster, cheaper)!](https://www.youtube.com/watch?v=BHdJFnx2wrc)

## Le schéma que je prends pour exemple

Un chatbot de support. Un déclencheur de chat, un agent basé sur un grand modèle, et un outil: une requête HTTP vers un point de terminaison de récupération qui répond aux questions à partir de mes documents. Quelqu’un pose une question sur le produit, l’agent appelle l’outil, lit le résultat et rédige la réponse.

**Agent de connaissance IA**

**Lors de la réception d’un message de chat** → **Agent de connaissance IA** (gpt-4.1, Modèle de Chat: Modèle de chat OpenAI (gpt-4.1); Mémoire: Mémoire simple; Outil: Interroger la base de connaissances (Requête HTTP. L’agent rédige la requête et décide quand l’appeler))

_Quatre nœuds. C’est vraiment rapide à construire, c’est d’ailleurs pour cela que cette structure est omniprésente._

## Un simple bonjour et cela vous coûte un modèle de pointe

Envoyez "bonjour" à cet agent. Vous obtenez une réponse amicale en environ 1,3 seconde, rédigée par l’un des plus grands modèles disponibles.

Aucun outil n’a été appelé. Rien n’a été récupéré. L’intégralité du prompt système a été envoyée en tokens d’entrée, y compris chaque ligne décrivant des outils qui n’ont jamais été utilisés.

| Step | What happens | Cost |
| :--- | :--- | ---: |
| Le message arrive | "bonjour" | 1 token |
| Le prompt système complet est envoyé | Chaque description d’outil, chaque règle sur l’appel des outils | la totalité |
| Le grand modèle décide | Il décide de ne rien appeler |  |
| Le grand modèle répond | "Bonjour, comment puis-je vous aider aujourd’hui ?" |  |

_Mon prompt était ici léger. Avec cinq outils attachés et l’ordre d’appel détaillé, c’est la ligne du milieu qui représente la majeure partie de la facture._

La salutation est le cas le plus simple à observer, mais elle n’est pas rare. Sur un chatbot, une part importante des messages ne nécessite ni récupération ni recherche d’informations.

## La même chose, mais explicitée

Voici le remplacement. Il y a plus de nœuds, et chacun d’eux représente une décision que j’ai prise une seule fois, plutôt qu’une décision qu’un modèle prend à chaque message.

**Chatbot RAG intelligent et efficace**

**Message de chat reçu** → **Trouver les messages passés** (Gestionnaire de mémoire, mode chargement, Mémoire: Mémoire simple) → **Routeur d’intention** (Classificateur de texte, deux catégories, Modèle de chat: Modèle très petit (gpt-4.1-nano))

- _aucune récupération de connaissances nécessaire_ → **Réponse simple** (Chaîne LLM basique sur le même petit modèle)

- _récupération de connaissances nécessaire_ → **Préparer la requête de récupération** (Chaîne LLM basique, gpt-4.1-mini) → **RAG via Lookio** (Requête HTTP simple. Aucun modèle à cette étape) → **Rédiger la réponse finale** (Chaîne LLM basique, gpt-4.1. Le seul grand modèle du canevas)

**Répondre au chat** → **Stocker les messages** (Gestionnaire de mémoire, mode insertion)

_Trois modèles sur le canevas, chacun dimensionné pour son étape. Le grand ne s’exécute que sur un seul nœud, et uniquement pour les messages qui l’atteignent._

### Router d’abord, avec un modèle qui ne coûte rien

Le seul travail du classificateur de texte est de décider quel chemin le message doit prendre. Deux catégories, chacune avec une description:

- **Aucune récupération de connaissances nécessaire.** Salutations, confirmations, discussions informelles. Tout ce qui peut être répondu sans consultation externe.
- **Récupération de connaissances nécessaire.** Le message nécessite des informations issues des documents avant de pouvoir être traité.

La classification est une tâche légère et un petit modèle s’en sort très bien. C’est assez rapide pour que l’étape soit presque invisible dans la latence totale, et assez peu coûteux pour que je n’y pense plus.

Le chemin économique consiste en une chaîne LLM basique sur ce même modèle minuscule avec un prompt système court. Un « Salut » revient maintenant en environ deux secondes, avec un résultat identique, sur un modèle dont le coût par token est une fraction de celui qu’il remplace.

**Le routeur a besoin de la conversation, sinon il se trompe sur les questions de suivi**

« Et pour le deuxième point ? » nécessite une récupération d’informations et ressemble à une banalité s’il est lu seul. Ainsi, le prompt du classificateur contient les messages précédents, formatés en lignes `human:` et `ai:`, avec une instruction pour se concentrer sur le nouveau message et traiter le reste comme contexte. Sans cela, les questions de suivi sont dirigées vers le chemin économique et le bot répond sans aucune information.

Un seul nœud de modèle alimente à la fois le routeur et la réponse simple. Ce sont des tâches différentes, mais d’une complexité similaire. Avoir un seul endroit pour changer le modèle signifie que j’essaie occasionnellement d’en tester un autre, au lieu de modifier deux nœuds et d’en oublier le second.

### Configurer le déclencheur pour répondre depuis un nœud

Un petit détail qui bloque tout le design si on l’oublie. Par défaut, un déclencheur de chat répond à partir du dernier nœud, or ce workflow possède deux chemins qui doivent tous deux pouvoir répondre.

Réglez le mode de réponse du déclencheur sur « répondre depuis un nœud », puis placez un nœud **Respond to Chat** là où les branches se rejoignent. Sans cela, il est impossible d’avoir un chemin économique et un chemin coûteux qui répondent tous les deux, ce qui est tout l’intérêt du routage.

### Le chemin de récupération, en trois nœuds

Regardez ce que l’agent a fait pour une question réelle. Le grand modèle a été sollicité, a pris 600 ms et a décidé d’appeler l’outil. Bonne décision. Mais ce qu’il a produit avec toute cette intelligence est une courte chaîne de requête, grossièrement une version nettoyée de ce que l’utilisateur vient de taper. Et pour l’écrire, l’intégralité du prompt système a été renvoyée.

**Tâches du tour** (Toutes sur le grand modèle)

- Décider qu’une récupération est nécessaire
- Rédiger une courte requête de recherche
- Rédiger la réponse finale à partir des résultats

**Besoin de chaque tâche** (Si on choisit par étape)

- Un classificateur, modèle minuscule
- Une réécriture, petit modèle
- Un grand modèle, et ici il est justifié

_Seul le dernier bénéficie du modèle coûteux, alors que dans une structure d’agent, les trois s’exécutent dessus._

Le chemin se compose donc de trois nœuds plutôt que d’un seul agent.

**Prepare retrieval query** est une chaîne LLM basique sur un mini modèle. Son prompt système : à partir du message de l’utilisateur, formuler la requête courte et concise à envoyer à l’outil de récupération de connaissances, et l’afficher directement sous forme de question. Dans mes tests, le petit modèle a écrit la même requête que le grand.

**RAG via Lookio** est une simple requête HTTP. La requête va dans le corps, l’ID de l’assistant et le mode sont des valeurs fixes que j’ai choisies plutôt que des paramètres sur lesquels un modèle pourrait dériver. La plupart des outils que vous attachez à un agent sont des API, et la plateforme vous fournit généralement le nœud prêt à être collé.

**Write the final response** reçoit le message original et le contenu récupéré, étiquetés, puis rédige la réponse. Celui-ci reste sur le grand modèle, car c’est dans la formulation de la réponse finale que la qualité s’exprime.

### La mémoire est désormais à votre charge

C’est la partie que l’agent gérait pour vous, et celle que vous devez rétablir.

Un nœud d’agent prend un sous-nœud de mémoire et le gère. Si on divise l’agent en étapes, plus rien ne le fait : la conversation est donc chargée une fois en haut et stockée une fois en bas.

| Step | What happens | Cost |
| :--- | :--- | ---: |
| Trouver les messages passés | Gestionnaire de mémoire en mode chargement, juste après le déclencheur | une fois |
| Chaque prompt l'ajoute | Le routeur, la réponse simple et les deux étapes de récupération reçoivent l'historique | ×4 |
| Respond to Chat | La réponse repart vers l'utilisateur |  |
| Stocker les messages | Gestionnaire de mémoire en mode insertion : le message utilisateur et la réponse | une fois |

_Plus de câblage qu’un sous-nœud de mémoire, pour le même tampon sous-jacent. En échange, vous voyez, étape par étape, exactement quelle quantité d\'historique a été fournie._

C’est plus de travail. C’est aussi le moment où l’on s’aperçoit qu’un agent injectait toute la conversation dans chaque tour, alors qu’une étape de réécriture de requête n’a besoin que des deux derniers messages plutôt que des vingt derniers.

## Ce que vous y gagnez

**Agent** (Décidé à l’exécution)

- Modèle volumineux à chaque tour, salutations ou non
- Prompt système et descriptions d’outils à chaque appel
- Peut ignorer un outil et répondre de mémoire
- Peut réorganiser les étapes, ce que l’on découvre en production

**Étapes explicites** (Décidé à la conception)

- Modèle volumineux sur un seul nœud parmi cinq
- Aucune description d’outil requise
- La récupération s’exécute toujours, car c’est une étape
- L’ordre suit exactement celui défini

_La prédictibilité est le critère que j’aurais classé dernier il y a un an, et que je classe premier aujourd’hui._

La troisième ligne est la plus importante pour moi. Un agent qui ignore un outil pour répondre avec ses propres connaissances est une erreur impossible à reproduire ou à tester. Un workflow ne peut pas faire ça. Le nœud est là, il s’exécute.

## Quand j’utilise encore un agent

Quand je ne connais réellement pas l’ordre des étapes. Pour de la recherche ouverte, où la seconde requête dépend des résultats de la première. Bref, dès que le nombre d’étapes n’est pas connu à l’avance.

C’est le test que j’utilise désormais : puis-je dessiner ce processus sur papier avant qu’il ne s’exécute ? Si oui, utiliser un agent revient à payer un modèle pour qu’il redécouvre mon dessin à chaque requête.

## La même question, un niveau au-dessus

C’est cette habitude qui se transfère. Quand j’utilise Claude Code ou Codex, beaucoup de mes actions ressemblent à ce bot de support, et les parties coûteuses sont les mêmes : tout le contexte est renvoyé pour une étape qui n’en aurait besoin que d’une fraction, ou un modèle redécouvre quelque chose que je savais déjà.

Savoir combien coûte l’appel d’un outil, parce qu’on l’a un jour configuré à la main en surveillant le nombre de tokens, permet de voir ce qui se passe à l’intérieur d’une interface qui ne montre presque rien.

Ouvrez vos propres agents et analysez les exécutions. Pour chacune, demandez-vous si vous auriez pu dessiner les étapes vous-même avant l’exécution. Pour la plupart des miens, c’était possible.

## Sources

- [n8n: Text Classifier node](https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.text-classifier/)
- [n8n: Basic LLM Chain node](https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.chainllm/)
- [n8n: Chat Memory Manager node](https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.memorymanager/)
- [OpenAI: model pricing](https://openai.com/api/pricing/)