2026年7月9日 周四晚上19:30,报名腾讯会议了解“如何构建自进化的动态知识库(Brain)”(限30人)
免费POC, 零成本试错
FDE知识库

FDE知识库

学习大模型的前沿技术与行业落地应用


收藏

提升RAG系统的回答质量:高质量企业文档解析(一)

发布日期:2024-09-02 05:28:22 浏览次数: 2967
作者:真聊技术

微信搜一搜,关注“真聊技术”


LLM(大型语言模型)在生成自然语言文本方面展现出强大的能力,但它们的训练数据通常来自于公开的、广泛的数据源,这意味着它们在面对特定企业的私有数据时,可能无法准确地生成相关的答案或信息。一种可行的思路是将这些专业数据用于微调大型语言模型(LLM),但这通常对技术和成本的要求都非常高。相比之下,RAG系统提供了一个更加经济和高效的解决方案。它通过在用户的原始问题后附加相关的私域数据,将其与通用LLM结合进行分析和总结。这样,RAG系统通过检索增强的方式为LLM提供更精准的信息,大大提升了最终的回答效果,如下图所示:

企业私有数据形成知识的重要性

企业的私有数据通常以文档形式存储,包括技术手册、政策文件、客户档案、研究报告等。这些文档承载了企业的核心知识,是企业运营的基础。通过将这些文档转换为可检索的结构化数据,RAG系统能够在需要时快速访问和利用这些数据,从而为LLM提供即时的参考。这一过程可以:

  • 提高回答的专业性:确保回答内容符合企业的专业要求和标准。

  • 增强数据安全性:通过私有数据的封闭检索,避免敏感信息泄露。

  • 支持动态更新:随着文档的更新,RAG系统能够不断刷新其知识库,保证回答内容的时效性。

企业私有数据存储介质的多样性

企业的私有数据通常以多种介质形式存储,这些介质承载了公司内部的关键知识和信息。常见的文档介质包括:

  1. 文本文档(如TXT、Markdown)

  2. 办公文档(如DOC、DOCX、PPT、XLSX)

  3. PDF文件

  4. 数据库(如SQL、NoSQL)

  5. 多媒体文件(如图像、音频、视频)

  6. 专有格式文件(如设计图纸、技术说明书等)

这些文档介质中的数据往往是结构化、半结构化或非结构化的,因此解析和读取这些数据对实现企业知识的自动化检索与生成至关重要。

基于DOC、DOCX文档的解析

DOCDOCX是微软Word的文件格式,广泛用于企业的各类文档编写和存储。解析这些文档类型的过程相对复杂,因为它们不仅包含文本,还可能嵌入各种复杂的元素,如表格、图像、超链接、页眉页脚、注释、修订历史等。这些元素的解析和读取涉及多个层次的技术挑战。

1. 文本内容的解析

  • 段落和标题:DOCX文件内部结构通常是通过XML来表示的,各个段落、标题有明确的标签。解析时需要识别这些标签,以提取不同层级的文本结构信息。

  • 字符样式:字体、大小、颜色等样式信息也可以通过解析XML获取,这对于保留原始文档的格式至关重要。
from docx import Document
def parse_docx_text(file_path):doc = Document(file_path)for para in doc.paragraphs:print(f"段落内容: {para.text}")

2. 表格内容的解析

  • 表格结构:表格在企业文档中非常常见,如财务报表、技术规范表等。解析表格时,需要精确识别每个单元格的数据,并保持其在表格中的位置。

  • 复杂表格:包括合并单元格、嵌套表格等,解析起来更为复杂,需要特殊的处理逻辑。
def parse_docx_tables(file_path):doc = Document(file_path)for table in doc.tables:for row in table.rows:print([cell.text for cell in row.cells])

3. 图像和其他嵌入对象的解析

  • 图像:DOCX文档中可能包含的图像可以通过解析文档内嵌的<w:drawing>标签来提取。

  • 其他对象:包括图表、公式、SmartArt等。由于这些对象可能以二进制格式存储,需要使用特定库或API来解析和处理。
