从Java转行大模型应用,GraphRAG 及相关技术学习
一、RAG 回顾——基于向量的 RAG(Vector RAG)
1.1 RAG 核心定义
RAG(Retrieval-Augmented Generation,检索增强生成)是一种结合“检索外部知识”与“大模型生成”的技术,核心解决大模型“知识滞后”“幻觉生成”的问题,通过先检索相关知识,再基于检索结果生成准确、有依据的回答。
1.2 Vector RAG 核心原理
Vector RAG(向量型 RAG)是最主流的 RAG 实现方式,核心依赖“向量嵌入”与“向量数据库”,流程如下:
文档处理:将原始文档分割为小块(Chunk),避免文本过长无法有效嵌入;
向量嵌入:通过嵌入模型(如 BERT、Sentence-BERT)将每个文本块转化为高维向量(嵌入向量),向量的相似度对应文本语义的相似度;
向量存储:将嵌入向量存入向量数据库(如 Pinecone、Chroma),便于快速检索;
检索生成:用户提问后,将问题转化为向量,在向量数据库中检索相似度最高的文本块,将检索结果作为上下文输入 LLM,生成回答。
1.3 Vector RAG 的优势与局限
优势:实现简单、检索速度快,能快速匹配语义相似的文本,适配大多数通用场景;
局限:无法捕捉文本间的“结构化关系”(如“张三是李四的同事”“A 公司收购 B 公司”),检索结果易碎片化,难以处理需要“关联推理”的场景(如多文档交叉关联、逻辑链条查询)。
二、Graph RAG 核心
2.1 Graph RAG 定义
Graph RAG(图检索增强生成)是 Vector RAG 的进阶形式,将“非结构化文本”转化为“结构化知识图谱”,基于知识图谱的节点、关系进行检索,再结合 LLM 生成回答,核心解决 Vector RAG 无法捕捉结构化关系、缺乏推理能力的问题。
2.2 Graph RAG 与 Vector RAG 的核心区别
对比维度 | Vector RAG | Graph RAG |
|---|---|---|
数据形式 | 非结构化文本块(向量形式) | 结构化知识图谱(节点、关系、属性) |
检索方式 | 语义相似度匹配(向量距离) | 节点关联查询、关系推理(图查询) |
核心能力 | 快速匹配相似文本 | 捕捉结构化关系、多步推理 |
适用场景 | 通用问答、简单信息检索 | 复杂推理、关联查询(如金融、法律、知识库) |
2.3 Graph RAG 核心流程
文本结构化:将非结构化文本(文档、对话等)解析为知识图谱的“节点、关系、属性”;
知识存储:将知识图谱存入图数据库(如 Neo4j),维护节点与关系的关联;
图检索:用户提问后,将问题转化为图查询语句(如 Cypher),检索知识图谱中相关的节点、关系;
增强生成:将图检索到的结构化知识作为上下文,输入 LLM,生成具有逻辑关联、可追溯的回答。
三、知识图谱建模(节点、关系、属性)
知识图谱(Knowledge Graph)是结构化的知识表示形式,核心由“节点(Entity)”“关系(Relationship)”“属性(Property)”三部分组成,本质是“图结构”(由节点和边构成,边即关系)。
3.1 节点(Entity)
节点是知识图谱的核心元素,代表“实体”,即现实世界中可区分、可识别的对象,分为两类:
实体节点:具体的人、事、物(如“张三”“北京”“苹果公司”“《三体》”);
概念节点:抽象的概念、类别(如“城市”“水果”“小说”“职业”)。
节点的核心作用:承载知识的“主体”,所有关系和属性都围绕节点展开。
3.2 关系(Relationship)
关系是连接两个节点的“边”,代表节点之间的关联,核心作用是“描述节点间的逻辑关系”,分为两类:
实体间关系:如“张三-同事-李四”“苹果公司-总部位于-北京”;
实体与概念间关系:如“北京-属于-城市”“《三体》-属于-小说”。
注意:关系具有“方向性”(如“张三-父亲-李四”≠“李四-父亲-张三”),且需具有明确的语义(避免模糊,如用“同事”而非“认识”)。
3.3 属性(Property)
属性是节点或关系的“附加信息”,用于补充描述节点/关系的特征,键值对(Key-Value)形式存储:
节点属性:如“张三”的属性(年龄:30,职业:工程师,性别:男);“北京”的属性(面积:16410 平方公里,人口:约 2184 万);
关系属性:如“张三-同事-李四”的属性(共事时间:5 年,所属部门:技术部)。
3.4 建模示例
文本:“张三,30 岁,是一名工程师,和李四是同事,两人在技术部共事 5 年,李四今年 32 岁。”
节点:张三(属性:年龄=30,职业=工程师)、李四(属性:年龄=32)、技术部(属性:无);
关系:张三-同事-李四(属性:共事时间=5 年,所属部门=技术部)。
四、Neo4j 数据库基础操作
4.1 Neo4j 简介
Neo4j 是最流行的“原生图数据库”,专门用于存储和查询知识图谱(图结构数据),相比关系型数据库(如 MySQL),无需定义表结构,能高效处理节点与关系的关联查询,核心优势是“图遍历速度快”。
核心概念:
节点(Node):对应知识图谱的节点,可添加标签(Label)区分类别(如 :Person、:City);
关系(Relationship):对应知识图谱的关系,有方向、类型(如 :COLLEAGUE、:LOCATED_IN);
属性(Property):节点和关系的附加信息,键值对形式;
标签(Label):用于分类节点(如给“张三”“李四”添加 :Person 标签,给“北京”添加 :City 标签)。
4.2 Neo4j 基础操作(桌面版)
4.2.1 启动与连接
启动 Neo4j 桌面版,创建新项目(Project);
新建数据库(Database),设置用户名(默认 neo4j)和密码;
启动数据库,点击“Open Browser”,输入用户名密码,进入查询界面(Browser)。
4.2.2 核心基础操作(Cypher 语句,后续详细讲解)
创建节点:创建带标签和属性的节点(如创建张三节点);
创建关系:连接两个已存在的节点,添加关系类型和属性;
查询节点/关系:检索指定标签、属性的节点,或指定类型的关系;
更新属性:修改节点或关系的属性值;
删除节点/关系:删除指定节点(需先删除关联关系,否则报错)、关系。
4.2.3 关键注意事项
Neo4j 中,节点必须通过关系连接(孤立节点可存在,但无实际意义);
删除节点前,必须先删除该节点的所有关联关系(否则会触发约束报错);
标签可给一个节点添加多个(如 :Person :Engineer),便于分类查询。
五、Cypher 查询语言
5.1 Cypher 简介
Cypher 是 Neo4j 的专用查询语言,语法简洁、接近自然语言,核心用于“创建、查询、更新、删除”图数据,类比关系型数据库的 SQL,但专为图结构设计,重点关注“节点与关系的关联”。
5.2 核心语法(常用操作)
5.2.1 创建(CREATE)
创建单个节点:CREATE (:Person {name: '张三', age: 30, job: '工程师'})
创建多个节点:CREATE (:Person {name: '李四', age: 32}), (:City {name: '北京', area: 16410})
创建节点+关系:CREATE (a:Person {name: '张三'})-[:COLLEAGUE {workYears: 5}]->(b:Person {name: '李四'})
说明:() 代表节点,[:关系类型] 代表关系,-> 表示关系方向,{} 内是属性。
5.2.2 查询(MATCH + RETURN)
查询所有 Person 节点:MATCH (p:Person) RETURN p.name, p.age;
查询张三的同事:MATCH (p:Person {name: '张三'})-[:COLLEAGUE]->(colleague) RETURN colleague.name;
查询带条件的节点:MATCH (p:Person) WHERE p.age > 30 RETURN p.name;
查询关系及属性:MATCH (a:Person)-[r:COLLEAGUE]->(b:Person) RETURN a.name, r.workYears, b.name;
5.2.3 更新(SET)
更新节点属性:MATCH (p:Person {name: '张三'}) SET p.age = 31, p.job = '高级工程师';
更新关系属性:MATCH (a:Person)-[r:COLLEAGUE]->(b:Person) WHERE a.name = '张三' SET r.workYears = 6;
5.2.4 删除(DELETE + REMOVE)
删除关系:MATCH (a:Person)-[r:COLLEAGUE]->(b:Person) DELETE r;
删除节点(先删关系):MATCH (p:Person {name: '张三'})-[r]->() DELETE r, p;
删除属性:MATCH (p:Person {name: '张三'}) REMOVE p.job;
5.2.5 常用技巧
用 AS 取别名:MATCH (p:Person) RETURN p.name AS 姓名, p.age AS 年龄;
用 LIMIT 限制结果数量:MATCH (p:Person) RETURN p.name LIMIT 10;
用 ORDER BY 排序:MATCH (p:Person) RETURN p.name, p.age ORDER BY p.age DESC;
六、Graph RAG 实现
6.1 Graph RAG 实现核心流程(完整链路)
数据准备:获取非结构化文本数据(如文档、PDF、对话记录),进行清洗(去重、去噪、分割);
文本结构化(知识抽取):通过 LLM 或知识抽取工具(如 spaCy、 Stanford CoreNLP),从文本中抽取“节点、关系、属性”;
示例:给 LLM 输入提示词“从以下文本中抽取实体、关系和属性,格式为:节点1-关系-节点2(属性);节点(属性)”,让 LLM 输出结构化结果;
知识存储:将抽取到的节点、关系、属性,通过 Cypher 语句写入 Neo4j 数据库,构建知识图谱;
图检索:将用户提问转化为 Cypher 查询语句(可通过 LLM 实现“自然语言转 Cypher”),查询 Neo4j 得到相关结构化知识;
增强生成:将图检索结果(节点、关系、属性)作为上下文,输入 LLM,生成回答(需提示 LLM 基于检索到的知识,避免幻觉);
优化迭代:根据用户反馈,调整知识抽取规则、Cypher 查询逻辑,优化知识图谱的完整性和检索准确性。
6.2 关键难点
知识抽取准确性:LLM 可能抽取错误的节点/关系,需添加人工校验或规则约束;
自然语言转 Cypher:用户提问可能模糊,需让 LLM 精准理解意图,生成正确的 Cypher 语句;
知识图谱维护:随着数据增加,需定期更新节点、关系,避免知识滞后或冗余。
七、LLM + Neo4j 实现 Graph RAG
7.1 核心逻辑
LLM 负责“自然语言理解”和“结构化生成”,Neo4j 负责“知识存储”和“图检索”,两者结合实现端到端的 Graph RAG,核心分工:
LLM:① 将非结构化文本抽取为节点、关系、属性;② 将用户自然语言提问转化为 Cypher 查询语句;③ 基于 Neo4j 检索到的知识,生成自然语言回答;
Neo4j:① 存储知识图谱(节点、关系、属性);② 执行 Cypher 查询,返回结构化知识。
7.2 实现步骤(简化版)
环境准备:安装 Neo4j(桌面版/服务器版)、LLM SDK(如 OpenAI API、LangChain)、Neo4j Python 驱动(neo4j);
知识抽取:调用 LLM API,输入文本和提示词,抽取节点、关系、属性,整理为 Cypher 创建语句;
写入 Neo4j:通过 Python 驱动连接 Neo4j,执行 Cypher 创建语句,构建知识图谱;
自然语言转 Cypher:用户提问后,调用 LLM,输入提问和提示词(如“将以下问题转化为 Neo4j 的 Cypher 查询语句,只返回 Cypher 语句,不添加其他内容”),得到 Cypher 语句;
图检索与生成:执行 Cypher 语句,获取检索结果,将结果作为上下文输入 LLM,生成最终回答。
7.3 示例代码片段(Python)
# 1. 连接 Neo4j from neo4j import GraphDatabase uri = "bolt://localhost:7687" user = "neo4j" password = "your_password" driver = GraphDatabase.driver(uri, auth=(user, password)) # 2. 调用 LLM 抽取知识(以 OpenAI 为例) import openai openai.api_key = "your_api_key" text = "张三,30 岁,是一名工程师,和李四是同事,两人在技术部共事 5 年。" prompt = f"从以下文本中抽取实体、关系和属性,生成 Neo4j Cypher 创建语句,只返回 Cypher 语句:{text}" response = openai.ChatCompletion.create( model="gpt-3.5-turbo", messages=[{"role": "user", "content": prompt}] ) cypher_create = response.choices[0].message.content # 3. 执行 Cypher,写入知识图谱 with driver.session() as session: session.run(cypher_create) # 4. 自然语言转 Cypher user_question = "张三的同事是谁?共事多少年?" prompt_cypher = f"将问题转化为 Neo4j Cypher 查询语句,只返回 Cypher:{user_question}" cypher_query = openai.ChatCompletion.create( model="gpt-3.5-turbo", messages=[{"role": "user", "content": prompt_cypher}] ).choices[0].message.content # 5. 执行查询,获取结果 with driver.session() as session: result = session.run(cypher_query) data = [dict(record) for record in result] # 6. 调用 LLM 生成回答 prompt_answer = f"基于以下知识,回答用户问题:{data}\n用户问题:{user_question}" answer = openai.ChatCompletion.create( model="gpt-3.5-turbo", messages=[{"role": "user", "content": prompt_answer}] ).choices[0].message.content print(answer)八、LangChain + 知识图谱 实现 Graph RAG
8.1 LangChain 核心作用
LangChain 是一个大模型应用开发框架,提供了丰富的组件,简化 Graph RAG 的实现,核心优势:
集成 LLM:支持 OpenAI、Anthropic、本地化 LLM(如 Llama 2),无需单独封装 API 调用;
集成 Neo4j:提供专门的 Neo4j 组件(Neo4jVector、Neo4jGraph),简化数据库连接和查询;
流程封装:将“知识抽取、图检索、生成回答”的链路封装为 Chain,无需手动拼接各步骤;
工具调用:支持“自然语言转 Cypher”工具(CypherQueryGenerator),自动生成查询语句。
8.2 LangChain + Neo4j 实现步骤
8.2.1 环境准备
安装依赖包:pip install langchain openai neo4j python-dotenv
8.2.2 核心组件说明
Neo4jGraph:LangChain 中连接 Neo4j 的核心组件,用于操作知识图谱;
CypherQueryGenerator:将自然语言提问转化为 Cypher 查询语句的工具;
GraphQAChain:端到端的 Graph RAG 链,整合“图检索 + LLM 生成”。
8.2.3 示例代码片段(Python)
from dotenv import load_dotenv from langchain.graphs import Neo4jGraph from langchain.chat_models import ChatOpenAI from langchain.chains import GraphQAChain from langchain.prompts import PromptTemplate # 1. 加载环境变量(存储 OpenAI API 密钥、Neo4j 连接信息) load_dotenv() # 2. 连接 Neo4j(自动读取环境变量中的 NEO4J_URI、NEO4J_USER、NEO4J_PASSWORD) graph = Neo4jGraph() # 3. 向 Neo4j 写入知识(可通过 LangChain 工具抽取,或手动执行 Cypher) cypher_create = """ CREATE (p1:Person {name: '张三', age: 30, job: '工程师'}) CREATE (p2:Person {name: '李四', age: 32}) CREATE (p1)-[:COLLEAGUE {workYears: 5, department: '技术部'}]->(p2) """ graph.query(cypher_create) # 4. 初始化 LLM(OpenAI GPT-3.5) llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0) # 5. 构建 Graph RAG 链 graph_qa_chain = GraphQAChain.from_llm( llm=llm, graph=graph, verbose=True, # 打印中间过程(Cypher 语句、检索结果) return_intermediate_steps=True # 返回中间步骤,便于调试 ) # 6. 提问并获取回答 user_question = "张三的同事是谁?他们在哪个部门共事?" response = graph_qa_chain({"query": user_question}) # 输出结果 print("回答:", response["result"]) print("中间步骤:", response["intermediate_steps"])8.3 关键优化点
提示词优化:自定义 PromptTemplate,让 LLM 更精准地生成 Cypher 语句、更贴合知识图谱的结构;
知识抽取优化:使用 LangChain 的 DocumentLoader 加载文档,结合 TextSplitter 分割文本,再用 LLMChain 抽取知识;
多轮对话支持:结合 ConversationBufferMemory,让 Graph RAG 记住上下文,支持多轮关联提问。
九、学习总结
Vector RAG 是基础,核心解决“相似文本检索”,但缺乏结构化关系捕捉能力;Graph RAG 是进阶,通过知识图谱实现“关联推理”,适配复杂场景;
知识图谱建模是 Graph RAG 的核心,需准确识别节点、关系、属性,确保知识的结构化和准确性;
Neo4j 是图数据库的核心工具,Cypher 是操作 Neo4j 的关键,需熟练掌握创建、查询、更新、删除等基础操作;
Graph RAG 的核心实现逻辑是“文本结构化→知识存储→图检索→增强生成”,LLM 负责理解和生成,Neo4j 负责存储和检索;
LangChain 简化了 Graph RAG 的开发,通过封装好的组件,可快速实现端到端的链路,重点掌握 Neo4jGraph、GraphQAChain 等核心组件的使用。
