n8n-agents

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

n8n Agents

n8n AI Agent

The n8n AI Agent node (
@n8n/n8n-nodes-langchain.agent
) is a multi-turn LLM driver with sub-nodes for the model, memory, tools, and an optional output parser. This skill is the deep guide to designing agents and the LangChain family around them. For the high-level "where an agent fits in a workflow" picture, see n8n-workflow-patterns
ai_agent_workflow.md
— this skill goes one level down into how to build it well.
For node-type formats: in workflow JSON the LangChain nodes use the long
@n8n/n8n-nodes-langchain.*
form (
.agent
,
.lmChatOpenAi
,
.memoryBufferWindow
,
.outputParserStructured
,
.toolWorkflow
,
.toolHttpRequest
,
.toolCode
). When you call
get_node
/
validate_node
, use the short form (
nodes-langchain.agent
). See n8n-mcp-tools-expert for the format rules.

n8n AI Agent节点(
@n8n/n8n-nodes-langchain.agent
)是一个多轮LLM驱动节点,包含模型、记忆、工具以及可选的输出解析器等子节点。本指南是关于设计Agent及其周边LangChain生态的深度教程。如需了解“Agent在工作流中的定位”等宏观内容,请查看n8n-workflow-patterns
ai_agent_workflow.md
——本指南将深入讲解如何构建高质量的Agent。
关于节点格式:在工作流JSON中,LangChain节点使用完整的
@n8n/n8n-nodes-langchain.*
格式(如
.agent
.lmChatOpenAi
.memoryBufferWindow
.outputParserStructured
.toolWorkflow
.toolHttpRequest
.toolCode
)。调用
get_node
/
validate_node
时,请使用简写格式(
nodes-langchain.agent
)。格式规则请参考n8n-mcp-tools-expert

Pick the right node first

先选择正确的节点

Reaching for an Agent when the task is one-shot classification or extraction is the most common over-build. Decide before you wire anything:
You need to…UseWhy
Call tools, reason over multiple turns, or hold memoryAI Agent (
.agent
)
The full loop: model + tools + memory + optional parser. Also a fine default when you'd rather standardize.
One-shot text in → text out, no toolsBasic LLM Chain (
.chainLlm
)
No agent loop, easier to debug. Still accepts an
outputParserStructured
sub-node.
Route a natural-language input to one of N branchesText Classifier (
.textClassifier
)
ONE node, N output handles, downstream wires directly into each. Not Agent + Switch.
Pull structured fields out of free textInformation Extractor (
.informationExtractor
)
Purpose-built field extraction with a schema.
3-way positive/neutral/negative splitSentiment Analysis (
.sentimentAnalysis
)
Built-in branch outputs.
Condense a long documentSummarization Chain (
.chainSummarization
)
Map-reduce summarization built in.
Generate an image / audio / videoThe provider's native single-call node (OpenAI, Gemini, ElevenLabs…)NEVER wrap media generation in an Agent — see "Binary and the agent boundary".
Text Classifier detail (the Agent + Switch anti-pattern): every category needs both a name AND a description. The model routes against the description, not the name — a category with no description gets picked by coin-flip. Set
options.enableAutoFixing: true
for robustness on edge inputs. One node, N branches, done. Reaching for an Agent that "decides" then a Switch that "routes" is two nodes plus prompt boilerplate for what Text Classifier does natively.
Chat-model nodes (
.lmChatOpenAi
,
.lmChatAnthropic
,
.lmChatOpenRouter
, …) are sub-nodes — they don't run standalone. They wire into a chain, agent, classifier, or extractor via the
ai_languageModel
connection.

当任务是单次分类或提取时就使用Agent,是最常见的过度设计。在搭建任何节点前,请先明确需求:
你需要……使用原因
调用工具、多轮推理或保留对话记忆AI Agent
.agent
完整闭环:模型+工具+记忆+可选解析器。当你希望标准化实现时,也是不错的默认选择。
单次文本输入→文本输出,无需工具基础LLM链
.chainLlm
无Agent循环,更易调试。仍支持接入
outputParserStructured
子节点。
将自然语言输入路由至N个分支之一文本分类器
.textClassifier
单个节点,N个输出端口,可直接连接下游节点。无需使用Agent+Switch组合。
从自由文本中提取结构化字段信息提取器
.informationExtractor
专为字段提取设计,支持自定义Schema。
三元情感划分(正面/中性/负面)情感分析
.sentimentAnalysis
内置分支输出。
浓缩长文档摘要链
.chainSummarization
内置Map-Reduce摘要逻辑。
生成图片/音频/视频服务商原生单次调用节点(OpenAI、Gemini、ElevenLabs等)切勿将媒体生成封装在Agent中——详见“二进制数据与Agent边界”部分。
文本分类器细节(Agent+Switch反模式):每个分类类别都需要名称和描述。模型会根据描述进行路由,而非名称——没有描述的类别会被随机选择。设置
options.enableAutoFixing: true
可提升边缘输入场景的鲁棒性。单个节点即可实现N分支路由,无需使用“Agent做决策+Switch做路由”的组合,后者需要两个节点及额外的提示词模板,而文本分类器可原生实现该功能。
聊天模型节点(
.lmChatOpenAi
.lmChatAnthropic
.lmChatOpenRouter
等)是子节点——无法独立运行。它们需通过
ai_languageModel
连接方式接入链、Agent、分类器或提取器。

