小智医疗解析
目录
标题
人工智能服务 AIService
package com.lzw.javaailangchain4j.assistant;
import dev.langchain4j.service.spring.AiService;
import static dev.langchain4j.service.spring.AiServiceWiringMode.EXPLICIT;
@AiService(wiringMode = EXPLICIT, chatModel = "qwenChatModel")
public interface Assistant {
String chat(String userMessage) ;
}
在这个接口中加上AiService 并指定大数据模型就可以利用@Autowired去注入
@Autowired
Assistant assistant;
@Test
public void testAssistant()
{
String anser = assistant.chat("你是谁");
System.out.println(anser);
}
实现聊天记忆
@Test
public void chartMeory(){
MessageWindowChatMemory chatMemory = MessageWindowChatMemory.withMaxMessages(10);
Assistant assistant1 = AiServices.builder(Assistant.class)
.chatModel(qwenChatModel)
.chatMemory(chatMemory)
.build();
String anser1 = assistant1.chat("我是lzw");
System.out.println(anser1);
String anser2 = assistant1.chat("我是谁");
System.out.println(anser2);
}
我设置的会话记忆只有十层超过之后就不会记住上下文记忆
使用AIsevice实现聊天记忆
package com.lzw.javaailangchain4j.assistant;
import dev.langchain4j.service.spring.AiService;
import static dev.langchain4j.service.spring.AiServiceWiringMode.EXPLICIT;
@AiService(
wiringMode = EXPLICIT,
chatModel = "qwenChatModel",
chatMemory = "chatMemory"
)
public interface MemorychatAssistant {
String chat(String userMessage) ;
}
然后对chatMemory进行配置Bean
package com.lzw.javaailangchain4j.config;
import dev.langchain4j.memory.ChatMemory;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MemorychatAssistantConfig {
@Bean
ChatMemory chatMemory() {
//设置聊天记忆记录的message数量
return MessageWindowChatMemory.withMaxMessages(10);
}
}
@Autowired
private MemorychatAssistant memorychatAssistant;
@Test
public void chartMeory1(){
String anser1 =memorychatAssistant.chat("我是lzw");
System.out.println(anser1);
String anser2 = memorychatAssistant.chat("我是谁");
System.out.println(anser2);
}
这样就可以简化代码直接使用
进行聊天记忆隔离
package com.lzw.javaailangchain4j.assistant;
import dev.langchain4j.service.MemoryId;
import dev.langchain4j.service.UserMessage;
import dev.langchain4j.service.spring.AiService;
import static dev.langchain4j.service.spring.AiServiceWiringMode.EXPLICIT;
@AiService(
wiringMode = EXPLICIT,
chatModel = "qwenChatModel",
chatMemoryProvider = "chatMemoryProvider"
)
public interface SeparateChatAssistant {
String chat(@MemoryId int memoryId, @UserMessage String userMessage);
}
创建chatMemoryProvider的Bean
package com.lzw.javaailangchain4j.config;
import dev.langchain4j.memory.chat.ChatMemoryProvider;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SeparateChatAssistantConfig {
@Bean
ChatMemoryProvider chatMemoryProvider() {
return memoryId -> MessageWindowChatMemory.builder()
.id(memoryId)
.maxMessages(10)
.build();
}
}
这样就保证了不同的用户有不同的聊天记忆
聊天记忆是怎么实现的呢
在MessageWindowChatMemory里面有个store字段

而ChatMemoryStore里面有两个实现类


在这个图中就可以清晰的看出默认的是使用Single这个实现类去实现的
而在single实现类中

聊天记忆是存储来List集合中的,当去查询聊天记忆时会先去调用checkMemoryId去检查id是否匹配,添加新的聊天记忆也是如此

具体的就是这样使用key value存储记忆不同的用户之间直接隔离
对于一种类的实现是将内存信息放在hashmap中
持久化聊天记忆 Persistence
默认情况下,聊天记忆存储在内存中。如果需要持久化存储,可以实现一个自定义的聊天记忆存储类, 以便将聊天消息存储在你选择的任何持久化存储介质中。
我们使用的是MongoDB
配置MongoDB,先去创建实体类映射MongoDB
@Data
@AllArgsConstructor
@NoArgsConstructor
@Document("chat_messages")
public class ChatMessages {
//唯一标识,映射到 MongoDB 文档的 _id 字段
@Id
private ObjectId messageId;
//private Long messageId;
private String content; //存储当前聊天记录列表的json字符串
}
先进行MonfoDB插入数据测试
@Autowired
MongoTemplate mongoTemplate;
@Test
public void testInsert2() {
ChatMessages chatMessages = new ChatMessages();
chatMessages.setContent("聊天记录");
mongoTemplate.insert(chatMessages);
}
得到结果

