embeddign优化

This commit is contained in:
spllzh
2025-08-07 20:51:29 +08:00
parent bdb78caf59
commit bd20deca35
12 changed files with 336 additions and 7 deletions

View File

@@ -1,8 +1,12 @@
package com.cst.langchain4jheima; package com.cst.langchain4jheima;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.FilterType;
@MapperScan("com.cst.langchain4jheima.mapper")
@SpringBootApplication @SpringBootApplication
public class Langchain4jHeima20250803Application { public class Langchain4jHeima20250803Application {

View File

@@ -17,7 +17,8 @@ import reactor.core.publisher.Flux;
streamingChatModel = "openAiStreamingChatModel", //配置流式 输出模型 streamingChatModel = "openAiStreamingChatModel", //配置流式 输出模型
// chatMemory = "chatMemory", // 配置聊天记忆对象 ,基于内存 // chatMemory = "chatMemory", // 配置聊天记忆对象 ,基于内存
chatMemoryProvider = "chatMemoryProvider",//配置会话记忆 提供者对象 基于Redis chatMemoryProvider = "chatMemoryProvider",//配置会话记忆 提供者对象 基于Redis
contentRetriever = "contentRetriever" // 配置向量数据库检索对象 contentRetriever = "contentRetriever", // 配置向量数据库检索对象
tools = "reservationTool" // 配置工具对象
) )
public interface CstAIStreamingService { public interface CstAIStreamingService {
@@ -28,7 +29,7 @@ public interface CstAIStreamingService {
public Flux<String> chatMemoryId(@MemoryId String memoryId, @UserMessage String message); public Flux<String> chatMemoryId(@MemoryId String memoryId, @UserMessage String message);
// @SystemMessage(fromResource = "system.txt") @SystemMessage(fromResource = "system.txt")
public Flux<String> chatMemoryIdRAG(@MemoryId String memoryId, @UserMessage String message); public Flux<String> chatMemoryIdRAG(@MemoryId String memoryId, @UserMessage String message);
} }

View File

@@ -0,0 +1,21 @@
package com.cst.langchain4jheima.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RestController;
/**
* <p>
* 前端控制器
* </p>
*
* @author 李中华 ,spllzh
* @since 2025-08-05
*/
@RestController
@RequestMapping("/reservation")
public class ReservationController {
}

View File

@@ -62,7 +62,7 @@ public class EnbedingModelConfig {
return embeddingStore; return embeddingStore;
} }
@Bean("myEmbeddingStoreInMemory2") // @Bean("myEmbeddingStoreInMemory2")
// @Primary // @Primary
public EmbeddingStore embeddingStoreInMemory2() throws IOException { public EmbeddingStore embeddingStoreInMemory2() throws IOException {
//1 , 加载知识库文档进 内存 //1 , 加载知识库文档进 内存
@@ -79,14 +79,14 @@ public class EnbedingModelConfig {
EmbeddingStoreIngestor ingestor = EmbeddingStoreIngestor.builder() EmbeddingStoreIngestor ingestor = EmbeddingStoreIngestor.builder()
.embeddingStore(embeddingStore) .embeddingStore(embeddingStore)
.documentSplitter(recursiveSplitter) //设置文档分割器 .documentSplitter(recursiveSplitter) //设置文档分割器
.embeddingModel(embeddingModel) // .embeddingModel(embeddingModel)
.build(); .build();
ingestor.ingest( documents1); ingestor.ingest( documents1);
return embeddingStore; return embeddingStore;
} }
@Bean("myEmbeddingStoreInRedis") // @Bean("myEmbeddingStoreInRedis") 不要打开,否则每次都会调用 阿里云的向量化模型 消耗token
// @Primary // @Primary
public EmbeddingStore embeddingStoreInRedis() throws IOException { public EmbeddingStore embeddingStoreInRedis() throws IOException {
//1 , 加载知识库文档进 内存 //1 , 加载知识库文档进 内存
@@ -107,7 +107,7 @@ public class EnbedingModelConfig {
} }
@Bean @Bean
public ContentRetriever contentRetriever(@Qualifier("myEmbeddingStoreInMemory2")EmbeddingStore store){ public ContentRetriever contentRetriever(){
EmbeddingStoreContentRetriever contentRetriever = EmbeddingStoreContentRetriever.builder() EmbeddingStoreContentRetriever contentRetriever = EmbeddingStoreContentRetriever.builder()
.embeddingStore(redisEmbeddingStore) .embeddingStore(redisEmbeddingStore)
.embeddingModel(embeddingModel) .embeddingModel(embeddingModel)

View File

@@ -0,0 +1,22 @@
package com.cst.langchain4jheima.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.cst.langchain4jheima.pojo.Reservation;
import org.apache.ibatis.annotations.Mapper;
/**
* <p>
* Mapper 接口
* </p>
*
* @author 李中华 ,spllzh
* @since 2025-08-05
*/
@Mapper
public interface ReservationMapper extends BaseMapper<Reservation> {
}

View File

@@ -0,0 +1,52 @@
package com.cst.langchain4jheima.pojo;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.TableField;
import java.io.Serializable;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* <p>
*
* </p>
*
* @author 李中华 ,spllzh
* @since 2025-08-05
*/
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("reservation")
public class Reservation implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
private Long id;
@TableField("name")
private String name;
@TableField("gender")
private String gender;
@TableField("phone")
private String phone;
@TableField("province")
private String province;
@TableField("datetime")
private LocalDateTime datetime;
}

View File

@@ -0,0 +1,23 @@
package com.cst.langchain4jheima.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.cst.langchain4jheima.pojo.Reservation;
import java.util.List;
/**
* <p>
* 服务类
* </p>
*
* @author 李中华 ,spllzh
* @since 2025-08-05
*/
public interface IReservationService extends IService<Reservation> {
boolean saveReservation(Reservation reservation);
List<Reservation> getReservationsByPhone(String phone);
}

View File

@@ -0,0 +1,44 @@
package com.cst.langchain4jheima.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cst.langchain4jheima.mapper.ReservationMapper;
import com.cst.langchain4jheima.pojo.Reservation;
import com.cst.langchain4jheima.service.IReservationService;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* <p>
* 服务实现类
* </p>
*
* @author 李中华 ,spllzh
* @since 2025-08-05
*/
@Service
public class ReservationServiceImpl extends ServiceImpl<ReservationMapper, Reservation> implements IReservationService {
/**
* 保存预约信息
* @param reservation 预约信息
* @return 是否保存成功
*/
public boolean saveReservation(Reservation reservation) {
return this.save(reservation);
}
/**
* 根据手机号查询预约信息
* @param phone 手机号
* @return 预约信息列表
*/
public List<Reservation> getReservationsByPhone(String phone) {
return this.lambdaQuery().eq(Reservation::getPhone, phone).list();
}
}

View File

@@ -0,0 +1,42 @@
package com.cst.langchain4jheima.tools;
import com.cst.langchain4jheima.pojo.Reservation;
import com.cst.langchain4jheima.service.IReservationService;
import dev.langchain4j.agent.tool.P;
import dev.langchain4j.agent.tool.Tool;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
/**
* Author: 李中华 wx: spllzh email(qq): 28668817@qq.com
* Date: 2025/8/5 20:36
**/
@Component
public class ReservationTool {
@Autowired
private IReservationService reservationService;
@Tool("根据手机号查询志愿填报预约信息")
public String getReservationsByPhone(String phone) {
return reservationService.getReservationsByPhone(phone).toString();
}
@Tool("保存志愿填报预约信息")
public String saveReservation(String name ,
@P("考生姓名") String gender ,
@P("考生手机号")String phone ,
@P("考生手省份")String province ,
@P("考生预约时间,格式为yyy-MM-dd'T' HH:mm") String datetime) {
Reservation reservation = new Reservation();
reservation.setName(name);
reservation.setGender(gender);
reservation.setPhone(phone);
reservation.setProvince(province);
reservation.setDatetime(LocalDateTime.parse(datetime));
return reservationService.saveReservation(reservation) ? "保存成功" : "保存失败";
}
}

View File

@@ -19,6 +19,7 @@ langchain4j:
log-requests: true log-requests: true
log-responses: true log-responses: true
max-segments-per-batch: 10 max-segments-per-batch: 10
# redis 向量数据库
community: community:
redis: redis:
host: 101.43.230.106 host: 101.43.230.106
@@ -35,4 +36,22 @@ spring:
port: 6389 port: 6389
host: 124.221.59.58 host: 124.221.59.58
password: qwe123 password: qwe123
database: 0 database: 0
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://124.221.59.58:3309/rj_user_clue?useUnicode=true&characterEncoding=utf8
username: root
password: ChangAndb.123!
hikari:
maximumPoolSize: 10
minimumIdle: 5
idleTimeout: 300000
maxLifetime: 600000
connectionTestQuery: "SELECT 1"
output:
ansi:
enabled: always
mybatis:
configuration:
map-underscore-to-camel-case: true

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.rongl.mapper.ReservationMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.cst.langchain4jheima.pojo.Reservation">
<id column="id" property="id" />
<result column="name" property="name" />
<result column="gender" property="gender" />
<result column="phone" property="phone" />
<result column="province" property="province" />
<result column="datetime" property="datetime" />
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id, name, gender, phone, province, datetime
</sql>
</mapper>

View File

@@ -0,0 +1,81 @@
package com.cst.langchain4jheima.service;
/**
* Author: 李中华 wx: spllzh email(qq): 28668817@qq.com
* Date: 2025/8/5 19:02
**/
import com.cst.langchain4jheima.Langchain4jHeima20250803Application;
import com.cst.langchain4jheima.pojo.Reservation;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import static org.junit.jupiter.api.Assertions.*;
import java.time.LocalDateTime;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
@SpringBootTest(classes = Langchain4jHeima20250803Application.class)
class ReservationServiceTest {
@Autowired
private IReservationService reservationService;
@Test
void testSaveReservation() {
// 创建测试数据
Reservation reservation = new Reservation();
reservation.setName("张三");
reservation.setGender("");
reservation.setPhone("13800138000");
reservation.setProvince("北京市");
reservation.setDatetime(LocalDateTime.now());
// 测试保存功能
boolean result = reservationService.save(reservation);
// 验证保存成功
assertTrue(result);
assertNotNull(reservation.getId());
}
@Test
void testGetReservationsByPhone() {
// 先保存一条测试数据
Reservation reservation = new Reservation();
reservation.setName("李四");
reservation.setGender("");
reservation.setPhone("13900139000");
reservation.setProvince("上海市");
reservation.setDatetime(LocalDateTime.now());
reservationService.save(reservation);
// 测试根据手机号查询功能
List<Reservation> reservations = ((com.cst.langchain4jheima.service.impl.ReservationServiceImpl) reservationService)
.getReservationsByPhone("13900139000");
// 验证查询结果
assertNotNull(reservations);
assertFalse(reservations.isEmpty());
assertEquals("李四", reservations.get(0).getName());
assertEquals("13900139000", reservations.get(0).getPhone());
}
@Test
void testGetReservationsByPhoneWithNoResults() {
// 测试查询不存在的手机号
List<Reservation> reservations = ((com.cst.langchain4jheima.service.impl.ReservationServiceImpl) reservationService)
.getReservationsByPhone("00000000000");
// 验证查询结果为空
assertNotNull(reservations);
assertTrue(reservations.isEmpty());
}
}