RAG工程落地:處理文檔中表格數據

RAG(Retrieval-Augmented Generation)工程落地過程中,處理文檔中的表格數據 是一個非常重要但復雜的問題,特別是針對技術文檔、報告、論文等結構化強的資料。比如PDF文檔里的表格數據,如下:

RAG處理表格數據的難點

(1)所攜帶的語義信息是不足的,不利于后面的語義檢索;

(2)標題與數據割裂;

(3)缺少上下文語義;

(4)Embedding 不適配結構化數據;

(5)轉換成純文本后,行列關系消失,難以支持細粒度查詢;

還有其他問題就不一一列舉了。

解決方案

我們該如何切割該PDF文檔呢?又該怎么精準的檢索查詢出表格中的數據呢?

直接對表格做向量存儲索引的檢索通常效果欠佳,可以借助大模型生成表格摘要用于嵌入與檢索。這有利于提高檢索精確度,加強大模型對表格的理解。在檢索階段,通過遞歸檢索出原始的表格用于后面生成。

1、文檔轉成MarkDown

建議在切分文檔之前,將所有非結構化的文檔,比如pdf,word,ppt,txt等都轉成帶有Markdown格式的文檔,這么做的好處很多,以后有空再聊。

(1)PDF轉MarkDown

有很多開源的組件,我常用的是pymupdf4llm 。以下是demo代碼:

import pymupdf4llm
from pathlib import Path# 設置參數
pdf_path = r"D:\Test\muxue\data2\caiwubaogao.pdf"  # 替換為您的 PDF 文件路徑
output_md = r"D:\Test\muxue\data2\caiwubaogao.md"           # 輸出的 Markdown 文件名
image_dir = r"D:\Test\muxue\data2\images"              # 圖片保存目錄
dpi = 300                         # 圖片分辨率
image_format = "png"              # 圖片格式,可選 "png"、"jpg" 等# 創建圖片保存目錄
Path(image_dir).mkdir(parents=True, exist_ok=True)# 轉換 PDF 為 Markdown,并提取圖片
md_text = pymupdf4llm.to_markdown(doc=pdf_path,write_images=True,image_path=image_dir,image_format=image_format,dpi=dpi
)# 保存 Markdown 內容到文件
with open(output_md, "w", encoding="utf-8") as f:f.write(md_text)print(f"Markdown 內容已保存到 {output_md}")
print(f"圖片已保存到目錄 {image_dir}")

(2)Word轉MarkDown

同樣有很多開源組件可用,我使用mammoth 。示例代碼如下:

import mammoth
import osdef docx_to_markdown_with_images(docx_path, output_md_path=None, image_dir="images"):os.makedirs(image_dir, exist_ok=True)def save_image(image):image_name = image.alt_text.replace(" ", "_") if image.alt_text else "image"ext = {"image/png": ".png","image/jpeg": ".jpg","image/gif": ".gif"}.get(image.content_type, ".bin")filename = f"{image_name}{ext}"image_path = os.path.join(image_dir, filename)# 避免重名counter = 1base_name = filename.rsplit(".", 1)[0]while os.path.exists(image_path):filename = f"{base_name}_{counter}{ext}"image_path = os.path.join(image_dir, filename)counter += 1# 讀取圖片數據,保存 —— **改這里!**with image.open() as img_file:with open(image_path, "wb") as out_file:out_file.write(img_file.read())# 返回 Markdown 中圖片的路徑,注意替換成相對路徑或 URL 時修改這里return {"src": image_path.replace("\\", "/")}with open(docx_path, "rb") as docx_file:result = mammoth.convert_to_markdown(docx_file,convert_image=mammoth.images.img_element(save_image))markdown_text = result.valueif output_md_path:with open(output_md_path, "w", encoding="utf-8") as f:f.write(markdown_text)return markdown_text# 示例
markdown = docx_to_markdown_with_images(r"D:\Test\muxue\data2\caiwubaogao.docx",output_md_path=r"D:\muxue\data2\caiwubaogao.md",image_dir=r"D:\Test\muxue\data2\images"
)
print(markdown)

2、采用特殊的文本切割器

(1)MarkdownNodeParser

