mcpField
N
n8n-binary-and-data

n8n-binary-and-data

github.com/czlonkowski数据与数据库6.5k1.9k 次安装4 天前更新
代码仓库

关于 n8n-binary-and-data

面向 n8n 工作流构建者的技能,讲解 `$json` 与 `$binary` 的文件数据分工,以及二进制内容在节点和 AI Agent 工具间的传递限制。提供保留文件、通过存储传递键或 URL、在聊天界面呈现图片的操作模式。

主要功能

  1. 01区分 `$json` 与 `$binary`
  2. 02读取和写入二进制数据
  3. 03避免转换节点丢失文件
  4. 04通过存储连接 Agent 工具
  5. 05用 URL 在聊天中呈现图片

适用场景

  1. 01排查下载文件落入错误字段
  2. 02转换数据后保留附件
  3. 03让 Agent 工具处理上传文件
  4. 04在聊天消息中显示生成的图片

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/czlonkowski/n8n-skills --skill n8n-binary-and-data

安装后在 Claude Code 中输入/n8n-binary-and-data确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

AGENT_TOOL_BINARY.md
BINARY_BASICS.md
CDN_REQUIREMENT.md
MERGE_FOR_CONTEXT.md
README.md

详细介绍

n8n 二进制数据

每个 n8n 条目都包含两个彼此独立的槽位:用于结构化数据的 $json 和用于文件字节的 $binary。它们在工作流中并行传递。文件内容——实际的 PDF、图像或 zip 文件——存放在 $binary 中,绝不会存放在 $json 中。如果弄错了这一区别,你就会读到空字段、在流程中途丢失文件,或把 AI Agent 无法使用的工具输入交给它。

本技能将介绍二进制数据的存放位置、读写方式、如何避免数据被悄悄剥离、二进制数据与 AI Agent 工具边界之间的严格隔离,以及为什么聊天界面需要 URL,而不是原始字节。


避免 90% 二进制数据错误的三条规则

  1. 文件内容在 $binary 中,而不在 $json 中。 HTTP 下载、“Read Files”或电子邮件附件触发后,字节会存放在 $binary.<key> 中。$json 最多只包含元数据。读取 $json.data 来获取文件内容将一无所获。

  2. 二进制数据不能跨越 AI Agent 工具边界——无论传入还是传出。 工具参数和工具返回值都只能是 JSON。无法将上传的图像作为文件传递给工具,工具也无法返回原始字节。请先将文件存入存储服务,再通过 JSON 传递键或 URL。参见 AGENT_TOOL_BINARY.md。

  3. 聊天界面通过 URL 而非 $binary 来呈现图像。 Slack、Discord、Teams、Telegram、嵌入式 webhook 聊天界面都不会读取二进制槽位。图像必须存放在可通过 URL 获取的位置。参见 CDN_REQUIREMENT.md。


两个槽位

每个条目的结构如下:

{
  "json": { "customerId": 42, "status": "sent" },
  "binary": {
    "invoice": {
      "data": "<base64-encoded bytes>",
      "mimeType": "application/pdf",
      "fileName": "invoice-42.pdf",
      "fileExtension": "pdf"
    }
  }
}

binary 中的键(此处为 invoice)称为二进制属性名称。大多数文件处理节点都有一个 binaryPropertyName 参数,用于指定该键——生成方为槽位命名,使用方则通过该名称引用它。大多数节点的默认键都是 data,因此在没有其他信息时,请假设使用 $binary.data。

$json 和 $binary 是不同的命名空间。表达式 {{ $binary.invoice.fileName }} 读取文件元数据;{{ $json.customerId }} 读取数据。它们绝不会混在一起。

这一区别也能解释 webhook 中一个容易踩坑的地方:接收 multipart/form-data 的 Webhook 触发器会将上传的文件放入 $binary,并将随附的表单字段放入 $json.body——因此,上传的文件根本不在 $json 下。(webhook 中 $json.body 的嵌套结构属于 n8n-expression-syntax 范畴。)

如需了解完整的槽位结构、mime 类型和大小限制,请参阅 BINARY_BASICS.md。


生成二进制数据

你很少需要手动创建 $binary 槽位——节点会替你填充:

来源二进制数据的存放方式
HTTP Request,设置 responseFormat: "file"响应正文存放在 $binary.data 中(或你指定的名称)
Read/Write Files from Disk文件内容读入 $binary
存储服务下载(S3、Google Drive、Dropbox 等)下载的文件存放在 $binary.<key> 中
带附件的电子邮件触发器每个附件都会放入 $binary
服务提供商的 AI 媒体节点(图像/音频生成)设置 options.binaryPropertyOutput,让字节存放在后续节点查找的位置

对于 HTTP 下载,最重要的字段是 responseFormat。请通过 get_node 检查 nodes-base.httpRequest——如果保留默认的 JSON/字符串格式,下载的文件就会变成 $json 中乱码文本,而不是 $binary 中的纯净字节;这是导致此问题的典型原因。


在 Code 节点中读取和写入二进制数据

大多数工作流都不需要直接处理字节——只需将二进制数据传递给使用方(电子邮件附件、文件上传、Slack 文件)即可。大多数字节处理任务都有原生节点:从文件提取(CSV、XLSX、PDF 文本、JSON、纯文本 → 条目或字段)、转换为文件(条目 → CSV / XLSX / JSON / 文本文件)、加密(使用 binaryData: true 对文件进行哈希处理)、压缩(zip / gzip)。只有在没有节点能处理该格式时,才在 Code 节点中读取或写入原始字节,并附上 Why Code: 说明。

使用 getBinaryDataBuffer 读取——不要尝试手动对 $binary.<key>.data 进行 base64 解码:

// Code node, "Run Once for Each Item"
const buffer = await this.helpers.getBinaryDataBuffer(0, 'data'); // (itemIndex, propertyName)
const text = buffer.toString('utf-8');
const length = buffer.length;

return [{
  json: { ...$json, length },
  binary: $input.item.binary,   // pass the binary through, or it's gone
}];

通过自行构建存储槽来写入——对字节进行 base64 编码,并附上 MIME 类型和文件名:

const text = 'Hello, world!';
return [{
  json: { ok: true },
  binary: {
    report: {
      data: Buffer.from(text).toString('base64'),
      mimeType: 'text/plain',
      fileName: 'report.txt',
      fileExtension: 'txt',
    },
  },
}];

Code 节点的沙箱、辅助工具和执行模式属于 n8n-code-javascript(以及 n8n-code-python)的范畴——语言层面的细节请参阅这些内容。这里需要记住的唯一二进制相关事项是:Code 节点若返回 [{ json: {...} }] 而未重新附加 binary,就会静默丢弃文件。请参阅 BINARY_BASICS.md。


在转换过程中保留二进制数据

仅处理 JSON 的节点——Edit Fields(Set)、Code、IF 等——可能会从输出中丢弃 $binary 存储槽。工作流验证通过,运行时也不会报错;但邮件节点准备附加文件时,下游却找不到文件。

有两种保留方式:

  • 在转换节点上启用直通选项。 Edit Fields 提供 includeOtherFields;Code 节点可以显式返回 binary: $input.item.binary。在可用时,这是成本最低的修复方法。
  • 分流后按位置合并。 将源数据同时路由到转换分支和旁路分支,然后使用 combineByPosition 模式的 Merge 节点重新合并。JSON 来自转换分支,二进制数据则从旁路分支保留下来。
[Source with binary] ─┬─→ [Edit Fields: change JSON] ─┐
                      │      (binary stripped here)     ├─→ [Merge: combineByPosition] ─→ [Email: attach]
                      └──────────────────────────────────┘
                          (bypass — binary passes through untouched)

combineByPosition 会配对每个输入中的第 N 个条目,因此各输入的字段数量必须一致。连接方式以及适用于多次剥离节点链的替代方案(提前上传、子工作流)请参阅 MERGE_FOR_CONTEXT.md。


Agent 工具的二进制数据边界

这是最容易出问题的地方。AI Agent 通过 JSON 与其工具(Custom Code Tool、Call n8n Workflow Tool、HTTP Request Tool、MCP 工具)交互。二进制数据无法通过这条通道双向传递。两种方向的解决方法相同:将字节暂存到存储中,通过 JSON 传递键或 URL,再在另一端获取文件。