def extract_images_from_docx(docx_path):doc = Document(docx_path)for rel in doc.part.rels.values():if "image" in rel.target_ref:print(f"提取图像: {rel.target_ref}")

4. 元数据的提取

  • 作者、创建日期、修订历史等元数据包含在文档的属性中,对于文档的版本控制和溯源管理非常重要。这些信息可以通过访问DOCX文件的docProps来提取。

5. 处理批量文档

  • 在企业中,批量处理大量DOCX文档是常见的需求。此时需要考虑并行处理技术,以提升解析效率,并可以考虑对解析后的内容进行语义切分,以优化后续的RAG应用。
import osfrom concurrent.futures import ProcessPoolExecutor
def process_docx_files(directory):docx_files = [f for f in os.listdir(directory) if f.endswith('.docx')]with ProcessPoolExecutor() as executor:for _ in executor.map(parse_docx_text, docx_files):pass
解析和处理企业的DOC、DOCX文档是RAG系统的重要步骤,通过精确提取文档中的结构化和非结构化信息,可以更好地实现语义切分和知识库的构建。这些处理步骤不仅确保了企业私有数据的有效利用,还极大提升了RAG系统的生成质量和检索精准度。
下面我们详细解析一段Python代码编写的DocxParser类的Docx解析方法。
解析方法代码:
def __call__(self, filename, binary=None, from_page=0, to_page=100000):self.doc = Document(filename) if not binary else Document(BytesIO(binary))pn = 0lines = []last_image = Nonefor p in self.doc.paragraphs:if pn > to_page:breakif from_page <= pn < to_page:if p.text.strip():if p.style and p.style.name == 'Caption':former_image = Noneif lines and lines[-1][1] and lines[-1][2] != 'Caption':former_image = lines[-1][1].pop()elif last_image:former_image = last_imagelast_image = Nonelines.append((self.__clean(p.text), [former_image], p.style.name))else:current_image = self.get_picture(self.doc, p)image_list = [current_image]if last_image:image_list.insert(0, last_image)last_image = Nonelines.append((self.__clean(p.text), image_list, p.style.name))else:if current_image := self.get_picture(self.doc, p):if lines:lines[-1][1].append(current_image)else:last_image = current_imagefor run in p.runs:if 'lastRenderedPageBreak' in run._element.xml:pn += 1continueif 'w:br' in run._element.xml and 'type="page"' in run._element.xml:pn += 1new_line = [(line[0], reduce(concat_img, line[1]) if line[1] else None) for line in lines]
tbls = []for tb in self.doc.tables:html= "<table>"for r in tb.rows:html += "<tr>"i = 0while i < len(r.cells):span = 1c = r.cells[i]for j in range(i+1, len(r.cells)):if c.text == r.cells[j].text:span += 1i = ji += 1html += 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 new_line, tbls
def __call__(self, filename, binary=None, from_page=0, to_page=100000):self.doc = Document(filename) if not binary else Document(BytesIO(binary))pn = 0lines = []last_image = None
  • 函数入口__call__是一个魔术方法,使得类实例可以像函数一样被调用。它接受文件名、二进制数据、起始页和结束页作为输入参数,并将文档加载到self.doc中。如果提供了二进制数据,则使用BytesIO进行处理。

  • 页数控制from_pageto_page参数允许我们控制从文档的哪个页开始解析,到哪个页结束。这对于处理大型文档时非常有用,可以避免一次性加载整个文档导致内存过载。
