Gemini 3 + AI Agent + Postgres Chat Memory : appels d'outils parallèles stockés sans thought_signature → 400 au tour suivant avec le nœud Vertex (régression après 2.25.7)

Décrivez le problème/l’erreur/la question

Un Agent IA (@n8n/n8n-nodes-langchain.agent) utilisant gemini-3-flash-preview avec Postgres Chat Memory et des outils échoue lors de conversations multi-tours : le tour qui effectue des appels d’outils parallèles réussit, mais le tour suivant échoue avec un 400 du modèle, avant l’exécution de tout outil.

Cause racine : lorsque Gemini 3 retourne des appels de fonction parallèles en une seule étape, n8n persiste les messages IA vers Postgres Chat Memory dont les appels de fonction manquent leur thought_signature (le message d’appel unique ré-émis est stocké avec additional_kwargs: {}). Au tour suivant, cet historique est relu, et le nœud Google Vertex Chat Model le rejette avec un 400 (thought_signature manquante).

Ceci est sensible au point de terminaison et semble être une régression :

  • Google Vertex Chat Model → 400 au tour suivant un tour d’appels parallèles.
  • Google Gemini Chat Model (API consumer) → tolère les mêmes signatures manquantes (pas d’erreur), donc cela masque le bogue.
  • Sur une ancienne version de n8n, le même workflow stockait un unique message d’appel d’outil signé par tour et n’échouait jamais ; après la mise à niveau vers 2.25.7, il stocke les appels parallèles sans signatures et le tour suivant 400 sur Vertex.

Étapes de reproduction (déterministes, ~6 nœuds)

  1. Chat Trigger → AI Agent + Google Vertex Chat Model (gemini-3-flash-preview) + Postgres Chat Memory + 2 outils Code triviale, avec un message système qui force le modèle à appeler les deux outils en parallèle à chaque tour (workflow ci-dessous).
  2. Tour 1 dans un nouveau chat (par exemple hi) : l’agent appelle les deux outils en parallèle → réussit.
  3. Tour 2 (même chat, même texte uniquement) : premier appel LLM → 400 avant l’exécution de tout outil.

En utilisant le nœud Google Gemini Chat Model (consumer) à la place, le même workflow s’exécute correctement pendant plusieurs tours — il tolère les signatures manquantes. Donc l’historique malformé est produit indépendamment du point de terminaison ; seul Vertex applique et rejette.

Mes questions

  1. S’agit-il d’une régression connue dans 2.25.7 dans la façon dont l’Agent IA sérialise les thought_signatures de Gemini vers la mémoire de chat pour les appels d’outils parallèles (appel ré-émis stocké avec additional_kwargs: {}) ?
  2. Quelle version de n8n persiste correctement les signatures d’appels parallèles, afin que je puisse la fixer ?
  3. Y a-t-il une solution de contournement prise en charge autre que le downgrade, l’évitement des appels d’outils parallèles ou la suppression des messages d’appel d’outils de la mémoire entre les tours ?

Quel est le message d’erreur (le cas échéant) ?

Erreur du wrapper n8n sur le nœud Chat Model :

Bad request - please check your parameters

API Google 400 sous-jacente par nœud :

  • Nœud Vertex : l’appel de fonction manque une thought_signature.
  • Nœud Gemini consumer : tolère les signatures manquantes (pas d’erreur). Il ne 400 qu’avec une thought_signature corrompue si une session mélange les points de terminaison (signature générée par Vertex relu via l’API consumer).

Veuillez partager votre workflow

Reproduction minimale (remplacez YOUR_GCP_PROJECT, ajoutez vos identifiants Vertex sur le nœud du modèle et un identifiant Postgres sur le nœud de mémoire — aucune autre donnée nécessaire) :

Partagez la sortie retournée par le dernier nœud

Le tour qui échoue ne atteint jamais le dernier nœud — le premier appel LLM de l’Agent 400. La cause est visible dans les lignes n8n_chat_histories écrites par le tour précédent (un tour d’appel parallèle montré) :

ai   | tool_calls: [tool_a, tool_b]   | additional_kwargs.__gemini_function_call_thought_signatures__: { tool_a_id: "<sig>" }   // seulement 1 sig pour 2 appels
tool | résultat tool_a
ai   | tool_calls: [tool_b]           | additional_kwargs: {}    // <-- appel ré-émis, PAS DE thought_signature
tool | résultat tool_b
ai   | "done"

Avec le nœud Vertex, le tour suivant relisant ceci 400. Avec le nœud Gemini consumer, l’historique identique est stocké mais le tour suivant réussit (les signatures ne sont pas appliquées). Sur la version plus ancienne de n8n, le même tour stockait plutôt un unique message d’appel d’outil consolidé avec sa signature, et les relecures n’échouaient jamais.

Informations sur votre configuration n8n

