n8n-agents-official

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

n8n Agents

n8n Agents

The n8n Agent node (
@n8n/n8n-nodes-langchain.agent
) is a multi-turn LLM driver with sub-nodes for the model, memory, tools, and optional output parser.
n8n Agent节点(
@n8n/n8n-nodes-langchain.agent
)是一个多轮LLM驱动节点,包含模型、记忆、工具和可选输出解析器等子节点。

When to use the Agent node vs raw chat completion

何时选择Agent节点 vs 原生聊天补全

Decision:
  • Need tool calls, multi-turn reasoning, or memory? Agent. Also a fine default when you don't want to think about it: standardizing on Agent across the workflow is reasonable and makes the path to upgrade simpler.
  • Want the lightest possible single-shot text-out call? Basic LLM Chain (
    @n8n/n8n-nodes-langchain.chainLlm
    ) with a chat-model sub-node (
    OpenRouter Chat Model
    ,
    OpenAI Chat Model
    ,
    Anthropic Chat Model
    , etc.). No agent loop, no tool/memory/parser slots, easier to debug. Note: chat-model nodes are sub-nodes, and they don't run standalone. They wire into a chain or agent. Agent works here too if you'd rather standardize.
  • Routing to one of N output branches based on natural-language input (the AI's job is to pick the branch)? Use the Text Classifier node (
    @n8n/n8n-nodes-langchain.textClassifier
    ). N output handles, one per category, and downstream paths wire directly into each. Every category needs both a name AND a description (the description is what the model picks against, names alone aren't enough). Set
    options.enableAutoFixing: true
    for robustness on edge inputs. Pair with a chat-model sub-node (
    OpenRouter Chat Model
    ,
    OpenAI Chat Model
    , etc.). Don't reach for Agent + Switch for this. Text Classifier is one node and purpose-built.
  • Structured output but no tools? Agent is the easier default with future expansion in mind. Basic LLM Chain also accepts an
    outputParserStructured
    sub-node and works fine where you want the lighter node.
  • Image / audio / video generation? The native single-call node for that provider when calling them directly (OpenAI Image, Gemini Image, ElevenLabs, etc.). HTTP Request when routing through an aggregator (OpenRouter, Together, etc.), because no native aggregator node exists and the native nodes hardcode their provider's base URL on the media operation. Don't wrap media generation in an Agent, see "Binary and the agent boundary" below.
There are other LangChain "chain" / utility nodes for narrow tasks: Information Extractor (pull structured fields from text), Sentiment Analysis (3-way branch), Summarization Chain, Basic LLM Chain.
Agent is a reasonable default for most LLM steps. Reach for Basic LLM Chain when you specifically want the leaner node for a one-shot text call with no tools, memory, or iteration. Reach for Information Extractor / Sentiment Analysis / Summarization Chain / Text Classifier when one of those purpose-built nodes matches the task exactly.
决策指南:
  • 需要工具调用、多轮推理或记忆功能? 选择Agent节点。若无需纠结细节,将Agent作为标准化选择也合理,后续升级路径更简单。
  • 想要最轻量的单次文本输出调用? 使用基础LLM链(
    @n8n/n8n-nodes-langchain.chainLlm
    )搭配聊天模型子节点(
    OpenRouter Chat Model
    OpenAI Chat Model
    Anthropic Chat Model
    等)。无Agent循环、无工具/记忆/解析器插槽,调试更简单。注意:聊天模型节点为子节点,无法独立运行,需接入链或Agent节点。若偏好标准化,Agent节点也可胜任。
  • 需要基于自然语言输入将路由指向N个输出分支之一(由AI决定分支)? 使用文本分类器节点(
    @n8n/n8n-nodes-langchain.textClassifier
    )。每个类别对应一个输出端口,下游路径可直接接入。每个类别需同时设置名称和描述(模型依据描述进行选择,仅名称不足以支撑判断)。设置
    options.enableAutoFixing: true
    可提升边缘输入场景的鲁棒性。搭配聊天模型子节点(
    OpenRouter Chat Model
    OpenAI Chat Model
    等)。请勿使用Agent + 开关节点实现此功能,文本分类器是专为该场景设计的单节点方案。
  • 需要结构化输出但无需工具? Agent节点是更易用的默认选择,且支持未来扩展。基础LLM链也可接入
    outputParserStructured
    子节点,在追求轻量节点的场景下表现良好。
  • 图片/音频/视频生成? 直接调用对应服务商的原生单次调用节点(如OpenAI Image、Gemini Image、ElevenLabs等)。若通过聚合器(如OpenRouter、Together等)调用,则使用HTTP Request节点,因为目前没有原生聚合器节点,且原生节点会在媒体操作中硬编码服务商的基础URL。请勿将媒体生成功能封装在Agent节点中,详见下文“二进制数据与Agent边界”部分。
LangChain还提供其他针对特定任务的“链”/实用节点:信息提取器(从文本中提取结构化字段)、情感分析(三分支)、摘要链、基础LLM链。
Agent节点是大多数LLM步骤的合理默认选择。当明确需要针对无工具、无记忆、无迭代的单次文本调用使用轻量节点时,选择基础LLM链。当任务与信息提取器/情感分析/摘要链/文本分类器的专属场景完全匹配时,选择对应节点。

Non-negotiables

不可妥协的规则

  1. Tool names and descriptions are part of the prompt. The model picks tools by name and description. Vague tool node names like (
    doStuff
    ) or weak descriptions ("does things with the data") cause silent failure: the model skips your tool, mis-selects it, or hallucinates parameters. Treat both like API design. See
    references/TOOLS.md
    .
  2. Structured output: parse AND autoFix.
    outputParserStructured
    with
    autoFix: true
    and a coding-capable fixer model (e.g., Claude Sonnet 4.6) is the production pattern.
  1. 工具名称和描述是提示词的一部分。 模型依据名称和描述选择工具。模糊的工具节点名称(如
    doStuff
    )或薄弱的描述(“处理数据”)会导致静默失败:模型跳过工具、错误选择工具或生成幻觉参数。需像设计API一样对待工具名称和描述。详见
    references/TOOLS.md
  2. 结构化输出:解析+自动修复。 使用开启
    autoFix: true
    outputParserStructured
    节点,并搭配具备编码能力的修复模型(如Claude Sonnet 4.6),这是生产环境的标准方案。

Strong defaults

推荐默认配置

  • Tool descriptions are modular prompt fragments. Anything specific to how to call this tool belongs in the tool's description, not the system prompt. Keeps the system prompt focused, and tools become reusable across agents. See
    references/SYSTEM_PROMPT.md
    .
  • Sub-workflow tools (
    toolWorkflow
    ) for anything multi-step.
    Any workflow becomes a tool with typed
    fromAi()
    inputs, and composes with branching, error handling, sub-workflows. See
    references/SUBWORKFLOW_AS_TOOL.md
    .
  • Wrap tools with user-visible side effects in human review. Sends, payments, refunds, account changes. Gate them behind a Slack / Chat / Discord / Telegram approval node so a human signs off before the tool runs. See
    references/HUMAN_REVIEW.md
    .
  • 工具描述为模块化提示片段。 任何与“如何调用该工具”相关的内容都应放在工具描述中,而非系统提示词。这样可保持系统提示词的聚焦性,且工具可在不同Agent间复用。详见
    references/SYSTEM_PROMPT.md
  • 多步骤逻辑使用子工作流工具(
    toolWorkflow
    )。
    任何工作流都可通过类型化的
    fromAi()
    输入转换为工具,并支持分支、错误处理、子工作流组合。这是n8n中最强大的方案,存疑时默认选择此方案。详见
    references/SUBWORKFLOW_AS_TOOL.md
  • 对有用户可见副作用的工具添加人工审核。 如发送消息、支付、退款、账户变更等操作。通过Slack/聊天/Discord/Telegram审核节点进行管控,确保工具运行前需人工确认。详见
    references/HUMAN_REVIEW.md

The sub-node pattern

子节点模式

The Agent node has a main input (the prompt or user message) and sub-node inputs:
ts
const aiAgent = node({
    type: '@n8n/n8n-nodes-langchain.agent',
    config: {
        name: 'Customer Support Agent',
        parameters: {
            promptType: 'define',
            text: '={{ $json.userMessage }}',
            options: {
                systemMessage: '...',
                passthroughBinaryImages: true,    // for vision / multimodal
            },
        },
        subnodes: {
            model: openRouterModel,
            memory: simpleMemory,
            tools: [generateImage, editImage, searchKnowledgeBase],
            outputParser: structuredParser,    // optional
        },
    },
})
The four sub-node slots:
  • model
    (required): the language model. OpenAI, Anthropic, OpenRouter, etc. Use chat-model variants, not completion variants.
  • memory
    (optional): conversation memory. Without it, every call is stateless. See
    references/MEMORY.md
    .
  • tools
    (optional, but the point of using an agent): tools the agent can call. See
    references/TOOLS.md
    .
  • outputParser
    (optional): forces structured JSON output. See
    references/STRUCTURED_OUTPUT.md
    .
Agent节点有一个主输入(提示词或用户消息)和子节点输入:
ts
const aiAgent = node({
    type: '@n8n/n8n-nodes-langchain.agent',
    config: {
        name: 'Customer Support Agent',
        parameters: {
            promptType: 'define',
            text: '={{ $json.userMessage }}',
            options: {
                systemMessage: '...',
                passthroughBinaryImages: true,    // 用于视觉/多模态场景
            },
        },
        subnodes: {
            model: openRouterModel,
            memory: simpleMemory,
            tools: [generateImage, editImage, searchKnowledgeBase],
            outputParser: structuredParser,    // 可选
        },
    },
})
四个子节点插槽:
  • model
    (必填):语言模型,如OpenAI、Anthropic、OpenRouter等。使用聊天模型变体,而非补全模型变体。
  • memory
    (可选):对话记忆。若无此节点,每次调用都是无状态的。详见
    references/MEMORY.md
  • tools
    (可选,但这是使用Agent的核心价值):Agent可调用的工具。详见
    references/TOOLS.md
  • outputParser
    (可选):强制输出结构化JSON。详见
    references/STRUCTURED_OUTPUT.md

Triggers

触发器

Different triggers shape the input differently:
  • Chat Trigger (
    @n8n/n8n-nodes-langchain.chatTrigger
    )
    with
    availableInChat: true
    : powers the canvas chat tester so you can poke at an agent while building it. Input is
    { chatInput, sessionId, files[] }
    .
    sessionId
    is what memory keys on, so pass it through wherever conversation continuity is needed. Files come in via
    files[]
    , see binary section below. Not a production surface, use Slack / Discord / Teams / Telegram / webhook for that.
  • Webhook: arbitrary input shape, no session by default. Manage continuity by passing a session/conversation ID through the request body and forwarding it to the memory node.
<!-- TEMPORARY: update below this to include a link to the new agent paradigm when it is released -->
  • External chat surface (Slack, Discord, Teams, Telegram): every chat-triggered workflow that posts replies MUST filter out the bot's own user ID, or it loops forever potentially crashing n8n. Prefer trigger-level filtering when the surface supports it (Slack's
    options.userIds
    is an exclusion list); otherwise filter in the first node after the trigger. Semantics differ per surface, see
    references/CHAT_AGENT_PATTERNS.md
    . Beyond the anti-loop filter, a simple bot (trigger → agent → reply) is fine in one workflow. Split into a "shell" workflow + agent-core sub-workflow once you need loading UX, sub-agents, reuse across surfaces, or robust error handling.
  • Manual / Schedule: ad-hoc invocations. Memory rarely useful unless explicitly continuing a previous run.
  • Execute Workflow Trigger (sub-workflow): when an agent is itself a tool of another agent. Treat the trigger's declared inputs as the contract.