LlamaIndex對MarkDown文件切分,有幾個切割器,比較常用的切割器是MarkdownNodeParser,示例代碼如下:

from llama_index.core import SimpleDirectoryReader, VectorStoreIndex
from llama_index.core.node_parser import MarkdownNodeParser# 加載 Markdown 文檔
documents = SimpleDirectoryReader(input_dir=r"D:\Test\RAGTest\data\markdown", required_exts=[".md"]).load_data()# 創建 Markdown 節點解析器
node_parser = MarkdownNodeParser.from_defaults(include_metadata=True,            # 包含元數據include_prev_next_rel=True,       # 包含前后節點關系header_path_separator="/"
)# 將文檔解析為節點列表
nodes = node_parser.get_nodes_from_documents(documents)

這個切割器是根據MarkDown的標題級別進行切割的。

(2)MarkdownElementNodeParser

為了處理表格,我們需要使用另一個切割器--MarkdownElementNodeParser。它會將markdown文檔中的文本、標題、表格等元素分別解析為不同類型的節點:普通文本為TextNode,表格為IndexNode(且“完美表格”會被轉為pandas DataFrame,非標準表格則以原始文本存儲)。解析后,節點類型和內容可直接區分,便于后續檢索和處理。

MarkdownElementNodeParser 與普通的數據分割器的區別主要在于它對其中的表格內容借助大模型生成了內容摘要與結構描述,并構造成索引 Node
(IndexNode),然后在查詢時通過索引 Node 找到表格內容 Node,將其一起輸入大模型進行生成。

from llama_index.core.llms.mock import MockLLM
from llama_index.core.node_parser.relational.markdown_element import MarkdownElementNodeParser
from llama_index.core.schema import Document, TextNode, IndexNode# 示例markdown文本,包含文本、標題和表格
md_text = """
# 第一章這是第一章的內容。| 年份 | 收益 |
| ---- | ---- |
| 2020 | 12000 |
| 2021 | 15000 |## 第二節這是第二節的內容。| 產品 | 數量 | 價格 |
| ---- | ---- | ---- |
| A    | 10   | 5    |
| B    | 20   | 8    |
"""# 構建Document對象
doc = Document(text=md_text)# 初始化MarkdownElementNodeParser
parser = MarkdownElementNodeParser(llm=MockLLM())# 解析為節點
nodes = parser.get_nodes_from_documents([doc])# 輸出每個節點的類型和內容
for i, node in enumerate(nodes):print(f"Node (i): 類型: {type(node).__name__}")print(f"內容: {getattr(node, 'text', getattr(node, 'table', ''))}\n")

切割+檢索的示例完整代碼如下:

'''
markdown中表格數據的切割和查詢
'''
from llama_index.core import VectorStoreIndex, Settings, SimpleDirectoryReader
from llama_index.llms.openai_like import OpenAILike
from llama_index.embeddings.openai_like import OpenAILikeEmbedding
from llama_index.core.node_parser.relational.markdown_element import (MarkdownElementNodeParser,
)
from llama_index.core.llms.mock import MockLLM# ================== 初始化模型 ==================
def init_models():"""初始化模型并驗證"""# Embedding模型embed_model = OpenAILikeEmbedding(model_name="BAAI/bge-m3",api_base="https://api.siliconflow.cn/v1",api_key="sk-xxx",embed_batch_size=10,)llm = OpenAILike(model="deepseek-ai/DeepSeek-V3",api_base="https://api.siliconflow.cn/v1",api_key="sk-xxx",context_window=128000,is_chat_model=True,is_function_calling_model=False,)Settings.embed_model = embed_modelSettings.llm = llm# 驗證模型test_embedding = embed_model.get_text_embedding("測試文本")print(f"Embedding維度驗證:{len(test_embedding)}")return embed_model, llminit_models()# load documents, split into chunks
documents = SimpleDirectoryReader(r"D:\Test\muxue\data2", required_exts=[".md"]).load_data()# 2. 強大的分割器node_parser = MarkdownElementNodeParser(llm=MockLLM())
nodes = node_parser.get_nodes_from_documents(documents)index = VectorStoreIndex(nodes)from llama_index.core.query_engine import CitationQueryEnginequery_engine = CitationQueryEngine.from_args(index,similarity_top_k=3,# here we can control how granular citation sources are, the default is 512citation_chunk_size=512,
)res = query_engine.query("股本增減變動幅度多大?請使用中文回答")
print(res.response)              # LLM 輸出回答
print("------來源---------------")
for node in res.source_nodes:print("相關片段:", node.text)print("片段分數:", node.score)print("片段元數據:", node.metadata)print("="*40)

