Spring+LangChain4j小智医疗项目
这里写目录标题
- LangChain4j入门
- 配置
- 测试
- Ollama
- 阿里云百炼平台
- AIService
- 聊天记忆
- 隔离聊天
- MongoDB
- 持久化存储
- Prompt
- *创建小智医疗助手
- Function Calling(Tools)
- 实战小智医疗智能体
- RAG
- Token分词器
- 向量存储
- 流式输出
- 总结
LangChain4j入门
LangChain4j 是一个用于构建基于大型语言模型(LLM)应用的 Java 框架,它简化了与 OpenAI、Hugging Face 等 LLM 服务的集成,并提供了工具链来构建复杂的 LLM 应用。
配置
<dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j-open-ai-spring-boot-starter</artifactId><version>1.0.0-beta3</version>
</dependency>
在yml配置api_key,base_ur,model_name必需项
一般将APIKEY保存在系统环境变量中,用System.getenv()
获取
测试
@Autowiredprivate OpenAiChatModel openAiChatModel;@Testpublic void testChat() {String question = "java的特性";String ans = openAiChatModel.chat(question);System.out.println(ans);}
Ollama
Ollama是一个允许开发者在本地计算环境中运行模型的工具。
- 选择模型:
- 输入命令行 ollama run deepseek-r1:1.5b
- 本地项目配置
<dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j-ollama</artifactId><version>1.0.0-beta3</version>
</dependency>
阿里云百炼平台
在线集成了阿里的通义系列大模型和第三方大模型,涵盖文本、
图像、音视频等不同模态。
依赖
<dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j-community-dashscope-spring-boot-starter</artifactId>
</dependency>
在官网申请API-Key
langchain4j:community:dashscope:chat-model:api-key: sk-66xxxxxxxmodel-name: qwen-max
AIService
<dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j-spring-boot-starter</artifactId>
</dependency>
AIService用于格式化输入,解析输出,记忆聊天等功能。
- 创建接口
package com.atguigu.java.ai.langchain4j.assistant;
public interface Assistant {String chat(String userMessage);
}
- 创建类测试
@Autowired
private QwenChatModel qwenChatModel;
@Test
public void testChat() {//创建AIServiceAssistant assistant = AiServices.create(Assistant.class, qwenChatModel);//调用service的接口String answer = assistant.chat("Hello");System.out.println(answer);
}
更方便的方式是使用@AIService注解,然后通过@Autowired使用
package com.atguigu.java.ai.langchain4j.assistant;@AiService(wiringMode = EXPLICIT, chatModel =
"qwenChatModel")
public interface Assistant {String chat(String userMessage);
}
聊天记忆
我们来测试每次聊天是否有记忆
@Autowired
private Assistant assistant;
@Test
public void testAssistant() {String question1 = "我是赵铁柱";String question2 = "我是谁?";String ans1 = assistant.chat(question1);String ans2 = assistant.chat(question2);System.out.println(ans1);System.out.println(ans2);
}
目前是没记忆的,需要使用chatMemory
- 注解
@AiService(wiringMode = EXPLICIT,chatMemory = "chatMemory" chatMemoryProvider="chatMemoryProvider")
- 配置类
package com.atguigu.java.ai.langchain4j.config;
@Configuration
public class MemoryChatAssistantConfig {@BeanChatMemory chatMemory() {//设置聊天记忆记录的message数量return MessageWindowChatMemory.withMaxMessages(10);}
}
- 注入测试
@Autowired
private MemoryChatAssistant memoryChatAssistant;
@Test
public void testChatMemory4() {String answer1 = memoryChatAssistant.chat("我是环环");System.out.println(answer1);String answer2 = memoryChatAssistant.chat("我是谁");System.out.println(answer2);
}
隔离聊天
- 在AIService中添加chatMemoryProvider
@AiService(wiringMode = WiringMode.EXPLICIT,chatModel = "qwenChatModel",chatMemory = "chatMemory"chatMemoryProvider="chatMemoryProvider")
public interface SeparateChatAssistant {/*** 处理用户消息并维护独立的对话上下文* @param memoryId 对话内存 ID(区分不同用户)* @param userMessage 用户输入的消息* @return AI 回复*/String chat(@MemoryId int memoryId, @UserMessage String userMessage);
}
- 配置chatMemoryProvider类
MongoDB
- 引入依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
- 配置项:
spring.data.mongodb.uri = mongodb://localhost:27017/chat_memory_db
- 实现Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
@Document("chat_message")
public class ChatMessages {@Id //对应数据库的id字段private ObjectId messageId; //MongoDB自动生成id为ObjectId类型private String content;}
- 使用MongoTemplate测试
@Autowired
private MongoTemplate mongoTemplate;@Test
public void testInsert(){ChatMessages chatMessages = new ChatMessages();chatMessages.setContent("哈哈哈哈");
// 数据库自动生成idmongoTemplate.insert(chatMessages);
}
接下来可以在IDEA中连接数据库在线查看。
操作 | 代码 | 具体代码 |
---|---|---|
插入 | insert(object) | |
查找 | findbyId(‘id’,Class)、findAll(Class) | |
更新 | upsert(query,update,Class) | Query query = Query.query(Criteria.where(“id”).is(id)); Update update = new Update().set(“age”, newAge); |
删除 | remove(query,Class) |
持久化存储
- 配置chatMemoryProvider
@AiService(chatMemoryProvider = "chatMemoryProvider")
和实体类 - 配置MongoChatMemoryStore,重写getMessages等三大方法
@Component
public class MongoChatMemoryStore implements ChatMemoryStore {@Autowiredprivate MongoTemplate mongoTemplate;@Overridepublic List<ChatMessage> getMessages(Object memoryId) {Query query = new Query(Criteria.where("memoryId").is(memoryId));ChatMessages chatMessages = mongoTemplate.findOne(query,ChatMessages.class);// 将String转成反序列化 转出List<ChatMessage>if (chatMessages==null){return new ArrayList<ChatMessage>();}List<ChatMessage> chatMessage = ChatMessageDeserializer.messagesFromJson(chatMessages.getContent());System.out.println("反序列化:"+chatMessage);return chatMessage;}@Overridepublic void updateMessages(Object memoryId, List<ChatMessage> list) {// 查询条件Criteria criteria = Criteria.where("memoryId").is(memoryId);Query query = new Query(criteria);Update update = new Update();// 插入更新消息列表update.set("content", ChatMessageSerializer.messagesToJson(list));mongoTemplate.upsert(query,update,ChatMessages.class);}@Overridepublic void deleteMessages(Object memoryId) {// 查询条件Criteria criteria = Criteria.where("memoryId").is(memoryId);// 构建查询对象Query query = new Query(criteria);mongoTemplate.remove(query,ChatMessages.class);}
}
- 测试
@Autowiredprivate Assistant assistant;@Testpublic void testAssistant() {String question1 = "我是赵铁柱";String question2 = "我是谁?";String ans1 = assistant.chat(1,question1);String ans2 = assistant.chat(1,question2);String ans3 = assistant.chat(2,question2);}
Prompt
@SystemMessage 设定角色,塑造AI助手的专业身份,明确助手的能力范围
- 配置@SystemMessage
@SystemMessage("你是我的好朋友,请用东北话回答问题。")//系统消息提示词
String chat(@MemoryId int memoryId, @UserMessage String userMessage);
- 配置用户输入@UserMessage
@UserMessage("你是我的好朋友,请用东北话回答问题。")//系统消息提示词
String chat(@UserMessage String userMessage);
- 配置@V传递参数
@UserMessage("你是我的好朋友,请用上海话回答问题,并且添加一些表情符号。{{message}}")
String chat(@V("message") String userMessage);
*创建小智医疗助手
- 创建XiaoZhiAssistant
- 提示词模版:xiaozhi-prompt-template.txt
- 配置chatMemoryProvider持久化和记忆回话隔离
- 创建实体类
- 创建Controller方法
Function Calling(Tools)
大语言模型的缺陷是数学能力不擅长。
- @Tool注解提供数学工具
@Component
public class CalculatorTools {@Tooldouble sum(double a, double b) {System.out.println("调用加法运算");return a + b;}@Tooldouble squareRoot(double x) {System.out.println("调用平方根运算");return Math.sqrt(x);}
}
- 在@AiService配置
tools ="calculatorTools"
根据工具的不同,即使没有任何描述,大语言模型可能也能很好地理解它,例如add(a, b) 。
实战小智医疗智能体
- 实现业务,在tools中提示大模型预约流程和结果
加载Mysql等
@Component
public class AppointmentTool {@Autowiredprivate AppointmentService appointmentService;@Tool(name="预约挂号",value="根据参数,先查询是否当天是否预约过,如果没有预约过,则进行预约,返回预约结果")public String appointment(Appointment appointment) {// 先查询是否当天是否预约过if (appointmentService.isAppointment(appointment)) {return "您今天已经预约过了,请勿重复预约";}// 进行预约boolean result = appointmentService.appointment(appointment);if (result) {return "预约成功";} else {return "预约失败";}}}
RAG
LLM的知识仅限于它所训练的数据。如果你想让LLM了解特定领域的知识或转专有数据,需要微调。
RAG通过检索外部知识库(如文档、数据库),将检索到的相关信息作为上下文输入给生成模型,辅助生成更准确的回答。
1. 全文搜索
2. **向量搜索**(向量余弦相似度,独立的向量数据库)
3. 混合搜索
RAG的过程
- 索引阶段
xx - 检索阶段
xxx - 文档加载器,文档解析器,文档分割器
//文档加载器,文档解析器,文档分割器
PathMatcher pathMatcher = FileSystems.getDefault().getPathMatcher("glob:*.txt");
List<Document> documents = FileSystemDocumentLoader.loadDocuments(folder, pathMatcher,new TextDocumentParser());
//
Token分词器
向量存储
之前我们使用的是InMemoryEmbeddingStore作为向量存储,但是不建议在生产中使用基于内存的向量存储。因此这里我们使用Pinecone作为向量数据库。
<dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j-pinecone</artifactId>
</dependency>
#集成阿里通义千问-通用文本向量-v3,注入EmbeddingModel
langchain4j.community.dashscope.embedding-model.api-key=${DASH_SCOPE_API_KEY}
langchain4j.community.dashscope.embedding-model.model-name=text-embedding-v3
- 配置EmbeddingStoreConfig
- //相似度匹配embeddingSearch
- 上传知识库到Pinecone
- 在AssistantConfig中添加contentRetrieverXiaozhiPincone
- AiService注解加contentRetriever=“contentRetrieverXiaozhiPincone”
流式输出
大模型的流式输出是指大模型在生成文本或其他类型的数据时,不是等到整个生成过程完成后再一次性返回所有内容,而是生成一部分就立即发送一部分给用户或下游系统,以逐步、逐块的方式返回结果。
<!--流式输出-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j-reactor</artifactId>
</dependency>
1.配置
#集成阿里通义千问-流式输出
langchain4j.community.dashscope.streaming-chat-model.api-key=${DASH_SCOPE_API_KEY}
langchain4j.community.dashscope.streaming-chat-model.model-name=qwen-plus
- AIService添加
streamingChatModel = "qwenStreamingChatModel"
- 修改chat方法返回类型为Flux,也别忘了修改Controller中的返回类型
总结
整个框架流程如下
完结撒花!
相关文章:

Spring+LangChain4j小智医疗项目
这里写目录标题 LangChain4j入门配置测试Ollama阿里云百炼平台AIService聊天记忆隔离聊天 MongoDB持久化存储Prompt*创建小智医疗助手Function Calling(Tools)实战小智医疗智能体 RAGToken分词器向量存储流式输出总结 LangChain4j入门 LangChain4j 是一…...

解决“VMware另一个程序已锁定文件的一部分,进程无法访问“
问题描述 打开VMware里的虚拟机时,弹出"另一个程序已锁定文件的一部分,进程无法访问"如图所示: 这是VM虚拟机的保护机制。虚拟机运行时,为防止数据被篡改,会将所运行的文件保护起来。当虚拟机崩溃或者强制…...

buuctf Crypto-鸡藕椒盐味1
1.题目: 公司食堂最新出了一种小吃,叫鸡藕椒盐味汉堡,售价八块钱,为了促销,上面有一个验证码,输入后可以再换取一个汉堡。但是问题是每个验证码几乎都有错误,而且打印的时候倒了一下。小明买到了一个汉堡&a…...

FreeRTOS的学习记录(基础知识)
FreeRTOS 简介 FreeRTOS 是一个开源的实时操作系统(RTOS),专为嵌入式系统设计。它提供了任务管理、时间管理、信号量、消息队列、内存管理等功能,适用于资源受限的微控制器。 FreeRTOS 是一个开源的实时操作系统内核,…...

会议分享|高超声速流动测量技术研讨会精彩探析
由中国空气动力学会测控专业委员会主办,中国科学技术大学工程科学学院承办的第八届三次委员会暨高超声速流动测量技术研讨会,5月16日在合肥盛大开幕。 会议专家报告分享了高超声速流动测量的最新研究成果、挑战与突破,展示了PIV高速摄像机、粒…...

1-10 目录树
在ZIP归档文件中,保留着所有压缩文件和目录的相对路径和名称。当使用WinZIP等GUI软件打开ZIP归档文件时,可以从这些信息中重建目录的树状结构。请编写程序实现目录的树状结构的重建工作。 输入格式: 输入首先给出正整数N(≤104)…...
redis开源协议的变更和使用影响
2013年:采用 BSD 协议 核心内容:Redis 最初采用 BSD 3-Clause 协议,允许用户自由使用、修改和分发代码,包括闭源商业用途。这种宽松的协议促进了 Redis 的快速普及,尤其是云计算厂商将其作为托管服务的基础。 影响:云服务商(如 AWS、阿里云等)可合法地将 Redis 集成到其…...
数据库的锁 - 全局锁、表锁、行锁
目录 一、全局锁 1.1 介绍 1.2 语法 1). 加全局锁 2). 数据备份 3). 释放锁 1.3 特点 二、表级锁 2.1 表锁 2.2 元数据锁(MDL) 2.3 意向锁 三、行级锁 3.1 行锁 3.2 间隙锁 & 临键锁 一、全局锁 1.1 介绍 全局锁是对整个数据库实…...

Unix/Linux | A Programming Guide
注:本文为 “UNIX / Linux 教程” 相关文章合辑。 略作重排,如有内容异常,请看原文。 UNIX / Linux Tutorial for Beginners: Learn Online in 7 days By : Emily Carter UpdatedFebruary 5, 2025 UNIX / Linux Tutorial Summary Linux …...

前端——布局方式
普通流(标准流) 所谓的标准流: 就是标签按照规定好默认方式排列. 1. 块级元素会独占一行,从上向下顺序排列。 常用元素:div、hr、p、h1~h6、ul、ol、dl、form、table 2. 行内元素会按照顺序,从左到右顺序排列&am…...

Multimodal models —— CLIP,LLava,QWen
目录 CLIP CLIP训练 CLIP图像分类 CLIP框架 Text Enocder Image Encoder LLava系列 LLava LLava贡献 LLava模型结构 总结 LLava两阶段训练 LLava 1.5 LLava 1.6 QWen CLIP CLIP是OpenAI 在 2021 年发布的,最初用于匹配图像和文本的预训练神经网络模型…...
Python模块化编程进阶指南:从基础到工程化实践
一、模块化编程核心原理与最佳实践 1.1 模块化设计原则 根据企业级项目实践,模块化开发应遵循以下核心原则: 单一职责原则:每个模块只承担一个功能域的任务(如用户认证模块独立于日志模块)接口隔离原则…...
json-server的用法-基于 RESTful API 的本地 mock 服务
json-server 是一个非常方便的工具,用于快速搭建基于 RESTful API 的本地 mock 服务,特别适合前端开发阶段模拟后端数据接口。 🧩 一、安装 npm install -g json-server🚀 二、快速启动 创建一个 db.json 文件(模拟数…...

LabVIEW与PLC通讯程序S7.Net.dll
下图中展示的是 LabVIEW 环境下通过调用S7.Net.dll 组件与西门子 PLC 进行通讯的程序。LabVIEW 作为一种图形化编程语言,结合S7.Net.dll 的.NET 组件优势,在工业自动化领域中可高效实现与 PLC 的数据交互,快速构建工业监控与控制应用。相较于…...
STM32 __main汇编分析
在STM32的启动流程中,__main是一个由编译器自动生成的C标准库函数,其汇编级调用逻辑可通过启动文件(如startup_stm32fxxx.s)观察到,但具体实现细节被封装在编译器的运行时库中。以下是其核心逻辑解析: 一、…...

使用GpuGeek高效完成LLaMA大模型微调:实践与心得分享
使用GpuGeek高效完成LLaMA大模型微调:实践与心得分享 🌟嗨,我是LucianaiB! 🌍 总有人间一两风,填我十万八千梦。 🚀 路漫漫其修远兮,吾将上下而求索。 随着大模型的发展࿰…...

华为IP(6)
VLAN聚合 VLAN聚合产生的技术背景 在一般是三层交换机中,通常采用一个VLAN接口的方式实现广播域之间的互通,这在某些情况下导致了IP地址的浪费 因为一个VLAN对应的子网中,子网号、子网广播地址、子网网关地址不能用作VLAN内的主机IP地址&a…...

1:OpenCV—图像基础
OpenCV教程 头文件 您只需要在程序中包含 opencv2/opencv.hpp 头文件。该头文件将包含应用程序的所有其他必需头文件。因此,您不再需要费心考虑程序应包含哪些头文件。 例如 - #include <opencv2/opencv.hpp>命名空间 所有 OpenCV 类和函数都在 cv 命名空…...

第三部分:内容安全(第十六章:网络型攻击防范技术、第十七章:反病毒、第十八章:入侵检测/防御系统(IDS/IPS))
文章目录 第三部分:内容安全第十六章:网络型攻击防范技术网络攻击介绍流量型攻击 --- Flood攻击单包攻击及防御原理扫描窥探攻击畸形报文攻击Smurf攻击Land攻击Fraggle攻击IP欺骗攻击 流量型攻击防御原理DDoS通用攻击防范技术 ---- 首包丢弃TCP类攻击SYN…...

Void: Cursor 的开源平替
GitHub:https://github.com/voideditor/void 更多AI开源软件:发现分享好用的AI工具、AI开源软件、AI模型、AI变现 - 小众AI Void,这款编辑器号称是开源的 Cursor 和 GitHub Copilot 替代品,而且完全免费! 在你的代码库…...

100G QSFP28 BIDI光模块一览:100G单纤高速传输方案|易天光通信
目录 前言 一、易天光通信100G QSFP28 BIDI光模块是什么? 二、易天光通信100G QSFP28 BIDI光模块采用的关键技术 三、100G QSFP28 BIDI光模块的优势 四、以“易天光通信100G BIDI 40km ER1光模块”为例 五、总结:高效组网,从“减”开始 关于…...
基于大模型的脑出血智能诊疗与康复技术方案
目录 一、术前阶段1.1 数据采集与预处理系统伪代码实现流程图1.2 特征提取与选择模块伪代码实现流程图1.3 大模型风险评估系统伪代码实现流程图二、术中阶段2.1 智能手术规划系统伪代码实现流程图2.2 麻醉智能监控系统伪代码实现流程图三、术后阶段3.1 并发症预测系统伪代码片段…...

卓力达电铸镍网:精密制造与跨领域应用的创新典范
目录 引言 一、电铸镍网的技术原理与核心特性 二、电铸镍网的跨领域应用 三、南通卓力达电铸镍网的核心优势 四、未来技术展望 引言 电铸镍网作为一种兼具高精度与高性能的金属网状材料,通过电化学沉积工艺实现复杂结构的精密成型,已成为航空航天、电…...

今日积累:若依框架配置QQ邮箱,来发邮件,注册账号使用
QQ邮箱SMTP服务器设置 首先,我们需要了解QQ邮箱的SMTP服务器地址。对于QQ邮箱,SMTP服务器地址通常是smtp.qq.com。这个地址适用于所有使用QQ邮箱发送邮件的客户端。 QQ邮箱SMTP端口设置 QQ邮箱提供了两种加密方式:SSL和STARTTLS。根据您选…...

快速入门机器学习的专有名词
机器学习(Machine Learning) 机器学习是计算机科学的一个领域,目的在于让计算机能够通过学习数据来做出预测或决策,而无需被明确编程来完成任务。 机器学习的工作模式: 数据:机器学习需要数据来“学习”…...
C#学习教程(附电子书资料)
概述 C#(读作"C Sharp")是一种由微软开发的现代编程语言,结合了C的高效性和Java的简洁性,专为.NET框架设计。以下是其核心特性和应用领域的详细介绍电子书资料:https://pan.quark.cn/s/6fe772420f95 一、语…...

Python之三大基本库——Matplotlib
好久没来总结了,今天刚好有时间,我们来继续总结一下python中的matplotlib 一、什么是Matplotlib Matplotlib是一个Python的2D绘图库,主要用于将数据绘制成各种图表,如折线图、柱状图、散点图、直方图、饼图等。它以各种硬拷贝…...

Tensorflow 2.X Debug中的Tensor.numpy问题 @tf.function
我在调试YOLOv3模型过程中想查看get_pred函数下面的get_anchors_and_decode函数里grid_shape的数值 #---------------------------------------------------# # 将预测值的每个特征层调成真实值 #---------------------------------------------------# def get_anchors_a…...

element基于表头返回 merge: true 配置列合并
<template><div class"wrap" v-loading"listLoading"><div class"content_wrap mt-10"><div style"text-align: center;"><h3>酿造交酒酒罐统计表({{month}}月{{day}}日)</h3…...

sql sql复习
虽然之前学习过sql,但由于重在赶学习进度,没有学扎实,导致自己刷题的时候有的地方还是模模糊糊,现在主要是复习,补一补知识点。 今日靶场: NSSCTF 云曦历年考核题 在做题之前先回顾一下sql注入的原理&…...