for p in self.doc.paragraphs:if pn > to_page:breakif from_page <= pn < to_page:if p.text.strip():if p.style and p.style.name == 'Caption':former_image = Noneif lines and lines[-1][1] and lines[-1][2] != 'Caption':former_image = lines[-1][1].pop()elif last_image:former_image = last_imagelast_image = Nonelines.append((self.__clean(p.text), [former_image], p.style.name))else:current_image = self.get_picture(self.doc, p)image_list = [current_image]if last_image:image_list.insert(0, last_image)last_image = Nonelines.append((self.__clean(p.text), image_list, p.style.name))else:if current_image := self.get_picture(self.doc, p):if lines:lines[-1][1].append(current_image)else:last_image = current_image
  • 段落遍历for p in self.doc.paragraphs遍历文档的所有段落。pn记录当前页码,控制页码范围内的解析。
  • 文本和图片处理

    • 段落文本:如果段落有文本内容且属于指定页码范围,则提取文本并进行清理(self.__clean)。

    • 图片处理:如果段落样式为“Caption”(说明文字),则判断是否与图片相关联,关联的图片会被提取出来并添加到lines列表中。对于普通段落,提取图片后也将其加入lines列表。
for run in p.runs:if 'lastRenderedPageBreak' in run._element.xml:pn += 1continueif 'w:br' in run._element.xml and 'type="page"' in run._element.xml:pn += 1
  • 分页符处理for run in p.runs遍历段落中的每一个运行块(run),检测是否存在分页符或手动分页符,并据此增加页码计数pn

    new_line = [(line[0], reduce(concat_img, line[1]) if line[1] else None) for line in lines]
  • 数据整合:将解析的行数据(文本+图片)进行合并处理。reduce(concat_img, line[1])会将同一行中的多张图片合并。

tbls = []for tb in self.doc.tables:html = "<table>"for r in tb.rows:html += "<tr>"i = 0while i < len(r.cells):span = 1c = r.cells[i]for j in range(i+1, len(r.cells)):if c.text == r.cells[j].text:span += 1i = ji += 1html += 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 new_line, tbls


  • 表格解析:遍历文档中的每一个表格,将表格内容提取并转换为HTML格式。对于单元格内容相同且连续的情况,使用colspan合并单元格。

  • 结果返回:最终函数返回提取的文本和图片组合(new_line),以及转换为HTML格式的表格(tbls)。


这段代码展示了如何精确地提取文档的核心信息,包括段落、图片和表格。通过控制解析的页码范围,可以高效处理大型文档,而对于图文并茂的文档,这段代码尤其有价值。

在RAG系统中,这样的解析步骤可以帮助企业将非结构化文档转化为结构化数据,并通过进一步的语义切分和向量化处理,为后续的检索和生成提供高质量的输入。这段代码不仅展示了文档内容提取的技术实现,还表明了在复杂文档环境下,精确的文本与图像关联处理对RAG系统的重要性。

说明:企业文档解析的内容较多,所以分成多篇来阐述,重点是Pdf的文档的解析,敬请期待


53AI,企业落地大模型首选服务商

产品:场景落地咨询+大模型应用平台+行业解决方案

承诺:免费POC验证,效果达标后再合作。零风险落地应用大模型,已交付160+中大型企业

联系我们

售前咨询
186 6662 7370
预约演示
185 8882 0121

微信扫码

添加专属顾问

回到顶部

加载中...

扫码咨询

扫码登录
登录即表示您同意《53AI网站服务协议》
服务协议

欢迎您使用【53AI 官方网站】(以下简称“本网站”或“我们”)。本《会员服务协议》(以下简称“本协议”)是您(以下简称“会员”或“用户”)与【深圳市博思协创网络科技有限公司】之间关于注册、登录及使用本网站会员服务所订立的法律协议。

在您注册或登录前,请务必审慎阅读、充分理解各条款内容,特别是免除或限制责任的条款、知识产权条款、争议解决条款等。此类条款将以加粗形式提示您注意。 当您通过微信公众号授权、手机验证码验证或其他方式成功登录本网站时,即视为您已完全理解并同意接受本协议的全部内容。

一、 定义

本网站:指由【深圳市博思协创网络科技有限公司】运营的,域名为【53ai.com】的网站及相关移动端页面。

会员服务:指本网站向注册会员提供的知识库文章查阅、内容检索及其他相关增值服务。

