n8n-ai-nodes-official

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

n8n AI nodes

n8n AI 节点

The AI 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. It lives inside a workflow, which owns its trigger, control flow, and lifecycle.
AI Agent 节点(
@n8n/n8n-nodes-langchain.agent
)是一个多轮 LLM 驱动节点,包含用于 model、memory、tools 以及可选 output parser 的 sub-nodes。它位于 workflow 内部,由该 workflow 管理其 trigger、control flow 和 lifecycle。

AI Agent node or first-class n8n Agent?

AI Agent 节点还是 first-class n8n Agent?

"Build me an agent" means a first-class n8n Agent (
n8n-agents-official
) by default. Use the node when the workflow owns the control flow and AI is one bounded step, or when the first-class Agent hits a limit:
<!-- TEMPORARY: revisit each limit below when n8n adds tool access to run data, sessions shared between channels and workflows, or Agents on every instance (Enterprise). -->
NeedWhy the node wins today
Trigger or upstream data mapped exactly into a tool parameterAgent tool expressions only see the model's own arguments. Node tools can use
$('Webhook').item.json...
One conversation shared between a chat channel and other workflowsAgent channel sessions and workflow sessions never meet
create_agent
isn't in the MCP tool list
Agents aren't enabled on this instance
“Build me an agent”默认指 first-class n8n Agent(
n8n-agents-official
)。当 workflow 负责 control flow、AI 仅是有明确边界的一步时,应使用该节点;或者当 first-class Agent 遇到限制时,也应使用该节点:
<!-- 临时处理:当 n8n 支持访问 run data 中的 tools、跨 channels 和 workflows 共享 sessions,或所有实例均支持 Agents(Enterprise)时,重新审视下列各项限制。 -->
需求当前使用该节点更具优势的原因
需要将 Trigger 或上游数据精确映射到某个 tool parameterAgent tool expressions 只能看到模型自己生成的 arguments。Node tools 可以使用
$('Webhook').item.json...
在一个 chat channel 与其他 workflows 之间共享同一段对话Agent channel sessions 与 workflow sessions 永远不会互通
create_agent
不在 MCP tool list 中
当前实例未启用 Agents

When to use the Agent node vs raw chat completion

何时使用 Agent 节点,而不是原始 chat completion

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.
决策:
  • 需要 tool calls、多轮推理或 memory? 使用 Agent。如果不想过多考虑,这也是一个合适的默认选择:在整个 workflow 中统一采用 Agent 合理,也能让日后的升级路径更简单。
  • 想要尽可能轻量的一次性 text-out 调用? 使用 Basic LLM Chain(
    @n8n/n8n-nodes-langchain.chainLlm
    ),并搭配 chat-model sub-node(
    OpenRouter Chat Model
    、
    OpenAI Chat Model
    、
    Anthropic Chat Model
    等)。它没有 agent loop,也没有 tool、memory、parser slots,更容易调试。注意:chat-model nodes 是 sub-nodes,不能独立运行;它们需要连接到 chain 或 agent。如果更想统一标准,Agent 在这里也适用。
  • 需要根据 natural-language input 路由到 N 个 output branches(由 AI 决定选择哪个分支)? 使用 Text Classifier 节点(
    @n8n/n8n-nodes-langchain.textClassifier
    )。它提供 N 个 output handles,每个 category 一个,下游 paths 可直接连接到相应 handle。每个 category 都必须同时设置 name AND description(模型会根据 description 进行选择,仅有 name 是不够的)。为提高边缘输入下的稳健性,设置
    options.enableAutoFixing: true
    。搭配 chat-model sub-node(
    OpenRouter Chat Model
    、
    OpenAI Chat Model
    等)。不要使用 Agent + Switch。Text Classifier 只有一个节点,并且是专为此类任务设计的。
  • 需要 structured output,但不需要 tools? 如果考虑未来的扩展能力,Agent 是更简单的默认选择。Basic LLM Chain 同样接受
    outputParserStructured
    sub-node;在希望使用更精简节点的场景中,它也能很好地工作。
  • 需要 Image / audio / video generation? 直接调用相应 provider 时,使用该 provider 的原生 single-call node(OpenAI Image、Gemini Image、ElevenLabs 等)。通过 aggregator(OpenRouter、Together 等)路由时则使用 HTTP Request,因为不存在原生 aggregator node,而且原生 node 会在 media operation 中硬编码其 provider 的 base URL。不要将媒体生成包装在 Agent 中,请参阅下文“Binary 与 Agent 边界”。
