RAG nâng cao 6 — GraphRAG: RAG trên tri thức có cấu trúc
Chỗ vector RAG bó tay
Các bài trước của series vá những lỗi cục bộ của RAG: chunk vụn, sót từ khoá, top-k nhiễu, câu mơ hồ (xem bản đồ RAG nâng cao). Nhưng còn một lớp câu hỏi mà dù bạn tinh chỉnh chunking, hybrid search hay reranking đến đâu, kiến trúc vector top-k phẳng vẫn không giải được. Có hai loại:
1. Câu hỏi tổng hợp toàn corpus (global). "Ba chủ đề rủi ro chính xuyên suốt toàn bộ báo cáo kiểm toán năm nay là gì?" "Tóm tắt các luận điểm chính trong toàn bộ hồ sơ tín dụng của nhóm khách hàng này." Không một chunk nào chứa sẵn đáp án. Đáp án nằm ở bức tranh gộp của hàng nghìn chunk. Vector search trả về top-k đoạn "giống câu hỏi nhất" — nhưng câu hỏi tổng hợp không giống bất kỳ đoạn cụ thể nào, nên top-k chỉ mang về vài mảnh rời rạc, bỏ sót phần lớn corpus.
2. Câu hỏi quan hệ nhiều bước (multi-hop). "Ông A liên quan tới công ty B qua những ai?" "Khoản vay này nối với tài khoản nhận tiền cuối cùng qua chuỗi trung gian nào?" Đáp án là một đường đi trong mạng lưới quan hệ. Mỗi bước quan hệ có thể nằm ở một tài liệu khác nhau. Vector search không có khái niệm "đi theo cạnh" — nó chỉ biết đo độ gần ngữ nghĩa, nên không lần được chuỗi A→X→Y→B.
Gốc rễ chung: vector RAG coi corpus là một túi chunk độc lập, không có cấu trúc liên kết giữa chúng. Câu hỏi tổng hợp cần thấy toàn cục; câu hỏi quan hệ cần đi theo liên kết. Cả hai đều đòi một thứ mà túi chunk không có: cấu trúc.
GraphRAG là gì
GraphRAG là hướng tiếp cận được Microsoft Research phổ biến năm 2024: thay vì (hoặc bên cạnh việc) đánh index chunk vào vector store, ta trích một knowledge graph (đồ thị tri thức — thực thể và quan hệ) từ tài liệu, rồi truy vấn trên đồ thị đó.
Ý tưởng cốt lõi gồm bốn bước offline (dựng index) và hai chế độ truy vấn online:
- Trích thực thể & quan hệ (entity/relationship extraction). Duyệt từng chunk, dùng LLM trích ra các thực thể (người, tổ chức, sản phẩm, điều khoản, tài khoản...) và quan hệ giữa chúng ("A sở hữu B", "điều 12 dẫn chiếu điều 5", "tài khoản X chuyển tiền cho Y").
- Xây graph. Gộp các thực thể trùng (entity resolution), nối các quan hệ thành đồ thị: nút là thực thể, cạnh là quan hệ. Đây chính là mô hình đồ thị thuộc tính (xem Đồ thị: tổng quan và mô hình dữ liệu đồ thị).
- Gom cụm cộng đồng (community detection). Chạy thuật toán phân cụm — phổ biến là Leiden (bản cải tiến của Louvain) — để chia đồ thị thành các cộng đồng: nhóm thực thể liên kết dày với nhau. Việc này có thể lặp phân cấp: cộng đồng lớn chứa cộng đồng con.
- Tóm tắt cộng đồng (community summary). Với mỗi cộng đồng, dùng LLM viết một bản tóm tắt: cộng đồng này nói về gì, các thực thể chính và quan hệ nổi bật. Đây là "bản tóm tắt theo chủ đề" mà corpus tự phân ra.
Khi truy vấn, GraphRAG dùng cấu trúc trên theo hai chế độ:
- Global search cho câu hỏi bao quát. Không đi tìm chunk. Thay vào đó, đưa các community summary cho LLM, mỗi cộng đồng sinh một câu trả lời bộ phận (map), rồi gộp lại thành đáp án cuối (reduce). Vì community summary phủ toàn bộ corpus, câu hỏi "chủ đề chính là gì" được trả lời từ bức tranh đầy đủ chứ không phải vài top-k.
- Local search cho câu hỏi quanh một (vài) thực thể. Định vị thực thể trong đồ thị, đi theo quan hệ ra các nút láng giềng, gom các thực thể/quan hệ/chunk gốc liên quan làm ngữ cảnh, rồi để LLM trả lời. Đây là cách lần chuỗi multi-hop "A liên quan B qua ai".
Phân biệt global vs local là điều quan trọng nhất cần nắm: global = "về toàn corpus, dùng community summary"; local = "quanh một điểm neo, đi theo cạnh". Chọn sai chế độ thì GraphRAG cũng trả lời tệ. Trong thực tế thường có bước routing phân loại câu hỏi để chọn chế độ (ý tưởng routing đã gặp ở query transformation).
Pipeline GraphRAG
Điểm mấu chốt của sơ đồ: toàn bộ chi phí LLM dồn vào cột trái (offline). Trích thực thể chạy LLM trên mỗi chunk; tóm tắt cộng đồng chạy LLM trên mỗi cộng đồng. Đổi lại, truy vấn online rẻ và nhanh vì đã có sẵn cấu trúc và bản tóm tắt.
Các thành phần chi tiết
Trích thực thể & quan hệ
Đây là khâu quyết định chất lượng đồ thị. Với mỗi chunk, prompt LLM trả về danh sách thực thể (kèm loại và mô tả ngắn) và quan hệ (chủ thể, đối tượng, loại quan hệ, mô tả). Ba lưu ý thực chiến:
- Định nghĩa loại thực thể theo miền. Ngân hàng nên khai báo rõ: KHÁCH_HÀNG, TÀI_KHOẢN, GIAO_DỊCH, SẢN_PHẨM, ĐIỀU_KHOẢN, PHÒNG_BAN... Thả tự do dễ ra đồ thị lộn xộn.
- Entity resolution (gộp trùng). "NCB", "Ngân hàng NCB", "Ngân hàng TMCP Quốc Dân" phải gộp về một nút. Đây là bài toán khó; sai thì đồ thị vỡ vụn thành nhiều nút cho cùng một thực thể.
- Gán trọng số/độ tin cậy cho cạnh khi cùng một quan hệ xuất hiện nhiều lần — phục vụ community detection và xếp hạng.
Xây graph và community detection
Sau khi có nút và cạnh, lưu vào graph database (điển hình là Neo4j, truy vấn bằng Cypher) hoặc biểu diễn đồ thị trong bộ nhớ. Community detection chia đồ thị thành cụm dày liên kết. Leiden được ưa dùng vì nhanh, ổn định và cho cụm chất lượng cao hơn Louvain (không sinh cụm rời rạc). Kết quả phân cấp cho phép trả lời global ở nhiều mức độ chi tiết: hỏi bao quát thì dùng cộng đồng mức cao, hỏi hẹp hơn thì xuống cộng đồng con.
Tóm tắt cộng đồng và truy vấn
Community summary là "đặc sản" của GraphRAG cho global search. Nó biến câu hỏi "tổng hợp 4.000 trang" thành "gộp vài chục bản tóm tắt cộng đồng" — vừa sức context của LLM. Cơ chế map-reduce: mỗi summary được hỏi độc lập (map, chạy song song), cho một câu trả lời bộ phận kèm điểm liên quan; bước reduce gộp các phần điểm cao thành đáp án cuối có dẫn nguồn.
Local search ngược lại: bắt đầu từ thực thể được nhắc trong câu hỏi, mở rộng ra hàng xóm trong đồ thị (1–2 hop), kéo về cả các chunk gốc gắn với những thực thể đó (đây là chỗ vector store vẫn hữu ích — để lấy chi tiết văn bản gốc), rồi tổng hợp trả lời.
Hybrid graph + vector
GraphRAG hiếm khi thay thế hoàn toàn vector RAG; hai bên bù nhau:
| Khía cạnh | Vector RAG | GraphRAG |
|---|---|---|
| Câu hỏi tra cứu chi tiết ("phí sản phẩm X là bao nhiêu") | Mạnh | Yếu (đồ thị không giữ mọi chi tiết) |
| Câu hỏi tổng hợp toàn corpus | Yếu | Mạnh (global search) |
| Câu hỏi quan hệ nhiều bước | Yếu | Mạnh (local search, đi theo cạnh) |
| Chi phí dựng index | Thấp | Cao (nhiều lời gọi LLM) |
| Độ trễ truy vấn | Thấp | Local thấp, global cao hơn (map-reduce) |
Kiến trúc hybrid thực dụng: giữ vector store cho tra cứu chi tiết và làm nguồn văn bản gốc; dựng knowledge graph cho câu hỏi tổng hợp và quan hệ; đặt một router phía trước phân loại câu hỏi để gọi đúng nhánh. Local search bản thân nó đã là hybrid — dùng đồ thị để định vị và mở rộng, dùng vector/chunk để lấy chi tiết.
Đánh đổi: sức mạnh đổi bằng chi phí index
GraphRAG không miễn phí. Đánh đổi cốt lõi cần cân nhắc trước khi quyết dùng:
- Chi phí index cao. Trích thực thể chạy LLM trên từng chunk; tóm tắt cộng đồng chạy LLM trên từng cộng đồng. Corpus lớn tốn hàng nghìn tới hàng chục nghìn lời gọi LLM để index một lần. Đây là khoản đắt nhất và là lý do chính khiến nhiều đội chần chừ.
- Chi phí cập nhật. Tài liệu đổi → phải trích lại, có thể phải chạy lại community detection và tóm tắt. Corpus biến động nhanh làm chi phí này lặp đi lặp lại.
- Chất lượng phụ thuộc khâu trích. Trích sai thực thể/quan hệ, gộp trùng kém → đồ thị nhiễu → câu trả lời sai một cách "có cấu trúc". Cần kiểm định đồ thị, không chỉ kiểm định câu trả lời.
Nguyên tắc chọn dùng: GraphRAG khi câu hỏi cần bức tranh toàn cục hoặc chuỗi quan hệ, và corpus đủ ổn định để khấu hao chi phí index. Với câu hỏi tra cứu chi tiết, một-nhảy, corpus biến động nhanh — vector RAG (hybrid + rerank) vẫn là lựa chọn rẻ và đủ tốt. Trong thực tế: làm vector RAG trước cho phần lớn câu hỏi, thêm GraphRAG cho lớp câu hỏi tổng hợp/quan hệ mà vector RAG chịu thua.
Công cụ
- Microsoft GraphRAG — thư viện OSS hiện thực đúng pipeline trên (trích → graph → Leiden → community summary → global/local search). Là điểm khởi đầu tốt để hiểu và thử nghiệm.
- Neo4j — graph database phổ biến để lưu và truy vấn đồ thị bằng Cypher; có tích hợp với LangChain/LlamaIndex và hỗ trợ vector index để làm hybrid.
- LlamaIndex / LangChain — đều có module xây và truy vấn knowledge graph (
KnowledgeGraphIndex, graph retriever...), tiện ghép vào pipeline RAG sẵn có.
Pseudocode minh hoạ
Đoạn dưới minh hoạ toàn bộ vòng đời GraphRAG — mã rút gọn để làm rõ ý, không phải API chạy được. Model minh hoạ là claude-opus-4-8.
# MINH HOẠ — pseudocode, không phải API thật
# ---------- OFFLINE: dựng index ----------
def build_graph_index(documents):
graph = Graph()
for doc in documents:
for chunk in chunk_document(doc):
# 1) LLM trích thực thể + quan hệ từ mỗi chunk (đắt!)
out = llm.extract(
model="claude-opus-4-8",
system="Trích thực thể (loại: KHACH_HANG, TAI_KHOAN, "
"GIAO_DICH, SAN_PHAM, DIEU_KHOAN) và quan hệ giữa chúng.",
text=chunk.text,
)
graph.add_entities(resolve(out.entities)) # gộp thực thể trùng
graph.add_relations(out.relations, source=chunk.id)
# 2) Gom cụm cộng đồng (phân cấp) — vd Leiden
communities = leiden(graph, resolution_levels=[0, 1, 2])
# 3) LLM tóm tắt từng cộng đồng (đắt!)
summaries = {}
for c in communities:
summaries[c.id] = llm.summarize(
model="claude-opus-4-8",
text=render(c.entities, c.relations),
)
return graph, communities, summaries
# ---------- ONLINE: truy vấn ----------
def answer(question, graph, communities, summaries):
if route(question) == "global":
# map: hỏi từng community summary song song
partials = [
llm.answer(model="claude-opus-4-8",
context=summaries[c.id], question=question)
for c in communities if relevant(c, question)
]
# reduce: gộp các phần điểm cao thành đáp án cuối
return llm.reduce(model="claude-opus-4-8", parts=partials,
question=question)
else: # local
seeds = link_entities(question, graph) # neo thực thể
subgraph = graph.expand(seeds, hops=2) # đi theo quan hệ
context = subgraph.entities + subgraph.relations \
+ fetch_source_chunks(subgraph) # lấy chi tiết gốc
return llm.answer(model="claude-opus-4-8",
context=context, question=question)
Ba ý cần rút ra: (1) chi phí LLM dồn hết vào build_graph_index; (2) global đi theo map-reduce trên community summary, local đi theo mở rộng đồ thị + chunk gốc; (3) router quyết định nhánh — sai router là sai chế độ.
Use case thực tế
Bối cảnh — NCB, hai bài toán mà vector RAG thua.
Bài toán 1 — mạng lưới sở hữu/giao dịch phục vụ điều tra AML. Bộ phận tuân thủ cần trả lời câu hỏi quan hệ: "Khách hàng bị cảnh báo này liên quan tới nhóm tài khoản đáng ngờ kia qua những trung gian nào?" Dữ liệu trải trên hồ sơ mở tài khoản, thông tin chủ sở hữu hưởng lợi, và log giao dịch. Vector RAG chỉ trả về từng mẩu rời — không lần được chuỗi quan hệ. GraphRAG dựng đồ thị: nút là khách hàng/tài khoản/pháp nhân, cạnh là "sở hữu", "đại diện", "chuyển tiền cho". Local search neo vào khách hàng bị cảnh báo, mở rộng 2–3 hop, làm lộ ra đường đi trung gian mà truy vấn phẳng không thấy. Đây là đầu vào cho quy trình điều tra rửa tiền (xem AML: tổng quan). Lưu ý: dùng cho gợi ý điều tra, luôn có cán bộ thẩm định; không tự động kết luận.
Bài toán 2 — tổng hợp toàn bộ quy định về một chủ đề. Câu hỏi kiểu "toàn bộ ràng buộc về hạn mức ngoại tệ đang nằm rải ở những quy định nào, tinh thần chung là gì?" là câu global. Kho quy định ~4.000 trang; vector top-k chỉ nhặt vài đoạn khớp từ khoá, bỏ sót các quy định nói cùng chủ đề bằng cách diễn đạt khác. GraphRAG gom các điều khoản liên quan vào cùng cộng đồng, community summary cho bức tranh gộp, global search map-reduce trả về câu tổng hợp có dẫn nguồn từ nhiều văn bản.
Ước lượng chi phí (minh hoạ, phải đo lại): index 4.000 trang ≈ vài nghìn chunk, mỗi chunk một lời gọi trích + vài trăm lời gọi tóm tắt cộng đồng → tốn đáng kể một lần; truy vấn sau đó rẻ. So với vector RAG (chỉ embed, gần như miễn phí LLM khi index), chi phí dựng cao hơn nhiều bậc. Kết luận vận hành: chỉ bật GraphRAG cho hai lớp câu hỏi trên; phần lớn câu tra cứu chi tiết vẫn đi qua vector RAG hybrid + rerank như bản đồ series đã dựng. Mọi con số ở đây là ước lượng minh hoạ cho một cấu hình cụ thể, không phải cam kết.
Ghi nhớ
- Vector RAG bó tay với hai lớp câu hỏi: tổng hợp toàn corpus (global) và quan hệ nhiều bước (local/multi-hop) — vì top-k phẳng coi corpus là túi chunk rời, không có cấu trúc.
- GraphRAG (Microsoft Research phổ biến 2024): LLM trích knowledge graph (thực thể + quan hệ) → community detection (Leiden) → LLM tóm tắt từng cộng đồng → truy vấn.
- Global search = map-reduce trên community summary, phủ toàn corpus, trả câu hỏi bao quát. Local search = neo vào thực thể, đi theo quan hệ, trả câu hỏi quanh một điểm. Router chọn chế độ.
- Đánh đổi lớn nhất là chi phí index: trích thực thể chạy LLM trên từng chunk, tóm tắt chạy LLM trên từng cộng đồng — đắt và lặp lại khi corpus đổi. Truy vấn online thì rẻ.
- Hybrid graph + vector là thực dụng: vector cho tra cứu chi tiết và văn bản gốc, graph cho tổng hợp và quan hệ; local search vốn đã dùng cả hai.
- Khi nào dùng: câu hỏi cần bức tranh toàn cục hoặc chuỗi quan hệ, corpus đủ ổn định. Câu tra cứu chi tiết, corpus biến động nhanh → vector RAG rẻ hơn và đủ.
- Công cụ: Microsoft GraphRAG (OSS), Neo4j (Cypher, có vector index), LlamaIndex/LangChain knowledge graph. Nền tảng đồ thị xem tổng quan và mô hình dữ liệu.
- Chất lượng phụ thuộc khâu trích và gộp trùng thực thể — kiểm định cả đồ thị, không chỉ câu trả lời. Bước tiếp theo là để agent tự điều phối truy vấn: Agentic RAG.
Nguồn tham khảo
- Edge et al. (2024), "From Local to Global: A Graph RAG Approach to Query-Focused Summarization" — arXiv:2404.16130 (paper gốc của Microsoft Research)
- Microsoft GraphRAG — tài liệu và mã nguồn chính thức: microsoft.github.io/graphrag và github.com/microsoft/graphrag
- Traag, Waltman, van Eck (2019), "From Louvain to Leiden: guaranteeing well-connected communities", Scientific Reports — arXiv:1810.08473 (thuật toán Leiden)
- Neo4j GraphRAG — neo4j.com/docs/neo4j-graphrag-python và tài liệu Cypher trong Neo4j Documentation
- LlamaIndex — Knowledge Graph Index / Property Graph documentation (docs.llamaindex.ai)
- LangChain — Graph / Knowledge Graph documentation (python.langchain.com)
Bài viết liên quan
Đặt nền cho chuỗi AI: phân biệt ba vòng tròn lồng nhau AI ⊃ ML ⊃ DL và khác biệt bản chất giữa lập trình truyền thống với học từ dữ liệu. Giới thiệu ba kiểu học máy (supervised, unsupervised, reinforcement), phân loại descriptive/predictive/prescriptive, quy trình ML end-to-end, chia train/validation/test, overfitting/underfitting và các thuật ngữ nền tảng, gắn với ứng dụng ngân hàng NCB.
Harness — lớp scaffolding quanh model (vòng lặp, tool, context, memory, verify, sub-agent) — mới là thứ quyết định agent chạy được hay chỉ là demo. Bài này mổ xẻ giải phẫu một harness, 7 kỹ năng cốt lõi khi xây agent, single vs multi-agent (kèm số liệu hiệu quả/chi phí), các repo nên dùng, và một quickstart Python dựng-là-chạy cho bối cảnh ngân hàng.
Hiểu LLM từ gốc: bản chất dự đoán token, ba giai đoạn huấn luyện (pretraining, fine-tuning, RLHF), token, context window và các tham số sinh (temperature, top-p). Nắm hiện tượng hallucination và kỹ thuật prompt engineering (vai trò, few-shot, chain-of-thought, ràng buộc đầu ra), kèm ví dụ gọi API model Claude mới nhất với adaptive thinking.
Vì sao dữ liệu quyết định chất lượng mô hình hơn cả thuật toán. Bài này đi qua toàn bộ pipeline chuẩn bị dữ liệu: phân loại dữ liệu, làm sạch (thiếu/ngoại lai/trùng lặp), mã hoá hạng mục, scaling, feature engineering, giảm chiều, và cách phòng data leakage — soi qua bài toán chấm điểm tín dụng.
Cảm nhận của bạn
Bình luận
Chưa có bình luận. Hãy là người đầu tiên chia sẻ!