The sub-node pattern

子节点模式

The Agent has a main input (the prompt / user message) and up to four sub-node slots, each wired by its own
ai_*
connection type:
SlotConnection typeRequired?Node example
model
ai_languageModel
Yes
.lmChatOpenAi
,
.lmChatAnthropic
,
.lmChatOpenRouter
memory
ai_memory
Optional
.memoryBufferWindow
,
.memoryPostgresChat
tools
ai_tool
Optional (but the point of an agent)
slackTool
,
.toolWorkflow
,
.toolHttpRequest
,
.toolCode
outputParser
ai_outputParser
Optional
.outputParserStructured
A sub-node connects FROM itself TO the agent. In workflow JSON the connection lives on the sub-node, keyed by the
ai_*
type:
json
"Main LLM": {
  "ai_languageModel": [[{ "node": "AI Agent", "type": "ai_languageModel", "index": 0 }]]
},
"Simple Memory": {
  "ai_memory": [[{ "node": "AI Agent", "type": "ai_memory", "index": 0 }]]
},
"Search customer DB": {
  "ai_tool": [[{ "node": "AI Agent", "type": "ai_tool", "index": 0 }]]
}
Multiple tools all connect into the same
ai_tool
index 0 — they stack, they don't fan into separate indices. With
n8n_update_partial_workflow
you wire each with an
addConnection
op using
sourceOutput: "ai_tool"
. The agent puts its final answer in
$json.output
(not
.text
, not
.response
) — downstream nodes read
{{ $json.output }}
.
See EXAMPLES.md for a complete stateless agent-core node-object snippet.

Agent拥有一个主输入(提示词/用户消息)和最多四个子节点插槽,每个插槽通过专属的
ai_*
连接类型接入:
插槽连接类型是否必填节点示例
model
ai_languageModel
.lmChatOpenAi
.lmChatAnthropic
.lmChatOpenRouter
memory
ai_memory
.memoryBufferWindow
.memoryPostgresChat
tools
ai_tool
否(但这是Agent的核心价值)
slackTool
.toolWorkflow
.toolHttpRequest
.toolCode
outputParser
ai_outputParser
.outputParserStructured
子节点需从自身连接至Agent。在工作流JSON中,连接信息存储在子节点中,以
ai_*
类型作为键:
json
"Main LLM": {
  "ai_languageModel": [[{ "node": "AI Agent", "type": "ai_languageModel", "index": 0 }]]
},
"Simple Memory": {
  "ai_memory": [[{ "node": "AI Agent", "type": "ai_memory", "index": 0 }]]
},
"Search customer DB": {
  "ai_tool": [[{ "node": "AI Agent", "type": "ai_tool", "index": 0 }]]
}
多个工具可接入同一个
ai_tool
索引0——它们会堆叠,而非分散到不同索引。使用
n8n_update_partial_workflow
时,可通过
addConnection
操作,指定
sourceOutput: "ai_tool"
来连接每个工具。Agent的最终结果会输出到**
$json.output
**(不是
.text
.response
)——下游节点需读取
{{ $json.output }}
完整的无状态Agent核心节点代码片段请参考EXAMPLES.md

Two non-negotiables

两项不可妥协的规则

  1. Tool names and descriptions ARE part of the prompt. The model picks a tool by reading its name and description — nothing else. A tool named
    tool1
    with an empty description is invisible to the model: it skips it, mis-selects it, or hallucinates parameters. There's usually no error — just an agent that "won't use my tool". Treat both like API design. → TOOLS.md
  2. Structured output must parse AND autoFix. An
    outputParserStructured
    with
    autoFix: true
    and a coding-capable fixer model is the production pattern. Without autoFix, one malformed JSON response halts the whole workflow. → STRUCTURED_OUTPUT.md

  1. 工具名称和描述是提示词的一部分。模型通过读取工具的名称和描述来选择工具——无其他依据。命名为
    tool1
    且描述为空的工具对模型来说是“不可见”的:模型会跳过它、错误选择它,或生成虚假参数。通常不会报错——只会出现“Agent不使用我的工具”的问题。请像设计API一样对待工具名称和描述。→ TOOLS.md
  2. 结构化输出必须支持解析和自动修复。配置
    autoFix: true
    outputParserStructured
    节点,搭配具备编码能力的修复模型,是生产环境的标准方案。如果没有自动修复,一次格式错误的JSON响应就会导致整个工作流中断。→ STRUCTURED_OUTPUT.md

Strong defaults

