RAG維保案例分享:如何實(shí)現(xiàn)"文+圖"的答案呈現(xiàn)
RAG一直被看成是大模型在企業(yè)應(yīng)用落地的標(biāo)準(zhǔn)配置,基于企業(yè)內(nèi)部文檔的問(wèn)答,已經(jīng)解鎖出大量使用需求和場(chǎng)景。在這些眾多類型的文檔中,有相當(dāng)一部分包含了各類復(fù)雜圖表,也就是所謂的多模態(tài)數(shù)據(jù)。
本篇以近期實(shí)施項(xiàng)目中的一個(gè)挖掘機(jī)維修場(chǎng)景為例,試圖給出一個(gè)針對(duì)標(biāo)準(zhǔn)化排版PDF 文檔(本文演示的固定格式維修手冊(cè)),使用基于坐標(biāo)區(qū)域截取方法,結(jié)合Markdown 語(yǔ)法在回答中顯示圖片的示例,供大家參考。
以下,enjoy:
1、業(yè)務(wù)背景
說(shuō)起挖掘機(jī)不禁讓人想到了藍(lán)翔,搜了下說(shuō)是截止到 23 年年底,全國(guó)范圍的液壓挖掘機(jī)保有量在 200 萬(wàn)臺(tái)左右。對(duì)于一名具體機(jī)主而言,在實(shí)際干活的過(guò)程中,可能碰到的來(lái)自發(fā)動(dòng)機(jī)、電器、液壓、工作裝置等大大小小幾百個(gè)故障,這也讓專業(yè)的挖機(jī)維修需求一直很旺盛。
但對(duì)于維修人員而言,顯然有幾個(gè)一直以來(lái)的痛點(diǎn)沒有被很好解決,比如設(shè)備故障類型繁多,單靠個(gè)人經(jīng)驗(yàn)難以覆蓋所有問(wèn)題。再有就是傳統(tǒng)老帶新的模式下,培訓(xùn)帶教周期過(guò)長(zhǎng)等。
注:維修案例示例內(nèi)容
后文會(huì)介紹一個(gè)基于包含 500 多個(gè)維修案例合集,開發(fā)的挖掘機(jī)故障診斷知識(shí)庫(kù)系統(tǒng),維修人員只需描述故障現(xiàn)象即可獲取相關(guān)案例,并支持圖文結(jié)合的答案呈現(xiàn),直觀展示故障部位和維修方法。
2、系統(tǒng)架構(gòu)
注:本項(xiàng)目擴(kuò)展自阿里云官方的 local_rag 示例,添加了本地 PDF 圖片提取和顯示功能,
?? 支持多種文檔類型(PDF、DOCX、TXT、XLSX、CSV)的上傳和處理
??? 智能 PDF 圖片提取與顯示
?? 本地知識(shí)庫(kù)構(gòu)建與管理
?? 集成阿里云通義千問(wèn)系列大語(yǔ)言模型
?? 支持非結(jié)構(gòu)化數(shù)據(jù)和結(jié)構(gòu)化數(shù)據(jù)處理
?? 可自定義 RAG 參數(shù)(召回?cái)?shù)量、相似度閾值等)
3、核心技術(shù)實(shí)現(xiàn)
3.1文檔處理與圖片提取
系統(tǒng)提供了多種 PDF 圖片提取和處理方法,以適應(yīng)不同場(chǎng)景需求:
1. 基于坐標(biāo)的區(qū)域截?。ㄍ扑]方法)
針對(duì)標(biāo)準(zhǔn)化排版的文檔(如固定格式的維修手冊(cè)),使用基于坐標(biāo)的精確截?。?/span>
def extract_images_from_maintenance_pdf(pdf_path, label_name):
image_mapping = {}
doc = fitz.open(pdf_path)
# 根據(jù)文檔格式定義的圖片區(qū)域坐標(biāo)
image_rect = fitz.Rect(400, 160, 750, 320) # 右側(cè)中間區(qū)域
for page_index, page in enumerate(doc):
# 直接從固定區(qū)域截取圖片
pix = page.get_pixmap(matrix=fitz.Matrix(2, 2), clip=image_rect)
if is_valid_image(pix):
# 保存和映射圖片...
優(yōu)勢(shì):
對(duì)固定格式文檔效果極佳
不受 PDF 內(nèi)部圖像對(duì)象表示形式限制
可以捕獲矢量圖形和復(fù)合元素
提高圖片提取的準(zhǔn)確率和質(zhì)量
2. 基于對(duì)象標(biāo)記的提?。▊溥x方法)
使用 PyMuPDF 的內(nèi)置功能識(shí)別 PDF 中的圖像對(duì)象:
def extract_images_from_pdf(pdf_path, label_name):
doc = fitz.open(pdf_path)
for page in doc:
image_list = page.get_images(full=True)
for img in image_list:
# 提取和處理圖片...
局限性:
僅能提取 PDF 中顯式存儲(chǔ)的圖像對(duì)象
無(wú)法提取矢量圖形或作為背景的圖片
可能會(huì)提取裝飾性元素或無(wú)關(guān)圖形
3. 其他優(yōu)化方案
基于內(nèi)容分析的智能提取:結(jié)合文本標(biāo)記定位圖片
多模態(tài) LLM 輔助:使用視覺模型輔助識(shí)別復(fù)雜文檔中的圖片
3.2圖片處理流程
3.3RAG 技術(shù)實(shí)現(xiàn)
分塊策略
系統(tǒng)針對(duì)不同類型的數(shù)據(jù)采用不同的分塊策略:
非結(jié)構(gòu)化文檔:
documents = SimpleDirectoryReader(input_files=enhanced_files).load_data()
index = VectorStoreIndex.from_documents(documents)
結(jié)構(gòu)化數(shù)據(jù):
nodes = []
for doc in documents:
doc_content = doc.get_content().split('\n')
for chunk in doc_content:
node = TextNode(text=chunk)
node.metadata = {'source': doc.get_doc_id()}
nodes = nodes + [node]
嵌入模型
默認(rèn)使用通義千問(wèn)文檔嵌入模型:
EMBED_MODEL = DashScopeEmbedding(
model_name=DashScopeTextEmbeddingModels.TEXT_EMBEDDING_V2,
text_type=DashScopeTextEmbeddingType.TEXT_TYPE_DOCUMENT,
)
# 若使用本地嵌入模型,請(qǐng)取消以下注釋:
# from langchain_community.embeddings import ModelScopeEmbeddings
# from llama_index.embeddings.langchain import LangchainEmbedding
# embeddings = ModelScopeEmbeddings(model_id="modelscope/iic/nlp_gte_sentence-embedding_chinese-large")
# EMBED_MODEL = LangchainEmbedding(embeddings)
檢索策略
采用兩階段檢索策略:
向量相似度初篩:
retriever_engine = index.as_retriever(similarity_top_k=20)
retrieve_chunk = retriever_engine.retrieve(prompt)
語(yǔ)義重排序:
dashscope_rerank = DashScopeRerank(top_n=chunk_cnt)
results = dashscope_rerank.postprocess_nodes(retrieve_chunk, query_str=prompt)
注:比較初步的檢索策略,可根據(jù)實(shí)際情況進(jìn)行調(diào)整
4. 圖片鏈接處理
只保留最相關(guān)文本塊中的圖片鏈接
移除其他文本塊的圖片鏈接
使用 Markdown 語(yǔ)法在回答中顯示圖片
prompt_template = """請(qǐng)參考以下內(nèi)容,僅使用第一個(gè)最相關(guān)文本塊中的圖片鏈接。
如果在第一個(gè)文本塊中看到"圖片鏈接:",將其轉(zhuǎn)換為Markdown圖片語(yǔ)法。
請(qǐng)忽略其他文本塊中的圖片鏈接。
"""
4、使用指南
4.1上傳數(shù)據(jù)
系統(tǒng)支持兩種文件上傳方式:臨時(shí)上傳:直接在 RAG 問(wèn)答頁(yè)面上傳文件,臨時(shí)使用
創(chuàng)建知識(shí)庫(kù):在"上傳數(shù)據(jù)"頁(yè)面中上傳文件,并在"創(chuàng)建知識(shí)庫(kù)"頁(yè)面構(gòu)建永久知識(shí)庫(kù)
支持的文件類型
非結(jié)構(gòu)化數(shù)據(jù):PDF、DOCX、TXT
結(jié)構(gòu)化數(shù)據(jù):XLSX、CSV
4.2創(chuàng)建知識(shí)庫(kù)
進(jìn)入"創(chuàng)建知識(shí)庫(kù)"頁(yè)面
選擇已上傳的類目或數(shù)據(jù)表
設(shè)置知識(shí)庫(kù)名稱
點(diǎn)擊"確認(rèn)創(chuàng)建知識(shí)庫(kù)"
4.3RAG 問(wèn)答
flowchart TD
A[用戶提問(wèn)] --> B[獲取知識(shí)庫(kù)]
B --> C[檢索相關(guān)文檔]
C --> D[重排序文檔]
D --> E[構(gòu)建提示詞]
E --> F[調(diào)用大語(yǔ)言模型]
F --> G[生成回答]
G --> H[顯示回答及圖片]
5、項(xiàng)目結(jié)構(gòu)
main.py - FastAPI 應(yīng)用入口和 Gradio 界面定義
chat.py - RAG 問(wèn)答核心功能和大模型調(diào)用
upload_file.py - 文件上傳和處理邏輯,包括 PDF 圖片提取
create_kb.py - 知識(shí)庫(kù)創(chuàng)建和管理
html_string.py - Web 界面 HTML 模板
File/ - 存放上傳的文件
VectorStore/ - 存放向量數(shù)據(jù)庫(kù)
static/images/ - 存放提取的圖片
images/ - UI 頭像圖片
6、自定義與擴(kuò)展
修改嵌入模型
可以使用本地嵌入模型替代云端 API。
在create_kb.py和chat.py中取消相關(guān)注釋并安裝額外依賴。
優(yōu)化提示詞模板
修改chat.py中的prompt_template變量以定制提示詞模板。
添加新的文檔類型支持
擴(kuò)展upload_file.py中的處理邏輯以支持更多文件類型。