Flowise 深度解析:从零到生产级 AI Agent 平台

0 阅读19分钟

适合人群:产品经理、前端/后端开发者、AI 应用工程师、架构师 代码版本:main 分支,2026年4月

1. Flowise 是什么?为什么要用它

想象你要搭建一个"基于公司内部文档的智能客服"。传统方式需要你:写 PDF 解析代码、接 Embedding API、建向量数据库、写检索逻辑、接 LLM、写对话管理……每一步都是工程活,少则一周多则一月。

Flowise 把这一切变成了拖拽连线

[PDF Loader] ──→ [Text Splitter] ──→ [OpenAI Embeddings] ──→ [Pinecone][用户问题] ──→ [Conversational Retrieval Chain] ←───────────────────┘
                        ↓
               [ChatOpenAI / GPT-4o][流式回答给用户]

这个流程在 Flowise 画布上拖 6 个节点、连几条线,10 分钟搞定。

和同类工具对比:

特性FlowiseLangFlowDifyn8n
开源免费✅ Apache 2.0部分
可视化✅ 直觉拖拽
自托管
原生 API✅ REST + SSE
MCP 协议支持✅ (2026新增)
节点生态丰富度⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
企业版功能

2. 五分钟跑起来

方式一:npx(最快)

npm install -g flowise
npx flowise start
# 打开 http://localhost:3000

方式二:Docker(推荐生产)

git clone https://github.com/FlowiseAI/Flowise.git
cd Flowise/docker
cp .env.example .env
docker compose up -d
# 打开 http://localhost:3000

方式三:源码开发模式

git clone https://github.com/FlowiseAI/Flowise.git
cd Flowise
pnpm install        # 安装所有子包依赖
pnpm build          # 构建所有包
pnpm start          # 生产启动

# 开发模式(热更新)
pnpm dev            # 访问 http://localhost:8080

提示:如果 pnpm build 内存不足报错 JavaScript heap out of memory,先执行 export NODE_OPTIONS="--max-old-space-size=4096"


3. 核心概念图谱

在深入代码之前,先建立概念地图,这是理解一切的基础:

┌─────────────────────────────────────────────────────────────────┐
│                        Flowise 概念全景                          │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  ┌──────────────┐    ┌──────────────┐    ┌──────────────────┐   │
│  │  ChatFlow     │    │  AgentFlow   │    │ OpenAI Assistant │   │
│  │  对话流       │    │  智能体流    │    │ OpenAI原生助手   │   │
│  │  (RAG/Chain) │    │  (V2新引擎)  │    │                  │   │
│  └──────┬───────┘    └──────┬───────┘    └────────┬─────────┘   │
│         │                   │                     │             │
│         └───────────────────┴─────────────────────┘             │
│                             │                                    │
│                    flowData (JSON)                               │
│                    节点 + 边 的有向图                             │
│                             │                                    │
│         ┌───────────────────┼─────────────────────┐             │
│         ▼                   ▼                     ▼             │
│   ┌──────────┐       ┌──────────┐          ┌──────────┐        │
│   │ ChatModel│       │  Tool    │          │  Memory  │        │
│   │ LLM节点  │       │  工具节点 │          │  记忆节点 │        │
│   └──────────┘       └──────────┘          └──────────┘        │
│   ┌──────────┐       ┌──────────┐          ┌──────────┐        │
│   │Embeddings│       │VectorStore│         │Doc Loader│        │
│   │嵌入模型  │       │向量数据库 │          │文档加载器 │        │
│   └──────────┘       └──────────┘          └──────────┘        │
│                                                                  │
│  ┌────────────────────────────────────────────────────────────┐ │
│  │                     支撑系统                                │ │
│  │  Credentials(凭据)  Variables(变量)  DocumentStore(文档库) │ │
│  │  Evaluations(评测)  Executions(执行记录)  MCP(协议接口)    │ │
│  └────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘

三种 Flow 类型对比:

类型适用场景引擎特点
ChatFlowRAG问答、简单对话链LangChain稳定成熟,节点丰富
AgentFlow V2复杂多步骤智能体、循环推理自研引擎支持条件分支、人工介入
OpenAI Assistant直接使用 OpenAI 原生 AssistantOpenAI API内置文件、代码解释器

4. Monorepo 架构全景

Flowise/                          ← 根目录 (pnpm workspace + Turbo)
├── packages/
│   ├── server/                   ← 🖥️  Node.js 后端
│   │   ├── src/
│   │   │   ├── index.ts          ← 应用入口,App 类
│   │   │   ├── routes/           ← 路由层 (60+ 路由)
│   │   │   ├── controllers/      ← 控制器层
│   │   │   ├── services/         ← 业务逻辑层 (39个模块)
│   │   │   ├── database/         ← TypeORM 实体 & 迁移
│   │   │   ├── queue/            ← BullMQ 任务队列
│   │   │   ├── enterprise/       ← 企业版功能
│   │   │   ├── metrics/          ← Prometheus / OpenTelemetry
│   │   │   ├── NodesPool.ts      ← 节点插件加载器
│   │   │   ├── CachePool.ts      ← 实例缓存池
│   │   │   ├── AbortControllerPool.ts ← 请求中止管理
│   │   │   └── utils/            ← 工具函数 (buildChatflow核心在这里)
│   │   └── marketplaces/         ← 内置流程模板 (JSON)
│   │
│   ├── ui/                       ← ⚛️  React 前端
│   │   └── src/
│   │       ├── views/canvas/     ← ReactFlow 可视化画布
│   │       ├── views/chatmessage/ ← 聊天界面
│   │       └── api/              ← 前端 API 调用层
│   │
│   ├── components/               ← 🧩 节点插件库
│   │   ├── nodes/
│   │   │   ├── chatmodels/       ← 26+ LLM (OpenAI/Claude/Gemini...)
│   │   │   ├── vectorstores/     ← 20+ 向量库 (Pinecone/Chroma/PG...)
│   │   │   ├── documentloaders/  ← PDF/Word/Web/Notion...
│   │   │   ├── embeddings/       ← 嵌入模型
│   │   │   ├── memory/           ← 对话记忆
│   │   │   ├── tools/            ← 工具 (搜索/计算/代码...)
│   │   │   ├── agents/           ← Agent 节点
│   │   │   ├── chains/           ← LangChain 链
│   │   │   ├── prompts/          ← Prompt 模板
│   │   │   └── agentflow/        ← AgentFlow V2 专用节点
│   │   └── src/Interface.ts      ← 节点接口规范
│   │
│   ├── agentflow/                ← 🤖 AgentFlow V2 引擎
│   └── api-documentation/        ← 📄 Swagger 文档
│
├── docker/                       ← Docker Compose 配置
└── turbo.json                    ← Turbo 构建配置