传入——用户上传了 Agent 工具必须处理的文件:

  1. 聊天触发器会提供一个 files[] 数组。将其拆分,并把每个文件上传到私有存储中的哈希键下。
  2. 在 Agent 运行前重新合并该分支(这是同步屏障,不是装饰),并在 Agent 上设置 executeOnce: true,避免 N 个文件触发 N 次 Agent 运行。
  3. 将键注入 Agent 的系统提示词,列出原始名称(便于人工理解)和存储键(工具所需),并明确说明“使用此键,完全一致”。
  4. 工具接收字符串参数形式的键,并自行从存储中下载文件。

传出——工具生成了 Agent 必须返回的文件:

  1. 工具子工作流生成二进制数据,将其上传到存储,并返回类似 { "ok": true, "key": "...", "url": "https://...", "mimeType": "image/png" } 的 JSON。
  2. Agent 在回复中嵌入 URL(或将键传给另一个工具)。

Agent 上的 passthroughBinaryImages: true 只会改变大模型看到的内容,用于视觉处理——它不会让工具接收文件,而且仅适用于图像(不包括 PDF、音频或视频)。任何工具仍然都需要使用“上传并传递键”的模式。完整模式、哈希策略、存储选项以及长时间运行工具的变体,请参阅 AGENT_TOOL_BINARY.md。

正在构建工具本身?Custom Code Tool 的约定请参阅 n8n-code-tool,AI Agent 与工具的组合模式请参阅 n8n-workflow-patterns。


聊天界面对 CDN 的要求

当工作流生成图像,且用户希望在聊天消息中显示该图像时:

  • 仅将二进制数据放在条目上还不够。 聊天客户端会渲染通过 URL 引用图像的消息(或通过平台自带的文件上传 API 推送字节)。它不会读取 $binary。
  • 这些字节必须存放在可通过 HTTPS URL 获取的位置。 先上传到对象存储或网盘,再嵌入返回的 URL。
  • n8n 没有内置 CDN。 存储服务由用户提供。

先询问用户已在使用哪种存储服务,而不是默认使用 S3——对象存储(S3、R2、GCS、Azure Blob、Backblaze B2、Supabase Storage)和网盘类服务(Dropbox、Google Drive、OneDrive、Box)都可用,而且生成的 URL 格式各不相同。如果用户尚未使用任何服务,Cloudflare R2 是最省事的起点。对于敏感内容,请使用带过期时间的签名 URL,而不是永久公开的 URL。参见 CDN_REQUIREMENT.md。


不支持的功能

  • $fromAI() 无法传递二进制数据。 它会用字符串、数字、布尔值和对象填充工具参数,不会传递文件字节。请改为传递存储键。
  • 工具参数和返回值只能是 JSON。 Agent 工具没有“二进制参数”,无论输入还是输出都不支持。
  • n8n 不提供 CDN 或公共文件托管服务。 通过 URL 提供文件始终由用户的存储服务负责,而非 n8n。
  • getBinaryDataBuffer 是 Code 节点的辅助函数。 它在 Custom Code Tool 沙盒中不可用(参见 n8n-code-tool)。

Data Tables 的位置

对于持久化的表格存储——例如对暂存文件进行引用计数、跟踪当前有效的键以及去重——请使用 n8n_manage_datatable 接口,该接口由 n8n-mcp-tools-expert 负责。本技能不涉及 Data Tables。


反模式

反模式问题所在修复方法
从 $json 读取文件内容字节存放在 $binary 中;$json 为空或仅包含元数据读取 $binary.<key>,或在 Code 节点中使用 getBinaryDataBuffer
未设置 responseFormat: "file" 就通过 HTTP 下载字节会以乱码文本的形式进入 $json,而不是干净的二进制数据在 HTTP Request 节点上设置 responseFormat: "file"
Code 节点返回 [{json:{...}}],但没有 binary文件会在后续流程中被静默丢弃在返回值中重新附加 binary: $input.item.binary
JSON 转换(Edit Fields/IF)丢失二进制数据邮件/上传节点找不到要附加的内容使用直通选项,或扇出后按位置合并
通过 $fromAI 将已上传的文件传给工具$fromAI 无法传递二进制数据;工具会收不到任何内容预先将文件存入存储服务,在系统提示词中注入键,由工具根据键获取文件
以为 passthroughBinaryImages 能让工具看到文件它只影响大模型能看到的内容,且仅适用于图像工具仍需使用“上传并传递键”的模式
工具向 Agent 返回原始二进制数据工具输出是 JSON;字节无法保留(还会撑大上下文)上传文件,并在 JSON 中返回 { key, url }
将 $binary 发送到聊天界面,并期待显示图像聊天客户端按 URL 渲染图像,而不是原始字节上传到存储服务/CDN,嵌入 URL,或使用平台文件 API
在 Code 节点中硬编码 base64工作流 JSON 会变得庞大、缓慢且容易泄露通过 $binary 引用,或上传后通过 URL 引用

