Postgres Chat Memory: Gemini fallback writes “user” type messages causing “Got unexpected type: user” deserialization error

该问题通常出现在 AI Agent 节点以 Anthropic 为主模型、Google Gemini 为 fallback 模型,并使用 Postgres Chat Memory 持久化会话的场景:Gemini 执行时写入的消息被保存为 type: "user" ,下一次读取同一会话时 LangCh

快速结论:该问题通常出现在 AI Agent 节点以 Anthropic 为主模型、Google Gemini 为 fallback 模型,并使用 Postgres Chat Memory 持久化会话的场景:Gemini 执行时写入的消息被保存为 type: "user",下一次读取同一会话时 LangChain 的反序列化抛出 Got unexpected type: user。优先排查对话记忆表中 Gemini 写出消息的 type 字段,而不是先怀疑模型或网络。

适用环境:n8n 2.27.4、Docker 自托管、Ubuntu 24.04、Node.js v24.16.0、SQLite 默认数据库、regular 执行模式;Issues 调试信息中 database 为 sqlite,而问题涉及 Postgres Chat Memory 节点,两者需注意区分。

最快修复方案:暂无确认的一步修复方案。Issue 中提出的修复思路是在 PostgresChatMemory.ts 的 saveContext 写入前,将 "user" 规范化为 "human"(并可将 "assistant" 映射为 "ai"),但该方案属于讨论中的建议,未被标记为已验证并合并的修复。

注意事项:Issue 已被维护者以“3 个月无近期活动”为由关闭,关闭不代表问题已修复或已确认根因。上述规范化属于代码层修改,需自行承担升级覆盖、回归测试和库兼容性风险;不建议用打 zip 补丁的方式绕过,讨论中也认为该方式风险较高。

问题场景

用户在工作流中使用 n8n 的 AI Agent 节点,主 LLM 配置为 Anthropic,fallback LLM 配置为 Google Gemini,并为该 Agent 接入 Postgres Chat Memory 保存会话历史。当某次执行由 Gemini 负责生成回复后,写入记忆表的消息类型是 "user";同一会话收到下一条消息时,Agent 读取历史记录并反序列化,直接抛出类型错误而失败。

报错原文

Got unexpected type: user

原因分析

根据 Issue 讨论,最可能的原因是:Postgres Chat Memory 在写入时没有规范化消息的 type 字段,Gemini 内部使用的角色名 "user"(与 OpenAI 的角色命名习惯一致)被原样序列化进 Postgres。

LangChain 的 StoredMessage 接口对 type 接受任意字符串,但 @langchain/core 的 mapStoredMessageToChatMessage 反序列化时只处理 "human"、"ai"、"system"、"tool" 和 "generic",因此遇到 "user" 就报 Got unexpected type: user。讨论认为,真正的修复点应在 n8n 聊天记忆层的序列化边界,而不是改动 LangChain 的严格反序列化逻辑。

环境排查

  • 确认 n8n 版本:Issues 中为 2.27.4,其他版本是否有相同行为未验证。
  • 确认部署方式:Docker 自托管,Ubuntu 24.04。
  • 确认 Node.js 版本:v24.16.0。
  • 确认 AI Agent 节点的主 LLM 与 fallback LLM 配置,尤其是 Anthropic 主模型 + Gemini fallback 的组合。
  • 确认 Postgres Chat Memory 节点的表结构与连接配置,检查历史记录中是否存在 type 为 "user" 的记录。
  • 注意 Issues 调试信息里 database 为 sqlite,需核对实际触发错误的会话存储是否确为 Postgres Chat Memory。
  • 确认 @langchain/core 及相关 LangChain 依赖版本,但 Issue 未给出具体版本号,不能据此判断兼容范围。

解决步骤

  1. 在 Postgres Chat Memory 对应的会话表中,定位由 Gemini fallback 执行产生的消息记录,确认其 type 字段为 "user" 而非期望的 "ai"。
  2. 清理或修正已污染的会话记录:把 Gemini 写出的、本应属于 AI 回复的 "user" 记录改为 "ai" 或在确认不影响业务后删除该会话,使下一次读取不再触发反序列化异常。此操作为基于错误原因的推断性应急处理,Issue 中没有明确验证记录。
  3. 可优先尝试的代码层修复:在 packages/nodes-base/nodes/LangChain/ChatMemory/PostgresChatMemory/PostgresChatMemory.ts 的 saveContext 写入 Postgres 前,对消息 type 做规范化,将 "user" 映射为 "human",并将 "assistant" 映射为 "ai",使存储层不依赖各 LLM 提供商的内部角色命名。
  4. 修改后在测试环境重新跑用 Anthropic 主模型 + Gemini fallback 的 AI Agent 工作流,覆盖 fallback 被触发的场景。
  5. 如果无法自行改源码,可关注或重新提交该 Issue,附上复现步骤和记忆表记录,推动在 PostgresChatMemory 节点内落地正式修复。

验证方法

让一次工作流执行由 Gemini fallback 负责回复,然后检查 Postgres Chat Memory 表中对应消息的 type 是否为 "ai"(或规范化后的 "human"/"ai" 映射结果符合预期);再向同一会话发送下一条消息,确认 Agent 读取历史时不再抛出 Got unexpected type: user,且能正常继续对话。

参考来源

n8n-io/n8n #33161

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 33047

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注