还有一些适用于特定任务的 LangChain “chain” / utility nodes:Information Extractor(从文本中提取结构化字段)、Sentiment Analysis(三路分支)、Summarization Chain、Basic LLM Chain。
Agent 是大多数 LLM steps 的合理默认选择。当你明确希望使用更精简的节点完成无 tools、memory 或 iteration 的 one-shot text call 时,再选择 Basic LLM Chain。当 Information Extractor / Sentiment Analysis / Summarization Chain / Text Classifier 与任务完全匹配时,应优先使用这些专用节点。

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. Tool names 和 descriptions 是 prompt 的一部分。 模型会根据 name 和 description 选择 tools。含糊的 tool node names(如
    doStuff
    )或薄弱的 descriptions(如“处理数据”)会造成静默失败:模型会跳过该 tool、选错 tool,或产生不存在的 parameters。应像设计 API 一样对待二者。参阅
    references/TOOLS.md
    。
  2. Structured output:既要 parse,也要 autoFix。 使用带有
    autoFix: true
    的
    outputParserStructured
    ,并配置具备 coding 能力的 fixer model(例如 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
    .
  • Tool descriptions 应作为模块化的 prompt fragments。 任何与如何调用这个 tool有关的具体内容都应放在 tool description 中,而不是 system prompt 中。这样可以让 system prompt 保持聚焦,并使 tools 能够在不同 agents 中复用。参阅
    references/SYSTEM_PROMPT.md
    。
  • 任何多步骤操作都应使用 Sub-workflow tools(
    toolWorkflow
    )。
    任意 workflow 都可以成为带有 typed
    fromAi()
    inputs 的 tool,并可与 branching、error handling、sub-workflows 组合。参阅
    references/SUBWORKFLOW_AS_TOOL.md
    。
  • 将具有 user-visible side effects 的 tools 置于 human review 之后。 发送、付款、退款、账户变更等操作都应先经过 Slack / Chat / Discord / Telegram approval node,由人工批准后再执行 tool。参阅
    references/HUMAN_REVIEW.md
    。

The sub-node pattern

Sub-node 模式

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 节点有一个 main input(prompt 或 user message),以及以下 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
        },
    },
})
四个 sub-node slots:
  • model
    (必填)
    :language model。OpenAI、Anthropic、OpenRouter 等。使用 chat-model variants,不要使用 completion variants。
  • memory
    (可选)
    :conversation memory。没有它,每次调用都是无状态的。参阅
    references/MEMORY.md
    。
  • tools
    (可选,但这是使用 agent 的主要意义所在)
    :agent 可以调用的 tools。参阅
    references/TOOLS.md
    。
  • outputParser
    (可选)
    :强制生成 structured JSON output。参阅
    references/STRUCTURED_OUTPUT.md
    。

Triggers

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.
  • 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_SURFACE_PATTERNS.md
    . A first-class n8n Agent can connect to Slack, Telegram, Discord, and Linear natively with no workflow, see
    n8n-agents-official
    . 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.
