RAGFlow
infiniflow/ragflow项目目录
项目简介
RAGFlow 是文档知识库与问答平台,支持解析和切分文档、构建检索索引,再结合全文检索、向量检索与重排生成回答,并提供引用片段和原文定位。
如何写进简历
维知 · 工业设备售后知识平台 | 场景化示例
项目描述:面向工业设备售后工程师,根据设备型号、固件版本和报警现象查询维修手册、故障说明及参数表,返回带原文出处的排查建议。
技术栈:Python、Quart、RAGFlow、Elasticsearch、MySQL、Redis
主要工作:
- 扫描资料解析与索引入库:针对扫描维修手册与参数表,接入
DeepDOC的文字识别、版面分析、表格提取和文本合并,通过任务调度完成分块、向量化与索引写入,保留文档归属及可用页码位置。 - 限定范围的混合检索与重排:将设备型号、固件映射为知识库和文档范围,利用全文与向量混合召回,再按词法与模型相关性加权重排;分开控制候选窗口、相似度阈值和返回条数,为报警码与口语化故障筛选证据。
- 证据预算与引用定位:利用
Token预算组装故障证据,解析回答引用编号并关联片段、文档和可用位置元数据,接入PDF原文定位,让售后工程师能够回查排查建议的出处。
面试题与回答
文档解析在 RAG 中有什么作用,解析错误会带来哪些影响?
展开收起
核心回答
RAGFlow的文档解析把上传文件转换成带结构与来源位置的片段,再交给向量化和索引。以通用PDF解析选择DeepDOC为例,它通过文字识别、版面分析、表格结构分析和文本合并等阶段恢复内容,并非一次视觉大模型调用。这些结果直接决定检索质量:如果型号被读错,关键词通道可能漏召回;表格串列会让检索命中的内容本身就错;页码或位置丢失又会影响原文定位。因此,需要同时检查解析内容、切块边界和来源位置,而不是只调向量相似度。
从解析任务到索引
Python后端的文档解析接口调用DocumentService.run()。对于未配置自定义解析流水线的文档,它通过queue_tasks()建立处理任务;后台执行器默认进入TaskManager.run_refactored_task(),由TaskHandler组织执行。配置了pipeline_id的文档则进入数据流任务,不能将两条路径混成同一种解析流程。解析入口、任务路由、后台执行入口。标准入库流程先从对象存储读取文件,经
ChunkService.build_chunks()选择解析模块、生成片段,再由EmbeddingService.embed_chunks()计算向量,最后写入文档索引。解析与切分是向量化的上游,任务进度完成并不等于表格内容已经逐项正确。标准入库链、解析模块选择与调用。DeepDOC 具体处理什么
通用解析模块会根据文件格式及
layout_recognize配置选择解析方式。选用DeepDOC的PDF路径时,Pdf.__call__()先处理页面图像与文字,再调用_layouts_rec()分析版面、_table_transformer_job()识别表格结构、_text_merge()合并文本,并提取表格、图片及位置标签,恢复段落衔接。PDF 多阶段解析。例如产品手册中的一张参数表,真正要保留的是“哪个型号对应哪个数值、单位和条件”,而非页面里出现了哪些字。若型号正确但列错位,混合检索和重排仍可能把这个错误片段排在前面。排查应先对照原表检查行列关系,再看表头与数据是否被切开;只有内容正确后,调整检索权重才有意义。
方案取舍
有干净文本层、版式简单的材料,可以评估更轻的解析方式;扫描件、多栏和复杂表格则需要更强的识别与结构恢复,代价是处理耗时和模型资源。选型时用同一批原文件比较关键字段、阅读顺序、表格关系和后续问答,避免仅以输出文本长度或解析成功率判断效果。
混合检索比单路检索在哪个环节获得收益?
展开收起
核心回答
RAGFlow混合检索的收益,首先看关键词与向量信号是否让正确证据进入候选并排到前面。关键词适合保留型号、错误码等精确词,向量适合覆盖不同措辞的相近含义;配置重排模型后,再对这些候选做更细的相关性判断。召回、融合与模型重排是不同环节,不能把最后答案的改善全部归因于混合检索。例如用户同时给出一个错误码和口语化的故障描述,词项信号有助于区分相近错误码,语义信号有助于找到使用另一种措辞的处理步骤。是否真正受益,要在同一批文档和问题上比较关键词、向量、混合三组结果,再固定生成配置检查答案。
用于设备售后时,可在业务层维护“设备型号、固件适用区间到知识库与文档”的关系,先确定本次允许范围,再传入检索。型号或固件缺失时补问,没有适用手册时直接返回资料缺口,避免把空匹配变成不限文档查询。这属于设备适用范围的接入设计,混合检索只在给定范围内排序。
候选召回与重排怎样衔接
Dealer.search()先构建关键词匹配表达式和查询向量,带上知识库、文档范围等过滤条件,把词项、稠密向量及融合表达式交给底层存储检索。knn_top_k、knn_num_candidates控制向量检索范围;rerank_candidates_count控制送入后续排序的候选窗口;page_size决定最终返回数量。这些参数不是同一个Top-K。混合查询构造、检索参数与候选窗口。模型重排只能重排这个窗口里已有的片段。正确证据没进入候选,换一个重排模型也找不回来;候选变多则会增加重排开销。因此应分别检查证据有没有召回、融合后排在哪里、重排后有没有进入最终上下文。
为什么要说明使用哪个后端
当前实现的评分路径与文档引擎有关,不能统一概括为
RRF:Infinity:在后端归一化各路分数并加权融合,未配置重排模型时直接使用融合分数。Elasticsearch:取得候选后,再发起限定候选标识的向量查询,获取干净的余弦分数,与本地词项相似度按用户权重组合。OceanBase、SereneDB:返回片段向量,沿用依赖向量的本地评分路径。GaussDB:在数据库侧完成融合及PageRank评分,本地再补标签等排序特征。
配置
rerank_mdl时,则进入rerank_by_model():模型对问题和候选文本评分,随后与词项分数、排序特征组合。vector_similarity_weight在这一分支作为模型分数的组合权重使用,不能仍把该项解释成原始向量余弦相似度。后端分支与最终排序、模型重排的分数组合。怎样验证收益来自哪里
先固定文档快照、解析和切分结果、知识库与文档范围、模型版本,准备带正确证据标注的问题集,并区分精确词查询、同义表达和混合查询。
- 看候选覆盖:比较单路和混合的证据
Recall@K,记录正确片段由哪一路补入。若混合组用了更大候选池,再补一组相同候选数量或相近成本的对照。 - 看排序:固定同一个重排模型,比较正确片段的排名、
nDCG@K或前若干条证据命中率;再在同一候选集上开关重排,区分融合收益与模型收益。 - 看最终回答和代价:固定提示词、上下文预算和生成模型,检查答案正确性、引用是否支持结论,以及检索和重排延迟。
这是一套评估方法,不能由源码直接推出准确率提升。混合后的噪声、候选截断和重排成本,都可能抵消召回互补的收益。
参考资料
- 国内:BAAI:BGE-M3 模型说明:参考稠密、稀疏检索的互补性,以及先混合召回、再模型重排的分工;不表示本项目必用该模型。
- 国内:JavaGuide:RAG 优化:参考精确词与语义查询的区别,以及候选池、重排结果和上下文预算应分别控制的解释。
- 国外:Microsoft:Hybrid Search Scoring:参考融合与语义重排是不同阶段;其中的
RRF是该服务的实现,不能直接套用到全部RAGFlow后端。 - 国外:Sentence Transformers:Retrieve & Re-Rank:参考高效召回与高成本精排的两阶段取舍。
RAG 的引用溯源到原文页面高亮应如何实现?
展开收起
核心回答
RAGFlow的这条链路依赖检索片段中的位置元数据,加上回答引用编号到片段列表的映射。Python检索返回chunk_id、doc_id和positions;聊天生成时使用片段编号组织引用,前端点击引用后带着文档和片段信息打开预览抽屉,由PDF预览器绘制高亮并滚动定位。当前引用也可能由生成后的相似度匹配补上,所以它提供的是回看证据的入口,不是自动证明答案正确。另一个需要保留的区别是:
doc_id标识文档记录,不是不可变的文件版本;历史引用要长期准确,还需要把原文版本和解析结果对应起来。片段如何带上原文位置
解析结果有位置时,
add_positions()将其保存为position_int,每项按“页码、左、右、上、下”排列,并把输入页索引加一,转换为这里使用的页码。一个片段可以带多个位置;没有可用位置时,这一步不会凭空产生坐标。位置写入是后续定位的数据起点。检索的
retrieval()在组织命中结果时保留chunk_id、doc_id、正文和positions,其中positions来自position_int。供接口使用的chunks_format()可以进一步把字段归一化为id、document_id、content和positions。前端需要保留这份来源信息,只有片段正文或文档名还不够完成区域高亮。回答中的编号如何指向片段
kb_prompt()按上下文预算选择片段,为它们添加ID和正文;引用提示词要求模型以[ID:i]标注来源。这里的i是本次片段列表的编号,不是原文页码,也不是文档主键。启用引用且存在检索知识时,
decorate_answer()会解析回答中已有的引用标记。如果完全没有识别到引用标记,并且有可用的向量模型,则调用insert_citations():将回答拆成句段,与检索片段做词法和向量相似度匹配,再插入标记。之后整理引用元数据并随答案返回。引用处理和相似度补标分别承担这两部分工作。这种补标能找到与回答相关的材料,但没有逐项证明原文蕴含该句结论。例如两段都提到同一产品,却可能对应不同型号或年份;标上相关片段后,仍要核对这些条件。
点击后怎样在 PDF 中高亮
- 解析引用。
MarkdownContent根据编号从reference.chunks取出片段,并通过文档信息找到文档 ID;点击支持原文定位的文件入口时,将文档 ID 与片段交给useClickDrawer()。 - 打开预览。
PdfSheet取得文档预览地址,并调用useGetChunkHighlights()处理片段位置;对PDF,继续交给PdfPreview。 - 转换位置。
buildChunkHighlights()把每组位置转换为包含pageNumber、boundingRect和rects的高亮数据。PdfPreview使用react-pdf-highlighter绘制区域,并通过滚动回调定位到首个高亮。高亮数据转换与PDF 预览连接了后端位置与页面展示。
当前预览实现读取第一页在
scale=1时的宽高作为高亮尺寸参考。不同页面尺寸、旋转页面等情况需要专门核对,不能由这条代码路径直接推断所有PDF都能精确对齐;片段缺少位置时,高亮构造也会返回空列表。长期溯源还要补齐什么
当前文档可以沿用同一 ID 重新解析,并清理旧片段;文档记录 ID 不承担不可变版本标识的职责。若要求旧回答始终能打开当时的原文,应记录文件版本或内容哈希、解析版本和引用片段快照,并让预览读取对应版本。这属于进一步设计,不能把现有
doc_id直接解释为已经提供了版本锁定。验收应分别检查编号是否映射正确、坐标是否落在对应页、原文是否支持答案,以及预览权限是否有效。可用跨页片段、同名新版文件、扫描件、混合页尺寸和无位置片段做对照;有引用标记、能打开文件和内容正确,需要各自的证据。
- 解析引用。