Version de n8n : 2.25.7 (se reproduit sur n8n Cloud et Docker auto-hébergé 2.25.7 avec le nœud Vertex ; n’a pas reproduit sur une ancienne version auto-hébergée)

Base de données (par défaut : SQLite) : PostgreSQL (Postgres Chat Memory)

Paramètre n8n EXECUTIONS_PROCESS (par défaut : own, main) : par défaut

Exécution de n8n via (Docker, npm, n8n cloud, application de bureau) : n8n Cloud et Docker auto-hébergé

Système d’exploitation : Linux (Docker, VPS) / n8n Cloud

Salut @Ori_Yona

Cela semble être une régression. Tu peux ajouter le texte suivant dans l’invite système :
« Tu DOIS appeler UN SEUL outil par réponse. N’appelle jamais plusieurs outils simultanément. »

Fais-moi savoir si ça fonctionne.

En dernier recours, tu pourrais revenir à la version de n8n antérieure à 2.25.7

Ça ne semble pas fonctionner de façon persistante, et j’aime bien en fait que ça envoie des appels d’outils en parallèle, parce que dans mon flux réel c’est un message intermédiaire pour l’utilisateur pendant qu’on cherche dans la base de connaissances avec des outils SQL, donc ça peut devenir long, et + je crois que c’est plus efficace en termes de tokens.

Y a-t-il un moyen de rétrograder une version n8n cloud ?

Pouvez-vous essayer le menu déroulant ?

@Ori_Yona :white_check_mark: Gérer la mémoire complexe des agents IA et les signatures d’appels d’outils parallèles dans n8n nécessite une connaissance architecturale approfondie, notamment pour déboguer les régressions de l’API Vertex.

:white_check_mark: Si vous cherchez à résoudre ces problèmes de stabilité ou avez besoin d’un expert senior en automatisation pour auditer et optimiser vos flux de travail en production, je vous invite à explorer les capacités de mon agence ici : https://automaelite.com/.

:white_check_mark: Je me spécialise dans la conception, la correction et la mise à l’échelle de systèmes n8n, IA, Make.com et GHL haute performance pour les agences sérieuses.

Je ne peux choisir qu’entre la dernière version stable ou la bêta.
La version bêta ne le résout pas aussi bien.

@Ori_Yona

Puisqu’il s’agit d’une défaillance gérée par le cloud :

  1. Ouvrez un ticket d’assistance via le tableau de bord n8n Cloud.
  2. Indiquez que la version antérieure à 2.25.7 ne pose aucun problème
  3. Mentionnez que vous avez déjà essayé de basculer entre Stable et Beta et que le problème persiste. Cela leur indique qu’il s’agit d’une incohérence de dépendances au niveau de la compilation et non d’une erreur utilisateur, ce qui accélère généralement l’escalade du ticket vers l’équipe d’ingénierie.

Ori, si Stable et Beta échouent tous les deux, le chemin de régression est probablement le mauvais levier maintenant. La prochaine chose qui vaut la peine d’être vérifiée est l’endroit où la signature disparaît : après le tour parallèle-tool réussi, récupère le message assistant stocké de Postgres Chat Memory et rédige le contenu/les arguments de l’outil, en laissant les clés autour de additional_kwargs / tool_calls visibles.

Si cette ligne stockée n’a déjà pas de thought_signature, le ticket de support peut être très spécifique : Vertex rejette la mémoire relue après un tour parallèle-tool car n8n stocke le message IA sans la signature. Peux-tu poster une ligne de message assistant stockée et rédactée d’immédiatement avant le prochain tour défaillant ?

Cela semble être un bogue qui mérite d’être signalé directement sur GitHub - n8n-io/n8n: Fair-code workflow automation platform with native AI capabilities. Combine visual building with custom code, self-host or cloud, 400+ integrations. · GitHub - le nœud Postgres Chat Memory devrait préserver les champs thought_signature lors du stockage des résultats d’appels d’outils parallèles. En tant que solution de contournement en attendant un correctif, vous pouvez essayer de basculer le nœud de mémoire vers « Window Buffer Memory » (en mémoire) - cela évite complètement l’aller-retour Postgres et le nœud Vertex ne rencontrera pas le problème de signature manquante puisque l’historique reste dans le même contexte d’exécution. Ce n’est pas persistant entre les sessions, mais cela fonctionne pour les tours multiples au sein d’une même session.

Voici les lignes stockées de Postgres immédiatement après l’appel d’outil parallèle, confirmant ce qui est dans la base de données avant le prochain appel en échec.

Ligne A (correcte — un message IA avec les deux appels parallèles) :