更新和插入
@Test
public void testUpdate() {
ObjectId id = new ObjectId("69c38b95e7a9443bf03b0db7");
Criteria criteria = Criteria.where("_id").is(id);
Query query = new Query(criteria);
Update update = new Update();
update.set("content", "hello world");
// 修改或新增
mongoTemplate.upsert(query, update, ChatMessages.class);
}
当你给的id不存在的话就会去创建而不是去修改了
删除操作
@Test
public void testDelete() {
Criteria criteria = Criteria.where("_id").is("69c38b95e7a9443bf03b0db7");
Query query = new Query(criteria);
mongoTemplate.remove(query, ChatMessages.class);
}
聊天记忆的持久化配置
我们首先会去创建记忆持久化的类去实现chatmemoryStore的接口重写里面的三个方法
package com.lzw.javaailangchain4j.store;
import com.lzw.javaailangchain4j.Bean.ChatMessages;
import dev.langchain4j.data.message.ChatMessage;
import dev.langchain4j.data.message.ChatMessageDeserializer;
import dev.langchain4j.data.message.ChatMessageSerializer;
import dev.langchain4j.store.memory.chat.ChatMemoryStore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Component;
import java.util.LinkedList;
import java.util.List;
@Component
public class MongoChatMemoryStore implements ChatMemoryStore {
@Autowired
private MongoTemplate mongoTemplate;
@Override
public List<ChatMessage> getMessages(Object memoryId) {
Criteria criteria = Criteria.where("memoryId").is(memoryId);
Query query = new Query(criteria);
ChatMessages chatMessages = mongoTemplate.findOne(query, ChatMessages.class);
if (chatMessages == null) {
//因为信息是存储再linkedlist的
return new LinkedList<>();
}
String contentJson = chatMessages.getContent();
return ChatMessageDeserializer.messagesFromJson(contentJson);
}
@Override
public void updateMessages(Object memoryId, List<ChatMessage> list) {
Criteria criteria = Criteria.where("memoryId").is(memoryId);
Query query = new Query(criteria);
Update update = new Update();
//将聊天记忆存储起来,将list转成json
update.set("content", ChatMessageSerializer.messagesToJson(list));
// 修改或新增
mongoTemplate.upsert(query, update, ChatMessages.class);
}
@Override
public void deleteMessages(Object memoryId) {
Criteria criteria = Criteria.where("memoryId").is(memoryId);
Query query = new Query(criteria);
mongoTemplate.remove(query, ChatMessages.class);
}
}
在这个持久化记忆里面我们是用memoryid去查询的
然后去配置这个类
@Configuration
public class SeparateChatAssistantConfig {
@Autowired
private MongoChatMemoryStore mongoChatMemoryStore;
@Bean
ChatMemoryProvider chatMemoryProvider() {
return memoryId -> MessageWindowChatMemory.builder()
.id(memoryId)
.maxMessages(10)
.chatMemoryStore(mongoChatMemoryStore)
.build();
}
}
@AiService(
wiringMode = EXPLICIT,
chatModel = "qwenChatModel",
chatMemoryProvider = "chatMemoryProvider"
)
public interface SeparateChatAssistant {
String chat(@MemoryId int memoryId, @UserMessage String userMessage);
}
这样就实现了聊天记忆的持久化
使用提示词
public interface SeparateChatAssistant {
@SystemMessage("你是我的好朋友,请用东北话回答问题。今天是{{current_date}}")
String chat(@MemoryId int memoryId, @UserMessage String userMessage);
}
上面加上SystemMessage就可以了,在MongoDB中的显示是

比原来多了一个system的回答在开头。当你将提示词换了之后你再使用3id去聊天他就会重置记忆
使用UserMessage
public interface MemorychatAssistant {
@UserMessage("你是我的好朋友,请用上海话回答问题,并且添加一些表情符号。 {{it}}")
String chat(String userMessage) ;
}
it就是占位符就是chat的参数userMessage每次对话都会带着这句话