不同触发器对输入的处理方式不同:
  • 聊天触发器(
    @n8n/n8n-nodes-langchain.chatTrigger
    ,开启
    availableInChat: true
    :支持画布聊天测试器,便于在构建Agent时进行调试。输入格式为
    { chatInput, sessionId, files[] }
    sessionId
    是记忆节点的键值,因此在需要保持对话连续性的场景中需传递该值。文件通过
    files[]
    传入,详见下文二进制数据部分。此触发器不适用于生产环境,生产环境建议使用Slack/Discord/Teams/Telegram/webhook。
  • Webhook:输入格式任意,默认无会话。可通过在请求体中传递会话/对话ID,并转发至记忆节点来管理连续性。
<!-- 临时注释:待新Agent范式发布后更新以下内容 -->
  • 外部聊天平台(Slack、Discord、Teams、Telegram):所有发送回复的聊天触发工作流必须过滤掉机器人自身的用户ID,否则会陷入无限循环,可能导致n8n崩溃。优先使用触发器级别的过滤(如Slack的
    options.userIds
    为排除列表,可添加机器人ID);若平台不支持,则在触发器后的第一个节点进行过滤。不同平台的语义不同,详见
    references/CHAT_AGENT_PATTERNS.md
    。除防循环过滤外,简单机器人(触发器→Agent→回复)可在单个工作流中实现。当需要加载UX、子Agent、跨平台复用或健壮的错误处理时,拆分为“外壳”工作流 + Agent核心子工作流。
  • 手动/调度:临时调用场景。除非明确需要延续之前的会话,否则记忆功能用处不大。
  • 执行工作流触发器(子工作流):当一个Agent本身是另一个Agent的工具时使用。将触发器声明的输入视为契约。

Binary and the agent boundary

二进制数据与Agent边界

The model can see uploaded files (vision) via
passthroughBinaryImages: true
. But tools cannot receive binary, and
fromAi()
parameters are JSON only. Base64 is also not accepted by tools, even through non-AI bindings.
Workaround: pre-stage uploads to storage before the agent runs, inject the storage keys into the system prompt, tools accept the key as a string parameter and re-fetch internally. Full pattern in
n8n-binary-and-data-official
references/AGENT_TOOL_BINARY.md
.
On the output side: the Agent's output formatter is text-shaped (or structured-text when an
outputParser
is wired). When a model returns binary (image bytes, audio bytes, video), the Agent doesn't surface it at all. There's nothing to dig out downstream, and trying to recover it via a Code or Set node after the Agent does not work. For one-shot media generation, use the provider's native single-call node directly such as
@n8n/n8n-nodes-langchain.googleGemini
or
@n8n/n8n-nodes-langchain.openAi
.
The exception: when a media step genuinely belongs in an agent (one tool among several, picked based on conversation context, or editing a previously-generated image), the workaround is a tool sub-workflow that uploads the result to storage and returns a key or URL. Pattern in
n8n-binary-and-data-official
references/AGENT_TOOL_BINARY.md
. Don't reach for this by default. The upload + key + re-fetch path adds nodes and a storage dependency you don't otherwise need. Only when the orchestration actually requires an agent's tool selection.
通过设置
passthroughBinaryImages: true
,模型可“查看”上传的文件(视觉场景)。但工具无法接收二进制数据,且
fromAi()
参数仅支持JSON格式。工具也不接受Base64编码,即使通过非AI绑定传递也不行。
解决方法:在Agent运行前将文件预上传至存储服务,将存储密钥注入系统提示词,工具接受密钥作为字符串参数并在内部重新获取。完整方案详见
n8n-binary-and-data-official
references/AGENT_TOOL_BINARY.md
输出端:Agent的输出格式化器为文本格式(接入
outputParser
时为结构化文本)。当模型返回二进制数据(图片字节、音频字节、视频字节)时,Agent不会输出任何内容。下游无法提取该数据,尝试通过Code或Set节点从Agent后恢复也无效。对于单次媒体生成,直接使用服务商的原生单次调用节点,如
@n8n/n8n-nodes-langchain.googleGemini
@n8n/n8n-nodes-langchain.openAi
例外情况:当媒体步骤确实需要集成到Agent中(作为多个工具之一,根据对话上下文选择,或编辑之前生成的图片),解决方法是使用工具子工作流将结果上传至存储服务并返回密钥或URL。方案详见
n8n-binary-and-data-official
references/AGENT_TOOL_BINARY.md
。请勿默认选择此方案,上传+密钥+重新获取的路径会增加节点和存储依赖,仅当编排确实需要Agent的工具选择功能时使用。