{
  "type": "ai",
  "content": "Calling tools: tool_a, tool_b",
  "tool_calls": [
    {"id": "ffcd9adc...", "name": "tool_a", "args": {"input": "test"}, "type": "tool_call"},
    {"id": "68f56e2d...", "name": "tool_b", "args": {"input": "test"}, "type": "tool_call"}
  ],
  "additional_kwargs": {
    "signatures": ["", "[REDACTED]", ""],
    "__gemini_function_call_thought_signatures__": {
      "ffcd9adc...": "[REDACTED]"
    }
  }
}

Ligne B (spurieuse — ne devrait PAS exister) :

{
  "type": "ai",
  "content": "Calling tool_b with input: {\"input\":\"test\"}",
  "tool_calls": [
    {"id": "68f56e2d...", "name": "tool_b", "args": {"input": "test"}, "type": "tool_call"}
  ],
  "additional_kwargs": {}
}

Constatations principales :

  1. Un deuxième message IA spécieux pour tool_b seul est écrit dans la base de données — il n’existe pas dans la réponse originale de Gemini. Il est synthétisé parce que messageLog de intermediateStep.action de tool_b est vide dans executeBatch.ts de n8n.
  2. signatures a 3 entrées pour 2 appels d’outil — bug décalage de un.
  3. __gemini_function_call_thought_signatures__ ne contient que l’ID de tool_atool_b complètement absent.
  4. La ligne B a additional_kwargs: {} — complètement vide, aucune signature.

Cela confirme que le problème est dans la couche de sérialisation de n8n, pas dans Gemini. Problème signalé sur GitHub ici : [Bug] AI Agent V3 + Postgres Chat Memory: parallel tool calls write spurious second AI message to DB → malformed Gemini history → HTTP 400 on next turn (regression since 2.25.7) · Issue #32271 · n8n-io/n8n · GitHub

Ori, cette paire de lignes est la preuve utile. La ligne B est la forme de rupture : n8n écrit un deuxième message IA que Gemini n’a pas envoyé, et cette ligne synthétique n’a pas de métadonnées de signature pour rejouer.

Cela garde le problème ciblé : pas la configuration du prompt ou la config Vertex, mais la sérialisation de la mémoire Agent V3/Postgres autour des appels d’outils parallèles. Puisque #32271 est déjà déposé et marqué dans Linear, le seul détail supplémentaire qui vaut la peine d’être ajouté là-bas est le build/runtime exact de n8n Cloud si vous avez quelque chose de plus spécifique que 2.25.7.

@Ori_Yona j’étais dans le département GitHub avant, celui-ci est une ancienne erreur dont je me souviens, ça couvrait les deux cas. Je pensais qu’ils l’avaient corrigée, c’était aussi signalé. HMI, je vais transmettre ça à l’équipe n8n sur Discord

Confirmation sans Chat Memory — se produit également sur le chemin d’exécution en direct (n8n 2.31.5)

J’ajoute un point de données au cas où cela aiderait d’autres personnes qui arrivent ici : j’ai rencontré cette erreur 400 exacte d’appel d’outil parallèle, mais sans aucun nœud Chat Memory dans le flux de travail du tout.

Configuration : AI Agent (@n8n/n8n-nodes-langchain.agent, typeVersion 3.1, ToolsAgent V3) + Google Vertex Chat Model sur gemini-3.5-flash-lite, 2 outils indépendants, pas de mémoire. C’est intermittent — cela échoue uniquement lorsque le modèle décide d’émettre les deux appels d’outil à la même étape (parallèle), et fonctionne quand il arrive à les appeler séquentiellement. La pile d’appels pointe vers ToolsAgent/V3/helpers/executeBatch.ts.

Le correctif qui a fermé le problème GitHub (#32481, livré dans n8n@2.28.4) se trouve sur le chemin d’enregistrement de chat-memory. Puisque je n’ai pas de nœud de mémoire, ce chemin ne s’exécute jamais et je reçois toujours l’erreur 400 — donc pour le cas sans mémoire, l’historique mal formé semble être produit pendant l’exécution batch en direct, et non lors de la persistance. J’ai ajouté le détail au problème GitHub.

Ce qui N’a PAS fonctionné pour moi :

  • Une instruction de message système indiquant au modèle d’appeler les outils un par un — le modèle l’a ignorée et a quand même émis des appels parallèles (erreur 400 à la première exécution).
  • Supprimer/modifier max iterations — aucun effet, l’échec est sans rapport avec le nombre d’itérations.

Ce qui fonctionne :

  • Basculer le modèle de chat vers gemini-2.5-flash — l’erreur disparaît complètement (ce bogue est spécifique à l’exigence thought_signature de Gemini 3.x).
  • Fusionner les deux outils en un seul outil qui retourne les deux ensembles de données — avec un seul outil, le modèle ne peut pas émettre d’appels parallèles, donc le chemin batch défaillant n’est jamais déclenché.

Donc, jusqu’à ce que le chemin d’exécution en direct soit corrigé, les options pratiques sont : rester sur un modèle 2.x pour l’agent, ou fusionner vos outils en un seul.