ESSAY

我为什么从 n8n 转向 Windmill

自动化工作流 技术选型 Windmill 全栈开发

“痛苦的试错后,我找到了真正适合 AI 时代的工作流引擎。“

核心观点 / 起源

在搭建博客社媒自动化分发系统的过程中,我经历了一次彻底的技术栈迁移——从 n8n 转向 Windmill。这不是一次简单的工具替换,而是一次痛苦的试错后的必然选择。

这次迁移让开发效率提升了 70%,执行性能提升了 62.5%,长文本处理成功率从 0% 提升到 100%。

n8n 的致命缺陷

n8n 在处理复杂 AI 工作流时暴露出 5 个致命问题:

1. AI 生成准确率仅 30%

n8n 的表达式语法 ={{$json.field}} 对 AI 极不友好。当我让 Claude 生成 n8n 工作流配置时,准确率只有 30%。这意味着每次生成的代码,我都需要手动修正 70% 的内容。

// n8n 的表达式语法示例
{
  "url": "={{$env.DEEPSEEK_BASE_URL}}/v1/chat/completions",
  "jsonBody": "={{JSON.stringify({
    messages: [{
      role: 'user',
      content: $('Workflow Input').first().json.content
    }]
  })}}"
}

这种嵌套的模板语法,既不是标准 JavaScript,也不是 Python,AI 模型很难准确理解和生成。

2. 长文本推理超时:100% 失败率

n8n 的 HTTP Request 节点有一个硬性限制:最大超时 60 秒。当我尝试用 DeepSeek 处理 5000+ 字的博客文章时,AI 推理时间通常需要 80-120 秒。结果就是:所有长文章处理失败率 100%。

我尝试过拆分文章、压缩 Prompt,但都无法根本解决问题。这个硬性限制让 n8n 在处理长文本场景时完全不可用。

3. 调试困难:单个 bug 耗时 10-20 分钟

n8n 的调试体验极差。你只能点击节点查看 JSON 输出,没有断点、没有日志、没有堆栈跟踪。

当工作流出错时,我需要:

  1. 点击每个节点查看输出
  2. 手动对比输入输出数据
  3. 猜测哪个节点出了问题
  4. 修改配置后重新运行整个工作流

单个 bug 的调试时间通常需要 10-20 分钟。

4. 版本控制噩梦:5000+ 行不可读的 JSON

n8n 的工作流是一个 5000+ 行的 JSON 文件。当我提交到 Git 时,diff 完全不可读:

{
  "nodes": [{
    "parameters": {
      "url": "={{$env.DEEPSEEK_BASE_URL}}/v1/chat/completions",
      "jsonBody": "={{JSON.stringify({...})}}",
      "options": {"timeout": 60000}
    },
    "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "name": "Generate Xiaohongshu Content",
    "type": "n8n-nodes-base.httpRequest",
    "position": [1240, 380]
  }]
}

这种格式根本无法进行有效的 Code Review。

5. 数据传递隐式:容易出错

n8n 的数据传递是隐式的,通过节点名称引用:

$('节点名').first().json.data

这种方式有两个问题:

  1. 数据流向不清晰:你需要点开每个节点才能知道它依赖哪些数据
  2. 重命名节点会导致错误:如果你重命名了一个节点,所有引用它的地方都会失效

这些问题让我不得不寻找替代方案,而 Windmill 的出现让我看到了希望。

过程 / 推演

Windmill 的架构优势

1. 纯 Python:AI 生成准确率 99%

Windmill 使用标准 Python 3.12 语法。当我让 Claude 生成 Windmill 脚本时,准确率达到 99%。

# Windmill 的标准 Python 语法
import requests
import wmill

def main(title: str, content: str) -> dict:
    api_key = wmill.get_variable("u/admin/deepseek_api_key")
    base_url = wmill.get_variable("u/admin/deepseek_base_url")
    
    response = requests.post(
        f"{base_url}/v1/chat/completions",
        headers={"Authorization": f"Bearer {api_key}"},
        json={
            "model": "deepseek-chat",
            "messages": [
                {"role": "user", "content": content}
            ],
            "temperature": 0.7,
            "max_tokens": 1200
        },
        timeout=120.0  # 可自定义超时时间
    )
    
    return response.json()

