Pannes en production

agent ia n8n qui n'appelle pas les outils

Workflow · n8n-agent-tool-calling-repro.json · mis à jour le 2026-08-06

Un AI Agent n8n qui répond à votre question sans jamais toucher l'outil que vous lui avez donné n'est presque jamais un bug n8n. Dans la grande majorité des rapports, c'est le modèle sous l'Agent qui échoue à émettre un tool call structuré, et n8n vous affiche fidèlement le texte qu'il a reçu. Le correctif est généralement une liste déroulante, pas une réécriture de workflow. Cette page sépare la seule cause qui concerne vraiment n8n de celles qui concernent le modèle, car chercher du côté du mauvais peut coûter une après-midi.

Le symptôme

L'Agent s'exécute, retourne une réponse plausible, et le sous-nœud outil en dessous ne montre aucune exécution. Pas d'erreur, pas de nœud rouge, juste un outil qui n'a jamais été appelé. Dans la version la plus claire de la panne, la sortie de l'Agent n'est pas du texte mais un objet JSON avec le tool call écrit en clair. Un cas rapporté, utilisant Gemini 2.5 Pro via n8n, a retourné un body contenant "functionCall": { "name": "Airtable_Send", "args": { ... } } verbatim, avec chaque argument correct, sans pour autant exécuter le nœud Airtable. Le modèle a décrit l'appel qu'il voulait effectuer au lieu de le faire, et n8n a affiché la description.

Une deuxième forme ressemble à l'Agent qui essaie et abandonne. Au lieu d'un saut silencieux, vous obtenez l'erreur Max iterations (10) reached. The agent could not complete the task within the allowed number of iterations. L'Agent a bouclé, n'a jamais produit un appel que le runtime pouvait exécuter, et a atteint son plafond. Même problème sous-jacent, mode d'échec plus bruyant.

Une troisième forme est intermittente. Le même workflow appelle l'outil sur une exécution et l'ignore sur la suivante sans changement de votre côté. Deux choses distinctes produisent ça et nécessitent des réponses différentes : une version de modèle ou de fournisseur qui a bougé sous vous, ou le non-déterminisme d'échantillonnage sur un prompt borderline, où le modèle allait toujours sauter l'appel une fraction du temps. C'est la version de ce bug qui fait perdre le plus de temps, parce qu'elle ressemble à votre prompt.

Ce qui le déclenche

Le modèle ne fait pas de structured tool calling. C'est la cause dominante de loin. Le Tools Agent n8n implémente l'interface tool-calling de LangChain, ce qui signifie qu'il dépend du modèle pour retourner un tool call lisible par une machine, pas une phrase à son sujet. Les modèles qui sont faibles là-dessus, ou qui passent par un fournisseur qui n'expose pas l'API function-calling, émettent l'appel en texte et l'Agent n'a rien à exécuter. Gemini est le nom qui revient le plus dans les rapports, et les petits modèles auto-hébergés suivent de près : un utilisateur a trouvé que nvidia/llama-3.1-nemotron-nano-4b retournait des tool calls sous forme de chaînes simples alors que le même workflow fonctionnait sur un modèle plus grand. L'outil, le prompt et le câblage étaient tous corrects. Le modèle était la variable.

Un workflow migré depuis un ancien type d'agent. Les versions antérieures de n8n exposaient plusieurs types d'agents (Conversational, ReAct, Plan and Execute, OpenAI Functions) qui parsaient le tool call depuis le texte du modèle. Les versions récentes ont fusionné le nœud Agent sur le Tools Agent et, dans certaines releases, ont supprimé le sélecteur de type d'agent entièrement, ce qui explique pourquoi des utilisateurs rapportent que le champ de type a simplement disparu. Un modèle faible qui s'en sortait sous ReAct, parce que n8n faisait le parsing, n'a rien sur quoi s'appuyer sous le Tools Agent, qui passe l'appel à l'API function-calling du fournisseur. Si le même graphe fonctionnait avant une mise à jour et s'est arrêté après, c'est un suspect principal.

Les paramètres de l'outil sont mal configurés. Un outil peut être effectivement ignoré même quand le modèle l'appelle, si ses arguments n'arrivent jamais. n8n remplit les paramètres d'outil via l'expression $fromAI(), et il y a de vraies lacunes : des arguments du tool call du modèle ont été rapportés comme n'atteignant pas les nœuds d'outils natifs n8n via $json alors que le même setup fonctionnait pour les outils LangChain intégrés. Un outil appelé mais qui reçoit des arguments vides ou incorrects ressemble, côté chat, exactement à un outil jamais appelé, ce qui explique pourquoi celui-ci se cache si bien.