参考文件

文件何时阅读
BINARY_BASICS.md首次处理二进制数据,或读取/写入 $binary 槽位、MIME 类型和大小限制时
AGENT_TOOL_BINARY.mdAgent 工具需要上传的文件,或要生成文件时——了解两个方向上的边界
MERGE_FOR_CONTEXT.mdJSON 转换后丢失二进制数据,需要重新附加时
CDN_REQUIREMENT.md在聊天界面中显示图像,或在任何需要通过 URL 引用图像的场景中

与其他技能集成

n8n-code-javascript / n8n-code-python:Code 节点用于读取/写入原始字节(getBinaryDataBuffer、Buffer.from(...).toString('base64'))。这些技能负责沙箱、辅助函数和执行模式的细节;本技能负责规定返回时必须重新附加二进制数据。

n8n-code-tool:Custom Code Tool 沙箱的限制更多——没有 $binary、没有 getBinaryDataBuffer、没有 $fromAI。工具需要文件时,可以通过本技能的存储键模式获取文件。

n8n-workflow-patterns:Agent 工具的二进制边界属于 AI-Agent-with-tools 模式的一部分;CDN 流程是一条生成 → 上传 → 回复链。

n8n-node-configuration:responseFormat、binaryPropertyName、includeOtherFields、binaryPropertyOutput 都是条件字段——使用 get_node 确认用户所用版本中的确切名称。

n8n-expression-syntax:使用 $binary.<key>.fileName 还是 $json.body(尤其是 Webhook 上传)属于表达式范畴。

n8n-validation-expert:二进制槽被丢弃属于静默故障——validate_workflow 不会标记出来。通过检查执行记录确认其是否存在。

n8n-mcp-tools-expert:负责 n8n_manage_datatable(Data Tables)和 n8n_executions——使用后者确认 binary 槽是否确实通过了某个节点。

n8n-error-handling:存储上传和下载可能失败;输入/输出暂存步骤需要错误分支,以免键缺失时静默返回 404。

using-n8n-mcp-skills:介绍这些技能如何协同工作的索引。


验证二进制数据是否保留

验证无法捕获被剥离的二进制槽——这属于静默故障。请确认执行是否正确:

  1. 使用 n8n_test_workflow(或触发一次真实运行)生成一条执行记录。
  2. 使用 n8n_executions 获取该执行记录,并检查每个节点的输出是否包含 binary 槽——即使 base64 内容过大而无法呈现,也会显示其是否存在以及元数据。
  3. binary 最后出现的节点,就是数据被剥离前的节点。应在该处进行直通或 Merge。

快速参考清单

  • 从 $binary.<key> 读取文件内容——绝不从 $json 读取
  • HTTP 下载使用 responseFormat: "file"
  • 文件必须继续传递时,Code 节点返回时要重新附加 binary
  • JSON 转换要么保留二进制数据,要么通过 Merge 将其合并回来(combineByPosition)
  • 不要尝试将二进制数据传入或传出 Agent 工具——改为通过 JSON 传递键/URL
  • passthroughBinaryImages 仅用于大模型视觉,不作为工具通道
  • 将聊天界面的图片上传到存储中;嵌入 URL,而非字节数据
  • 与用户一起选择存储后端(不要默认选 S3);敏感内容使用签名 URL
  • 通过检查执行记录确认二进制数据是否存在,而非依靠验证

请记住:两个槽并排存在。数据通过 $json 传递,文件通过 $binary 传递——文件一旦需要穿过 Agent 工具或到达聊天界面,就应以 URL 而非字节的形式传递。

评论

支持 Markdown