結果如下:

可以看出能夠精準的查詢出表格中的數據。

相關網址

MarkdownElementNodeParser的測試demo代碼:

https://github.com/run-llama/llama_index/blob/main/llama-index-core/tests/node_parser/test_markdown_element.py

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/85558.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/85558.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/85558.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

大模型在肺癌預測及個性化診療方案中的應用研究

目錄 一、引言 1.1 研究背景與意義 1.2 研究目的與創新點 1.3 國內外研究現狀 二、大模型預測肺癌的原理與方法 2.1 大模型概述 2.2 數據收集與預處理 2.3 特征工程 2.4 模型訓練與優化 三、術前預測與方案制定 3.1 病情評估 3.1.1 腫瘤大小、位置及分期預測 3.1.…

如何高效分享WordPress博客文章

在當今信息過載的時代,寫好一篇優秀的 WordPress 博客文章只是起點,如何有效地分享給更多讀者才是成功的關鍵所在。對于新手用戶而言,選擇合適的工具和平臺尤為重要。現在許多服務器提供商支持一鍵安裝WordPress功能,比如 Hosteas…

以孝治家有機農業生態文明考察組赴邯鄲心田農場考察學習

按照2025年中共中央、國務院印發了關于《鄉村全面振興規劃(2024—2027年)》的戰略部署。根據《鄉村全面振興規劃》提出的“堅持人與自然和諧共生。牢固樹立和踐行綠水青山就是金山銀山的理念,落實節約優先、保護優先、自然恢復為主的方針&…

解決el-input無法輸入的問題 vue2+element el-input

問題描述: 在el-dialog中el-form組件來做表單提交 中文輸入模式: 在初次輸入的時候能輸入內容 但是再次輸入無法更改內容 英文輸入模式: 只能輸入一個英文 很多文章都是說 是雙向綁定的問題 但是我仔細看了 變量的雙向綁定確實沒毛病 直到我發現了是因為我el-input中的圖…

16_集成學習

描述 集成學習(Ensemble Learning)是一種通過結合多個模型的預測結果來提高整體性能的技術。集成學習的核心思想是通過多個弱學習器的組合,可以構建一個強學習器。 sklearn中常見的集成學習算法: Bagging:通過自助采…

學習STC51單片機43(芯片為STC89C52RCRC)智能小車9(語音識別小車)

每日一言 不必與他人比較速度,你走的每一步都在書寫自己的傳奇。 案例:語音識別小車 這個是最后一個功能了,其實就是用語音功能讓小車自己切換各種模式,當然了我們需要先學習一下語音模塊 硬件:SU-03T 這個叫做非特定…

Android 中 解析 XML 字符串的幾種方式

在 Android 開發中,解析 XML 文件有多種方式,每種方式都有其特點和適用場景。常見的 XML 解析方式有 DOM 解析、SAX 解析 和 XmlPullParser 解析。 1、DOM 解析 DOM(Document Object Model)解析是一種基于樹結構的解析方式&#…

云端算力革命:川翔云電腦如何重新定義創作自由

在設計與科技深度融合的時代,高性能硬件的桎梏正成為創意釋放的最大障礙。川翔云電腦以云端算力為支點,通過彈性算力、高效存儲、多端接入三大核心優勢,讓頂級 GPU 資源觸手可及。 一、核心優勢:突破物理極限的云端工作站 彈性算…

1.容器技術與docker環境部署

一:docker概述 因為 Docker 輕便、快速的特性,可以使應用達到快速迭代的目的。每次小的變更,馬上就可以看到效果,而不用將若干個小變更積攢到一定程度再變更。每次變更一小部分其實是一種非常安全的方式,在開發環境中…