What goes in the system prompt vs the tool description

系统提示词 vs 工具描述的内容划分

Belongs in system promptBelongs in the tool's description
Persona, role, voiceWhat this specific tool does
Output format rules ("respond in markdown")When to use this tool vs others
Refusal/safety behaviorWhat each parameter means and its expected shape
Display protocols ("show images via
![]()
markdown")
Examples of good vs bad invocations
Universal context (current date, user role)Tool-specific gotchas (rate limits, edge cases)
Inter-tool flow ("after generating, always show via display protocol")Tool-specific input transformations
Benefit: tools become reusable. A well-described tool works in any agent that drops it in. The system prompt stays focused on role and shared behavior.
For deeper guidance and worked examples, see
references/SYSTEM_PROMPT.md
and
references/TOOLS.md
.
属于系统提示词的内容属于工具描述的内容
角色设定、身份、语气该工具的具体功能
输出格式规则(如“以markdown格式回复”)何时使用该工具而非其他工具
拒绝/安全行为规则每个参数的含义和预期格式
展示协议(如“通过
![]()
markdown格式展示图片”)
良好/糟糕调用示例
通用上下文(当前日期、用户角色)工具特定注意事项(速率限制、边缘情况)
工具间流程(如“生成后始终通过展示协议呈现”)工具特定输入转换规则
优势:工具可复用。描述完善的工具可在任何Agent中直接使用,系统提示词可聚焦于角色和通用行为规则。
如需更深入的指导和示例,详见
references/SYSTEM_PROMPT.md
references/TOOLS.md

Tool selection: the four types

工具选择:四种类型

Pick the lightest option that covers the job:
  • Native n8n tool node exists? (e.g.,
    slackTool
    ,
    gmailTool
    ,
    calculatorTool
    ) Use it. Lowest config overhead.
    • Native node is missing an operation or needs custom params (e.g., a Notion endpoint the node doesn't expose, a non-standard header, a different pagination shape)? HTTP Request Tool with the service's "Predefined Credential Type". Reuses the existing OAuth / API-key credential, gives full API access, no custom auth code.
  • Multi-step logic, or reusing a sub-workflow already in the project? Sub-workflow as tool (
    toolWorkflow
    ). Anything you can build as a workflow becomes a tool with typed
    fromAi()
    inputs. The most powerful option in n8n, so default here when in doubt. See
    references/SUBWORKFLOW_AS_TOOL.md
    .
  • Calling an external HTTP API the agent should orchestrate directly? HTTP Request Tool. Also good for slow async work via long-poll callback.
  • Tool already exists as a published, MCP-accessible workflow? MCP tool. Useful for cross-workflow agent capabilities. See
    n8n-extending-mcp-official
    .
See
references/TOOLS.md
for deeper guidance on each option and how to wire
fromAi()
parameters.
选择能满足需求的最轻量方案:
  • 存在原生n8n工具节点?(如
    slackTool
    gmailTool
    calculatorTool
    )直接使用。配置开销最低。
    • 原生节点缺少操作或需要自定义参数(如Notion节点未暴露的端点、非标准请求头、不同的分页格式)?使用带有服务“预定义凭证类型”的HTTP Request工具。可复用现有OAuth/API密钥凭证,支持完整API访问,无需自定义认证代码。
  • 需要多步骤逻辑,或复用项目中已有的子工作流? 将子工作流作为工具(
    toolWorkflow
    )。任何可构建为工作流的内容都可通过类型化的
    fromAi()
    输入转换为工具。这是n8n中最强大的方案,存疑时默认选择此方案。详见
    references/SUBWORKFLOW_AS_TOOL.md
  • 需要Agent直接编排调用外部HTTP API? 使用HTTP Request工具。也适用于通过长轮询回调实现的慢异步任务。
  • 工具已作为可访问MCP的工作流发布? 使用MCP工具。适用于跨工作流的Agent能力。详见
    n8n-extending-mcp-official
每种方案的深入指导及
fromAi()
参数的配置方法详见
references/TOOLS.md

Human review

人工审核

Before adding or skipping human review on a tool, check with the user. Whether sign-off is needed is a product / policy call (blast radius, audit requirements, how much they trust the model) that the user is better positioned to make than you. Surface the question, recommend based on the criteria below, and let them decide.
When a tool's effects need human approval before execution (sends, payments, refunds, account changes, customer-facing actions), wrap it with a review tool node:
slackHitlTool
,
discordHitlTool
,
telegramHitlTool
,
gmailHitlTool
, etc. (n8n's node names use
Hitl
for the human-in-the-loop pattern, and "human review" is what it's called in the UI.) The review node sits between the wrapped tool and the agent on the
ai_tool
connection: the wrapped tool's
ai_tool
output wires into the review node, and the review node's
ai_tool
output wires into the Agent. The agent calls through, the review node pauses for approval, on approve, the wrapped tool runs.
Default to / recommend human review when:
  • The tool sends, pays, refunds, or otherwise mutates user-visible state.
  • The approver is different from the chatter (manager-approves-customer-action, support team approves a customer-triggered refund).
  • The trigger is non-interactive (order, form, schedule) but the tool's effect needs human sign-off.
Approval messages should display the actual parameters the wrapped tool will receive, not text the model paraphrases. Use
$tool.parameters.<name>
directly, or iterate over
$tool.parameters
to list every param. Don't fill the approval text via
fromAi()
. You'd be approving a paraphrase, not the literal call. Customize button labels with the actual values, e.g.
Approve {{ $tool.parameters.amount }} refund
.
Full config patterns, per-platform setup, and the multi-channel approver pattern in
references/HUMAN_REVIEW.md
.
在添加或跳过工具的人工审核前,需与用户确认。是否需要签字确认属于产品/政策决策(影响范围、审计要求、对模型的信任程度),用户比开发者更适合做出判断。需明确提出问题,根据以下标准给出建议,由用户最终决定。
当工具的执行效果需要人工批准时(发送消息、支付、退款、账户变更、面向客户的操作),使用审核工具节点进行封装:
slackHitlTool
discordHitlTool
telegramHitlTool
gmailHitlTool
等(n8n节点名称使用
Hitl
表示人在回路模式,UI中称为“人工审核”)。审核节点位于封装工具和Agent的
ai_tool
连接之间:封装工具的
ai_tool
输出接入审核节点,审核节点的
ai_tool
输出接入Agent。Agent发起调用后,审核节点暂停等待批准,批准后封装工具才会运行。
默认推荐添加人工审核的场景:
  • 工具执行发送、支付、退款或其他会改变用户可见状态的操作。
  • 审批人与对话发起人为不同角色(如经理审批客户操作、支持团队审批客户触发的退款)。
  • 触发器为非交互式(订单、表单、调度),但工具执行效果需要人工确认。
审批消息应显示封装工具实际将接收的参数,而非模型转述的文本。直接使用
$tool.parameters.<name>
,或遍历
$tool.parameters
列出所有参数。请勿通过
fromAi()
填充审批文本,否则批准的是转述内容而非实际调用。可使用实际值自定义按钮标签,如
批准 {{ $tool.parameters.amount }} 退款
完整配置方案、各平台设置及多渠道审批人模式详见
references/HUMAN_REVIEW.md

Output parsing: when and how

输出解析:时机与方法

Add an
outputParser
sub-node when downstream needs structured data, not free-form text.
ts
const parser = outputParser({
    type: '@n8n/n8n-nodes-langchain.outputParserStructured',
    config: {
        parameters: {
            schemaType: 'manual',
            inputSchema: JSON.stringify({
                type: 'object',
                properties: {
                    score: { type: 'integer', minimum: 1, maximum: 5 },
                    category: { type: 'string', enum: ['bug', 'feature', 'question'] },
                    reason: { type: 'string' },
                    tags: { type: 'array', items: { type: 'string' } },
                },
                required: ['score', 'category', 'reason'],
            }),
            autoFix: true,
            customizeRetryPrompt: true,
            prompt: '...retry instructions...', // generally leave as default
        },
        subnodes: {
            languageModel: fixerModel,    // coding-capable model, e.g. Claude Sonnet 4.6
        },
    },
})
  1. Use
    schemaType: 'manual'
    with a real JSON schema, not
    jsonSchemaExample
    .
    An example can't express optional fields, enums, value ranges, or array constraints, so you outgrow it the first time the shape gets non-trivial. A schema lets you mark fields required vs optional, define enums, constrain numbers and string formats, and gives the model clearer rules to follow. Reach for
    schemaType: 'fromJson'
    with an example only for one-off shapes you're certain will never grow constraints.
  2. autoFix: true
    adds retry on parse failure.
    Wire a coding-capable model as the fixer sub-node (e.g., Claude Sonnet 4.6 or similar). Fixing malformed JSON against a schema is a structured-output / coding task, and a weak or generic model often produces another malformed retry, defeating the point.
For the full pattern including custom retry prompts, see
references/STRUCTURED_OUTPUT.md
.
当下游需要结构化数据而非自由文本时,添加
outputParser
子节点。
ts
const parser = outputParser({
    type: '@n8n/n8n-nodes-langchain.outputParserStructured',
    config: {
        parameters: {
            schemaType: 'manual',
            inputSchema: JSON.stringify({
                type: 'object',
                properties: {
                    score: { type: 'integer', minimum: 1, maximum: 5 },
                    category: { type: 'string', enum: ['bug', 'feature', 'question'] },
                    reason: { type: 'string' },
                    tags: { type: 'array', items: { type: 'string' } },
                },
                required: ['score', 'category', 'reason'],
            }),
            autoFix: true,
            customizeRetryPrompt: true,
            prompt: '...重试说明...', // 通常保持默认即可
        },
        subnodes: {
            languageModel: fixerModel,    // 具备编码能力的模型,如Claude Sonnet 4.6
        },
    },
})
  1. 使用
    schemaType: 'manual'
    搭配真实JSON Schema,而非
    jsonSchemaExample
    示例无法表达可选字段、枚举、值范围或数组约束,因此当格式变得复杂时会立即失效。Schema可标记必填/可选字段、定义枚举、约束数字和字符串格式,并为模型提供更清晰的规则。仅当确定格式永远不会添加约束的一次性场景时,才使用
    schemaType: 'fromJson'
    搭配示例。
  2. autoFix: true
    可在解析失败时自动重试。
    接入具备编码能力的修复模型作为子节点(如Claude Sonnet 4.6或类似模型)。针对Schema修复格式错误的JSON是结构化输出/编码任务,弱模型或通用模型通常会生成另一个格式错误的结果,导致重试失效。
包含自定义重试提示的完整方案详见
references/STRUCTURED_OUTPUT.md

Memory: brief mental model

记忆:简要模型

  • No memory: stateless. Right for one-shot tasks (classify, summarize).
  • memoryBufferWindow
    :
    keeps the last N messages per memory key and persists across executions via n8n's internal store. The key is whatever expression you bind to
    sessionKey
    . Chat triggers fill
    sessionId
    automatically, but you can key on anything (Slack
    thread_ts
    , a webhook conversation ID, a multi-tenant composite). The default for chat memory. The "window" is the sliding cap on how many messages stay in context, not a scope on persistence.
  • memoryPostgres
    /
    memoryRedis
    / similar:
    reach for these when you need to query or read memory outside the agent: displaying conversation history in your own UI, analytics on past chats, or sharing memory with another system. Otherwise
    memoryBufferWindow
    is enough.
Plumb a stable key from the trigger to memory consistently, or conversations get crossed. See
references/MEMORY.md
.
  • 无记忆:无状态。适用于单次任务(分类、摘要)。
  • memoryBufferWindow
    :为每个记忆键保留最近N条消息,并通过n8n内部存储跨执行持久化。键值为绑定到
    sessionKey
    的表达式。聊天触发器会自动填充
    sessionId
    ,但也可基于任何值(如Slack的
    thread_ts
    、webhook对话ID、多租户组合键)设置键值。这是聊天记忆的默认方案。“窗口”是指上下文保留的消息数量上限,而非持久化范围。
  • memoryPostgres
    /
    memoryRedis
    / 类似节点
    :当需要在Agent外部查询或读取记忆时使用(如在自定义UI中展示对话历史、对过往聊天进行分析、与其他系统共享记忆)。否则
    memoryBufferWindow
    已足够。
需从触发器向记忆节点稳定传递键值,否则对话会混乱。详见
references/MEMORY.md

RAG (retrieval augmented generation)

RAG(检索增强生成)

n8n has the LangChain RAG primitives: document loaders, text splitters, embeddings, vector stores, retrievers, rerankers. The pieces work, but opinionated end-to-end recipes ("which vector store, which chunking, when to rerank") depend heavily on data shape and scale.
This skill keeps RAG opinions thin on purpose. See
references/RAG.md
for more details on RAG.
n8n提供LangChain RAG原语:文档加载器、文本分割器、embeddings、vector stores、检索器、重排器。这些组件均可正常工作,但端到端的最佳实践(如选择哪个vector store、哪种分割方式、何时重排)高度依赖数据格式和规模。
本指南刻意简化了RAG相关建议。更多RAG细节详见
references/RAG.md

Reference files

参考文件

FileRead when
references/TOOLS.md
Adding tools to an agent, choosing between the four tool types, writing tool names and descriptions
references/SUBWORKFLOW_AS_TOOL.md
Wiring a sub-workflow as an agent tool via
toolWorkflow
, mapping
fromAi
overrides
references/SYSTEM_PROMPT.md
Writing or refactoring a system prompt, deciding what goes in the system prompt vs tool descriptions
references/STRUCTURED_OUTPUT.md
Forcing JSON output, configuring autoFix retries, validating downstream
references/MEMORY.md
Choosing a memory type, persistence and sessionId handling
references/RAG.md
Building retrieval-augmented agents, intentionally a stub
references/HUMAN_REVIEW.md
Adding human approval to a tool, configuring approval messages, multi-channel approver patterns
references/CHAT_AGENT_PATTERNS.md
Building a chat agent on Slack, Discord, Teams, Telegram, or any custom chat surface, multi-workflow shell + core + sub-agents topology
文件阅读时机
references/TOOLS.md
为Agent添加工具、选择四种工具类型、编写工具名称和描述时
references/SUBWORKFLOW_AS_TOOL.md
通过
toolWorkflow
将子工作流配置为Agent工具、映射
fromAi
覆盖项时
references/SYSTEM_PROMPT.md
编写或重构系统提示词、划分系统提示词与工具描述内容时
references/STRUCTURED_OUTPUT.md
强制JSON输出、配置自动修复重试、验证下游数据时
references/MEMORY.md
选择记忆类型、处理持久化和sessionId时
references/RAG.md
构建检索增强型Agent时(当前为 stub 文档)
references/HUMAN_REVIEW.md
为工具添加人工审核、配置审批消息、实现多渠道审批人模式时
references/CHAT_AGENT_PATTERNS.md
在Slack、Discord、Teams、Telegram或自定义聊天平台构建聊天Agent、实现多工作流外壳+核心+子Agent拓扑时

Anti-patterns

反模式

Anti-patternWhat goes wrongFix
Generic tool names (
doStuff
,
runQuery
)
Model can't tell which tool to pick, skips them or hallucinates parametersVerb-first specific names:
Search customer database
,
Generate image with Veo
Empty or one-line tool descriptionsModel has no clue when to invoke, bad selectionWrite a real description: what it does, when to use, parameter meanings
Cramming everything into the system promptBloated prompt, reuse impossible, per-tool guidance buriedMove tool-specific instructions to tool descriptions, keep system prompt to persona + global rules
Code-node tool where a sub-workflow would workNot reusable, can't be tested independently, can't compose with branchingUse
toolWorkflow
with a proper sub-workflow
Passing binary directly to a toolDoesn't work, binary can't cross the tool boundaryPre-stage to storage, pass keys via
fromAi
, tool fetches internally. See
n8n-binary-and-data-official
outputParserStructured
without
autoFix
One bad model output and the workflow failsSet
autoFix: true
with a cheap fixer model
Hardcoded
sessionId
or no sessionId
Conversations cross or memory never matchesPass sessionId from trigger consistently to memory and tools
Two near-identical tools instead of one with branchingModel gets confused, selection is non-deterministicOne tool with internal branching driven by parameters
Hardcoding a system prompt that's reused across workflows or iterated oftenEditing requires republishing, can't share across workflows, tuning churn lives in node JSONStore in a Data Table, load at runtime
Wrapping image / audio / video generation in an AgentBinary doesn't flow through tools or out of the output formatter, Agent adds nodes for no gainUse the provider's native single-call node directly (OpenAI Image, Gemini Image, ElevenLabs), HTTP Request only when going through an aggregator
Reaching for Agent + Switch to route on natural-language inputTwo nodes plus prompt boilerplate where Text Classifier is one node with N built-in output branchesUse Text Classifier (
@n8n/n8n-nodes-langchain.textClassifier
), each category gets its own output handle, wire downstream paths directly
Tool that mutates user-visible state (send, pay, refund) without human reviewAgent fires irreversible action on a wrong inferenceWrap with the review tool node that fits the channel (Slack/Chat/Discord/Telegram), show actual params via
$tool.parameters
Filling the review approval message via
fromAi()
The model paraphrases, you approve text not valuesUse
$tool.parameters.<name>
directly so the literal call is visible
Chat-triggered agent workflow that posts replies without filtering out the bot's own user IDBot's own messages re-trigger the workflow, infinite loop that burns runs and tokens until rate limits or n8n concurrency stops itPrefer trigger-level filtering when available (Slack Trigger's
options.userIds
is an exclusion list, put the bot ID there). Otherwise filter on
$json.user !== '<BOT_USER_ID>'
(or the surface equivalent) as the first node after the trigger. Required for ANY chat-triggered workflow that sends a reply (Slack, Discord, Teams, Telegram), regardless of complexity. See
references/CHAT_AGENT_PATTERNS.md
for per-surface semantics
Passing the bare blocks array to the Slack node's
blocksUi
when the agent returns Block Kit
The Slack node accepts the input silently and posts the message with no rich content; no error, no warningWrap as
{ "blocks": [...] }
with the value as a real array, not a stringified one. Expression:
={{ { "blocks": $('Agent').item.json.output.blocks } }}
. See
n8n-node-configuration-official
references/COMMS_NODES.md
"Block Kit messages"
反模式问题修复方案
通用工具名称(
doStuff
runQuery
模型无法判断应选择哪个工具,会跳过工具或生成幻觉参数使用动词开头的具体名称:
Search customer database
Generate image with Veo
空描述或单行工具描述模型不清楚何时调用工具,选择效果差编写完整描述:工具功能、使用场景、参数含义
所有内容都塞进系统提示词提示词臃肿、无法复用、工具专属指导被淹没将工具专属说明移至工具描述,系统提示词仅保留角色设定和全局规则
用Code节点实现工具,而子工作流可胜任无法复用、无法独立测试、无法与分支组合使用
toolWorkflow
搭配标准子工作流
直接向工具传递二进制数据无法工作,二进制数据无法跨越工具边界预上传至存储服务,通过
fromAi
传递密钥,工具在内部重新获取。详见
n8n-binary-and-data-official
使用
outputParserStructured
但未开启
autoFix
模型输出错误会导致工作流失败设置
autoFix: true
并搭配低成本修复模型
硬编码
sessionId
或未设置
sessionId
对话混乱或记忆不匹配从触发器向记忆和工具稳定传递
sessionId
使用两个近乎相同的工具,而非一个带分支的工具模型混淆,选择结果不确定使用一个工具,通过参数驱动内部分支
硬编码在多个工作流中复用或频繁迭代的系统提示词修改需重新发布、无法跨工作流共享、调优记录存储在节点JSON中将提示词存储在数据表中,运行时加载
将图片/音频/视频生成封装在Agent节点中二进制数据无法通过工具或输出格式化器传递,Agent节点徒增复杂度直接使用服务商的原生单次调用节点(OpenAI Image、Gemini Image、ElevenLabs),仅当通过聚合器调用时使用HTTP Request
使用Agent + 开关节点实现自然语言输入路由需要两个节点加提示词模板,而文本分类器是带N个内置输出分支的单节点使用文本分类器(
@n8n/n8n-nodes-langchain.textClassifier
),每个类别对应一个输出端口,直接接入下游路径
会改变用户可见状态的工具(发送、支付、退款)未添加人工审核Agent可能因推理错误执行不可逆操作使用对应渠道的审核工具节点(Slack/聊天/Discord/Telegram),通过
$tool.parameters
展示实际参数
通过
fromAi()
填充审批消息
模型转述内容,批准的是文本而非实际值直接使用
$tool.parameters.<name>
,确保可见的是实际调用参数
发送回复的聊天触发Agent工作流未过滤机器人自身用户ID机器人自身消息会重新触发工作流,导致无限循环,消耗运行次数和令牌,直到触发速率限制或n8n并发限制优先使用触发器级过滤(如Slack触发器的
options.userIds
排除列表,添加机器人ID)。若平台不支持,则在触发器后的第一个节点过滤
$json.user !== '<BOT_USER_ID>'
(或对应平台的等效字段)。所有发送回复的聊天触发工作流(Slack、Discord、Teams、Telegram)无论复杂度如何,都必须执行此操作。详见
references/CHAT_AGENT_PATTERNS.md
中各平台的语义说明
将Agent返回的Block Kit裸数组直接传递给Slack节点的
blocksUi
Slack节点会静默接受输入,但发布的消息无富内容;无错误、无警告将数组包装为
{ "blocks": [...] }
,确保值为真实数组而非字符串化数组。表达式示例:
={{ { "blocks": $('Agent').item.json.output.blocks } }}
。详见
n8n-node-configuration-official
references/COMMS_NODES.md
中“Block Kit消息”部分