AI Agent 开发中,长时间运行的任务是常见痛点。同步等待导致超时、资源占用影响响应速度。如果采用传统异步方案(如消息队列),需要处理队列配置、序列化、消费者逻辑、死信管理等,繁琐且维护成本高。本文介绍如何使用 Windmill 实现异步任务——只需写一个脚本函数,通过 Webhook 或 API 即可触发,并可通过其内置的 MCP Server 让 AI Agent 直接编排,大幅降低开发复杂度。

1. 问题背景 链接到标题

在 AI Agent 开发中,我们经常遇到这样的场景:

  • 文件处理:OCR 识别、视频转码、文档解析等耗时长
  • API 调用:外部服务响应慢或需要轮询
  • 批量任务:需要对大量数据进行处理
  • 异步流程:需要等待多个子任务完成后合并结果

如果这些任务同步执行,Agent 会被阻塞直到任务完成,超时风险高、用户体验差。

Windmill 是一个开源的工作流引擎,支持多种编程语言(Python/TypeScript/Go/Bash 等),可以轻松地将长时间任务托管执行,并通过 API、Webhook、Schedule 等方式触发,非常适合作为 AI Agent 的后端任务执行层。


Q:为什么不用 n8n? n8n 是更流行的选择,采用低代码/可视化工作流配置。Windmill 的定位是 Code-first——用常规编程语言(Python/TypeScript/Go)写脚本,而非拖拽配置。同时支持 GitOps,整个工作空间可直接版本化管理,更适合工程师主导的 AI Agent 场景。

2. Windmill 架构 链接到标题

Windmill 的核心组件:

  • Windmill Server:提供 Web UI、API 和 MCP Gateway
  • Windmill Worker:执行脚本和流的容器,支持水平扩展
  • PostgreSQL:存储所有状态(工作流定义、Job 队列、权限等)
  • Caddy:反向代理,提供统一入口
flowchart TB subgraph Windmill 系统 A[Caddy] --> B[Windmill Server] B --> C[PostgreSQL] B --> D[Worker] D --> C end E[AI Agent] -->|MCP| A F[LLM Client] -.->|对话| E style A fill:#e3f2fd,stroke:#1565c0,stroke-width:2px style B fill:#e3f2fd,stroke:#1565c0,stroke-width:2px style C fill:#fff3e0,stroke:#e65100,stroke-width:2px style D fill:#e8f5e9,stroke:#2e7d32,stroke-width:2px style E fill:#f3e5f5,stroke:#6a1b9a,stroke-width:2px style F fill:#fce4ec,stroke:#c62828,stroke-width:2px

3. 快速安装部署 链接到标题

Windmill 提供完整的 Docker Compose 配置,包含 PostgreSQL 数据库。以下是简化后的最小配置(仅保留 Server + Default Worker + PostgreSQL):

# docker-compose.yaml
version: '3.8'

