2026年7月8日 2 分钟阅读

Wayflow 实战:在任意 Web 应用嵌入 AI 可视化工作流编辑器

tinyash 0 条评论

给产品加一个 AI 工作流编辑器,听起来像是一个需要好几个月的工程。从零搭建拖拽画布、节点调色板、配置面板、运行引擎、还要适配 LLM 调用和 Human-in-the-Loop——光列需求就让人头皮发麻。

Wayflow 用一个 npm install 解决了这个问题。它是一个嵌入式的可视化工作流编辑器:一行代码挂载整个编辑器,开箱即用内置运行引擎,支持 LLM、工具调用、条件分支、人机审批,且框架无关(React、Vue、Svelte 或纯 JS 都能用)。

5 分钟跑起来

安装:

npm install wayflow

编辑器在 5 分钟内就能跑起来。挂载只需要一个容器和一个函数调用:

import { createWorkflowEditor } from 'wayflow'

const editor = createWorkflowEditor(document.getElementById('editor'))

编辑器会填充容器的宽高,所以给容器一个 height(空的

没有高度):

这时你看到的已经是完整的编辑器——画布、左侧节点调色板、右侧配置面板、顶部的运行控制按钮,全部可用。

要让工作流真正运行起来,需要加一个 runtime。Wayflow 提供了 Mock Provider,无需 API Key 即可在浏览器端测试:

import { createWorkflowEditor } from 'wayflow'
import { createLLMHandler, createMockProvider } from 'wayflow/models'
import { createRuntime } from 'wayflow/runtime'
import { runInBrowser } from 'wayflow/runtime/client'

const runtime = createRuntime({
  handlers: {
    llm: createLLMHandler(createMockProvider()),
  },
})

const editor = createWorkflowEditor(
  document.getElementById('editor'),
  {
    llm: { models: ['gpt-5.4-mini'] },
    onRun: ({ inputs, signal }) =>
      runInBrowser({ runtime, editor, inputs, signal }),
  },
)

拖一个 Input、一个 LLM、一个 Output 到画布上,连起来,按 Run——结果就会实时流式显示到每个节点上。整个过程不需要后端服务器,不需要 API Key。

节点图谱:两类节点

Wayflow 的节点分两大类别:Flow(流程控制)和 AI(模型调用)。

Flow 节点

  • Input — 定义工作流的输入参数。每个字段变成一个输出端口,供后续节点连线使用。
  • Output — 收集最终结果,连线进来的数据成为工作流的输出。
  • Conditional — 条件分支。比较值与目标,路由到 True 或 False 路径。
  • Merge — 合并多个输入,支持不同的合并模式(含 zip 列表合并)。
  • Array Operations — 对列表做 filter、map、count、sum 等变换。
  • Human Review — 暂停工作流等待人工审批或拒绝,然后继续执行。

AI 节点

  • LLM — 向语言模型发送提示词并获取回复。支持变量注入({ticket} 自动创建同名输入端口)、工具调用、结构化输出和图片输入。
  • Image Generation — 从文本提示词生成图片。

LLM 和 Image Generation 节点可以一次性对列表中的每个项目执行,例如同时总结五十张工单或批量生成多张图片。

LLM 节点:从提示词到结构化输出

LLM 节点是工作流中的核心 AI 能力。在配置面板的 Prompt 字段写入提示词,用 {变量名} 注入上游数据:

你是一个客服助理。用户的工单内容如下:
{ticket}

请判断该工单的优先级并简要说明原因。

输入 {ticket} 后,节点上会自动出现一个同名的输入端口——将上游数据连线进来,运行时就会自动代入。

结构化的输出更加实用。在 LLM 节点的 Output Schema 中添加字段(如 category: texturgency: number),模型将以 JSON 格式返回:

{ "category": "billing", "urgency": 3 }

每个字段变成独立的类型化输出端口——你可以将 category 连线到 Conditional 节点进行分支,将 urgency 传给下一步。

如果模型返回的不是有效的 JSON 或缺少字段,工作流会以清晰的错误信息失败,而不是向下游传递错误数据。