两次都能够带上这句话,依据他去回答
使用@V注解替换默认的it,他们两个的作用是一样的
public interface MemorychatAssistant {
@UserMessage("你是我的好朋友,请用上海话回答问题,并且添加一些表情符号。 {{userMessage}}")
String chat(@V("userMessage") String userMessage) ;
}

有两个及两个以上的参数就必须使用@V注解了
@Autowired
private MemoryChatAssistant memoryChatAssistant;
@Test
public void testUserMessage() {
String answer = memoryChatAssistant.chat("我是环环");
System.out.println(answer);
}
@UserMessage("你是我的好朋友,请用上海话回答问题,并且添加一些表情符号。{{message}}")
String chat(@V("message") String userMessage);
@UserMessage("你是我的好朋友,请用粤语回答问题。{{message}}")
String chat2(@MemoryId int memoryId, @V("message") String userMessage);
@SystemMessage(fromResource = "lzwPropt.txt")
String chat3(
@MemoryId int memoryId,
@UserMessage String userMessage,
@V("username") String username,
@V("age") int age
);
system的文件是我们自己写的
你是我的好朋友,请用东北话回答问题,回答问题的时候适当添加表情符号。
今天是 {{current_date}}。
@Autowired
private SeparateChatAssistant separateChatAssistant;
@Test
public void testSeparateChatAssistant() {
//假如说是从数据库获取用户姓名跟年龄
String name="埃特曼";
int age=14;
String anser = separateChatAssistant.chat3(3, "我是谁,我多大了", name, age);
System.out.println(anser);
}
这个的作用就是给系统提示词让他按照我们的提示词去回答
正式开始
首先要去创建小智的接口
@AiService(
wiringMode = EXPLICIT,
chatModel = "qwenChatModel",
chatMemoryProvider = "chatMemoryProviderXiaozhi"
)
public interface XiaozhiAssistant {
@SystemMessage(fromResource = "zhaozhi-prompt-template.txt")
String chat(@MemoryId Long memoryId, @UserMessage String userMessage);
}
提示词我们已经保存
你的名字是“硅谷小智”,你是一家名为“北京协和医院”的智能客服。
你是一个训练有素的医疗顾问和医疗伴诊助手。
你态度友好、礼貌且言辞简洁。
1、请仅在用户发起第一次会话时,和用户打个招呼,并介绍你是谁。
2、作为一个训练有素的医疗顾问:
尚硅⾕
3、配置小智助手
配置持久化和记忆隔离
4、封装对话对象
请基于当前临床实践和研究,针对患者提出的特定健康问题,提供详细、准确且实用的医疗建议。请同时考虑可能的病
因、诊断流程、治疗方案以及预防措施,并给出在不同情境下的应对策略。对于药物治疗,请特别指明适用的药品名
称、剂量和疗程。如果需要进一步的检查或就医,也请明确指示。
3、作为医疗伴诊助手,你可以回答用户就医流程中的相关问题,主要包含以下功能:
AI分导诊:根据患者的病情和就医需求,智能推荐最合适的科室。
AI挂号助手:实现智能查询是否有挂号号源服务;实现智能预约挂号服务;实现智能取消挂号服务。
4、你必须遵守的规则如下:
在获取挂号预约详情或取消挂号预约之前,你必须确保自己知晓用户的姓名(必选)、身份证号(必选)、预约科室
(必选)、预约日期(必选,格式举例:2025-04-14)、预约时间(必选,格式:上午 或 下午)、预约医生(可
选)。
当被问到其他领域的咨询时,要表示歉意并说明你无法在这方面提供帮助。
5、请在回答的结果中适当包含一些轻松可爱的图标和表情。
6、今天是 {{current_date}}。
去实现记忆的持久化
@Configuration
public class XiaozhiAssistanConfig {
@Autowired
private MongoChatMemoryStore mongoChatMemoryStore;
@Bean
ChatMemoryProvider chatMemoryProviderXiaozhi() {
return memoryId -> MessageWindowChatMemory.builder()
.id(memoryId)
.maxMessages(20)
.chatMemoryStore(mongoChatMemoryStore)
.build();
}
}
去封装一个会话对象
package com.lzw.javaailangchain4j.config;
import lombok.Data;
@Data
public class ChatForm {
private Long memoryId;//对话id
private String message;//用户问题
}
然后创建controller实现会话
@RestController
@RequestMapping("/xiaozhi")
@Tag(name="硅谷小智")
public class XiaozhiController {
@Autowired
private XiaozhiAssistant xiaozhiAssistant;
@Operation(summary = "对话")
@PostMapping("/chat")
public String chat(@RequestBody ChatForm chatForm) {
return xiaozhiAssistant.chat(chatForm.getMemoryId(), chatForm.getMessage());
}
}
调试接口

