RAG 詳解:將自己的資料加入 LLM 應用
您已經使用強大的 LLM(如 GPT-4 或 Claude)建立了一個聊天機器人,但它給出的答案很籠統,而且不瞭解您公司的內部文件。如何讓它回答關於您自己資料的問題?微調既昂貴又靜態。解決方案是檢索增強生成(RAG)。
在本文中,我們將以實用的方式解釋 RAG,展示如何逐步實現它,並分享建立可靠 LLM 應用程式的最佳實踐,讓它們能夠利用您的私有資料。
什麼是 RAG?
RAG 結合了兩種強大的技術:檢索(從知識庫中尋找相關資訊)和生成(使用 LLM 產生答案)。RAG 不是僅依賴 LLM 的預訓練知識,而是動態地取得相關文件並將其包含在提示中,讓模型基於您的資料來回答。
可以把它想像成 AI 的開書考試:它可以在回答之前查閱您的文件來找到答案。
為什麼要使用 RAG?
- 最新資訊:更新知識庫,無需重新訓練模型。
- 成本效益:無需昂貴的微調或大型上下文視窗。
- 準確性:透過將答案建立在檢索到的事實上,減少幻覺。
- 隱私:您的資料保留在向量資料庫中;只有相關片段會發送給 LLM。
- 靈活性:可與任何 LLM(OpenAI、Anthropic、本地模型)和任何文件類型搭配使用。
RAG 如何運作:核心組件
典型的 RAG 系統有四個主要部分:
- 文件擷取:載入並預處理您的文件(PDF、網頁、資料庫)。
- 嵌入模型:將文字區塊轉換為捕捉語意意義的數值向量。
- 向量資料庫:儲存並索引這些向量,以實現快速相似性搜尋。
- LLM:使用檢索到的上下文產生答案。
逐步指南:建立 RAG 管道
1. 準備您的文件
收集您的資料來源:PDF、Markdown 檔案、Confluence 頁面或 SQL 表格。清理文字(移除頁首、頁尾、樣板內容),並將其分割成 200–500 字的區塊,保留一些重疊(例如 50 字)以保留上下文。
使用 Python 的範例:
from langchain.text_splitter import RecursiveCharacterTextSplitter
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=500,
chunk_overlap=50
)
chunks = text_splitter.split_text(your_document)
2. 產生嵌入
使用嵌入模型,如 OpenAI 的 text-embedding-3-small 或開源模型如 all-MiniLM-L6-v2,將每個區塊轉換為向量。
from openai import OpenAI
client = OpenAI()
def get_embedding(text):
response = client.embeddings.create(
model="text-embedding-3-small",
input=text
)
return response.data[0].embedding
3. 儲存到向量資料庫
選擇一個向量資料庫:Pinecone、Weaviate、Qdrant,甚至帶有 pgvector 的 PostgreSQL。儲存每個區塊的嵌入以及元資料(來源、頁碼)。
import pinecone
pinecone.init(api_key="YOUR_KEY", environment="us-west1-gcp")
index = pinecone.Index("rag-demo")
vectors = [(f"chunk-{i}", get_embedding(chunk), {"text": chunk}) for i, chunk in enumerate(chunks)]
index.upsert(vectors=vectors)
4. 檢索相關區塊
當使用者提問時,將查詢嵌入並搜尋最相似的前 k 個區塊。
query_embedding = get_embedding(user_question)
results = index.query(vector=query_embedding, top_k=3, include_metadata=True)
context = "\n\n".join([match.metadata["text"] for match in results.matches])
5. 產生答案
建立一個包含檢索到的上下文的提示,並要求 LLM 根據它來回答。
prompt = f"""Answer the question based only on the following context:
{context}
Question: {user_question}
Answer:"""
response = client.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": prompt}]
)
print(response.choices[0].message.content)
RAG 與微調的比較
| 方面 | RAG | 微調 |
|---|---|---|
| 資料新鮮度 | 即時更新 | 靜態,直到重新訓練 |
| 成本 | 低(嵌入 + 儲存) | 高(訓練運算) |
| 實作 | 模組化,較容易 | 複雜,需要 ML 專業知識 |
| 使用案例 | 文件問答 | 風格調整、領域術語 |
RAG 的最佳實踐
- 明智地分塊:重疊區塊以避免切斷句子;考慮語意分塊。
- 使用混合搜尋:結合向量搜尋與關鍵字搜尋(BM25)以獲得更好的召回率。
- 重新排序結果:使用交叉編碼器按相關性重新排序檢索到的區塊。
- 仔細設計提示:指示 LLM 引用來源,並在上下文不足時說「我不知道」。
- 監控與評估:記錄查詢和回應;使用命中率和答案相關性等指標。
常見陷阱及如何避免
- 檢索效果差:如果嵌入未能捕捉領域特定意義,請嘗試微調嵌入模型或使用特定領域的模型。
- 上下文長度限制:不要塞入太多區塊;優先考慮頂部結果並保持提示簡潔。
- 幻覺:即使有上下文,LLM 也可能編造事實。使用嚴格的提示並考慮驗證步驟。
- 索引過時:設定管道,在文件變更時重新嵌入。
常見問題
RAG 和微調有什麼區別?
RAG 在推論時檢索相關資訊並將其包含在提示中,而微調則調整模型的權重以學習新模式。RAG 更適合動態、事實性知識;微調更適合風格或領域適應。
RAG 需要向量資料庫嗎?
嚴格來說不需要——您可以使用任何搜尋索引(例如 Elasticsearch),甚至對於小型資料集使用記憶體內餘弦相似度。但像 Pinecone 或 Qdrant 這樣的向量資料庫針對快速、可擴展的相似性搜尋進行了優化。
如何評估 RAG 系統?
衡量檢索品質(precision@k、召回率)和生成品質(答案相關性、忠實度)。像 Ragas 或 TruLens 這樣的工具可以幫助自動化評估。
結論
RAG 是一種實用且具成本效益的方式,可以將您自己的資料加入 LLM 應用程式。透過遵循上述步驟並遵守最佳實踐,您可以建立使用私有知識庫準確回答問題的 AI 助理。從小處著手,迭代,並始終進行評估。
在為您的 RAG 管道準備文件時,您經常需要將多個 PDF 合併為單一檔案以便於擷取。使用我們免費的 PDF Merger 快速安全地合併 PDF。