services:
  postgres:
    image: postgres:16
    restart: unless-stopped
    environment:
      POSTGRES_PASSWORD: windmill_secret
      POSTGRES_DB: windmill
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: [\"CMD-SHELL\", \"pg_isready -U postgres\"]
      interval: 10s
      timeout: 5s
      retries: 5

  windmill:
    image: ghcr.io/windmill-labs/windmill:latest
    pull_policy: always
    restart: unless-stopped
    ports:
      - \"8010:8000\"
      - \"8011:8001\"
    environment:
      - DATABASE_URL=postgres://postgres:windmill_secret@postgres:5432/windmill
      - MODE=server
      - BASE_URL=http://localhost:3900
    depends_on:
      postgres:
        condition: service_healthy
    volumes:
      - ./logs:/tmp/windmill/logs

  worker:
    image: ghcr.io/windmill-labs/windmill:latest
    pull_policy: always
    restart: unless-stopped
    deploy:
      replicas: 1
    environment:
      - DATABASE_URL=postgres://postgres:windmill_secret@postgres:5432/windmill
      - MODE=worker
      - WORKER_GROUP=default
      - FAVOR_UNSHARE_PID=true
    volumes:
      - worker_cache:/tmp/windmill/cache
      - ./logs:/tmp/windmill/logs

volumes:
  postgres_data:
  worker_cache:

启动服务:

docker compose up -d

访问 http://localhost:3900,使用默认账号 admin@windmill.dev / changeme 登录。


4. 快速上手 链接到标题

4.1 创建 Token 链接到标题

  1. 登录 Windmill 后,点击右上角头像 → Account Settings
  2. 进入 Tokens 标签页,点击 Generate Token
  3. 填写 Token 名称,选择类型为 Token(非 MCP)
  4. 复制生成的 Token,格式如下:
wm_xxxxxxxxxxxxxxxxxxxx

4.2 编写 HelloWorld Script 链接到标题

  1. 在 Windmill Web UI 中,点击左侧 ScriptsNew Script
  2. 选择语言(如 Python 或 TypeScript)
  3. 输入以下代码:
# main.py
def main(name: str) -> str:
    return f\"Hello, {name}!\"
  1. 点击右上角 Save 保存,然后 Deploy 部署
  2. 脚本路径:u/admin/hello_world

4.3 创建 Webhook Trigger 链接到标题

  1. 在脚本详情页,点击 TriggersWebhooksAdd Webhook
  2. 复制生成的 Webhook URL,格式:
http://<host>/api/w/<workspace>/jobs/run/h/u/<user>/<script_hash>

4.4 curl 调用示例 链接到标题

# 通过 Webhook 触发
curl -X POST "http://localhost:3900/api/w/default/jobs/run/h/u/admin/<script_hash>" \
  -H "Content-Type: application/json" \
  -d '{"name": \"Windmill\"}'

# 通过 API 触发(需要 Token)
curl -X POST "http://localhost:3900/api/w/default/scripts/u/admin/hello_world/run" \
  -H "Authorization: Bearer wm_xxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{"name": \"Windmill\"}'

响应示例:

{
  "id": "00000000000000000000000000000001",
  "status": "queued"
}

5. MCP 集成 链接到标题

Windmill 内置 MCP Server,可以将脚本/流作为工具暴露给 AI Agent。

5.1 创建 MCP Token 和 URL 链接到标题

  1. 进入 Account SettingsTokens,点击 Generate Token
  2. 选择 Generate MCP URL 选项
  3. 在 Scope 配置中选择 all scripts/flows,这样该 Token 有权访问工作区下所有脚本和流程。如果需要更细粒度的控制,可以选择 custom 选项分别选择 script、flow、app 等
  4. MCP URL 格式:
http://<windmill-host>:3900/api/mcp/w/default/mcp?token=<token>

注意:MCP 使用 HTTP Streamable 传输协议,需要 MCP 客户端支持该协议。

5.2 OpenCode 配置 MCP 链接到标题

在 OpenCode 配置文件中(~/.config/opencode/opencode.jsonopencode.jsonc)添加 MCP 服务器配置:

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "windmill": {
      "type": "remote",
      "url": "http://<windmill-host>:3900/api/mcp/w/default/mcp?token=<token>",
      "enabled": true
    }
  }
}

⚠️ 注意:Token 不要暴露在 URL 中,建议通过环境变量传递。

重启 OpenCode 后验证配置:

opencode mcp list

正常输出:

┌─ MCP Servers ──────────────────
│
●  ✓ windmill connected
│    http://<windmill-host>:3900/api/mcp/w/default/mcp?token=<token>
│
└─ 1 server(s)

验证成功后,可以在对话中直接调用 Windmill 脚本:

请帮我运行 hello_world 脚本,输入 name 为 "OpenCode"

5.3 连接验证 链接到标题

在 Claude Desktop / Cursor / OpenCode 等 MCP 客户端中,测试以下调用:

列出我的所有 Windmill 脚本

如果返回脚本列表,说明 MCP 连接正常。


6. 总结 链接到标题

Windmill 提供了完整的工作流执行平台:

  • 异步任务:通过 Webhook / API 触发,Agent 无需等待
  • 多语言支持:Python / TypeScript / Go / Bash 等
  • 内置 MCP:轻松对接 AI Agent,实现工具编排
  • 水平扩展:Worker 支持多副本部署,应对高并发
  • 自托管:Docker Compose 一键部署,PostgreSQL 持久化状态

通过 Windmill + MCP,我们可以构建真正的可编排 AI Agent 工作流,将长时间任务交给 Windmill 后台执行,Agent 专注于规划和决策。