包之间的依赖关系:

      ┌─────────────────────────────────────┐
      │              turbo build             │
      └──────────┬──────────────────────────┘
                 │ 构建顺序
      ┌──────────▼──────────┐
      │  packages/components │  ← 先构建(被server依赖)
      └──────────┬───────────┘
                 │
      ┌──────────▼──────────┐
      │  packages/server     │  ← 再构建
      └──────────┬───────────┘
                 │
      ┌──────────▼──────────┐
      │  packages/ui         │  ← 最后构建前端
      └─────────────────────┘

5. Server 后端深度解剖

5.1 启动流程(App 类)

index.ts 中的 App 类是整个后端的心脏,启动分两个阶段:

npx flowise start
       │
       ▼
  start() 函数
       │
       ├─── serverApp.initDatabase()
       │         │
       │         ├─ TypeORM 连接 + 数据库迁移
       │         ├─ IdentityManager   (权限/企业版)
       │         ├─ NodesPool         (扫描加载所有节点插件)
       │         ├─ AbortControllerPool
       │         ├─ getEncryptionKey  (凭据加密)
       │         ├─ initAuthSecrets   (JWT密钥)
       │         ├─ RateLimiterManager
       │         ├─ CachePool
       │         ├─ UsageCacheManager
       │         ├─ Telemetry
       │         ├─ SSEStreamer        (流式推送)
       │         └─ QueueManager      (仅 QUEUE 模式)
       │
       └─── serverApp.config()
                 │
                 ├─ Express 中间件 (cors/cookieParser/xss防护)
                 ├─ 请求日志
                 ├─ JWT/API Key 鉴权中间件
                 ├─ SSO 初始化
                 ├─ Prometheus/OpenTelemetry
                 ├─ /api/v1 路由挂载
                 └─ React SPA 静态文件兜底

5.2 请求鉴权流程

这是后端最复杂的中间件,理解它很重要:

请求到达 /api/v1/xxx
          │
    ┌─────▼──────┐
    │ 路径在白名单?│  ← /prediction/ /public-chatflows 等无需鉴权
    └─────┬──────┘
          │ 否
    ┌─────▼──────────────┐
    │ Header: x-request-from │
    │    === 'internal'?  │
    └─────┬──────────────┘
          │ 否(外部请求)
    ┌─────▼──────────────────┐
    │  validateAPIKey(req)    │  ← 校验 Bearer Token
    └─────┬──────────────────┘
          │ 有效
    ┌─────▼─────────────────────────────────┐
    │  查找 Workspace → Organization         │
    │  获取订阅 → 计划功能 → 注入 req.user   │
    └─────┬─────────────────────────────────┘
          │
         next()

5.3 数据库实体关系

┌──────────────────────────────────────────────────────────────┐
│                    核心数据模型关系                            │
│                                                              │
│  ┌──────────────┐  flowData(JSON)  ┌────────────────────┐   │
│  │   ChatFlow    │◄────────────────►│  IReactFlowObject  │   │
│  │  (核心实体)   │                  │  nodes[] + edges[] │   │
│  └──────┬───────┘                  └────────────────────┘   │
│         │ 1:N                                                │
│         ▼                                                    │
│  ┌──────────────┐     ┌─────────────────────────────────┐   │
│  │  ChatMessage  │     │ ChatMessageFeedback (点赞/差评) │   │
│  │  对话记录     │────►│                                 │   │
│  └──────────────┘     └─────────────────────────────────┘   │
│                                                              │
│  ┌──────────────┐     ┌──────────────────────────────────┐  │
│  │  Credential   │     │       DocumentStore              │  │
│  │  加密凭据     │     │  ┌─────────────────────────┐    │  │
│  └──────────────┘     │  │ DocumentStoreFileChunk   │    │  │
│                        │  │ (向量化后的文档分块)      │    │  │
│  ┌──────────────┐     │  └─────────────────────────┘    │  │
│  │  Variable     │     └──────────────────────────────────┘  │
│  │  全局变量     │                                            │
│  └──────────────┘     ┌──────────────────────────────────┐  │
│                        │ Evaluation + EvaluationRun        │  │
│  ┌──────────────┐     │ Dataset + DatasetRow               │  │
│  │  Execution    │     │ Evaluator   ← 评测体系             │  │
│  │  执行记录     │     └──────────────────────────────────┘  │
│  └──────────────┘                                            │
└──────────────────────────────────────────────────────────────┘

关键:ChatFlow.flowData 字段存储的是一个 JSON 字符串,反序列化后是 IReactFlowObject

// packages/server/src/Interface.ts
interface IReactFlowObject {
  nodes: IReactFlowNode[]   // 每个节点:id、type、data(含inputs)
  edges: IReactFlowEdge[]   // 节点间的连接:source → target
  viewport: { x, y, zoom }
}

这个 JSON 就是整个 AI 流程的"蓝图",引擎读取它来执行推理。

5.4 服务层 39 个模块速查

