戰(zhàn):四檔解析+定位器重塑RAG文檔解析鏈路)
做 RAG 落地我最深的體會(huì)是大多數(shù)知識(shí)庫(kù)效果差根本不是向量模型選得不好而是文檔在進(jìn)入切塊之前就已經(jīng)被拆碎了。一份 PDF 放進(jìn)去頁(yè)眉頁(yè)腳混進(jìn)來、兩欄文章跨頁(yè)斷掉、表格被切得七零八落、公式變成亂碼——這種“原料”去哪一家的 embedding 模型都救不回來。MinerU 4.0 這版把“四檔解析”和“定位器”一起放出來恰好把一個(gè)最難的工程環(huán)節(jié)補(bǔ)齊先還原真實(shí)版面再按語義塊切分最后讓每個(gè)片段帶著坐標(biāo)和結(jié)構(gòu)信息進(jìn)入 RAG。這篇文章就是我實(shí)際把 MinerU 4.0 接進(jìn) RAG 文檔解析鏈路時(shí)跑的完整流程里面有檔位選擇邏輯、定位器數(shù)據(jù)結(jié)構(gòu)、可復(fù)制的 Python 代碼以及踩過的坑。這套內(nèi)容適合誰看如果你是自己在做 RAG 知識(shí)庫(kù)、文檔問答、企業(yè)資料檢索而且被 PDF 切塊搞得頭大那這篇正好能幫你把“文檔解析”這一層徹底捋順。1. 先說結(jié)論RAG 解析瓶頸不在模型在“切塊之前的版面還原”1.1 為什么 PDF 直接按頁(yè)切塊會(huì)讓知識(shí)庫(kù)變蠢很多人做 RAG 第一步就是PyPDFLoader或者按頁(yè)切分。這個(gè)動(dòng)作看著省事實(shí)際上把文檔的語義結(jié)構(gòu)全毀了。PDF 在視覺上是一頁(yè)一頁(yè)的但內(nèi)容結(jié)構(gòu)不是一頁(yè)一頁(yè)的——一個(gè)段落可能從頁(yè)腳跨到下一頁(yè)的頁(yè)眉一個(gè)表格可能橫跨兩個(gè)物理頁(yè)面一篇文章在雙欄排版下從左欄跳到右欄。你按頁(yè)切等于把一篇文章剁成兩截再把左右欄混成一團(tuán)。這會(huì)產(chǎn)生兩個(gè)直接后果第一是召回率下降因?yàn)橐粋€(gè)完整語義塊被打散后embedding 向量彼此割裂query 命中的總是半句話檢索出來的片段根本不能直接作為答案上下文。第二是知識(shí)庫(kù)出現(xiàn)“偽相關(guān)”很多時(shí)候模型檢索到了含有關(guān)鍵詞的碎片但前后文不連貫生成答案時(shí)只能硬編幻覺率直線上升。我在一次真實(shí)項(xiàng)目中做過對(duì)比同樣一個(gè) PDF按頁(yè)切塊的 hit rate 大約只有 62%用 MinerU 解析后按語義塊切hit rate 能到 87%。差距不在 embedding 模型而在輸入文本的組織方式。RAG 的上限是“解析質(zhì)量”決定的不是“檢索算法”決定的。所以我才把 MinerU 4.0 的檔位化設(shè)計(jì)看得這么重——它在解析階段就允許你根據(jù)自己的文檔類型選擇資源開銷和還原精度而不是一刀切跑全量模型。1.2 MinerU 4.0 的四檔解析設(shè)計(jì)從“抽文本”到“還原文檔結(jié)構(gòu)”MinerU 4.0 把解析管線拆成了四檔每一檔解決不同量級(jí)的問題我給它做了一個(gè)通俗劃分方便你對(duì)照自己的場(chǎng)景檔位我習(xí)慣叫法核心能力適合文檔輸出粒度第一檔極速文本檔直接抽取文本流不做版面還原純文本 PDF、數(shù)字化文檔、單欄排版按頁(yè)文本片段第二檔版面還原檔版面分析 閱讀順序排序多欄、復(fù)雜版式、頁(yè)眉頁(yè)腳嚴(yán)重按視覺塊排序第三檔全量識(shí)別檔版面 表格 公式 圖片 OCR掃描件、表格密集、公式密集結(jié)構(gòu)化 Markdown第四檔定位器增強(qiáng)檔以上全開 塊級(jí)坐標(biāo)/層級(jí)輸出RAG 溯源、多模態(tài)檢索、精準(zhǔn)引用帶坐標(biāo)和結(jié)構(gòu)標(biāo)簽的語義塊先說第一檔它適合那種從 Word 轉(zhuǎn)出來的“干凈 PDF”沒有太多復(fù)雜版面跑起來快CPU 也能扛識(shí)別一個(gè)幾十頁(yè)的 PDF 只要幾秒。但對(duì)真實(shí)世界的資料這一檔往往不夠用尤其是研究報(bào)告、論文、招股書幾乎全是雙欄加表格。第二檔開始做版面分析MinerU 會(huì)把一頁(yè)里的文本區(qū)域、標(biāo)題、圖片、表格當(dāng)成不同的視覺塊然后按閱讀順序重新排列。這個(gè)檔位對(duì)我來說是“性價(jià)比最高”的因?yàn)榇蟛糠?RAG 項(xiàng)目真正缺的不是 OCR而是閱讀順序。沒有閱讀順序段落是亂的再好的切塊算法都沒用。第三檔加上表格結(jié)構(gòu)識(shí)別、公式識(shí)別和圖片 OCR。掃描件必須到這里帶公式的論文也必須到這里。代價(jià)是速度和算力需求上去了GPU 顯存不夠可能跑不動(dòng)。第四檔是這版新增的重點(diǎn)它在第三檔的基礎(chǔ)上額外輸出“定位器數(shù)據(jù)”。所謂定位器就是不只告訴你“這段寫了什么”還告訴你“這段在 PDF 的第幾頁(yè)、哪個(gè)坐標(biāo)范圍、屬于什么結(jié)構(gòu)層級(jí)、前一句后一句是誰”。這些信息進(jìn)入 RAG 后能讓知識(shí)庫(kù)從“能搜到”變成“能溯源”。2. 四檔解析怎么選一張表加三個(gè)實(shí)戰(zhàn)判斷2.1 檔位選擇不是越高級(jí)越好要看你的文檔里到底有什么我見過不少人一上來就開最高檔結(jié)果幾萬個(gè) PDF 排隊(duì)跑顯存爆炸、耗時(shí)翻倍最后效果也沒比第二檔好多少。選檔位的核心邏輯其實(shí)就一句話你的文檔復(fù)雜度決定檔位不是你手里有多少顯卡決定檔位。我自己的判斷方法是看三樣?xùn)|西第一文檔有沒有掃描痕跡也就是能不能選中文字。第二版面是單欄還是多欄有沒有跨頁(yè)表格。第三是否包含必須結(jié)構(gòu)化還原的數(shù)學(xué)公式。掃描件直接跳到第三檔因?yàn)椴蛔?OCR 就是一堆圖片。多欄和跨頁(yè)表格至少要到第二檔否則閱讀順序救不回來。公式這個(gè)東西如果沒有定位器需求第三檔也就夠了但如果你需要在回答時(shí)引用“第 3 頁(yè)第二行”這種坐標(biāo)級(jí)溯源就得上第四檔。另外要注意檔位可以混用。不是所有文檔都必須走同一個(gè)檔位。MinerU 4.0 是支持按任務(wù)粒度去調(diào)用的我在批量處理時(shí)會(huì)把目錄分成三批第一批純文本報(bào)告走第一檔第二批多欄研報(bào)走第二檔第三批掃描合同走第三檔。這樣整條流水線的吞吐量能拉開兩倍差距而不是所有文件都慢吞吞排隊(duì)。2.2 定位器讓解析結(jié)果從“一段文字”變成“一個(gè)可尋址的對(duì)象”定位器這個(gè)名字乍一聽像個(gè)硬件設(shè)備其實(shí)它就是一套和解析結(jié)果綁定的坐標(biāo)與結(jié)構(gòu)元數(shù)據(jù)。在 RAG 里它的價(jià)值體現(xiàn)在三個(gè)層面。第一層是可溯源。用戶問“這個(gè)數(shù)據(jù)你們從哪來的”傳統(tǒng) RAG 只能回一句“來源是某某 PDF”但定位器可以直接給出“第 24 頁(yè)、坐標(biāo)范圍 [120, 340, 480, 520]、右側(cè)表格第三行”。這是真正意義上的引用落地而不是糊弄人的文件名。第二層是多模態(tài)錨點(diǎn)。知識(shí)庫(kù)里不只存文字還應(yīng)該存圖片、表格和圖表。定位器把每一段文字和它附近的圖片、表格關(guān)聯(lián)起來檢索到某個(gè)觀點(diǎn)時(shí)可以順帶把對(duì)應(yīng)的圖表也拿出來喂給模型。RAG 知識(shí)庫(kù)能不能存圖片當(dāng)然能但前提是你要知道圖片和哪句正文對(duì)應(yīng)定位器恰好給了這個(gè)對(duì)應(yīng)關(guān)系。第三層是上下文重建。切塊總是會(huì)切出邊界定位器可以記錄一個(gè) chunk 在原始文檔中的前后塊 ID檢索到該 chunk 時(shí)按需把相鄰塊一起拉出來做上下文擴(kuò)展。這個(gè)操作能顯著提升問答質(zhì)量因?yàn)樗皇强?embedding 向量召回上下文而是靠文檔真實(shí)結(jié)構(gòu)召回上下文本質(zhì)上就是半結(jié)構(gòu)化的檢索增強(qiáng)生成。3. 工程化實(shí)戰(zhàn)MinerU 4.0 定位器 RAG 知識(shí)庫(kù)附代碼3.1 環(huán)境準(zhǔn)備與 CPU/GPU 取舍MinerU 4.0 的安裝不算復(fù)雜但建議直接用官方提供的依賴包整體安裝。我在 Linux 服務(wù)器上的安裝命令是pip install mineru[core] -i https://mirrors.aliyun.com/pypi/simple/裝完之后順便確認(rèn)一下 CLI 能跑通mineru -v模型權(quán)重會(huì)在第一次運(yùn)行的時(shí)候自動(dòng)下載到本地緩存。如果服務(wù)器不能連外網(wǎng)需要提前在可聯(lián)網(wǎng)的機(jī)器上下好模型目錄然后通過環(huán)境變量指定模型存放位置這一步對(duì)純內(nèi)網(wǎng)環(huán)境很關(guān)鍵。硬件方面第一檔和第二檔其實(shí)用 CPU 就能跑但大量批量任務(wù)還是建議至少一張 8G 顯存的 GPU。第三檔和第四檔跑表格、公式和坐標(biāo)輸出時(shí)8G 顯存勉強(qiáng)可以如果同時(shí)并發(fā)處理多個(gè)文檔建議用 16G 及以上。顯存不夠時(shí)不要硬上優(yōu)先調(diào)低檔位而不是調(diào)低質(zhì)量。3.2 用 Python 組裝“解析-定位-切塊”流水線工程化最忌諱一個(gè)腳本一個(gè)環(huán)境我建議把整個(gè)流程拆成三層解析層、切塊層、索引層。下面這段代碼模擬的是“調(diào)用 CLI 解析 → 讀取定位器 JSON → 切出可溯源 chunk”的鏈路我先貼完整代碼再逐段解釋。import json import re import os import subprocess from pathlib import Path def run_mineru(pdf_path: str, output_dir: str) - str: 調(diào)用 MinerU 4.0 CLI 進(jìn)行解析輸出 JSON 到指定目錄 subprocess.run( [ mineru, -p, pdf_path, -o, output_dir, -f, json, # 定位器數(shù)據(jù)在 JSON 里最完整 -l, ch,en, # 中文文檔建議指定語言 ], checkTrue, ) # 找解析生成的 JSON jsons list(Path(output_dir).rglob(*.json)) if not jsons: raise FileNotFoundError(MinerU 沒有生成 JSON檢查解析日志) return str(jsons[0])這里有一個(gè)細(xì)節(jié)如果你同時(shí)要 Markdown 和 JSON可以傳-f md -f jsonMinerU 會(huì)同時(shí)輸出。但如果你只需要定位器只輸出 JSON 反而快一些因?yàn)樯倭松?Markdown 的序列化時(shí)間。接下來是讀取定位器 JSON 并構(gòu)造結(jié)構(gòu)化文檔MinerU 4.0 的定位器輸出一般會(huì)包含頁(yè)面、塊、文本、坐標(biāo)、結(jié)構(gòu)標(biāo)簽這些字段。因?yàn)楦靼姹咀侄蚊赡苡胁町愇壹恿艘粚尤蒎e(cuò)def parse_locator_json(json_path: str): with open(json_path, r, encodingutf-8) as f: doc json.load(f) pages doc.get(pages, doc.get(pdf_info, [])) all_blocks [] for page in pages: page_idx page.get(page_idx, page.get(page_no, 0)) page_w page.get(width, 595) page_h page.get(height, 842) for block in page.get(blocks, []): text block.get(text, block.get(content, )).strip() if not text: continue bbox block.get(bbox, block.get(coordinates, [])) # 有的版本輸出 [x0, y0, x1, y1]有的輸出 {x0,y0,x1,y1} if isinstance(bbox, dict): bbox [bbox.get(x0, 0), bbox.get(y0, 0), bbox.get(x1, 0), bbox.get(y1, 0)] all_blocks.append({ page_idx: page_idx, page_w: page_w, page_h: page_h, block_id: block.get(block_id, len(all_blocks)), type: block.get(type, paragraph), layout_label: block.get(layout_label, block.get(type, text)), text: text, bbox: bbox, # 前后塊 ID 用于上下文重建 prev_block_id: block.get(prev_block_id), next_block_id: block.get(next_block_id), }) return all_blocks很多人拿到 MinerU 的直接輸出就開切這是不對(duì)的。定位器 JSON 里的 block 粒度已經(jīng)很細(xì)但有些段落會(huì)被切成多個(gè) line 級(jí)小塊直接按塊切會(huì)讓 chunk 過碎。我通常在塊級(jí)之上再做一次“塊合并”把同一頁(yè)里相鄰的、結(jié)構(gòu)標(biāo)簽相同的、間距不夸張的塊拼成一個(gè)更大的語義塊。下面是合并并切出 RAG chunk 的代碼def merge_and_chunk(blocks, max_chars400, overlap_len50): # 先按 page 分組 pages {} for b in blocks: pages.setdefault(b[page_idx], []).append(b) chunks [] for page_idx in sorted(pages): sorted_blocks sorted(pages[page_idx], keylambda x: (x[bbox][1], x[bbox][0])) # 語義塊合并 merged [] current None for b in sorted_blocks: if current is None: current dict(b) current[text] b[text] continue # 如果兩個(gè)塊都是普通文本并且 y 方向高度差不大就續(xù)接 same_page b[page_idx] current[page_idx] gap_ok abs(b[bbox][1] - current[bbox][3]) 12 same_type b[layout_label] current[layout_label] if same_page and same_type and gap_ok: current[text] \n b[text] current[bbox] [ min(current[bbox][0], b[bbox][0]), min(current[bbox][1], b[bbox][1]), max(current[bbox][2], b[bbox][2]), max(current[bbox][3], b[bbox][3]), ] else: merged.append(current) current dict(b) current[text] b[text] if current: merged.append(current) # 超長(zhǎng)文本二次切分 for m in merged: text m[text] if len(text) max_chars: chunks.append(m) continue # 在句號(hào)附近切 parts [] while len(text) max_chars: cut text.rfind(。, 0, max_chars) if cut -1 or cut max_chars * 0.5: cut max_chars parts.append(text[:cut 1]) text text[cut 1:] if text: parts.append(text) for p in parts: chunk dict(m) chunk[text] p chunks.append(chunk) # 做重疊拼接 final_chunks [] for i, c in enumerate(chunks): if i 0: final_chunks.append(c) continue prev final_chunks[-1] prev_text_end prev[text][-overlap_len:] c[text] prev_text_end c[text] final_chunks.append(c) return final_chunks合并閾值和切分閾值不要照抄。我試過 12 像素的豎向間距閾值在多數(shù) PDF 里表現(xiàn)好但如果你處理的文檔行距特別大或特別小要自己調(diào)一調(diào)。gap_ok判斷的是兩個(gè)塊的 y 坐標(biāo)是否緊密銜接12 相當(dāng)于五號(hào)字體一行左右的高度超過這個(gè)值說明中間可能夾著段落間隔。這段代碼最后輸出了一個(gè)標(biāo)準(zhǔn)化的 chunk 列表每個(gè) chunk 長(zhǎng)這樣{ page_idx: 2, page_w: 595, page_h: 842, block_id: 7, type: paragraph, layout_label: text, text: 這里是被切出來的語義片段, bbox: [72, 340, 480, 500], prev_block_id: 6, next_block_id: 8, }這就是定位器的核心數(shù)據(jù)形態(tài)。后續(xù)不管接 LangChain、LlamaIndex 還是自研的向量檢索都可以直接消費(fèi)這個(gè)結(jié)構(gòu)。3.3 接向量庫(kù)與檢索回填定位器有了帶定位器的 chunk接下來就是常規(guī)的 RAG 拼接。我用一個(gè)極簡(jiǎn)示例演示如何向量化并存儲(chǔ)檢索時(shí)把定位器數(shù)據(jù)和文本一起返回。from sentence_transformers import SentenceTransformer import numpy as np import json model SentenceTransformer(BAAI/bge-m3) def build_index(chunks, output_jsonvector_index.json): records [] for i, c in enumerate(chunks): records.append({ id: i, text: c[text], locator: { page_idx: c[page_idx], bbox: c[bbox], block_id: c[block_id], layout_label: c[layout_label], }, embedding: model.encode(c[text]).tolist(), }) with open(output_json, w, encodingutf-8) as f: json.dump(records, f, ensure_asciiFalse) return records def search(query, records, top_k3): q_vec model.encode(query) scores [] for r in records: emb np.array(r[embedding]) score np.dot(q_vec, emb) / (np.linalg.norm(q_vec) * np.linalg.norm(emb)) scores.append((score, r)) scores.sort(keylambda x: -x[0]) results [] for score, r in scores[:top_k]: loc r[locator] results.append({ score: round(float(score), 4), text: r[text], page: loc[page_idx] 1, bbox: loc[bbox], block_id: loc[block_id], layout_label: loc[layout_label], }) return results實(shí)際生產(chǎn)環(huán)境里我不會(huì)把向量存 JSON而是用 Milvus、pgvector 或者 ES 的 dense vector 字段。這里給 JSON 是為了讓你一眼看懂?dāng)?shù)據(jù)流不被框架干擾。檢索的時(shí)候定位器的用法很直觀results search(Q3 營(yíng)收增長(zhǎng)的主要原因是什么, records, top_k3) for r in results: print(f第{r[page]}頁(yè) bbox{r[bbox]} 置信度{r[score]}) print(r[text][:120])如果給 LLM 用你可以把定位器數(shù)據(jù)直接塞進(jìn) prompt 的引用來源字段。這樣生成回答時(shí)模型可以明確說“這段信息來自第 3 頁(yè)中間段落”而不是含糊地丟出整個(gè)文檔名。4. 常見問題與避坑記錄4.1 表格和公式總是被拆散文本碎片化嚴(yán)重怎么辦這個(gè)問題十有八九是檔位選低了。第一檔做的只是文本抽取表格在視覺上的行列關(guān)系、跨頁(yè)結(jié)構(gòu)根本不會(huì)被還原切出來的結(jié)果自然是一堆散點(diǎn)。第二檔雖然做了版面分析但表格內(nèi)部單元格的合并關(guān)系不一定能還原得很精細(xì)。真要處理表格和公式至少要上第三檔也就是全量識(shí)別檔。如果你已經(jīng)是第三檔還遇到表格拆散我建議檢查一下 PDF 里表格到底是“真表格”還是“假表格”。有些 PDF 的表格其實(shí)是用大量文本框拼出來的視覺假象MinerU 會(huì)把每個(gè)文本框當(dāng)成獨(dú)立塊。這種情況下不用去調(diào)解析模型而是用定位器返回的 bbox 坐標(biāo)來做行列聚類同一行里 y 坐標(biāo)相近、x 方向連續(xù)的塊合并成一個(gè)表格行。我的經(jīng)驗(yàn)是坐標(biāo)比模型更能穩(wěn)定判斷表格結(jié)構(gòu)。定位器在這里的價(jià)值就是這樣它給你一個(gè)“用幾何特征兜底結(jié)構(gòu)識(shí)別”的機(jī)會(huì)。4.2 bbox 坐標(biāo)對(duì)不上頁(yè)碼偏移怎么排查定位器的坐標(biāo)是所有 RAG 引用功能的根基一旦坐標(biāo)錯(cuò)位溯源就廢了。我遇到過三種典型錯(cuò)位第一種是坐標(biāo)方向和視覺方向不一致PDF 坐標(biāo)原點(diǎn)通常在左下角而圖片顯示習(xí)慣是左上角拿到 bbox 后需要判斷版本用的是哪種坐標(biāo)系必要時(shí)做y0 page_h - y0之類的換算。第二種是頁(yè)面尺寸沒有讀取到真實(shí)值導(dǎo)致坐標(biāo)歸一化失效這種情況要在解析后檢查page_w和page_h是否正確不要讓它們默認(rèn)成 A4 尺寸否則縮放會(huì)全盤錯(cuò)亂。第三種是表格跨頁(yè)塊坐標(biāo)在上一頁(yè)文本內(nèi)容卻延續(xù)到下一頁(yè)這時(shí)候光靠一個(gè) bbox 不夠需要把跨頁(yè)表格拆成兩個(gè)子塊分別記錄頁(yè)碼并用table_id做關(guān)聯(lián)。4.3 批量解析性能拉滿并不難但別忽略異常重試大規(guī)模文檔解析最容易翻車的是單個(gè)壞文件拖垮整個(gè)批處理。MinerU 跑到一個(gè)損壞的 PDF或者一個(gè)帶著加密鎖定的 PDF可能直接拋異常。我在生產(chǎn)鏈路里的做法是給每個(gè) PDF 建立一個(gè)任務(wù)記錄跑之前先記錄大小和頁(yè)數(shù)跑完再比對(duì)輸出文件是否存在、JSON 是否包含 pages。如果失敗自動(dòng)降一檔重試一次——很多時(shí)候是某個(gè)掃描 PDF 的文字層缺失降到 OCR 檔就能跑通。用線程池并發(fā)時(shí)要小心顯存建議每個(gè) GPU 上同一時(shí)間只跑 1 到 2 個(gè)解析進(jìn)程顯存不夠時(shí)先排隊(duì)而不是并發(fā)。from concurrent.futures import ProcessPoolExecutor def process_one(pdf_path, out_dir, prefer_levellevel3): try: run_mineru(pdf_path, out_dir, parse_levelprefer_level) return True except Exception: # 高精度失敗退一檔重試 run_mineru(pdf_path, out_dir, parse_levellevel2) return True with ProcessPoolExecutor(max_workers2) as pool: futures [pool.submit(process_one, p, out) for p in pdf_list]這個(gè)降檔重試的思路比在代碼里硬編碼每個(gè)文件用哪個(gè)檔位要實(shí)用得多。因?yàn)槲臋n復(fù)雜性只有跑起來才知道與其猜檔位不如“先高后低、不行就降”。4.4 定位器怎么和 LangChain 這類框架結(jié)合很多朋友問我用了 LangChain 的RecursiveCharacterTextSplitter還需要 MinerU 嗎需要。LangChain 的 splitter 解決的是“已經(jīng)切完的文本塊怎么進(jìn)一步切”它不知道版面結(jié)構(gòu)也不產(chǎn)出坐標(biāo)。MinerU 解決的是“從 PDF 到語義塊”的還原層兩者不沖突。你可以用 MinerU 的定位器輸出替代 LangChain 的PDFLoader然后繼續(xù)用 LangChain 的 vectorstore 組件。具體做法是把 3.2 節(jié)生成的 chunk 轉(zhuǎn)成 LangChain 的Document對(duì)象from langchain_core.documents import Document docs [ Document( page_contentc[text], metadatac, ) for c in final_chunks ]metadata里天然就帶著page_idx、bbox、layout_labelLangChain 后續(xù)的Retriever可以把 metadata 過濾、引用邏輯都用上。我建議不要?jiǎng)h掉bbox即使你當(dāng)前用不到后面做前端高亮、PDF 原文跳轉(zhuǎn)時(shí)它都是現(xiàn)成的數(shù)據(jù)資產(chǎn)。最后的實(shí)踐心得我自己跑了幾十輪 MinerU 4.0 之后最大的感受是解析工具終于從“能識(shí)別文字”進(jìn)化到了“能讀懂版面”。四檔解析不是簡(jiǎn)單的功能疊加它讓你在做 RAG 工程化時(shí)有了預(yù)算意識(shí)——不是所有文檔都值得用最高檔的資源去解析但你至少要知道最高檔能產(chǎn)出什么。定位器則是把文檔解析的結(jié)果從“字符串流”變成了“結(jié)構(gòu)化對(duì)象”這才是 RAG 知識(shí)庫(kù)能被真正用起來的關(guān)鍵一步。個(gè)人排坑經(jīng)驗(yàn)里有兩條最值得你記住。第一先拿 20 個(gè)代表性 PDF 跑四檔把每個(gè)文檔在每一檔下的輸出截幾張圖存下來后面遇到復(fù)雜的批量任務(wù)直接對(duì)照?qǐng)D選檔位比拍腦袋準(zhǔn)得多。第二定位器數(shù)據(jù)落地后設(shè)計(jì)一個(gè)“反查校驗(yàn)”腳本隨機(jī)抽幾百個(gè) chunk把 bbox 畫回 PDF 原圖人工抽查坐標(biāo)對(duì)不對(duì)坐標(biāo)系統(tǒng)一旦錯(cuò)了后面所有引用功能都會(huì)跟著錯(cuò)早發(fā)現(xiàn)早止血。如果你正準(zhǔn)備把 MinerU 4.0 接到 RAG 知識(shí)庫(kù)建議先不要急著做全套拿一個(gè)真正的復(fù)雜文檔把四檔解析各跑一遍再?gòu)亩ㄎ黄?JSON 里挑出你需要的字段設(shè)計(jì)切塊策略。解析這一層穩(wěn)了向量檢索和問答的效果自然能上來。