Un outil connecté est désactivé en place. Celui-là est vraiment un comportement n8n. Si vous connectez deux outils ou plus à un Agent et désactivez l'un en le sélectionnant et en appuyant sur D, certaines versions font échouer chaque requête qui a besoin d'un outil, en terminant par l'erreur Max iterations (10) reached plutôt que d'ignorer silencieusement le nœud désactivé. Rapporté sur n8n 2.9.4 et fermé comme impossible à reproduire, ce qui indique que c'est dépendant de l'environnement et de la version, pas universel. Ça vaut la peine de le connaître précisément parce que ça ressemble exactement à un problème de modèle de l'extérieur.

L'instruction ne rend pas l'outil utile à appeler. Un modèle décide d'appeler un outil à partir du nom et de la description de l'outil et de votre system prompt. Si la description est vide ou générique, ou si le prompt ne dit jamais au modèle que l'outil existe et quand l'utiliser, un modèle capable répondra souvent depuis ses propres connaissances. C'est réel, mais c'est sur-prescrit comme cause : des équipes réécrivent des prompts pendant une semaine alors que le modèle était simplement incapable d'un structured call en premier lieu.

Une régression de version ou de fournisseur. Plusieurs rapports décrivent des workflows qui appelaient les outils de manière fiable pendant des mois et se sont arrêtés après une mise à jour, avec des threads intitulés "tools not working since yesterday" ou "agent that stopped using its assigned tools". Quand le graphe n'a pas changé et que le comportement a changé, suspectez la version du modèle, la release n8n, ou le fournisseur avant de suspecter votre propre configuration.

Distinguer les cas

Avant de changer quoi que ce soit, répondez à une question : le modèle a-t-il seulement tenté un structured call ? Tout ce qui suit en dépend, et n8n vous montre la réponse si vous regardez au bon endroit.

Ouvrez l'exécution de l'Agent et lisez la sortie brute du modèle, pas la réponse finale de l'Agent. Si la sortie contient une structure functionCall ou tool_calls rendue en texte, le modèle a essayé et son appel n'est jamais devenu une vraie invocation. C'est un problème de capacité ou de fournisseur, et aucun travail sur le prompt ne le corrigera. Si la sortie est de la prose ordinaire sans tentative d'appel, le modèle a choisi de ne pas appeler l'outil, ce qui pointe vers le prompt et la description de l'outil. Si l'exécution se termine par Max iterations (10) reached, vérifiez si un outil connecté est désactivé avant de supposer quoi que ce soit sur le modèle.

Le test décisif est de tenir tout constant sauf le modèle. Exécutez le même graphe, même prompt, même outil, en changeant uniquement le modèle. Si l'outil s'exécute sur un modèle et est ignoré sur un autre, le modèle était la cause et vous en avez terminé. C'est exactement ce que l'artefact de cette page est conçu pour faire : un Tools Agent, un outil Calculator, et un prompt qui ne peut être répondu correctement qu'en l'appelant. Changez le modèle et observez le sous-nœud Calculator s'exécuter ou rester intact.

Le correctif