推荐默认配置

  • Per-tool usage goes in the tool description, not the system prompt. Anything about how to call this specific tool belongs with the tool, so it travels across agents and keeps the system prompt focused. → 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, and reuse. Default here when in doubt. → SUBWORKFLOW_AS_TOOL.md and n8n-subworkflows.
  • Wrap tools with user-visible side effects in human review. Sends, payments, refunds, account changes get gated behind an approval node so a human signs off before the tool fires. → HUMAN_REVIEW.md
  • Raise
    maxIterations
    .
    The default tool-call cap is low (single digits on most versions) — fine for a one-tool agent, far too low for a multi-tool agent that chains several calls per turn. It surfaces as "max iterations reached" or empty output. Set
    options.maxIterations
    to a realistic ceiling (15 for a focused sub-agent, 50-200 for a broad orchestrator).
  • Put the current date in the system prompt via
    {{ $now }}
    (or
    {{ $now.format('DDDD') }}
    ). A hardcoded date is stale immediately.

  • 工具的使用说明应放在工具描述中,而非系统提示词。任何与“如何调用该特定工具”相关的内容都应与工具绑定,这样工具可在不同Agent间复用,同时保持系统提示词的简洁性。→ SYSTEM_PROMPT.md
  • 多步骤任务使用子工作流工具(
    .toolWorkflow
    。任何工作流都可通过带类型的
    $fromAI()
    输入转换为工具,支持分支、错误处理和复用。不确定时优先选择此方案。→ SUBWORKFLOW_AS_TOOL.mdn8n-subworkflows
  • 对有用户可见副作用的工具添加人工审核。发送消息、支付、退款、账户变更等操作需通过审批节点,确保工具执行前需人工确认。→ HUMAN_REVIEW.md
  • 提高
    maxIterations
    。默认的工具调用次数上限非常低(大多数版本为个位数)——适合单工具Agent,但远不足以支撑多工具Agent的多轮调用。问题表现为“达到最大迭代次数”或输出为空。将
    options.maxIterations
    设置为合理的上限(专注型子Agent设为15,通用编排型设为50-200)。
  • 在系统提示词中通过
    {{ $now }}
    (或
    {{ $now.format('DDDD') }}
    )添加当前日期
    。硬编码的日期会立即失效。

The four tool types

四种工具类型

Pick the lightest option that covers the job:
Tool typeNodeUse when
Native tool node
slackTool
,
gmailTool
,
toolCalculator
, …
The capability maps to one existing node + one operation. Lowest overhead.
Sub-workflow as tool
.toolWorkflow
More than one node, reusable logic, or you want independent testability. The canonical n8n way — default when in doubt.
HTTP Request Tool
.toolHttpRequest
A single external HTTP API the agent should orchestrate directly. Reuse the service's predefined credential to cover operations a native node doesn't expose.
MCP Client Tool
.mcpClientTool
A maintained MCP server already covers it, or you want one published workflow to serve many agents.
There is also a Custom Code Tool (
.toolCode
) for pure inline computation — but its runtime contract (string in / string out, no
$fromAI
, no
$helpers
) is owned by the n8n-code-tool skill. Read that before writing one. Rule of thumb: if you find yourself reaching for
$fromAI()
inside the code, you want
.toolWorkflow
instead.
选择能满足需求的最轻量方案:
工具类型节点使用场景
原生工具节点
slackTool
gmailTool
toolCalculator
功能对应单个现有节点+单个操作。开销最低。
子工作流工具
.toolWorkflow
需要多个节点、可复用逻辑或独立可测试性。n8n的标准方案——不确定时优先选择
HTTP请求工具
.toolHttpRequest
Agent需直接编排单个外部HTTP API。复用服务预定义的凭证,可覆盖原生节点未暴露的操作。
MCP客户端工具
.mcpClientTool
已有维护中的MCP服务器,或希望单个发布的工作流为多个Agent提供服务。
还有自定义代码工具
.toolCode
)用于纯内联计算——但其运行时约定(字符串输入/输出,不支持
$fromAI
$helpers
)由n8n-code-tool技能负责。编写前请先阅读该技能。经验法则:如果需要在代码中使用
$fromAI()
,则应选择
.toolWorkflow

$fromAI()
: how the agent fills tool parameters

$fromAI()
:Agent如何填充工具参数

Tool parameters the agent should decide are wrapped in
$fromAI()
. It is a real n8n expression helper, used inside a tool node's parameter expressions:
={{ $fromAI('paramName', 'what to put here — be specific: format, range, example', 'string') }}
  • paramName — the name the model uses internally (snake_case or camelCase, be consistent).
  • description — tells the model what value to produce. It is part of the prompt — write it like JSDoc.
  • type (optional) —
    'string'
    (default),
    'number'
    ,
    'boolean'
    ,
    'json'
    . A wrong-typed value fails the call.
  • defaultValue (optional) — used when the model omits it.
$fromAI()
carries JSON only — it cannot carry binary (no base64, no file bytes). And not every parameter has to be
$fromAI
: plumb identity, authority limits, and correlation IDs (
userId
, refund caps,
sessionId
) deterministically from workflow context so the agent can't get them wrong or even see them. → TOOLS.md for the full anatomy and the "give the agent a button, not a steering wheel" pattern.

Agent需要决定的工具参数需用
$fromAI()
包裹。这是一个真实的n8n表达式助手,用于工具节点的参数表达式中:
={{ $fromAI('paramName', '此处需明确:格式、范围、示例', 'string') }}
  • paramName —— 模型内部使用的参数名称(蛇形命名或驼峰命名,保持一致)。
  • description —— 告知模型需要生成的值。这是提示词的一部分——请像编写JSDoc一样描述。
  • type(可选)——
    'string'
    (默认)、
    'number'
    'boolean'
    'json'
    。类型错误的值会导致调用失败。
  • defaultValue(可选)—— 模型未提供参数时使用的默认值。
$fromAI()
仅支持JSON数据——无法传递二进制数据(不支持base64、文件字节)。并非所有参数都需要
$fromAI
:身份信息、权限限制、关联ID(
userId
、退款上限、
sessionId
)应从工作流上下文确定性地传递,避免Agent出错或篡改。→ TOOLS.md查看完整结构及“给Agent按钮而非方向盘”的设计模式。

