RAG 基础与局限
为什么 AI 需要"外挂记忆",以及朴素 RAG 为何还不够好
想象一位过度自信的顾问
你雇了一位顾问,他只读过 2023 年以前的书。你问他今天股价,他自信给出一个答案——但那是编造的。这就是没有外部知识的 LLM 的状态:训练截止日期之后的事情一概不知,但还是会"合理猜测"。
RAG 的诞生就是为了解决这个问题:先搜索,再回答。
幻觉问题
LLM 在不确定时会"合理编造"——看起来正确但完全错误的答案
知识截止日期
训练数据有时间边界,最新事件、内部文档一概不知
私有数据隔离
公司内部文档、合同、代码库不在训练数据里——也不该在
朴素 RAG 的工作流程
基础 RAG 其实很简单:把文档切成小块,存到向量数据库,用户提问时找最相似的块,拼到提示词里。
文档切块
向量化存储
语义检索
注入提示词
LLM 生成
固定大小切块破坏语义完整性;PDF/表格等复杂格式解析失真;检索只看语义相似,忽略关键词精确匹配——这三个问题让朴素 RAG 在企业场景下成功率不足 60%。
RAGFlow 怎么解决这些问题?
RAGFlow 的核心主张是:文档理解质量决定 RAG 质量。它不像大多数 RAG 框架那样把解析当作预处理步骤,而是把它做成核心竞争力。
视觉 AI 识别 PDF 布局,表格、图表、公式分别处理,不再"文字乱炖"
按语义和文档结构分块,保留表格行、代码块的完整性
向量语义检索 + 关键词全文检索,互为补充,融合排序
知识点检测
你的公司每天都有新政策文件发布,你想让 AI 客服立刻知道最新政策。哪种方案最合适?
你用朴素 RAG 处理公司 PDF 财务报告,发现 AI 经常回答错误财务数字。最可能的原因是什么?
RAGFlow 架构全景
认识这个系统的每个"角色"——以及他们如何分工协作
这就是你上传一份 PDF 后发生的事情
想象你经营一家图书馆。你的工作不只是把书放上架——你要先对每本书编目,建索引,写摘要,标注关键词。有人问问题时,你还要判断哪些书最相关,摘录关键段落,再给出综合答案。RAGFlow 就是一个自动化"图书馆员"。
系统的主要组成部分
前端层
API 层
核心引擎层
存储层
一段真实的检索代码
当你在对话框提问时,RAGFlow 实际运行的检索逻辑是这样的:
def retrieval(question, kb_ids, embd_mdl,
rerank_mdl=None, top=1024):
embs, _ = embd_mdl.encode([question])
ans = settings.docStoreConn.search(
"ragflow_*",
query_vector=embs[0],
highlight=True
)
if rerank_mdl:
ans = rerank_mdl.rerank(question, ans)
return ans
定义一个"检索"函数,接收问题、知识库ID和向量化模型
把用户的问题转成数字向量(就像把问题翻译成机器语言)
在 Elasticsearch 里搜索:找哪些文档块和这个问题向量最接近
在所有以"ragflow_"开头的知识库索引里搜
用向量相似度作为主要排序依据
同时高亮显示匹配的关键词(用于展示给用户)
如果配置了重排序模型,对结果进行精细排序
返回最终排序结果
知识点检测
RAGFlow 用 Celery 异步任务队列处理文档解析,而不是在 API 请求里直接处理。这样做最主要的原因是什么?
文档解析流水线
DeepDoc 如何读懂 PDF、Word、Excel——让 AI 看到的和人看到的一样
为什么文档解析这么难?
想象把一张精心排版的报纸扫描成图片,然后让人从图片里"重建"报纸的文字结构。你必须判断:哪些文字是标题?哪些是正文?哪些数字属于表格的哪一行?
对于 PDF,计算机看到的不是"段落和表格",而是一堆"某坐标某字体某大小的字符"。把这些字符还原成有意义的结构,就是 DeepDoc 要解决的核心问题。
RAGFlow 的核心哲学是"文档理解质量决定一切"。如果解析阶段把表格变成乱码、把图表扔掉,后续再好的检索也无法补救。因此 RAGFlow 把大量工程资源投入解析层,而不是检索层。
DeepDoc 的解析步骤
用视觉 AI 模型识别 PDF 页面的布局区域:标题区、正文区、表格区、图片区、页眉页脚
对扫描版 PDF 或图片区域进行OCR,提取文字内容
专门的模型识别表格的行列结构,确保行与列数据正确对应,不会"混行"
根据文档结构(章节、段落、表格单元)而非固定字数进行分块,每个块是一个完整语义单元
记录每个块的来源(文件名、页码、位置),回答时可以精确引用来源
文件格式与对应处理器
不同格式有不同的解析逻辑,RAGFlow 为每种格式准备了专门的处理器:
组件们的"工作对话"
当一份 PDF 进入系统,幕后的组件是这样协作的:
知识点检测
你上传了一份扫描版财务报告(扫描仪扫的图片),RAGFlow 说能识别。哪个功能使这成为可能?
检索与重排序
如何找到真正相关的内容,而不只是"看起来像"的内容
两种"搜索思维"
想象你在找一位老同学。方法一:在同学录里搜名字"张伟"(关键词)。方法二:描述他的特征"那个总戴眼镜、喜欢打篮球的高个子"(语义)。两种方法各有优缺:名字精确但找不到外号;特征灵活但可能找到多个相似的人。
RAGFlow 的混合检索同时用两种方法,然后把结果合并。
向量检索(语义)
把问题和文档都转成向量,找"意思最近"的内容。能处理同义词、换种说法等情况。但对精确术语、数字、缩写不敏感。
全文检索(关键词)
经典的 BM25 算法,精确匹配关键词。对专有名词、产品编号、条款编号等效果极好。但不能理解语义,不知道"车"和"汽车"是同一个东西。
混合融合(RRF)
倒数排名融合算法,把两个排序列表合并为一个综合排名。取两种方法各自的优势,互补短板。
重排序:第二轮精筛
第一轮检索用速度换精度——快速找出前 100 个候选块。但"候选"不等于"最佳"。重排序模型会对这 100 个候选做精细的相关性评分,选出最好的 5-10 个交给 LLM。
就像招聘:HR 先从简历堆里快速筛出 100 份(第一轮检索),再由用人部门仔细面试前 10 名(重排序),最终决定录用谁(发给 LLM)。
class DefaultRerank:
def rerank(self, query, chunks,
batch_size=16):
pairs = [[query, c] for c in chunks]
scores = self.model.compute_score(pairs)
ranked = sorted(
zip(chunks, scores),
key=lambda x: x[1],
reverse=True
)
return [c for c, _ in ranked]
定义重排序类和方法,接收用户问题和候选文档块
batch_size=16 表示每次处理16个,避免显存溢出
把问题和每个文档块组成"问题+答案"对
让重排序模型给每对打一个相关性分数
按分数从高到低排序...
把文档块和分数打包在一起再排序
按分数降序(最相关的排最前)
只返回文档块,丢掉分数(用户不需要看原始分数)
知识点检测
你在查询产品质检数据库:"SK-2023-A7 的不良率是多少?"你期望哪种检索方式找到最精确的答案?
生产部署模式
把 RAGFlow 从演示环境变成可靠的企业级服务
RAGFlow 的 Docker 架构
RAGFlow 使用Docker Compose 启动整套服务。一条命令,七个服务同时运行:
ragflow
核心 API + Web 服务,处理所有业务逻辑
elasticsearch
存储和检索所有向量索引,RAGFlow 的检索引擎
minio
对象存储,保存上传的原始文档文件
mysql
关系数据库,存储用户信息、知识库配置、对话记录
redis
缓存和任务队列,Celery 用它传递异步任务
infinity
可选的自托管向量数据库,替代外部 Elasticsearch
关键配置项解读
# LLM 模型配置
LLM_FACTORY=OpenAI
OPENAI_API_KEY=sk-xxx
LLM_MODEL=gpt-4o
# Embedding 模型
EMBEDDING_MODEL=BAAI/bge-large-zh
# 存储配置
ES_HOST=elasticsearch
MINIO_HOST=minio:9000
注释:LLM 模型配置
使用 OpenAI 作为 LLM 提供商(也可换成 Ollama、DeepSeek 等)
你的 OpenAI API 密钥(保密!不要提交到代码库)
具体使用哪个模型(gpt-4o 最强但贵,gpt-3.5-turbo 便宜)
注释:Embedding(向量化)模型配置
使用 BAAI 的中文优化 Embedding 模型,中文场景效果更好
注释:存储配置
Elasticsearch 服务地址(Docker 网络里的服务名)
MinIO 对象存储地址和端口
生产环境要考虑的三件事
数据持久化
Docker 容器重启后数据默认消失。必须把 Elasticsearch、MySQL、MinIO 的数据目录挂载到主机磁盘。
资源规划
DeepDoc 解析时 CPU 密集,Elasticsearch 需要充足内存(建议 8GB+)。生产环境至少 16GB RAM,有 GPU 更好(加速 OCR 和 Embedding)。
访问控制
RAGFlow 自带RBAC 权限管理。生产环境务必修改默认密码,配置 HTTPS,限制 MinIO 和 Elasticsearch 的外部访问。
告诉 AI 帮你部署 RAGFlow 时,指定"生产环境配置",要求生成包含 Volume 挂载和资源限制的 docker-compose.yml。这样生成的配置文件才是真正可用的,而不是演示版。