GraphRAG 技能
基於知識圖譜而非平面區塊的檢索增強生成。從您的文件中提取實體與關係,儲存於圖資料庫,LLM 在查詢時根據圖結構進行推理。
為什麼是圖而非向量
向量搜尋找到的是相似區塊。它無法追蹤關聯:
- 「哪些供應商受到 X 工廠停電的影響?」需要
Outage → affects → Plant → supplied_by → Supplier— 需要兩跳,單一區塊無法包含。 - 「總結我們所知關於專案 Y 的一切」需要圍繞 Y 的社群,而非十個最相似的段落。
如果您的問題是單一事實查詢,請堅持使用向量 RAG — 它更簡單。當問題跨越關係時,才考慮 GraphRAG。
技術棧
- Kuzu — 嵌入式圖資料庫(
pip install kuzu),無需執行伺服器,Cypher 查詢語言。從這裡開始。 - Neo4j — 當嵌入式無法滿足需求時:多用戶、更大圖形、Bloom 視覺化。相同的 Cypher 技能可延用。
- LLM 提取 — 任何具有結構化輸出能力的強大模型,用於實體/關係提取。
流程
1. 先定義模式
不要讓提取器隨意發明類型 — 否則你會得到 40 種同一關係的不同寫法。事先宣告節點與邊的類型:
CREATE NODE TABLE Person(name STRING, PRIMARY KEY(name));
CREATE NODE TABLE Project(name STRING, status STRING, PRIMARY KEY(name));
CREATE NODE TABLE Document(title STRING, date DATE, PRIMARY KEY(title));
CREATE REL TABLE WORKS_ON(FROM Person TO Project, role STRING);
CREATE REL TABLE MENTIONS(FROM Document TO Person);
CREATE REL TABLE MENTIONS_PROJECT(FROM Document TO Project);
保持模式簡潔(5-10 種節點類型)。你可以擴展它,但無法輕鬆清理一個混亂的圖。
2. 提取實體與關係
將文件分塊(500-1000 個 token,重疊),然後提示提取器:
從以下文字中提取實體與關係。
允許的節點類型:Person, Project, Document
允許的邊類型:WORKS_ON (Person→Project), MENTIONS (Document→Person),
MENTIONS_PROJECT (Document→Project)
規則:
- 正規化名稱(「J. Smith」和「John Smith」視為同一 Person)
- 僅提取文字中明確陳述或清楚暗示的關係
- 回傳 JSON:{"nodes": [...], "edges": [...]}
文字:
<chunk>
手動抽查 10-20 個區塊。提取品質是下游所有應用的天花板 — 嘈雜的圖會給出嘈雜的答案。
3. 載入 Kuzu
import kuzu
db = kuzu.Database("./knowledge.kz")
conn = kuzu.Connection(db)
# 建立模式,然後為每個提取的節點/邊進行參數化 MERGE/CREATE
載入時去重(對主鍵使用 MERGE)— 同一實體會出現在許多區塊中。
4. 查詢模式
局部查詢 — 與某實體相關的一切:
MATCH (p:Person {name: $name})-[r]-(neighbor)
RETURN type(r), neighbor;
多跳躍推理 — 沿著圖中的關係追蹤:
// 哪些人參與了文件中提及的關於停電的專案?
MATCH (d:Document)-[:MENTIONS_PROJECT]->(proj:Project)<-[:WORKS_ON]-(p:Person)
WHERE d.title CONTAINS 'outage'
RETURN DISTINCT p.name, proj.name;
全局總結 — 社群檢測,然後總結每個社群:
// 找到密集連接的集群(執行一次,將社群 ID 儲存在節點上)
CALL show_tables(); // 然後使用圖的社群檢測
用 LLM 總結每個社群:「這些實體圍繞著主題 X 聚集。」這是 GraphRAG 的「全域查詢」— 問題如「這些文件的主要主題是什麼?」
5. 用 LLM 回答
有效的查詢模式:
- 代理將問題轉譯為 1-3 個 Cypher 查詢
- 結果以結構化行回傳
- LLM 根據行合成答案,引用節點/邊證據
- 如果查詢沒有回傳結果,代理重新組織問題 — 絕不幻構圖內容
時態知識(代理記憶)
對於跨會話的代理記憶,為邊加上時間:VALID_FROM / VALID_TO 時間戳,將被取代的事實標記而非刪除。這是時態知識圖譜模式(參見 Graphiti/Zep):「使用者過去偏好 X,現在偏好 Y」保持可查詢,而不是被覆蓋。
反模式
- 無模式提取。 自由形式提取會產生沒人能查詢的圖。
- 什麼都用 GraphRAG。 在乾淨文件上進行單一事實查詢?向量搜尋更便宜且效果更好。只在關係重要處使用圖。
- 盲目信任提取。 每個流程都需要抽查迴圈;提取錯誤會默默累積。
- 超大區塊。 超過 ~1000 個 token 時實體提取品質會下降 — 模型開始遺漏關係。使用較小區塊,更多數量。
- 載入時不進行去重。 「John Smith」、「J. Smith」、「Smith」三個節點會默默破壞多跳躍查詢。