System prompt vs tool description

系统提示词 vs 工具描述

Belongs in the system promptBelongs in the tool's description
Persona, role, voiceWhat this specific tool does
Global output/format rules ("respond in markdown")When to use it vs other tools
Refusal / safety behaviorWhat each parameter means and its shape
Display protocols (
![]()
for images)
Examples of good vs bad invocations
Universal context (current date via
$now
, user role)
Tool-specific gotchas (rate limits, edge cases)
Inter-tool flow ("after generating, always display")Tool-specific input transformations
Why split it: a well-described tool works in any agent that drops it in, tool details only "load" when the model considers that tool (token efficiency), and you update one tool description instead of a paragraph buried in a 5000-token prompt. → SYSTEM_PROMPT.md

属于系统提示词的内容属于工具描述的内容
角色设定、职责、语气该特定工具的功能
全局输出/格式规则(如“用Markdown回复”)何时使用该工具而非其他工具
拒绝/安全行为每个参数的含义及格式
展示协议(如图片使用
![]()
正确/错误调用示例
通用上下文(如通过
$now
获取当前日期、用户角色)
工具特定注意事项(速率限制、边缘场景)
工具间流程(如“生成后始终展示”)工具特定输入转换规则
拆分原因:描述清晰的工具可在任何Agent中复用,工具细节仅在模型考虑使用该工具时才会“加载”(提升Token效率),且只需更新工具描述,无需修改嵌入在5000Token提示词中的段落。→ SYSTEM_PROMPT.md

Structured output: when and how

结构化输出:场景与实现

Add an
outputParserStructured
sub-node (wired
ai_outputParser
) when downstream needs strict JSON, not free-form text. Two rules:
  1. Use
    schemaType: 'manual'
    with a real JSON Schema, not
    jsonSchemaExample
    .
    An example can't express required-vs-optional, enums, numeric ranges, or array constraints — you outgrow it the first time the shape gets non-trivial. Reach for
    fromJson
    + an example only for throwaway shapes.
  2. autoFix: true
    with a coding-capable fixer model.
    Wire a second model into the parser's
    ai_languageModel
    slot. Reconciling broken JSON against a schema is a coding task — a weak fixer just produces another malformed retry and burns tokens.
STRUCTURED_OUTPUT.md for the schema patterns, the load-bearing "DO NOT wrap in markdown" retry line, and the parse-failure cookbook.

当下游需要严格的JSON而非自由文本时,添加
outputParserStructured
子节点(通过
ai_outputParser
连接)。需遵循两条规则:
  1. 使用
    schemaType: 'manual'
    并配置真实的JSON Schema,而非
    jsonSchemaExample
    。示例无法表达必填/可选字段、枚举值、数值范围或数组约束——当结构变得复杂时,示例方案会立即失效。仅在临时结构场景下使用
    fromJson
    +示例。
  2. 开启
    autoFix: true
    并搭配具备编码能力的修复模型
    。将第二个模型接入解析器的
    ai_languageModel
    插槽。根据Schema修复错误JSON是编码任务——弱修复模型只会生成另一个格式错误的重试结果,浪费Token。
STRUCTURED_OUTPUT.md查看Schema模式、关键的“请勿用Markdown包裹”重试语句,以及解析失败解决方案。

Memory: brief mental model

记忆:简要模型

Memory is a sub-node (
ai_memory
). Without it, every call is stateless — correct for one-shot tasks (classify, summarize). With it, the agent holds a conversation, keyed by whatever expression you bind to
sessionKey
.
  • memoryBufferWindow
    — keeps the last N exchanges per key and persists across executions via n8n's store. The default for chat.
    contextWindowLength
    defaults to 5, which is very low
    — 50 is a saner starting point. Messages past the window are gone entirely.
  • memoryPostgresChat
    /
    memoryRedisChat
    — only when memory must be read outside the agent (your own UI, analytics, cross-system). Not needed just to survive restarts; BufferWindow already does that.
Plumb a stable key from the trigger to memory consistently. Chat triggers fill
sessionId
automatically; for other surfaces derive one (Slack
thread_ts
, a webhook conversation ID). Never hardcode
sessionId: 'default'
and never put
sessionId
behind
$fromAI
(the model will fabricate a UUID). → MEMORY.md

记忆是一个子节点(
ai_memory
)。没有记忆时,每次调用都是无状态的——适合单次任务(分类、摘要)。开启记忆后,Agent可通过绑定到
sessionKey
的表达式来维持对话状态。
  • memoryBufferWindow
    —— 为每个键保留最近N次对话,并通过n8n存储跨执行持久化。是聊天场景的默认选择。
    contextWindowLength
    默认值为5,非常低
    ——建议从50开始设置。超出窗口的消息会被完全丢弃。
  • memoryPostgresChat
    /
    memoryRedisChat
    —— 仅当记忆需要在Agent外部读取时使用(如自定义UI、分析、跨系统调用)。仅为了重启后保留记忆无需使用该方案;BufferWindow已支持持久化。
从触发器稳定传递键到记忆节点。聊天触发器会自动填充
sessionId
;其他场景需自行生成(如Slack的
thread_ts
、Webhook的对话ID)。切勿硬编码
sessionId: 'default'
,也不要将
sessionId
放在
$fromAI
之后(模型会生成虚假的UUID)。→ MEMORY.md

Binary and the agent boundary

二进制数据与Agent边界

This is the seam that trips people up:
  • The model CAN see uploaded images (vision) via
    options.passthroughBinaryImages: true
    on the agent.
  • Tools CANNOT receive binary.
    $fromAI()
    is JSON-only — no base64, no bytes, even through non-AI bindings.
  • The agent's output is text-shaped (or structured-text with a parser). When a model returns image/audio/video bytes, the Agent doesn't surface them at all — there's nothing to recover downstream.
Workaround: pre-stage uploads to storage before the agent runs, inject the storage keys into the system prompt, and let tools accept the key as a string parameter and re-fetch internally. For one-shot media generation, skip the agent and call the provider's native single-call node directly.
The binary mechanics (which storage, how to stage, how to re-fetch) are owned by n8n-binary-and-data — see its agent-tool binary reference. This skill only marks the boundary; don't re-derive the mechanics here.

这是最容易出错的环节:
  • 模型可查看上传的图片(视觉能力),需在Agent上设置
    options.passthroughBinaryImages: true
  • 工具无法接收二进制数据
    $fromAI()
    仅支持JSON——不支持base64、字节,即使通过非AI绑定也不行。
  • Agent的输出为文本格式(或通过解析器输出结构化文本)。当模型返回图片/音频/视频字节时,Agent不会输出任何内容——下游无法恢复这些数据。
解决方案:在Agent运行前将文件上传到存储服务,将存储密钥注入系统提示词,让工具接收密钥作为字符串参数并在内部重新获取文件。对于单次媒体生成任务,跳过Agent直接调用服务商的原生单次调用节点。
二进制数据的具体机制(选择哪种存储、如何上传、如何重新获取)由n8n-binary-and-data技能负责——请查看其Agent工具二进制参考文档。本指南仅界定边界,不重复推导具体实现。

Human review (gate destructive tools)

人工审核(限制高风险工具)

When a tool's effect needs human sign-off before execution (sends, payments, refunds, account changes), wrap it with a review tool node —
slackHitlTool
,
discordHitlTool
,
telegramHitlTool
,
gmailHitlTool
, etc. (n8n names these "Hitl" / human-in-the-loop). The review node sits between the wrapped tool and the agent on the
ai_tool
connection: wrapped tool → review node → Agent.
Whether sign-off is needed is a product/policy call — surface the question to the user, recommend based on blast radius, and let them decide.
The critical rule: show the actual parameters the wrapped tool will receive. Use the literal
{{ $tool.parameters.<name> }}
in the approval message, never a
$fromAI()
paraphrase — otherwise the human approves text the model made up, not the call about to fire. → HUMAN_REVIEW.md

当工具执行的操作需要人工确认时(如发送消息、支付、退款、账户变更),请使用审核工具节点包裹——如
slackHitlTool
discordHitlTool
telegramHitlTool
gmailHitlTool
等(n8n将这些命名为“Hitl”/人工介入)。审核节点需位于被包裹工具与Agent之间
ai_tool
连接链中:被包裹工具→审核节点→Agent。
是否需要确认属于产品/政策决策——需向用户明确该问题,根据影响范围给出建议,由用户决定。
关键规则:展示被包裹工具将接收的真实参数。在审批消息中使用字面量
{{ $tool.parameters.<name> }}
,切勿使用
$fromAI()
生成的转述——否则人工审核的是模型生成的文本,而非即将执行的真实调用。→ HUMAN_REVIEW.md

Chat agents (Slack, Discord, Teams, Telegram)

聊天Agent(Slack、Discord、Teams、Telegram)

The one non-negotiable, regardless of complexity: any chat-triggered workflow that posts a reply MUST filter out the bot's own user ID, or its own replies re-trigger it in an infinite loop that burns runs and tokens. Prefer trigger-level filtering when available (Slack Trigger's
options.userIds
is an exclusion list — put the bot ID there); otherwise filter
$json.user !== '<BOT_USER_ID>'
in the first node after the trigger.
Beyond the filter, a simple bot (trigger → agent → reply) lives fine in one workflow. Split into shell + core + sub-agents only once you need loading UX, sub-agents, multi-surface reuse, or robust error handling:
  • Shell — trigger, anti-loop filter, event-type Switch, loading/error UX, renders the reply. No LLM.
  • Core — stateless agent,
    chatInput
    +
    threadId
    inputs, memory keyed on
    threadId
    , tools and sub-agents.
  • Sub-agents — one narrow domain each, called via
    .toolWorkflow
    , stateless (full context in
    chatInput
    ).
