跳到主要内容

Flowise 全景:可视化搭 LLM 应用,图即程序

30 秒导读: Flowise 是一个「可视化拖拽搭 LLM 应用」的 IDE。你在浏览器画布上把「聊天模型 / 检索器 / 提示词 / 智能体」拖成节点、连成线,存下来是一坨 JSON(叫 flowData);后端把这坨 JSON 当源码读,编译成一条真正能跑的 LangChain 流水线(或一个有状态的解释器),接到用户提问就执行、把 token 流式吐回。一句话:图即程序,后端是编译器 + 运行时。


1. 这是什么(零基础也能懂)

一句话定义: Flowise 把「手写 LangChain 编排代码」这件事,变成了「在画布上拖节点、拉连线」。

解决谁的什么问题: 假设你要做一个「带知识库的客服机器人」——用 LangChain 手写,你得自己 new ChatOpenAI()new Retriever()ConversationalRetrievalQAChain.fromLLM(...),再把它们拼起来、处理记忆、处理流式。Flowise 让你把这些每一样都变成画布上的一个,用连线表示「谁的输出喂给谁的输入」,连完点保存就能对外提供一个 /prediction API。给不想手写编排、但懂 LLM 概念的工程师用。

它能做什么:

  • 可视化编排 LLM 链(Chatflow)、多智能体(Multi-Agent / Sequential Agent)、以及新一代的 AgentFlow V2。
  • 内置 380+ 个集成节点(模型 / 向量库 / 工具 / 记忆 / 文档加载器……,见 §7 代码地图)。
  • 一键把画布变成 REST API、可嵌入聊天气泡、流式(SSE)对话。
  • 队列模式水平扩展、执行追踪与评测(observe 包)。

用起来什么样: 装好后 npx flowise start,打开 http://localhost:3000,画布上拖三个框——ChatOpenAIConversation Chain → 连上一个 Buffer Memory——保存,就得到一个能对话的 API:

curl http://localhost:3000/api/v1/prediction/<chatflow-id> \
-X POST -H "Content-Type: application/json" \
-d '{"question": "你好,你是谁?", "streaming": true}'

一句话直觉/类比:flowData源代码,把后端当编译器 + 运行时——你画的图不是「配置」,它就是这个应用的程序,后端负责把它翻译成可执行的东西并跑起来。这条直觉贯穿全部后续章节。

本节不碰底层。记住一件事就行:画布产出一张图,后端把图当程序执行。


2. 顶层全景(它大概怎么转)