添加tools工具
@Component
public class CalculatorTools {
@Tool(name = "加法", value = "返回两个参数相加之和")
double sum(
@ToolMemoryId int memoryId,
@P(value="加数1", required = true) double a,
@P(value="加数2", required = true) double b) {
System.out.println("调用加法运算 " + memoryId);
return a + b;
}
@Tool(name = "平方根", value = "返回给定参数的平方根")
double squareRoot(
@ToolMemoryId int memoryId, double x) {
System.out.println("调用平方根运算 " + memoryId);
return Math.sqrt(x);
}
}
如果你不配置的话有的时候ai会出现幻觉(计算出的结果并不对)@Tool是给方法进行说明的以防ai看不懂,@P是给参数说明的里面的required是默认为true代表你必须传入该参数,@ToolMemoryId是为了有些需求需要展示用户的id(那个用户调用的方法)
测试用例
@Autowired
private SeparateChatAssistant separateChatAssistant;
@Test
public void testCalculatorTools() {
String answer =separateChatAssistant.chat(99,"65006500的平方根为多少?");
String anser1 = separateChatAssistant.chat(99, "3+5等于多少");
System.out.println(answer);
System.out.println(anser1);
}
结果

做一个优化,将预约信息跟查询预约放入数据库
首先就需要创建数据库
CREATE DATABASE `guiguxiaozhi`;
USE `guiguxiaozhi`;
CREATE TABLE `appointment` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`username` VARCHAR(50) NOT NULL,
`id_card` VARCHAR(18) NOT NULL,
`department` VARCHAR(50) NOT NULL,
`date` VARCHAR(10) NOT NULL,
`time` VARCHAR(10) NOT NULL,
`doctor_name` VARCHAR(50) DEFAULT NULL,
PRIMARY KEY (`id`)
);
创建他的实体类
package com.lzw.javaailangchain4j.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Appointment {
@TableId(type = IdType.AUTO)
private Long id;
private String username;
private String idCard;
private String department;
private String date;
private String time;
private String doctorName;
}
然后创建Sevice和Mapper各种东西
进行测试
@SpringBootTest
public class AppointmentSevicesTest {
@Autowired
private AppointmentService appointmentService;
@Test
void testGetOne() {
Appointment appointment = new Appointment();
appointment.setUsername("张三");
appointment.setIdCard("123456789012345678");
appointment.setDepartment("内科");
appointment.setDate("2025-04-14");
appointment.setTime("上午");
Appointment appointmentDB = appointmentService.getOne(appointment);
System.out.println(appointmentDB);
}
@Test
void testSave() {
Appointment appointment = new Appointment();
appointment.setUsername("张三");
appointment.setIdCard("123456789012345678");
appointment.setDepartment("内科");
appointment.setDate("2025-04-14");
appointment.setTime("上午");
appointment.setDoctorName("张医生");
appointmentService.save(appointment);
}
}

