n8n-code-tool
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinesen8n Custom Code Tool
n8n 自定义代码工具
Expert guidance for writing code inside — the tool an AI Agent can invoke, not the regular workflow Code node.
@n8n/n8n-nodes-langchain.toolCode为编写代码的专业指南——这是AI Agent可调用的工具,并非常规工作流中的Code节点。
@n8n/n8n-nodes-langchain.toolCode⚠️ This is NOT the Code node
⚠️ 这不是Code节点
The Custom Code Tool looks like a Code node in the editor — same JavaScript editor, similar layout — but it is a completely different node from a different package with a different runtime contract.
| Code node | Custom Code Tool | |
|---|---|---|
| Node type | | |
| Package | | |
| Invoked by | Previous node (workflow flow) | AI Agent (LangChain) |
| Input | | |
| Return | | A string |
| N/A | Not available (see Errors) |
| HTTP helper | | Not exposed to the tool sandbox |
| State | Per-run execution data | No |
If you treat it like a Code node, it fails. The rest of this skill covers the Code Tool's actual contract.
自定义代码工具在编辑器中看起来和Code节点类似——同样的JavaScript编辑器、相似布局,但它是来自不同包的完全不同的节点,具有不同的运行时约定。
| Code节点 | 自定义代码工具 | |
|---|---|---|
| 节点类型 | | |
| 包 | | |
| 调用方 | 前序节点(工作流流转) | AI Agent(LangChain) |
| 输入 | | |
| 返回值 | | 字符串 |
| 无 | 不可用(参见错误部分) |
| HTTP辅助工具 | | 未暴露给工具沙箱 |
| 状态 | 每运行一次的执行数据 | 无 |
如果将它当作Code节点使用,一定会失败。本文剩余部分将介绍Code Tool的实际约定。
Quick Start
快速开始
Minimal JavaScript Code Tool
极简JavaScript代码工具
javascript
// `query` is whatever the AI sent (a string by default)
return `You asked: ${query}`;javascript
// `query`是AI发送的任意内容(默认是字符串)
return `You asked: ${query}`;Minimal Python Code Tool
极简Python代码工具
python
undefinedpython
undefined_query
is whatever the AI sent (a string by default)
_query_query
是AI发送的任意内容(默认是字符串)
_queryreturn f"You asked: {_query}"
undefinedreturn f"You asked: {_query}"
undefinedEssential Rules
核心规则
- Return a string. Numbers are auto-converted. Anything else throws .
"The response property should be a string, but it is an object" - Input variable is fixed: (JS),
query(Python). You cannot rename it._query - Do NOT use inside the Code Tool sandbox — it throws
$fromAI()."No execution data available" - Do NOT use return format — that's for Code nodes. Throws
[{json: {...}}]."Wrong output type returned" - Use a descriptive tool name (letters/numbers/underscores, v1.1+). The agent calls the tool by its name.
- Write a precise description — the LLM decides whether to invoke the tool based on it.
- 返回字符串。数字会自动转换为字符串。返回其他类型会抛出错误:"The response property should be a string, but it is an object"。
- 输入变量固定:JavaScript中为,Python中为
query。不能重命名。_query - 不要在Code Tool沙箱中使用——会抛出错误:"No execution data available"。
$fromAI() - 不要使用返回格式——这是Code节点的格式。会抛出错误:"Wrong output type returned"。
[{json: {...}}] - 使用描述性的工具名称(仅包含字母/数字/下划线,v1.1及以上版本支持)。Agent会通过该名称调用工具。
- 编写精准的描述——LLM会根据描述决定是否调用工具。
The Two Input Modes
两种输入模式
The Code Tool has two input shapes, controlled by :
specifyInputSchemaCode Tool有两种输入形式,由控制:
specifyInputSchemaMode 1: Unstructured (default, specifyInputSchema: false
)
specifyInputSchema: false模式1:非结构化(默认,specifyInputSchema: false
)
specifyInputSchema: falseThe AI passes a single string as . If you need multiple fields, the AI has to stuff them into that one string and you parse them out. In practice, LLMs will happily pass a JSON string if your description tells them to.
queryjavascript
// Parse a JSON string the AI sent
let params;
try {
params = typeof query === 'string' ? JSON.parse(query) : query;
} catch (e) {
throw new Error('Expected a JSON object. Parser said: ' + e.message);
}
const price = Number(params.price);
const months = Number(params.months);
// ...
return JSON.stringify({ monthly_payment: /* ... */ });Pros: simplest to set up, one field to describe.
Cons: no schema validation — if the LLM forgets a field, the tool throws at runtime.
Best for: quick prototypes, tools with one natural input (a question, a URL, a text blob).
AI会将单个字符串作为传递。如果需要多个字段,AI必须将它们打包到该字符串中,你需要自行解析。实际使用中,如果你的描述明确要求,LLM会主动传递JSON字符串。
queryjavascript
// 解析AI发送的JSON字符串
let params;
try {
params = typeof query === 'string' ? JSON.parse(query) : query;
} catch (e) {
throw new Error('Expected a JSON object. Parser said: ' + e.message);
}
const price = Number(params.price);
const months = Number(params.months);
// ...
return JSON.stringify({ monthly_payment: /* ... */ });优点:设置最简单,只需描述一个字段。
缺点:无模式验证——如果LLM遗漏字段,工具会在运行时抛出错误。
最佳适用场景:快速原型开发、仅需一个自然输入(问题、URL、文本块)的工具。
Mode 2: Structured (specifyInputSchema: true
)
specifyInputSchema: true模式2:结构化(specifyInputSchema: true
)
specifyInputSchema: trueThe tool becomes a LangChain . The LLM sees a typed argument schema and passes a validated object as . You access fields directly.
DynamicStructuredToolqueryjavascript
// query is now an object matching your schema
const price = query.price;
const months = query.months;
const residual_percent = query.residual_percent;
const monthly = computeAnnuity(price, months, residual_percent);
return JSON.stringify({ monthly_payment: monthly });Schema is defined via either:
- +
schemaType: "fromJson"(n8n v≥1.3) — paste an example JSON, n8n infers the schemajsonSchemaExample - +
schemaType: "manual"— write a full JSON Schema yourselfinputSchema
Pros: LLM gets type hints, invalid calls rejected before your code runs, cleaner code.
Cons: a little more setup; requires n8n version with schema support.
Best for: production tools with multiple typed parameters (calculators, API wrappers, anything with numeric fields the LLM tends to stringify).
See: INPUT_SCHEMA.md for complete schema setup.
工具会成为LangChain的。LLM会看到类型化的参数模式,并将经过验证的对象作为传递。你可以直接访问字段。
DynamicStructuredToolqueryjavascript
// query现在是匹配你定义的模式的对象
const price = query.price;
const months = query.months;
const residual_percent = query.residual_percent;
const monthly = computeAnnuity(price, months, residual_percent);
return JSON.stringify({ monthly_payment: monthly });模式可通过以下两种方式定义:
- +
schemaType: "fromJson"(n8n v≥1.3)——粘贴示例JSON,n8n会自动推断模式jsonSchemaExample - +
schemaType: "manual"——自行编写完整的JSON SchemainputSchema
优点:LLM会获得类型提示,无效调用会在代码运行前被拒绝,代码更简洁。
缺点:设置稍复杂;需要支持模式功能的n8n版本。
最佳适用场景:具有多个类型化参数的生产级工具(计算器、API包装器、任何LLM容易转为字符串的数字字段场景)。
参考:INPUT_SCHEMA.md 获取完整的模式设置说明。
Return Format
返回格式
The return value must be a string. The LLM reads it as the tool's observation.
javascript
// ✅ String
return "42";
// ✅ Number (auto-converted to string by n8n)
return 42;
// ✅ JSON-encoded structured result (recommended for rich output)
return JSON.stringify({ result: 42, currency: "SEK" });
// ❌ Raw object → "The response property should be a string, but it is an object"
return { result: 42 };
// ❌ Workflow item format → "Wrong output type returned"
return [{ json: { result: 42 } }];
// ❌ Array → "The response property should be a string, but it is an object"
return [1, 2, 3];返回值必须是字符串。LLM会将其作为工具的观察结果读取。
javascript
// ✅ 字符串
return "42";
// ✅ 数字(n8n会自动转换为字符串)
return 42;
// ✅ JSON编码的结构化结果(推荐用于复杂输出)
return JSON.stringify({ result: 42, currency: "SEK" });
// ❌ 原始对象 → "The response property should be a string, but it is an object"
return { result: 42 };
// ❌ 工作流项目格式 → "Wrong output type returned"
return [{ json: { result: 42 } }];
// ❌ 数组 → "The response property should be a string, but it is an object"
return [1, 2, 3];Best practice: JSON-stringify structured results
最佳实践:对结构化结果进行JSON序列化
When your tool has more than a trivial scalar output, return a JSON string:
javascript
return JSON.stringify({
monthly_payment_sek: 5405,
loan_amount: 351920,
total_cost_of_credit: 63295
});The LLM parses JSON reliably and can pick the fields it needs to present to the user.
当工具的输出不止是简单标量时,返回JSON字符串:
javascript
return JSON.stringify({
monthly_payment_sek: 5405,
loan_amount: 351920,
total_cost_of_credit: 63295
});LLM可以可靠地解析JSON,并提取所需字段呈现给用户。
Error handling: the agent reads your failures
错误处理:Agent会读取你的错误信息
Errors don't just stop the workflow — they go back to the LLM, which usually corrects its call and retries. Use that:
javascript
// Option A: throw — n8n surfaces the message to the agent
if (!isFinite(price)) throw new Error('price must be a number, e.g. 439900');
// Option B: return an error string — agent reads it like any tool result
if (!isFinite(price)) return JSON.stringify({ error: 'price must be a number, e.g. 439900' });Either way, write error messages for the LLM: state what was wrong and what a valid call looks like. A bare wastes the retry; an instructive message usually fixes the next call.
throw new Error('invalid input')错误不仅会终止工作流——还会返回给LLM,LLM通常会纠正调用并重试。利用这一点:
javascript
// 选项A:抛出错误——n8n会将消息传递给Agent
if (!isFinite(price)) throw new Error('price must be a number, e.g. 439900');
// 选项B:返回错误字符串——Agent会像处理普通工具结果一样读取它
if (!isFinite(price)) return JSON.stringify({ error: 'price must be a number, e.g. 439900' });无论哪种方式,都要为LLM编写错误信息:说明错误内容以及正确调用的示例。仅抛出会浪费重试机会;有指导性的信息通常能修正下一次调用。
throw new Error('invalid input')Tool Name and Description
工具名称与描述
These fields are NOT documentation — they are the tool contract the LLM sees. Treat them as prompt engineering.
这些字段不是文档——它们是LLM可见的工具约定。将其视为提示工程的一部分。
Name
名称
- Must match (v1.1+). No spaces, no hyphens, no emoji.
[A-Za-z0-9_]+ - Use a verb-y descriptive name: ,
calculate_car_loan,get_weather.search_orders - The agent calls the tool by this name. (the default) is useless — the agent won't know when to call it.
Code Tool
- 必须匹配(v1.1及以上版本)。不能包含空格、连字符或表情符号。
[A-Za-z0-9_]+ - 使用动词性的描述性名称:、
calculate_car_loan、get_weather。search_orders - Agent会通过该名称调用工具。默认名称毫无用处——Agent不知道何时调用它。
Code Tool
Description
描述
- Explain when to use it and what to send.
- If unstructured mode, include an example of the JSON string the LLM should send.
- If structured mode, the schema speaks for itself — just describe purpose.
Unstructured example (JSON-in-string pattern):
Deterministiskt beräknar månadskostnad för billån. Anropa med EN JSON-sträng:
{"price":439900,"down_payment":87980,"interest_rate":6.95,"months":36,"residual_percent":50}
Fält: price (SEK), down_payment (SEK), interest_rate (% per år), months, residual_percent (0-99).Structured example (schema-defined):
Deterministically computes the monthly car-loan payment given price, down payment,
annual interest rate, term, and residual percent. Use whenever the user asks for
monthly cost, total credit cost, or loan breakdown.- 说明何时使用工具以及需要传递什么内容。
- 如果是非结构化模式,要包含LLM应发送的JSON字符串示例。
- 如果是结构化模式,模式会自行说明——只需描述工具用途。
非结构化示例(字符串中嵌入JSON模式):
Deterministiskt beräknar månadskostnad för billån. Anropa med EN JSON-sträng:
{"price":439900,"down_payment":87980,"interest_rate":6.95,"months":36,"residual_percent":50}
Fält: price (SEK), down_payment (SEK), interest_rate (% per år), months, residual_percent (0-99).结构化示例(模式定义):
Deterministically computes the monthly car-loan payment given price, down payment,
annual interest rate, term, and residual percent. Use whenever the user asks for
monthly cost, total credit cost, or loan breakdown.Top Errors and Fixes
常见错误与修复方案
Error 1: "There was an error: 'Cannot assign to read only property \"name\" of object: Error: No execution data available'"
"There was an error: 'Cannot assign to read only property \"name\" of object: Error: No execution data available'"错误1:"There was an error: 'Cannot assign to read only property \"name\" of object: Error: No execution data available'"
"There was an error: 'Cannot assign to read only property \"name\" of object: Error: No execution data available'"Cause: you called inside the Code Tool sandbox.
$fromAI()Fix: is a helper for other tool-enabled nodes (HTTP Request Tool, SendGrid Tool, , etc.) — it's not exposed inside . Read the AI's input from directly (or use for structured fields).
$fromAI()toolWorkflowtoolCodequeryspecifyInputSchema原因:你在Code Tool沙箱中调用了。
$fromAI()修复:是为其他支持工具的节点(HTTP请求工具、SendGrid工具、等)设计的辅助函数——它并未暴露在中。直接从读取AI的输入(或使用获取结构化字段)。
$fromAI()toolWorkflowtoolCodequeryspecifyInputSchemaError 2: "Wrong output type returned"
"Wrong output type returned"错误2:"Wrong output type returned"
"Wrong output type returned"Cause: you returned a workflow-style array like . That's the Code node contract, not the Code Tool contract.
[{ json: { ... } }]Fix: return a string. For structured data, .
return JSON.stringify(output)原因:你返回了工作流风格的数组,比如。这是Code节点的约定,而非Code工具的约定。
[{ json: { ... } }]修复:返回字符串。对于结构化数据,使用。
return JSON.stringify(output)Error 3: "The response property should be a string, but it is an object"
"The response property should be a string, but it is an object"错误3:"The response property should be a string, but it is an object"
"The response property should be a string, but it is an object"Cause: you returned a plain object or array.
Fix: the result, or coerce to a string.
JSON.stringify()原因:你返回了普通对象或数组。
修复:对结果执行,或转换为字符串。
JSON.stringify()Error 4: AI never calls the tool
错误4:AI从不调用工具
Cause: tool name is generic (, ) or description doesn't clearly state when to use it.
Code ToolMy ToolFix: rename to a verb-y name (), and rewrite the description to explicitly state the trigger conditions (e.g. "Use this whenever the user asks about monthly cost").
calculate_car_loan原因:工具名称过于通用(如、),或描述未明确说明使用场景。
Code ToolMy Tool修复:重命名为动词性名称(如),并重写描述以明确说明触发条件(例如:“当用户询问月付款金额时使用此工具”)。
calculate_car_loanError 5: AI sends garbage into query
query错误5:AI向query
传递无效内容
queryCause: unstructured tool with a vague description. The LLM guesses at the format.
Fix: either (a) include a concrete JSON example in the description, or (b) switch to so the LLM gets a typed schema.
specifyInputSchema: trueSee: ERROR_PATTERNS.md for full catalog with reproductions.
原因:非结构化工具的描述模糊。LLM会猜测格式。
修复:要么(a)在描述中包含具体的JSON示例,要么(b)切换到,让LLM获得类型化模式。
specifyInputSchema: true参考:ERROR_PATTERNS.md 获取完整的错误目录及复现方法。
What's NOT Available in the Sandbox
沙箱中不可用的功能
The Code Tool sandbox is narrower than the Code node sandbox. Don't assume helpers carry over:
| Helper | Code node | Code Tool |
|---|---|---|
| ✅ | ❌ |
| ✅ | ❌ |
| ✅ | ❌ |
| ❌ | ❌ (despite sitting next to an AI agent) |
| ✅ | ❌ |
| ✅ | ✅ (standard in JS sandbox) |
| ✅ | ❌ |
| ✅ | ❌ |
| ✅ | ❌ |
Implication: the Code Tool is for pure computation. If you need an HTTP call, an API lookup, or cross-invocation state, use a different tool node:
- HTTP Request Tool for external API calls
- (Call Sub-workflow Tool) for multi-step logic with access to the full Code node sandbox
toolWorkflow - MCP / database tools for persistent state
Code Tool沙箱比Code节点沙箱的限制更多。不要想当然地认为辅助函数可以通用:
| 辅助函数 | Code节点 | Code工具 |
|---|---|---|
| ✅ | ❌ |
| ✅ | ❌ |
| ✅ | ❌ |
| ❌ | ❌(即使与AI Agent一起使用) |
| ✅ | ❌ |
| ✅ | ✅(JS沙箱中的标准功能) |
| ✅ | ❌ |
| ✅ | ❌ |
| ✅ | ❌ |
结论:Code Tool适用于纯计算场景。如果需要HTTP调用、API查询或跨调用状态,请使用其他工具节点:
- HTTP请求工具:用于外部API调用
- (调用子工作流工具):用于多步骤逻辑,可访问完整的Code节点沙箱
toolWorkflow - MCP/数据库工具:用于持久化状态
When to Use Code Tool vs Alternatives
何时使用Code Tool vs 替代方案
Use Code Tool when:
- ✅ Pure deterministic computation (math, parsing, formatting, validation)
- ✅ Lightweight transformations the LLM shouldn't do itself (precision math, regex)
- ✅ You want the code inline in the workflow, not in a separate sub-workflow
Use (Call Sub-workflow Tool) when:
toolWorkflow- ✅ You need multiple parameters with clean typing
$fromAI() - ✅ You need access to , credentials, or other nodes
this.helpers - ✅ Logic is reusable across agents
- ✅ You want structured typed inputs WITHOUT writing a JSON Schema
Use HTTP Request Tool when:
- ✅ The tool is fundamentally a single API call
- ✅ You want per-parameter bindings in URL/query/body
$fromAI()
Rule of thumb: if you find yourself wanting , you probably want instead of .
$fromAI()toolWorkflowtoolCode使用Code Tool的场景:
- ✅ 纯确定性计算(数学运算、解析、格式化、验证)
- ✅ LLM不应自行处理的轻量级转换(精确数学运算、正则表达式)
- ✅ 希望代码内联在工作流中,而非单独的子工作流
使用****(调用子工作流工具)的场景:
toolWorkflow- ✅ 需要多个参数,并希望使用简洁的类型绑定
$fromAI() - ✅ 需要访问、凭证或其他节点
this.helpers - ✅ 逻辑可在多个Agent之间复用
- ✅ 想要结构化类型化输入,但不想编写JSON Schema
使用HTTP请求工具的场景:
- ✅ 工具本质上是单个API调用
- ✅ 希望在URL/查询/请求体中为每个参数绑定
$fromAI()
经验法则:如果你发现自己需要使用,那么你可能应该使用而非。
$fromAI()toolWorkflowtoolCodeComplete Working Example
完整可用示例
A production calculator tool (unstructured, JSON-in-string pattern):
json
{
"parameters": {
"name": "calculate_car_loan",
"description": "Computes monthly car-loan payment using an annuity formula with residual/balloon. Call with a single JSON string. Example: {\"price\":439900,\"down_payment\":87980,\"interest_rate\":6.95,\"months\":36,\"residual_percent\":50,\"setup_fee\":695,\"monthly_admin_fee\":59}. Required: price, down_payment, interest_rate, months, residual_percent. Optional: setup_fee, monthly_admin_fee (default 0).",
"language": "javaScript",
"jsCode": "let params;\ntry {\n params = typeof query === 'string' ? JSON.parse(query) : query;\n} catch (e) {\n throw new Error('Invalid JSON: ' + e.message);\n}\n\nconst price = Number(params.price);\nconst down_payment = Number(params.down_payment);\nconst interest_rate = Number(params.interest_rate);\nconst months = Number(params.months);\nconst residual_percent= Number(params.residual_percent);\nconst setup_fee = Number(params.setup_fee ?? 0) || 0;\nconst monthly_admin_fee = Number(params.monthly_admin_fee ?? 0) || 0;\n\nif (!isFinite(price) || price <= 0) throw new Error('price must be > 0');\nif (down_payment < 0 || down_payment >= price) throw new Error('down_payment must be in [0, price)');\n\nconst principal = price - down_payment;\nconst residual = price * (residual_percent / 100);\nconst r = interest_rate / 100 / 12;\nconst growth = Math.pow(1 + r, months);\nconst base = r === 0\n ? (principal - residual) / months\n : (principal - residual / growth) * r / (1 - 1 / growth);\nconst monthly_payment = base + monthly_admin_fee;\n\nreturn JSON.stringify({\n monthly_payment_sek: Math.round(monthly_payment),\n loan_amount: Math.round(principal),\n residual_value_sek: Math.round(residual),\n total_cost_of_credit: Math.round(monthly_payment * months + residual + setup_fee - principal)\n});"
},
"type": "@n8n/n8n-nodes-langchain.toolCode",
"typeVersion": 1.3,
"name": "calculate_car_loan"
}Wire it into an AI Agent via the connection type.
ai_tool生产级计算器工具(非结构化,字符串中嵌入JSON模式):
json
{
"parameters": {
"name": "calculate_car_loan",
"description": "Computes monthly car-loan payment using an annuity formula with residual/balloon. Call with a single JSON string. Example: {\"price\":439900,\"down_payment\":87980,\"interest_rate\":6.95,\"months\":36,\"residual_percent\":50,\"setup_fee\":695,\"monthly_admin_fee\":59}. Required: price, down_payment, interest_rate, months, residual_percent. Optional: setup_fee, monthly_admin_fee (default 0).",
"language": "javaScript",
"jsCode": "let params;\ntry {\n params = typeof query === 'string' ? JSON.parse(query) : query;\n} catch (e) {\n throw new Error('Invalid JSON: ' + e.message);\n}\n\nconst price = Number(params.price);\nconst down_payment = Number(params.down_payment);\nconst interest_rate = Number(params.interest_rate);\nconst months = Number(params.months);\nconst residual_percent= Number(params.residual_percent);\nconst setup_fee = Number(params.setup_fee ?? 0) || 0;\nconst monthly_admin_fee = Number(params.monthly_admin_fee ?? 0) || 0;\n\nif (!isFinite(price) || price <= 0) throw new Error('price must be > 0');\nif (down_payment < 0 || down_payment >= price) throw new Error('down_payment must be in [0, price)');\n\nconst principal = price - down_payment;\nconst residual = price * (residual_percent / 100);\nconst r = interest_rate / 100 / 12;\nconst growth = Math.pow(1 + r, months);\nconst base = r === 0\n ? (principal - residual) / months\n : (principal - residual / growth) * r / (1 - 1 / growth);\nconst monthly_payment = base + monthly_admin_fee;\n\nreturn JSON.stringify({\n monthly_payment_sek: Math.round(monthly_payment),\n loan_amount: Math.round(principal),\n residual_value_sek: Math.round(residual),\n total_cost_of_credit: Math.round(monthly_payment * months + residual + setup_fee - principal)\n});"
},
"type": "@n8n/n8n-nodes-langchain.toolCode",
"typeVersion": 1.3,
"name": "calculate_car_loan"
}通过连接类型将其接入AI Agent。
ai_toolIntegration with Other Skills
与其他技能的集成
n8n-code-javascript: the Code node skill. Most JavaScript patterns (arrays, map/filter, DateTime) transfer — but I/O contract is different. Don't copy data-access code.
n8n-node-configuration: is a classic displayOptions-driven conditional field. Use on to see schema-related properties.
specifyInputSchemaget_node({detail: "standard"})@n8n/n8n-nodes-langchain.toolCoden8n-workflow-patterns: Code Tool sits inside the "AI Agent with tools" pattern. An agent typically has several tools; Code Tool is the "local compute" option.
n8n-validation-expert: the three Code Tool errors listed above have clear signatures — if validation surfaces "Wrong output type returned", you know to switch from array-of-items to a string.
n8n-code-javascript:Code节点的技能。大多数JavaScript模式(数组、map/filter、DateTime)可以复用——但I/O约定不同。不要复制数据访问代码。
n8n-node-configuration:是典型的由displayOptions驱动的条件字段。对使用查看与模式相关的属性。
specifyInputSchema@n8n/n8n-nodes-langchain.toolCodeget_node({detail: "standard"})n8n-workflow-patterns:Code Tool属于“带工具的AI Agent”模式。一个Agent通常会有多个工具;Code Tool是“本地计算”选项。
n8n-validation-expert:上面列出的三个Code Tool错误具有明确的特征——如果验证提示“Wrong output type returned”,你就知道需要从项目数组切换为字符串返回格式。
Quick Reference Checklist
快速参考检查清单
Before deploying a Code Tool:
- Node type is (not
@n8n/n8n-nodes-langchain.toolCode)nodes-base.code - Tool name is descriptive, verb-y, snake_case (e.g. )
calculate_car_loan - Description states when to use the tool and (if unstructured) shows a JSON example
- Input read from (JS) or
query(Python)_query - No in the code body
$fromAI() - No /
$input/$json— those aren't in the sandbox$helpers - Return is a string (use for structured output)
JSON.stringify() - Wired into an AI Agent via connection
ai_tool - Tested with the exact kind of input the LLM will send (JSON in a string, or schema-validated object)
部署Code Tool前:
- 节点类型为(而非
@n8n/n8n-nodes-langchain.toolCode)nodes-base.code - 工具名称具有描述性、动词性、采用蛇形命名法(如)
calculate_car_loan - 描述说明了工具的使用场景,且(如果是非结构化模式)包含JSON示例
- 输入从(JS)或
query(Python)读取_query - 代码中未使用
$fromAI() - 代码中未使用/
$input/$json——这些在沙箱中不可用$helpers - 返回值是字符串(结构化输出使用)
JSON.stringify() - 通过连接类型接入AI Agent
ai_tool - 使用LLM会发送的精确输入类型(字符串中的JSON或模式验证后的对象)进行测试
Additional Resources
额外资源
- INPUT_SCHEMA.md — structured input (DynamicStructuredTool) in depth
- ERROR_PATTERNS.md — full error catalog with causes and fixes
- INPUT_SCHEMA.md — 深入介绍结构化输入(DynamicStructuredTool)
- ERROR_PATTERNS.md — 完整的错误目录及原因与修复方案
Official sources
官方资源
- n8n Custom Code Tool docs
- ToolCode source — the sandbox contract
- LangChain tool docs — DynamicTool / DynamicStructuredTool
Remember: the Code Tool is a LangChain tool wearing a Code-node UI. Contract is: string in, string out. Everything else follows from that.
- n8n自定义代码工具文档
- ToolCode源码 — 沙箱约定
- LangChain工具文档 — DynamicTool / DynamicStructuredTool
记住:Code Tool是一个披着Code节点UI的LangChain工具。约定是:字符串输入,字符串输出。其他所有规则都由此衍生。