SpringBoot项目实战:用LangChain4J + 通义千问快速搭建一个带记忆的AI客服(附完整代码)
SpringBoot实战基于LangChain4J与通义千问构建智能医疗客服系统在医疗健康领域AI客服系统正逐渐成为提升患者体验、优化医疗资源分配的重要工具。本文将手把手带你实现一个具备多轮对话记忆功能的智能医疗客服系统基于SpringBoot框架整合LangChain4J与阿里云通义千问大模型从零开始构建完整的解决方案。1. 项目架构设计与技术选型医疗行业的智能客服需要处理复杂的专业咨询同时要保证对话的连贯性和准确性。我们的系统架构分为三个核心层接入层SpringBoot RESTful API提供HTTP接口业务逻辑层LangChain4J实现的大模型交互与记忆管理基础设施层通义千问大模型持久化存储技术栈对比表技术选项优势适用场景LangChain4J简化大模型集成内置记忆管理Java生态的AI应用开发通义千问中文理解能力强医疗领域优化专业领域问答场景MongoDB文档型存储适合非结构化数据对话历史存储提示医疗行业对数据安全性要求极高建议生产环境使用加密存储和传输首先创建SpringBoot项目添加关键依赖dependencies !-- LangChain4J 核心 -- dependency groupIddev.langchain4j/groupId artifactIdlangchain4j-spring-boot-starter/artifactId version0.25.0/version /dependency !-- 通义千问适配器 -- dependency groupIddev.langchain4j/groupId artifactIdlangchain4j-community-dashscope-spring-boot-starter/artifactId version0.25.0/version /dependency !-- MongoDB持久化 -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-data-mongodb/artifactId /dependency /dependencies2. 大模型接入与基础配置在application.yml中配置通义千问的访问参数langchain4j: community: dashscope: chat-model: api-key: ${DASHSCOPE_API_KEY} model-name: qwen-max temperature: 0.7 max-retries: 3 spring: data: mongodb: uri: mongodb://localhost:27017/medical_chatbot创建基础的对话测试类验证连接SpringBootTest public class QwenConnectionTest { Autowired private QwenChatModel chatModel; Test void testBasicChat() { String response chatModel.generate(你好请用专业医疗术语回答); System.out.println(模型响应 response); } }3. 实现多轮对话记忆系统医疗咨询往往需要多轮交互才能完成我们通过LangChain4J的ChatMemory机制实现对话记忆。3.1 基础记忆实现Configuration public class ChatMemoryConfig { Bean Scope(value WebApplicationContext.SCOPE_REQUEST, proxyMode ScopedProxyMode.TARGET_CLASS) public ChatMemory chatMemory() { return MessageWindowChatMemory.withMaxMessages(20); } }创建AI服务接口AiService public interface MedicalChatAgent { SystemMessage( 你是三甲医院专业医疗助手回答需符合临床指南。 当不确定时应建议患者面诊。 ) String chat(UserMessage String message); }3.2 记忆隔离与持久化不同患者的对话需要隔离存储我们实现MongoDB持久化Component public class MongoChatMemoryStore implements ChatMemoryStore { Autowired private MongoTemplate mongoTemplate; Override public ListChatMessage getMessages(Object memoryId) { Query query new Query(Criteria.where(sessionId).is(memoryId)); ChatSession session mongoTemplate.findOne(query, ChatSession.class); return session ! null ? ChatMessageDeserializer.messagesFromJson(session.getMessages()) : new ArrayList(); } Override public void updateMessages(Object memoryId, ListChatMessage messages) { Query query new Query(Criteria.where(sessionId).is(memoryId)); Update update new Update() .set(messages, ChatMessageSerializer.messagesToJson(messages)) .set(lastUpdated, Instant.now()); mongoTemplate.upsert(query, update, ChatSession.class); } }4. 医疗专业功能增强4.1 科室分诊功能实现智能分诊工具类Tool(根据症状推荐就诊科室) public class DepartmentTriageTool { private static final MapString, String SYMPTOM_DEPARTMENT Map.of( 头痛发热, 发热门诊, 胸痛, 心血管内科, 腹痛, 消化内科 ); ToolMemoryId private String sessionId; public String triage(P(患者描述的症状) String symptoms) { return SYMPTOM_DEPARTMENT.getOrDefault(symptoms, 请到分诊台咨询); } }4.2 用药提醒功能Tool(提供药品用法用量建议) public class MedicationAdvisor { public String advise( P(药品名称) String medicine, P(患者年龄) int age, P(特殊状况) String condition) { // 实际项目中应接入药品知识库 return switch(medicine.toLowerCase()) { case 阿司匹林 - 成人每日75-100mg餐后服用; case 布洛芬 - age 12 ? 每次200mg每6小时一次 : 请咨询儿科医生; default - 请遵医嘱或查看药品说明书; }; } }5. RESTful API封装创建SpringBoot控制器暴露服务接口RestController RequestMapping(/api/medical-chat) public class MedicalChatController { Autowired private MedicalChatAgent chatAgent; PostMapping(/chat) public ResponseEntityChatResponse handleChat( RequestBody ChatRequest request, RequestHeader(X-Session-ID) String sessionId) { String response chatAgent.chat(request.getMessage()); return ResponseEntity.ok(new ChatResponse(response)); } }使用Swagger文档化APIConfiguration public class SwaggerConfig { Bean public OpenAPI medicalChatOpenAPI() { return new OpenAPI() .info(new Info().title(智能医疗助手API) .version(1.0) .description(基于大模型的医疗咨询系统)); } }6. 系统优化与扩展6.1 性能监控添加Prometheus监控指标Configuration public class MetricsConfig { Bean MeterRegistryCustomizerMeterRegistry metricsCommonTags() { return registry - registry.config().commonTags( application, medical-chatbot); } Bean public TimedAspect timedAspect(MeterRegistry registry) { return new TimedAspect(registry); } }6.2 知识库增强实现RAG(检索增强生成)流程Component public class MedicalKnowledgeRetriever { Autowired private EmbeddingStoreTextSegment embeddingStore; Autowired private EmbeddingModel embeddingModel; public String retrieveRelevantInfo(String query) { // 1. 将查询转换为向量 Embedding queryEmbedding embeddingModel.embed(query).content(); // 2. 在向量库中搜索相似内容 ListEmbeddingMatchTextSegment relevantMatches embeddingStore.findRelevant(queryEmbedding, 3); // 3. 返回最相关的文本片段 return relevantMatches.stream() .map(match - match.embedded().text()) .collect(Collectors.joining(\n\n)); } }7. 部署与测试建议7.1 容器化部署Dockerfile示例FROM eclipse-temurin:17-jdk-jammy WORKDIR /app COPY target/medical-chatbot.jar app.jar EXPOSE 8080 ENTRYPOINT [java, -jar, app.jar]7.2 压力测试要点对话响应时间应控制在3秒内支持至少100并发会话记忆检索延迟500ms医疗AI系统的开发需要特别关注准确性和安全性。在实际部署前建议进行全面的医学专业测试并设置人工审核环节。系统应明确告知用户其辅助性质关键医疗决策仍需专业医生做出。