RAGFlow

复杂文档解析与知识问答平台
2 份简历参考3 道面试问答
反馈(在 GitHub 新标签页打开)

主要技术:Quart、RAGFlow、DeepDOC、Elasticsearch、MySQL、Redis

项目目录

项目简介

RAGFlow 是一套面向复杂文档的知识库与问答平台。用户导入产品手册、合同或制度文件后,可以查询资料中的内容,查看回答引用的片段,并返回原文核对。后端以 Python 为主,结合文档解析、全文与向量检索、重排和模型生成处理一次问答。

例如,上传一份含扫描页和参数表的 PDF,先查看解析与切分结果,再围绕表格中的型号或参数提问;系统从知识库选取片段回答,并在存在位置元数据时支持原文高亮。知识库管理、解析进度、片段检查和问答预览都能在平台中完成。

项目亮点

  • 复杂文档解析: 选择 DeepDOC 的 PDF 路径时,依次处理文字识别、版面、表格结构和文本合并,保留内容与可用位置,便于检查串列、断段和识别错误。
  • 候选召回与精排分开: 组合全文和向量信号,按知识库与文档范围召回,再按配置进行模型重排;候选窗口、分数阈值与最终返回数量分别控制。
  • 有预算的证据与引用: 按片段内容预算组织模型上下文,为回答关联文档和片段引用;引用也可能由生成后的相似度匹配补标,读者仍可回看原文核对。
  • 异步解析与索引任务: 文件入库交给后台任务执行,标准路径衔接分块、向量化与索引写入;自定义解析流水线走另一条任务路线,进度与处理结果分开记录。

技术架构

文件进入对象存储后,后台任务按解析配置生成片段与向量,并写入所选文档引擎。DeepDOC 负责相应文档解析,Elasticsearch 等引擎承担索引与检索,关系库保存知识库、文档和会话信息。

问答时,后端组织检索范围、候选与重排结果,组装证据交给模型;前端读取回答及引用,连接文档预览。全文与向量信号按所选检索后端的评分策略组合。

代码位置 主要职责
api/db/services/document_service.py、rag/svr/ 建立解析任务,调度标准入库或自定义流水线
rag/app/、deepdoc/ 按文件类型解析、切分文本并保留结构与位置
rag/nlp/search.py、rag/prompts/generator.py 召回、排序及证据上下文组装
api/db/services/dialog_service.py 组织问答生成与引用结果
web/src/components/document-preview/ 展示原文,并利用位置元数据高亮片段

如何写进简历

设备智答 · 工业设备售后知识助手 | 制造业场景示例

项目描述:面向工业设备售后工程师的知识助手,解析维修手册、参数表和故障说明,回答故障排查问题,并支持通过原文页码和区域核对操作依据。

技术栈:Python、Quart、RAGFlow、DeepDOC、Elasticsearch、MySQL、Redis

主要工作:

  • DeepDOC 文档解析与异步入库:基于 DeepDOC 对扫描手册执行 OCR、版面识别和表格提取,经后台任务完成分块、向量化与索引写入;保留参数表、文档身份及位置信息,为故障检索和原文回查提供结构化资料。
  • 故障码与描述的混合检索:按设备型号、版本选定手册,空范围时停止检索;在有效范围内组合全文与向量召回,结合词法得分与模型重排融合排序,分层控制候选和上下文,兼顾故障码精确匹配与症状语义。
  • 证据预算与原文引用定位:以 kb_prompt 按片段组织证据预算,保留标题和引用编号,再把回答引用关联到检索片段与文档;结合 PDF 页码和区域定位展示维修参数与步骤出处,支持工程师回查。

合同随查 · 合同条款检索助手 | 法律服务业场景示例

项目描述:面向合同审阅人员的条款检索助手,解析主合同与补充协议,在选定文件中查询付款、交付及违约约定,返回带出处的解释供人工审阅。

技术栈:Python、Quart、RAGFlow、DeepDOC、Elasticsearch、MySQL、Redis

