# N8n！AI工作流自动化平台

## 概述

n8n 是一个非常强大的开源 AI 工作流自动化平台，能够通过拖拽的方式，让各个 AI 工具相互配合，构建复杂的自动化流程，高效处理我们日常遇到的问题。

与 n8n 相关的网址包括：n8n 的[官网](https://n8n.io/) 、[官方文档](https://docs.n8n.io/)、 [Github 页面](https://github.com/n8n-io/n8n)。

## 软件部署

部署方式包括 Node 部署和 Docker 部署两种，因为 n8n 主要通过调用 AI 工具的 API 来工作（也可以调用本地的 AI 模型），所以本身对于机器性能的要求并不高，即便是 NAS 这种性能比较一般的机器也可以轻松部署。

n8n 默认情况下使用`SQLite`作为数据库，也可以使用`PostgreSQL`替换默认的`SQLite`数据库，本文中使用`PostgreSQL`数据库来构建，构建前需要自行创建一个名为`n8n`的数据库。

```dockerfile
docker run -itd --name n8n --restart always \
 -e GENERIC_TIMEZONE="Asia/Shanghai" \
 -e TZ="Asia/Shanghai" \
 -e N8N_SECURE_COOKIE=false \
 -e DB_TYPE=postgresdb \
 -e DB_POSTGRESDB_DATABASE=n8n \
 -e DB_POSTGRESDB_HOST=「HOST」 \
 -e DB_POSTGRESDB_PORT=「PORT」 \
 -e DB_POSTGRESDB_USER=「USER」 \
 -e DB_POSTGRESDB_PASSWORD=「PASSWORD」 \
 -p 5678:5678 \
 -v 「PATH_N8N」:/home/node/.n8n \
 n8nio/n8n:latest
```

>[!info]  信息
>容器内的`/home/node/.n8n`保存了配置文件，但是镜像没有并非以`root`用户登录，因为权限问题无法将文件直接写入，导致加上`-v 「PATH_N8N」:/home/node/.n8n` 后会无法正常运行，可以先构建容器，将里面的文件复制出来，在加上这句话就可以正常运行了。

>[!info]  信息
>默认 n8n 使用`http`协议访问时只能运行在`localhost`，而使用`https`协议时不受限，通过设置`N8N_SECURE_COOKIE=false`可以不遵守这一限制。n8n 放在内网使用时，可以避免在内网进行反向代理，比较方便，也相对安全。而在公网使用时，这样设置容易导致密码和 API Key 的泄露，还是应当申请证书进行反向代理。

## 工作流节点

工作流由一个个节点组成，前一个工作流输出的结果传到下一个工作流中作为输入，构成了复杂的自动化流程。

### 触发器节点

工作流的第一个节点是触发器节点，触发器节点定义了工作流在何种情况下被触发，主要触发方式有以下几种：

![](https://img.papergate.top:5000/i/2025/06/6861167a83df7.webp)

触发方式大致上就是手动触发、定时触发、事件触发这三种。

### 工作节点

工作节点主要是一些获取数据和对数据进行处理的节点。

#### HTTP 节点

HTTP 节点可以进行 HTTP 请求，可以将前一个节点的输出作为`Header`或者`params`中的一部分，自身的`response`也可以作为下一个节点的输入来使用。

比如，在这样一个逻辑链条中：

![](https://img.papergate.top:5000/i/2025/07/68631cb27e7dd.webp)

上一个节点的输入是`JSON`数据：

![](https://img.papergate.top:5000/i/2025/07/68631d2fbb230.webp)

我们可以在请求中将其作为参数传入，比如放在`body`中：

![](https://img.papergate.top:5000/i/2025/07/68631d62ce880.webp)

#### Field 节点

可以从杂乱无章的`JSON`数据中提取出我们想要的数据，比如，在这样一个逻辑链条中：

![](https://img.papergate.top:5000/i/2025/07/68631e1f8fd2c.webp)

输入数据的格式比较凌乱：

![](https://img.papergate.top:5000/i/2025/07/68631e750d23b.webp)

我们可以对数据进行处理：

![](https://img.papergate.top:5000/i/2025/07/68631e96c62f3.webp)

得到简洁的输出数据：

![](https://img.papergate.top:5000/i/2025/07/68631ebca55c0.webp)

#### Merge 节点

`Merge`节点将左侧的输入按照顺序放到一个列表中，传到右侧，如图：

![](https://img.papergate.top:5000/i/2025/07/68631f2abeaa4.webp)

两个输入，经过`Merge`以后，变成了单输出，输出上写着`2个项目`。

![](https://img.papergate.top:5000/i/2025/07/68632003c38ee.webp)

>[!info]  信息
>`2个项目`的意思就是，`Merge`节点右侧接有运算时，左侧之前传入的参数会分`2`次分别传入到右侧，在右侧进行`2`次计算，并得到`2`个结果。

#### Aggregate 节点

上面提到，`Merge`节点右侧接有运算时会计算多次，有时候当我们想要将其作为一个整体传到右侧进行计算时，就需要用到`Aggregate`节点。

>[!info]  信息
>输入是`json`数据，当最外层是列表时，列表的每个元素会计算一次，`Aggregate`节点就是在列表外套一个对象，将列表中的所有元素放到一个对象中，这样就只计算一次。

#### Split 节点

Split 节点和上面讲的正好相反，比如当我们左侧的输入是一个当做整体的列表时，右侧有一个「新增单位」的运算，如图：

![](https://img.papergate.top:5000/i/2025/07/686321d314943.webp)

我们的想法是，列表中的每一个值都要新增，这时候我们就需要用到`Split`节点。`Split`节点就是把对象展开成列表。

#### Code 节点

`Code`节点上可以运行`JS`程序或者`python`程序，因为`python`程序还在测试阶段，使用体验不是很好，本人建议还是直接写`JS`程序。

![](https://img.papergate.top:5000/i/2025/07/686322f1afd6e.webp)

`Code`节点有`2`种`Mode`，分别是`Run Once for All Items`和`Run Once for Each Item`，前面那种模式，可以省略掉一个`Aggregate`节点，因为不管前面有几个项目，都会被当做一个整体一次处理，而后面那种模式会将每个项目单独处理。

![](https://img.papergate.top:5000/i/2025/07/686322e1a6051.webp)

两种模式下的语法也有些微不同。

#### AI 节点

AI 节点是一个很伟大的东西，它提供了一个非常强大的功能，把非结构化、结构未知的数据转成结构化的数据。

![](https://img.papergate.top:5000/i/2025/07/686324ca12c68.webp)

左侧传入的是一段食谱文本和一些类别信息：

![](https://img.papergate.top:5000/i/2025/07/6863252ba4b6f.webp)

我们在 AI 节点上写上一些提示词：

```text
阅读以下食谱文本
{{ $json.data[0].body.text }}
需要对这一食谱进行分类，类别可以有一个或者多个，优先从以下类别中选择
{{ $json.data[1].category }}
如果上述类别不足以描述该食谱，可以使用新的类别，返回一个严格的 JSON 数组。
```

连接`DeepSeek`模型和`Structured Output Parser`，指定输出格式如下：

![](https://img.papergate.top:5000/i/2025/07/686325fd8eda5.webp)

这样 AI 模型经过运算，就会以我们想要的格式将结果输出。

## 实例

举一个实例来说明，在之前的[文章](https://blog.papergate.top:5000/posts/mealie%E6%9E%84%E5%BB%BA%E4%BA%8B%E6%97%A0%E5%B7%A8%E7%BB%86%E7%9A%84%E9%A3%9F%E8%B0%B1%E7%AE%A1%E7%90%86%E7%B3%BB%E7%BB%9F/)中，我们知晓了`Mealie`是一款功能强大的食谱管理系统，但是维护其繁杂的数据库是一件辛苦的事情，实在是非常的劝退。

所以，很容易想到，如果使用`n8n`这样一个自动化平台，若是只需要将食谱的文字部分一股脑的传入进去，平台会调用`AI`功能自动为我们将文字解析成结构化的数据，并调用 API 接口传入 `Mealie`，那岂不是非常令人振奋吗！

经过我的不懈努力，最终也是成功实现了这一功能！

### 常规参数

一些常规数据，类型为字符串或者数字，使用`DeepSeek`直接识别。

```text
解析以下食谱文本并提取关键信息：

{{ $json.body.text }}

请以JSON格式返回以下字段：
1. name：菜名
2. recipe_servings：几人份（纯数字）
3. recipe_yield_quantity：几人份（纯数字）
4. prep_time：准备时间（如1 小时，数字和中文之间有1个空格）
5. perform_time：烹饪时间（如30 分钟，数字和中文之间有1个空格）
6. total_time：总时间（如30 分钟，数字和中文之间有1个空格）
7. description：菜品描述（1-2句话）
```

### 营养参数

营养参数让`DeepSeek`根据食谱的配料自己估算。

```text
分析以下食谱文本并精确估算营养数据：

{{ $json.body.text }}

要求：
1. 输出标准JSON格式的营养信息
2. 所有数值必须为具体数字（整数或小数），禁止使用范围
3. 基于常见食材营养数据估算，保持合理比例
4. 单位严格按以下要求：
   - 能量：千卡(kcal)
   - 重量：克(g)
   - 钠/胆固醇：毫克(mg)
注意：
1. 所有字段必须存在，无数据时填0
2. 数值需符合膳食常识（如蛋白质≈总热量15-20%）
3. 脂肪类总和不超过fat_content
4. 优先考虑主要食材的营养贡献
```

### 烹制方法

让 AI 自动分析文本，总结归纳。

```text
阅读并分析以下食谱文本：

{{ $json.body.text }}

提取烹饪步骤并以JSON格式输出，要求：
1. 使用数组表示步骤，每个步骤包含：
   - text：步骤详细说明
   - summary：步骤简要概括
   - title：仅当几个相似步骤的第一个显示概括标题，其余留空
   - ingredient_references：保持空数组
2. 对连续相似步骤进行分组，只在第一个步骤设置title
3. 保持输出简洁规范
```
### 效果

其他部分涉及到了许多的逻辑运算和`JS`脚本，处理方式相对比较传统，按照调用各种 API 的逻辑顺序依次调用，即可实现。

![](https://img.papergate.top:5000/i/2025/07/68631a83b3138.webp)


---

> 作者: Aphros  
> URL: https://blog.papergate.top/posts/n8nai%E5%B7%A5%E4%BD%9C%E6%B5%81%E8%87%AA%E5%8A%A8%E5%8C%96%E5%B9%B3%E5%8F%B0/  