工具调用:让 LLM 操作你的系统

LLM 有语言能力但看不见你的数据。工具节点让模型在工作流执行过程中调用你的函数。

定义一个工具需要三样东西:描述、类型化参数、处理函数:

const getWeather = defineTool({
  description: '查询指定城市的天气',
  args: { city: 'string' },
  handler: async ({ city }) => {
    const res = await fetch(`https://api.example.com/weather?city=${city}`)
    return res.json()
  },
})

description 和参数名是模型决定何时调用工具的依据——写得像向队友解释一样清晰即可。

工具分两边注册。处理函数需要真实的 API 凭证,所以放在服务端的 runtime 中:

const runtime = createRuntime({
  handlers: { llm: createLLMHandler(provider) },
  tools: { getWeather },
})

编辑器端不需要处理函数(也不应该接触到密钥),用 defineToolMetadata 注册工具的名称和描述即可,让用户在节点的 Tools 字段中选择。

Human-in-the-Loop:需要审批的步骤

有些步骤不应该无人值守——发送邮件前需要确认、超过阈值的退款需要审批。Human Review 节点在这些位置暂停工作流,等待人工决策。

拖入一个 Human Review 节点,将待审核的数据连线到其输入端口,设置审批说明,连接 Approved 和 Rejected 两条输出路径。工作流运行到该节点时自动暂停,显示审批卡片,审批人可编辑数据后批准或拒绝。

在生产环境中,暂停可能持续数分钟甚至数天。Wayflow 使用 Run Sessions 实现持久化,只需实现一个 CheckpointStore(对接你的数据库):

const store: CheckpointStore = {
  save: (runId, record) => db.put(runId, JSON.stringify(record)),
  load: async (runId) => {
    const row = await db.get(runId)
    return row ? JSON.parse(row) : undefined
  },
  delete: (runId) => db.delete(runId),
  list: async () => (await db.rows()).map(row => JSON.parse(row)),
}

const sessions = createRunSessions(runtime, { store })

每个 checkpoint 只是 JSON 格式的工作流图加上运行状态——任何数据库都适用。

自定义节点:内置节点不够用时

如果内置的节点类型满足不了你的需求,Wayflow 允许定义完全自定义的节点。一个自定义节点由定义(编辑器中显示什么)和处理函数(运行时做什么)两部分组成。

定义节点的端口和配置:

const sendEmail: NodeTypeDefinition = {
  label: 'Send Email',
  category: 'Custom',
  icon: 'mail',
  ports: {
    inputs: [
      { id: 'to', dataType: 'string', label: 'To' },
      { id: 'body', dataType: 'string', label: 'Body' },
    ],
    outputs: [{ id: 'sent', dataType: 'boolean', label: 'Sent' }],
  },
  configSchema: {
    subject: { type: 'text', label: 'Subject' },
  },
}

在编辑器中注册:

const editor = createWorkflowEditor(element, {
  nodeTypes: { ...BUILTIN_NODE_TYPES, sendEmail },
})

服务端注册处理函数:

const runtime = createRuntime({
  handlers: {
    sendEmail: async (node, inputs) => {
      await sendMail({
        to: inputs.to,
        body: inputs.body,
        subject: node.data.subject,
      })
      return { sent: true }
    },
  },
})

自定义节点出现在调色板中,与内置节点一起使用。

从原型到生产

Wayflow 的运行环境从浏览器到服务端可以无缝切换。开发阶段用 runInBrowser 和 Mock Provider 快速验证流程;生产阶段将 runtime 部署到服务器,对接真实的 LLM 提供商。

典型的落地路径是:你的用户(或你自己的团队)在编辑器里设计工作流——保存为 JSON 图数据到数据库。后端加载这个图,通过 runtime 按需执行——放在自己的 API 后面、定时任务中或队列 worker 里。编辑器只负责创建,不参与运行。

Wayflow 的设计理念正是如此:嵌入,而非重建。它是一个开箱即用的编辑器,但从不限制你将其变成什么。

相关链接

发表评论

你的邮箱地址不会被公开,带 * 的为必填项。