拓冰建站拓冰建站
首页 / 资讯中心 / 正文

n8n 生产级聊天机器人实战:Chat Agent 的 Shell + Core + Sub-Agents 多工作流组合模式(n8n-mcp)

n8n 生产级聊天机器人实战Chat Agent 的 Shell Core Sub-Agents 多工作流组合模式n8n-mcp【免费下载链接】n8n-mcpA MCP for Claude Desktop / Claude Code / Windsurf / Cursor to build n8n workflows for you项目地址: https://gitcode.com/GitHub_Trending/n8/n8n-mcp本文是 n8n Agents Skilldata/skills/n8n-agents/中CHAT_AGENT_PATTERNS.md的深度展开核心讲解面向 Slack、Discord、Microsoft Teams、Telegram 及嵌入式 Webhook 聊天等外部聊天入口的多工作流组合架构防循环过滤、Shell 外壳、Agent Core 大脑、Sub-Agent 专家四层如何拆分与协同以及各聊天平台的专属陷阱。读完本文你将掌握一套可直接落地的防死循环 加载态 UX 线程会话 无状态子代理生产级聊天机器人设计方案并能借助 n8n-mcp 提供的 MCP 工具n8n_update_partial_workflow、n8n_get_workflow、validate_workflow、n8n_test_workflow逐节点构建与验证这些工作流。第一条铁律防循环过滤Anti-Loop Filtering任何由聊天触发器发起、且会回复消息的工作流必须在触发器之后立即过滤掉机器人自己的用户 ID否则它会无限触发自身——每一次回复都会触发新的一次运行直到触发速率限制或 n8n 并发保护甚至可能拖垮整个 n8n 实例。这是每一个机器人无论简单还是复杂的最低底线也是 n8n-agents 技能体系中反复强调的聊天机器人无限循环问题的标准解法。优先在触发器层面过滤当触发器原生支持过滤时优先使用触发器级过滤——循环在任何一个下游节点运行之前就被切断。但各平台的语义差异很大务必对照你的 n8n 版本逐一核实平台触发器类型过滤语义Slackn8n-nodes-base.slackTriggeroptions.userIds是排除列表黑名单——列出的用户在工作流运行前被丢弃。把机器人自己的 User ID 放进去。已在触发器源码中验证源码在if (userIds.includes(event.user))时提前 return。Telegramn8n-nodes-base.telegramTriggeradditionalFields.userIds是包含列表白名单——只有列出的用户才能触发。它不是机器人排除过滤器且 Telegram 机器人默认看不到自己的消息因此通常不需要防循环。用白名单把私有机器人限制到特定真人即可。Discord、Teams无没有原生的用户级触发器过滤——必须使用下游的 Filter 节点。Slack 触发器级过滤示例{ parameters: { trigger: [message], channelId: { __rl: true, mode: list, value: CHANNEL_ID }, options: { userIds: {{ [\BOT_USER_ID\] }} } }, type: n8n-nodes-base.slackTrigger }触发器不支持时的兜底首个节点即过滤当触发器不提供可用的排除过滤器时触发器后的第一个节点必须丢弃机器人自己的 ID{ parameters: { conditions: { conditions: [ { leftValue: {{ $json.user }}, rightValue: BOT_USER_ID, operator: { type: string, operation: notEquals } } ] } }, type: n8n-nodes-base.filter }机器人用户 ID 来自你机器人的认证信息中的 API IDSlack 的bot_user_id、Discord 的 application ID、Teams 的botId。何时拆分为 Shell Core Sub-Agents在防循环过滤之外一个简单机器人一个触发器 → 一个 Agent → 一条回复外加过滤器完全可以放在单个工作流里。Shell Core Sub-Agents 的拆分是为生产级健壮性服务的当以下任一条件成立时才值得拆机器人需要加载中状态的 UX打字指示器、reaction、占位消息以及超越单条消息的优雅错误处理机器人被多个聊天入口同时调用比如 Slack 和 Discord 都要存在专业领域Notion 数据库 schema、CRM 自定义字段、Linear 标签Agent 不该把这些内联携带Agent 或其工具会被跨工作流复用。如果以上都不成立保持单个工作流过滤器仍然必须保留。拆分后的形态如下[chat-surface workflow] ──► [agent core workflow] ──► [sub-agent workflows] (the shell) (the brain) (specialists) - 从聊天入口触发 - 无状态 - 每个只负责一个窄领域 - 防循环过滤 - chatInput threadId - 仅 chatInput - 路由 / 事件类型 - 基于 threadId 的内存 - 各自的工具 模型 - 加载态 错误 UX - 工具、子代理 - 渲染回复 - 不关心聊天入口细节完整的三个节点对象示例无状态 Agent Core、Slack 路由 Shell、Notion 领域 Sub-Agent见 EXAMPLES.md——它们是社区版 n8n JSON 片段用于适配而非直接导入凭证 ID、工作流 ID、频道/机器人 ID 均为占位符需用n8n_update_partial_workflow在ai_*输出上执行addNodeaddConnection构建再用n8n_get_workflow和validate_workflow验证。Shell聊天外壳层Shell 接收聊天事件决定是否回应管理 UX调用 Core渲染回复。它不做推理、不用 LLM全是确定性逻辑。按事件类型分流同一个触发器会同时触发消息、reaction、提及、斜杠命令、按钮点击等不同事件。在防循环过滤器之后放一个Switch把每种事件路由到正确的处理器owner message → Execute Workflow: agent-core owner reaction → no-op或一个 reaction 处理器 unknown user → 固定文案回复 slash command: /summary → Execute Workflow: summary-command button click → Execute Workflow: interaction-handler每个 case 都是独立的子工作流因为路由决策和实际工作是不同的关注点不同的模型、超时、内存形态。新增一个斜杠命令 一个 Switch 输出 一个子工作流而不是新的顶层触发器。Slack 专属注意payload 形态随版本演进硬编码路径前务必用一个真实事件验证reactions / mentions 通过 Slack Trigger 以 Events API 事件流入但斜杠命令和 Block Kit 按钮点击通常不会Slack 把这些投递到单独的 Request URL。它们需要通过第二个 Webhook 节点喂给同一个 Switch或使用社区 Socket Mode 节点。斜杠命令暴露command字段Block Kit 交互以type block_actions和actions数组到达。加载状态 UX每个退出路径都要清理用户在没有确认信号时会认为什么都没发生。模式在 Agent 调用前添加加载指示器并在所有退出路径上移除它——包括错误路径。[Trigger] → [Filter bot] → [Switch] → (owner message) → [Add loading reaction] (:spinner:, 等) → [Execute Workflow: Agent core] onError: continueErrorOutput ├── (success) → [Remove reaction] → [Send reply] └── (error) → [Remove reaction] → [Send error message with link]错误路径是最容易遗漏的——没有它指示器会永远挂在那里用户会以为机器人还在工作。Execute Workflow 节点上的onError: continueErrorOutput启用第二个分支详见 n8n-error-handling。对 Discord / Telegram打字指示器是有时间上限的对耗时较长的 Agent先发送一条占位消息再编辑它。线程即会话连续性用聊天入口的线程原语作为记忆的sessionKeyworkflowInputs: { value: { chatInput: {{ $(Filter bot).item.json.text }}, threadId: {{ $(Filter bot).item.json.thread_ts || $(Filter bot).item.json.ts }} } }thread_ts || ts是 Slack 的经典惯用法线程内的回复携带thread_ts指向父消息而父消息只有ts。回退到ts让父消息成为其线程的会话键于是每个线程都是一段全新对话记忆不会跨线程泄漏。**只用用户 ID、频道 ID 或工作区 ID 是错的——它们会串会话。**发送回复时也要指向同一线程otherOptions.thread_ts.replyValues.thread_ts 同一个thread_ts || ts。错误 UX暴露出来不要挂死错误分支发送一条带失败执行链接的简短消息There was a workflow error. https://n8n-host/workflow/id/executions/{{ $execution.id }}$execution.id是错误触发时刻的实时执行 ID。主机地址要跨环境参数化。Agent Core大脑层Agent Core 是一个子工作流声明两个输入chatInput用户消息和threadId聊天入口的线程/会话 ID。它返回 Agent 的最终输出——字符串、结构化对象、或聊天入口专属的信封Block Kit、adaptive card。除 MEMORY.md 之外唯一聊天专属的接线就是把threadId直接接到sessionKeysessionIdType: customKey, sessionKey: {{ $json.threadId }}threadId的流动路径是触发器 →透传节点→ 记忆。绝不能把它放在$fromAI后面——Agent 会伪造一个 UUID这是 SUBWORKFLOW_AS_TOOL.md 反复强调的plumbed 参数原则身份、会话、限额这类确定性值必须由工作流侧注入Agent 不可见、不可改。按执行次变化的上下文用户身份、附加文件放在 Agent 之前的 Set 节点里并模板化进系统提示词见 SYSTEM_PROMPT.md 的 file-handling injection 与 piecing 两节。不要投机性地加 Set 节点——在复用成为现实之前直接内联在systemMessage里就够了。Block Kit / adaptive cards必须搭配 outputParserStructuredBlock Kit / adaptive cards 必须与outputParserStructured配对详见 STRUCTURED_OUTPUT.md。用schemaType: manual 真实 JSON Schema的指导在这里更加严格Block Kit 和 adaptive card 依赖跨 block 类型的oneOf联合类型加上每个 block 内的枚举style等——jsonSchemaExample完全无法表达这些而且会产生自信地错误的 block 树最终被聊天入口拒收。EXAMPLES.md 的 Agent Core 片段给出了一个真实可用的 manual schema 示例header/section/divider三种 block 的oneOf联合并配autoFix: true和独立的 coding-capable 修复模型。Block Kit 信封陷阱Slack 专属当 Agent 返回 Block Kit、你通过 Slack 节点的blocksUi发布时值必须是形如{ blocks: [...] }的对象其中值必须是真实数组——既不是裸数组也不是字符串化的数组✅ {{ { blocks: $(Call Agent core).item.json.output.blocks } }} ❌ {{ $(Call Agent core).item.json.output.blocks }}只传数组会静默失败——Slack 节点接受了输入消息发布出来却没有富内容且没有任何错误或警告。详见 NODE_FAMILY_GOTCHAS.md 的 Slack 章节。Sub-Agents把 Agent 当作工具Sub-Agent 是自己的工作流 自己的 Agent 节点通过.toolWorkflow从路由 Agent 调用。以下情况值得引入领域有一组路由 Agent 不该携带的 schema / 枚举Notion DB 属性、Linear 标签、CRM 字段领域有 5 个工具会塞满路由器的工具列表该能力被多个路由器复用该领域值得用比路由器更便宜/更快的模型。契约无状态Stateless**契约是无状态的。路由器在chatInput中发送完整请求——没有共享记忆没有隐式上下文。必须在工具描述路由器侧**和 **Sub-Agent 的系统提示词被调用侧**两侧同时强化IMPORTANT: This tool is stateless. Send all relevant context in a single message. If you need to create an entry, include ALL required fields upfront.没有这条路由器会假设隐式上下文存在Sub-Agent 则靠猜。其余关于子工作流即工具的接线细节类型化输入、$fromAI映射、plumbed 参数、输出形状契约、Stop and Error与onError: continueErrorOutput的取舍、独立测试→ SUBWORKFLOW_AS_TOOL.md。新鲜 Schema 注入当领域 schema 可能运行时变化时Notion DB 选项会演进、Linear 团队会加标签每次 Sub-Agent 调用都重新拉取而不是硬编码[Execute Workflow Trigger] ↓ [Notion: Get Database] # 拉取实时 schema ↓ [Agent] system prompt template 包含: ## Database Schema {{ $(Get a database).first().json.properties.toJsonString() }}代价是每次调用多一次 API 请求换来的好处是 Sub-Agent 永远不会因为提示词过期而返回 that property doesnt exist。对低并发的聊天助手很划算对高并发热点路径把 schema 缓存到 Data Table 并设置 TTL。EXAMPLES.md 的第三个片段Notion ideas sub-agent正是这个模式的完整实现Get a database在main上先于 Agent 运行properties通过.toJsonString()模板化进系统提示词Sub-Agent 跑在比路由器更便宜的模型上示例为claude-haiku-4.6maxIterations也相应降到 15宽路由器为 50。反模式速查表反模式出错表现修复Shell 顶部没有机器人用户 ID 过滤机器人自己的消息重新触发工作流——无限循环触发器级排除Slackoptions.userIds或首个节点 Filter$json.user ! BOT_USER_ID把机器人 ID 放进 Telegram 的userIds期望排除它是白名单——只有机器人会触发真人全部被挡看起来修好了实际是静默失败Telegram 机器人默认看不到自己的消息userIds只用于给真人放行只在成功路径移除加载指示器任何错误后用户都看到机器人永远思考中onError: continueErrorOutput 两个分支都移除用用户/频道/工作区 ID 做会话键同一频道内不同线程的对话互相串扰使用线程原语Slackthread_ts || ts已需要多入口/子代理/复用时仍用单工作流无法复用、UX 泄漏进推理逻辑、难以隔离测试拆成 Shell Core Sub-Agents仅在需求真实存在时Sub-Agent 读写共享记忆调用方无法推理其行为、无法安全重试Sub-Agent 无状态——完整上下文放chatInputSub-Agent 提示词中硬编码领域 schemaSchema 腐烂Sub-Agent 之后选到无效选项运行时重新拉取并模板化把裸 blocks 数组传给blocksUiSlack 发布空消息无任何错误包装为{ blocks: [...] }真实数组与 n8n-mcp 的工程落地衔接这套模式在本仓库中不仅是一份设计文档还与 MCP 服务器暴露的构建工具链直接对应形成设计 → 构建 → 验证的闭环构建EXAMPLES.md 中的三个节点对象片段按文档说明通过n8n_update_partial_workflow的addNodeaddConnection在ai_*输出上组装而不是一次性整包导入。MCP 工具的分发与 schema 定义见 src/mcp/server.ts 与 src/mcp/handlers-n8n-manager.ts。验证组装后使用n8n_get_workflowmode: structure核对结构再用validate_workflow做校验n8n_test_workflow工具支持对子工作流独立测试schema 位于 src/mcp/handlers-n8n-manager.ts与 SUBWORKFLOW_AS_TOOL.md 中用钉住数据独立测试工具子工作流的建议一致。会话模型仓库的 Chat Trigger 处理器src/triggers/handlers/chat-handler.ts展示了与本文threadId一致的会话思维——它通过crypto.randomUUIDCSPRNG122 位熵生成不可猜测的sessionId并以{ action: sendMessage, sessionId, chatInput }的 payload 结构发送到聊天 Webhooksrc/triggers/handlers/chat-handler.ts、src/triggers/handlers/chat-handler.ts。这印证了本文的核心原则会话键必须稳定、确定、由工作流侧生成并贯穿记忆与工具绝不可交给 Agent 决定。关键参考与延伸阅读本主题在技能体系中的完整上下文本文档的母文档与技能总览data/skills/n8n-agents/SKILL.md三个完整节点对象示例无状态 Agent Core / Slack 路由 Shell / Notion 领域 Sub-AgentEXAMPLES.md工具命名、描述、$fromAI的完整规则TOOLS.md.toolWorkflow的形状与参数映射SUBWORKFLOW_AS_TOOL.md按执行次变化的上下文、文件注入、提示词存储SYSTEM_PROMPT.md解析器配置、autoFix、修复模型STRUCTURED_OUTPUT.md记忆类型、sessionKey持久化MEMORY.mdonError: continueErrorOutput与错误 UXdata/skills/n8n-error-handling/Slack 节点参数形态Block KitNODE_FAMILY_GOTCHAS.mdSlack 章节各入口接收上传文件 / 返回生成文件的机制data/skills/n8n-binary-and-data/高层工作流中的 Agent骨架ai_agent_workflow.md最后一条总结模型看不到你的接线——它看到的是一条系统提示词和一组有名字、有描述的工具。把防循环过滤当作触发器的第一道闸把threadId当作会话的唯一钥匙把每个 Sub-Agent 当作一个无状态的 API大多数机器人行为异常的问题在落地前就会消失。【免费下载链接】n8n-mcpA MCP for Claude Desktop / Claude Code / Windsurf / Cursor to build n8n workflows for you项目地址: https://gitcode.com/GitHub_Trending/n8/n8n-mcp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门