赞
踩
RAGFlow github地址
https://github.com/infiniflow/ragflow`
RAGFlow 是一款基于深度文档理解构建的开源 RAG(Retrieval-Augmented Generation)引擎。RAGFlow 可以为各种规模的企业及个人提供一套精简的 RAG 工作流程,结合大语言模型(LLM)针对用户各类不同的复杂格式数据提供可靠的问答以及有理有据的引用。
“Quality in, quality out”,RAGFlow 基于深度文档理解,能够从各类复杂格式的非结构化数据中提取真知灼见。真正在无限上下文(token)的场景下快速完成大海捞针测试。对于用户上传的文档,它需要自动识别文档的布局,包括标题、段落、换行等,还包含难度很大的图片和表格。对于表格来说,不仅仅要识别出文档中存在表格,还会针对表格的布局做进一步识别,包括内部每一个单元格,多行文字是否需要合并成一个单元格等。并且表格的内容还会结合表头信息处理,确保以合适的形式送到数据库,从而完成 RAG 针对这些细节数字的“大海捞针”。
RAGFlow 提供多种文本模板,用户可以根据需求选择合适的模板,确保结果的可控性和可解释性。因此 RAGFlow 在处理文档时,给了不少的选择:Q&A,Resume,Paper,Manual,Table,Book,Law,通用… 。当然,这些分类还在不断继续扩展中,处理过程还有待完善。后续还会抽象出更多共通的东西,使各种定制化的处理更加容易。
RAGFlow 是一个完整的 RAG 系统,而目前开源的 RAG,大都忽视了 RAG 本身的最大优势之一:可以让 LLM 以可控的方式回答问题,或者换种说法:有理有据、消除幻觉。我们都知道,随着模型能力的不同,LLM 多少都会有概率会出现幻觉,在这种情况下, 一款 RAG 产品应该随时随地给用户以参考,让用户随时查看 LLM 是基于哪些原文来生成答案的,这需要同时生成原文的引用链接,并允许用户的鼠标 hover 上去即可调出原文的内容,甚至包含图表。如果还不能确定,再点一下便能定位到原文。RAGFlow 的文本切片过程可视化,支持手动调整,答案提供关键引用的快照并支持追根溯源,从而降低幻觉的风险。
RAGFlow 支持 支持丰富的文件类型,包括 Word 文档、PPT、excel 表格、txt 文件、图片、PDF、影印件、复印件、结构化数据, 网页等。对于无序文本数据,RAGFlow 可以自动提取其中的关键信息并转化为结构化表示;而对于结构化数据,它则能灵活切入,挖掘内在的语义联系。最终将这两种不同来源的数据统一进行索引和检索,为用户提供一站式的数据处理和问答体验。
RAGFlow 支持全面优化的 RAG 工作流可以支持从个人应用乃至超大型企业的各类生态系统;大语言模型 LLM 以及向量模型均支持配置,用户可以根据实际需求自主选择。;基于多路召回、融合重排序,能够权衡上下文语义和关键词匹配两个维度,实现高效的相关性计算;提供易用的 API,可以轻松集成到各类企业系统,无论是对个人用户还是企业开发者,都极大方便了二次开发和系统集成工作。
DeepDoc 是 RAGFlow 的核心组件,它利用视觉信息和解析技术,对文档进行深度理解,提取文本、表格和图像等信息。DeepDoc 的功能模块包括:
RAGFlow提供了四种文档解析器,分别是docx_parser
,excel_parser
,pdf_parser
和ppt_parser
。
这是 RAGFlow 系统的“大脑”,负责将各种格式的文档进行解析,从中提取出文本、图像和表格等关键内容。无论是PDF、Word文档还是Excel表格,文档解析器都能够准确捕捉信息,为后续的处理打下基础。
RAGFlow文档解析时根据不同场景提供了11中文档解析方式,分别是book
,laws
,manual
,naive
,one
,paper
,picture
,presentation
,qa
,resume
和table
。针对不同的场景,RAGFlow分别做了有针对性的文档解析。
我们以通用场景(naive)为示例,来做文档解析说明。
# 使用的类库
python-docx==1.1.0
# 主要代码 def __call__(self, filename, binary=None, from_page=0, to_page=100000): self.doc = Document( filename) if not binary else Document(BytesIO(binary)) pn = 0 lines = [] for p in self.doc.paragraphs: if pn > to_page: break if from_page <= pn < to_page and p.text.strip(): lines.append(self.__clean(p.text)) for run in p.runs: if 'lastRenderedPageBreak' in run._element.xml: pn += 1 continue if 'w:br' in run._element.xml and 'type="page"' in run._element.xml: pn += 1 tbls = [] for tb in self.doc.tables: html= "<table>" for r in tb.rows: html += "<tr>" i = 0 while i < len(r.cells): span = 1 c = r.cells[i] for j in range(i+1, len(r.cells)): if c.text == r.cells[j].text: span += 1 i = j i += 1 html += f"<td>{c.text}</td>" if span == 1 else f"<td colspan='{span}'>{c.text}</td>" html += "</tr>" html += "</table>" tbls.append(((None, html), "")) return [(l, "") for l in lines if l], tbls
在解析docx
格式文档时,RAGFlow采用了python-docx
类库,从代码中可以看到,解析的时候首先先解析了docx
文档的段落部分,然后再解析了表格部分。最后将段落部分和表格部分简单的组合在了一起。
每种解析方式中,解析docx文档段落的方式是一致,主要区别在于解析文档表格的处理方式。
naive
在解析docx
时,不仅按照段落的方式提取了文本,而且还把表格内容以HTML的格式解析了出来。one
laws
等其他场景在解析文档时,只按照段落的方式提取了文本,表格的内容没有处理。
RAGFlow的naive
在解析docx
格式文档时,可以将文档的文字内容准确的识别出来,但是在解析表格时,有时候会发生错行等错误。而且最后解析表格时,表格的位置会发生偏差,不能原原本本的还原文档中表格的位置。
# 使用的类库
tika==2.6.0
# 识别代码
elif re.search(r"\.doc$", filename, re.IGNORECASE):
callback(0.1, "Start to parse.")
binary = BytesIO(binary)
doc_parsed = parser.from_buffer(binary)
sections = doc_parsed['content'].split('\n')
sections = [(l, "") for l in sections if l]
callback(0.8, "Finish parsing.")
RAGFlow不同场景在解析doc
格式文档时,都采用了tika
类库来读取文档内容。
# 使用的类库
PyPDF2==3.0.1
pdfplumber==0.10.4
RAGFlow在解析pdf文件时,提供了两种不同的方式的解析,分别是识别布局的解析和不识别布局的解析。默认采用的是识别布局的方式来解析pdf文档的。
不识别布局的解析时,采用了PyPDF2
来解析文档。它仅解析了标题,文本内容和大纲,对于图片表格等内容没有做解析。
识别布局解析时,RAGFlow采用了pdfplumber
和PyPDF2
两个类库来解析文档。其中pdfplumber
负责将pdf
文件转成图片,并读取文本和总页数。 PyPDF2
负责读取pdf
文档的大纲。同时RAGFlow还采用了ocr技术,ocr使用的模型是 /InfiniFlow/deepdoc,在解析中额外加载了一个 XGB 模型 InfiniFlow/text_concat_xgb_v1.0 用于内容提取。ocr的作用是识别图片信息,识别表格和识别布局定位等。
在RAGFlow中,还存在文件的预处理策略,包括但不限于数据的清理操作,比如在
deepdoc/vision/layout_recognizer.py
中的就包含着文档中无用内容的判断,示例如下:
def __is_garbage(b):
patt = [r"^•+$", r"(版权归©|免责条款|地址[::])", r"\.{3,}", "^[0-9]{1,2} / ?[0-9]{1,2}$",
r"^[0-9]{1,2} of [0-9]{1,2}$", "^http://[^ ]{12,}",
"(资料|数据)来源[::]", "[0-9a-z._-]+@[a-z0-9-]+\\.[a-z]{2,3}",
"\\(cid *: *[0-9]+ *\\)"
]
return any([re.search(p, b["text"]) for p in patt])
文档中版权内容,参考来源信息等内容会被清理。但是这样处理比较分散,而且不同的流程中也充斥着大量的特殊处理,导致从源码很难拆分出明确的预处理逻辑。
9]+ *\)"
]
return any([re.search(p, b[“text”]) for p in patt])
文档中版权内容,参考来源信息等内容会被清理。但是这样处理比较分散,而且不同的流程中也充斥着大量的特殊处理,导致从源码很难拆分出明确的预处理逻辑。
总体来说,RAGFlow在解析pdf文件时,是先解析文本内容,然后再解析表格内容,最后再将二者合并。RAGFlow相对于其他框架来说,在解析效果上相对其他 RAG 项目也会好一些。从实际前端的展示的 Demo 来看,RAGFlow 可以将解析后的文本块与原始文档中的原始位置关联起来,这个效果还是比较惊艳的,目前看起来只有 RagFlow 实现了类似的效果。但是也存在一定的问题,比如表格内容识别不全,表格格式有时候会错乱。在识别科学性论文时,识别效果比较差等。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。