知识库内容:指本网站发布的包括但不限于文字、图表、数据、研究报告、行业分析等数字化内容资源。

二、 账号注册与登录

登录方式:本网站支持以下登录方式,您可根据实际情况选择:

微信公众号授权登录:您同意将您的微信OpenID信息授权给本网站,用于创建或关联会员账号。

手机验证码登录:您需提供真实有效的手机号码,并通过短信验证码完成身份验证与登录/注册。

账号安全:您的账号仅限您本人使用,禁止赠与、借用、租用、转让或售卖。因您保管不善导致的账号被盗、密码泄露等损失,由您自行承担。

实名认证:根据相关法律法规要求,我们可能要求您在特定功能下完成实名认证。如您拒绝提供,可能无法使用部分或全部服务。

未成年人保护:若您未满18周岁,请在法定监护人的陪同下阅读本协议,并在征得监护人同意后使用本服务。

三、 服务内容与规范

知识库查阅权限:会员登录后,有权按照其会员等级对应的权限范围,在线浏览、检索本网站知识库中的相关文章及内容。

服务变更:我们有权根据业务发展需要,调整、变更或终止部分服务内容,并将以网站公告、公众号消息等方式提前通知。

禁止行为:您在使用服务时不得实施以下行为:

利用技术手段批量爬取、下载、转存知识库内容;

将知识库内容用于商业目的或未经授权地向第三方传播;

干扰本网站正常运行或侵犯其他用户合法权益;

发布违法违规信息或从事违反公序良俗的活动。

四、 知识产权声明

权利归属:本网站知识库中的排版设计、软件代码等内容的知识产权均归【公司全称】或原权利人所有,受《中华人民共和国著作权法》等法律保护。

有限许可:本网站授予会员一项非独占、不可转让、不可转授权的普通许可,仅限于个人学习、研究之目的在线查阅知识库内容。

侵权追责:未经书面许可,任何单位或个人不得以任何形式复制、转载、摘编、镜像、汇编或以其他方式使用上述内容。一经发现,我们保留追究其法律责任的权利。

五、 个人信息保护

我们重视对您个人信息的保护。关于我们如何收集、使用、存储和保护您的个人信息,请单独阅读 《隐私政策》。

您通过微信公众号授权或手机号验证所提供的信息,我们将严格按照《个人信息保护法》的规定处理,仅用于身份识别、服务提供及安全验证等必要用途。

您可以随时通过网站设置或联系客服行使查阅、更正、删除个人信息及撤回授权同意的权利。

六、 免责声明

内容准确性:知识库内容仅供参考,不构成专业建议。我们不对其完整性、准确性、时效性作任何明示或暗示的保证,您应自行判断并承担使用风险。

不可抗力:因自然灾害、政策法规变化、网络故障、第三方平台接口异常(如微信接口维护、运营商短信通道故障)等不可抗力导致的服务中断或延迟,我们不承担违约责任。

第三方链接:本网站可能包含指向第三方网站的链接,该等网站的内容和服务不受我们控制,请您自行甄别风险。

七、 违约责任

如您违反本协议约定,我们有权视情节采取警告、限制功能、暂停服务、注销账号等措施,并保留要求赔偿损失的权利。

如因您的违约行为导致我们遭受行政处罚、第三方索赔或商誉损失,您应承担全部赔偿责任(包括但不限于罚款、赔偿金、律师费、公证费等)。

八、 法律适用与争议解决

本协议的订立、执行和解释均适用中华人民共和国大陆地区法律。

因本协议产生的或与本协议有关的任何争议,双方应友好协商解决;协商不成的,任何一方均可向【公司所在地】有管辖权的人民法院提起诉讼。

九、 其他

本协议构成双方就本服务达成的完整协议,取代此前任何口头或书面约定。

本协议任一条款被认定为无效或不可执行的,不影响其他条款的效力。

我们对本协议享有最终解释权,并在法律允许的范围内保留随时修改的权利。修改后的协议一经公布即生效,继续使用服务即视为同意修订内容。


已查阅