配置Tools
@Component
public class AppointmentTools {
@Autowired
private AppointmentService appointmentService;
@Tool(name="预约挂号", value ="根据参数,先执行工具方法queryDepartment查询是否可预约,并直\n" +
"接给用户回答是否可预约,并让用户确认所有预约信息,用户确认后再进行预约")
public String bookAppointment(Appointment appointment) {
//查找数据库中是否包含对应的预约记录
Appointment appointmentDB = appointmentService.getOne(appointment);
if (appointmentDB == null) {
appointment.setId(null);//防止大模型幻觉设置了id
if (appointmentService.save(appointment)) {
return "预约成功,并返回预约详情";
} else {
return "预约失败";
}
}
return "您在相同的科室和时间已有预约";
}
@Tool(name="取消预约挂号", value = "根据参数,查询预约是否存在,如果存在则删除预约记录并返回取\n" +
"消预约成功,否则返回取消预约失败")
public String cancelAppointment(Appointment appointment) {
Appointment appointmentDB = appointmentService.getOne(appointment);
if (appointmentDB != null) {
//删除预约记录
if (appointmentService.removeById(appointmentDB.getId())) {
return "取消预约成功";
} else {
return "取消预约失败";
}
}
//取消失败
return "您没有预约记录,请核对预约科室和时间";
}
@Tool(name = "查询是否有号源", value="根据科室名称,日期,时间和医生查询是否有号源,并返回给用户")
public boolean queryDepartment(
@P(value = "科室名称") String name,
@P(value = "日期") String date,
@P(value = "时间,可选值:上午、下午") String time,
@P(value = "医生名称", required = false) String doctorName
) {
System.out.println("查询是否有号源");
System.out.println("科室名称:" + name);
System.out.println("日期:" + date);
System.out.println("时间:" + time);
System.out.println("医生名称:" + doctorName);
return true;
}
//如果没有指定医生名字,则根据其他条件查询是否有可以预约的医生(有返回true,否则返回
//如果指定了医生名字,则判断医生是否有排班(没有排版返回false)
//如果有排班,则判断医生排班时间段是否已约满(约满返回false,有空闲时间返回true)
}
根据用户给的ai发的信息我们去查询是否有号源,给用户预约和取消预约
进行一下测试

对话框

增强RAG
RAG有两个过程一个是检索一个是索引
首先索引
为什么要进行分段,就是为了减少不必要的信息污染大模型导致幻读,提供的上下文是有限的整个知识库并不能全部放入其中,提供的信息越多花费越多而且反应时间越长
检索
通过向量模型将用户查询转换成向量文本,然后去向量知识库中去做相似度匹配得出分数最高的(就是相似度最高的)结合原本的系统提示词和查询信息去发送给大模型
文本加载器
public class RAGTest {
@Test
public void testReadDocument() {
//使用FileSystemDocumentLoader读取指定目录下的知识库文档
//并使用默认的文档解析器TextDocumentParser对文档进行解析
Document document = FileSystemDocumentLoader.loadDocument("D:/java/knowledge/测试.txt");
System.out.println(document);
}
}
使用默认的解析器