CHAT_AGENT_PATTERNS.md for per-surface semantics, threading-as-session, and the full topology.

无论复杂度如何,必须遵守的规则:任何发送回复的聊天触发工作流都必须过滤机器人自身的用户ID,否则机器人的回复会触发无限循环,消耗运行次数和Token。优先使用触发器级别的过滤(如Slack触发器的
options.userIds
排除列表——将机器人ID加入其中);否则在触发器后的第一个节点中过滤
$json.user !== '<BOT_USER_ID>'
除过滤规则外,简单机器人(触发器→Agent→回复)可在单个工作流中实现。仅当需要加载态UI、子Agent、多渠道复用或健壮的错误处理时,才拆分为外壳+核心+子Agent
  • 外壳——触发器、防循环过滤、事件类型Switch、加载/错误UI、回复渲染。无LLM。
  • 核心——无状态Agent,输入为
    chatInput
    +
    threadId
    ,记忆以
    threadId
    为键,包含工具和子Agent。
  • 子Agent——每个负责一个细分领域,通过
    .toolWorkflow
    调用,无状态(完整上下文在
    chatInput
    中)。
CHAT_AGENT_PATTERNS.md查看各渠道语义、会话线程化以及完整拓扑结构。

RAG (retrieval augmented generation)

RAG(检索增强生成)

