Spring AI - Redis缓存对话

先看效果

对话过程被缓存到了Redis 中。

原理

在上一节我们快速入门了SpringAI,具体文章请查看:快速入门Spring AI

创建 ChatClient 的代码如下:

java 复制代码
this.chatClient = ChatClient.builder(chatModel)
        .defaultSystem(DEFAULT_PROMPT)
        .defaultAdvisors(new MessageChatMemoryAdvisor(new InMemoryChatMemory()))
        .defaultAdvisors(new SimpleLoggerAdvisor())
        .defaultOptions(OpenAiChatOptions.builder().temperature(0.0d).build())
        .build();

其中new MessageChatMemoryAdvisor(new InMemoryChatMemory()) 会将对话缓存在内存中,查看类InMemoryChatMemory 的源码发现,它实际上实现了ChatMemory 接口,实现了 addget以及clear三个方法。

实现

先添加 Redis 的依赖:

xml 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

然后定义一个类 RedisChatMemory 实现 ChatMemory 接口,实现三个方法:

java 复制代码
@Override
public void add(String conversationId, List<Message> messages) {
    long time = System.currentTimeMillis();

    for (Message message : messages) {
        redisTemplate.opsForHash().put(conversationId, String.valueOf(time), message);
    }
}

@Override
public List<Message> get(String conversationId, int lastN) {
    Map<Object, Object> entries = redisTemplate.opsForHash().entries(conversationId);
    return entries.entrySet().stream()
            .sorted((o1, o2) -> {
                long time1 = Long.parseLong(o1.getKey().toString());
                long time2 = Long.parseLong(o2.getKey().toString());
                return Long.compare(time1, time2);
            }).limit(lastN)
            .map(e -> new UserMessage(e.getValue().toString()))
            .collect(Collectors.toList());
}

@Override
public void clear(String conversationId) {
    redisTemplate.delete(conversationId);
}

再把 RedisChatMemory 注册成 Bean 对象:

java 复制代码
@Bean
public RedisChatMemory redisChatMemory(RedisTemplate<String, Object> redisTemplate) {
    return new RedisChatMemory(redisTemplate);
}

最后替换 ChatClient 定义中的 InMemoryChatMemory

java 复制代码
this.chatClient = ChatClient.builder(chatModel)
        .defaultSystem(DEFAULT_PROMPT)
//      .defaultAdvisors(new MessageChatMemoryAdvisor(new InMemoryChatMemory()))
        .defaultAdvisors(new MessageChatMemoryAdvisor(redisChatMemory))
        .defaultAdvisors(new SimpleLoggerAdvisor())
        .defaultOptions(OpenAiChatOptions.builder().temperature(0.0d).build())
        .build();

具体代码:代码地址

相关推荐
week_泽29 分钟前
第5课:短期记忆与长期记忆原理 - 学习笔记_5
java·笔记·学习·ai agent
像风一样自由36 分钟前
android native 中的函数动态注册方式总结
android·java·服务器·安卓逆向分析·native函数动态注册·.so文件分析
兮动人1 小时前
Maven指定加载的类
java·maven·maven指定加载的类
wangkay881 小时前
【Java 转运营】Day04:抖音新号起号前准备全指南
java·开发语言·新媒体运营
亲爱的非洲野猪2 小时前
Java线程池深度解析:从原理到最佳实践
java·网络·python
亲爱的非洲野猪2 小时前
深入解析享元模式:用Java实现高性能对象复用
java·开发语言·享元模式
qq_401700412 小时前
Qt 事件处理机制
java·数据库·qt
rannn_1113 小时前
【Java项目】中北大学Java+数据库课设|校园食堂智能推荐与反馈系统
java·数据库·后端·课程设计·中北大学
NE_STOP3 小时前
SpringBoot-shiro-jwt-dubbo-redis分布式统一权限系统(完结)
java
zfj3213 小时前
java函数式接口 @FunctionalInterface用法
java·函数·function