主要工作:

  • 合同版面解析与条款定位:基于 DeepDOC 串联扫描合同的 OCR、版面分析及表格提取,将正文和金额表分块入库;保留 page_num_int、position_int 与文档身份,使条款解释能够定位到原文页面和区域。
  • 合同范围收敛与条款聚合:按审阅对象选择主合同、补充协议及参考制度,校验文档集合后限定检索,空范围时停止请求;按条款编号补取相关条件,将付款期限、触发条件与例外组织在同一解释上下文。
  • 条款候选召回与模型精排:以全文与向量检索共同处理条款术语和自然语言问法,先取得候选片段,再用 Rerank 模型相关性与词法得分融合排序;区分候选窗口、阈值与引用数量,让长合同中的关键条款优先进入上下文。
  • 长文证据与引用回查:通过 kb_prompt 按片段正文控制证据输入,保留文档标题与引用身份;生成后解析引用编号并关联原始片段,结合 PDF 预览核对条款及金额表,衔接长文检索与可解释答复。

面试题与回答

3 题
  1. 文档解析在 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 多阶段解析。

    例如产品手册中的一张参数表,真正要保留的是“哪个型号对应哪个数值、单位和条件”,而非页面里出现了哪些字。若型号正确但列错位,混合检索和重排仍可能把这个错误片段排在前面。排查应先对照原表检查行列关系,再看表头与数据是否被切开;只有内容正确后,调整检索权重才有意义。

    方案取舍

    有干净文本层、版式简单的材料,可以评估更轻的解析方式;扫描件、多栏和复杂表格则需要更强的识别与结构恢复,代价是处理耗时和模型资源。选型时用同一批原文件比较关键字段、阅读顺序、表格关系和后续问答,避免仅以输出文本长度或解析成功率判断效果。

  2. 混合检索比单路检索在哪个环节获得收益?

    展开收起

    核心回答

    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 在这一分支作为模型分数的组合权重使用,不能仍把该项解释成原始向量余弦相似度。后端分支与最终排序、模型重排的分数组合。

    怎样验证收益来自哪里

    先固定文档快照、解析和切分结果、知识库与文档范围、模型版本,准备带正确证据标注的问题集,并区分精确词查询、同义表达和混合查询。

    1. 看候选覆盖:比较单路和混合的证据 Recall@K,记录正确片段由哪一路补入。若混合组用了更大候选池,再补一组相同候选数量或相近成本的对照。
    2. 看排序:固定同一个重排模型,比较正确片段的排名、nDCG@K 或前若干条证据命中率;再在同一候选集上开关重排,区分融合收益与模型收益。
    3. 看最终回答和代价:固定提示词、上下文预算和生成模型,检查答案正确性、引用是否支持结论,以及检索和重排延迟。

    这是一套评估方法,不能由源码直接推出准确率提升。混合后的噪声、候选截断和重排成本,都可能抵消召回互补的收益。

    参考资料

  3. 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 中高亮

    1. 解析引用。 MarkdownContent 根据编号从 reference.chunks 取出片段,并通过文档信息找到文档 ID;点击支持原文定位的文件入口时,将文档 ID 与片段交给 useClickDrawer()。
    2. 打开预览。 PdfSheet 取得文档预览地址,并调用 useGetChunkHighlights() 处理片段位置;对 PDF,继续交给 PdfPreview。
    3. 转换位置。 buildChunkHighlights() 把每组位置转换为包含 pageNumber、boundingRect 和 rects 的高亮数据。PdfPreview 使用 react-pdf-highlighter 绘制区域,并通过滚动回调定位到首个高亮。高亮数据转换与PDF 预览连接了后端位置与页面展示。

    当前预览实现读取第一页在 scale=1 时的宽高作为高亮尺寸参考。不同页面尺寸、旋转页面等情况需要专门核对,不能由这条代码路径直接推断所有 PDF 都能精确对齐;片段缺少位置时,高亮构造也会返回空列表。

    长期溯源还要补齐什么

    当前文档可以沿用同一 ID 重新解析,并清理旧片段;文档记录 ID 不承担不可变版本标识的职责。若要求旧回答始终能打开当时的原文,应记录文件版本或内容哈希、解析版本和引用片段快照,并让预览读取对应版本。这属于进一步设计,不能把现有 doc_id 直接解释为已经提供了版本锁定。

    验收应分别检查编号是否映射正确、坐标是否落在对应页、原文是否支持答案,以及预览权限是否有效。可用跨页片段、同名新版文件、扫描件、混合页尺寸和无位置片段做对照;有引用标记、能打开文件和内容正确,需要各自的证据。