n8n ships the LangChain RAG primitives (document loaders, splitters, embeddings, vector stores, retrievers). Two opinions worth stating up front:
  1. Rule out cheaper lookups first. Exact lookups → a database or Data Table query, not RAG. Freshness → a live search tool. A small/structured doc set → give the agent list/fetch tools. Reach for a vector store only when there are too many docs to list and queries are semantic.
  2. Wire the vector store as a retrieval tool (
    mode: 'retrieve-as-tool'
    ,
    ai_tool
    ) so the agent decides when retrieval is relevant and can phrase the query itself. Embed query and documents with the same model.
RAG.md (intentionally thin — defaults depend on data shape and scale).

n8n内置了LangChain的RAG原语(文档加载器、拆分器、嵌入模型、向量存储、检索器)。先明确两个观点:
  1. 优先排除更廉价的查询方案。精确查询→使用数据库或数据表查询,而非RAG。实时数据→使用实时搜索工具。小型/结构化文档集→为Agent提供列表/查询工具。仅当文档数量过多无法列出且查询为语义查询时,才使用向量存储。
  2. 将向量存储作为检索工具接入
    mode: 'retrieve-as-tool'
    ai_tool
    ),让Agent自行决定何时需要检索,并可自行构造查询语句。查询和文档需使用相同的嵌入模型。
RAG.md(内容简洁,因默认配置取决于数据格式和规模)。

Reference files

参考文档

FileRead when
TOOLS.mdAdding tools, choosing among the four types, writing names/descriptions,
$fromAI
anatomy
SUBWORKFLOW_AS_TOOL.mdWiring a sub-workflow as a tool via
.toolWorkflow
, mapping agent-filled vs plumbed params
SYSTEM_PROMPT.mdWriting/refactoring a system prompt, the system-prompt-vs-tool-description split
STRUCTURED_OUTPUT.mdForcing JSON output, configuring autoFix, the fixer model, parse-failure fixes
MEMORY.mdChoosing a memory type, persistence, sessionId handling
HUMAN_REVIEW.mdAdding human approval, approval-message content, multi-channel approver
CHAT_AGENT_PATTERNS.mdBuilding a Slack/Discord/Teams/Telegram bot, shell + core + sub-agents topology
RAG.mdRetrieval-augmented agents (thin by design)
EXAMPLES.mdConcrete node-object snippets: stateless agent core, Slack router shell, domain sub-agent

文件阅读场景
TOOLS.md添加工具、选择工具类型、编写名称/描述、
$fromAI
结构
SUBWORKFLOW_AS_TOOL.md通过
.toolWorkflow
将子工作流配置为工具、映射Agent填充参数与确定性传递参数
SYSTEM_PROMPT.md编写/重构系统提示词、系统提示词与工具描述的拆分规则
STRUCTURED_OUTPUT.md强制JSON输出、配置自动修复、修复模型选择、解析失败解决方案
MEMORY.md选择记忆类型、持久化配置、sessionId处理
HUMAN_REVIEW.md添加人工审核、审核消息内容、多渠道审核人配置
CHAT_AGENT_PATTERNS.md构建Slack/Discord/Teams/Telegram机器人、外壳+核心+子Agent拓扑
RAG.md检索增强型Agent(内容简洁)
EXAMPLES.md具体节点代码片段:无状态Agent核心、Slack路由外壳、领域子Agent

Anti-patterns

反模式

Anti-patternWhat goes wrongFix
Generic tool names (
tool1
,
doStuff
,
runQuery
)
Model can't tell which tool to pick — skips them or hallucinates paramsVerb-first specific names:
Search customer database
,
Generate image with Veo
Empty or one-line tool descriptionsModel has no idea when to invoke; bad selection, no errorWrite a real description: what it does, when to use, what each param means
Cramming per-tool instructions into the system promptBloated prompt, no reuse, per-tool guidance buriedMove tool-specific instructions into tool descriptions
Agent + Switch to route on natural languageTwo nodes + prompt boilerplate where Text Classifier is one nodeUse Text Classifier — each category gets its own output handle (name and description)
Wrapping image/audio/video generation in an AgentBinary doesn't flow through tools or out of the agent outputUse the provider's native single-call node directly
outputParserStructured
without
autoFix
One malformed response halts the workflow
autoFix: true
+ a coding-capable fixer model
Passing binary directly to a toolDoesn't work — binary can't cross the tool boundaryPre-stage to storage, pass keys; see n8n-binary-and-data
Hardcoded
sessionId
/ no sessionId /
sessionId
behind
$fromAI
Conversations cross, or the model fabricates a UUIDPlumb a stable key from the trigger to memory and tools
Two near-identical toolsSelection is non-deterministic, model gets confusedOne tool with internal branching driven by a parameter
Chat bot with no bot-user filterIts own replies re-trigger it → infinite loopExclude the bot user ID at the trigger or first node
maxIterations
left at the low default on a multi-tool agent
"Max iterations reached" / empty outputRaise
options.maxIterations
Filling the human-review message via
$fromAI()
Approver signs off on a paraphrase, not the real callUse literal
{{ $tool.parameters.<name> }}

