راستش را بخواهید، تا یکی دو سال پیش، هر وقت کسی میگفت RAG، ذهن همه ما مستقیم میرفت سراغ embedding برداری و pgvector و قس علی هذا. سیستمهای Vector RAG در پاسخ به پرسشهای مفهومی و یافتن تکههای متنی مشابه عملکرد خوبی دارند، اما خب، وقتی پای پرسشهای چندمرحلهای (Multi-hop)، روابط ساختاریافته بین موجودیتها یا تحلیلهای گسترده روی کل سند به میان میآید، کم میآورند. اینجاست که GraphRAG وارد میدان میشود؛ رویکردی که با ترکیب گراف دانش (Knowledge Graph) و مدلهای زبانی بزرگ، روابط بین موجودیتها را بهجای صرفاً شباهت معنایی، در فرآیند بازیابی دخیل میکند.
عددی که شخصاً مرا قانع کرد به این رویکرد جدی نگاه کنم، بنچمارک KG-LM شرکت Diffbot بود: GraphRAG بهطور میانگین ۳.۴ برابر دقیقتر از Vector RAG عمل میکند، و در پرسشهای ساختاریافتهای مثل KPIها و پیشبینیهای مالی — جایی که Vector RAG امتیاز ۰٪ میگیرد (بله، صفر مطلق) — GraphRAG هنوز عملکرد قابل قبولی دارد. در این راهنمای جامع ۲۰۲۶، میخواهیم معماری GraphRAG، تفاوت آن با Vector RAG، مقایسه سه فریمورک پیشرو (Microsoft GraphRAG، LightRAG و Neo4j) و یک پیادهسازی عملی با Python را با هم مرور کنیم.
GraphRAG چیست و چرا اهمیت دارد؟
GraphRAG (Graph Retrieval-Augmented Generation) یک رویکرد پیشرفته در RAG است که بهجای تکیه صرف بر embedding برداری، اسناد را بهصورت گراف دانش از موجودیتها (افراد، سازمانها، مفاهیم، رویدادها) و روابط بین آنها مدلسازی میکند. این ساختار به مدل اجازه میدهد روی اطلاعات بههممتصل، استدلال رابطهای انجام دهد — کاری که Vector RAG ذاتاً برایش ساخته نشده.
خلاصه مزایای کلیدی نسبت به Vector RAG
- استدلال چندمرحلهای: پاسخ به پرسشهایی مانند «کدام مشتریان آلمانی از محصولی استفاده میکنند که شرکت تأمینکننده آن سال گذشته توسط ما تملک شده است؟» (تلاش کنید این را با Vector RAG حل کنید!)
- کاهش توهمزایی (Hallucination): چون پاسخ بر پایه روابط تعریفشده در گراف بنا میشود، نه شباهت تقریبی.
- قابلیت توضیحپذیری بالاتر: هر پاسخ را میتوان به مسیر مشخصی در گراف نسبت داد — مهم برای حوزههایی مثل حقوق و پزشکی.
- تحلیل سراسری (Global Reasoning): پاسخ به پرسشهایی که نیازمند درک کل کورپوس هستند، نه فقط چند تکه متن.
معماری GraphRAG: از متن خام تا پاسخ نهایی
یک سیستم GraphRAG معمولی از سه مرحله اصلی تشکیل میشود. بیایید قدمبهقدم جلو برویم.
۱. ساخت گراف (Indexing)
- تکهسازی متن: اسناد به قطعات کوچکتر (Chunk) تقسیم میشوند.
- استخراج موجودیتها و روابط: یک LLM روی هر تکه فراخوانی میشود تا موجودیتها (Node) و روابط (Edge) را بهصورت ساختاریافته استخراج کند.
- تشکیل گراف دانش: موجودیتهای همنام ادغام (Entity Resolution) و در یک گراف ذخیره میشوند.
- تشخیص اجتماع (Community Detection): الگوریتمهایی مانند Leiden برای کشف خوشههای موضوعی استفاده میشوند.
- خلاصهسازی سلسلهمراتبی: برای هر اجتماع، یک خلاصه تولید میشود تا در پرسشهای سراسری استفاده شود.
نکتهای که من معمولاً به تیمها یادآوری میکنم: همین مرحله ۲ میتواند هزینه شما را منفجر کند. دربارهاش باز هم صحبت میکنیم.
۲. بازیابی (Retrieval)
دو حالت اصلی بازیابی در GraphRAG وجود دارد:
- Local Search: ابتدا با شباهت برداری موجودیتهای مرتبط شناسایی میشوند، سپس همسایگان آنها در گراف پیمایش میشود. مناسب پرسشهای موضعی.
- Global Search: از خلاصههای اجتماعها (در سطوح سلسلهمراتبی مختلف) برای پاسخ به پرسشهای گسترده استفاده میشود.
۳. تولید (Generation)
زیرگراف بازیابیشده بههمراه پرسش به LLM ارسال میشود تا پاسخ نهایی تولید شود. در رویکرد Text2Cypher، LLM ابتدا پرسش طبیعی را به یک کوئری Cypher تبدیل میکند، آن را روی Neo4j اجرا میکند و سپس از نتیجه برای تولید پاسخ بهره میبرد. این الگو، اگر درست پیاده شود، شفافیت فوقالعادهای به سیستم میدهد چون میتوانید عین کوئری اجراشده را لاگ کنید.
GraphRAG در برابر Vector RAG: چه زمانی کدام را انتخاب کنیم؟
| ویژگی |
Vector RAG |
GraphRAG |
| نوع داده | متن غیرساختاریافته | روابط ساختاریافته |
| روش بازیابی | شباهت معنایی (Cosine) | پیمایش گراف + Cypher |
| استدلال | سطحی، تکتکه | چندمرحلهای، رابطهای |
| هزینه ساخت ایندکس | پایین | ۱۰۰ تا ۱۰۰۰ برابر بیشتر |
| توضیحپذیری | ضعیف | قوی (مسیر قابل ردیابی) |
| مناسب برای | پرسشهای مفهومی، چتبات عمومی | تحلیل مالی، کشف تقلب، حقوق، پزشکی |
یک قانون سرانگشتی ساده: اگر پرسش شما با عبارت «X و Y چه شباهتی دارند؟» شروع میشود، Vector RAG کافی است. اما اگر با «X چگونه به Y متصل است؟» یا «همه مسیرهای بین X تا Z چیست؟» شروع میشود، به GraphRAG نیاز دارید. ساده، ولی به طرز عجیبی همیشه جواب میدهد.
سه فریمورک پیشرو در ۲۰۲۶: Microsoft GraphRAG، LightRAG و Neo4j
Microsoft GraphRAG
پروژه متنباز مایکروسافت که با الگوریتم Leiden برای تشخیص اجتماع و خلاصهسازی سلسلهمراتبی، در پرسشهای تحلیلی گسترده عملکرد فوقالعادهای دارد. ضعف اصلیاش هم؟ هزینه بالای ایندکسگذاری؛ چون برای هر تکه متن چندین فراخوانی LLM لازم است. خبر خوب اینکه نسخه LazyGraphRAG معرفیشده در مایکروسافت ریسرچ، این هزینه را تا ۰.۱٪ نسخه اصلی کاهش میدهد — بله، یکهزارم.
LightRAG
پروژهای از HKUDS (پذیرفتهشده در EMNLP 2025) که با سیستم بازیابی دو سطحی (Low-level برای موجودیتها، High-level برای مفاهیم) به ۷۰ تا ۹۰ درصد کیفیت Microsoft GraphRAG با تنها ۱٪ هزینه آن میرسد. در مارس ۲۰۲۶، پشتیبانی از OpenSearch بهعنوان بکاند یکپارچه و ویزارد راهاندازی محلی با Docker اضافه شد. به نظر شخصی من، شروع کار با همین گزینه برای اکثر تیمها منطقیتر است.
Neo4j + LangChain (Graphiti)
ترکیب پایگاهداده گرافی Neo4j با LangChain یا پکیج رسمی neo4j-graphrag-python راهحل سطح-سازمانی است. Neo4j Graphiti بهطور بومی از بازیابی هیبریدی (گراف + بردار) پشتیبانی میکند و برای محیطهای تولید با نیاز به مقیاسپذیری بالا و حاکمیت داده مناسب است.
جدول مقایسهای
| معیار |
Microsoft GraphRAG |
LightRAG |
Neo4j GraphRAG |
| هزینه ایندکس | بسیار بالا | ~۱٪ از GraphRAG | متغیر (زیرساخت) |
| کیفیت پاسخ | بالاترین (تحلیلی) | ۷۰-۹۰٪ از GraphRAG | بالا با تنظیم |
| سرعت ایندکس | کند | سریع | سریع |
| بهترین کاربرد | تحلیل سراسری | پرسشهای دامنهخاص | محیط تولید سازمانی |
| پشتیبانی هیبریدی | از طریق Neo4j | بومی | بومی |
پیادهسازی عملی GraphRAG با Python و Neo4j
خب، حرف کافی است؛ بیایید کد بزنیم. در این بخش، یک پایپلاین کامل GraphRAG را با استفاده از neo4j-graphrag-python و LangChain میسازیم.
گام ۱: نصب وابستگیها
uv pip install \
neo4j-graphrag==1.6.0 \
langchain==0.3.7 \
langchain-community==0.3.7 \
langchain-openai==0.2.6 \
langchain-experimental==0.3.4 \
neo4j==5.24.0 \
python-dotenv==1.0.1
برای اجرای محلی Neo4j از Docker استفاده کنید (یک خط، تمام):
docker run -d \
--name neo4j-graphrag \
-p 7474:7474 -p 7687:7687 \
-e NEO4J_AUTH=neo4j/strongpassword \
-e NEO4J_PLUGINS='["apoc"]' \
neo4j:5.24
گام ۲: ساخت گراف از اسناد
import os
from dotenv import load_dotenv
from neo4j import GraphDatabase
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langchain_experimental.graph_transformers import LLMGraphTransformer
from langchain_community.document_loaders import PyPDFLoader
from langchain_neo4j import Neo4jGraph
load_dotenv()
graph = Neo4jGraph(
url=os.environ["NEO4J_URI"],
username=os.environ["NEO4J_USERNAME"],
password=os.environ["NEO4J_PASSWORD"],
)
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
transformer = LLMGraphTransformer(
llm=llm,
allowed_nodes=["Person", "Organization", "Product", "Location"],
allowed_relationships=["WORKS_AT", "FOUNDED", "LOCATED_IN", "PRODUCES"],
)
docs = PyPDFLoader("company_report.pdf").load()
graph_docs = transformer.convert_to_graph_documents(docs)
graph.add_graph_documents(
graph_docs,
baseEntityLabel=True,
include_source=True,
)
یک نکته که خیلیها در اولین تجربه نادیده میگیرند: پارامتر allowed_nodes و allowed_relationships بهشدت کیفیت گراف را افزایش میدهد و از تولید نودهای بیربط جلوگیری میکند. اگر این را خالی بگذارید، LLM همه چیز را به نود تبدیل میکند — حتی صفتها — و گراف شما به یک کلاف سردرگم تبدیل میشود.
گام ۳: بازیابی با Text2Cypher
from langchain_neo4j import GraphCypherQAChain
cypher_chain = GraphCypherQAChain.from_llm(
cypher_llm=ChatOpenAI(model="gpt-4o", temperature=0),
qa_llm=ChatOpenAI(model="gpt-4o-mini", temperature=0),
graph=graph,
verbose=True,
validate_cypher=True,
return_intermediate_steps=True,
allow_dangerous_requests=True,
)
result = cypher_chain.invoke({
"query": "کدام محصولات توسط شرکتهای مستقر در آلمان تولید میشوند؟"
})
print(result["result"])
گام ۴: بازیابی هیبریدی (گراف + بردار)
قدرت واقعی GraphRAG وقتی آشکار میشود که آن را با جستجوی برداری ترکیب کنید. در عمل، تقریباً همه پروژههای موفقی که دیدهام، از همین الگوی هیبریدی استفاده میکنند:
from neo4j_graphrag.retrievers import HybridRetriever
from neo4j_graphrag.generation import GraphRAG
from neo4j_graphrag.llm import OpenAILLM
from neo4j_graphrag.embeddings import OpenAIEmbeddings as NGEmbeddings
driver = GraphDatabase.driver(
os.environ["NEO4J_URI"],
auth=(os.environ["NEO4J_USERNAME"], os.environ["NEO4J_PASSWORD"]),
)
retriever = HybridRetriever(
driver=driver,
vector_index_name="document_embeddings",
fulltext_index_name="document_fulltext",
embedder=NGEmbeddings(model="text-embedding-3-large"),
return_properties=["text", "source"],
)
rag = GraphRAG(
retriever=retriever,
llm=OpenAILLM(model_name="gpt-4o", model_params={"temperature": 0}),
)
response = rag.search(
query_text="رابطه بین برند X و شرکت مادر آن چیست؟",
retriever_config={"top_k": 8},
)
print(response.answer)
گام ۵: روتینگ هوشمند پرسش
الگوی توصیهشده در ۲۰۲۶ این است که پرسشهای ساده را به Vector RAG و پرسشهای پیچیده چندمرحلهای را به GraphRAG ارجاع دهید. خبر خوب این است که این روتر فقط چند خط کد است:
from langchain_core.prompts import ChatPromptTemplate
router_prompt = ChatPromptTemplate.from_template("""
پرسش زیر را در یکی از این دو دسته طبقهبندی کن:
- "vector": پرسشهای مفهومی، تعریفی، یا جستجوی شباهت معنایی
- "graph": پرسشهای چندمرحلهای، رابطهای، تجمیعی یا مقایسهای
پرسش: {question}
خروجی فقط یکی از دو کلمه vector یا graph باشد.
""")
router_chain = router_prompt | llm
def smart_rag(question: str) -> str:
route = router_chain.invoke({"question": question}).content.strip().lower()
if route == "graph":
return cypher_chain.invoke({"query": question})["result"]
return rag.search(query_text=question).answer
چالشها و بهترین شیوهها در محیط تولید
۱. حل تعارض موجودیتها (Entity Resolution)
«Microsoft Corp»، «Microsoft» و «MSFT» باید به یک نود نگاشت شوند. این نکته به ظاهر کوچک، در عمل بزرگترین قاتل کیفیت گراف است. از تطبیق فازی (مانند RapidFuzz) همراه با تأیید LLM استفاده کنید تا هم سرعت داشته باشید و هم دقت.
۲. بهروزرسانی تدریجی گراف
هر تغییر در سند، نیازمند استخراج مجدد موجودیت، آشتی با گراف موجود، و بازاجرای الگوریتم تشخیص اجتماع است. Mem0 و Graphiti برای حافظه عامل که نیازمند بهروزرسانی پیوسته است، گزینه بهتری از Microsoft GraphRAG هستند.
۳. کنترل هزینه LLM
- از مدلهای کوچکتر مانند
gpt-4o-mini یا claude-haiku-4-5 برای استخراج موجودیت استفاده کنید.
- پردازش دستهای (Batch) برای کاهش سربار درخواستها به کار ببرید.
- اگر تعداد اسناد بالاست، به LazyGraphRAG یا LightRAG مهاجرت کنید — قبل از اینکه صورتحساب OpenAI شما را شوکه کند.
۴. ارزیابی کیفیت
برای ارزیابی، از مجموعه پرسش-پاسخ نشانهگذاریشده استفاده کنید و معیارهای NDCG، MRR و دقت پاسخ نهایی (با LLM-as-Judge) را اندازه بگیرید. ابزارهایی مانند Ragas و DeepEval از ارزیابی GraphRAG پشتیبانی میکنند.
موارد استفاده در دنیای واقعی
- کشف تقلب مالی: شناسایی مسیرهای تراکنش پنهان بین حسابها
- تحلیل زنجیره تأمین: ردیابی وابستگیهای چندسطحی تأمینکنندگان
- اکتشاف دارو: یافتن روابط بین ژنها، پروتئینها و بیماریها
- سیستمهای توصیهگر پیشرفته: ترکیب رفتار کاربر با گراف محصول
- دستیار حقوقی: ردیابی استنادهای متقابل بین قوانین و آرای قضایی
- تحلیل کدبیس: پاسخ به پرسشهایی مانند «اگر این تابع را تغییر دهم، چه ماژولهایی تحت تأثیر قرار میگیرند؟» (که، صادقانه بگویم، یکی از مفیدترین کاربردهایی است که در یک تیم بزرگ تجربه کردهام)
سؤالات متداول (FAQ)
چه زمانی نباید از GraphRAG استفاده کرد؟
اگر داده شما فاقد ساختار رابطهای است (مثلاً مجموعهای از مقالات بلاگ یا چتلاگهای عمومی)، یا اگر پرسشها صرفاً شباهت معنایی میخواهند، Vector RAG سادهتر، ارزانتر و کافی است. همچنین اگر بودجه LLM محدود است و حجم اسناد بالاست، ابتدا Hybrid Search + Reranking را امتحان کنید. در بسیاری از موارد، همین کار جواب میدهد.
تفاوت GraphRAG با Knowledge Graph سنتی چیست؟
گراف دانش سنتی توسط متخصص دامنه بهصورت دستی یا نیمهخودکار با کوئریهای SQL/SPARQL ساخته میشد. GraphRAG از LLM برای استخراج خودکار موجودیتها و روابط از متن غیرساختاریافته استفاده میکند و در زمان پرسش، LLM دوباره برای تفسیر زیرگراف بازیابیشده به کار گرفته میشود. این یعنی LLM هم در ساخت و هم در مصرف گراف نقشآفرین است.
آیا میتوان GraphRAG را روی مدلهای متنباز اجرا کرد؟
بله. LightRAG و Neo4j GraphRAG با مدلهایی مانند Llama 3.1 70B، Qwen 2.5 و Mistral Large از طریق Ollama یا vLLM سازگار هستند. اما توقع نداشته باشید کیفیت یکسان باشد — کیفیت استخراج موجودیت روی مدلهای زیر ۷۰ میلیارد پارامتر معمولاً افت محسوسی دارد و تنظیم پرامپت دقیقتری میخواهد.
هزینه ساخت GraphRAG برای یک کورپوس ۱۰۰۰ سندی چقدر است؟
با gpt-4o-mini و میانگین ۵ صفحه در هر سند، هزینه استخراج موجودیتها در Microsoft GraphRAG حدود ۱۵-۳۰ دلار، در LightRAG حدود ۰.۵-۲ دلار، و در LazyGraphRAG کمتر از ۰.۲ دلار است. این برآورد شامل ذخیرهسازی Neo4j نمیشود.
آیا GraphRAG میتواند جایگزین کامل Vector RAG شود؟
خیر، و توصیه هم نمیشود. تجربه ۲۰۲۶ نشان داده که معماری هیبریدی بهترین نتیجه را میدهد: Vector RAG برای یافتن سریع تکههای مرتبط، و GraphRAG برای پاسخ به پرسشهای رابطهای. روتر هوشمند پرسش (مانند نمونه کد بالا) به شما اجازه میدهد بسته به نوع پرسش، مسیر مناسب را انتخاب کنید.
جمعبندی
GraphRAG در ۲۰۲۶ از یک تکنیک تجربی به ابزار تولیدی تبدیل شده است. اگر داده شما روابط ساختاریافته دارد و پرسشها چندمرحلهای هستند، GraphRAG بهطور قابل توجهی دقت و توضیحپذیری را افزایش میدهد. برای شروع، LightRAG را امتحان کنید؛ اگر به مقیاسپذیری سازمانی و حاکمیت داده نیاز دارید، به Neo4j GraphRAG مهاجرت کنید؛ و فقط در صورتی به Microsoft GraphRAG بروید که بنچمارکهای شما نشان دهد افزایش کیفیت، توجیهگر هزینه چندبرابری آن است.
گام بعدی؟ یک کورپوس کوچک از حوزه کاری خود انتخاب کنید، با نمونه کدهای بالا شروع کنید و مجموعهای ۲۰-۳۰ پرسشی برای ارزیابی بسازید. تنها با اندازهگیری میتوانید تشخیص دهید که آیا GraphRAG برای شما ارزش هزینه را دارد یا نه — و معمولاً همین کورپوس کوچک، تصمیم نهایی را برایتان روشن میکند.