不同 triggers 会以不同方式影响输入结构:
  • Chat Trigger(
    @n8n/n8n-nodes-langchain.chatTrigger
    )配合
    availableInChat: true
    :支持画布聊天测试器,方便在构建 agent 时直接进行测试。输入为
    { chatInput, sessionId, files[] }
    。
    sessionId
    是 memory 使用的 key,因此需要在所有需要保持对话连续性的位置传递它。Files 通过
    files[]
    传入,参阅下方 binary 部分。它不是生产环境入口,生产环境应使用 Slack / Discord / Teams / Telegram / webhook。
  • Webhook:输入结构任意,默认没有 session。通过 request body 传递 session/conversation ID,并将其转发给 memory node,以管理对话连续性。
  • External chat surface(Slack、Discord、Teams、Telegram):每个会回复消息的 chat-triggered workflow 都必须过滤掉 bot 自身的 user ID,否则它可能不断循环触发,最终导致 n8n 崩溃。如果相应 surface 支持,优先在 trigger level 进行过滤(Slack 的
    options.userIds
    是排除列表);否则应在 trigger 后的第一个 node 中过滤。不同 surface 的具体语义有所不同,参阅
    references/CHAT_SURFACE_PATTERNS.md
    。First-class n8n Agent 可以原生连接 Slack、Telegram、Discord 和 Linear,无需额外 workflow,参阅
    n8n-agents-official
    。除了防止循环的过滤逻辑外,简单的 bot(trigger → agent → reply)可以在一个 workflow 中完成。当需要 loading UX、sub-agents、跨 surface 复用或可靠的 error handling 时,再拆分为“shell”workflow 和 agent-core sub-workflow。
  • Manual / Schedule:临时调用。除非要明确继续之前的运行,否则 memory 通常没有太大用处。
  • Execute Workflow Trigger(sub-workflow):当一个 agent 本身是另一个 agent 的 tool 时使用。应将 trigger 声明的 inputs 视为契约。

Binary and the agent boundary

Binary 与 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
,模型可以看到上传的文件(vision)。但是,tools 无法接收 binary,
fromAi()
parameters 也只能是 JSON。即使通过非 AI bindings,tools 同样不接受 Base64。
变通方法:在 agent 运行前将 uploads 预存到 storage,把 storage keys 注入 system prompt,再让 tools 接收对应的 string parameter,并在内部重新获取文件。完整模式见
n8n-binary-and-data-official
的
references/AGENT_TOOL_BINARY.md
。
在输出端,Agent 的 output formatter 采用 text 形态(连接了
outputParser
时为 structured-text)。当 model 返回 binary(image bytes、audio bytes、video)时,Agent 完全不会将其暴露出来。下游无法提取这些内容,在 Agent 之后使用 Code 或 Set node 尝试恢复也不可行。对于 one-shot media generation,应直接使用 provider 的原生 single-call node,例如
@n8n/n8n-nodes-langchain.googleGemini
或
@n8n/n8n-nodes-langchain.openAi
。
例外情况是 media step 确实应属于 agent 的一部分,例如它是多个 tools 中需要根据对话上下文选择的一个,或者要编辑之前生成的 image。此时可使用 tool sub-workflow,将结果上传到 storage 并返回 key 或 URL。模式见
n8n-binary-and-data-official
的
references/AGENT_TOOL_BINARY.md
。不要默认采用这种方式。upload + key + re-fetch 路径会增加 nodes 和 storage 依赖,而通常并无必要。只有当 orchestration 确实需要由 agent 选择 tool 时,才应使用它。

What goes in the system prompt vs the tool description

System prompt 与 tool description 中分别应包含什么

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
.
应放入 system prompt应放入 tool description
角色设定、职责、语气这个具体 tool 做什么
Output format 规则(“respond in markdown”)何时使用这个 tool,而不是其他 tool
拒绝与安全行为每个 parameter 的含义及其预期结构
展示协议(“show images via
![]()
markdown”)
正确与错误调用示例
通用 context(当前日期、用户角色)Tool-specific 陷阱(rate limits、edge cases)
工具间流程(“after generating, always show via display protocol”)Tool-specific input transformations
这样做的好处是 tools 可以复用。描述完善的 tool 可用于任何将其加入的 agent,而 system prompt 则专注于角色和共享行为。
如需更深入指导和实际示例,请参阅
references/SYSTEM_PROMPT.md
和
references/TOOLS.md
。