Flowise 是一个 pnpm monorepo,六个包分工明确。README 的 👨‍💻 Developers 段只点了前四个核心包,另外两个(agentflow / observe)是后来抽出的可嵌入前端组件(依据:README.md 的 Developers 段 + 各 packages/*/package.jsonname 字段)。

2.1 六包分工

包目录package name职责一句话
packages/serverflowise后端:Express API、把图编译成执行、SSE、队列(本讲的主角)
packages/uiflowise-ui前端:基于 ReactFlow 的拖拽画布,产出 flowData
packages/componentsflowise-components380+ 个集成节点,每个节点是一个实现 init/run 的类
packages/agentflow@flowiseai/agentflow可嵌入的 AgentFlow V2 画布 React 组件
packages/api-documentationflowise-api由 express 自动生成的 swagger-ui API 文档
packages/observe@flowiseai/observe可嵌入的「执行 / 评测 / 运行时」观测组件

2.2 一张图看懂主数据流

怎么读这张图:从上往下是一次对话的生命周期;左边是「设计期」(画图存图),右边是「运行期」(提问→执行→流式回)。命中哪条执行引擎,取决于 chatflow.type(§2.3)。

设计期(浏览器画布)
拖拽节点 + 连线 ──► ReactFlow.toObject() ──► flowData(JSON) 存进 DB
(packages/ui) (ChatFlow 实体)

════════════════════════════════════════════════════════│═══════════════
运行期(一次 /prediction) ▼
① 载入 ChatFlow
POST /prediction/:id │
│ ▼
▼ ② NodesPool 提供节点池
controllers/predictions ──► services/predictions ──► utils/buildChatflow
(设 SSE 头 / 建流) (薄封装) utilBuildChatflow

按 chatflow.type 分流 ③
┌─────────────────┴─────────────────┐
▼ ▼
经典引擎 executeFlow V2 引擎 executeAgentFlow
(CHATFLOW / MULTIAGENT) (AGENTFLOW)
拓扑构建→逐节点 init→ nodeExecutionQueue
ending 节点 run 取一个→跑→入队后继
│ │
└─────────────┬─────────────────────┘

④ SSEStreamer 把 token/事件
逐条 SSE 推回浏览器

2.3 部件职责与落点

部件干什么在哪
Prediction 控制器校验来源、建 SSE 流、队列模式订阅 redispackages/server/src/controllers/predictions/index.ts createPrediction
Prediction 服务薄封装,调 utilBuildChatflowpackages/server/src/services/predictions/index.ts buildChatflow
编译/执行总入口组织数据、按 type 分流两大引擎packages/server/src/utils/buildChatflow.ts utilBuildChatflowexecuteFlow
节点池 NodesPool启动时扫描 components/dist/nodes,实例化每个节点类packages/server/src/NodesPool.ts NodesPool
经典引擎拓扑 BFS 构建 LangChain 流水线packages/server/src/utils/index.ts buildFlow
V2 引擎队列驱动的有状态解释器packages/server/src/utils/buildAgentflow.ts executeAgentFlow
SSE 流器把执行过程逐条推回客户端packages/server/src/utils/SSEStreamer.ts SSEStreamer

3. 主线一句话走完(从请求到回答)

不进代码细节,先把一次 /prediction 的调用链在脑子里连成一条线:

createPrediction ← 控制器:校验 origin、若流式则设 event-stream 头
↓ (controllers/predictions/index.ts)
predictionsServices.buildChatflow ← 服务:薄封装
↓ (services/predictions/index.ts)
utilBuildChatflow ← 总入口:查 DB 拿 chatflow、准备输入
↓ (utils/buildChatflow.ts:990)
executeFlow ← 组织执行数据后,在这里按 type 分流
↓ (utils/buildChatflow.ts:301)
├─ chatflow.type === 'AGENTFLOW' ─────► executeAgentFlow (V2 队列解释器)
│ (utils/buildAgentflow.ts:1541)
└─ 否则(CHATFLOW / MULTIAGENT)───────► 经典拓扑构建 + buildFlow + ending.run

关键分流点是一行判断:utils/buildChatflow.ts:481const isAgentFlowV2 = chatflow.type === 'AGENTFLOW'——命中就 return executeAgentFlow({...}):482),把整条请求交给 V2 引擎;否则继续往下走经典路径。

记住这一层调用链,后面 01–04 章都是在放大这条线上的某一段。控制器如何建 SSE、队列模式怎么接,见 04


4. 两大执行引擎:为什么有两套、怎么分流

Flowise 历史上先有「经典引擎」(面向 Chatflow 和第一代 Multi-Agent),后来新增了「AgentFlow V2」这套更灵活的画布与运行时。两者并存,由持久化在 ChatFlow 实体上的 type 字段决定走哪条(ChatFlow.type,见 packages/server/src/database/entities/ChatFlow.ts)。

4.1 两条路的分流依据

type 由前端保存时写入:经典画布存 CHATFLOWMULTIAGENTpackages/ui/src/views/canvas/index.jsx:236 type: isAgentCanvas ? 'MULTIAGENT' : 'CHATFLOW');AgentFlow V2 画布存 AGENTFLOW。后端两处判断把请求劈开:

判断位置命中后走
chatflow.type === 'AGENTFLOW'buildChatflow.ts:481 isAgentFlowV2V2 队列解释器 executeAgentFlow
端点节点类别是 Multi/Sequential AgentsbuildChatflow.ts:539 isAgentFlow经典引擎里的多智能体子路径 buildAgentGraph(网关在 :605
其余(普通链)同上,false经典引擎:buildFlow + ending 节点 .run()

注意区分三个名字相近、含义不同的变量(别混,这是全篇最易错的一处):

变量位置判定什么作用
isAgentFlowV2:481chatflow.type === 'AGENTFLOW'引擎:V2 还是经典
isAgentFlow:539端点节点类别是不是 Multi Agents / Sequential AgentsendingNodes.filter(... category ...)在经典引擎内部选子路径:走 buildAgentGraph:605if (isAgentFlow) 用的就是它)还是普通链
isAgentFlow:1003另一个同名变量,等于 chatflow.type === 'MULTIAGENT'仅用于指标计数incrementSuccessMetricCounter 等,:1096/1108/1114),buildAgentGraph 分流无关

一句话记住分流层级:引擎级分流看 typeAGENTFLOW→V2);经典引擎内的多智能体子路径看端点类别(:539),而不是看 type === 'MULTIAGENT':1003 那个同名变量只喂指标)。

4.2 两套引擎的根本区别

维度经典引擎(executeFlow)AgentFlow V2(executeAgentFlow)
触发 typeCHATFLOW / MULTIAGENTAGENTFLOW
核心思路拓扑构建:把图当有向图,BFS 从起点初始化到端点,最后 run 端点解释执行:一个 nodeExecutionQueue 队列,取一个节点跑、按输出把后继入队
控制流由图的静态拓扑决定,一次性构建成流水线运行时动态决定——支持条件分支、循环、人工介入(human-in-the-loop)
状态主要靠 LangChain 链自身 + 记忆节点显式的执行状态 agentFlowExecutedData + 共享 state,逐节点累积
入口符号buildChatflow.ts:301 executeFlowbuildAgentflow.ts:1541 executeAgentFlow

经典引擎的骨架:constructGraphsgetEndingNodes / getStartingNodesbuildFlow(逐节点 init)→ ending 节点 .run()buildChatflow.ts:788 endingNodeInstance.run(...))。深入见 02

V2 的骨架是一个 while (nodeExecutionQueue.length > 0 && status === 'INPROGRESS') 循环(buildAgentflow.ts:2020),每轮 shift() 一个节点执行、再 processNodeOutputs 把该走的后继压回队列,直到队空或触达 MAX_ITERATIONS(默认 1000,buildAgentflow.ts:1912)。深入见 03


5. 阅读地图(建议顺序)

按「由浅入深、先数据后引擎」的顺序读:

顺序章节讲什么什么时候读
101-flow-and-node-model.mdflowData 的结构(nodes/edges)、节点类的 init/run 契约、NodesPool 怎么把 380+ 节点装进内存想先搞懂「图是怎么被表示的」
202-classic-engine.md经典引擎:constructGraphs → 拓扑 BFS → 逐节点 init → ending run,多智能体子路径想懂 CHATFLOW/MULTIAGENT 怎么跑
303-agentflow-v2-engine.mdV2:队列解释器、条件/循环/人工介入、stateagentFlowExecutedData想懂 AGENTFLOW 的动态控制流
404-request-lifecycle-streaming-queue.md一次请求从 controller 到 SSE 的全生命周期、队列模式(BullMQ + Redis)水平扩展想懂上线部署与流式细节
505-frontend-canvas.mdReactFlow 画布怎么把拖拽变成 flowData、保存/加载/节点面板想改前端或懂图是怎么产生的

6. 巧妙之处速览(读完带走的精华)

四个贯穿全局的设计决策,先白话点破,细节在各章:

  • 图编译成执行,而不是解释配置。 flowData 不是被逐字「读参数」,而是被当有向图做拓扑分析、构建成真正的对象图再跑。这让「拖拽的图」和「手写的 LangChain 代码」在能力上对齐。(utils/index.ts constructGraphsbuildFlow
  • 节点的 init/run 两段式。 每个节点类分两步:init(nodeData, input, options) 先把自己实例化成一个可用对象(一个 LLM、一个链、一个检索器),run(...) 才真正产出结果。构建期把整张图 init 成对象图,执行期只 run 端点,让上游节点作为下游的「已初始化输入」被注入。(packages/components/src/Interface.ts:162-163utils/index.ts:641newNodeInstance.init(...)
  • 变量插值 {{ }} 节点输入里写 {{ $flow.sessionId }}{{ chat_history }}{{ 上游节点.output }} 这类占位符,构建时由 getVariableValueutils/index.ts:874)在 resolveVariables 中解析成真实值——这是「连线传值」之外的第二套取值机制。V2 另有 $iteration / $flow 等运行时变量(buildAgentflow.tsresolveVariables)。
  • 队列模式水平扩展。MODE=QUEUE 后,Web 进程只负责接收请求与推 SSE,真正的执行被丢进 BullMQ 队列由 Worker 消费(queue/PredictionQueue.ts:107 里 Worker 调 executeFlow),执行事件经 Redis 发布/订阅回传给持有 SSE 连接的 Web 进程(RedisEventPublisher / RedisEventSubscriber)。这让执行层可以独立于接入层横向扩容。见 04

7. 顶层代码地图(导航索引)

用符号名 grep 比行号抗漂移。下表是理解全景该打开的关键文件与符号:

主题文件符号
请求入口 / 建 SSE 流packages/server/src/controllers/predictions/index.tscreatePrediction
服务薄封装packages/server/src/services/predictions/index.tsbuildChatflow
编译/执行总入口packages/server/src/utils/buildChatflow.tsutilBuildChatflow(:990)、executeFlow(:301)
引擎分流点packages/server/src/utils/buildChatflow.tsisAgentFlowV2(:481 选引擎)、isAgentFlow(:539 端点类别选子路径,:605 网关)、isAgentFlow(:1003 是 type==='MULTIAGENT' 的同名变量,仅用于指标)
经典引擎:拓扑 BFS 构建packages/server/src/utils/index.tsbuildFlow(:516)、constructGraphs
经典引擎:端点执行packages/server/src/utils/buildChatflow.tsendingNodeInstance.run(:788)
经典多智能体(LangGraph)packages/server/src/utils/buildAgentGraph.tsbuildAgentGraphcompileMultiAgentsGraphcompileSeqAgentsGraph
V2 引擎:队列解释器packages/server/src/utils/buildAgentflow.tsexecuteAgentFlow(:1541)、主循环(:2020)、executeNode(:1051)
节点池packages/server/src/NodesPool.tsNodesPoolinitializeNodes
节点契约packages/components/src/Interface.tsINode.init(:162)、INode.run(:163)
变量插值packages/server/src/utils/index.tsgetVariableValue(:874)、resolveVariables
SSE 流器packages/server/src/utils/SSEStreamer.tsSSEStreamerstreamTokenEvent(:165)、streamMetadataEvent(:289)
队列模式执行packages/server/src/queue/PredictionQueue.tsexecuteFlow 调用(:107)、BaseQueue new Worker(:61)
持久化实体packages/server/src/database/entities/ChatFlow.tsflowDatatype(CHATFLOW/MULTIAGENT/AGENTFLOW)
前端存图packages/ui/src/views/canvas/index.jsxhandleSaveFlowreactFlowInstance.toObject()(:226-228)

本章只搭心智模型,不重复各章细节。下一步按 §5 的顺序进入 01