services/
├── 核心流程
│   ├── predictions/         AI推理入口
│   ├── chatflows/           Flow CRUD
│   ├── chat-messages/       对话记录
│   └── executions/          执行历史 (AgentFlow)
│
├── RAG 知识库
│   ├── documentstore/       文档管理 & 向量化
│   ├── vectors/             向量 upsert
│   └── upsert-history/      向量化历史
│
├── 模型 & 工具
│   ├── credentials/         凭据加密存储
│   ├── tools/               自定义工具
│   ├── nodes/               组件节点查询
│   ├── variables/           全局变量
│   └── settings/            系统设置
│
├── OpenAI 专项
│   ├── assistants/          OpenAI Assistant
│   ├── openai-assistants/   Assistant 对话
│   ├── openai-assistants-vector-store/
│   └── openai-realtime/     实时语音对话
│
├── AI 评测
│   ├── evaluations/         评测运行管理
│   ├── evaluator/           评测器配置
│   └── dataset/             评测数据集
│
├── MCP 协议 (2026新增)
│   ├── mcp-server/          将Chatflow发布为MCP Server
│   └── mcp-endpoint/        MCP端点处理
│
├── 平台功能
│   ├── marketplaces/        模板市场
│   ├── export-import/       导入导出
│   ├── stats/               统计数据
│   ├── feedback/            用户反馈
│   ├── leads/               潜在用户收集
│   ├── apikey/              API Key 管理
│   ├── agentflowv2-generator/ AI生成Flow
│   └── text-to-speech/      文字转语音
│
└── 基础设施
    ├── log/                 日志
    ├── validation/          输入校验
    ├── fetch-links/         URL内容获取
    └── load-prompts/        Prompt加载

6. 节点系统:一切皆插件

节点系统是 Flowise 最精妙的设计,理解它就理解了整个扩展机制。

6.1 节点接口规范

每个节点必须实现 INode 接口(来自 packages/components/src/Interface.ts):

// 节点的标准结构(以 Calculator 工具节点为例)
class Calculator_Tools implements INode {
  label: string    // UI 显示名称: "Calculator"
  name: string     // 编程标识符: "calculator"(存入flowData)
  version: number  // 版本号,用于迁移兼容
  type: string     // 节点类型: "Calculator"
  icon: string     // 图标文件名
  category: string // 分类: "Tools"
  description: string
  baseClasses: string[]  // ⚡ 关键!决定节点可连接到哪些插槽
  
  inputs?: INodeParams[]    // 输入参数列表
  credential?: INodeParams  // 凭据配置
  
  // 初始化:返回可用的 LangChain 对象
  async init(nodeData: INodeData, input: string, options: ICommonObject): Promise<any>
  
  // 可选:动态加载选项(如模型列表)
  loadMethods?: {
    [key: string]: (nodeData: INodeData) => Promise<INodeOptionsValue[]>
  }
}

6.2 以 ChatOpenAI 节点为例看完整实现

class ChatOpenAI_ChatModels implements INode {
  constructor() {
    this.label = 'OpenAI'
    this.name = 'chatOpenAI'
    this.version = 8.3
    this.type = 'ChatOpenAI'
    this.category = 'Chat Models'
    
    // baseClasses 决定"这个节点的输出可以插入哪些接口"
    // 继承 LangchainChatOpenAI 的所有父类,使插槽兼容
    this.baseClasses = [this.type, ...getBaseClasses(LangchainChatOpenAI)]
    
    // 凭据配置
    this.credential = {
      label: 'Connect Credential',
      name: 'credential',
      type: 'credential',
      credentialNames: ['openAIApi']
    }
    
    // 参数配置 → 对应 UI 侧面板的表单
    this.inputs = [
      { label: 'Model Name', name: 'modelName', type: 'asyncOptions',
        loadMethod: 'listModels', default: 'gpt-4o-mini' },
      { label: 'Temperature', name: 'temperature', type: 'number',
        step: 0.1, default: 0.9 },
      { label: 'Reasoning', name: 'reasoning', type: 'boolean',
        description: 'For o-series and gpt-5 reasoning models' },
      // ... 更多参数
    ]
  }
  
  // 动态加载模型列表(从 OpenAI API 拉取)
  loadMethods = {
    async listModels(): Promise<INodeOptionsValue[]> {
      return await getModels(MODEL_TYPE.CHAT, 'chatOpenAI')
    }
  }
  
  // 核心:初始化并返回 LangChain ChatOpenAI 实例
  async init(nodeData: INodeData, _: string, options: ICommonObject): Promise<any> {
    const credentialData = await getCredentialData(nodeData.credential, options)
    const openAIApiKey = getCredentialParam('openAIApiKey', credentialData, nodeData)
    
    const model = new ChatOpenAI({
      temperature: parseFloat(nodeData.inputs.temperature),
      modelName: nodeData.inputs.modelName,
      openAIApiKey,
      streaming: true
    })
    return model
  }
}

module.exports = { nodeClass: ChatOpenAI_ChatModels }

6.3 NodesPool 启动加载机制

服务器启动
     │
     ▼