@Test
public void testLoadDocument2() {
// 从一个目录中加载所有的.txt文档
// 从一个目录中加载所有的.txt文档
PathMatcher pathMatcher = FileSystems.getDefault().getPathMatcher("glob:*.txt");
List<Document> documents = FileSystemDocumentLoader.loadDocuments("D:/java/knowledge", pathMatcher, new TextDocumentParser());
for (Document document : documents) {
System.out.println(document.metadata());
System.out.println(document);
}

这个默认的解析器只能解析txt,md等无法解析pdf所以需要用到另一个解析器
ApachePdfBoxDocumentParser
@Test
public void testParsePDF() {
Document document = FileSystemDocumentLoader.loadDocument(
"D:/java/knowledge/医院信息.pdf",
new ApachePdfBoxDocumentParser()
);
System.out.println(document);
}

将知识库文本进行向量转换和存储
@Test
public void testReadDocumentAndStore() {
//使用FileSystemDocumentLoader读取指定目录下的知识库文档
//并使用默认的文档解析器对文档进行解析(TextDocumentParser)
Document document = FileSystemDocumentLoader.loadDocument("D:/java/knowledge/人工智能.md");
//为了简单起见,我们暂时使用基于内存的向量存储
InMemoryEmbeddingStore<TextSegment> embeddingStore = new InMemoryEmbeddingStore<>();
//ingest
//1、分割文档:默认使用递归分割器,将文档分割为多个文本片段,每个片段包含不超过 300个token,并且有 30个token的重叠部分保证连贯性尚硅⾕
//DocumentByParagraphSplitter(DocumentByLineSplitter(DocumentBySentenceSplitter(DocumentByWordSplitter)))
//2、文本向量化:使用一个LangChain4j内置的轻量化向量模型对每个文本片段进行向量化
//3、将原始文本和向量存储到向量数据库中(InMemoryEmbeddingStore)
EmbeddingStoreIngestor.ingest(document, embeddingStore);
//查看向量数据库内容
System.out.println(embeddingStore);
}

在小智RAG中实现
在Tools中配置一下
@Bean
public ContentRetriever contentRetrieverXiaozhi() {
// 1. 加载指定目录下的知识库文档(使用 FileSystemDocumentLoader)
Document document1 = FileSystemDocumentLoader.loadDocument("D:/java/knowledge/医院信息.md");
Document document2 = FileSystemDocumentLoader.loadDocument("D:/java/knowledge/科室信息.md");
Document document3 = FileSystemDocumentLoader.loadDocument("D:/java/knowledge/神经内科.md");
List<Document> documents = Arrays.asList(document1, document2, document3);
// 2. 创建内存向量存储(InMemoryEmbeddingStore)
InMemoryEmbeddingStore<TextSegment> embeddingStore = new InMemoryEmbeddingStore<>();
// 3. 使用默认文档分割器,将文档切分并存入向量存储(EmbeddingStoreIngestor)
EmbeddingStoreIngestor.ingest(documents, embeddingStore);
// 4. 基于向量存储构建内容检索器(EmbeddingStoreContentRetriever)
return EmbeddingStoreContentRetriever.from(embeddingStore);
}
然后在引入
@AiService(
wiringMode = EXPLICIT,
chatModel = "qwenChatModel",
chatMemoryProvider = "chatMemoryProviderXiaozhi",
tools = "appointmentTools",
contentRetriever = "contentRetrieverXiaozhi" //配置向量存储
)
public interface XiaozhiAssistant {
@SystemMessage(fromResource = "zhaozhi-prompt-template.txt")
String chat(@MemoryId Long memoryId, @UserMessage String userMessage);
}
这样之后智能回答会更加准确
#集成阿里通义千问-通用文本向量-v3
langchain4j.community.dashscope.embedding-model.api-key=${DASH_SCOPE_API_KEY}
langchain4j.community.dashscope.embedding-model.model-name=text-embedding-v4
@SpringBootTest
public class EmbeddingTest {
@Autowired
private EmbeddingModel embeddingModel;
@Test
public void testEmbeddingModel(){
Response<Embedding> embed = embeddingModel.embed("你好");
System.out.println("向量维度:" + embed.content().vector().length);
System.out.println("向量输出:" + embed.toString());
}
}
结果

在硅谷小智中整合向量数据库
上传知识库到Pinecone
@Test
public void testUploadKnowledgeLibrary() {
// 使用 FileSystemDocumentLoader 读取指定目录下的知识库文档
// 并使用默认的文档解析器对文档进行解析
Document document1 = FileSystemDocumentLoader.loadDocument("D:/java/knowledge/医院信息.md");
Document document2 = FileSystemDocumentLoader.loadDocument("D:/java/knowledge/科室信息.md");
Document document3 = FileSystemDocumentLoader.loadDocument("D:/java/knowledge/神经内科.md");
List<Document> documents = Arrays.asList(document1, document2, document3);
// 文本向量化并存入向量数据库:将每个片段进行向量化,得到一个嵌入向量
EmbeddingStoreIngestor
.builder()
.embeddingStore(embeddingStore)
.embeddingModel(embeddingModel)
.build()
.ingest(documents);
}
@Autowired
private EmbeddingStore embeddingStore;
@Autowired
private EmbeddingModel embeddingModel;
@Bean
public ContentRetriever contentRetrieverXiaozhiPincone() {
// 创建一个 EmbeddingStoreContentRetriever 对象,用于从嵌入存储中检索内容
return EmbeddingStoreContentRetriever
.builder()
// 设置用于生成嵌入向量的嵌入模型
.embeddingModel(embeddingModel)
// 指定要使用的嵌入存储
.embeddingStore(embeddingStore)
// 设置最大检索结果数量,这里表示最多返回 1 条匹配结果
.maxResults(1)
// 设置最小得分阈值,只有得分大于等于 0.8 的结果才会被返回
.minScore(0.8)
// 构建最终的 EmbeddingStoreContentRetriever 实例
.build();
}
@AiService(
wiringMode = EXPLICIT,
streamingChatModel = "qwenStreamingChatModel",
chatMemoryProvider = "chatMemoryProviderXiaozhi",
tools = "appointmentTools",
contentRetriever = "contentRetrieverXiaozhiPincone" //配置向量存储
)
public interface XiaozhiAssistant {
@SystemMessage(fromResource = "zhaozhi-prompt-template.txt")
Flux<String> chat(@MemoryId Long memoryId, @UserMessage String userMessage);
}
然后直接运行
更多推荐




所有评论(0)