Tool selection: the four types

Tool selection:四种类型

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 tool node?(例如
    slackTool
    、
    gmailTool
    、
    calculatorTool
    )直接使用。它的配置开销最低。
    • 原生 node 缺少某个 operation,或需要 custom params?(例如 node 未暴露某个 Notion endpoint、需要非标准 header,或采用不同的 pagination shape)使用 HTTP Request Tool,并设置该服务的“Predefined Credential Type”。它可以复用现有 OAuth / API-key credential,提供完整 API 访问能力,无需编写 custom auth code。
  • 涉及 multi-step logic,或需要复用项目中已有的 sub-workflow? 使用 Sub-workflow as tool(
    toolWorkflow
    )。任何能够构建为 workflow 的内容,都可以成为带有 typed
    fromAi()
    inputs 的 tool。这是 n8n 中最强大的选项,因此拿不准时默认使用它。参阅
    references/SUBWORKFLOW_AS_TOOL.md
    。
  • 需要调用 agent 可直接编排的 external HTTP API? 使用 HTTP Request Tool。它也适合通过 long-poll callback 处理缓慢的异步工作。
  • 所需 tool 已经是一个已发布且可通过 MCP 访问的 workflow? 使用 MCP tool。它适用于跨 workflow 提供 agent capabilities。参阅
    n8n-extending-mcp-official
    。
有关每种选项的深入指导以及
fromAi()
parameters 的连接方式,请参阅
references/TOOLS.md
。

Human review

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
.
在添加或跳过某个 tool 的 human review 前,先与用户确认。是否需要签核属于 product / policy decision(影响范围、审计要求、用户对模型的信任程度),相比 Agent,用户更适合做出这一决定。应明确提出问题,依据以下标准给出建议,然后由用户决定。
当 tool 的 effects 在执行前需要 human approval(发送、付款、退款、账户变更、面向用户的操作)时,使用 review tool node 包装它,例如
slackHitlTool
、
discordHitlTool
、
telegramHitlTool
、
gmailHitlTool
等。n8n 的 node names 对 human-in-the-loop 模式使用
Hitl
,UI 中则将其称为“human review”。review node 位于被包装的 tool 与 agent 之间,并连接在
ai_tool
connection 上:被包装 tool 的
ai_tool
output 连接到 review node,review node 的
ai_tool
output 再连接到 Agent。Agent 的调用会经过该节点,review node 暂停流程等待批准;批准后,被包装的 tool 才会执行。
以下情况默认建议使用 human review:
  • tool 会发送消息、付款、退款,或以其他方式修改用户可见的状态。
  • 审批者与聊天参与者不同,例如经理审批客户操作、支持团队审批客户触发的退款。
  • trigger 是非交互式的(订单、表单、schedule),但 tool 的 effects 需要人工签核。
Approval messages 应显示被包装 tool 将收到的实际 parameters,而不是由 model 改写的文本。直接使用
$tool.parameters.<name>
,或遍历
$tool.parameters
列出所有 params。不要通过
fromAi()
填充 approval text,否则批准的只是改写内容,而不是实际调用。应使用实际值自定义按钮标签,例如
Approve {{ $tool.parameters.amount }} refund
。
完整的配置模式、各平台设置以及多渠道审批者模式见
references/HUMAN_REVIEW.md
。

Output parsing: when and how

