LangChain4j 项目实战--1:硅谷小智(医疗智能客服)笔记
通过@AiService注解声明 AI 服务,指定聊天模型、记忆提供者,结合@MemoryId实现提示词和会话控制。/*** 硅谷小智(北京协和医院智能客服)核心接口*/wiringMode = EXPLICIT, // 显式绑定模式(精准控制依赖)chatModel = "qwenChatModel", // 指定使用的大模型(如通义千问)chatMemoryProvider = "chatMe
·
一、项目背景与核心目标
基于 LangChain4j 实现北京协和医院智能客服(硅谷小智),核心功能包括:
- 医疗咨询:提供病因、诊断、治疗、预防等医疗建议;
- 就医伴诊:AI 分导诊、挂号查询 / 预约 / 取消;
- 会话能力:聊天记忆(上下文)、记忆持久化(MongoDB)、个性化提示词;
- 交互规范:友好礼貌、仅首次会话打招呼、跨领域咨询致歉、带可爱表情。
二、核心组件实现
2.1 1. 定义小智助手接口(XiaozhiAgent)
通过 @AiService 注解声明 AI 服务,指定聊天模型、记忆提供者,结合 @SystemMessage/@MemoryId/@UserMessage 实现提示词和会话控制。
package com.atguigu.java.ai.langchain4j.assistant;
import dev.langchain4j.service.*;
import dev.langchain4j.service.spring.AiService;
import static dev.langchain4j.service.spring.AiServiceWiringMode.EXPLICIT;
/**
* 硅谷小智(北京协和医院智能客服)核心接口
*/
@AiService(
wiringMode = EXPLICIT, // 显式绑定模式(精准控制依赖)
chatModel = "qwenChatModel", // 指定使用的大模型(如通义千问)
chatMemoryProvider = "chatMemoryProviderXiaozhi" // 绑定自定义的聊天记忆提供者
)
public interface XiaozhiAgent {
/**
* 核心聊天方法
* @param memoryId 会话记忆ID(用于隔离不同用户的上下文)
* @param userMessage 用户输入的问题
* @return 小智的回复
*/
@SystemMessage(fromResource = "zhaozhi-prompt-template.txt") // 从资源文件加载系统提示词
String chat(@MemoryId Long memoryId, @UserMessage String userMessage);
}
2.2 2. 系统提示词模板(zhaozhi-prompt-template.txt)
放置在 resources 根目录,定义小智的角色、规则、回复风格,包含 {{current_date}} 动态占位符(自动填充当前日期)。
txt
你的名字是“硅谷小智”,你是一家名为“北京协和医院”的智能客服。
你是一个训练有素的医疗顾问和医疗伴诊助手。
你态度友好、礼貌且言辞简洁。
### 核心规则
1. 仅在用户发起第一次会话时,和用户打个招呼,并介绍你是谁。
2. 作为医疗顾问:
请基于当前临床实践和研究,针对患者提出的特定健康问题,提供详细、准确且实用的医疗建议。
需包含可能的病因、诊断流程、治疗方案以及预防措施,并给出不同情境下的应对策略。
涉及药物治疗时,明确药品名称、剂量和疗程;需要就医/检查时,明确指示。
3. 作为医疗伴诊助手(挂号相关):
- AI分导诊:根据病情/需求推荐最合适的科室;
- AI挂号助手:支持查询号源、预约挂号、取消挂号;
- 操作挂号/取消挂号前,必须确认用户的姓名(必选)、身份证号(必选)、预约科室(必选)、预约日期(格式:2025-04-14,必选)、预约时间(上午/下午,必选)、预约医生(可选)。
4. 跨领域咨询:被问到医疗/挂号以外的问题时,致歉并说明无法提供帮助。
5. 回复风格:适当添加轻松可爱的图标和表情(如😊、💊、🏥)。
### 补充信息
今天是 {{current_date}}。
2.3 3. 配置聊天记忆(持久化 + 隔离)
通过 @Configuration 配置类创建 ChatMemoryProvider,实现会话记忆的持久化(MongoDB)和隔离(按 memoryId 区分用户),控制最大记忆消息数。
package com.atguigu.java.ai.langchain4j.config;
import dev.langchain4j.memory.ChatMemory;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.memory.store.MongoChatMemoryStore;
import dev.langchain4j.service.ChatMemoryProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 硅谷小智的聊天记忆配置
*/
@Configuration
public class XiaozhiAgentConfig {
// 注入MongoDB持久化存储对象(需提前配置MongoDB连接)
@Autowired
private MongoChatMemoryStore mongoChatMemoryStore;
/**
* 创建小智专属的聊天记忆提供者
* @return 按memoryId隔离的聊天记忆
*/
@Bean
ChatMemoryProvider chatMemoryProviderXiaozhi() {
// 为每个memoryId创建独立的MessageWindowChatMemory
return memoryId -> MessageWindowChatMemory.builder()
.id(memoryId) // 会话ID(用户唯一标识)
.maxMessages(20) // 最大记忆20条消息(控制上下文长度)
.chatMemoryStore(mongoChatMemoryStore) // 持久化到MongoDB
.build();
}
}
2.4 4. 封装对话请求对象(ChatForm)
统一接收前端 / 测试端的对话请求参数,包含会话 ID 和用户消息。
package com.atguigu.java.ai.langchain4j.bean;
import lombok.Data;
/**
* 聊天请求表单对象
*/
@Data // Lombok注解,自动生成get/set/toString等方法
public class ChatForm {
private Long memoryId; // 对话ID(用户唯一标识,用于记忆隔离)
private String message;// 用户输入的问题/指令
}
2.5 5. 控制器层(Controller)
暴露接口供外部调用,接收用户请求并转发给 XiaozhiAgent。
package com.atguigu.java.ai.langchain4j.controller;
import com.atguigu.java.ai.langchain4j.assistant.XiaozhiAgent;
import com.atgu.java.ai.langchain4j.bean.ChatForm;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
/**
* 硅谷小智前端交互接口
*/
@RestController
public class XiaozhiController {
@Autowired
private XiaozhiAgent xiaozhiAgent;
/**
* 聊天接口
* @param chatForm 聊天请求参数(memoryId + message)
* @return 小智的回复
*/
@PostMapping("/xiaozhi/chat")
public String chat(@RequestBody ChatForm chatForm) {
// 调用小智核心方法
return xiaozhiAgent.chat(chatForm.getMemoryId(), chatForm.getMessage());
}
}
2.6 6. 测试方法
package com.atguigu.java.ai.langchain4j;
import com.atguigu.java.ai.langchain4j.assistant.XiaozhiAgent;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
public class XiaozhiAgentTest {
@Autowired
private XiaozhiAgent xiaozhiAgent;
/**
* 测试小智核心功能
*/
@Test
public void testXiaozhiChat() {
// 第一次会话(memoryId=1,用户首次提问)
String answer1 = xiaozhiAgent.chat(1L, "我最近胃疼,该怎么办?");
System.out.println("小智回复1:" + answer1);
// 预期回复:打招呼+医疗建议(如“你好呀😊!我是硅谷小智,协和医院的智能客服~胃疼可能是胃炎/胃溃疡等原因💊,建议先做胃镜检查🏥,日常避免辛辣饮食...)
// 第二次会话(同一memoryId,上下文连续)
String answer2 = xiaozhiAgent.chat(1L, "那我该挂哪个科室?");
System.out.println("小智回复2:" + answer2);
// 预期回复:基于上文推荐科室(如“胃疼建议挂消化内科哦😜,消化内科主要处理胃肠相关疾病~”)
// 跨领域咨询测试
String answer3 = xiaozhiAgent.chat(1L, "怎么订机票?");
System.out.println("小智回复3:" + answer3);
// 预期回复:致歉(如“抱歉呀😅,我是协和医院的智能客服,暂时无法解答订机票的问题哦~”)
}
}
三、待优化与扩展方向
3.1 1. 信息查询能力增强(RAG 检索增强生成)
当前提示词仅定义规则,但缺乏医院 / 科室 / 医生的真实数据,需结合 RAG 实现精准信息查询:
- 数据准备:将协和医院的位置、营业时间、科室列表、医生信息(职称、擅长领域、出诊时间)存入向量数据库(如 Milvus/PGVector);
- RAG 集成:在
XiaozhiAgent中添加 RAG 检索逻辑,用户询问 “协和医院在哪”“消化内科有哪些医生” 时,从向量库检索真实数据并生成回复; - 优势:避免大模型 “幻觉”,保证信息准确。
3.2 2. 业务功能落地(Function Calling 函数调用)
当前仅定义了挂号 / 取消挂号的规则,需通过 Function Calling 对接真实业务系统:
- 步骤 1:定义业务函数(如查询号源、预约挂号、取消挂号):
// 挂号服务接口 public interface RegistrationService { // 查询科室号源 String queryRegistrationSource(String department, String date); // 预约挂号 String register(String name, String idCard, String department, String date, String time, String doctor); // 取消挂号 String cancelRegistration(String name, String idCard, String department, String date); } - 步骤 2:在 LangChain4j 中配置 Function Calling,让大模型根据用户指令自动调用上述函数;
- 步骤 3:函数执行结果返回给大模型,由大模型整理成自然语言回复用户(如 “已为你预约 2025-04-14 上午消化内科张医生的号😘,请携带身份证前往就诊~”)。
3.3 3. 其他优化点
- 参数校验:在 Controller 层校验
ChatForm的memoryId和message非空,挂号相关指令校验姓名 / 身份证等必填参数; - 异常处理:添加全局异常处理器,捕获大模型调用 / 数据库 / 业务系统异常,返回友好提示;
- 多轮会话优化:调整
maxMessages数量,平衡上下文长度和性能; - 表情 / 格式标准化:定义固定的表情库,避免回复风格混乱。
四、核心总结
- 硅谷小智的核心是
@AiService注解的XiaozhiAgent接口,通过@SystemMessage定义角色 / 规则,@MemoryId实现会话隔离; - 聊天记忆通过
ChatMemoryProvider配置,结合MongoChatMemoryStore实现持久化,maxMessages控制上下文长度; - 现阶段实现了基础的医疗咨询 / 伴诊规则,后续需通过 RAG 补充真实信息、Function Calling 对接业务系统,完成功能落地。
更多推荐



所有评论(0)