反模式问题修复方案
通用工具名称(
tool1
doStuff
runQuery
模型无法区分工具——跳过工具或生成虚假参数使用动词开头的具体名称:
Search customer database
Generate image with Veo
工具描述为空或仅一行模型不知道何时调用工具;选择错误,无报错编写完整描述:功能、使用场景、参数含义
将工具专属指令塞入系统提示词提示词臃肿、无法复用、工具相关指引被淹没将工具专属指令移至工具描述
使用Agent+Switch处理自然语言路由需要两个节点+提示词模板,而文本分类器可单个节点实现使用文本分类器——每个类别拥有独立输出端口(需配置名称和描述
将图片/音频/视频生成封装在Agent中二进制数据无法通过工具或Agent输出传递直接调用服务商的原生单次调用节点
outputParserStructured
未开启
autoFix
一次格式错误的响应会中断整个工作流开启
autoFix: true
并搭配具备编码能力的修复模型
直接向工具传递二进制数据无法生效——二进制数据无法跨越工具边界先上传至存储服务,传递密钥;参考n8n-binary-and-data
硬编码
sessionId
/无
sessionId
/
sessionId
通过
$fromAI
传递
会话混乱,或模型生成虚假UUID从触发器稳定传递键到记忆和工具节点
两个几乎相同的工具模型选择不确定,易混淆合并为一个工具,通过参数驱动内部分支
聊天机器人未过滤自身用户ID自身回复触发无限循环在触发器或第一个节点中排除机器人用户ID
多工具Agent保留默认的低
maxIterations
出现“达到最大迭代次数”/输出为空提高
options.maxIterations
通过
$fromAI()
生成人工审核消息
审核人确认的是转述内容,而非真实调用使用字面量
{{ $tool.parameters.<name> }}

What's NOT available via the community MCP

社区MCP不支持的功能

Want to doReality
Run / chat-test the agent end-to-end with live tokens
n8n_test_workflow
runs the workflow, but a true multi-turn chat session is a UI activity (canvas chat tester).
Set credentials' actual secret values
n8n_manage_credentials
creates/updates credential records, but the agent provider keys themselves are entered/verified in the UI.
Assign a workflow's Error WorkflowUI only — see n8n-error-handling. Build the catch-all, then hand the user the UI step.
Pin the exact model availability per instanceModel lists shift between versions —
search_nodes
/
get_node
reflect what's installed. Verify on the target instance.
What the MCP can do: search and inspect every LangChain node (
search_nodes
,
get_node
), validate node config and the whole graph (
validate_node
,
validate_workflow
), build and patch the agent and its sub-nodes (
n8n_update_partial_workflow
with
addConnection
on
ai_*
outputs), test (
n8n_test_workflow
), and pull the saved JSON to verify wiring (
n8n_get_workflow
). The deep AI-agent guide also lives in
tools_documentation({topic: "ai_agents_guide", depth: "full"})
.

需求现状
使用真实Token端到端运行/测试Agent聊天会话
n8n_test_workflow
可运行工作流,但真正的多轮聊天会话是UI操作(画布聊天测试器)。
设置凭证的实际密钥值
n8n_manage_credentials
可创建/更新凭证记录,但Agent服务商密钥需在UI中输入/验证。
为工作流分配错误工作流仅支持UI操作——参考n8n-error-handling。先构建全局错误处理,再指导用户完成UI步骤。
固定实例的精确模型可用性模型列表会随版本变化——
search_nodes
/
get_node
会返回已安装的模型。请在目标实例上验证。
MCP支持的功能:搜索和查看所有LangChain节点(
search_nodes
get_node
)、验证节点配置和整个图谱(
validate_node
validate_workflow
)、构建和修补Agent及其子节点(
n8n_update_partial_workflow
搭配
ai_*
输出的
addConnection
操作)、测试(
n8n_test_workflow
)、以及拉取已保存的JSON验证连接(
n8n_get_workflow
)。深度AI Agent指南也可通过
tools_documentation({topic: "ai_agents_guide", depth: "full"})
获取。

Integration with other skills

与其他技能的集成

  • n8n-workflow-patterns (
    ai_agent_workflow.md
    ) — the high-level "agent in a workflow" shape. This skill is the deep dive; start there for architecture.
  • n8n-mcp-tools-expert — node-type formats (short form for
    get_node
    , long form in JSON) and tool-selection guidance. Consult before any MCP call.
  • n8n-node-configuration
    displayOptions
    -driven fields on the agent and sub-nodes; Slack/Block Kit message shapes (
    NODE_FAMILY_GOTCHAS.md
    , Slack section).
  • n8n-expression-syntax
    {{ }}
    ,
    $json.output
    ,
    $now
    , and
    $fromAI
    /
    $tool.parameters
    all rely on correct expression syntax.
  • n8n-code-tool — the Custom Code Tool's runtime contract (string in/out, no
    $fromAI
    ). Read it before writing a
    .toolCode
    .
  • n8n-subworkflows — the sub-workflow primitive that
    .toolWorkflow
    builds on (Execute Workflow Trigger inputs/outputs, naming, search-before-build).
  • n8n-binary-and-data — owns the agent-tool binary boundary mechanics (staging uploads, returning generated files).
  • n8n-validation-expert — interpreting
    validate_workflow
    results, including AI-connection issues (a tool wired into
    main
    instead of
    ai_tool
    flags as disconnected).
  • n8n-error-handling
    onError: 'continueErrorOutput'
    on tool sub-workflows and the agent-core call; error UX on chat shells.
  • n8n-code-javascript / n8n-code-python — for Code-node logic inside a tool sub-workflow (different sandbox from the Code Tool).

  • n8n-workflow-patterns
    ai_agent_workflow.md
    )——“Agent在工作流中定位”的宏观内容。本指南是深度教程;架构设计请先参考该文档。
  • n8n-mcp-tools-expert——节点格式(
    get_node
    使用简写,JSON中使用完整格式)和工具选择指引。调用任何MCP前请参考该技能。
  • n8n-node-configuration——Agent及其子节点的
    displayOptions
    驱动字段;Slack/Block Kit消息格式(
    NODE_FAMILY_GOTCHAS.md
    的Slack章节)。
  • n8n-expression-syntax——
    {{ }}
    $json.output
    $now
    $fromAI
    /
    $tool.parameters
    都依赖正确的表达式语法。
  • n8n-code-tool——自定义代码工具的运行时约定(字符串输入/输出,不支持
    $fromAI
    )。编写
    .toolCode
    前请阅读该技能。
  • n8n-subworkflows——
    .toolWorkflow
    基于的子工作流原语(Execute Workflow Trigger输入/输出、命名、构建前搜索)。
  • n8n-binary-and-data——负责Agent工具二进制边界的具体实现(上传预存、返回生成文件)。
  • n8n-validation-expert——解读
    validate_workflow
    结果,包括AI连接问题(如工具接入
    main
    而非
    ai_tool
    会标记为未连接)。
  • n8n-error-handling——工具子工作流和Agent核心调用的
    onError: 'continueErrorOutput'
    配置;聊天外壳的错误UI。
  • n8n-code-javascript / n8n-code-python——工具子工作流内部的代码节点逻辑(与代码工具的沙箱不同)。

