LangChain 課程 – RAG 工具整合
主題:Knowledge Graph RAG(GraphRAG)
簡介
在資訊爆炸的時代,單純的文字檢索已無法滿足「關聯性」與「推理」的需求。Knowledge Graph RAG(GraphRAG) 結合了向量檢索(Vector Retrieval)與圖結構的語意關係,讓 LLM 能在「知道」與「推論」之間取得更好的平衡。
對於想要在企業內部文件、產品說明或法律條文等高度結構化資料上建立問答系統的開發者來說,GraphRAG 能提供更精準的上下文、跨實體關聯的推理,以及可視化的知識圖譜,大幅提升使用者體驗與決策品質。
本篇文章將以 LangChain 為基礎,說明如何在 Python 環境下快速組裝 GraphRAG,並示範 3~5 個實用程式碼範例,協助你從零開始打造具備圖譜推理能力的 RAG 系統。
核心概念
1️⃣ 什麼是 GraphRAG?
GraphRAG 是 Retrieval‑Augmented Generation 的延伸概念,核心流程如下:
- 構建知識圖譜:將文件、實體、屬性與關係抽取成圖的節點(Node)與邊(Edge)。
- 向量化節點:使用嵌入模型(如 OpenAI
text-embedding-ada-002)將每個節點轉成向量,以支援相似度搜尋。 - 圖搜尋 + 向量檢索:先在圖中定位相關實體,再以向量檢索找出最相近的文件段落。
- 組合上下文:將檢索結果與圖關係(如「父子」或「屬於」)組成 Prompt,交給 LLM 產生答案。
重點:圖結構提供「關聯性」的線索,向量檢索提供「語意相似度」的支援,兩者結合可讓模型在回答時兼顧精確度與推理深度。
2️⃣ LangChain 中的 GraphRAG 元件
LangChain 為 GraphRAG 提供了以下高階抽象:
| 元件 | 功能說明 |
|---|---|
GraphStore |
抽象圖資料庫(支援 Neo4j、Weaviate Graph 等) |
GraphRetriever |
先在圖上做鄰近節點搜尋,再呼叫向量檢索 |
GraphRAGChain |
將檢索結果自動組合成 Prompt,完成完整的 RAG 流程 |
PromptTemplate |
可自訂加入圖關係描述的 Prompt 版型 |
透過這些元件,我們只需要 少量程式碼 就能完成從資料匯入、圖建構到問答產生的完整管線。
3️⃣ 建立圖資料庫(以 Neo4j 為例)
以下示範如何使用 neo4j 官方驅動將抽取出的實體寫入圖中,並建立 HAS_CONTENT 與 RELATED_TO 兩種關係。
from neo4j import GraphDatabase
class Neo4jGraph:
def __init__(self, uri, user, password):
self.driver = GraphDatabase.driver(uri, auth=(user, password))
def close(self):
self.driver.close()
def create_node(self, label: str, properties: dict):
"""建立單一節點"""
with self.driver.session() as session:
cypher = f"MERGE (n:{label} {{id: $id}}) SET n += $props"
session.run(cypher, id=properties["id"], props=properties)
def create_relation(self, src_id: str, dst_id: str, rel_type: str):
"""建立兩節點之間的關係"""
with self.driver.session() as session:
cypher = (
"MATCH (a {id: $src}) MATCH (b {id: $dst}) "
f"MERGE (a)-[r:{rel_type}]->(b)"
)
session.run(cypher, src=src_id, dst=dst_id)
小技巧:使用
MERGE可以避免重複節點,適合在增量匯入時使用。
4️⃣ 向量化節點與儲存至向量資料庫
LangChain 內建的 Embedding 接口可直接與 OpenAI、Cohere、或本地模型串接。下面示範把 Neo4j 中的節點內容向量化,並寫入 Weaviate(支援圖向量混合搜尋)。
from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import Weaviate
import weaviate
# 初始化向量模型
embedder = OpenAIEmbeddings(model="text-embedding-ada-002")
# 初始化 Weaviate 客戶端
client = weaviate.Client(url="http://localhost:8080")
vector_store = Weaviate(client, "DocumentChunk", embedding=embedder)
def embed_and_store(node_id: str, text: str):
"""將文字向量化後寫入 Weaviate,並在 metadata 中保存圖節點 ID"""
vector_store.add_texts(
texts=[text],
metadatas=[{"node_id": node_id}],
ids=[node_id] # 直接使用圖節點的 ID 作為向量 ID,方便對應
)
5️⃣ 完整的 GraphRAG 查詢流程
以下是一個 端到端 的範例,展示如何使用 GraphRetriever 先找出與問題相關的實體,再透過向量檢索取得段落,最後交給 LLM 產生答案。
from langchain.chains import GraphRAGChain
from langchain.llms import OpenAI
from langchain.prompts import PromptTemplate
from langchain.retrievers import GraphRetriever
# 1. 建立 GraphRetriever(Neo4j + Weaviate)
graph_retriever = GraphRetriever(
graph_store=Neo4jGraph(uri="bolt://localhost:7687", user="neo4j", password="pwd"),
vector_store=vector_store,
top_k=5, # 先取 5 個相關實體
vector_top_k=3 # 每個實體再向量檢索 3 個段落
)
# 2. 定義 Prompt(加入圖關係說明)
template = """
以下是與使用者問題相關的知識圖譜節點與文件段落,請根據它們給出完整且具備推理的答案。
問題:{question}
相關節點:
{graph_context}
檔案內容:
{retrieved_chunks}
答案:
"""
prompt = PromptTemplate.from_template(template)
# 3. 建立 GraphRAGChain
rag_chain = GraphRAGChain(
retriever=graph_retriever,
llm=OpenAI(model="gpt-4o-mini"),
prompt=prompt,
return_source_documents=True
)
# 4. 執行查詢
def ask(question: str):
result = rag_chain.invoke({"question": question})
print("🗨️ 答案:", result["output"])
print("\n--- 來源文件 ---")
for doc in result["source_documents"]:
print(f"- {doc.metadata['node_id']}: {doc.page_content[:120]}...")
# 範例問題
ask("台灣的 5G 網路建置時程與主要廠商有哪些?")
執行流程說明
GraphRetriever先在 Neo4j 中搜尋與「5G」、 「台灣」 相關的節點(如Technology,Company)。- 針對每個節點,利用 Weaviate 向量檢索取得最相似的文件段落。
PromptTemplate把「圖節點」與「檔案內容」組合成 Prompt,確保 LLM 能同時看到結構化關係與文字資訊。- LLM 產生答案,同時回傳每個來源段落,方便做可追溯性與驗證。
常見陷阱與最佳實踐
| 陷阱 | 說明 | 解決方案 |
|---|---|---|
| 圖與向量不同步 | 新增或更新文件後忘記同步到 Neo4j/Weaviate,導致檢索不到最新資訊。 | 建立 CI/CD 流程,使用事件驅動(如 Kafka)即時更新兩個資料庫。 |
| 節點嵌入維度不一致 | 不同模型產生的向量長度不同,會造成向量庫錯誤。 | 統一使用同一套嵌入模型,或在儲存前 pad/truncate 為固定長度。 |
| 關係過於稀疏 | 若圖中只有少量邊,圖搜尋的貢獻有限,變相成為純向量檢索。 | 在抽取階段加入 共現關係、語意相似度 作為輔助邊,提升圖的密度。 |
| Prompt 長度超限 | 圖節點與檢索結果過多,導致 Prompt 超過模型 token 限制。 | 使用 摘要 或 關鍵詞抽取,只保留最相關的 2~3 個節點與段落。 |
| 安全與隱私 | 知識圖譜可能包含敏感資訊,直接暴露給 LLM 會有洩漏風險。 | 在 Prompt 中 遮蔽 敏感欄位,或使用 私有 LLM(如 OpenAI 的 Azure OpenAI)部署於內部網路。 |
最佳實踐
- 分層檢索:先用圖搜尋縮小範圍,再用向量檢索取得文字細節,能顯著降低成本。
- 定期重訓嵌入:隨著語料庫成長,重新訓練或 fine‑tune 嵌入模型,以避免「向量漂移」。
- 加入置信度:在
GraphRAGChain輸出中加入每個來源的相似度分數,讓使用者可自行判斷答案可信度。 - 可視化檢查:利用 Neo4j Bloom 或 Graphistry 觀察圖結構,確保關係正確且沒有孤立節點。
實際應用場景
| 領域 | 典型案例 | GraphRAG 帶來的價值 |
|---|---|---|
| 企業內部知識庫 | 員工查詢產品規格、維運手冊 | 能跨文件、跨產品線自動關聯,減少重複問答 |
| 醫療健康 | 醫師查詢藥物相互作用、臨床指南 | 圖譜捕捉藥物‑疾病‑症狀的多層關係,提升診斷建議的精準度 |
| 法律合規 | 法律顧問檢索條文與案例判例 | 圖譜表現條文‑判例‑法官‑裁決的層次結構,讓 LLM 能提供具法理依據的說明 |
| 金融風控 | 分析公司關聯、交易網絡 | 圖譜揭露隱蔽的關聯公司或資金流向,向量檢索補足文字說明 |
| 教育平台 | 學生提問課程概念、歷史事件 | 透過圖譜呈現概念間的因果關係,讓回答更具說服力與可追溯性 |
總結
Knowledge Graph RAG(GraphRAG) 是在 LLM 時代提升問答品質的關鍵技術。透過 LangChain 的高階抽象,我們可以在幾行程式碼內完成:
- 圖資料庫建構(Neo4j / Weaviate Graph)
- 節點向量化(OpenAI Embeddings)
- 圖+向量雙重檢索(GraphRetriever)
- Prompt 組合與答案生成(GraphRAGChain)
在實務上,GraphRAG 能幫助企業將分散的文字資料轉化為 可推理的知識圖譜,同時保持向量檢索的語意彈性。只要注意 資料同步、Prompt 長度、隱私保護 等常見陷阱,並遵循最佳實踐,就能快速打造出具備 高精度、可追溯、跨領域推理 能力的智能問答系統。
快把本文的範例套用到自己的專案中,讓 LLM 不再只是一個「文字生成器」,而是 知識驅動的助理!祝開發順利 🚀。