Output parsing:何时以及如何使用

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
.
当下游需要 structured data,而不是 free-form text 时,添加
outputParser
sub-node。
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. 使用
    schemaType: 'manual'
    和真实的 JSON schema,不要使用
    jsonSchemaExample
    。
    示例无法表达 optional fields、enums、value ranges 或 array constraints,因此数据结构刚开始变得复杂时,很快就会遇到局限。Schema 可以标记 required 与 optional fields、定义 enums、约束 numbers 和 string formats,并为 model 提供更清晰的规则。只有在处理确定永远不会增加约束的一次性结构时,才使用
    schemaType: 'fromJson'
    搭配示例。
  2. autoFix: true
    会在 parse failure 后添加 retry。
    将具备 coding 能力的 model 接入 fixer sub-node,例如 Claude Sonnet 4.6 或同类模型。依据 schema 修复格式错误的 JSON 属于 structured-output / coding 任务,能力较弱或过于通用的 model 经常只会再次生成格式错误的内容,从而失去 autoFix 的意义。
包含 custom retry prompts 在内的完整模式见
references/STRUCTURED_OUTPUT.md
。

Memory: brief mental model

Memory:简要心智模型

  • 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
.
  • No memory:无状态。适用于 one-shot tasks(分类、摘要)。
  • memoryBufferWindow
    :按 memory key 保留最近 N 条 messages,并通过 n8n 的 internal store 跨 executions 持久化。Key 是绑定到
    sessionKey
    的任意 expression。Chat triggers 会自动填充
    sessionId
    ,但也可以使用其他值作为 key,例如 Slack
    thread_ts
    、webhook conversation ID 或 multi-tenant composite。它是 chat memory 的默认选择。“window”表示上下文窗口中最多保留多少条 messages 的滑动上限,而不是持久化范围。
  • memoryPostgres
    /
    memoryRedis
    或类似节点
    :当需要在 agent 之外查询或读取 memory 时使用,例如在自己的 UI 中显示 conversation history、分析过去的 chats,或与其他系统共享 memory。否则
    memoryBufferWindow
    已经足够。
应始终从 trigger 向 memory 一致地传递稳定的 key,否则不同 conversations 可能会串联。参阅
references/MEMORY.md
。

RAG (retrieval augmented generation)

RAG(retrieval augmented generation)

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 primitives:document loaders、text splitters、embeddings、vector stores、retrievers、rerankers。这些组件可以协同工作,但高度依赖数据形态和规模的具体端到端方案(选择哪种 vector store、如何 chunking、何时 rerank)也存在很大差异。
本 skill 有意尽量不预设 RAG 方案。更多细节见
references/RAG.md
。

Reference files

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_SURFACE_PATTERNS.md
Building a chat bot workflow on Slack, Discord, Teams, Telegram, or any custom chat surface: shell + core + sub-agents, including a first-class Agent as the core via Message an Agent
文件何时阅读
references/TOOLS.md
为 agent 添加 tools、在四种 tool types 之间选择、编写 tool names 和 descriptions
references/SUBWORKFLOW_AS_TOOL.md
通过
toolWorkflow
将 sub-workflow 接入为 agent tool,以及映射
fromAi
overrides
references/SYSTEM_PROMPT.md
编写或重构 system prompt,以及决定内容应放入 system prompt 还是 tool descriptions
references/STRUCTURED_OUTPUT.md
强制 JSON output、配置 autoFix retries、验证下游数据
references/MEMORY.md
选择 memory type、持久化及 sessionId 处理
references/RAG.md
构建 retrieval-augmented agents;该文件有意仅提供基础内容
references/HUMAN_REVIEW.md
为 tool 添加 human approval、配置 approval messages、multi-channel approver patterns
references/CHAT_SURFACE_PATTERNS.md
在 Slack、Discord、Teams、Telegram 或其他 custom chat surface 上构建 chatbot workflow:shell + core + sub-agents,包括通过 Message an Agent 使用 first-class Agent 作为 core

