幾百G縣志如何變成能對話的AI
RAG 與向量資料庫,從原理到落地
一、問題的起點
你有一個縣城的全部縣志。明清舊志、民國油印件、建國後的正式縣志、二十年的年鑑、幾百部族譜、政協文史資料、老照片……堆在圖書館的鐵皮櫃裡,紙質的,落灰的。
有人說,現在AI這麼厲害,能不能讓AI讀完這些東西,然後我問它「本縣歷史上最大的水災是哪一年」,它就能告訴我?
能。但不是你想的那種「讀完」。
二、AI 不是讀完了所有書
這是最重要的認知糾偏。
ChatGPT、Claude 這些大語言模型(LLM),它們的「知識」來自訓練階段讀過的網際網路文本。但它們有一個硬限制——上下文視窗。
當前最強的 Claude,上下文視窗約 100 萬 tokens,大約相當於幾百頁文件。而一個縣的全部史料,純文本可能有 100-500MB,相當於幾萬頁。
差了 100 倍。裝不下。
所以你不能把幾百G的掃描件全塞給AI,讓它「讀完」。這在物理上不可能。
三、不需要訓練,需要檢索
很多人的第一反應是「用這些縣志訓練一個AI」。
這是對「訓練」的誤解。訓練一個大語言模型,是 Anthropic、OpenAI 這些公司花幾千萬美元、用幾千張GPU、跑幾個月才能做的事。你不需要這樣做,Claude 已經會理解中文了。
你需要的是讓 Claude 在回答問題之前,先翻到正確的那一頁。
這就是 RAG(Retrieval-Augmented Generation,檢索增強生成)。
| 方式 | 成本 | 做什麼 | 你需要嗎 |
|---|---|---|---|
| 訓練(Training) | $10M+ | 教會AI理解語言 | 不需要 |
| 微調(Fine-tuning) | $1K+ | 讓AI學特定領域語感 | 大多數場景不需要 |
| RAG | $0-100 | 建索引,問什麼檢索什麼 | 這才是你需要的 |
打個比方:
你去圖書館問「中國歷史上最大的水災?」
沒有 RAG 的 AI:憑自己讀書時的記憶回答。可能記錯細節,甚至編一個聽起來合理但不存在的事件——這就是 AI 幻覺(Hallucination)。
有 RAG 的 AI:先請圖書管理員去書架找到最相關的 5 頁,翻開擺在面前,然後基於這 5 頁回答,並註明「見《卷二十·災異》第 3 頁」。
RAG 不是讓 AI 更聰明,而是讓 AI 有據可查。
四、完整管道:從紙到對話
一個縣志智慧問答系統的完整流程,分四個階段:
| 階段 | 輸入 | 輸出 | 關鍵技術 |
|---|---|---|---|
| 1. 紙質史料 | 📚 紙質縣志 | 📄 掃描件(圖片/PDF) | 掃描器 |
| 2. 數位化 | 📄 掃描件 | 📝 純文本 | OCR 辨識 |
| 3. 知識化 | 📝 純文本 | 🗄️ 向量索引 | Embedding + 向量資料庫 |
| 4. 服務化 | 🗄️ 向量索引 | 🧠 AI 問答 | RAG 系統 |
展開來看,核心步驟有五個:
步驟一:掃描
把紙質縣志變成圖片或 PDF。很多縣圖書館已經做過數位化,直接拿掃描件就行。
步驟二:OCR(光學字元辨識)
掃描件是圖片,AI 讀不了圖片裡的文字。需要 OCR 把圖片變成可編輯的純文本。
難度取決於原始材料的年代:
| 材料類型 | OCR 方案 | 準確率 |
|---|---|---|
| 1980年後印刷體 | 普通 OCR 就行 | 98%+ |
| 民國印刷/油印件 | 需要好的 OCR 模型 | 90-95% |
| 明清刻本/手抄本 | 專用古籍 OCR | 80-90% |
現在開源的 PaddleOCR(百度)對中文辨識非常好,古籍也有專門的模型。這一步成本接近零,耗時幾小時。
步驟三:切片 + 向量化(核心步驟)
這一步是整個系統的心臟。分兩件事:
切片(Chunking):把長文本切成小段落,每段 200-500 字。
比如《縣志·卷二十·災異》全文 20,000 字,切成 40 個片段:
- 片段 1:乾隆三年夏,淫雨四十日……(500字)
- 片段 2:次年春,知縣修堤……(500字)
- 片段 3:光緒十九年秋,大水……(500字)
- ……共 40 個片段
向量化(Embedding):把每個片段「翻譯」成一串數字。
「乾隆三年夏,淫雨四十日,河溢,淹田三萬畝」
↓ 經過 Embedding 模型
[0.12, -0.34, 0.78, 0.02, ...] (1024 個浮點數)
這串數字編碼了這段話的「語義指紋」。意思相近的文本,數字就相近。
這就是向量。Embedding 模型就是這個翻譯機。
步驟四:存入向量資料庫
向量生成後,需要一個地方儲存和檢索。這就是向量資料庫。
傳統資料庫(MySQL、PostgreSQL)的索引是 B-Tree,做的是精確匹配——「WHERE name = '張三'」。
向量資料庫的索引是 HNSW 或 IVF,做的是近似最近鄰搜尋——「找出跟這段話意思最像的 5 條記錄」。
| 傳統資料庫 | 向量資料庫 | |
|---|---|---|
| 搜尋「水災」 | 只找標題裡有「水災」兩個字的文件 | 找到關於「洪水」「河溢」「大水漫城」的段落 |
| 原理 | 字面匹配 | 語義匹配(向量距離近) |
步驟五:檢索 + LLM 問答
使用者提問時,系統做三件事:
① 把問題也變成向量
「本縣歷史上最嚴重的水災是哪一年?」 → [0.11, -0.30, 0.80, ...]
② 在向量資料庫中搜尋最相似的 5 個片段
命中:
- 「乾隆三年夏,淫雨四十日,河溢,淹田三萬畝…」
- 「光緒十九年秋,大水漫城三尺…」
- 「本縣三面環水,歷來多水患…」
③ 把這 5 段原文 + 問題一起發給 Claude
Claude 閱讀後回答:
「據《卷二十·災異》記載,本縣歷史上最嚴重的水災為乾隆三年(1738年)夏季,連降暴雨四十日,河水漫溢,淹沒農田三萬畝……」
Claude 沒有讀完整部縣志。它只讀了圖書管理員遞過來的那 5 頁。但這 5 頁是對的。
五、兩個獨立的選型決策
搭建 RAG 系統需要選兩樣東西,它們來自完全不同的廠商:
Embedding 模型(翻譯機) — 負責把文字變成向量:
| 廠商 | 產品 | 特點 |
|---|---|---|
| 智源研究院(北京) | BGE-M3 | 中文最強,開源免費,本地運行 |
| 阿里雲 | GTE-Qwen2 | 中文極好,開源免費,本地運行 |
| OpenAI | text-embedding-3 | 英文強,中文好,API 付費 |
| Voyage AI | Voyage-3 | 品質高,API 付費 |
向量資料庫(倉庫) — 負責存向量、搜向量:
| 廠商 | 產品 | 特點 |
|---|---|---|
| Chroma Inc | ChromaDB | Python 原生,pip install 即用 |
| Qdrant Ltd | Qdrant | Rust 高效能,生產環境首選 |
| PostgreSQL 社群 | pgvector | PG 擴充套件,已有 PG 專案直接加 |
| Pinecone | Pinecone | 全託管雲端服務,零維運 |
| Zilliz(國產) | Milvus | 開源分散式,億級向量 |
兩者自由組合。BGE-M3 + ChromaDB 可以,GTE-Qwen2 + Qdrant 也可以。唯一的約束是向量維度要對齊——模型輸出 1024 維,資料庫就配置接收 1024 維。就像鏡頭卡口要匹配機身一樣。
模型不存東西,資料庫不懂語義。 模型負責「理解」,資料庫負責「記住和找到」。
六、這個過程需要寫程式碼嗎?
需要。但不多。
不存在一個軟體讓你「選資料夾 → 點開始 → 等 → 完成」。你需要寫一個 Python 腳本,大約 50 行,串聯整個流程。
核心程式碼骨架:
# 安裝: pip install chromadb sentence-transformers
import os, chromadb
from sentence_transformers import SentenceTransformer
# 載入翻譯機(首次運行自動下載模型,約 2GB)
model = SentenceTransformer("BAAI/bge-m3")
# 初始化倉庫(本地文件,無需伺服器)
db = chromadb.PersistentClient(path="./county-vectors")
collection = db.get_or_create_collection("縣志")
# 遍歷所有文本文件
for filename in os.listdir("./county-data"):
text = open(f"./county-data/{filename}").read()
# 切片:每 500 字一段
chunks = [text[i:i+500] for i in range(0, len(text), 450)]
# 翻譯:文字 → 向量
vectors = model.encode(chunks)
# 入庫:向量 + 原文一起存
for j, chunk in enumerate(chunks):
collection.add(
ids=[f"{filename}_{j}"],
documents=[chunk],
embeddings=[vectors[j].tolist()]
)
print(f"完成: {filename}, {len(chunks)} 個片段已入庫")
這段程式碼做了三件事:載入模型、切片、存入資料庫。在一台普通筆電上,處理一整部縣志(50萬字)大約需要 5-10 秒。
七、需要 GPU 叢集嗎?
不需要。
這是很多人對 AI 專案的最大誤解。整個 RAG 流程分三個層次,算力需求天壤之別:
你在做的事 — 推理(Inference):
- 用別人訓好的模型生成 embedding
- Mac 筆電就夠,零成本
- 100 萬段文本,幾小時跑完
大公司在做的事 — 訓練(Training):
| 訓練目標 | 需要的 GPU | 花費 |
|---|---|---|
| 訓練一個 7B 參數的 LLM | 64-256 張 A100 | $100K - $1M |
| 訓練 Claude / GPT-4 級別 | 數千張 H100 | $10M - $100M |
你做 RAG,全程都是推理,不是訓練。
就像你開車不需要造引擎。智源花了幾千張 GPU 訓好 BGE-M3 模型,你 pip install 下載過來,直接用。
八、怎麼知道結果準不準?
這是 RAG 系統真正的深水區。向量檢索不是玄學,有系統的評估方法。
第一層:人工抽檢
準備 50 個你自己寫的問題(你最懂縣志),每個問題你知道答案出自哪一段。跑檢索,看返回的 5 段裡有沒有命中正確答案。
| 命中率 | 判斷 |
|---|---|
| 45/50 = 90% | 可以上線 |
| 35/50 = 70% | 需要調參 |
| 15/50 = 30% | 模型或切片策略有問題 |
第二層:對比實驗
固定測試問題,換不同配置跑:
| 實驗 | 配置 | 命中率 | 備註 |
|---|---|---|---|
| 1 | BGE-M3 + 切片 500 字 | 82% | 基準 |
| 2 | BGE-M3 + 切片 200 字 | 88% | 更準 |
| 3 | GTE-Qwen2 + 切片 200 字 | 85% | |
| 4 | OpenAI + 切片 200 字 | 78% | 中文不如國產 |
不需要理論推導,直接跑資料說話。
第三層:四個調優旋鈕
如果準確率不夠,依次嘗試:
旋鈕 1 · 切片策略(零成本,影響最大)
按自然段落切,不要硬切字數。保留章節標題作為前綴,如「【卷二十·災異】乾隆三年夏…」。相鄰片段重疊 10-20%,防止答案被切斷。
旋鈕 2 · 檢索策略(零成本)
純向量搜尋能理解同義詞,但可能漏精確詞;純關鍵詞搜尋精確匹配,但不理解語義。混合搜尋——兩者加權合併——是最佳實踐。
旋鈕 3 · 換 Embedding 模型(需重新跑一遍向量化)
BGE-M3 不夠好就試 GTE-Qwen2,反之亦然。
旋鈕 4 · 微調 Embedding 模型(成本最高,效果最好)
準備幾百對訓練資料,讓模型學會「圩」和「堤壩」意思相近,向量應該靠近。
本質上跟所有工程一樣:量化指標 → 對比實驗 → 調參 → 再量化。不是玄學,是科學。
九、部署上線的成本
以一個中等規模的縣(10 萬頁掃描件)為例:
一次性成本:
| 項目 | 方案 | 費用 |
|---|---|---|
| 掃描 | 圖書館可能已有數位化版本 | 視情況 |
| OCR | PaddleOCR 本地跑 | 免費 |
| Embedding | BGE-M3 本地跑 | 免費 |
| 向量資料庫 | ChromaDB / Qdrant 開源 | 免費 |
月度營運成本:
| 項目 | 費用 |
|---|---|
| VPS 伺服器(2核4G) | ¥50-100/月 |
| LLM API(DeepSeek,日均1000次問答) | ¥90/月 |
| 網域 | ¥50/年 |
| 月總成本 | ¥150-200 |
向量庫是資產,大模型是水龍頭。 水龍頭可以隨時換品牌(Claude、DeepSeek、豆包、通義千問),水庫不能。誰先把一個縣的資料向量化,誰就佔了坑。
全國 2800+ 個縣,99% 沒有這樣的系統。資料本身就是壁壘。
十、總結
RAG 的本質: 不是讓 AI 更聰明,而是給 AI 配了一個圖書管理員。
向量資料庫的本質: 不是存文字的資料庫,而是存「意思」的資料庫。
Embedding 模型的本質: 不是翻譯語言,而是把語義翻譯成數學。
整個系統的本質: 先建圖書館索引(一次性),再當智慧圖書管理員(持續服務)。
你不需要訓練AI。你不需要GPU叢集。你不需要幾百萬預算。
你需要的是:一台筆電,50 行 Python,和一個值得被數位化的縣城。