FastGPT 深度解读
“工作流驱动的知识库平台”——中文生态最活跃的 RAG 平台,用可视化编排把 LLM 能力变成企业可用的产品
一句话定位
28K+ star 的开源知识库工作流平台,核心差异化在于可视化工作流引擎 + QA 对拆分策略 + 多租户 SaaS 架构——把”LLM + 向量检索”这个技术组合包装成企业级产品,让非技术用户也能搭建智能问答系统。
调研元信息
| 项目 | 值 |
|---|---|
| 调研日期 | 2026-06-23 |
| 仓库 | labring/FastGPT |
| Stars | ~28K+ |
| 主语言 | TypeScript(后端 + 前端全栈) |
| 框架 | Next.js + MongoDB + PostgreSQL |
| 许可证 | Apache-2.0(代码)/ 附加商业条款(云服务) |
| 犀牛鸟状态 | 候选竞赛项目 |
| 社区活跃度 | 中文 RAG 开源项目 Top 3,Issue 响应速度中等 |
设计哲学
“工作流驱动一切”
FastGPT 的设计哲学可以用一句话概括:RAG 的瓶颈不在检索算法,而在如何让检索结果真正服务于业务流程。
类比:WeKnora 像一个顶级搜索引擎实验室——算法论文满墙,但没有前台。FastGPT 像一个装修好的企业图书馆——有借阅证(权限管理)、有分区(多租户)、有导览手册(工作流模板),检索柜台的效率不是最快的,但整个系统运转流畅,新员工来了能立刻用。
再换一个类比:如果 RAG 是做菜,检索算法是食材采购——WeKnora 研究的是如何买到最新鲜、最优质的食材(三路混合检索 + 复合 Rerank)。FastGPT 研究的是如何把食材变成一道完整的套餐——开胃菜(预处理)、主菜(检索+生成)、甜点(后处理),每道菜有清晰的顺序和搭配规则,客人只需要说”我要套餐 A”就能得到一桌好菜。
这个哲学判断的底层逻辑是:企业为”能跑通的业务流程”付费,不为”3% 的检索精度提升”付费。一个检索精度 85% 但有完整工作流、权限管理、多租户支持的平台,比一个检索精度 92% 但只有裸 API 的引擎更容易被企业采购。
TypeScript 全栈的务实选择
FastGPT 选择了 TypeScript 全栈 Monorepo(Next.js 前端 + Node.js 后端),这和 WeKnora(Go) / RAGFlow(Python)的选择截然不同。
为什么不是 Python?Python 是 ML/NLP 的标准语言,但 FastGPT 的核心不是算法创新,而是产品工程——前端交互、工作流编排、权限系统、API 网关。这些领域 TypeScript 的生态远优于 Python:React 生态最成熟的工作流可视化库都是 JavaScript/TypeScript 写的;Next.js 提供了开箱即用的 SSR + API Routes;前后端共享类型定义消除了接口文档的维护负担。
为什么不是 Go?Go 在高并发后端上有优势,但 FastGPT 的瓶颈在 LLM 调用(外部 HTTP 请求)而非计算密集型任务。Node.js 的异步 I/O 模型同样适合这种场景,而且和前端共享语言栈的工程效率收益更大。
SaaS-Ready 的架构直觉
FastGPT 从第一天就按 SaaS 多租户架构设计。这不是事后补丁,而是核心设计约束。这意味着:
- 数据隔离是默认行为,不是可选配置
- API Key 管理是核心功能,不是管理后台的附加页
- 用量配额是内置机制,不是部署后自己写的中间件
- 云原生部署(Sealos)是一等公民,不是 README 里的一段备注
核心架构详解
全局架构图
┌──────────────────────────────────────────────┐
│ FastGPT 系统全景 │
└──────────────────┬───────────────────────────┘
│
┌──────────────────────────────────┼──────────────────────────────────┐
│ │ │
┌────────▼─────────┐ ┌───────────▼───────────┐ ┌──────────▼──────────┐
│ 工作流引擎 │ │ 知识库系统 │ │ 多租户 & 权限 │
│ Workflow Engine │ │ Knowledge Base │ │ Multi-tenant │
└────────┬─────────┘ └───────────┬───────────┘ └──────────┬──────────┘
│ │ │
┌────────┼──────────┐ ┌──────────┼──────────┐ ┌──────────┼──────────┐
│ │ │ │ │ │ │ │ │
FlowNode Edge 变量 QA对拆分 向量检索 全文检索 用户隔离 API Key 用量配额
编排 连接 传递 管线 (pgvector) (MongoDB) Team 管理 Quota
│ │ │ │ │ │ │ │ │
└────────┼──────────┘ └──────────┼──────────┘ └──────────┼──────────┘
│ │ │
└──────────────────────────────────┼──────────────────────────────────┘
│
┌──────────────────▼───────────────────────────┐
│ 插件市场 │
│ Plugin Marketplace (社区贡献工作流模块) │
└──────────────────────────────────────────────┘
│
┌──────────────────▼───────────────────────────┐
│ Sealos 云原生部署层 │
│ (K8s / Helm / 一键部署 / 自动扩缩容) │
└──────────────────────────────────────────────┘
五大子系统概览
| 子系统 | 核心职责 | 关键设计决策 |
|---|---|---|
| 工作流引擎 | 可视化编排 LLM 调用链 | FlowNode 有向图模型,运行时解释执行 |
| 知识库系统 | 文档摄入→向量化→检索 | QA 对拆分 + 双路召回(向量+全文) |
| 插件市场 | 社区贡献可复用工作流模块 | 工作流子图封装为插件,热插拔 |
| 多租户架构 | 用户隔离、权限、配额 | MongoDB 文档级隔离 + RBAC 权限模型 |
| 部署层 | 云原生一键部署 | Sealos + K8s Helm Chart |
工作流引擎深度解析
工作流引擎是 FastGPT 的灵魂。理解它就理解了 FastGPT 为什么能从众多 RAG 项目中脱颖而出。
为什么需要工作流?
传统 RAG 系统的调用链是硬编码的:用户提问 → 向量检索 → 拼接 prompt → LLM 生成 → 返回答案。这个链路对简单的问答场景够用,但企业场景的需求远不止于此:
- 用户问了一个问题,如果知识库没有相关内容,要不要自动调用外部搜索?
- 检索到的内容质量不高时,要不要用 LLM 重新改写查询再检索一次?
- 某些敏感话题需要审核,要不要在 LLM 生成前插入一个”安全检查”环节?
- 用户的问题可能包含多个意图,要不要先做意图分类再分别检索?
这些问题都指向同一个需求:RAG 的调用链不应该是固定的,而应该是可编排的。工作流引擎就是实现这种编排能力的基础设施。
FlowNode 有向图模型
FastGPT 的工作流用有向无环图(DAG)来表示。图的节点是 FlowNode,边是数据流连接。
┌──────────┐
│ 开始节点 │
│ (用户输入) │
└─────┬────┘
│
┌─────▼────┐
│ LLM 节点 │
│ (意图分类) │
└─────┬────┘
│
┌──────────┼──────────┐
│ │ │
┌──────▼──────┐ ┌─▼────────┐ ┌▼─────────┐
│ 条件分支:检索 │ │条件分支:闲聊│ │条件分支:其他│
└──────┬──────┘ └─┬────────┘ └─┬────────┘
│ │ │
┌──────▼──────┐ ┌─▼────────┐ ┌─▼────────┐
│ 知识库检索 │ │ 直接回复 │ │ 转人工 │
└──────┬──────┘ └──────────┘ └──────────┘
│
┌──────▼──────┐
│ Rerank 节点 │
└──────┬──────┘
│
┌──────▼──────┐
│ LLM 生成 │
└──────┬──────┘
│
┌──────▼──────┐
│ 结束节点 │
│ (返回用户) │
└─────────────┘
FlowNode 类型体系:
| 节点类型 | 作用 | 输入 | 输出 | 示例 |
|---|---|---|---|---|
workflowStart |
流程入口 | 用户消息 | 结构化输入 | 用户问题 + 对话历史 |
workflowEnd |
流程出口 | LLM 输出 | 返回消息 | 最终回答文本 |
llmNode |
LLM 调用 | prompt + 模型参数 | 文本输出 | 意图分类 / 摘要 / 生成 |
datasetNode |
知识库检索 | 查询文本 + 知识库 ID | 检索结果列表 | 向量+全文双路召回 |
ifElseNode |
条件分支 | 条件表达式 | true/false 路由 | 意图判断 / 内容审核 |
variableUpdateNode |
变量更新 | 变量名 + 新值 | 更新后的变量 | 累积上下文 |
httpNode |
HTTP 请求 | URL + 参数 | 响应数据 | 调用外部 API |
codeNode |
自定义代码 | 输入变量 | 输出变量 | 数据格式转换 |
loopNode |
循环执行 | 列表 + 子流程 | 聚合结果 | 批量处理多个文档 |
pluginNode |
插件调用 | 插件输入 | 插件输出 | 调用社区贡献的工作流模块 |
answerNode |
中间回复 | 文本 | 推送给用户 | 流式输出中间结果 |
边连接与变量传递
工作流中节点之间的连接不仅是控制流(执行顺序),还承载了数据流(变量传递)。
变量系统:
FastGPT 的变量系统有三个层级:
1. 全局变量(Global Variables)
└─ 在工作流开始时初始化,所有节点可读写
└─ 如:用户信息、当前时间、系统配置
└─ 生命周期:整个工作流执行期间
2. 环境变量(Environment Variables)
└─ 在应用配置中定义,只读
└─ 如:API Key、模型名称、温度参数
└─ 生命周期:应用级,跨工作流共享
3. 节点输出变量(Node Output Variables)
└─ 每个节点执行后产出的变量
└─ 如:LLM 节点的输出文本、检索节点的结果列表
└─ 生命周期:节点执行完毕后,下游节点可引用
变量引用语法:
下游节点通过 ${nodeId.outputKey} 语法引用上游节点的输出。例如:
${llm_1.text}引用 LLM 节点 1 的文本输出${dataset_1.list}引用检索节点 1 的结果列表${code_1.result}引用代码节点 1 的计算结果
这种设计类似于 Unix 管道——每个节点是一个命令,变量引用就是管道连接。ls | grep foo 中 ls 的输出通过管道传给 grep;FastGPT 中 LLM 节点的输出通过变量引用传给检索节点。
条件分支节点详解
ifElseNode 是工作流灵活性的关键。它支持以下条件类型:
| 条件类型 | 说明 | 示例 |
|---|---|---|
| 文本包含 | 判断字符串是否包含子串 | 输出中包含”检索” |
| 文本相等 | 判断字符串是否完全匹配 | 意图分类结果为”闲聊” |
| 数值比较 | 大于/小于/等于 | 检索结果数量 > 0 |
| 正则匹配 | 正则表达式匹配 | 输出匹配 ERR_\w+ |
| 变量存在 | 判断变量是否有值 | 外部 API 返回了结果 |
条件分支让工作流可以实现复杂的业务逻辑。例如:
用户提问
→ LLM 意图分类
→ 如果是"知识查询" → 知识库检索 → Rerank → LLM 生成
→ 如果是"闲聊" → 直接 LLM 回复(跳过检索)
→ 如果是"操作指令" → HTTP 调用外部系统 → 返回操作结果
循环节点详解
loopNode 是 FastGPT v4.x 引入的高级节点,支持对列表数据做迭代处理。
使用场景:
- 批量检索多个知识库:对每个知识库 ID 执行检索子流程,最后合并结果
- 多轮改写:对同一个查询用不同的改写策略反复优化,直到检索质量达标
- 分段处理长文档:把长文档按段落拆分,对每段独立做摘要
循环终止条件:
- 列表遍历完毕(最常见)
- 条件满足(如检索相似度超过阈值)
- 最大迭代次数(防止死循环)
日常类比:循环节点就像工厂里的流水线——产品一个个通过,每个产品经过相同的处理步骤。区别在于 FastGPT 的循环可以”提前下线”——如果某个产品的质量已经达标,就不必走完所有步骤。
运行时执行模型
工作流引擎的运行时执行模型如下:
1. 编排阶段(用户在前端编辑工作流)
└─ 前端将工作流序列化为 JSON 图结构
└─ 存储到 MongoDB 的 workflow 字段
2. 调度阶段(用户发起对话)
└─ 从 MongoDB 加载工作流 JSON
└─ 构建邻接表,找到起始节点
└─ 初始化全局变量
3. 执行阶段
└─ 从起始节点开始,按拓扑序执行
└─ 每个节点执行时,先解析输入变量(替换 ${} 引用)
└─ 执行节点逻辑(调用 LLM / 检索 / 条件判断等)
└─ 将输出变量写入运行时上下文
└─ 根据边连接找到下一个节点,继续执行
└─ 遇到分支节点时,只走满足条件的分支
└─ 遇到循环节点时,进入子流程迭代
4. 输出阶段
└─ 收集所有 answerNode 和 workflowEnd 的输出
└─ 通过 SSE(Server-Sent Events)流式推送给前端
流式输出的实现细节:
FastGPT 使用 SSE 实现流式输出,这是聊天场景的关键体验优化。用户不需要等到整个工作流执行完毕才看到结果——LLM 节点生成的内容会实时推送,中间节点(如 answerNode)也可以在流程中推送中间结果。
客户端 FastGPT 服务端
│ │
│─── POST /chat ──────────→│
│ │── 开始执行工作流
│ │
│←── SSE: "正在检索知识库..." │── answerNode 推送状态
│ │
│←── SSE: "检索到3条相关内容" │── datasetNode 完成
│ │
│←── SSE: "根据您的提问..." │── llmNode 流式生成
│←── SSE: "..." │
│←── SSE: [DONE] │── workflowEnd 完成
知识库实现
知识库系统是 FastGPT 的第二大核心子系统。它负责文档的摄入、向量化、存储和检索。
文档摄入管线
文档上传
│
├─ 1. 文件解析
│ └─ 支持 PDF / Word / TXT / Markdown / Excel / CSV
│ └─ 使用第三方解析服务(如 txt2vec / 自建解析器)
│
├─ 2. 文本提取
│ └─ 从解析结果中提取纯文本
│ └─ 保留元数据(页码、段落位置、来源信息)
│
├─ 3. 分块策略选择
│ ├─ 自动模式:按文档类型自动选择
│ │ └─ FAQ 文档 → QA 对拆分
│ │ └─ 技术文档 → 按段落分块
│ │ └─ 其他 → 固定大小分块
│ └─ 手动模式:用户指定分块参数
│ └─ 块大小 / 重叠长度 / 分隔符
│
├─ 4. 向量化
│ └─ 调用 Embedding 模型(OpenAI / 本地模型)
│ └─ 生成 768/1536 维向量
│
└─ 5. 存储
├─ 向量 → pgvector / Milvus
├─ 原文 + 元数据 → MongoDB
└─ 全文索引 → MongoDB $text 索引
双路召回机制
FastGPT 的检索管线采用双路召回:向量语义检索 + MongoDB 全文检索。
向量检索:
用户查询 → Embedding 模型 → 查询向量
→ pgvector / Milvus ANN 搜索
→ 返回 top-K 最相似的 chunks
→ 相似度分数 = 余弦相似度
全文检索:
用户查询 → jieba 分词 → 关键词列表
→ MongoDB $text 索引搜索
→ 返回 top-K 匹配的 chunks
→ 相关度分数 = MongoDB textScore
双路合并:
向量结果和全文结果合并
→ rerankWeight 参数控制权重
→ final_score = rerankWeight × vector_score + (1 - rerankWeight) × fulltext_score
→ 按合并分数排序,返回 top-N
rerankWeight 的设计缺陷:
这种线性插值合并看起来简洁,但有一个根本问题:向量分数和全文分数不在同一个量纲上。余弦相似度的范围通常是 [0.5, 0.99],MongoDB textScore 的范围可能是 [0.1, 5.0]。直接加权平均意味着 textScore 的绝对值会主导结果——除非 rerankWeight 设得非常高(>0.9),否则全文分数的贡献几乎被忽略。
WeKnora 用 RRF(只看排名不看分数)优雅地解决了这个量纲问题。FastGPT 没有采用 RRF,这是一个可改进的点。参见 跨项目深度分析 中对 RRF 的讨论。
多查询扩展策略
多查询扩展是 FastGPT 检索管线中最有价值的设计。
工作原理:
用户原始查询:"怎么让电脑跑得更快"
│
▼
LLM 改写为多个子查询:
├─ "CPU 超频方法"
├─ "内存升级指南"
└─ "SSD 优化技巧"
│
▼
对每个子查询分别做双路召回
│
▼
合并所有子查询的检索结果
│
▼
去重 + 按 rerankWeight 加权排序
│
▼
返回 top-N 结果
为什么这对中文场景特别有用?
中文表达的同义性极强。同一个意思可能有完全不同的措辞:
| 原始表达 | 可能的同义表达 |
|---|---|
| 怎么提高性能 | 性能优化方法 / 加速技巧 / 提升运行速度 |
| 数据库连接失败 | DB 连接报错 / 连不上数据库 / 数据库超时 |
| 部署教程 | 安装步骤 / 上线流程 / 如何部署 |
如果只对原始查询做向量检索,同义表达的文档可能被遗漏。多查询扩展用 LLM 把同义表达显式展开,大幅扩大了召回面。
多查询扩展的代价:
- 每次检索需要调用 LLM 做查询改写(增加延迟和成本)
- 多个子查询的检索结果合并后数量可能过多,需要更精细的去重和排序
- LLM 改写可能引入无关子查询,导致检索结果偏移
与其他项目的对比:
| 项目 | 多查询扩展 | 实现方式 |
|---|---|---|
| FastGPT | 支持 | LLM 改写为 N 个子查询 |
| WeKnora | 不支持(多路检索本身就扩大了召回面) | BM25 + 向量 + 图谱 |
| Dify | 支持 | 类似的 LLM 改写策略 |
| RAGFlow | 不支持 | 依赖模板驱动的高质量分块 |
| AnythingLLM | 不支持 | 单路向量检索 |
QA 对拆分策略
QA 对拆分是 FastGPT 最具标志性的特色功能,也是它区别于其他 RAG 平台的核心差异化之一。
传统分块 vs QA 对拆分
传统 RAG 系统的文档处理流程是:文档 → 按固定大小/段落分块 → 向量化。这种方式的痛点是:分块是”被动”的——它不知道用户可能会问什么问题。
日常类比:传统分块就像把一本教科书按页码撕成小册子。用户问”什么是牛顿第二定律”,你需要在所有小册子里搜索这句话。但如果教科书里写的是”加速度与力成正比”而不是直接出现”牛顿第二定律”这几个字,向量检索可能找不到。
QA 对拆分的思路是:先让 LLM 把文档内容改写成”问题-答案”对,再对 Q 和 A 分别向量化。这样用户的问题可以直接匹配到 Q,然后返回对应的 A。
类比:这就像请一个老师把教科书的内容改写成”问答题集”。学生问”牛顿第二定律是什么”,直接翻到对应的问答题:
- Q:牛顿第二定律的表述是什么?
- A:物体的加速度与所受合力成正比,与质量成反比,方向与合力方向相同。公式为 F=ma。
这种方式比在原文中搜索精确得多——因为 Q 已经预判了用户可能的提问方式。
QA 对拆分的技术实现
原始文档段落:
"FastGPT 的工作流引擎支持条件分支、循环和变量传递。
用户可以根据意图分类结果,将对话路由到不同的处理流程。
条件分支支持文本包含、正则匹配、数值比较等条件类型。"
│
▼ LLM 调用(prompt: 将以下内容拆分为 QA 对)
生成的 QA 对:
Q1: FastGPT 工作流引擎支持哪些控制结构?
A1: 支持条件分支、循环和变量传递。
Q2: 条件分支的作用是什么?
A2: 根据意图分类结果,将对话路由到不同的处理流程。
Q3: 条件分支支持哪些条件类型?
A3: 支持文本包含、正则匹配、数值比较等条件类型。
拆分 prompt 的关键设计:
FastGPT 的 QA 拆分 prompt 大致如下(简化版):
你是一个专业的知识库助手。请将以下文本内容拆分为多个问答对。
要求:
1. 每个问答对覆盖文本中的一个关键知识点
2. 问题应该尽量贴近用户可能的提问方式
3. 答案应该完整、准确,直接来自原文
4. 不要遗漏重要信息
5. 避免过于宽泛的问题(如"这段话讲了什么")
输出格式:
Q: [问题]
A: [答案]
待拆分文本:
{content}
存储方式:
每个 QA 对在数据库中存储为一条记录,包含:
{
_id: ObjectId,
datasetId: "知识库 ID",
collectionId: "文档集合 ID",
q: "FastGPT 工作流引擎支持哪些控制结构?", // 问题文本
a: "支持条件分支、循环和变量传递。", // 答案文本
vector_q: [0.123, -0.456, ...], // 问题的向量
vector_a: [0.789, 0.012, ...], // 答案的向量
chunkIndex: 0, // 在原文中的位置
source: "原始文档名", // 来源信息
}
检索时的匹配策略:
用户的查询和 QA 对的匹配有两种模式:
模式一:Q 优先匹配——用户查询和 Q 字段做向量相似度匹配。优势:直接匹配问题,精度高。劣势:如果用户的措辞和预设 Q 差异大,可能匹配不上。
模式二:Q+A 联合匹配——用户查询同时和 Q、A 做向量匹配,取最高分。优势:覆盖面更广。劣势:可能匹配到 A 中出现但 Q 未涵盖的内容。
FastGPT 默认使用模式一,用户可以在知识库设置中切换。
QA 对拆分的优势
| 维度 | 传统分块 | QA 对拆分 |
|---|---|---|
| 检索精度 | 中等(依赖分块质量) | 高(Q 直接对应用户问题) |
| 上下文完整性 | 难保证(分块可能切断语义) | 好(A 是完整回答) |
| 处理成本 | 低(只做分块+向量化) | 高(需要 LLM 调用做拆分) |
| 适合文档类型 | 长文档、结构化文档 | FAQ 类、知识类文档 |
| 可控性 | 低(自动分块结果不可预测) | 高(可手动编辑 QA 对) |
QA 对拆分的代价与局限
代价一:LLM 调用成本。每段文本都需要调用 LLM 生成 QA 对,大规模文档库的摄入成本显著高于传统分块。一篇 10,000 字的文档可能拆分出 50-100 个 QA 对,每个 QA 对需要一次 LLM 调用。
代价二:信息可能被遗漏或扭曲。LLM 在拆分过程中可能遗漏文档中的细节,或者对原文的理解有偏差。这种”二次加工”引入了信息失真的风险。
代价三:不适合叙述性文档。QA 对拆分最适合”知识型”文档(API 文档、FAQ、产品说明),但对叙述性文档(故事、论文、报告)效果差——因为叙述性文档的信息是线性递进的,不是可以独立提取的知识点。
局限四:无法自动维护。原文更新后,QA 对需要重新生成。FastGPT 目前没有自动检测原文变更并重新生成 QA 对的机制(对比 WeKnora 的知识自维护)。
手动 Q&A 优化
FastGPT 还支持手动创建和编辑 QA 对。这是一个重要的产品决策——承认自动拆分不是万能的,允许人工介入修正。
手动 Q&A 的使用场景:
- 自动拆分的 QA 对质量不满意,人工修正
- 某些高频问题需要精确的标准化回答(如客服话术)
- 补充文档中没有但用户经常问的问题
- 为特定的业务场景定制问答内容
手动 Q&A 和自动生成的 Q&A 在检索时一视同仁,用户无感知。
插件市场
插件市场是 FastGPT 工作流生态的扩展机制。
插件的本质
FastGPT 的插件本质上是一个封装好的工作流子图。用户可以把一段常用的工作流片段保存为插件,之后在其他工作流中通过 pluginNode 调用。
日常类比:插件就像厨房里的”预制菜包”——你自己调配了一次秘制酱料(工作流),觉得不错,封装成酱料包(插件),下次做菜直接用酱料包,不需要重新调配。
插件系统的工作方式
1. 创建插件
└─ 在工作流编辑器中选择一段节点组合
└─ 定义插件的输入/输出接口
└─ 保存为插件模板
└─ 存储到 MongoDB 的 plugin 集合
2. 使用插件
└─ 在工作流中添加 pluginNode
└─ 选择要调用的插件
└─ 绑定输入变量到插件的输入接口
└─ 插件的输出接口作为节点的输出变量
3. 分享插件
└─ 插件作者可以发布到插件市场
└─ 其他用户浏览市场、安装插件
└─ 安装后插件出现在工作流编辑器的节点面板中
内置插件类型
| 插件类型 | 功能 | 输入 | 输出 |
|---|---|---|---|
| HTTP 请求 | 调用外部 API | URL + 参数 | 响应数据 |
| 数据库查询 | 查询外部数据库 | SQL / 查询参数 | 查询结果 |
| 文本处理 | 格式转换、正则提取 | 文本 | 处理后的文本 |
| 图片生成 | 调用 DALL-E / SD | 文本描述 | 图片 URL |
| 代码执行 | 运行自定义 JS 代码 | 输入变量 | 输出变量 |
与 Dify 插件市场的对比
| 维度 | FastGPT 插件 | Dify 插件 |
|---|---|---|
| 本质 | 工作流子图 | 独立 Python/Node 模块 |
| 开发门槛 | 低(可视化编辑) | 中(需要写代码) |
| 灵活性 | 受限于工作流节点类型 | 高(任意代码逻辑) |
| 社区规模 | 较小 | 较大(6 万+ star 的社区) |
| 安全性 | 高(沙箱内执行) | 需要审核机制 |
| 贡献方式 | 前端导出 → 市场上传 | PR → 审核 → 合并 |
FastGPT 的插件系统在灵活性上不如 Dify(无法执行任意代码逻辑),但在安全性和低门槛上有优势——可视化编辑意味着非技术用户也能创建插件,而工作流子图的封装方式天然比执行任意代码更安全。
多租户架构
多租户是 FastGPT 作为 SaaS 平台的基础能力。
数据隔离模型
FastGPT 使用 MongoDB 的文档级隔离:
租户 A(Team A)
├─ 知识库 A1
│ ├─ 文档集合 A1-1
│ └─ 文档集合 A1-2
├─ 应用 A1
└─ API Key A1
租户 B(Team B)
├─ 知识库 B1
├─ 应用 B1
└─ API Key B1
每条数据记录都带有 teamId 字段,查询时自动过滤。这意味着:
- 租户 A 的知识库数据对租户 B 完全不可见
- 租户 A 的应用配置对租户 B 完全不可见
- 租户 A 的 API Key 不能访问租户 B 的资源
为什么选择文档级隔离而不是数据库级隔离?
数据库级隔离(每个租户一个数据库)隔离性更强,但运维成本高——1000 个租户就需要管理 1000 个数据库。文档级隔离只需要一个 MongoDB 实例,通过 teamId 字段在应用层实现隔离。对于 FastGPT 的目标用户(中小团队)来说,这种方案在成本和隔离性之间取得了合理的平衡。
权限模型
FastGPT 采用 RBAC(Role-Based Access Control)权限模型:
| 角色 | 权限范围 | 典型用户 |
|---|---|---|
| Owner | 团队所有权限 + 成员管理 + 删除团队 | 团队创建者 |
| Admin | 应用 + 知识库的完全控制 | 团队管理员 |
| Editor | 应用 + 知识库的读写权限 | 内容编辑 |
| Viewer | 应用 + 知识库的只读权限 | 普通成员 |
权限控制的粒度细到知识库级别:
知识库权限矩阵:
读取 写入 删除 管理(修改权限)
Owner ✓ ✓ ✓ ✓
Admin ✓ ✓ ✓ ✓
Editor ✓ ✓ ✗ ✗
Viewer ✓ ✗ ✗ ✗
自定义角色 按需配置
API Key 管理
API Key 是外部系统访问 FastGPT 的凭证:
API Key 类型:
├─ 应用级 Key
│ └─ 绑定到特定应用(工作流)
│ └─ 只能通过该 Key 调用对应应用的对话接口
│ └─ 适合:第三方系统集成
│
└─ 团队级 Key
└─ 绑定到整个团队
└─ 可以访问团队内所有资源
└─ 适合:内部系统批量调用
API Key 还可以设置用量限额(每日最大调用次数 / 每日最大 Token 消耗),防止滥用。
用量配额系统
配额维度:
├─ 每日对话次数上限
├─ 每日 Token 消耗上限
├─ 知识库容量上限(文档数 / 向量数)
├─ 并发对话数上限
└─ 存储空间上限
配额层级:
├─ 免费版:基础限额
├─ 专业版:提升限额
└─ 企业版:自定义限额 + SLA
配额系统为 FastGPT 的商业化提供了基础设施——不同付费等级对应不同的配额上限,超额时可以提示升级或自动限流。
Sealos 云原生部署
FastGPT 选择 Sealos 作为云原生部署方案,这是一等公民级别的支持,不是 README 里的可选方案。
为什么选择 Sealos?
Sealos 是一个基于 Kubernetes 的云操作系统,提供应用商店式的一键部署体验。FastGPT 选择它的理由:
| 维度 | Docker Compose | Sealos |
|---|---|---|
| 部署方式 | 命令行 + 配置文件 | 应用商店一键安装 |
| 运维门槛 | 需要手动管理容器 | 自动扩缩容 + 自愈 |
| 多实例 | 需要手动配置 | 内置负载均衡 |
| 数据库运维 | 自建或外部 | Sealos 内置数据库服务 |
| 适合用户 | 技术团队 | 非技术团队也能部署 |
部署架构
Sealos 集群
├─ FastGPT App Pod(可水平扩展)
│ ├─ Next.js 前端 + API Routes
│ └─ 工作流引擎 + 知识库服务
├─ MongoDB Pod(Sealos 托管)
├─ PostgreSQL + pgvector Pod(Sealos 托管)
├─ Redis Pod(缓存 + 会话)
└─ Sealos Ingress(TLS + 路由)
与竞品的差异化矩阵
| 能力维度 | FastGPT | WeKnora | Dify | RAGFlow | AnythingLLM |
|---|---|---|---|---|---|
| 核心定位 | 工作流知识库平台 | 检索引擎 | LLM 应用平台 | 文档解析+RAG | 个人知识库 |
| 检索路数 | 2 路(向量+全文) | 3 路(BM25+向量+图谱) | 2 路(BM25+向量) | 2 路(BM25+向量) | 1 路(向量) |
| 分块策略 | 固定大小 + QA 对 | 4 级自适应 | 固定大小 | 模板驱动 | 固定大小 |
| QA 对拆分 | 支持(核心特色) | 不支持 | 不支持 | 不支持 | 不支持 |
| 工作流引擎 | 可视化编排(核心) | 无 | 可视化编排(核心) | 无 | 无 |
| 插件市场 | 有(工作流子图) | 有(Plugin 管线) | 有(代码模块) | 无 | 无 |
| 多租户 | 内置(SaaS-ready) | 无 | 内置 | 无 | 无 |
| 权限管理 | RBAC 细粒度 | 无 | RBAC | 无 | 简单认证 |
| 开发语言 | TypeScript | Go | Python | Python | Node.js |
| 向量库支持 | pgvector / Milvus | 10 种 | 3-4 种 | 3-4 种 | 11 种 |
| 文档解析 | 基础(依赖第三方) | IMA 解析器 | 基础 | 强(深度解析) | 基础 |
| Rerank | 单模型 + 线性合并 | 三信号复合 | 单模型 | 单模型 | 无 |
| 知识自维护 | 无 | 自动巡检 | 无 | 无 | 无 |
| 部署方式 | Sealos / Docker | Docker | Docker / K8s | Docker | Docker |
| 中文优化 | jieba + QA 对 | 中文分词 | 基础 | 强 | 基础 |
| 社区规模 | ~28K | ~14K | ~60K+ | ~30K | ~35K |
FastGPT 的差异化定位总结:
- 唯一主打 QA 对拆分——这在特定场景(FAQ 类文档、客服系统)中检索质量显著优于传统分块
- 可视化工作流 + 多租户的组合——Dify 有工作流但没有 FastGPT 的知识库聚焦,RAGFlow 有文档解析但没有工作流
- 中文生态最友好——jieba 分词、QA 对拆分对中文场景的优化、社区以中文用户为主
- SaaS 化程度最高——Sealos 一键部署、RBAC 权限、API Key 管理、用量配额,开箱即用的商业化能力
FastGPT 的劣势:
- 检索深度不足——没有 BM25 专业引擎、没有知识图谱、Rerank 策略简单
- 文档解析弱——依赖第三方解析器,不如 RAGFlow 的深度解析能力
- 向量库选择少——只支持 pgvector 和 Milvus,不如 WeKnora 的 10 种
- 社区规模不如 Dify——插件生态和工作流模板的丰富度有差距
源码关键实体索引
TypeScript 模块索引
| 模块路径 | 核心功能 | 关键类型/函数 |
|---|---|---|
packages/service/core/workflow/ |
工作流引擎 | Workflow, FlowNode, dispatchWorkFlow() |
packages/service/core/workflow/dispatch/ |
节点执行器 | dispatchLLM(), dispatchDatasetSearch(), dispatchIfElse() |
packages/service/core/dataset/ |
知识库管理 | Dataset, Collection, Data |
packages/service/core/dataset/search/ |
双路召回 | searchDatasetData(), embeddingSearch(), fullTextSearch() |
packages/service/core/dataset/training/ |
数据集训练 | generateQA(), generateVector(), createTrainingUsage() |
packages/service/core/ai/ |
LLM 调用抽象 | chatCompletion(), embeddings(), queryExtension() |
packages/service/support/permission/ |
权限管理 | authDataset(), authApp(), managePermission() |
packages/service/support/user/ |
用户管理 | User, Team, MemberGroup |
packages/global/core/workflow/type.d.ts |
工作流类型定义 | FlowNodeTypeEnum, EdgeEnum |
packages/global/core/dataset/type.d.ts |
知识库类型定义 | DatasetDataSchema, SearchDataResponseItemType |
projects/app/src/pages/ |
前端页面 | 应用编辑、知识库管理、对话界面 |
projects/app/src/components/core/workflow/ |
工作流可视化 | ReactFlow 定制组件 |
关键类型定义
// 工作流节点类型枚举(简化版)
enum FlowNodeTypeEnum {
workflowStart = 'workflowStart',
workflowEnd = 'workflowEnd',
llmNode = 'llmNode',
datasetNode = 'datasetNode',
ifElseNode = 'ifElseNode',
variableUpdateNode = 'variableUpdateNode',
httpNode = 'httpNode',
codeNode = 'codeNode',
loopNode = 'loopNode',
pluginNode = 'pluginNode',
answerNode = 'answerNode',
}
// 知识库检索结果类型
interface SearchDataResponseItemType {
id: string;
q: string; // 问题文本
a: string; // 答案文本
datasetId: string;
collectionId: string;
sourceName: string; // 来源文档名
similarity: number; // 相似度分数
score: number; // 综合分数(向量+全文加权)
}
核心执行流程追踪
从用户输入到最终回复的完整调用链:
用户输入 (HTTP POST /api/v1/chat/completions)
→ API 路由层 (projects/app/src/service/api/)
→ 认证中间件 (packages/service/support/permission/)
→ 加载应用配置 (MongoDB apps 集合)
→ 加载工作流定义 (app.workflow 字段)
→ dispatchWorkFlow() (packages/service/core/workflow/)
→ 拓扑排序确定执行顺序
→ 逐节点执行:
├─ dispatchLLM() → 调用 LLM API
├─ dispatchDatasetSearch() → 双路召回
│ ├─ embeddingSearch() → pgvector/Milvus ANN
│ ├─ fullTextSearch() → MongoDB $text
│ └─ 合并结果 + rerankWeight 加权
├─ dispatchIfElse() → 条件判断
├─ dispatchHttp() → 外部 API 调用
└─ dispatchCode() → 沙箱执行 JS
→ 收集输出 → SSE 流式推送
局限性分析
检索深度不足
这是 FastGPT 最大的技术短板。
没有专业 BM25 引擎:MongoDB $text 索引不是专业全文检索引擎。它的限制包括:
| 能力 | MongoDB $text | Elasticsearch / Solr |
|---|---|---|
| BM25 加权 | 不支持(只有 textScore) | 支持(完整 BM25 参数) |
| 模糊匹配 | 不支持 | 支持(Fuzzy Query) |
| 同义词扩展 | 不支持 | 支持(同义词词典) |
| 停用词自定义 | 有限 | 完全自定义 |
| 分词器可插拔 | 不支持 | 支持 |
| 跨字段加权 | 不支持 | 支持(field boost) |
| 高亮显示 | 不支持 | 支持 |
这意味着 FastGPT 的全文检索对以下场景表现不佳:
- 包含错别字的查询(需要模糊匹配)
- 专业术语的同义词查询(如同义词词典)
- 需要精确匹配错误码、版本号的查询(需要 BM25 加权)
Rerank 策略过于简单:单参数 rerankWeight 的线性插值无法区分多个排序信号的差异。当向量分数和全文分数的分布差异很大时,线性插值的结果可能被一方主导。
对比 WeKnora 的三信号复合 Rerank(0.6 Rerank 模型 + 0.3 基础分 + 0.1 来源可信度),FastGPT 的 Rerank 在鲁棒性上差距明显。参见 跨项目深度分析。
向量库后端选择少
FastGPT 只支持 pgvector 和 Milvus 两个向量库后端。对比:
| 项目 | 支持的向量库数量 | 灵活性 |
|---|---|---|
| WeKnora | 10 | 极高 |
| AnythingLLM | 11 | 极高 |
| Dify | 3-4 | 中等 |
| RAGFlow | 3-4 | 中等 |
| FastGPT | 2 | 低 |
对于已有 Qdrant / Weaviate / Chroma 等向量库基础设施的团队,迁移到 pgvector 或 Milvus 的成本不低。
文档解析能力弱
FastGPT 的文档解析依赖第三方服务,没有自建解析器。对比 RAGFlow 的深度解析能力(版面分析、表格识别、公式提取),FastGPT 在以下场景表现差:
- 复杂排版的 PDF(多栏、图文混排)
- 扫描件 PDF(需要 OCR)
- 表格密集的文档(需要表格结构化提取)
- 包含数学公式的文档
没有知识自维护
知识库内容过时后没有自动检测机制(对比 WeKnora 的过期检测 + 矛盾检测 + 缺口检测)。企业用户需要人工定期审查知识库内容,运维成本高。
工作流编排的表达力上限
可视化工作流的表达力受限于节点类型。虽然 codeNode 提供了自定义代码执行的出口,但在工作流编辑器中无法表达以下复杂逻辑:
- 递归处理(如树形结构的遍历)
- 异步并发控制(如同时调用 3 个 API,取最快返回的 2 个)
- 复杂的状态机(如多轮对话的状态转移)
这些场景需要直接编写代码,而 FastGPT 的工作流编排器无法覆盖。
竞赛贡献切入点
FastGPT 的竞赛贡献方向基于”检索深度补强 + 知识库自维护 + 工作流智能化”三条主线。
高影响力方向
方向一:引入 BM25 专业检索引擎替换 MongoDB $text
这是检索质量提升最大的单一改进。用 Elasticsearch 或 Meilisearch 替换 MongoDB $text 索引,获得完整的 BM25 加权、模糊匹配、同义词扩展能力。然后在合并策略上用 RRF 替换线性插值,解决量纲不一致问题。
这个方向的技术路径清晰、效果可量化(用 RAGAS 评估改进前后的检索质量),适合作为竞赛的主贡献。参见 RAG 评估方法论。
方向二:知识库自维护机制
借鉴 WeKnora 的 Wiki 巡检思路,在 FastGPT 中实现知识库内容的自动巡检:
- 过期检测:基于文档元数据和内容时效性分析
- 矛盾检测:基于语义比对发现同一主题的矛盾内容
- 缺口检测:基于用户查询日志分析高频但低检索质量的主题
这个方向的创新点在于结合 FastGPT 的 QA 对结构——可以对 Q 和 A 分别做矛盾检测,精度可能高于传统分块方式。
方向三:QA 对拆分策略增强
当前的 QA 对拆分完全依赖 LLM 的一次性生成,存在信息遗漏和质量不稳定的问题。改进方向:
- 多轮迭代拆分:先生成初步 QA 对,再让 LLM 检查是否有遗漏知识点,补充缺失的 QA 对
- 基于查询日志的 QA 对优化:分析用户实际查询,发现现有 QA 对覆盖不到的问题,自动补充
- QA 对质量评估:自动评估每个 QA 对的检索质量,低分 QA 对标记为需要人工审核
方向四:工作流节点增加 Rerank 专用节点
当前 Rerank 逻辑硬编码在检索节点的合并步骤中。把 Rerank 抽象为独立的工作流节点,让用户可以在工作流中灵活插入 Rerank 环节,支持:
- 多种 Rerank 策略选择(Cross-Encoder / LLM Rerank / 规则 Rerank)
- 自定义 Rerank 权重
- 级联 Rerank(先粗排再精排)
中等影响力方向
方向五:Agentic RAG 工作流模板
预置几种 Agentic RAG 工作流模板,让用户开箱即用高级 RAG 模式:
- Self-RAG:LLM 自我评估检索结果质量,不满意则重新检索
- Multi-Agent RAG:多个 Agent 协作,每个 Agent 负责不同知识领域
- Adaptive RAG:根据查询复杂度自动选择检索策略
参见 Agentic RAG 模式。
方向六:向量库适配器扩展
新增 Qdrant / Weaviate / Chroma 适配器,让 FastGPT 支持更多向量库后端。技术上只需要实现 VectorStore 接口的几个方法(upsert / query / delete),工作量不大但实用性高。
贡献优先级矩阵
| 方向 | 影响力 | 工作量 | 风险 | 推荐优先级 |
|---|---|---|---|---|
| BM25 替换 $text + RRF | 极高 | 中 | 低 | P0 |
| 知识库自维护 | 高 | 高 | 中 | P1 |
| QA 对拆分增强 | 高 | 中 | 低 | P1 |
| Rerank 节点化 | 中 | 低 | 低 | P2 |
| Agentic RAG 模板 | 中 | 中 | 中 | P2 |
| 向量库扩展 | 低 | 低 | 低 | P3 |
交叉引用
| 相关页面 | 关系 |
|---|---|
| RAG 知识库全景 | FastGPT 在 5 项目比较中的定位 |
| 跨项目深度分析 | RRF/Rerank 的跨项目比较 |
| WeKnora 深度解读 | 检索引擎路线的对比参照 |
| Dify 深度解读 | 工作流平台的竞品对比 |
| RAGFlow 深度解读 | 文档解析路线的对比参照 |
| AnythingLLM 深度解读 | 个人知识库路线的对比参照 |
| Agentic RAG 模式 | 6 种 RAG 模式与 FastGPT 工作流的结合 |
| RAG 评估方法论 | RAGAS 评估如何应用于 FastGPT |
| RAG Agent 集成 | Agent 与 FastGPT 工作流的集成模式 |
| 选型决策树 | 什么场景选 FastGPT |
| RAG 挑战总览 | FastGPT 面临的通用 RAG 挑战 |
| Memory vs RAG 边界 | D 线(RAG)与 B 线(Memory)的分工——FastGPT 的多查询扩展本质上是在 RAG 侧弥补 Memory 的缺失 |
| 腾讯记忆生态 | FastGPT 在腾讯 DB-Agent-Memory 生态中的位置——知识库层 vs 记忆层的边界 |
学习建议
如果你是第一次接触 FastGPT 的源码,建议按以下顺序阅读:
-
先部署体验——用 Sealos 或 Docker Compose 一键部署,完整走通”创建知识库 → 上传文档 → 创建应用 → 对话测试”的流程。这是理解 FastGPT 产品逻辑的基础,大约需要 2-3 小时。
-
再读
packages/global/core/workflow/type.d.ts——理解工作流的类型定义,所有节点类型、边类型、变量类型都在这里。这是源码阅读的地图,大约需要 1 小时。 -
然后读
packages/service/core/workflow/dispatch/——逐个理解每种节点的执行逻辑。建议按使用频率排序:llmNode→datasetNode→ifElseNode→codeNode→httpNode,每个大约需要 30 分钟。 -
接着读
packages/service/core/dataset/search/——理解双路召回的实现细节,特别是向量检索和全文检索的合并逻辑。大约需要 1-2 小时。 -
再读
packages/service/core/dataset/training/——理解 QA 对拆分的实现,特别是 LLM 调用的 prompt 设计和结果解析。大约需要 1 小时。 -
最后读
packages/service/support/permission/——理解多租户和权限模型。如果竞赛方向不涉及权限系统,可以跳过。
每个模块大约需要 1-2 小时精读。建议逐段消化。
推荐的竞赛入门路径:
如果目标是竞赛贡献,建议从”方向一:BM25 替换 $text + RRF”开始。这个方向的技术路径最清晰、效果最可量化,而且不涉及 FastGPT 核心架构的修改(只是替换检索后端和合并策略),风险最低。先用 Docker Compose 搭建开发环境,然后:
- 在
packages/service/core/dataset/search/中找到全文检索的调用点 - 引入 Elasticsearch 客户端,实现 BM25 检索替代 MongoDB $text
- 在合并策略中用 RRF 替换线性插值
- 用 RAGAS 评估改进前后的检索质量
- 提 PR 并附上评估报告