Anti-patterns

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_SURFACE_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"
Anti-pattern会发生什么问题修复方式
Generic tool names(
doStuff
、
runQuery
)
模型无法判断应该选择哪个 tool,会跳过它们或产生不存在的 parameters使用动词开头且具体的名称,例如
Search customer database
、
Generate image with Veo
Empty 或只有一行的 tool descriptions模型不知道何时调用,导致选择效果不佳编写真实描述:它做什么、何时使用、parameters 的含义
将所有内容都塞入 system promptPrompt 臃肿、无法复用,tool-specific guidance 难以被发现将 tool-specific instructions 移到 tool descriptions,让 system prompt 只保留 persona 和 global rules
在 sub-workflow 可以完成时仍使用 Code-node tool无法复用、无法独立测试、无法与 branching 组合使用带有适当 sub-workflow 的
toolWorkflow
直接向 tool 传递 binary不起作用,binary 无法跨越 tool boundary预存到 storage,通过
fromAi
传递 keys,由 tool 在内部获取。参阅
n8n-binary-and-data-official
使用
outputParserStructured
但不启用
autoFix
一次错误的 model output 就会导致 workflow 失败设置
autoFix: true
,并使用成本较低的 fixer model
硬编码
sessionId
或完全不提供
sessionId
Conversations 串联或 memory 永远无法匹配始终将 trigger 中的 sessionId 传给 memory 和 tools
使用两个几乎相同的 tools,而不是让一个 tool 内部 branching模型变得困惑,选择结果不确定使用一个 tool,并通过 parameters 在内部 branching
硬编码会在 workflows 间复用或经常迭代的 system prompt修改时需要重新发布,无法跨 workflows 共享,调优内容散落在 node JSON 中存入 Data Table,并在运行时加载
将 image / audio / video generation 包装在 Agent 中Binary 无法通过 tools 流动,也无法从 output formatter 输出,Agent 只会增加 nodes直接使用 provider 的原生 single-call node(OpenAI Image、Gemini Image、ElevenLabs);仅在通过 aggregator 时使用 HTTP Request
使用 Agent + Switch 根据 natural-language input 进行路由需要两个 nodes 和 prompt boilerplate,而 Text Classifier 仅需一个 node 就内置 N 个 output branches使用 Text Classifier(
@n8n/n8n-nodes-langchain.textClassifier
),为每个 category 设置独立的 output handle,并直接连接下游 paths
Tool 会修改 user-visible state(send、pay、refund),但没有 human reviewAgent 可能因错误推断而执行不可逆操作使用适合当前 channel 的 review tool node(Slack/Chat/Discord/Telegram),并通过
$tool.parameters
显示实际 params
通过
fromAi()
填充 review approval message
Model 会改写内容,导致用户批准的是文本而非实际 values直接使用
$tool.parameters.<name>
,确保实际调用清晰可见
Chat-triggered agent workflow 在回复消息时未过滤 bot 自身的 user IDBot 自己的消息会再次触发 workflow,形成无限循环,消耗 runs 和 tokens,直到触发 rate limits 或被 n8n concurrency 停止可用时优先在 trigger level 过滤(Slack Trigger 的
options.userIds
是排除列表,将 bot ID 放入其中)。否则,在 trigger 后的第一个 node 中使用
$json.user !== '<BOT_USER_ID>'
(或对应 surface 的等效方式)进行过滤。任何会发送回复的 chat-triggered workflow(Slack、Discord、Teams、Telegram)都必须执行此操作,无论其复杂程度如何。各 surface 的具体语义见
references/CHAT_SURFACE_PATTERNS.md
Agent 返回 Block Kit 时,将裸 blocks array 传给 Slack node 的
blocksUi
Slack node 会静默接受输入并发布消息,但不会包含 rich content;没有 error,也没有 warning包装为
{ "blocks": [...] }
,其中 value 必须是真正的 array,而不是字符串化形式。Expression:
={{ { "blocks": $('Agent').item.json.output.blocks } }}
。参阅
n8n-node-configuration-official
的
references/COMMS_NODES.md
中“Block Kit messages”部分