ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

LLM大模型+微信小程序:基于RAG与知识图谱的AI医疗问诊系统设计

LLM大模型+微信小程序:基于RAG与知识图谱的AI医疗问诊系统设计 做毕业设计最怕什么不是不会写代码而是“看起来像管理系统”。学生管理系统、图书管理系统、外卖点餐系统——这些题目做了十年答辩评委看了十年早就审美疲劳了。但如果你做的是LLM 大模型 微信小程序 AI 智能医疗问诊平台技术栈里同时出现 RAG、Spring AI、Neo4j 知识图谱、Spring Boot、Vue 3评委的第一反应一定是这个学生跟得上时代。这篇文章就是来拆解这个毕业设计项目的。我会从零开始讲清楚每一个技术组件的作用、它们如何串联成一条完整的数据链路以及哪些地方最容易踩坑。无论你是刚准备开题还是已经写了一半代码正在调试这篇文章都值得收藏。1. 这篇文章真正要解决的问题这个项目标题看起来很长拆开看其实是三个核心问题第一大模型怎么在微信小程序里变成一个能用的产品直接调 OpenAI 接口不行吗答案是在国内环境、毕业设计场景、医疗垂直领域下直接调通用大模型接口既不符合项目稳定性要求也体现不出专业度。你需要一个自己的知识引擎。第二RAG 和知识图谱在医疗问诊里到底怎么落地很多同学对 RAG 的理解停留在“向量数据库 相似度检索”但医疗场景有它特殊的地方——需要精确的实体关系比如“高血压”和“心内科”之间的归属关系需要可解释的推理路径而不是单纯的“语义相似”。这就是 Neo4j 知识图谱登场的原因。第三一个完整的 AI 全栈项目应该长什么样从数据采集、知识抽取、图谱构建、向量化、接口服务、小程序展示到部署上线这中间涉及的工具链和工程思路才是毕业设计真正的加分项。阅读这篇文章的读者我假设你已经具备 Java 基础和基本的 Web 开发概念。如果你还没接触过 AI 项目这篇文章会帮你建立整体认知如果你正在做类似项目后面的代码和配置可以直接参考。2. 技术选型与核心概念速通2.1 为什么是 Spring AI 而不是直接调 HTTP 接口Spring AI 是 Spring 官方推出的 AI 应用开发框架它的核心价值不是“多了一个调用大模型的封装”而是把模型接入、Prompt 管理、RAG 检索、结构化输出这几个高频操作统一成了 Spring 风格的编程模型。你可以把它类比成 Spring Boot 对数据库的整合——以前你用 JDBC 手写连接、手写事务后来 MyBatis 帮你搞定现在 Spring AI 做的就是把“调用大模型 处理上下文 管理 Prompt”这件事标准化了。在医疗问诊场景中Spring AI 的Advisor 机制非常有用。你可以在对话链路上统一注入系统 Prompt、知识检索器、日志记录器就像 Spring MVC 拦截器一样。这个设计让“每次问诊前先查知识图谱再组装上下文”的逻辑变得非常优雅。2.2 RAG 到底是什么医疗场景为什么需要它RAGRetrieval-Augmented Generation检索增强生成是目前企业落地大模型应用的主流方案。它的核心思想是不指望大模型记住所有知识而是先从一个外部知识源文档库、数据库、知识图谱里检索出与用户问题最相关的内容再把检索结果作为上下文交给大模型生成答案。用通俗的话说大模型像一个博学的医生但他可能会记错细节RAG 是给他一本可以随时翻阅的医学手册每次回答问题前先翻一下手册再开口。在医疗问诊场景中RAG 解决的是幻觉问题。通用大模型在你问“感冒了应该挂什么科”时可能会答出一些通用建议但无法结合你所在医院的实际科室设置、药品目录、医生排班来回答。通过 RAG 接入医院自己的知识库和知识图谱之后答案就有了数据支撑和可追溯来源。2.3 Neo4j 知识图谱补足了什么RAG 如果只用向量检索本质上还是“语义模糊匹配”它不知道“糖尿病”和“内分泌科”之间的明确关系也不知道“胰岛素”是“糖尿病”的“治疗药物”。这些实体关系在向量空间里是隐性的、不精确的。Neo4j 图数据库的价值在于它把实体和关系显式地建模出来。你可以直接查询“从糖尿病出发经治疗药物再关联到哪几个科室”图数据库会沿着关系边给出一条清晰的路径。这在医疗推理中尤其重要因为医疗决策需要的是可解释的路径而不是一个黑盒的概率得分。2.4 整体技术栈一览层级技术选型职责前端展示微信小程序用户对话入口、问诊结果展示管理后台Vue 3 Element Plus管理员维护知识库、查看问诊日志可选后端服务Spring Boot统一接口、业务逻辑、权限控制AI 编排Spring AI大模型接入、Prompt 管理、RAG 链路知识存储Neo4j 向量数据库实体关系图谱 文档向量索引大模型通义千问 / DeepSeek 等最终问答生成这个技术栈的每条链路都不是多余的微信小程序解决触达问题Spring Boot 解决工程化问题Spring AI 解决 AI 集成问题Neo4j 解决知识结构化问题向量库解决语义检索问题。3. 环境准备与前置条件在开始写代码之前环境搭建是最基础也是最容易出问题的一步。以下是我推荐的环境清单依赖项推荐版本/方案备注JDKJDK 17 及以上Spring Boot 3.x 要求 JDK 17 起步Maven3.8依赖管理Node.js18前端构建工具链Neo4j社区版 5.x如果本机安装不方便用 DockerDocker Desktop最新稳定版推荐用于 Neo4j 和向量库微信开发者工具最新稳定版小程序调试大模型 API Key阿里云百炼 / DeepSeek 开放平台申请一个即可版本提醒上述版本是当前主流实践的通用推荐具体以你项目实际使用的版本为准。如果你的 Spring Boot 版本或 Spring AI 版本不同个别配置类名称可能有差异但整体架构思路不变。3.1 用 Docker 安装 Neo4jNeo4j 在本机安装稍微有点麻烦推荐直接用 Docker。先确保 Docker Desktop 已启动然后执行docker run -d \ --name neo4j \ -p 7474:7474 -p 7687:7687 \ -e NEO4J_AUTHneo4j/yourpassword \ -v $HOME/neo4j/data:/data \ neo4j:5.19.0-community启动完成后浏览器访问http://localhost:7474用neo4j / yourpassword登录就能看到 Neo4j Browser 管理界面。如果没有 Docker 环境也可以从 Neo4j 官网下载 Desktop 桌面版或 Community Server 直接运行Windows 用户注意配置NEO4J_HOME环境变量。3.2 向量数据库选型Neo4j 5.x 本身提供了向量索引功能如果你的数据量不大可以直接把向量存在 Neo4j 里少做一个中间件。如果数据量较大再引入 Milvus 或 Chroma。毕业设计场景下优先使用 Neo4j 自带的向量索引部署简单、演示方便。4. 系统整体架构与数据流设计这个项目的架构我建议画成一条流水线来理解医疗数据采集 - 知识抽取 - 实体/关系入库(Neo4j) - 文本切片向量化(向量索引) - 小程序提问 - Spring AI 接收 - 识别意图 - 图查询(Neo4j Cypher) 向量检索(相似度) - 组装 Prompt - 大模型生成 - 返回小程序展示4.1 数据从哪里来医疗数据的来源可以有很多种公开的医学知识库如症状-疾病-科室对应关系医院科室介绍、医生排班表、药品说明书医学教材、临床指南的公开摘要毕业设计阶段不需要追求数据量庞大但要保证数据质量。建议准备300 到 500 条高质量的结构化医疗数据覆盖常见科室、常见症状、常见疾病、常用药物这四类实体以及它们之间的关系。4.2 项目工程结构后端部分推荐按以下包结构组织src/main/java/com/example/medical/ ├── MedicalApplication.java ├── config/ │ ├── Neo4jConfig.java │ ├── SpringAiConfig.java │ └── VectorStoreConfig.java ├── controller/ │ └── ChatController.java ├── service/ │ ├── ChatService.java │ ├── MedicalGraphService.java │ └── RAGService.java ├── repository/ │ ├── DiseaseRepository.java │ └── ...... ├── entity/ │ ├── Disease.java │ ├── Symptom.java │ └── Department.java └── vo/ └── ChatResponse.java这个结构遵循了 Spring Boot 官方推荐的分层架构controller 只负责 HTTP 协议转换service 负责业务逻辑repository 负责数据访问。后续写毕业设计文档时这个结构也方便你画架构图。5. 医疗知识图谱构建实战5.1 在 Neo4j 中创建实体和关系首先在 Neo4j Browser 中执行一段 Cypher创建最基础的医疗本体。这里以“感冒”为例CREATE (d:Disease {name: 感冒, category: 呼吸系统疾病, description: 由多种病毒引起的上呼吸道感染}) CREATE (s1:Symptom {name: 发热, description: 体温超过37.3℃}) CREATE (s2:Symptom {name: 咳嗽, description: 干咳或有痰咳嗽}) CREATE (s3:Symptom {name: 鼻塞, description: 鼻腔阻塞呼吸不畅}) CREATE (dep:Department {name: 呼吸内科, location: 门诊楼2层, phone: 010-88888888}) CREATE (drug:Drug {name: 布洛芬, usage: 成人一次0.2g一日不超过4次}) CREATE (d)-[:HAS_SYMPTOM]-(s1) CREATE (d)-[:HAS_SYMPTOM]-(s2) CREATE (d)-[:HAS_SYMPTOM]-(s3) CREATE (d)-[:TREATED_IN]-(dep) CREATE (d)-[:TREATMENT_DRUG]-(drug)这段 Cypher 创建了四类节点和四类关系HAS_SYMPTOM疾病有哪些症状TREATED_IN疾病对应哪个科室TREATMENT_DRUG治疗药物有了这个基础结构后续查询就变得很直观。例如当用户提问“我发烧咳嗽应该挂什么科”时项目可以先提取症状实体“发烧”“咳嗽”再用 Cypher 查询MATCH (s:Symptom)-[:HAS_SYMPTOM]-(d:Disease)-[:TREATED_IN]-(dep:Department) WHERE s.name IN [发热, 咳嗽] RETURN d.name AS disease, dep.name AS department, dep.location AS location LIMIT 5这个查询的价值在于它用图数据库的关系路径把“症状 - 疾病 - 科室”这条推理链路一次性查出来。这在纯向量检索里很难做到因为向量检索只能告诉你“这段文本和那段文本语义相近”无法告诉你“这两个实体之间有一条确切的治疗关系”。5.2 通过 Java 操作 Neo4j在 Spring Boot 项目中引入 Neo4j 官方驱动dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-data-neo4j/artifactId /dependency然后在application.yml中配置连接信息spring: data: neo4j: uri: bolt://localhost:7687 username: neo4j password: yourpassword接着创建一个查询服务Service public class MedicalGraphService { private final Neo4jClient neo4jClient; public MedicalGraphService(Neo4jClient neo4jClient) { this.neo4jClient neo4jClient; } public ListMapString, Object findDepartmentsBySymptoms(ListString symptoms) { String cypher MATCH (s:Symptom)-[:HAS_SYMPTOM]-(d:Disease)-[:TREATED_IN]-(dep:Department) WHERE s.name IN $symptoms RETURN d.name AS disease, dep.name AS department, dep.location AS location LIMIT 5 ; return neo4jClient.query(cypher) .bind(symptoms).to(symptoms) .fetch().all().stream() .map(row - (MapString, Object) row) .collect(Collectors.toList()); } }这里的Neo4jClient是 Spring Data Neo4j 提供的客户端对象支持参数绑定、异步查询等能力。注意 Cypher 里的$symptoms是一个参数占位符必须在bind方法中指定对应的值这样可以防止 Cypher 注入和 SQL 预编译是同一个道理。6. 后端 RAG 检索链路实现6.1 引入 Spring AI 依赖以 Spring AI 接入通义千问或者 DeepSeek 为例不同模型厂商的依赖坐标略有区别但结构类似dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-starter-model-qwen/artifactId /dependency dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-starter-vector-store-neo4j/artifactId /dependency然后在配置文件中写入模型 API Keyspring: ai: model: qwen: api-key: ${DASHSCOPE_API_KEY} base-url: https://dashscope.aliyuncs.com/compatible-mode/v1 options: model: qwen-plus如果你的模型支持 OpenAI 兼容协议也可以使用spring-ai-starter-model-openai作为 starter然后通过配置切换供应商。这个灵活性是 Spring AI 的一个优势。6.2 实现混合检索医疗问诊的 RAG 链路我的建议是不要只做向量检索而是做“图谱精确检索 向量语义检索”的组合Service public class RAGService { private final MedicalGraphService graphService; private final VectorStore vectorStore; public RAGService(MedicalGraphService graphService, VectorStore vectorStore) { this.graphService graphService; this.vectorStore vectorStore; } public String buildContext(String userQuestion) { // 1. 从问题中粗略提取症状关键词这里可以调用大模型做实体抽取 ListString symptoms extractSymptoms(userQuestion); // 2. 图谱精确查询 ListMapString, Object graphResult graphService.findDepartmentsBySymptoms(symptoms); // 3. 向量语义检索 ListDocument docs vectorStore.similaritySearch( SearchRequest.query(userQuestion).withTopK(5) ); // 4. 组装上下文 StringBuilder context new StringBuilder(); context.append(【知识图谱信息】\n).append(graphResult).append(\n\n); context.append(【相关医疗资料】\n); for (Document doc : docs) { context.append(doc.getContent()).append(\n); } return context.toString(); } }这里有一个核心设计思路知识图谱负责精确向量检索负责开放。用户问“感冒挂什么科”时图谱直接给出科室名称和位置用户问“感冒期间饮食上有什么注意事项”时图谱可能没有这个内容此时向量检索会从医疗文档中找到相关资料。6.3 用 Advisor 统一对话链路Spring AI 的 Advisor 机制非常像 Spring MVC 拦截器。你可以在它里面实现“先检索再组装 Prompt再调用模型”的固定流程Configuration public class SpringAiConfig { Bean public ChatClient chatClient(RAGService ragService) { return ChatClient.builder() .defaultAdvisors(new QuestionAnswerAdvisor(ragService)) .defaultSystem( 你是一个专业的医疗导诊助手。请基于提供的医疗知识回答问题。 如果知识库中没有明确依据请如实告知用户需要前往医院就诊。 回答时要求 1. 先给出最可能的科室建议 2. 再补充疾病和症状解释 3. 最后给出免责声明本回答仅供参考不能替代专业医生诊断。 ) .build(); } }这里的关键是QuestionAnswerAdvisor它的作用是在每次调用模型前自动查询你的知识库把检索结果注入到 Prompt 中。这个机制让“每次提问都携带最新知识”成为默认行为不需要在每个业务方法里手动拼 Prompt。6.4 完整问答接口Controller 层只需要一个很薄的接口RestController RequestMapping(/api/chat) public class ChatController { private final ChatClient chatClient; public ChatController(ChatClient chatClient) { this.chatClient chatClient; } PostMapping(/ask) public ChatResponse ask(RequestBody AskRequest request) { String answer chatClient.prompt() .user(request.getQuestion()) .call() .content(); return ChatResponse.success(answer); } } public class AskRequest { private String question; // getter / setter 省略 }从 600 行手写 HTTP 调用大模型的代码到 10 行 Spring AI 接口这就是框架的价值把复杂的 AI 集成变成了标准的 Spring 编程。7. 微信小程序端实现7.1 小程序页面结构小程序端至少要包含两个页面pages/index/index用户输入症状或问题选择“智能问诊”pages/result/result展示 AI 回答、推荐科室、注意事项用微信开发者工具创建项目后页面配置如下// pages/index/index.json { navigationBarTitleText: AI智能问诊, usingComponents: {} }7.2 调用后端接口小程序的网络请求需要先在小程序后台配置域名白名单。开发阶段可以勾选“不校验合法域名”。// pages/index/index.js Page({ data: { question: , loading: false }, handleInput(e) { this.setData({ question: e.detail.value }); }, async submitQuestion() { const { question } this.data; if (!question.trim()) { wx.showToast({ title: 请输入症状描述, icon: none }); return; } this.setData({ loading: true }); try { const res await new Promise((resolve, reject) { wx.request({ url: http://localhost:8080/api/chat/ask, method: POST, header: { Content-Type: application/json }, data: { question: question }, success: resolve, fail: reject }); }); if (res.data.code 200) { wx.navigateTo({ url: /pages/result/result?answer${encodeURIComponent(res.data.data.answer)} }); } else { wx.showToast({ title: 服务异常, icon: none }); } } catch (err) { wx.showToast({ title: 网络请求失败, icon: none }); } finally { this.setData({ loading: false }); } } })这里需要注意两个问题。第一个如果后端跑在本地电脑小程序开发者工具必须在“详情 - 本地设置”中打开“不校验合法域名”否则请求会被拦截。第二个真机调试时localhost 会指向手机而不是电脑需要改成电脑在局域网中的 IP 地址。7.3 结果展示页面结果页除了展示 AI 回答文本还可以用卡片组件展示推荐科室和注意事项view classpage view classanswer-card text classanswer-text{{answer}}/text /view view classtips-card text classtips-title温馨提示/text text classtips-content本回答仅供参考不能替代专业医生诊断。/text /view /view这个小程序端的核心价值是用微信生态的触达能力把 AI 能力封装成一个用户无感的问诊入口。用户不需要懂大模型是什么只需要输入症状拿到建议。8. 系统联调与效果验证8.1 启动顺序正确的启动顺序如下先启动 Neo4jDocker 或本机确认 Neo4j Browser 能访问数据已导入启动 Spring Boot 后端用 Postman 或浏览器访问POST http://localhost:8080/api/chat/ask后端确认正常后再打开微信开发者工具运行小程序8.2 后端接口验证用 curl 测试接口curl -X POST http://localhost:8080/api/chat/ask \ -H Content-Type: application/json \ -d {question: 我最近两天发烧、咳嗽应该挂什么科}预期返回格式{ code: 200, message: success, data: { answer: 根据您的症状发热、咳嗽建议优先前往呼吸内科就诊。呼吸内科位于门诊楼2层出诊时间为周一至周五上午8:00-12:00下午13:30-17:00。您描述的症状可能与上呼吸道感染如感冒有关就诊前请注意休息、多饮水。本回答仅供参考不能替代专业医生诊断。 } }如果结果里出现了知识图谱中的科室信息说明整条链路已经打通如果回答纯粹是大模型生成的通用内容说明 RAG 检索可能没有命中需要检查该疾病是否已经导入 Neo4j。8.3 效果量化评估毕业设计答辩时评委大概率会问“你的系统效果怎么评估”建议提前准备三个维度的验证记录知识命中率准备 100 个常见问诊问题统计系统答案中是否包含正确科室或药品信息响应延迟记录从用户提问到返回答案的平均耗时目标是 3 秒以内有无幻觉内容人工检查回答中是否存在知识库之外的编造内容这些数据不需要很庞大但一定要真实记录。可以用一张 Excel 表记录测试日期、问题、预期答案、系统答案、是否命中。答辩时展示这个表比任何口头描述都有说服力。9. 常见问题与排查思路问题现象可能原因排查方式解决方案Neo4j 无法启动端口 7474/7687 被占用lsof -i:7474查看占用进程释放端口或更换映射端口Cypher 查询结果为 null实体名称大小写不匹配在 Neo4j Browser 中执行同样的 Cypher 检查统一实体命名注意代码和 CQL 名称完全一致Spring AI 调用大模型超时网络不通或 API Key 无效检查日志中的状态码用 curl 直接调用 API 测试确认 API Key 额度检查代理配置向量检索始终为空向量索引未创建或未执行写入查看 Neo4j 索引信息执行向量索引创建脚本确认向量字段维度一致小程序请求返回 404后端接口路径写错或服务未启动在小程序调试器中查看网络请求详情核对 controller 路径与小程序 url确认后端已启动大模型回答完全没用到知识库内容Advisor 链路未生效或上下文长度不够开启 Spring AI 日志打印 Prompt 内容检查 Advisor 注册是否正确适当增大 maxToken真机预览时无法请求后端手机与电脑不在同一网络用浏览器访问局域网 IP 测试后端将小程序请求地址改为局域网 IP并关闭电脑防火墙排查时最有效的方法是先跑通一条最小链路再逐步加依赖。比如先直接用 Postman 调用后端接口确认后端没问题再用 curl 调模型 API 确认 Key 没问题最后再回过来看小程序端的错误。10. 毕业设计中的加分项与工程建议10.1 四个加分设计第一数据可视化。Neo4j Browser 本身就能展示知识图谱但这只是给开发者看的。建议在管理后台留一个图谱展示页面用 Vue 3 关系图组件把“症状-疾病-科室-药物”的网络关系展示出来。答辩时演示效果极佳。第二多轮对话记忆。Spring AI 中可以通过ChatMemory实现对话记忆让用户可以追问“那这个药有副作用吗”。虽然毕业设计不要求做到产品级但实现一个简单的基于 Session 的对话记忆能体现工程完整度。第三完善的异常处理。给全局加上RestControllerAdvice统一返回错误码和提示信息。这个细节很多人忽略但是阅卷老师调接口、看代码时规范错误处理会留下很好的印象。第四测试用例。给MedicalGraphService和ChatService各写几个单元测试用 H2 或 Neo4j Test 容器模拟数据。答辩被追问“你测过吗”时直接打开测试类演示。10.2 数据合规与安全涉及医疗数据务必要注意项目演示数据必须脱敏不能使用真实患者的病历信息。药品、科室、疾病描述可以使用公开医学知识库内容但需要在毕业设计文档中注明数据来源。系统内展示的诊断内容必须附带“仅供参考不能替代专业医生诊断”的免责声明。这个细节不仅影响学术规范也是 AI 医疗应用的基本伦理底线。另外项目中的 API Key 不要硬编码到代码里建议通过环境变量或配置文件外部化。答辩时这一点还能体现你对工程安全的思考。10.3 答辩时需要讲清楚的一个核心观点答辩时最容易打动评委的一个表述是“这个项目不是简单地把大模型接入小程序。它做的是把医疗知识先结构化到 Neo4j 图数据库中再结合 RAG 向量检索形成一个混合检索的知识增强问答链路。大模型在这里不是知识库而是生成器真正的知识来源是项目自建的医疗知识图谱和医疗文档库。”这段话简洁、有深度能体现出你对技术选型背后原因的理解。11. 总结与后续学习方向这个毕业设计项目最值得学习的地方不在于某个单一技术有多深而在于它展示了一条非常完整的“数据 - 知识 - 检索 - 生成 - 产品”的 AI 应用管线。每个环节都不是孤立的Neo4j 图谱为 RAG 提供了结构化的精确知识RAG 为 Spring AI 提供了可扩展的上下文Spring AI 又为小程序提供了稳定的后端服务。如果时间允许下一步可以深入的方向有三个第一个把实体抽取做得更智能不依赖关键词匹配而是用大模型做 Slot Filling让用户用自然语言描述时也能准确识别结构化实体第二个引入 Agent 机制让模型根据问题复杂度决定是只查图谱、只查向量库、还是两者都查第三个将问诊结果沉淀回知识库实现基于用户反馈的知识增量更新。建议把这个项目当成“第一个 AI 全栈项目”来做先跑通最小链路再逐层加功能。过程中的每一个报错都是你答辩论据的一部分。先把知识图谱建起来把接口跑通你的毕业设计就已经成功了一大半。
返回列表