这就是标准的 Python 代码,没有任何魔法语法。AI 可以完美理解和生成。

2. 灵活超时:长文本处理成功率 100%

Windmill 允许你自定义超时时间。我将超时时间设置为 120 秒后,所有长文章处理成功率达到 100%。

3. 原生调试:调试时间从 10-20 分钟 → 2-5 分钟

Windmill 支持标准的 Python 调试工具:

def main(title: str, content: str) -> dict:
    print(f"Processing: {title}")  # 直接打印日志
    print(f"Content length: {len(content)}")
    
    result = process_content(content)
    print(f"Result: {result}")
    
    return result

调试时间从 10-20 分钟缩短到 2-5 分钟。

4. !inline 机制:SOP 直接嵌入代码

Windmill 的 !inline 机制允许你将 SOP 文档直接嵌入代码,无需外部文件依赖。这样做的好处:

  • 零外部依赖:不需要单独管理 SOP 文件
  • 版本一致性:代码和 SOP 在同一个文件中,不会出现版本不一致的问题
  • 部署简单:只需要部署一个 Python 文件

5. 并行 Flow:执行时间从 120s → 45s

Windmill 的 forloopflow 支持真正的并行执行:

# flow.yaml
- id: parallel_processing
  type: forloopflow
  value:
    type: static
    value: ["xiaohongshu", "x", "linkedin", "zhihu"]
  modules:
    - id: process_platform
      value:
        type: script
        path: f/blog-distribution/platform_worker
  parallel: true  # 真正并行

4 个平台同时处理,执行时间从 120 秒缩短到 45 秒。

6. 显式数据流:函数参数 + 返回值

Windmill 使用标准的函数参数和返回值传递数据:

# Step 1: 生成摘要
def generate_summary(title: str, content: str) -> dict:
    return {
        "xiaohongshu": "摘要1",
        "x": "摘要2",
        "linkedin": "摘要3",
        "zhihu": "摘要4"
    }

# Step 2: 处理平台
def process_platform(platform: str, summary: str) -> dict:
    return {
        "platform": platform,
        "content": summary,
        "passed": True
    }

数据流向一目了然,不需要点开每个节点查看。

理论上的优势需要数据验证,下面是实际的性能对比。

性能对比数据

开发效率提升

指标n8nWindmill提升幅度
AI 生成准确率30%99%+230%
单个 bug 调试时间10-20 分钟2-5 分钟-80%
新平台开发时间4 小时1.2 小时-70%
代码可读性评分2/55/5+150%

执行性能提升

指标n8n (串行)Windmill (并行)提升幅度
平均执行时间120 秒45 秒-62.5%
长文本处理成功率0%100%+100%
Token 消耗9500 tokens8612 tokens-9.3%
单篇成本$0.0019$0.0017-10.5%

结语 / 反思

迁移成本方面:

  • 学习成本:如果你会 Python,学习成本几乎为零
  • 迁移时间:我花了 2 天时间将整个工作流从 n8n 迁移到 Windmill
  • 部署成本:Windmill CE 版本完全免费,可以自托管

n8n 适合简单的自动化任务,但在以下场景中完全不适用:

  1. 需要 AI 辅助开发:表达式语法对 AI 不友好
  2. 需要处理长文本:60 秒超时限制无法突破
  3. 需要频繁调试:调试体验极差
  4. 需要版本控制:JSON 格式不可读

Windmill 则完美解决了这些问题:

  1. 纯 Python 语法:AI 生成准确率 99%
  2. 灵活超时:长文本处理成功率 100%
  3. 原生调试:调试时间缩短 80%
  4. 标准代码格式:Git diff 完全可读

如果你正在搭建复杂的自动化工作流,尤其是涉及 AI 推理的场景,我强烈建议你直接选择 Windmill,而不是 n8n。


技术栈:

  • Windmill CE v1.687.0
  • Python 3.12
  • DeepSeek Chat (通过 AgentRouter 代理)
  • Docker 部署