L'ordre est délibéré, du moins cher et plus fréquent au premier.

  1. Utilisez un modèle qui émet des tool calls de manière fiable. Sur la liste de fournisseurs actuelle, ça signifie les modèles OpenAI, Anthropic, Groq, Mistral ou Azure OpenAI connus pour leur function calling. En pratique, les équipes se stabilisent sur un modèle Anthropic ou OpenAI solide pour tout ce qui a plus d'un outil. Si vous devez utiliser un petit modèle auto-hébergé, vérifiez le tool calling en isolation avant de construire un graphe dessus, car la plupart des petits modèles dégradent exactement sur cette capacité en premier.
  2. Supprimez les outils que vous n'utilisez pas, ne les désactivez pas. Si vous voulez retirer un outil de l'Agent, supprimez la connexion plutôt que de le désactiver en place. Sur les versions où le bug de l'outil désactivé mord, cette seule configuration transforme un Agent qui fonctionne en une boucle qui meurt au plafond d'itérations, et la suppression contourne ça quelle que soit votre version.
  3. Confirmez que l'outil reçoit ses arguments. Vérifiez que chaque paramètre $fromAI() est mappé et que le nœud outil reçoit une entrée non vide lors d'une exécution. Un outil appelé avec des arguments vides échoue aussi silencieusement qu'un outil jamais appelé, donc un nœud vert n'est pas une preuve en soi.
  4. Rendez l'outil utile à appeler. Donnez à chaque outil un nom et une description d'une ligne qui dit ce qu'il fait et quand l'utiliser, et nommez l'outil dans le system prompt. Ne vous arrêtez pas au prompt pour autant : une instruction explicite ne peut pas sauver un modèle incapable d'un structured call.
  5. Épinglez vos versions. Une fois qu'un graphe fonctionne, notez l'id du modèle et la version n8n. Quand ça casse sans changement de votre côté, le premier diagnostic est lequel des deux a bougé.
  6. Si le tool calling reste peu fiable, abandonnez l'Agent pour cette étape. Pour une action unique et déterministe, un nœud LLM simple suivi du nœud que vous auriez appelé comme outil est plus fiable et moins cher, car il supprime entièrement la discrétion du modèle. Réservez l'Agent pour le routage vraiment ouvert. La même intuition qui borne une boucle déréglée dans LangGraph s'applique ici : retirez la décision au modèle quand la décision n'est pas vraiment ouverte.

Vérifier le correctif

Prouvez que l'outil s'exécute, ne faites pas confiance à la réponse finale. Un résultat final correct ne prouve pas que l'outil a tourné, car un modèle capable peut calculer un petit résultat lui-même. Ouvrez le sous-nœud outil dans l'exécution et confirmez qu'il a une entrée et une sortie pour la run. S'il n'en a pas, l'Agent a répondu sans lui.

Forcez un appel que le modèle ne peut pas simuler. L'artefact utilise 23951 * 417, interdit au modèle de le calculer, et attend 9987567 du Calculator. Exécutez-le une fois avec un modèle connu pour être faible en tool calling et une fois avec un modèle solide, en ne changeant rien d'autre. Le modèle faible laisse le Calculator intact ou retourne un blob functionCall ; le modèle solide exécute le Calculator. Ce contraste, sur votre propre instance, est le diagnostic complet en deux exécutions.

Puis observez-le sous charge réelle pendant quelques jours. La fiabilité du tool calling n'est pas binaire selon les entrées. Un modèle qui appelle l'outil sur des prompts propres peut le sauter sur des prompts plus complexes. Loggez, par exécution, si l'outil attendu s'est exécuté, et traitez un taux de saut croissant comme un changement de modèle à investiguer, pas un prompt à modifier. Si vous câblez des agents en production et voulez ça mesuré plutôt que supposé, c'est le type de travail que nous faisons dans agentic systems, et le pilier n8n couvre où le nœud Agent a sa place et où il n'en a pas.

Sources

Chaque affirmation ici trace soit au workflow de reproduction de cette page, soit à un cas rapporté dans le champ sources de la page. Le functionCall émis en texte, avec l'exemple Airtable et le passage à un modèle plus fort comme résolution, vient du thread de la communauté n8n sur l'Agent qui n'appelle pas un outil. La panne de l'outil désactivé avec l'erreur Max iterations (10) reached, sur n8n 2.9.4 et fermé comme impossible à reproduire, est le GitHub issue 26356. La dépendance à la capacité de tool calling du modèle découle de la documentation du Tools Agent, qui indique que le nœud implémente l'interface tool-calling de LangChain. Le cas du petit modèle est le thread du forum développeur NVIDIA sur le modèle nemotron qui retourne des tool calls sous forme de chaînes. La lacune sur les paramètres d'outil, où un nœud d'outil natif ne reçoit pas les arguments du modèle tandis qu'un outil LangChain intégré le fait, est le GitHub issue 15506, et le mécanisme $fromAI() dont il dépend est la documentation n8n sur le fait de laisser le modèle spécifier les paramètres d'outil. Le passage au Tools Agent et le sélecteur de type d'agent disparu sont le rapport auto-hébergé 1.82.2. Les rapports de régression, les cas de description d'outil et d'instruction requise, et la forme générale de la panne sont tirés des threads de la communauté restants listés dans les sources.

Cas rapportés

Laissez votre email, on revient vers vous.