LangGraph状态机工程:构建复杂AI工作流的完整指南 传统RAG检索增强生成在处理简单的单跳问题时表现良好——“文章里提到了什么” “这个概念是什么意思”——但当问题涉及多个实体之间的关系、需要跨多个文档推理时传统RAG就显得力不从心。GraphRAGGraph-based Retrieval Augmented Generation通过将知识图谱与LLM结合为这类复杂查询提供了更强大的解决方案。本文从原理到落地系统介绍GraphRAG的工程实践。为什么需要GraphRAG先来看传统RAG的核心局限。场景一多跳推理问题“A公司的CEO在哪所大学的同学后来创立了什么公司“传统RAG单次向量检索找到A公司CEO毕业于X大学”找到B公司创始人也毕业于X大学”但无法建立两者之间的同学关系更无法回答B公司创始人创立了什么其他公司这个需要多步推理的问题。GraphRAG知识图谱中有[CEO]→[毕业于]→[X大学]←[就读于]←[B创始人]的路径通过图遍历可以直接找到相关信息。场景二实体关系聚合问题列出所有与GPT-4技术相关的论文作者以及他们各自的研究领域传统RAG会返回若干文档片段但无法系统地聚合所有相关作者的信息容易遗漏。GraphRAG以GPT-4为起点通过作者关系遍历所有相关节点系统化地返回完整信息。场景三社区摘要与宏观视角问题AI安全领域的主要研究机构有哪些它们之间有什么关联这类问题需要鸟瞰视角传统RAG难以提供跨文档的系统性总结而GraphRAG的社区检测功能天然支持这类全局性查询。## GraphRAG的核心架构GraphRAG尤其是Microsoft开源版本的处理流程分为两个阶段### 索引阶段离线构建原始文档 ↓ 文本分块文本片段 ↓ 实体提取LLM实体关系列表 ↓ 实体去重与合并知识图谱 ↓ 社区检测Leiden算法层次化社区结构 ↓ 社区摘要生成LLM社区摘要实体提取是索引阶段的核心。GraphRAG使用LLM从文本中识别实体人、组织、事件、概念等和关系pythonENTITY_EXTRACTION_PROMPT 从以下文本中提取所有实体和它们之间的关系。文本{input_text}输出格式JSON{ entities: [ {name: 实体名称, type: PERSON/ORGANIZATION/CONCEPT/EVENT, description: 简短描述} ], relationships: [ {source: 实体A, target: 实体B, type: 关系类型, description: 关系描述} ]}注意- 只提取文本中明确提到的实体和关系- 关系类型应简洁明了如WORKS_FOR, FOUNDED, COLLABORATED_WITH等- 每个实体的描述不超过50字### 查询阶段GraphRAG提供两种查询模式Local Search局部搜索适合具体问题- 先找到与查询最相关的实体- 然后提取这些实体的邻居子图- 将子图信息和原始文本片段一起送给LLM生成答案Global Search全局搜索适合宏观问题- 利用预计算的社区摘要- 在各社区摘要上并行生成答案- 聚合多个社区的答案生成最终回复## 使用Microsoft GraphRAG快速上手bash# 安装pip install graphrag# 初始化项目mkdir graphrag-democd graphrag-demopython -m graphrag.index --init --root .# 准备文档放入input目录mkdir -p input# 将你的.txt文件放入input目录# 配置编辑settings.yaml# 主要配置LLM API、嵌入模型、语言关键配置文件settings.yamlyamlencoding_model: cl100k_baseskip_workflows: []llm: api_key: ${GRAPHRAG_API_KEY} type: openai_chat model: gpt-4o-mini # 推荐用mini降低成本 model_supports_json: true max_tokens: 4000 temperature: 0embeddings: async_mode: threaded llm: api_key: ${GRAPHRAG_API_KEY} type: openai_embedding model: text-embedding-3-small # 成本效益最优chunks: size: 300 overlap: 100 group_by_columns: [id]input: type: file file_type: text base_dir: input# 实体提取配置entity_extraction: max_gleanings: 1 # 提取轮次1轮已足够大多数场景# 社区报告配置community_reports: max_length: 2000 max_input_length: 8000构建索引bash# 构建知识图谱索引耗时操作取决于文档量和模型速度python -m graphrag.index --root .查询pythonimport asynciofrom graphrag.query.context_builder.entity_extraction import EntityVectorStoreKeyfrom graphrag.query.indexer_adapters import ( read_indexer_entities, read_indexer_relationships, read_indexer_reports, read_indexer_text_units)from graphrag.query.structured_search.local_search.mixed_context import LocalSearchMixedContextfrom graphrag.query.structured_search.local_search.search import LocalSearchfrom graphrag.query.llm.oai.chat_openai import ChatOpenAIfrom graphrag.query.llm.oai.embedding import OpenAIEmbedding# 加载索引数据INPUT_DIR ./output/artifactsCOMMUNITY_LEVEL 2 # 社区层级越高越宏观entities read_indexer_entities(INPUT_DIR, COMMUNITY_LEVEL)relationships read_indexer_relationships(INPUT_DIR)text_units read_indexer_text_units(INPUT_DIR)reports read_indexer_reports(INPUT_DIR, COMMUNITY_LEVEL)# 初始化本地搜索llm ChatOpenAI(api_keyyour_api_key, modelgpt-4o)embedding OpenAIEmbedding(api_keyyour_api_key, modeltext-embedding-3-small)context_builder LocalSearchMixedContext( entitiesentities, relationshipsrelationships, text_unitstext_units, community_reportsreports, entity_text_embeddingsentity_embeddings, text_embedderembedding)search_engine LocalSearch( llmllm, context_buildercontext_builder, token_encodertoken_encoder, response_typesingle paragraph)# 执行查询result await search_engine.asearch(LLM在医疗诊断中的应用案例有哪些)print(result.response)## 自建轻量GraphRAG方案Microsoft GraphRAG功能完整但成本较高构建大型文档集可能消耗数百美元API费用。对于中小规模项目可以考虑轻量级自建方案pythonfrom neo4j import GraphDatabasefrom sentence_transformers import SentenceTransformerimport numpy as npclass LightweightGraphRAG: 基于Neo4j的轻量级GraphRAG实现 def __init__(self, neo4j_uri: str, username: str, password: str): self.driver GraphDatabase.driver(neo4j_uri, auth(username, password)) self.embedder SentenceTransformer(BAAI/bge-m3) def add_entity(self, name: str, entity_type: str, description: str): 添加实体到知识图谱 embedding self.embedder.encode(description).tolist() with self.driver.session() as session: session.run( MERGE (e:Entity {name: $name}) SET e.type $type, e.description $description, e.embedding $embedding , namename, typeentity_type, descriptiondescription, embeddingembedding) def add_relationship(self, source: str, target: str, rel_type: str, description: str ): 添加实体间关系 with self.driver.session() as session: session.run( MATCH (a:Entity {name: $source}) MATCH (b:Entity {name: $target}) MERGE (a)-[r:RELATES_TO {type: $rel_type}]-(b) SET r.description $description , sourcesource, targettarget, rel_typerel_type, descriptiondescription) def local_search(self, query: str, depth: int 2) - str: 局部搜索找到相关实体及其邻居 query_embedding self.embedder.encode(query).tolist() # 使用向量相似度找到入口实体 with self.driver.session() as session: # Neo4j 5.x支持向量索引 result session.run( CALL db.index.vector.queryNodes(entity-embeddings, 5, $embedding) YIELD node, score WHERE score 0.7 RETURN node.name AS entity, node.description AS description, score ORDER BY score DESC , embeddingquery_embedding) seed_entities [r[entity] for r in result] if not seed_entities: return 未找到相关实体 # 从种子实体出发获取子图 context_parts [] for entity in seed_entities[:3]: with self.driver.session() as session: subgraph session.run(f MATCH path (e:Entity {{name: $entity}})-[r*1..{depth}]-(neighbor) RETURN e, r, neighbor LIMIT 50 , entityentity) for record in subgraph: context_parts.append( f{record[e][name]} --[{record[r][-1][type]}]-- {record[neighbor][name]}: f{record[neighbor].get(description, )} ) return \n.join(context_parts)## GraphRAG vs 传统RAG选型决策矩阵| 维度 | 传统RAG | GraphRAG ||------|---------|---------|| 适合查询类型 | 单跳、事实查询 | 多跳、关系推理、全局摘要 || 构建成本 | 低 | 中-高LLM提取 || 查询延迟 | 低~200ms | 中-高~1-3s || 知识更新 | 容易 | 需重建图或增量更新 || 可解释性 | 差 | 好推理路径可见 || 适合规模 | 大规模文档 | 中等规模、高质量文档 |## 实际落地建议混合策略不必非此即彼。可以用传统RAG处理简单查询遇到复杂关系查询时自动切换到GraphRAG。成本控制- 使用GPT-4o-mini而非GPT-4进行实体提取成本降低90%- 对重复的实体描述进行去重减少LLM调用次数- 设置合理的max_gleanings1次通常足够增量更新生产环境中文档会不断增加设计增量更新机制避免每次全量重建- 新文档提取实体后合并到现有图中- 修改文档删除旧实体/关系重新提取- 定期全量重建如每周确保图的质量## 总结GraphRAG不是传统RAG的替代品而是针对特定场景的强化方案。当你的应用需要处理复杂关系推理、全局知识摘要或者需要在大型知识库中进行多跳查询时GraphRAG的投入是值得的。理解两者的边界根据业务需求选择合适的方案才是2026年RAG工程师的核心竞争力。