快来看,n8n更新了!生产型AI操作手册:复杂智能体模式

内容来源:https://blog.n8n.io/production-ai-playbook-complex-agent-patterns/
内容总结:
多智能体系统构建指南:从原型到生产级应用的实战策略
核心问题:复杂性悬崖
当AI工作流从单一智能体扩展到多智能体系统时,许多团队会遭遇“复杂性悬崖”——最初干净的概念验证逐渐演变成没人愿意在周五下午调试的混乱系统。问题不在于多智能体系统本身脆弱,而在于大多数团队沿用搭建原型的方式,零散地添加组件,却没有一个架构来支撑整体。每个智能体单独运行正常,但它们之间的交互却制造出难以预测、更难追溯的故障模式。
解决方案:以生产级软件思维构建架构
正确的做法不是回避复杂性,而是用生产级软件的纪律来构建多智能体系统——明确组件边界、定义清晰的接口、隔离故障域、实现独立测试。
架构思维优于提示词工程
在动手连接节点之前,应将问题视为架构挑战而非提示词挑战。从一个复杂任务(如“处理并回复客户支持工单”)开始,分解出每一个子任务:工单分类、知识库检索、账户状态查询、回复起草、政策合规校验、结果路由。然后对每个子任务提出两个问题:
- 这需要大语言模型吗?还是可以用确定性逻辑处理?
- 如果需要大语言模型,是否需要独立的智能体?
这种分解方式会形成一份蓝图,明确哪些是确定性节点、哪些是简单的大语言模型调用、哪些真正需要智能体推理。
多智能体架构模式
模式一:AI Agent Tool——动态委派
通过将第二个智能体配置为工具,让编排智能体在运行时动态决定调用哪个专家。例如,客户运营编排器可根据用户请求,将问题分发给账单智能体、技术支持智能体或账户管理智能体。关键在于工具描述——模糊的描述会导致路由错误,需要精确说明每个专家处理的业务范围及其不处理的内容。
适用场景:路由决策不明确、需要大语言模型推理来判断调用哪个专家的情况。
模式二:子工作流——可复用的智能体组件
当执行路径较为可预测,或同一智能体逻辑需要在多个工作流中复用时,子工作流是更干净的选择。子工作流拥有独立的触发器、逻辑和输出,可以独立测试、跨工作流复用、由不同团队成员分别维护,并支持独立版本控制。
适用场景:可预测的流水线、需要共享的通用组件、以及独立可测试性比动态路由灵活性更重要的场景。
记忆与上下文管理
在多智能体协作中,上下文管理是核心设计决策。太多上下文浪费令牌并降低响应质量,太少则导致智能体信息不足。
记忆类型选择:
- Simple Memory(窗口缓冲):存储最近N条消息,适用于单智能体对话和最近的5-10轮对话足以提供上下文的场景
- 数据库记忆(Postgres、Redis、MongoDB):支持跨会话持久化,适用于客户多次联系、需要记住历史对话的场景
会话ID策略:
- 共享会话ID:编排器和专家共享对话历史
- 隔离会话ID:每个智能体只看到自己的对话历史,避免上下文泄露
- 基于用户的会话ID:使用客户ID作为会话ID,实现跨执行会话的上下文记忆
实用建议: 不要让每个智能体都看到完整的对话历史;对长对话使用摘要记忆;关键事实(如客户等级)不应依赖记忆,而应从系统实时拉取。
智能体循环与迭代推理
某些任务可通过反馈循环让智能体审视并优化自身输出。其模式为:生成初始输出 → 验证(代码节点确定性检查或LLM-as-a-Judge评估)→ 未通过则带着具体错误反馈返回修改 → 循环计数器防止无限运行。
反馈的关键在于具体性——不是笼统地说“再试一次”,而是要给出“你的响应中置信度分数1.5超出有效范围0-1,类别‘misc’不在允许列表中”这样的具体信息。
适用场景:质量波动大的内容生成、需严格匹配结构化模式的数据提取、二次调用大语言模型成本低于坏输出抵达生产环境的成本。
不适用场景:分类任务(首次回答通常最佳)、时间敏感型工作流、可通过确定性后处理修复常见错误的任务。
设计决策
提示链 vs. 智能体委派
提示链是固定顺序的线性流水线,每一步是简单的大语言模型调用,适用于步骤已知且顺序固定的场景。智能体委派让编排智能体在运行时决定下一步操作,适用于步骤依赖输入、需要灵活决策的场景。实践中最好的系统是两者的组合——用提示链处理可预测的部分,用智能体委派处理需要灵活推理的部分。
保持扁平 vs. 拆分工作流
当工作流只有3-5步线性步骤、只有一人维护、逻辑特定于单一用例时保持扁平。当同一逻辑在多处复制、节点超过15-20个难以导航时拆分为子工作流。当输入模糊需要推理、不同子任务需要不同模型或工具时添加多智能体协调。
生产最佳实践
故障处理: 每个智能体或子工作流应拥有独立的错误处理,以结构化错误响应返回(包含success、error类型、消息、尝试次数等字段)。回退策略包括:简化提示词重试、降级到更简单的模型或方法、上报人工审核、返回安全默认响应。务必为每个子工作流和智能体工具调用设置超时。
成本与令牌管理: 多智能体系统的令牌消耗可能是单智能体的10-20倍。应精确定义每个智能体的上下文范围、根据任务选择合适的模型(轻量模型用于分类路由,强大模型用于高级推理)、限制循环迭代次数(2-3次通常足够)、最小化工具描述以降低每次请求的令牌成本、监控并设置令牌消耗告警阈值。
实用技巧
- 先从单个智能体开始构建整个任务,运行正常后再分解
- 工具描述应像API文档一样精确
- 在接入父工作流前,单独测试每个子工作流或专家智能体
- 能用Switch节点进行确定性路由时就别用智能体
- 记录编排智能体的决策日志,便于排查路由错误
- 保持系统提示词聚焦于该智能体的领域
- 每个多智能体工作流都要有“这个智能体失败时怎么办”的答案
- 对智能体配置进行版本管理
生产级系统的标志不是永不失败,而是失败能以可预测的方式被处理,不会引发连锁反应。
中文翻译:
本篇文章是探讨构建可靠AI系统的成熟策略与实践案例系列中的一部分。您可以通过RSS、LinkedIn或X关注《生产级AI实战手册》,第一时间了解新主题的发布动态。如果您是n8n新手,建议从入门指南开始阅读。
复杂性悬崖
您的第一个AI工作流运行得堪称完美。一个代理、一项任务、结果清晰。于是,您增加了第二个代理来处理相关的工作,接着又加入了第三个。您为第一个代理提供了调用第二个代理的工具。您引入了记忆机制,让代理能在不同步骤间共享上下文。您还为边缘情况添加了分支逻辑。然而,在某个时刻,这个最初作为清晰概念验证的系统,变成了一个没人愿意在周五下午去调试的棘手问题。
这就是“复杂性悬崖”,几乎所有超越单代理工作流的团队都会遇到。挑战并不在于多代理系统本身脆弱,而在于大多数团队构建它们的方式与构建第一个原型时如出一辙:在缺乏统一架构支撑的情况下,零散地添加各种组件。每个代理单独运行时都表现良好,但它们之间的交互会产生难以预测、更难以追踪的故障模式。
解决方法并非回避复杂性。复杂的问题需要复杂的解决方案。关键在于,构建多代理系统时,应采用与构建任何生产级软件相同的严谨原则:即组件间有清晰的边界、明确的接口、隔离的故障域,以及独立测试每个部件的能力。
本文将涵盖如何在n8n中实现这一点,从架构决策到您可以即刻应用的、具体的实践模式。
以架构思维思考,而非提示词
在您打开n8n画布并开始连接节点之前,请退后一步,将问题视为一个架构挑战,而非提示词挑战。一个能良好扩展的多代理系统与一个因自身负担而崩溃的系统之间的区别,通常归结为在任何人撰写任何一条系统提示词之前,工作是如何被分解的。
首先,将目标分解为离散的步骤。以一个复杂的任务为例,比如“处理并回复客户支持工单”,将其中涉及的每个子任务都列出来:从分类工单、从知识库中检索相关上下文,到检查客户账户状态、草拟回复、依据公司政策验证回复,再到路由结果。这些子任务中的每一个,都可以成为其自身代理或工作流步骤的候选。
然后,针对每个子任务问自己两个问题。
- 这需要LLM(大语言模型)吗?还是可以用确定性逻辑处理?检查账户状态是一次数据库查询。按类别路由是一个Switch节点。不要用一个简单的节点就能处理得更好的工作来动用代理。(我们曾在《确定性步骤 + AI步骤》一文中详细讨论过这一点。)
- 如果确实需要LLM,它需要自己的代理吗?代理是一个拥有工具访问权限的推理循环。如果子任务只是一个“输入提示,输出响应”的操作(例如总结文档或对文本进行分类),那么一个基础的LLM链会更轻量、更容易控制。请将代理保留给那些需要多步骤推理、工具使用或动态决策的子任务。
这种分解方式为您提供了一份蓝图。您知道哪些部分是确定性节点,哪些是简单的LLM调用,哪些真正需要代理的推理能力。这份蓝图就是您的架构,它确保了系统在成长过程中始终保持可管理性。
使用AI代理工具实现多代理架构
n8n支持一种多代理架构,其中一个代理可以将任务委派给另一个代理。其主要机制是“AI代理工具”,它允许您将第二个代理配置为第一个代理可以调用的一个工具。
以下是其在实践中的运作方式。您有一个协调代理(orchestrator agent),它接收初始输入并决定接下来需要做什么。该协调代理可以访问多个工具,而这些工具中的一个或多个本身就是配置完整的代理,拥有自己的模型、系统提示词和工具集。
示例:一个拥有多个专家的客户运营代理
协调代理收到一个客户请求,并使用其推理能力来决定调用哪位专家。
- 账单专家代理:可以访问账单API,了解退款政策,并被提示处理与支付相关的查询。
- 技术支持专家代理:可以访问知识库和故障排除文档,被提示诊断和解决技术问题。
- 账户管理专家代理:可以访问CRM和账户数据,被提示处理升级、取消和账户变更。
协调代理无需知道如何处理账单的边缘情况或诊断技术问题。它只需充分理解请求,以便将其路由到正确的专家那里,然后将结果返回给用户。每个专家代理都是独立的,拥有自己的系统提示词、自己的工具和自己的模型。如果账单代理开始产生糟糕的响应,您可以调试并修复该代理,而无需触碰其他代理。
工具描述在此处至关重要。协调代理关于调用哪个专家的决策,是由您为每个工具编写的描述所驱动的。模糊的描述会导致路由错误。请具体说明每个专家代理处理什么,以及同样重要的是,它不处理什么。
何时使用此模式: 动态委派,即协调代理需要在运行时推理应该调用哪位专家。当路由决策本身模棱两可,且从LLM的推理中获益比从确定性规则中获益更多时,此模式效果很好。
动手尝试:
练习1:多代理客户路由(AI代理工具)
本节所描述的模式在此工作流模板中提供了端到端的实现。一个协调代理接收客户请求,通过AI代理工具动态委派给账单、技术或账户专家,解析结构化响应,并将模糊或失败的请求路由给人工作升级,最后返回统一的JSON包。
(使用openai/gpt-4.1-mini,但您可以替换为任何支持的模型或提供商)。协调代理和三位专家代理各自拥有自己的“聊天模型”子节点。
curl -X POST "YOUR_WEBHOOK_ENDPOINT_URL" \ -H "Content-Type: application/json" \ -d '{ "requestId": "REQ-001", "customerId": "cust-12345", "customerTier": "pro", "message": "4月15日我的月度订阅被扣了两次费用。你能退还重复收取的费用吗?", "email": "test@example.com" }'
注意:示例使用curl。Windows PowerShell用户可以在WSL中运行它们,替换为Invoke-RestMethod,或使用任何HTTP客户端,如Postman。
子工作流:可复用的代理组件
AI代理工具对于动态委派非常强大,但它并非总是最佳选择。当执行路径更可预测,或者当您需要在多个工作流中复用相同的代理逻辑时,子工作流是更清晰的方法。
“调用n8n工作流工具”允许您将任何n8n工作流打包成一个可供AI代理调用的工具。这个子工作流是一个独立的工作流,拥有自己的触发器、逻辑和输出。父代理像调用其他任何工具一样调用它,传入输入并接收结构化结果。
为什么子工作流优于AI代理工具:
- 独立测试: 每个子工作流都可以单独触发和测试。您无需运行整个父工作流来验证“研究子工作流”是否返回了正确的结果。
- 可复用性: 同一个子工作流可以作为工具在多个父工作流中使用。一个“获取并总结文档”的子工作流,可以为客户支持代理、入职引导代理和内部问答代理提供服务。
- 团队协作: 不同的团队成员可以负责不同的子工作流。理解账单逻辑的人维护账单子工作流;理解知识库的人维护检索子工作流。对其中一个的修改无需与其他人协调。
- 版本控制: 子工作流可以独立进行版本控制。您可以在不触碰父代理的情况下更新“研究子工作流”,并且如果更新导致问题,可以回滚。
示例:使用子工作流代理的内容处理管线
假设您正在构建一个工作流,它接收一个主题,进行研究,撰写草稿,然后审查草稿质量。不要将其构建为一个巨大的代理,而是将其分解为三个子工作流。
- 研究子工作流: 接收一个主题作为输入,搜索相关来源(知识库、网络、内部文档),并返回结构化的研究笔记。此子工作流拥有自己的AI代理,配备搜索和检索工具。
- 写作子工作流: 接收研究笔记和简报作为输入,生成一篇草稿文章。此子工作流使用一个能力强的模型进行生成,并可能包含自己的验证步骤。
- 审阅子工作流: 接收草稿和原始简报作为输入,根据标准(准确性、语气、完整性)评估质量,并返回一个分数和修改建议。这可以使用“LLM作为评判者”模式。
父工作流通过调用研究子工作流来协调整个管线,将其输出传递给写作子工作流,然后将草稿交给审阅子工作流。如果审阅者为草稿打分低于阈值,则连同修改笔记一起循环回写作子工作流。每个部分都是可测试、可替换和可独立维护的。
何时使用此模式: 可预测的管线,即您知道操作的顺序;多个工作流共享的可复用组件;以及任何独立可测试性比动态路由灵活性更重要的场景。
动手尝试:
练习2:内容处理管线(子工作流协调器)
本节所描述的模式以四个工作流的形式提供端到端实现:一个父协调器,它调用三个独立的子工作流。
– 父工作流:内容处理管线。(包含)Webhook,标准化,研究,写作,审阅,评估,IF(质量门控),最终确定,响应。
– 研究子工作流:收集关于该主题的背景笔记。
– 写作子工作流:根据研究和简报,生成大约400字的草稿。
– 审阅子工作流:根据准确性、语气、完整性和清晰度为草稿打分,并在不符合要求时返回修改笔记。
父工作流使用“执行工作流触发器”(Execute Workflow Trigger)的透传模式,通过每个子工作流传递一个共享状态对象,然后运行一个IF检查,要么最终确定草稿(分数达到阈值),要么将草稿连同审阅者的反馈一起循环回写作子工作流。一个revisionCount(修改次数)加maxRevisions(最大修改次数)的上限充当安全出口,确保循环永远运行下去。
(使用openai/gpt-4.1-mini),因此您可以混合使用不同的能力(研究用轻量级模型,写作和审阅用能力更强的模型)而无需触碰父工作流。如果您愿意,也可以替换为任何支持的提供商。
curl -X POST "YOUR_WEBHOOK_ENDPOINT_URL" \ -H "Content-Type: application/json" \ -d '{ "topic": "LLM API的提示缓存", "brief": "解释提示缓存、何时使用它以及成本权衡。约400字,面向API开发者。", "qualityThreshold": 7.5, "maxRevisions": 2 }'
将qualityThreshold设置为一个几乎无法达到的值,例如9.99,然后重新发送。审阅者每次都会给出低于阈值的分数,IF节点会将草稿连同修改笔记路由回写作子工作流,在达到maxRevisions次迭代后,循环会退出并返回hitMaxRevisions: true和qualityPassed: false。在通过和达到最大修改次数这两种情况下,响应包都保持相同的结构,因此您的下游消费者可以依赖一个稳定的合约。
curl -X POST "YOUR_WEBHOOK_ENDPOINT_URL" \ -H "Content-Type: application/json" \ -d '{ "topic": "LLM API的提示缓存", "brief": "解释提示缓存、何时使用它以及成本权衡。约400字,面向API开发者。", "qualityThreshold": 9.99, "maxRevisions": 2 }'
下载练习2的父工作流模板。
记忆与上下文管理
当代理在多个步骤或对话中协同工作时,管理每个代理知道什么成为了核心设计决策。上下文太多,则会浪费Token、降低响应速度,并用无关信息混淆模型。上下文太少,则代理会在缺乏必要信息的情况下做出决策。
n8n提供了几个连接到AI代理节点的记忆子节点,包括用于窗口缓冲记忆的简单记忆,以及基于数据库的选项,如PostgreSQL聊天记忆、Redis聊天记忆和MongoDB聊天记忆。
简单记忆(窗口缓冲)
这是最常用的选择。它存储对话中最近的N条消息,并在每次新请求时将它们作为上下文传递。窗口大小是可配置的,因此您可以控制代理看到多少历史记录。这对于近期上下文最重要的对话式工作流效果很好。其取舍在于,一旦消息移出窗口,代理就会完全忘记它。
何时使用: 单代理对话、支持聊天工作流,以及任何最后5-10次交流能提供足够上下文的场景。
数据库支持的记忆(PostgreSQL, Redis, MongoDB)
对于需要跨会话持久化记忆的工作流,这些选项将对话历史存储在外部数据库中。代理可以回忆来自先前交互的上下文,而不仅仅是当前会话。这使得工作流能够支持客户多次联系支持时,代理应记住之前对话的场景。
何时使用: 多会话工作流、长时间运行的处理流程,以及任何上下文需要在单次执行之外持续存在的场景。
会话ID(多代理记忆的关键)
会话ID决定了代理加载哪个对话历史。默认情况下,每次执行都有自己的会话。但您可以控制它以实现强大的模式。
- 跨代理共享会话ID: 如果您的协调代理和专家代理使用相同的会话ID,它们会共享对话历史。专家代理可以看到用户告诉协调代理的内容。当您希望在委派过程中保持连续性时,这很有用。
- 每个代理的隔离会话ID: 每个代理获取自己的会话ID,因此它只能看到自己的对话历史。这保持了专家代理的专注,并防止了上下文在领域间泄漏。协调代理通过工具调用显式地传递相关上下文,而不是依赖共享记忆。
- 基于用户的会话ID: 使用客户ID或用户ID作为会话ID,以便代理能在多次执行中记住与该特定用户的过去交互。回头的客户能得到有上下文的支持,而无需重新解释他们的问题。
多代理设置的实际指导:
- 积极限定上下文范围。 不要将完整的对话历史传递给每个代理。账单专家代理不需要看到三步骤之前发生的技术故障排查过程。只通过工具调用参数传递相关的内容。
- 对长对话使用摘要记忆。 如果对话经常超过您的窗口缓冲,考虑使用一个摘要步骤,将较旧的消息浓缩成一个摘要。代理看到摘要加上最近的消息,使上下文保持可管理,同时不丢失重要细节。
- 将关键事实存储在记忆之外。 如果存在代理绝对不能忘记的关键信息(客户等级、账户状态、活跃订阅),不要依赖记忆来保存它们。在每次交互开始时,从您的系统中新鲜拉取这些数据,并将其注入系统提示词或上下文中。
动手尝试:
练习3:自我纠正的提取代理(带记忆)
本节所描述的模式在此工作流模板中提供了端到端的实现。一个提取代理将会议笔记解析为严格的JSON模式,以提取行动项(id, title, assignee, deadline, priority, context)。一个以sessionId为键的窗口缓冲记忆子节点,确保代理在同一会话的多次运行中保持一致,因此使用相同的sessionId多次调用工作流会保留ID编号和语气。一个代码节点根据模式验证每个项目,在验证失败时,工作流会带着一个包含特定错误的编号列表循环回代理,以便其进行修改。一个maxAttempts上限在代理无法产生有效输出时退出循环,并将其路由到人工审核。
该模板配对使用了两个独立的状态层。记忆提供了跨会话的连续性(代理记住相同sessionId的先前提取结果),而一个自我纠正循环处理执行内的质量控制(代理在验证失败时修改其输出)。缓冲区保存跨会话对话,而attemptCount和previousExtraction作为循环状态的一部分流经管线。
(使用openai/gpt-4.1-mini,它对此任务效果很好,但您可以替换为任何支持的模型或提供商。)
sessionIdType设置为customKey,键绑定到{{ $('Normalize Request').first().json.sessionId }}。这就是让记忆以用户为作用域而非以执行为作用域的原因。
curl -X POST "YOUR_WEBHOOK_ENDPOINT_URL" \ -H "Content-Type: application/json" \ -d '{ "requestId": "REQ-001", "sessionId": "session-demo-1", "meetingNotes": "同步笔记(4月16日):Sara需要在周五前向Acme发送更新后的定价方案。Marco将在下周二前与法律团队跟进新的主服务协议。将安全审查推到下一个迭代,负责人待定。每个人应在4月24日的规划会议前审阅Q3 OKR草案。", "maxAttempts": 3 }'
使用相同的sessionId和一批新的会议笔记。代理将继续从上一次运行中断的ID编号开始(因此,如果上一次运行产生了AI-001到AI-004,这次运行将从AI-005开始),而不是从AI-001重新开始。
curl -X POST "YOUR_WEBHOOK_ENDPOINT_URL" \ -H "Content-Type: application/json" \ -d '{ "requestId": "REQ-002", "sessionId": "session-demo-1", "meetingNotes": "站会(4月23日):Priya将在周一前为新仪表盘草拟发布公告。Liam需要在本周与设计团队安排重新设计项目的启动会议。将分析审计推迟到下个月。", "maxAttempts": 3 }'
现在切换到一个不同的sessionId,以确认每个会话的隔离性。ID编号应重置为AI-001:
curl -X POST "YOUR_WEBHOOK_ENDPOINT_URL" \ -H "Content-Type: application/json" \ -d '{ "requestId": "REQ-003", "sessionId": "session-demo-fresh", "meetingNotes": "快速同步(4月24日):Alex需要在周五下班前发布API速率限制修复。Jamie将在下周为缓存层起草RFC。", "maxAttempts": 3 }'
设置maxAttempts: 2,解析+验证节点将拒绝第一次尝试,工作流带着验证错误作为反馈循环回提取代理,您将在响应中看到attemptsUsed: 2。代理通常在第二次尝试时恢复,因此预期success: true并提取到一个项目。
curl -X POST "YOUR_WEBHOOK_ENDPOINT_URL" \ -H "Content-Type: application/json" \ -d '{ "requestId": "REQ-004", "sessionId": "session-demo-retry", "meetingNotes": "随想:也许我们应该做点什么。可能有人会。最终。不清楚。", "maxAttempts": 2 }'
将maxAttempts设为1,使用相同的模糊笔记。第一次验证失败立即触发退出分支,响应包与正常路径保持相同的结构,但包含success: false, hitMaxAttempts: true和routedTo: "human_review",以便团队成员可以接手失败的提取操作。下游契约在通过和失败的情况下是稳定的。
curl -X POST "YOUR_WEBHOOK_ENDPOINT_URL" \ -H "Content-Type: application/json" \ -d '{ "requestId": "REQ-005", "sessionId": "session-demo-exit", "meetingNotes": "随想:也许我们应该做点什么。可能有人会。最终。不清楚。", "maxAttempts": 1 }'
提示:如果您想在一次运行中同时看到重试循环触发和达到最大尝试次数后退出,可以临时收紧解析+验证节点中的验证规则(例如,要求每个项目都有一个非待定的截止日期)。在更严格的验证和maxAttempts: 2下,代理通常两次尝试都无法满足规则,因此您会看到attemptsUsed: 2和hitMaxAttempts: true。
代理循环与迭代推理
某些任务受益于让代理在将输出传递到下游之前审查并优化自己的输出。不是一次生成响应就指望它足够好,而是给代理一个反馈循环,让它能够生成、评估和修改,直到输出达到您的质量标准。
模式:自我纠正的代理循环
- 代理生成其初始输出(草稿回复、数据提取、带有推理的分类结果)。
- 一个验证步骤根据质量标准检查输出。这可以是一个带有确定性检查的代码节点、一次“LLM作为评判者”评估,或两者兼有。
- 如果输出通过,则继续向下游传递。如果失败,代理会收到反馈(哪里错了,要修复什么)并生成修改后的输出。
- 一个循环计数器确保这不会永远运行下去。在2-3次尝试后,如果输出仍未通过,则路由到备用路径(人工审核、更简单的模型、模板化回复)。
在n8n中,循环通过AI代理节点、一个验证代码节点和一个IF节点(要么将输出向前路由,要么循环回去)的组合来工作。使用一个Set节点来跟踪尝试次数并在每次循环时递增它。IF节点检查两个条件:输出是否通过了验证,以及尝试次数是否超过了最大值。任一条件都会退出循环。
// 循环计数器和退出检查
const maxAttempts = 3;
const currentAttempt = $input.first().json.attemptCount || 1;
const validationPassed = $input.first().json.isValid;
return {
shouldContinue: !validationPassed && currentAttempt < maxAttempts,
attemptCount: currentAttempt + 1,
output: $input.first().json.output,
feedback: $input.first().json.validationErrors
};
反馈验证结果
使自我纠正生效的关键在于告诉代理哪里错了。不要只说“再试一次”。要在下一次提示中包括具体的验证错误。例如,类似这样的内容:“您之前的回复列出的置信度为1.5,这超出了0-1的有效范围。类别‘misc’不在允许列表中。请修改您的回复以修复这些问题。”具体的反馈会产生有针对性的修复。
何时使用代理循环:
- 质量波动的内容生成(草拟、总结、翻译)
- 输出必须符合严格模式的结构化数据提取
- 任何第二次LLM调用的成本低于糟糕输出到达生产环境的成本的场景
何时跳过代理循环:
- 模型的第一个答案通常就是最佳答案的分类任务(重试很少能改进分类)
- 对时间敏感的、2-3次循环迭代带来的额外延迟是不可接受的工作流
- 通过确定性后处理可以修复常见错误而无需重新调用模型的任务(例如,对结构化输出进行正则表达式清理)
动手尝试:
练习4:自我评论的写作循环(写手+评论家)
本节所描述的模式在此工作流模板中提供了端到端的实现。一个写手代理根据主题和简报草拟一篇文章。一个评论家代理根据准确性、清晰度、相关性和简洁性为草稿打分,并返回具体的问题。如果分数低于minScore,工作流会带着评论家列举的问题循环回写手,以便其进行修改。一个maxIterations上限在草稿无法达到标准时退出循环,并将其路由到人工审核。
这是一个双代理合作的循环:写手和评论家有独立的系统提示词、独立的角色和独立的聊天模型子节点(因此如果您愿意,可以为写手使用一个更便宜的模型,为评论家使用一个更强的模型)。写手从不给自己打分,评论家也从不写作。这种分离保持了每个代理提示词的专注性,并使故障模式易于诊断。
(使用openai/gpt-4.1-mini),但您可以混合使用不同的能力(写手用轻量级模型,评论家用更强的模型)而无需触碰任何其他部分。
curl -X POST "YOUR_WEBHOOK_ENDPOINT_URL" \ -H "Content-Type: application/json" \ -d '{ "requestId": "REQ-001", "topic": "LLM API的提示缓存", "brief": "用大约350字向后端开发者解释提示缓存。涵盖它是什么、何时使用它以及成本权衡。", "minScore": 7.5, "maxIterations": 3 }'
将minScore设为9.5,然后重新发送。评论家每次都会给出低于阈值的分数,IF节点会将草稿连同列举的问题路由回写手,在达到maxIterations次迭代后,循环会退出并返回success: false, hitMaxIterations: true和routedTo: "human_review"。最后的原始草稿和未解决的评论家反馈会保留在响应中,以便人工审阅者可以接替循环放弃的地方继续工作。
curl -X POST "YOUR_WEBHOOK_ENDPOINT_URL" \ -H "Content-Type: application/json" \ -d '{ "requestId": "REQ-002", "topic": "LLM API的提示缓存", "brief": "用大约350字向后端开发者解释提示缓存。涵盖它是什么、何时使用它以及成本权衡。", "minScore": 9.5, "maxIterations": 2 }'
下载练习4的工作流模板。
设计决策
提示链 vs. 代理委派
当您有一个多步骤的AI任务时,有两种根本不同的方式来组织它,选择错误的方式会引入不必要的复杂性或不必要的僵化。
- 提示链是一个线性管线,其中每一步的输出作为下一步的输入。第1步提取关键信息,第2步使用该信息生成草稿,第3步评估草稿。序列在设计时是固定的。每一步都是一个简单的LLM调用(而非一个带有工具的完整代理),工作流控制它们之间的流程。
- 代理委派让协调代理能够决定下一步做什么。代理对输入进行推理,决定调用哪个工具或子代理,处理结果,然后决定下一个行动。序列在运行时基于代理的推理而浮现。
何时使用提示链:
- 步骤事先已知,并且总是以相同顺序执行
- 每一步都有清晰、聚焦的任务(提取,然后生成,然后验证)
- 您想要最大的可预测性和可调试性
- 成本效率很重要,因为每一步只使用它需要的Token,没有代理推理循环的开销
何时使用代理委派:
- 步骤取决于输入,并且可能因执行而异
- 代理需要根据在每一步学到的信息,在多个可能的行动之间做出决定(查阅知识库、检查数据库、调用API)
- 您需要系统处理不适合预定管线的新颖输入
- 任务需要迭代推理,代理在其发现的基础上继续构建
在实践中,最好的系统是结合两者。对工作流中可预测的部分(数据清洗、格式化、最终验证)使用提示链,而对那些真正需要灵活推理的部分(理解模棱两可的请求、选择正确的信息来源)使用代理委派。目标是尽量减少代理推理的范围,使其仅限于需要它的步骤,而保持其余部分确定性和可预测性。
示例:一个混合提示链和代理委派的流程
- 提示链,第1步: 一个基础的LLM调用从传入请求中提取结构化信息(客户姓名、问题类型、紧急程度)。这是一个固定的提取任务,不需要代理推理。
- 代理委派,第2步: 一个代理接收结构化信息并决定如何处理。对于账单问题,它查询账单API。对于技术问题,它搜索知识库。对于账户问题,它查找CRM。代理根据问题类型选择合适的工具。
- 提示链,第3步: 代理的发现结果被输入到一个简单的LLM调用中,该调用遵循模板结构生成回复草稿。固定任务,无需代理推理。
- 确定性,第4步: 一个代码节点验证回复并根据置信度进行路由。
第1步和第3步成本低廉、速度快且可预测。第2步是代理发挥价值的地方。第4步是纯逻辑。每一层都为任务使用了正确的工具。
何时分解工作流(以及何时保持扁平)
并非每个工作流都需要子工作流或多代理层级结构。为一个简单的流程过度设计会增加开销而没有任何益处。这里有一个实用的决策框架。
保持扁平当:
- 工作流有3-5个线性步骤,没有分支
- 只有一个人维护它
- 逻辑特定于一个用例,不太可能被复用
- 您仍在原型设计阶段,架构可能会改变
- 整个工作流能舒适地放在单个画布视图上
分解为子工作流当:
- 您在多个工作流中复制相同的逻辑(将其规范化成一个子工作流)
- 工作流已增长超过15-20个节点,变得难以导航
- 不同部分需要不同的专业知识来维护(账单逻辑 vs. AI提示 vs. API集成)
- 您需要独立测试特定部分,而无需触发整个管线
- 某一部分的故障应与其余部分隔离开
添加多代理协调当:
- 输入是模棱两可的,需要推理来确定正确的处理路径
- 不同的子任务需要根本不同的模型、工具或系统提示词
- 系统需要处理您无法完全提前预见到的新颖任务类型
- 单个代理的上下文窗口在处理所有事情时会溢出
这个过程是自然的:从扁平开始,当您发现自己在重复或难以扩展时提取出子工作流,当路由决策确实从LLM推理中获益时添加多代理委派。抵制住从最复杂的模式开始的冲动。构建您所需要的,然后当复杂性要求时进行重构。
生产最佳实践
处理代理链中的故障
在多代理或多步骤系统中,故障是不可避免的。模型返回垃圾数据。API超时。专家代理被一个不寻常的输入搞糊涂。问题不在于故障是否会发生,而在于系统在故障发生时如何响应。
原则:隔离故障域
每个代理或子工作流都应该有自己的错误处理。如果账单专家代理失败,该故障不应级联到技术支持代理或使协调器崩溃。构建每个组件来处理自己的错误,并返回一个父工作流可以据此行动的结构化故障响应。
模式:结构化的错误响应
不要让代理故障抛出未处理的错误,而是将每个代理或子工作流调用包装在错误处理中,返回一个一致的结构。
// 标准错误响应结构
return {
success: false,
error: {
type: 'agent_failure', // 或 'timeout', 'validation_error', 'api_error'
message: '账单代理无法处理退款请求',
attemptCount: 2,
lastOutput: rawOutput
},
fallback: 'route_to_human'
};
协调器检查success字段并进行相应路由。成功的结果继续通过正常路径。故障根据错误类型路由到备选逻辑。
备用策略:
- 使用更简单的提示重试。 如果代理的响应未达到模式或质量标准,使用一个更受约束、减少代理决策空间的提示进行重试。
- 回退到更简单的模型或方法。 如果一个复杂的代理链在特定输入上持续失败,将其路由到一个范围更窄、单步骤的LLM调用。您用灵活性换取了可靠性。
- 升级到人工审核。 对于关键工作流,始终准备好一条路径,在自动化处理失败时路由到人工处理。这是一条安全网,防止故障产生不良结果。(我们曾在《人工监督》一文中详细讨论过人机协作模式。)
- 返回一个安全默认值。 对于低风险工作流,一个模板化的“我们已收到您的请求,团队成员将跟进”的回复,要好过一个胡编乱造的答案或一次静默失败。
超时很重要。 当一个代理在链中挂起时,整个管线都会停滞。在每次子工作流调用和代理工具调用上设置明确的超时。如果专家代理在您的阈值内(对于大多数基于API的代理,30秒是一个合理的起点)没有响应,将其视为故障并路由到备选逻辑。明确的超时优于无限制的等待。
成本与Token管理
多代理系统会成倍增加Token使用量。每个代理都会为其系统提示词、对话历史、工具描述和推理消耗Token。一个调用三个专家代理(每个都有自己的上下文)的协调器,很容易消耗单代理工作流10-20倍的Token。如果没有审慎的管理,成本的增长速度会超过所解决问题的复杂性。
策略1:为每个代理限定上下文范围
不要给每个代理完整的对话历史。账单专家需要账单相关部分的对话,而不是之前15条关于技术故障排查的消息。使用您的工作流逻辑来提取并仅将相关上下文传递给每个专家。
策略2:为每个任务选择合适的模型
并非每个代理都需要您最强大(也是最昂贵)的模型。对分类、路由和简单的提取任务使用轻量级模型。将您最强大的模型保留给那些真正需要高级推理、细微生成或复杂工具使用的任务。在n8n中,每个代理和LLM节点可以连接到不同的模型,因此这是一个配置决策,而非架构变更。
策略3:限制循环迭代次数
自我纠正循环和代理推理循环应始终有一个最大迭代次数。没有上限,一个困惑的代理可能会无限循环,消耗Token却不产生任何有用的东西。两到三次迭代通常就足够了。如果代理在三次尝试后仍不能产生有效响应,问题可能出在提示或任务定义上,而不是重试次数。
策略4:最小化工具描述
附加到代理上的每个工具都会为每个请求增加Token,因为代理需要在其上下文中包含工具描述来决定使用哪些工具。如果一个代理有15个工具,但大多数请求只用到3个,考虑将其分解为更聚焦的、每个代理拥有更少工具的代理。更少的工具描述意味着更低的每请求Token成本,并且通常能获得更好的工具选择准确性。
策略5:监控并设置预算
跟踪每次工作流执行、每个代理和每次工具调用的Token使用情况。n8n的执行数据包含此信息。为异常的Token消耗设置告警阈值。特定代理Token的突然激增通常表明存在提示问题、循环运行的迭代次数超出预期,或上下文在无限制地增长。
技巧与窍门
- 从单个代理开始,然后分解。 首先将整个任务构建为单个代理。一旦它工作了,确定其推理的哪些部分是可分离的,并将它们提取到专家代理或子工作流中。这种方法确保您在拆分之前理解整个问题,并防止过早分解造成不必要的协调开销。
- 像编写API文档一样编写工具描述。 协调器根据工具描述决定调用哪个专家。将这些描述视为API文档,具体说明工具的作用、它期望的输入、返回的内容以及它不处理什么。“处理账单相关事务”是一个糟糕的描述。“处理退款请求、账单查询和支付争议。需要客户ID和问题描述。返回一个包含已采取行动的结果。”是一个能驱动可靠路由的描述。
- 在连接专家之前先隔离测试它们。 每个子工作流或专家代理在接入父工作流之前,都应能独立正常工作。直接对专家运行测试输入,验证输出,并在组件级别修复问题。调试一个您不确定哪个组件出了问题的多代理系统,比独立调试每个部分要困难得多。
- 在可能时使用确定性路由,在必要时使用代理路由。 如果您能通过一个Switch节点(基于类别字段、工单类型或先前的分类步骤)来确定调用哪个专家,那就这么做,而不是让代理来决定。确定性路由更快、更便宜,并且永远不会因为误解描述而将请求路由到错误的专家。基于代理的路由适用于输入确实模棱两可,且分类无法简化为显式规则的情况。
- 记录协调器的推理过程。 当协调器决定调用某个专家时,记录该决定以及触发它的输入。这创建了一个审计追踪,对于调试错误路由非常宝贵。如果协调器一直将账单问题发送给技术支持代理,日志会向您展示模式,以便您可以修复工具描述或系统提示词。
- 保持系统提示词的聚焦性。 一个专家代理应该有一个涵盖其领域且不涉及其它领域的系统提示词。不要包含关于“乐于助人”的一般性指示、每种可能输出类型的格式化规则,或关于更广泛系统的上下文。聚焦的系统提示词能产生更好的结果并消耗更少的Token。
- 设计优雅降级。 每个多代理工作流都应有一个针对“如果这个代理失败了会发生什么?”的答案。如果答案是“整个系统都崩溃了”,请添加备选逻辑。生产级系统的标志不是它从不失败,而是故障能被可预测地处理并且不会产生级联效应。
- 对您的代理配置进行版本控制。 当您更改系统提示词、更换模型或修改工具集时,跟踪该更改。多代理系统有很多活动部件,性能退化可能源自其中任何一个。如果没有版本控制,您只能猜测是哪个更改导致了问题。
下一步内容
复杂的代理模式为您提供了架构能力,来处理高级AI任务,而不会创建一个无法维护的系统。通过将问题分解为专家代理、通过子工作流组合逻辑、审慎地管理记忆并面向故障进行构建,您将获得一个能与您的用例一起扩展,而不是因自身负担而崩溃的系统。
在下一篇文章中,我们将涵盖“扩展代理能力”——如何用您现有技术栈和更广泛生态系统中的工具来装备您的代理,使它们能够与您的团队所依赖的工具和服务一起成长。
本篇文章是探讨构建可靠AI系统的成熟策略与实践案例系列的一部分。在此处了解《生产级AI实战手册》中已有哪些主题,或通过RSS、LinkedIn或X第一时间了解新主题的添加动态。
参考文献
英文来源:
This post is part of a series that explores proven strategies and practical examples for building reliable AI systems. Find out when new topics are added to the Production AI Playbook via RSS, LinkedIn or X. If you are new to n8n, start with the introduction.
The Complexity Cliff
Your first AI workflow worked beautifully. One agent, one task, clean results. So you added a second agent to handle a related job, then a third. You gave the first agent a tool to call the second. You introduced memory so the agents could share context across steps. You added branching logic for edge cases. And somewhere along the way, the system that started as a clean proof of concept turned into something nobody wants to debug on a Friday afternoon.
This is the complexity cliff, and it hits nearly every team that moves beyond single-agent workflows. The challenge isn't that multi-agent systems are inherently fragile. It's that most teams build them the same way they built their first prototype, adding pieces incrementally without an architecture to hold them together. Each agent works fine in isolation, but the interactions between them create failure modes that are hard to predict and harder to trace.
The fix isn't to avoid complexity. Complex problems require complex solutions. The fix is to build your multi-agent systems with the same discipline you'd bring to any production software, which means clear boundaries between components, explicit interfaces, isolated failure domains, and the ability to test each piece independently.
This post covers how to do that in n8n, from architecture decisions to concrete patterns you can apply today.
Thinking in Architecture, Not Prompts
Before you open the n8n canvas and start connecting nodes, step back and think about the problem as an architecture challenge rather than a prompting challenge. The difference between a multi-agent system that scales and one that collapses under its own weight usually comes down to how the work was decomposed before anyone wrote a single system prompt.
Start by breaking the goal into discrete steps. Take a complex task like "process and respond to customer support tickets" and map out every sub-task involved, from classifying the ticket and retrieving relevant context from the knowledge base, to checking the customer's account status, drafting a response, verifying the response against company policy, and routing the result. Each of those sub-tasks is a candidate for its own agent or workflow step.
Then ask two questions about each sub-task.
Does this need an LLM, or can deterministic logic handle it? Checking account status is a database lookup. Routing by category is a Switch node. Don't use an agent for work that a simple node handles better. (We covered this in detail in the Deterministic Steps + AI Steps post.)
If it does need an LLM, does it need its own agent? An agent is a reasoning loop with access to tools. If the sub-task is a single prompt-in, response-out operation (like summarizing a document or classifying text), a basic LLM chain is lighter weight and easier to control. Reserve agents for sub-tasks that require multi-step reasoning, tool use, or dynamic decision-making.
This decomposition gives you a blueprint. You know which pieces are deterministic nodes, which are simple LLM calls, and which genuinely need agent reasoning. That blueprint is your architecture, and it's what keeps the system manageable as it grows.
Multi-Agent Architectures with the AI Agent Tool
n8n supports multi-agent architectures where one agent can delegate tasks to another. The primary mechanism is the AI Agent Tool, which lets you configure a second agent as a tool that the first agent can call.
Here's how this works in practice. You have an orchestrator agent, the one that receives the initial input and decides what needs to happen. That orchestrator has access to several tools, and one or more of those tools are themselves fully configured agents with their own models, system prompts, and tool sets.
Example: A customer operations agent with specialists
The orchestrator receives a customer request and uses its reasoning to determine which specialist to engage.
- A billing agent has access to the billing API, knows the refund policy, and is prompted to handle payment-related inquiries
- A technical support agent has access to the knowledge base and troubleshooting documentation, prompted to diagnose and resolve technical issues
- A account management agent has access to the CRM and account data, prompted to handle upgrades, cancellations, and account changes
The orchestrator doesn't need to know how to handle billing edge cases or diagnose technical problems. It needs to understand the request well enough to route it to the right specialist, then relay the result back to the user. Each specialist agent is self-contained, with its own system prompt, its own tools, and its own model. If the billing agent starts producing poor responses, you debug and fix that agent without touching the others.
The tool description is critical here. The orchestrator's decision about which specialist to call is driven by the descriptions you write for each tool. Vague descriptions lead to misrouting. Be specific about what each specialist handles and, just as importantly, what it doesn't handle.
When to use this pattern: Dynamic delegation, where the orchestrator needs to reason about which specialist to engage at runtime. This works well when the routing decision is ambiguous and benefits from LLM reasoning rather than deterministic rules.
Try it yourself
Exercise 1: Multi-Agent Customer Router (AI Agent Tool)
The pattern described in this section is provided end-to-end in this workflow template. An orchestrator agent receives a customer request, dynamically delegates to a billing, technical, or account specialist via the AI Agent Tool, parses the structured response, and routes ambiguous or failed requests to human escalation before returning a unified JSON envelope.
openai/gpt-4.1-mini
, but you can swap in any supported model or provider). The orchestrator and each of the three specialists has its own Chat Model sub-node.
curl -X POST "YOUR_WEBHOOK_ENDPOINT_URL" \ -H "Content-Type: application/json" \ -d '{ "requestId": "REQ-001", "customerId": "cust-12345", "customerTier": "pro", "message": "I was charged twice for my monthly subscription on April 15. Can you refund the duplicate charge?", "email": "test@example.com" }'
Note: Examples use curl
. Windows PowerShell users can run them in WSL, swap in Invoke-RestMethod
, or use any HTTP client like Postman.
Sub-workflows as Reusable Agent Components
The AI Agent Tool is powerful for dynamic delegation, but it's not always the right choice. When the execution path is more predictable, or when you need the same agent logic across multiple workflows, sub-workflows are the cleaner approach.
The Call n8n Workflow Tool lets you package any n8n workflow as a tool that an AI agent can call. The sub-workflow is a standalone workflow with its own trigger, logic, and output. The parent agent calls it like any other tool, passing inputs and receiving structured results.
Why sub-workflows over the AI Agent Tool - Independent testing: Each sub-workflow can be triggered and tested on its own. You don't need to run the entire parent workflow to verify that the research sub-workflow returns good results.
- Reusability: The same sub-workflow can be used as a tool in multiple parent workflows. A "fetch and summarize documentation" sub-workflow might serve a customer support agent, an onboarding agent, and an internal Q&A agent.
- Team collaboration: Different team members can own different sub-workflows. The person who understands billing logic maintains the billing sub-workflow. The person who understands the knowledge base maintains the retrieval sub-workflow. Changes to one don't require coordination with the others.
- Version control: Sub-workflows can be versioned independently. You can update the research sub-workflow without touching the parent agent, and roll back if the update causes problems.
Example: A content pipeline with sub-workflow agents
Say you're building a workflow that takes a topic, researches it, writes a draft, and reviews the draft for quality. Instead of building this as one massive agent, break it into three sub-workflows.- Research sub-workflow: Takes a topic as input, searches relevant sources (knowledge base, web, internal docs), and returns structured research notes. This sub-workflow has its own AI agent with search and retrieval tools.
- Writer sub-workflow: Takes research notes and a brief as input, generates a draft article. This sub-workflow uses a capable model for generation and might include its own validation step.
- Reviewer sub-workflow: Takes the draft and the original brief as input, evaluates quality against criteria (accuracy, tone, completeness), and returns a score with revision suggestions. This could use an LLM-as-a-Judge pattern.
The parent workflow orchestrates the pipeline by calling the research sub-workflow, passing its output to the writer, and then handing the draft to the reviewer. If the reviewer scores the draft below threshold, loop back to the writer with the revision notes. Each piece is testable, replaceable, and maintainable on its own.
When to use this pattern: Predictable pipelines where you know the sequence of operations, reusable components that multiple workflows share, and any scenario where independent testability matters more than dynamic routing flexibility.
Try it yourself
Exercise 2: Content Pipeline (Subworkflow Orchestrator)
The pattern described in this section is provided end-to-end as four workflows: a parent orchestrator that calls three independent subworkflows.
– Parent: Content Pipeline. Webhook, Normalize, Research, Writer, Reviewer, Evaluate, IF (Quality Gate), Finalize, Respond.
– Research subworkflow. Gathers background notes on the topic.
– Writer subworkflow. Produces a draft of roughly 400 words from the research and brief.
– Reviewer subworkflow. Scores the draft on accuracy, tone, completeness, and clarity, and returns revision notes when it falls short.
The parent threads a shared state object through each subworkflow using the Execute Workflow Trigger in passthrough mode, then runs an IF check that either finalizes the draft (score meets threshold) or loops it back to the Writer with the Reviewer's feedback. A revisionCount
plus maxRevisions
cap acts as a safety exit so the loop never runs forever.
openai/gpt-4.1-mini
), so you can mix capabilities (lighter model for Research, more capable model for Writer and Reviewer) without touching the parent. Swap in any supported provider if you prefer.
curl -X POST "YOUR_WEBHOOK_ENDPOINT_URL" \ -H "Content-Type: application/json" \ -d '{ "topic": "Prompt caching for LLM APIs", "brief": "Explain prompt caching, when to use it, and the cost tradeoffs. ~400 words for API developers.", "qualityThreshold": 7.5, "maxRevisions": 2 }'
qualityThreshold
to a near-unreachable value like 9.99 and resend. The Reviewer will score below threshold on every pass, the IF node will route the draft back to the Writer with revision notes, and after maxRevisions
iterations the loop exits with hitMaxRevisions: true
and qualityPassed: false
. The response envelope keeps the same shape in both the pass and max-revisions cases, so your downstream consumers can rely on a stable contract.
curl -X POST "YOUR_WEBHOOK_ENDPOINT_URL" \ -H "Content-Type: application/json" \ -d '{ "topic": "Prompt caching for LLM APIs", "brief": "Explain prompt caching, when to use it, and the cost tradeoffs. ~400 words for API developers.", "qualityThreshold": 9.99, "maxRevisions": 2 }'Download the Exercise 2 parent workflow template
Memory and Context Management
When agents work together across multiple steps or conversations, managing what each agent knows becomes a core design decision. Too much context and you waste tokens, slow down responses, and confuse the model with irrelevant information. Too little context and the agent makes decisions without the information it needs.
n8n provides several memory sub-nodes that connect to the AI Agent node, including Simple Memory for window buffer memory and database-backed options like Postgres Chat Memory, Redis Chat Memory, and MongoDB Chat Memory.
Simple Memory (Window Buffer)
The most common choice. It stores the last N messages in the conversation and passes them as context with each new request. The window size is configurable, so you control how much history the agent sees. This works well for conversational workflows where recent context matters most. The trade-off is that once a message falls outside the window, the agent forgets it entirely.
When to use it: Single-agent conversations, support chat workflows, any scenario where the last 5-10 exchanges provide sufficient context.
Database-backed memory (Postgres, Redis, MongoDB)
For workflows that need persistent memory across sessions, these options store conversation history in an external database. The agent can recall context from previous interactions, not just the current session. This enables workflows where a customer contacts support multiple times and the agent should remember prior conversations.
When to use it: Multi-session workflows, long-running processes, any scenario where context needs to survive beyond a single execution.
Session IDs (the key to multi-agent memory)
Session IDs determine which conversation history an agent loads. By default, each execution gets its own session. But you can control this to enable powerful patterns.
- Shared session ID across agents: If your orchestrator and specialist agents use the same session ID, they share conversation history. The specialist can see what the user told the orchestrator. This is useful when you want continuity across the delegation.
- Isolated session IDs per agent: Each agent gets its own session ID, so it only sees its own conversation history. This keeps specialist agents focused and prevents context leakage between domains. The orchestrator passes relevant context explicitly through the tool call rather than relying on shared memory.
- User-based session IDs: Use a customer ID or user ID as the session ID so the agent remembers past interactions with that specific user across multiple executions. A returning customer gets contextual support without having to re-explain their issue.
Practical guidance for multi-agent setups - Scope context aggressively. Don't pass the full conversation history to every agent. The billing specialist doesn't need to see the technical troubleshooting that happened three steps ago. Pass only what's relevant through the tool call parameters.
- Use summary memory for long conversations. If conversations regularly exceed your window buffer, consider using a summarization step that condenses older messages into a summary. The agent sees the summary plus recent messages, keeping context manageable without losing important details.
- Store key facts outside of memory. If there are critical pieces of information the agent must never forget (customer tier, account status, active subscriptions), don't rely on memory to preserve them. Pull that data fresh from your systems at the start of each interaction and inject it into the system prompt or context.
Try it yourself
Exercise 3: Self-Correcting Extraction Agent (with Memory)
The pattern described in this section is provided end-to-end in this workflow template. An extraction agent parses meeting notes into a strict JSON schema for action items (id, title, assignee, deadline, priority, context). A Window Buffer Memory sub-node keyed on sessionId
keeps the agent consistent across runs in the same session, so calling the workflow multiple times with the same sessionId
preserves id numbering and tone. A Code node validates each item against the schema, and on validation failure the workflow loops back to the agent with a numbered list of the specific errors so it can revise. A maxAttempts
cap exits the loop and routes to human review when the agent cannot produce valid output.
The template pairs two independent state layers. Memory provides cross-session continuity (the agent remembers prior extractions for the same sessionId
), while a self-correcting loop handles within-execution quality control (the agent revises its output when validation fails). The buffer holds the cross-session conversation, and attemptCount
plus previousExtraction
flow through the pipeline as part of the loop state.
openai/gpt-4.1-mini
, which works well for this task, but you can swap in any supported model or provider.
sessionIdType
is set to customKey
with the key bound to {{ $('Normalize Request').first().json.sessionId }}
. This is what makes the memory user-scoped rather than execution-scoped.
curl -X POST "YOUR_WEBHOOK_ENDPOINT_URL" \ -H "Content-Type: application/json" \ -d '{ "requestId": "REQ-001", "sessionId": "session-demo-1", "meetingNotes": "Sync notes (April 16): Sara to send updated pricing deck to Acme by Friday. Marco will follow up with the legal team about the new MSA before next Tuesday. Push the security review to next sprint, assignee TBD. Everyone should review the Q3 OKRs draft before our planning session on April 24.", "maxAttempts": 3 }'
sessionId
and a fresh batch of meeting notes. The agent will continue id numbering from where step 4 left off (so if step 4 produced AI-001 through AI-004, this run will start at AI-005) instead of restarting at AI-001.
curl -X POST "YOUR_WEBHOOK_ENDPOINT_URL" \ -H "Content-Type: application/json" \ -d '{ "requestId": "REQ-002", "sessionId": "session-demo-1", "meetingNotes": "Standup (April 23): Priya will draft the launch announcement for the new dashboard by Monday. Liam to schedule a kickoff with the design team for the redesign project this week. Defer the analytics audit to next month.", "maxAttempts": 3 }'
Now switch to a different sessionId
to confirm the per-session isolation. Id numbering should reset to AI-001:
curl -X POST "YOUR_WEBHOOK_ENDPOINT_URL" \ -H "Content-Type: application/json" \ -d '{ "requestId": "REQ-003", "sessionId": "session-demo-fresh", "meetingNotes": "Quick sync (April 24): Alex to ship the API rate-limit fix before EOD Friday. Jamie will draft the RFC for the caching layer next week.", "maxAttempts": 3 }'
maxAttempts: 2
, the Parse + Validate node will reject the first attempt, the workflow loops back through the Extraction Agent with the validation errors as feedback, and you'll see attemptsUsed: 2
in the response. The agent usually recovers on the second pass, so expect success: true
with one extracted item.
curl -X POST "YOUR_WEBHOOK_ENDPOINT_URL" \ -H "Content-Type: application/json" \ -d '{ "requestId": "REQ-004", "sessionId": "session-demo-retry", "meetingNotes": "Random thoughts: maybe we should do something. someone might. eventually. unclear.", "maxAttempts": 2 }'
maxAttempts
to 1 with the same ambiguous notes. The first failed validation immediately trips the exit branch, and the response envelope keeps the same shape as the happy path but with success: false
, hitMaxAttempts: true
, and routedTo: "human_review"
so a teammate can pick up the failed extraction. The downstream contract is stable across both pass and failure cases.
curl -X POST "YOUR_WEBHOOK_ENDPOINT_URL" \ -H "Content-Type: application/json" \ -d '{ "requestId": "REQ-005", "sessionId": "session-demo-exit", "meetingNotes": "Random thoughts: maybe we should do something. someone might. eventually. unclear.", "maxAttempts": 1 }'
Tip: if you want to see both the retry loop firing AND the max-attempts exit in a single run, temporarily tighten the validation rules in the Parse + Validate node (for example, require every item to have a non-TBD deadline). With stricter validation and maxAttempts: 2
, the agent often can't satisfy the rule on either attempt, so you'll see attemptsUsed: 2
along with hitMaxAttempts: true
.
Agent Loops and Iterative Reasoning
Some tasks benefit from letting an agent review and refine its own output before passing it downstream. Instead of generating a response once and hoping it's good enough, you give the agent a feedback loop that lets it generate, evaluate, and revise until the output meets your quality bar.
Pattern: Self-correcting agent loop- The agent generates its initial output (a draft response, a data extraction, a classification with reasoning).
- A validation step checks the output against quality criteria. This could be a Code node with deterministic checks, an LLM-as-a-Judge evaluation, or both.
- If the output passes, it continues downstream. If it fails, the agent receives the feedback (what was wrong, what to fix) and generates a revised output.
- A loop counter ensures this doesn't run forever. After 2-3 attempts, if the output still doesn't pass, route to a fallback path (human review, simpler model, templated response).
In n8n, the loop works through a combination of the AI Agent node, a validation Code node, and an IF node that either routes the output forward or loops back. Use a Set node to track the attempt count and increment it on each loop. The IF node checks two conditions, whether the output passed validation and whether the attempt count exceeded the maximum. Either condition exits the loop.
JavaScript
// Loop counter and exit check const maxAttempts = 3; const currentAttempt = $input.first().json.attemptCount || 1; const validationPassed = $input.first().json.isValid; return { shouldContinue: !validationPassed && currentAttempt < maxAttempts, attemptCount: currentAttempt + 1, output: $input.first().json.output, feedback: $input.first().json.validationErrors };
Feeding back the validation result
The key to making self-correction work is telling the agent what went wrong. Don't just say "try again." Include the specific validation errors in the next prompt. For example, something like "Your previous response listed a confidence score of 1.5, which is outside the valid range of 0-1. The category 'misc' is not in the allowed list. Revise your response to fix these issues." Specific feedback produces targeted fixes.
When to use agent loops:
- Content generation where quality varies (drafting, summarizing, translating)
- Structured data extraction where the output must conform to a strict schema
- Any task where the cost of a second LLM call is lower than the cost of a bad output reaching production
When to skip agent loops: - Classification tasks where the model's first answer is usually its best answer (retrying rarely improves classification)
- Time-sensitive workflows where the added latency of 2-3 loop iterations is unacceptable
- Tasks with deterministic post-processing that can fix common errors without re-invoking the model (like regex cleanup on a structured output)
Try it yourself
Exercise 4: Self-Critiquing Writer Loop (Writer + Critic)
The pattern described in this section is provided end-to-end in this workflow template. A Writer Agent drafts an article from a topic and brief. A Critic Agent scores the draft on accuracy, clarity, relevance, and conciseness, and returns specific issues. If the score is below minScore
, the workflow loops back to the Writer with the critic's enumerated issues so it can revise. A maxIterations
cap exits the loop and routes to human review when the draft cannot meet the bar.
This is a two-agent cooperating loop: the Writer and Critic have separate system prompts, separate roles, and separate Chat Model sub-nodes (so you can use a cheaper model for the Writer and a stronger one for the Critic if you want). The Writer never scores its own work, and the Critic never writes. That separation keeps each agent's prompt focused and makes the failure modes easy to diagnose.
openai/gpt-4.1-mini
for both, but you can mix capabilities (lighter model for the Writer, stronger one for the Critic) without touching anything else.
curl -X POST "YOUR_WEBHOOK_ENDPOINT_URL" \ -H "Content-Type: application/json" \ -d '{ "requestId": "REQ-001", "topic": "Prompt caching for LLM APIs", "brief": "Explain prompt caching in roughly 350 words for backend developers. Cover what it is, when to use it, and the cost tradeoffs.", "minScore": 7.5, "maxIterations": 3 }'
minScore
to 9.5 and resend. The Critic will score below threshold on every pass, the IF node will route the draft back to the Writer with the enumerated issues, and after maxIterations
iterations the loop exits with success: false
, hitMaxIterations: true
, and routedTo: "human_review"
. The last raw draft and the unresolved critic feedback are preserved on the response so a human reviewer can pick up where the loop gave up.
curl -X POST "YOUR_WEBHOOK_ENDPOINT_URL" \ -H "Content-Type: application/json" \ -d '{ "requestId": "REQ-002", "topic": "Prompt caching for LLM APIs", "brief": "Explain prompt caching in roughly 350 words for backend developers. Cover what it is, when to use it, and the cost tradeoffs.", "minScore": 9.5, "maxIterations": 2 }'Download the Exercise 4 workflow template
Design Decisions
Prompt Chaining vs. Agent Delegation
When you have a multi-step AI task, there are two fundamentally different ways to structure it, and choosing the wrong one creates unnecessary complexity or unnecessary rigidity.
Prompt chaining is a linear pipeline where each step's output feeds the next step's input. Step 1 extracts key information, Step 2 uses that information to generate a draft, Step 3 evaluates the draft. The sequence is fixed at design time. Each step is a simple LLM call (not a full agent with tools), and the workflow controls the flow between them.
Agent delegation gives the orchestrating agent the ability to decide what to do next. The agent reasons about the input, decides which tool or sub-agent to call, processes the result, and decides the next action. The sequence emerges at runtime based on the agent's reasoning.
When to use prompt chaining: - The steps are known in advance and always execute in the same order
- Each step has a clear, focused task (extract, then generate, then validate)
- You want maximum predictability and debuggability
- Cost efficiency matters because each step uses only the tokens it needs, without the overhead of an agent's reasoning loop
When to use agent delegation: - The steps depend on the input and may vary per execution
- The agent needs to decide between multiple possible actions (consult the knowledge base, check the database, call an API) based on what it learns at each step
- You need the system to handle novel inputs that don't fit a predetermined pipeline
- The task requires iterative reasoning where the agent builds on what it discovers
In practice, the best systems combine both. Use prompt chaining for the predictable parts of your workflow (data cleaning, formatting, final validation) and agent delegation for the parts that genuinely require flexible reasoning (understanding an ambiguous request, choosing the right information source). The goal is to minimize the scope of agent reasoning to only the steps that need it, keeping the rest deterministic and predictable.
Example: A hybrid prompt chain and agent delegation flow- Prompt chain, Step 1: A basic LLM call extracts structured information from the incoming request (customer name, issue type, urgency). This is a fixed extraction task that doesn't need agent reasoning.
- Agent delegation, Step 2: An agent receives the structured information and decides how to handle it. For billing issues, it queries the billing API. For technical issues, it searches the knowledge base. For account issues, it looks up the CRM. The agent chooses the right tools based on the issue type.
- Prompt chain, Step 3: The agent's findings feed into a simple LLM call that generates a response draft following a template structure. Fixed task, no agent reasoning needed.
- Deterministic, Step 4: A Code node validates the response and routes it based on confidence.
Steps 1 and 3 are cheap, fast, and predictable. Step 2 is where the agent earns its keep. Step 4 is pure logic. Each layer uses the right tool for the job.
When to Break a Workflow Apart (and When to Keep It Flat)
Not every workflow needs sub-workflows or multi-agent hierarchies. Over-engineering a simple process adds overhead without benefit. Here's a practical decision framework.
Keep it flat when:
- The workflow has a linear sequence of 3-5 steps with no branching
- Only one person maintains it
- The logic is specific to one use case and unlikely to be reused
- You're still prototyping and the architecture might change
- The total workflow fits comfortably on a single canvas view
Break it into sub-workflows when: - You're copying the same logic across multiple workflows (normalize it into one sub-workflow)
- The workflow has grown past 15-20 nodes and is becoming hard to navigate
- Different parts require different expertise to maintain (billing logic vs. AI prompting vs. API integration)
- You need to test a specific section independently without triggering the full pipeline
- A failure in one section should be isolated from the rest
Add multi-agent coordination when: - The input is ambiguous and requires reasoning to determine the right processing path
- Different sub-tasks need fundamentally different models, tools, or system prompts
- The system needs to handle novel task types that you can't fully anticipate in advance
- A single agent's context window would overflow trying to handle everything
The progression is natural, starting flat, extracting sub-workflows when you find yourself duplicating or struggling with scale, and adding multi-agent delegation when the routing decisions genuinely benefit from LLM reasoning. Resist the urge to start with the most complex pattern. Build what you need, then refactor as complexity demands it.
Production Best Practices
Handling Failures in Agent Chains
In a multi-agent or multi-step system, failures are inevitable. A model returns garbage. An API times out. A specialist agent gets confused by an unusual input. The question isn't whether failures will happen but how your system responds when they do.
Principle: Isolate failure domains
Each agent or sub-workflow should have its own error handling. If the billing specialist agent fails, that failure shouldn't cascade into the technical support agent or crash the orchestrator. Build each component to handle its own errors and return a structured failure response that the parent workflow can act on.
Pattern: Structured error responses
Instead of letting agent failures throw unhandled errors, wrap each agent or sub-workflow call in error handling that returns a consistent structure.
JavaScript
// Standard error response structure return { success: false, error: { type: 'agent_failure', // or 'timeout', 'validation_error', 'api_error' message: 'Billing agent could not process the refund request', attemptCount: 2, lastOutput: rawOutput }, fallback: 'route_to_human' };
The orchestrator checks thesuccessfield and routes accordingly. Successful results continue through the normal path. Failures route to fallback logic based on the error type.
Fallback strategies: - Retry with a simpler prompt. If the agent's response didn't meet the schema or quality bar, retry with a more constrained prompt that reduces the agent's decision space.
- Fall back to a simpler model or approach. If a complex agent chain keeps failing on a particular input, route it to a simpler single-step LLM call with a narrowly scoped prompt. You trade flexibility for reliability.
- Escalate to human review. For critical workflows, always have a path that routes to a human when automated handling fails. This is the safety net that prevents failures from producing bad outcomes. (We covered human-in-the-loop patterns in detail in the Human Oversight post.)
- Return a safe default. For low-stakes workflows, a templated "We received your request and a team member will follow up" response is better than a hallucinated answer or a silent failure.
Timeouts matter. When one agent in a chain hangs, the entire pipeline stalls. Set explicit timeouts on every sub-workflow call and agent tool invocation. If a specialist agent doesn't respond within your threshold (30 seconds is a reasonable starting point for most API-backed agents), treat it as a failure and route to fallback logic. An explicit timeout is better than an indefinite wait.
Cost and Token Management
Multi-agent systems multiply token usage. Every agent consumes tokens for its system prompt, conversation history, tool descriptions, and reasoning. An orchestrator that calls three specialist agents, each with their own context, can easily consume 10-20x the tokens of a single-agent workflow. Without deliberate management, costs scale faster than the complexity of the task being solved.
Strategy 1: Scope context per agent
Don't give every agent the full conversation history. The billing specialist needs the billing-relevant portion of the conversation, not the 15 messages about technical troubleshooting that came before. Use your workflow logic to extract and pass only the relevant context to each specialist.
Strategy 2: Choose the right model per task
Not every agent needs your most capable (and expensive) model. Use a lightweight model for classification, routing, and simple extraction tasks. Reserve your most capable model for tasks that genuinely require advanced reasoning, nuanced generation, or complex tool use. In n8n, each agent and LLM node can connect to a different model, so this is a configuration decision, not an architecture change.
Strategy 3: Limit loop iterations
Self-correcting loops and agent reasoning loops should always have a maximum iteration count. Without a cap, a confused agent can loop indefinitely, consuming tokens and producing nothing useful. Two to three iterations is usually sufficient. If the agent can't produce a valid response in three attempts, the issue is likely in the prompt or the task definition, not in the number of retries.
Strategy 4: Minimize tool descriptions
Every tool attached to an agent adds tokens to every request because the agent needs the tool descriptions in its context to decide which tools to use. If an agent has 15 tools but only uses 3 for most requests, consider breaking it into focused agents with fewer tools each. Fewer tool descriptions means lower per-request token costs and often better tool selection accuracy.
Strategy 5: Monitor and set budgets
Track token usage per workflow execution, per agent, and per tool call. n8n's execution data includes this information. Set alert thresholds for abnormal token consumption. A sudden spike in tokens for a particular agent often indicates a prompt issue, a loop that's running more iterations than expected, or context that's growing unbounded.
Tips and Tricks- Start with one agent, then decompose. Build the entire task as a single agent first. Once it works, identify which parts of its reasoning are separable and extract them into specialist agents or sub-workflows. This approach ensures you understand the full problem before you split it up, and it prevents premature decomposition that creates unnecessary coordination overhead.
- Write tool descriptions like API documentation. The orchestrator decides which specialist to call based on tool descriptions. Treat these descriptions like API docs, being specific about what the tool does, what inputs it expects, what it returns, and what it doesn't handle. "Handles billing stuff" is a bad description. "Processes refund requests, billing inquiries, and payment disputes. Requires a customer ID and issue description. Returns a resolution with action taken." is a description that drives reliable routing.
- Test specialists in isolation before connecting them. Each sub-workflow or specialist agent should work correctly on its own before you wire it into the parent workflow. Run test inputs directly against the specialist, verify the outputs, and fix issues at the component level. Debugging a multi-agent system where you're not sure which component is failing is exponentially harder than debugging each piece independently.
- Use deterministic routing when you can, agent routing when you must. If you can determine which specialist to call with a Switch node (based on a category field, a ticket type, or a prior classification step), do that instead of having an agent decide. Deterministic routing is faster, cheaper, and never routes to the wrong specialist because it misunderstood the description. Agent-based routing is for cases where the input is genuinely ambiguous and classification can't be reduced to explicit rules.
- Log the orchestrator's reasoning. When the orchestrator decides to call a specialist, log that decision along with the input that triggered it. This creates an audit trail that's invaluable for debugging misroutes. If the orchestrator keeps sending billing questions to the technical support agent, the logs will show you the pattern so you can fix the tool descriptions or the system prompt.
- Keep system prompts focused. A specialist agent should have a system prompt that covers its domain and nothing else. Don't include general instructions about being helpful, formatting rules for every possible output type, or context about the broader system. Focused system prompts produce better results and consume fewer tokens.
- Design for graceful degradation. Every multi-agent workflow should have an answer to "what happens if this agent fails?" If the answer is "the whole thing breaks," add fallback logic. The mark of a production-grade system isn't that it never fails. It's that failures are handled predictably and don't cascade.
- Version your agent configurations. When you change a system prompt, swap a model, or modify a tool set, track that change. Multi-agent systems have a lot of moving parts, and a performance regression could come from any one of them. Without versioning, you're left guessing which change caused the problem.
What's Next
Complex agent patterns give you the architecture to handle sophisticated AI tasks without creating a system that's impossible to maintain. By breaking problems into specialist agents, composing logic through sub-workflows, managing memory deliberately, and building for failure, you get a system that scales with your use case instead of collapsing under its own weight.
In the next post, we'll cover Extending Agent Capabilities, how to equip your agents with tools from your existing stack and the broader ecosystem so they can grow alongside the tools and services your team relies on.
This post is part of a series that explores proven strategies and practical examples for building reliable AI systems. Find out what topics are already available in the Production AI Playbook here, or be the first to know when new topics are added via RSS, LinkedIn or X.
References:
文章标题:快来看,n8n更新了!生产型AI操作手册:复杂智能体模式
文章链接:https://news.qimuai.cn/?post=4303
本站文章均为原创,未经授权请勿用于任何商业用途