资讯中心

基于Neo4j与LLM的GraphRAG医疗智能问答系统实战

📅 2026/8/6 2:32:43
基于Neo4j与LLM的GraphRAG医疗智能问答系统实战
大家好我是专注于分享AI与数据技术实战经验的博主。在医疗健康领域如何让AI系统不仅能回答简单问题还能像专家一样进行逻辑推理和诊断辅助是当前技术落地的核心挑战。传统的检索增强生成RAG在处理复杂的、关联性强的医学知识时常常力不从心。本文将手把手带你实现一个基于知识图谱Neo4j和大语言模型LLM的图检索增强GraphRAG医疗健康知识诊断智能问答系统。这个项目非常适合作为计算机专业的毕业设计它融合了图数据库、LLM应用和智能问答三大热门方向既有理论深度又有完整的工程实践。通过本文你将掌握从零搭建一个GraphRAG系统的全流程包括Neo4j知识图谱的构建、LLM的集成调用、GraphRAG的核心检索逻辑以及一个完整的Web问答界面。无论你是想深入学习图数据库与LLM的结合应用还是急需一个高质量、有亮点的毕业设计项目这篇文章都能为你提供清晰的路径和可运行的代码。1. 项目背景与核心概念解析在深入代码之前我们有必要厘清几个核心概念理解它们如何协同工作来解决医疗问答的难题。1.1 为什么需要GraphRAG传统的基于向量数据库的RAGRetrieval-Augmented Generation系统其核心是“语义相似度检索”。它将文档切成块转换成向量然后根据用户问题检索最相似的文本块喂给LLM生成答案。这种方法在处理事实性、描述性知识时效果很好。然而医疗诊断是一个高度依赖逻辑推理和关系网络的过程。例如用户提问“我最近咳嗽、发烧并且感觉全身乏力可能是什么问题” 简单的语义检索可能会返回关于“咳嗽”、“发烧”、“乏力”的独立描述段落。但一个医生会立刻在脑海中构建一个关系图咳嗽 - 可能是 - 呼吸道感染 - 常见症状包括 - 发烧、乏力。这种实体间的关联关系是向量检索难以直接捕捉的。GraphRAG正是为了解决这一问题而生。它利用知识图谱来存储实体疾病、症状、药品、检查项和它们之间丰富的关系导致、表现为、治疗、禁忌。当用户提问时系统不是检索相似的文本片段而是从问题中抽取实体如“咳嗽”、“发烧”。在图数据库中进行图遍历查询找到与这些实体相关联的其他实体和路径例如找到同时连接“咳嗽”和“发烧”的疾病节点。将查询到的子图结构包含实体和关系作为上下文提供给LLM。 这样LLM获得的不是零散的文本而是一个结构化的“知识片段”极大提升了推理的准确性和可解释性。1.2 技术栈组成与角色我们的系统主要由以下部分组成Neo4j 作为图数据库存储结构化的医疗知识图谱。它是我们系统的“知识大脑”。大语言模型 (LLM) 作为系统的“推理引擎”。我们使用其完成1) 从自然语言问题中抽取实体2) 根据图谱检索到的结构化信息生成流畅、专业的诊断建议和回答。本文将使用 OpenAI 的 GPT 系列模型作为示例你也可以替换为国内可访问的模型如文心一言、通义千问的API。GraphRAG 检索层 这是系统的“连接器”。它接收用户问题调用LLM进行实体抽取构造Cypher查询语句Neo4j的查询语言在图谱中检索相关子图并将子图信息格式化后送入LLM生成最终答案。后端框架 (FastAPI) 提供RESTful API处理前端请求协调GraphRAG检索层与LLM的交互。前端界面 (Streamlit) 提供一个简单直观的Web界面供用户输入问题并查看回答和背后的知识图谱证据。Streamlit非常适合快速构建数据科学应用。2. 环境准备与项目搭建工欲善其事必先利其器。我们先来准备好开发环境并创建项目结构。2.1 软件与环境要求操作系统 Windows 10/11, macOS, 或 Linux (Ubuntu 20.04)。本文演示以 macOS/Linux 命令行环境为主Windows 用户建议使用 WSL2 或 Git Bash。Python 版本 3.8 - 3.11。推荐使用 3.9 或 3.10兼容性最好。使用python --version检查。Neo4j 数据库 我们将使用Neo4j AuraDB免费的云托管版本或Neo4j Desktop本地图形化管理工具。对于毕业设计AuraDB免费版足够使用无需在本地安装数据库服务。代码编辑器 VS Code 或 PyCharm。2.2 创建项目与虚拟环境首先创建一个清晰的项目目录结构。# 1. 创建项目目录 mkdir medical_graphrag_qa cd medical_graphrag_qa # 2. 创建虚拟环境 (以 venv 为例) python -m venv venv # 3. 激活虚拟环境 # macOS/Linux: source venv/bin/activate # Windows: # venv\Scripts\activate # 4. 创建必要的项目文件 touch requirements.txt touch .env.example mkdir src mkdir data激活虚拟环境后你的命令行提示符前会出现(venv)字样。2.3 安装依赖包编辑requirements.txt文件填入以下内容# 核心依赖 neo4j5.20.0 openai1.12.0 langchain0.1.0 langchain-community0.0.10 langchain-openai0.0.8 # Web框架与工具 fastapi0.104.1 uvicorn[standard]0.24.0 streamlit1.28.0 # 工具类 python-dotenv1.0.0 pydantic2.5.0 pydantic-settings2.1.0然后安装所有依赖pip install -r requirements.txt关键依赖说明neo4j: Neo4j 官方的 Python 驱动。openai,langchain: 用于调用和编排 LLM。LangChain 提供了构建链Chain的高层抽象让GraphRAG流程更清晰。fastapi,uvicorn: 用于构建高性能后端 API。streamlit: 快速构建交互式前端。python-dotenv: 管理环境变量如数据库密码、API密钥。2.4 配置 Neo4j 数据库我们使用Neo4j AuraDB免费云服务它提供了512MB存储足够毕业设计使用。注册与创建实例访问 Neo4j Aura 官网注册账号。在控制台点击 “Create Database”选择 “Free” 套餐。设置数据库名称如medical-kg选择区域点击创建。等待几分钟实例状态变为 “Running”。获取连接信息实例创建成功后点击 “Open” 下拉菜单选择 “Connection details”。你会看到NEO4J_URI(格式如neo4js://xxxx.databases.neo4j.io),NEO4J_USERNAME(默认neo4j), 和NEO4J_PASSWORD。务必保存好密码它只显示一次。本地环境变量配置复制.env.example文件为.env。编辑.env文件填入你的 AuraDB 信息和 OpenAI API Key。# .env 文件内容 NEO4J_URIneo4js://your-aura-db-id.databases.neo4j.io NEO4J_USERNAMEneo4j NEO4J_PASSWORDyour-strong-password-here OPENAI_API_KEYsk-your-openai-api-key-here重要安全提示.env文件包含敏感信息务必将其添加到.gitignore文件中切勿提交到版本控制系统如Git。3. 构建医疗知识图谱知识图谱是系统的基石。我们需要将非结构化的医疗文本或结构化数据转化为图数据库中的节点和关系。3.1 设计图谱Schema一个简化的医疗知识图谱可以包含以下类型的节点和关系节点 (Node):Disease(疾病) 如感冒肺炎。Symptom(症状) 如咳嗽发烧头痛。Drug(药品) 如阿莫西林布洛芬。Examination(检查) 如血常规胸部X光。关系 (Relationship):HAS_SYMPTOM 疾病-症状。感冒 -[:HAS_SYMPTOM]- 咳嗽。COMMON_DRUG 疾病-药品。肺炎 -[:COMMON_DRUG]- 阿莫西林。NEEDS_EXAM 疾病-检查。肺炎 -[:NEEDS_EXAM]- 胸部X光。ACCOMPANY_WITH 症状-症状。咳嗽 -[:ACCOMPANY_WITH]- 咽痛。BELONGS_TO 疾病-科室。感冒 -[:BELONGS_TO]- 呼吸内科。3.2 准备与导入数据我们可以从公开的医疗数据集中提取或者为了演示手动创建一个小型数据集。我们在data/目录下创建一个medical_kg_data.json文件。// data/medical_kg_data.json { diseases: [ { name: 感冒, desc: 普通感冒是一种常见的急性上呼吸道病毒性感染性疾病。, department: 呼吸内科, symptoms: [咳嗽, 流鼻涕, 打喷嚏, 咽痛, 发烧], common_drugs: [感冒灵颗粒, 对乙酰氨基酚], needs_exam: [血常规] }, { name: 肺炎, desc: 肺炎是指终末气道、肺泡和肺间质的炎症可由细菌、病毒等病原体引起。, department: 呼吸内科, symptoms: [咳嗽, 咳痰, 胸痛, 发烧, 呼吸困难], common_drugs: [阿莫西林, 左氧氟沙星], needs_exam: [血常规, 胸部X光, 痰培养] }, { name: 高血压, desc: 高血压是一种动脉血压升高的慢性病是心脑血管病的主要危险因素。, department: 心血管内科, symptoms: [头晕, 头痛, 心悸, 耳鸣], common_drugs: [硝苯地平, 卡托普利], needs_exam: [血压测量, 心电图, 肾功能检查] } ] }3.3 编写数据导入脚本接下来我们编写一个Python脚本读取上面的JSON数据并将其导入到Neo4j中。创建文件src/init_kg.py。# src/init_kg.py import json from neo4j import GraphDatabase from dotenv import load_dotenv import os # 加载环境变量 load_dotenv() class Neo4jConnection: def __init__(self): self.uri os.getenv(NEO4J_URI) self.user os.getenv(NEO4J_USERNAME) self.password os.getenv(NEO4J_PASSWORD) self.driver None def connect(self): self.driver GraphDatabase.driver(self.uri, auth(self.user, self.password)) return self.driver def close(self): if self.driver is not None: self.driver.close() def clear_database(tx): # 清空现有图谱谨慎操作仅用于演示和初始化 tx.run(MATCH (n) DETACH DELETE n) print(已清空数据库。) def create_disease_node(tx, disease): # 创建疾病节点 query MERGE (d:Disease {name: $name}) SET d.description $desc, d.department $dept RETURN d tx.run(query, namedisease[name], descdisease[desc], deptdisease[department]) def create_symptom_relationship(tx, disease_name, symptom_list): # 创建症状节点并建立关系 for symptom in symptom_list: query MERGE (s:Symptom {name: $symptom_name}) WITH s MATCH (d:Disease {name: $disease_name}) MERGE (d)-[:HAS_SYMPTOM]-(s) tx.run(query, symptom_namesymptom, disease_namedisease_name) def create_drug_relationship(tx, disease_name, drug_list): # 创建药品节点并建立关系 for drug in drug_list: query MERGE (dr:Drug {name: $drug_name}) WITH dr MATCH (d:Disease {name: $disease_name}) MERGE (d)-[:COMMON_DRUG]-(dr) tx.run(query, drug_namedrug, disease_namedisease_name) def create_exam_relationship(tx, disease_name, exam_list): # 创建检查节点并建立关系 for exam in exam_list: query MERGE (e:Examination {name: $exam_name}) WITH e MATCH (d:Disease {name: $disease_name}) MERGE (d)-[:NEEDS_EXAM]-(e) tx.run(query, exam_nameexam, disease_namedisease_name) def main(): conn Neo4jConnection() driver conn.connect() # 读取数据 with open(data/medical_kg_data.json, r, encodingutf-8) as f: data json.load(f) with driver.session() as session: # 清空数据库可选第一次运行或需要重置时使用 # session.execute_write(clear_database) for disease in data[diseases]: print(f正在导入疾病: {disease[name]}) # 1. 创建疾病节点 session.execute_write(create_disease_node, disease) # 2. 创建症状及关系 session.execute_write(create_symptom_relationship, disease[name], disease[symptoms]) # 3. 创建药品及关系 session.execute_write(create_drug_relationship, disease[name], disease[common_drugs]) # 4. 创建检查及关系 session.execute_write(create_exam_relationship, disease[name], disease[needs_exam]) conn.close() print(知识图谱数据导入完成) if __name__ __main__: main()运行此脚本将数据导入Neo4jpython src/init_kg.py导入成功后你可以登录 Neo4j AuraDB 控制台使用内置的Bloom或Browser工具可视化你的图谱。执行一个简单的查询如MATCH (n) RETURN n LIMIT 25就能看到初步构建的图谱。4. 核心组件开发GraphRAG检索与问答链这是系统的核心逻辑。我们将使用 LangChain 来编排整个流程。4.1 构建图检索器 (Graph Retriever)图检索器的任务是接收用户问题从中提取实体并构造Cypher查询从Neo4j中获取相关的子图信息。创建文件src/graph_retriever.py。# src/graph_retriever.py from langchain.chains import GraphCypherQAChain from langchain_community.graphs import Neo4jGraph from langchain_openai import ChatOpenAI from langchain.prompts import PromptTemplate from dotenv import load_dotenv import os load_dotenv() class MedicalGraphRetriever: def __init__(self): # 1. 连接Neo4j图数据库 self.graph Neo4jGraph( urlos.getenv(NEO4J_URI), usernameos.getenv(NEO4J_USERNAME), passwordos.getenv(NEO4J_PASSWORD) ) # 2. 初始化LLM self.llm ChatOpenAI( modelgpt-3.5-turbo, temperature0, # 温度设为0使输出更确定 openai_api_keyos.getenv(OPENAI_API_KEY) ) # 3. 定义图谱Schema帮助LLM理解如何生成Cypher self.graph_schema self.graph.get_schema # 4. 定制Cypher生成提示词 self.cypher_generation_prompt PromptTemplate.from_template( 你是一个专业的Neo4j Cypher查询生成器。 给定一个输入问题基于以下图谱Schema将其转换成一个Cypher查询语句。 不要解释只返回Cypher查询。 图谱Schema: {schema} 问题: {question} ) # 5. 定制答案生成提示词 self.qa_prompt PromptTemplate.from_template( 你是一个专业的医疗健康助手。请基于以下上下文信息用中文专业、清晰、有条理地回答用户的问题。 如果上下文信息不足以回答问题请如实告知你不知道不要编造信息。 在回答中可以引用上下文中的疾病、症状、药品和检查项。 上下文信息: {context} 问题: {question} 请给出回答: ) def retrieve(self, question: str) - str: 核心检索方法根据问题检索图谱并返回文本化上下文 try: # 步骤1让LLM根据问题生成Cypher查询 cypher_prompt self.cypher_generation_prompt.format( schemaself.graph_schema, questionquestion ) cypher_query self.llm.invoke(cypher_prompt).content.strip() print(f生成的Cypher查询: {cypher_query}) # 步骤2在Neo4j中执行查询获取结果 graph_result self.graph.query(cypher_query) print(f图谱查询结果: {graph_result}) # 步骤3将图谱结果格式化为文本上下文 # 这里简单地将结果中的节点和关系信息拼接成字符串 context_text self._format_graph_result(graph_result) return context_text except Exception as e: print(f图检索过程中发生错误: {e}) return f检索知识图谱时出错: {str(e)} def _format_graph_result(self, result): 将Neo4j查询结果格式化为易读的文本 if not result: return 未在知识图谱中找到相关信息。 formatted_lines [] for record in result: # record 是一个字典键是Cypher查询中定义的变量名 for key, value in record.items(): if isinstance(value, list): formatted_lines.append(f{key}: {, .join([str(v) for v in value])}) else: formatted_lines.append(f{key}: {value}) return \n.join(formatted_lines) def answer_question(self, question: str) - str: 完整的问答流程检索 生成 context self.retrieve(question) if 出错 in context or 未找到 in context: # 如果检索失败直接让LLM基于常识回答需谨慎 final_prompt f用户问{question}。我未能在知识库中找到确切信息请你基于通用医学知识谨慎回答并说明这并非来自特定知识库。 else: final_prompt self.qa_prompt.format(contextcontext, questionquestion) answer self.llm.invoke(final_prompt).content return answer, context # 返回答案和用于解释的上下文 # 简单测试 if __name__ __main__: retriever MedicalGraphRetriever() test_question 感冒有哪些症状 answer, context retriever.answer_question(test_question) print( 检索到的上下文 ) print(context) print(\n 生成的答案 ) print(answer)运行测试python src/graph_retriever.py你应该能看到LLM生成的Cypher查询类似MATCH (d:Disease {name: ‘感冒’})-[:HAS_SYMPTOM]-(s:Symptom) RETURN d.name as disease, collect(s.name) as symptoms查询结果以及最终生成的答案。4.2 构建FastAPI后端服务现在我们将检索和问答能力封装成REST API。创建文件src/api.py。# src/api.py from fastapi import FastAPI, HTTPException from pydantic import BaseModel from src.graph_retriever import MedicalGraphRetriever import uvicorn from dotenv import load_dotenv load_dotenv() app FastAPI( title医疗健康GraphRAG智能问答系统API, description基于Neo4j知识图谱和LLM的医疗诊断问答系统, version1.0.0 ) # 全局检索器实例 retriever MedicalGraphRetriever() class QuestionRequest(BaseModel): question: str class AnswerResponse(BaseModel): answer: str retrieved_context: str status: str success app.get(/) def read_root(): return {message: 医疗健康GraphRAG智能问答系统API已就绪} app.post(/ask, response_modelAnswerResponse) async def ask_question(request: QuestionRequest): 接收用户问题返回基于知识图谱的答案。 try: if not request.question or request.question.strip() : raise HTTPException(status_code400, detail问题不能为空) print(f接收到问题: {request.question}) answer, context retriever.answer_question(request.question) return AnswerResponse( answeranswer, retrieved_contextcontext ) except Exception as e: print(fAPI处理错误: {e}) raise HTTPException(status_code500, detailf服务器内部错误: {str(e)}) app.get(/health) def health_check(): 健康检查端点 try: # 可以添加对Neo4j和OpenAI连接的健康检查 return {status: healthy, database: connected, llm: available} except Exception as e: return {status: unhealthy, error: str(e)}, 503 if __name__ __main__: uvicorn.run(app, host0.0.0.0, port8000)使用以下命令启动后端服务cd medical_graphrag_qa python src/api.py服务将在http://localhost:8000启动。你可以访问http://localhost:8000/docs查看自动生成的交互式API文档Swagger UI并直接在那里测试/ask接口。4.3 构建Streamlit前端界面最后我们创建一个简单的前端让用户可以通过网页交互。创建文件src/frontend.py。# src/frontend.py import streamlit as st import requests import json # 页面配置 st.set_page_config( page_title医疗健康智能诊断助手, page_icon, layoutwide ) # 标题和描述 st.title( 基于知识图谱与AI的医疗健康问答系统) st.markdown( 这是一个演示系统它结合了**Neo4j知识图谱**和**大语言模型**能够理解症状并基于医学知识进行推理。 **请注意**本系统提供的信息仅供参考不能替代专业医生的诊断。如有健康问题请及时就医。 ) # 初始化会话状态 if chat_history not in st.session_state: st.session_state.chat_history [] # 侧边栏 - 显示知识图谱信息 with st.sidebar: st.header(ℹ️ 系统信息) st.markdown( **技术栈**: - 后端: FastAPI - 图数据库: Neo4j AuraDB - 大语言模型: OpenAI GPT - 前端: Streamlit **知识图谱包含**: - 疾病、症状、药品、检查等实体 - 实体间的诊断、治疗、检查关系 ) if st.button(清空对话历史): st.session_state.chat_history [] st.rerun() # 主界面 col1, col2 st.columns([3, 2]) with col1: st.subheader( 开始咨询) user_question st.text_area( 请输入您的症状或健康问题例如咳嗽发烧可能是什么病感冒应该吃什么药:, height100, keyinput_question ) if st.button(提交问题, typeprimary): if user_question.strip(): with st.spinner(正在查询知识图谱并生成回答...): try: # 调用后端API api_url http://localhost:8000/ask # 确保后端正在运行 payload {question: user_question} response requests.post(api_url, jsonpayload, timeout30) if response.status_code 200: result response.json() answer result.get(answer, 未收到答案) context result.get(retrieved_context, 无上下文) # 保存到对话历史 st.session_state.chat_history.append({ question: user_question, answer: answer, context: context }) else: st.error(f请求失败: {response.status_code} - {response.text}) except requests.exceptions.ConnectionError: st.error(无法连接到后端服务请确保 src/api.py 正在运行。) except Exception as e: st.error(f发生错误: {str(e)}) else: st.warning(请输入问题再提交。) # 显示对话历史 st.subheader( 对话历史) if st.session_state.chat_history: for i, chat in enumerate(reversed(st.session_state.chat_history[-5:]), 1): # 只显示最近5条 with st.expander(fQ{i}: {chat[question][:50]}...): st.markdown(f**问题**: {chat[question]}) st.markdown(f**回答**: {chat[answer]}) # 可以隐藏详细的上下文点击展开 with st.expander(查看检索到的知识图谱上下文): st.code(chat[context], languagetext) else: st.info(暂无对话历史。请在上方提出问题。) with col2: st.subheader( 知识图谱检索演示) st.markdown( 当你提交问题时系统会 1. **理解问题**LLM提取关键医学实体如“咳嗽”、“发烧”。 2. **图谱查询**生成Cypher语句在Neo4j中查找关联的疾病、症状、药品。 3. **生成回答**LLM结合检索到的结构化知识生成专业回答。 **示例查询**: - “感冒有哪些症状” - “肺炎需要做什么检查” - “咳嗽和发烧同时出现可能是什么病” - “高血压常用药有哪些” ) # 可以添加一个示例按钮快速填充问题 if st.button(加载示例问题: ‘感冒有哪些症状’): st.session_state.input_question 感冒有哪些症状 st.rerun() # 页脚 st.markdown(---) st.caption( ⚠️ **免责声明**: 本系统为学术演示项目其生成内容可能存在不准确或过时之处绝不能用于实际医疗诊断或治疗决策。所有健康问题请咨询合格医疗人员。 )启动前端应用streamlit run src/frontend.pyStreamlit 会自动在浏览器中打开页面通常是http://localhost:8501。现在你就可以通过这个界面与你的GraphRAG医疗问答系统交互了5. 系统优化与高级功能基础系统搭建完成后我们可以从以下几个方面进行优化使其更健壮、更智能。5.1 优化Cypher查询生成上面的简单提示词可能生成不准确或低效的Cypher。我们可以提供更详细的示例Few-Shot Prompting来引导LLM。# 在 graph_retriever.py 的 cypher_generation_prompt 中改进 self.cypher_generation_prompt PromptTemplate.from_template( 你是一个Neo4j Cypher专家。根据以下图谱Schema和示例将用户问题转化为一个精确的Cypher查询。 只返回Cypher语句不要有其他内容。 图谱Schema: {schema} 示例 问题 “感冒有哪些症状” Cypher MATCH (d:Disease {{name: 感冒}})-[:HAS_SYMPTOM]-(s:Symptom) RETURN d.name as disease, collect(s.name) as symptoms 问题 “什么病会导致咳嗽和发烧” Cypher MATCH (d:Disease)-[:HAS_SYMPTOM]-(s:Symptom) WHERE s.name IN [咳嗽, 发烧] WITH d, collect(s.name) as matched_symptoms WHERE size(matched_symptoms) 2 RETURN d.name as disease, matched_symptoms 问题 “肺炎需要做什么检查” Cypher MATCH (d:Disease {{name: 肺炎}})-[:NEEDS_EXAM]-(e:Examination) RETURN d.name as disease, collect(e.name) as examinations 现在请为以下问题生成Cypher查询 问题 {question} Cypher )5.2 增加多轮对话记忆当前的系统是无状态的。为了实现多轮对话如用户追问需要引入对话记忆。我们可以使用LangChain的ConversationBufferMemory。# src/advanced_chain.py from langchain.memory import ConversationBufferMemory from langchain.chains import ConversationalRetrievalChain from langchain_community.chat_message_histories import StreamlitChatMessageHistory # 在Streamlit前端初始化记忆 msgs StreamlitChatMessageHistory(keylangchain_messages) memory ConversationBufferMemory(memory_keychat_history, chat_memorymsgs, return_messagesTrue) # 将记忆整合到检索链中需使用LangChain的特定Chain类 # 注意这需要调整之前的GraphCypherQAChain或使用更灵活的LCELLangChain Expression Language重新构建链。5.3 处理模糊查询与答案验证当用户问题模糊或图谱中无直接答案时系统应妥善处理。实体链接消歧 如果LLM抽取出“苹果”需要区分是水果还是公司。在医疗领域“心脏”可能指器官也可能指疾病“心脏病”。可以通过在提示词中强调医疗上下文或使用更专业的医学实体识别模型来改善。置信度与回退 在图检索后可以计算返回结果的“丰富度”如关联路径的条数、节点的度中心性。如果结果太稀疏则触发“回退”机制让LLM明确告知用户“知识库中未找到确切信息以下是一些一般性建议...”而不是强行编造。6. 常见问题与排查指南在开发和部署过程中你可能会遇到以下问题问题现象可能原因解决思路连接Neo4j失败1. URI、用户名或密码错误。2. AuraDB实例未启动或已暂停。3. 本地网络问题或防火墙阻止。1. 检查.env文件中的NEO4J_URI格式是否正确neo4js://。2. 登录AuraDB控制台确认实例状态为 “Running”。3. 尝试在浏览器中打开AuraDB提供的“Browser”链接用相同凭证登录测试。OpenAI API调用失败1. API Key无效或过期。2. 账户余额不足。3. 请求超时或网络问题。1. 在OpenAI平台检查API Key状态和余额。2. 尝试在命令行用curl或简单脚本测试API连通性。3. 考虑增加超时时间或使用代理需合规。LLM生成的Cypher语法错误1. 提示词不够清晰。2. LLM对图谱Schema理解有偏差。3. 问题过于复杂。1. 优化cypher_generation_prompt提供更具体的示例。2. 在提示词中更清晰地描述节点标签和关系类型。3. 增加一个“Cypher验证”步骤尝试执行查询如果失败则让LLM重试或简化问题。检索结果为空1. 知识图谱中确实没有相关信息。2. 实体抽取错误导致查询条件不匹配。3. Cypher查询逻辑过于严格。1. 在Neo4j Browser中手动执行生成的Cypher查询验证。2. 打印出LLM抽取的实体检查是否正确。3. 考虑使用模糊匹配CONTAINS或~或查询更广泛的关联路径。Streamlit前端无法连接后端1. 后端API服务 (src/api.py) 未启动。2. 前端代码中的API地址 (http://localhost:8000) 错误。3. 端口被占用。1. 确保在运行streamlit run前已在一个终端运行python src/api.py。2. 检查后端服务是否在预期的IP和端口上运行。3. 使用netstat -an | grep 8000(Linux/macOS) 或Get-NetTCPConnection -LocalPort 8000(Windows PowerShell) 查看端口占用。导入数据时出现编码错误JSON文件包含非UTF-8字符。确保JSON文件以UTF-8编码保存。在open()函数中明确指定encoding‘utf-8’。7. 项目扩展与毕业设计提升建议一个基础的GraphRAG系统已经完成。要让其成为出色的毕业设计可以考虑以下扩展方向丰富知识图谱数据源 从权威医学网站如默沙东诊疗手册、公开数据集如CHIP、CMeKG或医学文献中爬取或解析更多数据。关系深化 添加更多关系类型如COMPLICATION_WITH并发症、CONTRAINDICATION禁忌症、PREVENTION预防措施等。属性完善 为节点添加更多属性如疾病的发病率、高危人群药品的用法用量、副作用。实现混合检索结合向量检索。将疾病的描述文本、药品说明书等长文本进行向量化存储如使用ChromaDB、Milvus。当用户提出描述性、非结构化问题时如“描述一下糖尿病的典型表现”优先使用向量检索获取详细文本。当用户问题涉及明确实体和关系时如“A药和B药能一起吃吗”使用图检索。设计一个路由机制自动判断使用哪种或混合使用两种检索方式。增强系统可解释性在前端界面中不仅显示最终答案还可以可视化检索到的知识子图。利用Neo4j的Bloom或前端库如D3.js, vis.js将关联的疾病、症状节点和关系以图的形式展示出来让推理过程“看得见”。引入评估体系构建一个小的测试集QA对从准确性、相关性、完整性、安全性是否产生有害建议等维度评估系统性能。与传统的纯向量RAG系统进行对比实验用数据证明GraphRAG在关系推理问题上的优势。部署与工程化使用Docker容器化你的应用包括Python环境、依赖。编写Dockerfile和docker-compose.yml。尝试将服务部署到云服务器如阿里云ECS、腾讯云轻量应用服务器或云原生平台如Railway、Render并配置域名。这个项目从零到一的搭建过程完整覆盖了现代AI应用的核心环节数据处理、知识工程、大模型应用开发、前后端集成。它不仅是一个优秀的毕业设计更是你迈向AI工程师或LLM应用开发者的扎实一步。建议你在理解本文每个模块的基础上选择一个扩展方向深入实践这会让你的项目脱颖而出。