Quick reference checklist

快速检查清单

Before shipping an agent:
  • Right node: Agent for tools/memory/multi-turn; Text Classifier for routing; Information Extractor for fields; native node for media
  • Model wired via
    ai_languageModel
  • Every tool has a verb-first specific name AND a real description
  • $fromAI()
    descriptions
    are specific (format, range, example); identity/limits/sessionId plumbed deterministically, not via
    $fromAI
  • Per-tool guidance lives in tool descriptions, not the system prompt
  • $now
    in the system prompt (no hardcoded date)
  • maxIterations
    raised for multi-tool agents
  • Memory keyed on a stable
    sessionKey
    from the trigger (not
    'default'
    , not
    $fromAI
    );
    contextWindowLength
    raised from 5
  • Structured output:
    schemaType: 'manual'
    +
    autoFix: true
    + a coding-capable fixer model
  • Destructive tools wrapped in human review; approval message uses
    $tool.parameters
    , not
    $fromAI
  • Chat bots filter the bot's own user ID (trigger-level or first node)
  • Binary: model vision via
    passthroughBinaryImages
    ; tools get storage keys, never bytes
  • Validated with
    validate_workflow
    and verified with
    n8n_get_workflow
    (sub-nodes on
    ai_*
    , not
    main
    )

Remember: an agent is only as good as its tool names, descriptions, and system-prompt discipline. The model can't see your wiring — it sees a system prompt and a list of named, described tools. Design those like an API and most "the agent won't behave" problems disappear.
上线Agent前请确认:
  • 节点选型正确:工具/记忆/多轮任务用Agent;路由用文本分类器;字段提取用信息提取器;媒体生成本地用原生节点
  • 模型已通过
    ai_languageModel
    连接
  • 每个工具都有动词开头的具体名称和完整描述
  • $fromAI()
    描述
    明确(格式、范围、示例);身份/权限/sessionId为确定性传递,未使用
    $fromAI
  • 工具专属指引在工具描述中,而非系统提示词
  • 系统提示词包含
    $now
    (无硬编码日期)
  • 多工具Agent已提高
    maxIterations
  • 记忆以触发器传递的稳定
    sessionKey
    为键(非
    'default'
    ,非
    $fromAI
    );
    contextWindowLength
    已从5提高
  • 结构化输出
    schemaType: 'manual'
    +
    autoFix: true
    + 具备编码能力的修复模型
  • 高风险工具已包裹人工审核;审核消息使用
    $tool.parameters
    ,而非
    $fromAI
  • 聊天机器人已过滤自身用户ID(触发器级别或第一个节点)
  • 二进制数据:模型视觉能力已开启
    passthroughBinaryImages
    ;工具接收存储密钥,而非字节
  • 已验证:通过
    validate_workflow
    验证,并通过
    n8n_get_workflow
    确认连接(子节点通过
    ai_*
    连接,而非
    main

记住:Agent的性能取决于工具名称、描述和系统提示词的规范性。模型无法看到你的连接配置——它只能看到系统提示词和一组带名称、描述的工具。像设计API一样设计这些内容,大多数“Agent行为不符合预期”的问题都会迎刃而解。