背景介绍
最近被不同的人安利了 FastGPT 项目,实际上手体验了一下,使用流程类似之前调研过的 Dify, 包含的功能主要是:任务流的编排,知识库管理,另外还有一些外部工具的调用能力。使用页面如下所示:
实际去看了下项目的代码分布,结果发现如下所示:
难道后端 Python 只需要如此少的代码量就可以实现一个大模型应用了?深入了解了 FastGPT 的实现,发现其 Python 为测试代码,完整的项目实现都是基于前端语言 ts 和 js 实现。这篇文章就主要介绍下 FastGPT 知识库 RAG 设计的实现细节。
FastGPT 简介
FastGPT 被设计为基于 LLM 大语言模型的知识库问答系统,与常规的 RAG 相比增加了额外工作流编排的能力,这部分类似 Dify。但是相对 Dify 而言可调用的第三方应用更少一些。按照习惯先查看项目的架构图:
一般而言,从架构图中就可以看到项目的独特之处。之前 qanything 和 ragflow 同样从架构图看出 RAG 项目的设计差异。
对于常规的 RAG 架构图,这张图可以明显看到大模型模块被放大,而且文件入库的流程都会先调用大模型。从大模型的输出来看,存在 QA 拆分
, 文本分段
和 手动输入
三种情况:
文本分段
是常规的 RAG 的处理方案QA 拆分
看起来是基于原始文本生成问答对,这部分猜测应该是根据大模型生成问答对,之前 Dify 也有类似的功能,被称为Q&A 模式
手动输入
则是直接输入问答对,这部分应该是手工输入数据进行补充;
预计文件入库环节的大模型调用主要作用于 QA 拆分
。
技术选型
官方给出的技术栈为:NextJs + TS + ChakraUI + Mongo + Postgres (Vector 插件)
- NextJs 用于构建前后端服务,可以在单个工程中同时构建前后端代码,熟悉 Flask 应该对这个玩法不陌生,只是 Flask 是后端想把前端的活干了,而 NextJs 则是前端把后端的活干了;
- TS 用于编写具体的代码;
- ChakraUI 是 UI 组件库;
- MongoDB 是作为业务数据库使用,事实上 FastGPT 中的文件也是基于 MongoDB 的 GridFS 进行存储;
- Postgres 用于存储向量数据;
核心模块解读
与常规的 Python 实现大模型应用不同,基于 TypeScript 没有类似 langchain 的框架,因此需要自行实现知识库构建的完整流程。
文件入库流程
实际文件的入库对应的接口为 api/core/dataset/collection/create/fileId
, 因为是基于 NextJs 实现的,接口与文件的组织结构是一样的,对应的处理实现是在 projects/app/src/pages/api/core/dataset/collection/create/fileId.ts
中
文件入库会执行文件读取,切片,然后会依次写入知识库,实际会根据不同写入模式内容上有一些差异,具体的实现如下所示:
// 1. 读取文件
const {
rawText, filename } = await readFileContentFromMongo({
teamId,
bucketName: BucketNameEnum.dataset,
fileId
});
// 2. 切片,文本分段会保留 20% 的重叠,QA 拆分则没有重叠
const chunks = rawText2Chunks({
rawText,
chunkLen: chunkSize,
overlapRatio: trainingType === TrainingModeEnum.chunk ? 0.2