NodesPool.initialize()
     │
     ├─ 扫描 packages/components/nodes/** 目录
     │       每个子目录 = 一个节点
     │
     ├─ require(节点文件)  ← 动态加载 .js 文件
     │       取出 nodeClass
     │
     ├─ new nodeClass()   ← 实例化,读取 label/name/type/inputs 等元数据
     │
     └─ componentNodes[name] = instance
              │
              ▼
     内存 Map: { "chatOpenAI": ChatOpenAI实例,
                 "calculator": Calculator实例,
                 "pinecone": Pinecone实例,
                 ... 200+ 节点 }

这就是为什么增加一个新节点只需要在 components/nodes/ 下新建一个目录和文件,重启后自动可用。

6.4 当前支持的节点生态(26 大类)

chatmodels/     → OpenAI, Claude(Anthropic), Gemini, Ollama, DeepSeek,
                  Groq, Mistral, Cohere, Bedrock, Azure, HuggingFace...
                  共 25+ 模型

vectorstores/   → Pinecone, Chroma, Weaviate, Qdrant, PGVector, 
                  Supabase, Milvus, OpenSearch, Redis, Faiss...

documentloaders/→ PDF, Word, Excel, PowerPoint, Notion, GitHub,
                  Confluence, YouTube, Playwright, Cheerio...

embeddings/     → OpenAI, Cohere, HuggingFace, Bedrock, Ollama...

tools/          → Calculator, SerpAPI, Browserless, DuckDuckGo,
                  WriteFile, ReadFile, SQL Database, Custom Function...

memory/         → BufferMemory, SummaryMemory, RedisMemory,
                  PostgresMemory, ZepMemory, MotorHead...

chains/         → ConversationalRetrievalQA, LLMChain,
                  MultiPromptChain, ApiChain...

agents/         → ConversationalAgent, ToolAgent, OpenAI Function Agent...

agentflow/      → AgentFlow V2 专用: LLM节点、工具节点、条件节点...

7. 一次对话的完整生命周期

这是理解 Flowise 运行原理最关键的部分,我们追踪一次用户提问的全程:

┌──────────────────────────────────────────────────────────────────────┐
│               一次 AI 对话的完整生命周期                               │
└──────────────────────────────────────────────────────────────────────┘

用户在聊天框输入: "公司的退款政策是什么?"
       │
       │ HTTP POST /api/v1/prediction/{chatflowId}
       │ Body: { question, chatId, streaming: true }
       ▼
┌─────────────────────────────────┐
│  鉴权中间件                      │
│  检查 Bearer Token / 白名单      │
└────────────┬────────────────────┘
             │
             ▼
┌─────────────────────────────────┐
│  predictionsController           │
│  → predictionsService.buildChatflow()
└────────────┬────────────────────┘
             │
             ▼
┌─────────────────────────────────────────────────────────────────┐
│  utilBuildChatflow() ← 核心函数 (buildChatflow.ts, 1164行)       │
│                                                                  │
│  1. 从数据库读取 ChatFlow                                         │
│     chatflow = await db.findOne(ChatFlow, { id: chatflowId })    │
│                                                                  │
│  2. 解析 flowData JSON                                            │
│     const { nodes, edges } = JSON.parse(chatflow.flowData)       │
│                                                                  │
│  3. 识别起始节点 & 结束节点                                        │
│     startingNodes = nodes without incoming edges                 │
│     endingNode   = node with type "conversationalRetrievalQA"    │
│                                                                  │
│  4. 拓扑排序节点                                                  │
│     按依赖关系确定节点执行顺序                                      │
│                                                                  │
│  5. 逐节点 init()                                                 │
│     ┌──────────────────────────────────────────────┐            │
│     │  [Pinecone] → init() → return PineconeStore  │            │
│     │       ↓                                      │            │
│     │  [OpenAI Embeddings] → init() → return model │            │
│     │       ↓                                      │            │
│     │  [ChatOpenAI] → init() → return llm          │            │
│     │       ↓                                      │            │
│     │  [BufferMemory] → init() → return memory     │            │
│     │       ↓                                      │            │
│     │  [ConversationalRetrievalQA]                 │            │
│     │    → init(vectorstore, llm, memory)          │            │
│     │    → return chain                             │            │
│     └──────────────────────────────────────────────┘            │
│                                                                  │
│  6. CachePool 检查                                               │
│     已缓存的实例直接复用,避免重复初始化                            │
│                                                                  │
│  7. executeFlow()                                                │
│     chain.invoke({ question: "公司的退款政策是什么?" })           │
│                                                                  │
└────────────┬────────────────────────────────────────────────────┘
             │
             ▼
┌─────────────────────────────────────────────────────────────────┐
│  流式输出 (SSEStreamer)                                           │
│                                                                  │
│  LLM 每生成一个 token → SSEStreamer.streamCustomEvent()          │
│                                                                  │
│  客户端收到:                                                      │
│  data: {"event":"token","data":"根"}                             │
│  data: {"event":"token","data":"据"}                             │
│  data: {"event":"token","data":"公"}                             │
│  data: {"event":"token","data":"司"}                             │
│  ...                                                             │
│  data: {"event":"end","data":"[DONE]"}                           │
└────────────┬────────────────────────────────────────────────────┘
             │
             ▼
┌─────────────────────────────────┐
│  保存对话记录                    │
│  chatMessageService.create({    │
│    role: "apiMessage",          │
│    content: "完整回答...",       │
│    sourceDocuments: [...],      │
│    chatflowid, chatId           │
│  })                             │
└─────────────────────────────────┘

关于 Queue 模式(生产高并发):

普通模式(单机):
  请求 → Server → 直接执行 → 响应

Queue 模式(分布式):
  请求 → Server → BullMQ → Redis → Worker → 执行
                                       ↓
  Server ← SSE ← RedisEventSubscriber ←┘

Queue 模式通过设置 MODE=queue + REDIS_URL 环境变量开启,适合高并发生产环境。


8. 三大进阶能力

8.1 RAG 知识库系统(DocumentStore)

文档存储是 RAG(检索增强生成)的基础设施:

┌─────────────────────────────────────────────────────┐
│               DocumentStore 生命周期                  │
├─────────────────────────────────────────────────────┤
│                                                      │
│  上传阶段                                             │
│  ┌────────┐   ┌──────────────┐   ┌───────────────┐  │
│  │ 上传文件│──►│ DocumentStore│──►│文件分块 Chunk │  │
│  │PDF/URL │   │ (数据库记录) │   │ (存 SQLite)   │  │
│  └────────┘   └──────────────┘   └───────┬───────┘  │
│                                           │          │
│  向量化阶段                               ▼          │
│  ┌────────────────┐   ┌─────────────────────────┐   │
│  │ Embedding 模型  │──►│ 向量数据库 (Pinecone等) │   │
│  │ (OpenAI/Cohere)│   │ 存储 向量 + metadata    │   │
│  └────────────────┘   └─────────────────────────┘   │
│                                                      │
│  查询阶段                                             │
│  ┌──────────────┐  相似度检索  ┌──────────────────┐  │
│  │ 用户问题     │────────────►│ 向量数据库        │  │
│  │ → 向量化     │             │ Top-K 相关文档块  │  │
│  └──────────────┘             └────────┬─────────┘  │
│                                        │             │
│  ┌─────────────────────────────────────▼──────────┐  │
│  │              LLM                               │  │
│  │  System: "基于以下文档回答...[检索到的文档]"    │  │
│  │  User:   "公司的退款政策是什么?"              │  │
│  └────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────┘

8.2 MCP 协议集成(2026年最新特性)

MCP(Model Context Protocol)是 Anthropic 主导的 AI 工具标准协议。Flowise 2026年4月新增了将 ChatFlow 发布为 MCP Server 的能力:

                    MCP 架构
┌────────────────────────────────────────────────────┐
│                                                    │
│  MCP Client               MCP Server (Flowise)     │
│  (Claude Desktop          ┌─────────────────────┐  │
│   / Cursor / 自研)        │  任意 ChatFlow       │  │
│                           │  + MCP 开关          │  │
│  "查一下公司知识库"──────►│  token验证           │  │
│                           │  → 执行 Flow         │  │
│  ◄──── 返回结构化结果 ────│  → 返回 MCP 格式     │  │
│                           └─────────────────────┘  │
└────────────────────────────────────────────────────┘

代码侧,mcp-server/index.ts 负责管理配置,核心是为每个 Chatflow 生成一个 128-bit 随机 token,并用恒时比较crypto.timingSafeEqual)防止时序攻击:

// 安全的 token 校验(防时序攻击)
const storedBuffer  = Buffer.from(config.token,  'utf8')
const providedBuffer = Buffer.from(token, 'utf8')
if (!crypto.timingSafeEqual(storedBuffer, providedBuffer)) {
  throw new InternalFlowiseError(StatusCodes.UNAUTHORIZED, 'Invalid token')
}

8.3 AI 评测系统

评测系统用于衡量你的 Agent/RAG 效果,是生产落地的关键:

┌─────────────────────────────────────────────────────────────────┐
                      AI 评测体系架构                              
├─────────────────────────────────────────────────────────────────┤
                                                                  
  第一步:准备数据集                                               
  ┌──────────────────────────────────────────┐                   
           Dataset (数据集)                                     
    ┌─────────────────────────────────────┐                    
     DatasetRow 1: input / expected_output│                    
     DatasetRow 2: ...                                       
     DatasetRow N: ...                                       
    └─────────────────────────────────────┘                    
  └──────────────────────────────────────────┘                   
                                                                  
  第二步:配置评测器 (Evaluator)                                   
  ┌──────────────────────────────────────────────────────────┐   
    规则型评测器:      Contains / DoesNotContain / Equals      
                      StartsWith / EndsWith / Regex            
    LLM 评测器:       使用另一个LLM判断答案质量                  
  └──────────────────────────────────────────────────────────┘   
                                                                  
  第三步:运行评测 (Evaluation Run)                               
  ┌──────────────────────────────────────────────────────────┐   
    对每条 DatasetRow:                                          
    1. 调用目标 ChatFlow (POST /api/v1/prediction)             
    2. 获取 actual_output                                      
    3. 用评测器对比 actual vs expected                          
    4. 记录 pass/fail + 评分                                    
  └──────────────────────────────────────────────────────────┘   
                                                                 
  第四步:查看报告(通过率、平均分、逐条对比)                        
└─────────────────────────────────────────────────────────────────┘

9. 生产部署方案

9.1 环境变量速查(.env 核心配置)

# ===== 基础 =====
PORT=3000
HOST=0.0.0.0

# ===== 数据库 (默认 SQLite,生产推荐 PostgreSQL) =====
DATABASE_TYPE=postgres
DATABASE_HOST=your-db-host
DATABASE_PORT=5432
DATABASE_NAME=flowise
DATABASE_USER=postgres
DATABASE_PASSWORD=yourpassword

# ===== 加密密钥 (用于加密存储的 API Keys) =====
SECRETKEY_STORAGE_TYPE=local    # 或 aws (AWS Secrets Manager)
FLOWISE_SECRETKEY_OVERWRITE=your-random-32char-key

# ===== 认证 (不设则无登录限制) =====
FLOWISE_USERNAME=admin
FLOWISE_PASSWORD=your-password

# ===== 文件存储 =====
BLOB_STORAGE_TYPE=local         # 或 s3
STORAGE_PATH=/data/flowise

# ===== 高并发队列模式 =====
MODE=queue
REDIS_URL=redis://your-redis:6379
QUEUE_NAME=flowise-queue

# ===== 速率限制 =====
CHATFLOW_RATE_LIMIT_MAX_REQUEST=100
CHATFLOW_RATE_LIMIT_DURATION_IN_MIN=1

# ===== 监控 =====
ENABLE_METRICS=true
METRICS_PROVIDER=prometheus     # 或 open_telemetry

9.2 三种部署规模

小型(个人/小团队)

单机部署
┌────────────────────────────────┐
│  Docker Container              │
│  ┌──────────┐  ┌────────────┐  │
│  │ Flowise  │  │  SQLite    │  │
│  │ Server   │  │ (本地文件) │  │
│  └──────────┘  └────────────┘  │
│  本地文件系统存储附件            │
└────────────────────────────────┘

中型(企业内部)

docker-compose 部署
┌────────────────────────────────────────────────┐
│                                                │
│  ┌────────────┐   ┌──────────┐  ┌──────────┐  │
│  │  Flowise   │──►│PostgreSQL│  │  Redis   │  │
│  │  (主进程)  │   │(持久化DB)│  │(会话/缓存)│  │
│  └────────────┘   └──────────┘  └──────────┘  │
│          │                                     │
│          └──► S3/MinIO (文件存储)               │
│                                                │
│  Nginx 反向代理 + HTTPS                         │
└────────────────────────────────────────────────┘

大型(高并发 SaaS)

分布式部署(Queue 模式)
┌──────────────────────────────────────────────────────────┐
│                                                          │
│  ┌──────────────────────────────────────────────────┐   │
│  │              负载均衡 (Nginx/ALB)                  │   │
│  └─────────────────────┬────────────────────────────┘   │
│                         │                                │
│          ┌──────────────┼──────────────┐                │
│          ▼              ▼              ▼                │
│  ┌──────────────┐ ┌──────────────┐ ┌──────────────┐    │
│  │  Flowise     │ │  Flowise     │ │  Flowise     │    │
│  │  Server 1    │ │  Server 2    │ │  Server 3    │    │
│  │  (API层)     │ │  (API层)     │ │  (API层)     │    │
│  └──────┬───────┘ └──────┬───────┘ └──────┬───────┘    │
│         │                │                │             │
│         └────────────────┼────────────────┘             │
│                          ▼                              │
│              ┌──────────────────────┐                  │
│              │  Redis + BullMQ 队列  │                  │
│              └──────────┬───────────┘                  │
│                         │                               │
│          ┌──────────────┼──────────────┐               │
│          ▼              ▼              ▼               │
│  ┌──────────────┐ ┌──────────────┐ ┌──────────────┐   │
│  │  Worker 1    │ │  Worker 2    │ │  Worker N    │   │
│  │  (执行Flow) │ │  (执行Flow) │ │  (执行Flow) │   │
│  └──────────────┘ └──────────────┘ └──────────────┘   │
│                          │                              │
│              ┌───────────┴──────────┐                  │
│              │  PostgreSQL (主数据库)│                  │
│              └──────────────────────┘                  │
└──────────────────────────────────────────────────────────┘

10. 实战示例:从简单到高级

🟢 入门示例一:Hello World 对话机器人

场景:最简单的 AI 对话,不接任何外部知识库。

节点配置(2个节点):

[ChatPromptTemplate]
  System: "你是一个友好的助手,用中文回答问题。"
  Human:  "{input}"
       ↓
[ChatOpenAI]
  Model: gpt-4o-mini
  Temperature: 0.7
       ↓
  回答输出

API 调用

# 部署后,通过 API 调用(无需 API Key 的公开 Flow)
curl -X POST "http://localhost:3000/api/v1/prediction/{chatflowId}" \
  -H "Content-Type: application/json" \
  -d '{"question": "你好,介绍一下你自己"}'

# 响应
{
  "text": "你好!我是一个友好的AI助手,我可以帮助你回答各种问题...",
  "chatId": "abc123",
  "sessionId": "session-xyz"
}

🟡 进阶示例二:公司文档智能问答(RAG)

场景:将公司 PDF 文档接入 AI,实现精准问答。

完整节点配置(6个节点):

┌──────────────────────────────────────────────────────────────┐
│                      RAG 问答 Flow                            │
│                                                              │
│  [PDF File Loader]         [OpenAI Embeddings]               │
│  上传公司文档.pdf    ────►  text-embedding-3-small            │
│       ↓                          ↓                           │
│  [Recursive Text Splitter]       │                           │
│  chunkSize: 1000           ──────┘                           │
│  chunkOverlap: 200               ↓                           │
│       └─────────────────► [Chroma Vector Store]              │
│                            collection: "company-docs"        │
│                                   ↓                          │
│  [Buffer Memory]          [Conversational Retrieval QA]      │
│  对话历史记忆        ────►  Chain (核心链)                     │
│                                   │                          │
│                            [ChatOpenAI]                      │
│                            gpt-4o, temperature: 0            │
└──────────────────────────────────────────────────────────────┘

带流式输出的 API 调用

// 使用 EventSource 接收流式输出
const eventSource = new EventSource(
  `http://localhost:3000/api/v1/chatflows-streaming/${chatflowId}`
)

// 发送问题
const response = await fetch(
  `http://localhost:3000/api/v1/prediction/${chatflowId}`,
  {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${apiKey}`   // 如果开启了鉴权
    },
    body: JSON.stringify({
      question: "我们的年假政策是什么?",
      chatId: "user-session-001",     // 保持会话连续性
      streaming: true
    })
  }
)

// 逐 token 处理
const reader = response.body.getReader()
while (true) {
  const { done, value } = await reader.read()
  if (done) break
  const text = new TextDecoder().decode(value)
  // text 格式: "data: {"event":"token","data":"根"}\n\n"
  process.stdout.write(parseToken(text))
}

生产优化技巧

  • Document Store 中提前向量化,避免每次请求重新处理文档
  • 对 Chroma/Pinecone 设置 topK: 5,只检索最相关的 5 块
  • 使用 Buffer Memory with max token limit 控制历史长度,防止超出上下文

🟠 高级示例三:多工具 ReAct Agent(可搜索+可计算)

场景:搭建一个能联网搜索、做数学计算、查询天气的智能助手。

┌──────────────────────────────────────────────────────────────┐
│                    多工具 Agent Flow                           │
│                                                              │
│  工具层(3个工具节点)                                          │
│  [Calculator] [SerpAPI Search] [Custom HTTP Tool]            │
│       │              │                │                      │
│       └──────────────┼────────────────┘                      │
│                       ↓                                      │
│              [Tool Agent 节点]                               │
│              AgentType: openai-function-agent                │
│                       │                                      │
│              [ChatOpenAI]                                    │
│              Model: gpt-4o                                   │
│              Temperature: 0                                  │
│                       │                                      │
│              [Buffer Memory]                                 │
│              对话历史                                         │
└──────────────────────────────────────────────────────────────┘

自定义 HTTP Tool 配置(调用企业内部 API):

{
  "name": "get_employee_info",
  "description": "查询员工信息,输入员工ID,返回姓名、部门、职级",
  "url": "https://internal.company.com/api/employees/{employeeId}",
  "method": "GET",
  "headers": {
    "Authorization": "Bearer {{$vars.INTERNAL_API_KEY}}"
  }
}

运行过程(ReAct 推理链):

用户: "帮我查一下工号 E001 的张三,顺便算下他入职3年的年薪总计(年薪15万)"

Agent 思考:
  1. 需要查员工信息 → 调用 get_employee_info(E001)
  2. 工具返回:{"name":"张三","salary":150000}
  3. 需要计算 → 调用 Calculator("150000 * 3")
  4. 工具返回:450000
  5. 综合输出答案

Agent: "张三(工号E001)入职3年的年薪总计为45万元。"

🔴 专家示例四:AgentFlow V2 多步骤审批流程

场景:用 AgentFlow V2 构建一个"内容审核 + 人工介入"的智能体,不合格内容自动退回,合格后才发布。

┌─────────────────────────────────────────────────────────────────┐
│                  AgentFlow V2 内容审核流                         │
│                                                                  │
│  [Start 节点]                                                    │
│   接收: { content: "待审核文章内容" }                              │
│       ↓                                                          │
│  [LLM 节点 - 内容安全审核]                                        │
│   System: "你是内容审核专家,检测违规内容"                          │
│   输出 JSON: { safe: true/false, reason: "..." }                  │
│       ↓                                                          │
│  [Condition 节点]  ← 条件分支                                     │
│   if safe == true → 走"通过"分支                                  │
│   if safe == false → 走"拒绝"分支                                 │
│       │                    │                                      │
│       ▼                    ▼                                      │
│  [HumanInput 节点]     [DirectReply 节点]                         │
│  "内容待审核,请确认"   "内容违规,已拒绝: {reason}"               │
│  等待人工点击继续         流程结束                                  │
│       ↓                                                          │
│  [HTTP 节点]                                                      │
│  POST 到发布 API                                                  │
│       ↓                                                          │
│  [DirectReply 节点]                                               │
│  "发布成功!"                                                      │
└─────────────────────────────────────────────────────────────────┘

AgentFlow V2 专属节点一览:

节点作用
Start流程入口,定义输入参数结构
LLM调用 LLM 处理,支持结构化输出
Agent带工具调用的自主 Agent
Condition基于规则/LLM 的条件分支
ConditionAgentLLM 判断走哪条分支
HumanInput暂停等待人工输入/确认
Loop循环执行,直到满足条件
Iteration对列表逐项处理
HTTP调用外部 HTTP API
CustomFunction执行自定义 JavaScript
ExecuteFlow嵌套调用另一个 ChatFlow
RetrieverRAG 检索
DirectReply直接返回结果,结束流程
StickyNote注释说明,不影响执行

🔴 专家示例五:将 Flow 暴露为 MCP Server

场景:把你的公司知识库问答 Flow 变成 MCP 工具,让 Claude Desktop 直接调用。

第一步:在 Flow 设置中开启 MCP Server

Flow 设置 → MCP Server → 开启
  Tool Name: "company_knowledge_base"
  Description: "查询公司内部知识库,包含HR政策、产品文档等"
→ 生成 Token: a1b2c3d4...(32位hex,128bit熵)

第二步:配置 Claude Desktop(~/Library/Application Support/Claude/claude_desktop_config.json

{
  "mcpServers": {
    "company-kb": {
      "url": "http://your-flowise.com/api/v1/mcp/{chatflowId}",
      "headers": {
        "Authorization": "Bearer a1b2c3d4..."
      }
    }
  }
}

第三步:Claude Desktop 直接调用

用户(在Claude Desktop中): 
  "帮我查一下公司的年假政策"

Claude 自动调用 MCP 工具:
  company_knowledge_base(query="年假政策")
  → Flowise 执行 RAG Flow
  → 返回相关内容

Claude: "根据公司规定,年假政策如下:入职满1年享有5天..."

安全机制(代码层面):

// mcp-server/index.ts 中的 Token 校验
// 使用 crypto.timingSafeEqual 防止时序攻击
const storedBuffer  = Buffer.from(config.token,  'utf8')
const providedBuffer = Buffer.from(token, 'utf8')
if (storedBuffer.length !== providedBuffer.length
    || !crypto.timingSafeEqual(storedBuffer, providedBuffer)) {
  throw new InternalFlowiseError(401, 'Invalid token')
}

11. 二次开发:自定义节点

自定义节点是 Flowise 最强大的扩展点,掌握它就能接入任何服务。

11.1 节点开发完整模板

// packages/components/nodes/tools/MyCustomTool/MyCustomTool.ts

import { INode, INodeData, INodeParams, ICommonObject } from '../../../src/Interface'
import { getBaseClasses } from '../../../src/utils'
import { Tool } from '@langchain/core/tools'

// Step 1: 定义工具的实际逻辑(继承 LangChain Tool)
class MyCustomToolLogic extends Tool {
  name = 'my_custom_tool'
  description = '这个工具做什么事,Agent 会根据这段描述决定何时调用它'
  
  private apiEndpoint: string
  private apiKey: string
  
  constructor(apiEndpoint: string, apiKey: string) {
    super()
    this.apiEndpoint = apiEndpoint
    this.apiKey = apiKey
  }
  
  // 核心:工具被 Agent 调用时执行的逻辑
  async _call(input: string): Promise<string> {
    try {
      const response = await fetch(`${this.apiEndpoint}?q=${encodeURIComponent(input)}`, {
        headers: { 'Authorization': `Bearer ${this.apiKey}` }
      })
      const data = await response.json()
      return JSON.stringify(data)
    } catch (error) {
      return `Error: ${error.message}`
    }
  }
}

// Step 2: 定义节点类(INode 接口)
class MyCustomTool_Tools implements INode {
  label: string
  name: string
  version: number
  description: string
  type: string
  icon: string
  category: string
  baseClasses: string[]
  inputs: INodeParams[]
  credential: INodeParams

  constructor() {
    this.label = '我的自定义工具'          // UI 显示名
    this.name = 'myCustomTool'             // 编程标识符(唯一)
    this.version = 1.0
    this.type = 'MyCustomTool'
    this.icon = 'custom-tool.svg'          // 放到 nodes/icons/ 目录
    this.category = 'Tools'
    this.description = '调用我的自定义 API 服务'
    
    // 告诉系统这个节点可以接入哪些插槽
    this.baseClasses = [this.type, ...getBaseClasses(MyCustomToolLogic)]
    
    // 凭据配置(可选,存入加密的 Credential 表)
    this.credential = {
      label: 'API Key',
      name: 'credential',
      type: 'credential',
      credentialNames: ['myServiceApi']    // 需在 credentials/ 下对应定义
    }
    
    // 输入参数(会在 UI 侧面板显示为表单)
    this.inputs = [
      {
        label: 'API Endpoint',
        name: 'apiEndpoint',
        type: 'string',
        placeholder: 'https://api.myservice.com/v1/query',
        description: '你的服务 API 地址'
      },
      {
        label: '超时时间 (ms)',
        name: 'timeout',
        type: 'number',
        default: 5000,
        optional: true,
        additionalParams: true    // 折叠到"高级参数"中
      }
    ]
  }

  // Step 3: init 方法:根据用户配置返回可用实例
  async init(nodeData: INodeData, _: string, options: ICommonObject): Promise<any> {
    const apiEndpoint = nodeData.inputs?.apiEndpoint as string
    
    // 从加密存储中读取凭据
    const { getCredentialData, getCredentialParam } = await import('../../../src/utils')
    const credentialData = await getCredentialData(nodeData.credential ?? '', options)
    const apiKey = getCredentialParam('myApiKey', credentialData, nodeData)
    
    return new MyCustomToolLogic(apiEndpoint, apiKey)
  }
}

// Step 4: 导出(固定格式)
module.exports = { nodeClass: MyCustomTool_Tools }

11.2 配套凭据定义

// packages/components/credentials/MyServiceApi.credential.ts

import { INodeParams, INodeCredential } from '../src/Interface'

class MyServiceApi implements INodeCredential {
  label: string
  name: string
  version: number
  inputs: INodeParams[]

  constructor() {
    this.label = 'My Service API'
    this.name = 'myServiceApi'
    this.version = 1.0
    this.inputs = [
      {
        label: 'API Key',
        name: 'myApiKey',
        type: 'password'    // 密码类型,UI 中会隐藏
      }
    ]
  }
}

module.exports = { credClass: MyServiceApi }

11.3 节点开发注意事项

开发自定义节点时的关键点:

① baseClasses 要正确设置
  → 决定节点输出口能连哪些目标插槽
  → 通常: [this.type, ...getBaseClasses(YourLangChainClass)]

② init() 要返回 LangChain 兼容对象
  → ToolBaseRetrieverBaseChatModel 等

③ inputs 中的 type 对应 UI 组件
  → string → 文本输入框
  → number → 数字输入框
  → boolean → 开关
  → options → 下拉选择
  → asyncOptions + loadMethod → 动态下拉(从 API 加载选项)
  → json → JSON 编辑器
  → code → 代码编辑器
  → password → 密码输入框

④ additionalParams: true
  → 参数折叠到"Additional Parameters"里,保持 UI 整洁

⑤ optional: true
  → 参数非必填,不填也能运行

12. 学习路线图

根据不同目标,这里给出三条清晰的学习路径:

┌─────────────────────────────────────────────────────────────────┐
                      Flowise 学习路线图                           
                                                                  
  阶段 0: 产品认知(1天)                                           
  ┌────────────────────────────────────────────────────────────┐ 
     跑起来,点开模板市场,用 "Conversational Retrieval QA"   
       上传一个PDF文档,聊两句                                  
      README 和官方文档 docs.flowiseai.com                  
  └────────────────────────────────────────────────────────────┘ 
                                                                 
  阶段 1: 使用层(3-5天)                                           
  ┌────────────────────────────────────────────────────────────┐ 
     从模板市场导入各类 Flow,理解每种模式                      
     亲手搭建 RAG 问答 Flow(PDF  Embedding  VectorDB)     
     搭建多工具 Agent(Calculator + SerpAPI)                  
     学会用 Credentials 管理 OpenAI Key 等凭据                
     通过 API 集成到自己的应用(REST + Streaming)             
  └────────────────────────────────────────────────────────────┘ 
                                                                 
  阶段 2: 进阶开发(1-2周)                                         
  ┌────────────────────────────────────────────────────────────┐ 
     阅读 packages/server/src/index.ts 理解启动流程            
     追踪一次请求: routes  controllers  services            
     理解 Interface.ts 中的核心类型定义                        
     学习 NodesPool + CachePool 的工作机制                    
     开发第一个自定义节点(Tool 类型最简单)                    
  └────────────────────────────────────────────────────────────┘ 
                                                                 
  阶段 3: 深度架构(2-4周)                                         
  ┌────────────────────────────────────────────────────────────┐ 
     读懂 buildChatflow.ts(1164行核心执行引擎)                
     理解 AgentFlow V2 引擎(packages/agentflow)             
     搭建生产级部署(PostgreSQL + Redis Queue 模式)           
     接入 Prometheus 监控                                     
     实现 MCP Server 集成                                    
  └────────────────────────────────────────────────────────────┘ 
                                                                 
  阶段 4: 贡献社区(持续)                                          
  ┌────────────────────────────────────────────────────────────┐ 
     提交 Bug Fix(Issues 列表有 641 个等待)                   
     贡献新节点(新的 LLM、工具、向量库适配)                   
     参与 Discord 社区(活跃度极高)                           
  └────────────────────────────────────────────────────────────┘ 
└─────────────────────────────────────────────────────────────────┘

关键代码文件优先级

学习时按这个顺序阅读代码效率最高:

第一轮(理解脉络):
  packages/server/src/index.ts          ← 整个应用的入口和骨架
  packages/server/src/Interface.ts      ← 所有核心类型定义
  packages/server/src/routes/index.ts   ← 60+路由的全景视图

第二轮(理解核心):
  packages/server/src/NodesPool.ts      ← 节点插件加载机制
  packages/server/src/utils/buildChatflow.ts ← 执行引擎(最重要)
  packages/server/src/CachePool.ts      ← 实例缓存机制

第三轮(理解节点):
  packages/components/src/Interface.ts  ← INode 接口规范
  packages/components/nodes/chatmodels/ChatOpenAI/ ← 典型节点实现
  packages/components/nodes/tools/Calculator/ ← 最简单的节点

第四轮(理解服务):
  packages/server/src/services/predictions/  ← AI 推理入口
  packages/server/src/services/documentstore/ ← RAG 文档系统
  packages/server/src/services/mcp-server/   ← MCP 最新特性
  packages/server/src/queue/QueueManager.ts  ← 分布式队列

总结

Flowise 是一个设计相当工整的工程项目。它的核心价值链可以用一句话概括:

用 JSON 描述的有向图(flowData)+ 动态加载的节点插件(NodesPool)+ 拓扑执行引擎(buildChatflow)= 可视化构建任意 LLM 应用

整个系统的几个设计亮点值得特别学习:

插件化节点系统:每个节点完全解耦,遵循统一的 INode 接口,加载、缓存、执行三个阶段清晰分离,扩展一个新节点完全不影响其他部分。

双模式架构:单机模式(直接执行)和 Queue 模式(BullMQ + Redis)无缝切换,只需一个环境变量,让从开发到生产的迁移几乎零成本。

安全设计到位:凭据 AES 加密存储、API Key 恒时比较、XSS 防护、CSRF 保护、Rate Limiting 分层——这些在开源项目中不常见,值得借鉴。

MCP 协议的前瞻性:2026年4月率先集成 MCP,让任意 Chatflow 可被 Claude Desktop / Cursor 等客户端直接调用,打通了 AI 生态的互通壁垒。

如果你是 AI 应用开发者,Flowise 既是一个生产可用的工具,也是一本活生生的最佳实践教材。源码本身就是最好的文档。


相关资源

  • 官方 GitHub:github.com/FlowiseAI/Flowise
  • 官方文档:docs.flowiseai.com
  • Discord 社区:discord.gg/jn3n7PDGNJ
  • Flowise Cloud:flowiseai.com(托管版,开箱即用)