關于 RSA:RSA 加密算法過程

RSA 是一種非對稱加密算法,用“公鑰”加密,用“私鑰”解密,保證數據傳輸安全。 比喻理解:鎖和鑰匙 想象一下: 公鑰是“上鎖的鎖”,別人可以用它鎖住箱子(加密),但打不開…

SM3算法C語言實現(無第三方庫,帶測試)

一、SM3算法介紹 SM3算法是中國國家密碼管理局(OSCCA)于2010年發布的商用密碼散列函數標準,屬于我國自主設計的密碼算法體系之一 ,標準文檔下載地址為:SM3密碼雜湊算法 。SM3算法輸出長度為256位(32字節&a…

搜索二叉數(c++)

前言 在學習數據結構的時候我們學習過二叉樹,那啥是搜索二叉樹呢?我們知道單純的二叉樹沒有增刪查改的實際意義,因為沒有任何限制條件的二叉樹其實用處很局限。但是堆就不一樣了,他就是一個二叉樹加上了大小堆的限制條件&#xf…

vc MFC在opencv的Mat圖像上顯示中文:Mat轉位MFC的CImage,畫圖寫文字,再轉回Mat

vc MFC在opencv的Mat圖像上顯示中文:Mat轉位MFC的CImage,畫圖寫文字,再轉回Mat // Step 1 創建CImage獲取dc int iImgW matImgSized.cols; int iImgH matImgSized.rows; int iChannel matImgSized.channels(); bool bCon matImgSized.is…

Docker環境部署

目錄 一:Docker 概述 1.什么是 Docker 2:Docker 的優勢 3.Docker 的應用場景 4:Docker 核心概念 二:Docker 安裝 1:本安裝方式使用阿里的軟件倉庫 三:Docker 鏡像操作 1:獲取鏡像 2.查看鏡像信息 3.查看鏡像詳細信息 4.修改鏡像標簽(老名字新名字) 5:刪…

Axios 攔截器實現原理深度剖析:構建優雅的請求處理管道

在構建現代前端應用時,網絡請求處理是關鍵環節。作為最流行的HTTP客戶端庫之一,Axios通過其攔截器機制(Interceptors)提供了強大的請求/響應處理能力。本文將深入Axios源碼,揭示攔截器背后的精妙設計與實現原理。 一、…

寶塔安裝nginx-http-flv-module,音視頻直播,第二篇

1,先安裝環境安裝nginx 先卸載原有nigix nigix 大于等于 1.2.6 cd /www/server # 進入寶塔目錄 yum install git -y git clone https://gitee.com/winshining/nginx-http-flv-module.git 使用源碼安裝nigix 在 自定義模塊 區域點擊「添加」,填寫以下參…

低延遲4G專網:保障關鍵業務的實時通信

在工業互聯網、智慧園區、應急通信等對“實時性”要求極高的場景中,網絡延遲的高低,直接決定了業務運行的可靠性與安全性。IPLOOK依托多年核心網研發經驗,推出的低延遲4G專網解決方案,正是為此類關鍵業務打造的“通信專線”&#…

NLP語言發展路徑分享

自然語言處理初期發展歷程 早期:離散表示 one-hot(只表達“有/無”,語義完全丟失)→ n-gram(局部上下文,但高維稀疏)→ TF-IDF(考慮詞頻與權重,但不能表達詞關聯&#x…

如何將文件從安卓設備傳輸到電腦?

將文件從 Android 手機傳輸到 PC 是例行公事嗎?想讓文件傳輸更輕松嗎?幸運的是,您可以從本文中獲得 7 種方法,其中包含詳細的步驟,幫助您輕松了解如何將文件從 Android 傳輸到 PC,涵蓋了從無線工具到傳統 U…

【經驗分享】淺談京東商品SKU接口的技術實現原理

京東商品 SKU 接口的技術實現原理涉及數據建模、架構設計、接口協議、安全機制及性能優化等多個技術層面。以下從技術角度詳細拆解其實現邏輯: 一、SKU 數據模型與存儲架構 1. SKU 數據模型設計 核心字段定義: 基礎屬性:SKU ID、商品名稱、…