惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Hacker News: Ask HN
Hacker News: Ask HN
Recent Commits to openclaw:main
Recent Commits to openclaw:main
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
C
Check Point Blog
S
Security Affairs
Hacker News - Newest:
Hacker News - Newest: "LLM"
S
Secure Thoughts
Recorded Future
Recorded Future
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
T
The Blog of Author Tim Ferriss
B
Blog
C
Cybersecurity and Infrastructure Security Agency CISA
Google DeepMind News
Google DeepMind News
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
A
Arctic Wolf
T
The Exploit Database - CXSecurity.com
Stack Overflow Blog
Stack Overflow Blog
T
Threat Research - Cisco Blogs
GbyAI
GbyAI
AWS News Blog
AWS News Blog
MongoDB | Blog
MongoDB | Blog
Y
Y Combinator Blog
Google Online Security Blog
Google Online Security Blog
T
Troy Hunt's Blog
I
InfoQ
L
LINUX DO - 热门话题
WordPress大学
WordPress大学
C
Cisco Blogs
G
GRAHAM CLULEY
The Register - Security
The Register - Security
A
About on SuperTechFans
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Schneier on Security
Schneier on Security
Project Zero
Project Zero
H
Hackread – Cybersecurity News, Data Breaches, AI and More
P
Privacy & Cybersecurity Law Blog
Cloudbric
Cloudbric
H
Hacker News: Front Page
小众软件
小众软件
雷峰网
雷峰网
The Hacker News
The Hacker News
www.infosecurity-magazine.com
www.infosecurity-magazine.com
T
Tor Project blog
博客园 - 聂微东
N
Netflix TechBlog - Medium
V
Vulnerabilities – Threatpost
The GitHub Blog
The GitHub Blog
腾讯CDC
P
Palo Alto Networks Blog
Scott Helme
Scott Helme

博客园 - cn2025

kubesphere-KDP 工具脚本【kubeSphere发布ruoyi-pro前端】20260720 HbuilderX 内置终端转为 gitBash 20260720 kubeSphere发布ruoyi-pro后端-用到脚本 kubeSphere发布ruoyi-web前端 20260711 kubeSphere发布ruoyi-pro后端 k8s集群-kubeShpere 20260710 安装Helm 20260710 k8s-portainer docker 镜像查询 k8集群一键重置 docker run OceanBase spring ai alibaba doc AI2.0 【多模态】 20260615 世界只有一个墨脱 AI2.0 【Mcp-client】 20260611 AI2.0 【Mcp-server】 20260611 GoLand 配Go SDK AI2.0 【redis向量-Rag】 问答顾问器QuestionAnswerAdvisor 20260608 AI2.0 【redis向量】redis-stack 20260608 AI2.0 【Embedding】嵌入模型 20260606 AI 工具 AI2.0 Tool调用20260604 AI2.0 对话chatMemory20260601 AI2.0 模型输出结构化【POJO、Record、List、Map 】20260530 AI2.0 Prompt【模板、流式 API、系统提示词】 20260529 AI2.0 自定义Advisor 20260528 AI2.0 ollama 20260528 AI2.0 dashscope-openai 20260527 ps 配Claude 20260527 spring-ai-alibaba-agent 260526 票务 Tool+Spring Security【动态tooLs:toolCallbacks】 20260525 spring-ai-alibaba-agent 260525 spring-ai-alibaba-agent 260523 票务 Tool接口 / 方法 / 参数【无意义、可读、业务化、参数数量过多】 20260521 票务 Tool参数幻觉 20260521 spring-ai-alibaba-agent 260521 ToolTemperature 温度过低,AI推算缺失自由度20260520 spring-ai-alibaba-agent 260520 票务Tool 20260519 票务助手 -多模型20260518 结构化输出 -原理【structuredconverter】20260518 spring-ai-alibaba-agent 260518 Dify 添加Ollma模型qwen2:0.5b 应用 20260516 docker 部【dify-api】/【dify-web】 20260514 Chatclient 结构化输出20260514 spring-ai-alibaba-agent 260514 Chatmemory 多层(近、中、长期)20260513 ChatmemoryJdbc 历史对话存【JDBC】20260511 spring-ai-alibaba-agent 260511 ChatmemoryConversationId 多用户对话记忆 20260508 spring-ai-alibaba-agent 260508 ChatmemoryMax 历史对话长度20260507 2026SE Chatmemory 对话记忆20260506 spring-ai-alibaba-agent 260506 ChatClientPrompt 自定义拦截器【ReReadingAdvisor】重读提示词 20260430 docker-apache/kafka:4.1.2部暑 集群20260423 ChatClientPrompt Template.st20260428 ChatClientPrompt Template20260427 sb-KafkaListener 20260425 docker-apache/kafka:4.1.2部暑 20260425 dashscope-sb ChatClientPrompt20260425 SBAI-MultiPlatformAndModel 20260424 PlatformModel SB-ChatClient-DeepSeekDashScopeOllamaModel 20260424 dashscope-sb ChatClient20260420 ollama-sb 多态 图转文 20260418 【gemma3:4b 解析慢】 dashscope-sb 多模态(图片、语音识别) 文生视频 ollama-sb 20260414 dashscope-sb 阿里百炼-文生图20260413 dashscope-sb20260413 dashscope-sb20260411 docker-zabbix 20260410 deepseek-sb20260408 MQTT20260403 spring-ai-alibaba-agent 260403 MqttTest 20260401 spring-ai-alibaba-agent 260401 docker安装 EMQX spring-ai-alibaba-agent 260331 MQTT 20260331 spring-ai-alibaba-agent 三大 Java 生态 AI Agent 框架 CentOS7-静态 IP centos-stream10 安装 百炼-工作流-sb sb-flink1.13.1-jdk8-分隔字符串 20260125
ChatmemoryRedis 历史对话存【REDIS】20260512
cn2025 · 2026-05-12 · via 博客园 - cn2025

1、pom

<properties>
<java.version>17</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>3.2.0</spring-boot.version>
<spring-ai.version>1.0.0</spring-ai.version>
<spring-ai-alibaba.version>1.0.0.2</spring-ai-alibaba.version>
    <jedis.version>5.2.0</jedis.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 阿里云通义千问(DashScope)starter -->
<dependency>
<groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-starter-dashscope</artifactId>
</dependency>

<!--对话记忆 chat-memory-->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-autoconfigure-model-chat-memory</artifactId>
</dependency>
<!-- Spring AI JDBC 聊天记忆核心依赖 -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-chat-memory-repository-jdbc</artifactId>
</dependency>
<!-- Spring Boot JDBC Starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!-- MySQL 驱动 -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<!-- Spring AI Alibaba Redis 记忆 Starter -->
<dependency>
<groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-starter-memory-redis</artifactId>
</dependency>

<!-- Jedis 客户端依赖 -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>${jedis.version}</version>
</dependency>

</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- 统一管理Spring AI依赖版本 -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-bom</artifactId>
<version>${spring-ai.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-bom</artifactId>
<version>${spring-ai-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!-- Spring AI 里程碑/快照仓库(必须配置,否则依赖无法下载) -->
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<releases>
<enabled>false</enabled>
</releases>
</repository>
</repositories>

2、yml


server:
port: 18081
spring:
ai:
dashscope:
api-key: sk-8718a83408d7443b9544cXXXXXXXX
chat:
memory:
repository:
jdbc:
initialize-schema: always
schema: classpath:/sql/schema-mysql.sql
   memory:
   # Redis 配置必须放在 spring.ai 下,层级要和你的 @Value 匹配
   redis:
   host: 192.168.91.165 # 你的 Redis 地址
   port: 6379
   timeout: 5000
   # password: 123456 # 有密码再打开

datasource:
url: jdbc:mysql://192.168.91.165:3306/springai?useSSL=false&serverTimezone=UTC
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
logging:
level:
org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor: debug
#org.springframework.ai.chat.client.advisor: debug


3、config
import com.alibaba.cloud.ai.memory.redis.RedisChatMemoryRepository;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.memory.MessageWindowChatMemory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class config {

@Value("${spring.ai.memory.redis.host}")
private String redisHost;

@Value("${spring.ai.memory.redis.port}")
private int redisPort;

@Value("${spring.ai.memory.redis.password:}")
private String redisPassword;

@Value("${spring.ai.memory.redis.timeout}")
private int redisTimeout;

// @Bean
// ChatMemory chatMemoryMax(ChatMemoryRepository chatMemoryRepository) {
// return MessageWindowChatMemory
// .builder()
// // 自定义最大消息数,覆盖默认的20条 (2 轮用户 + 助手对话)
// //保留最近 2 条消息。若超出则删除最早的消息
// .maxMessages(2)
// // 绑定持久化仓库(支持多用户会话隔离)
// .chatMemoryRepository(chatMemoryRepository)
// .build();
// }
//
// @Bean
// ChatMemory chatMemoryJdbc(JdbcChatMemoryRepository chatMemoryRepository) {
// return MessageWindowChatMemory
// .builder()
// // 自定义最大消息数,覆盖默认的20条 (2 轮用户 + 助手对话)
// //保留最近 4 条消息。若超出则删除最早的消息
// .maxMessages(4)
// // 绑定JDBC持久化仓库(支持多用户会话隔离)
// .chatMemoryRepository(chatMemoryRepository)
// .build();
// }

@Bean
RedisChatMemoryRepository redisChatMemoryRepository() {
return RedisChatMemoryRepository
.builder()
.host(redisHost)
.port(redisPort)
// 无密码时注释该行
//.password(redisPassword)
.timeout(redisTimeout)
.build();
}

@Bean
ChatMemory chatMemoryRedis(RedisChatMemoryRepository chatMemoryRepository) {
return MessageWindowChatMemory
.builder()
// 自定义最大消息数,覆盖默认的20条 (2 轮用户 + 助手对话)
//保留最近 4 条消息。若超出则删除最早的消息
.maxMessages(4)
// 绑定JDBC持久化仓库(支持多用户会话隔离)
.chatMemoryRepository(chatMemoryRepository)
.build();
}
}


4、tool
package com.sb.dashscope18081.tool;

import org.springframework.ai.chat.client.ChatClientRequest;
import org.springframework.ai.chat.client.ChatClientResponse;
import org.springframework.ai.chat.client.advisor.api.AdvisorChain;
import org.springframework.ai.chat.client.advisor.api.BaseAdvisor;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.chat.prompt.PromptTemplate;
import java.util.Map;

/**
* 自定义拦截器(Advisor,重读提示词
*/
public class ReReadingAdvisor implements BaseAdvisor {

// 重读提示词模板
private static final String DEFAULT_USER_TEXT_ADVISE = """
{re2_input_query}
Read the question again: {re2_input_query}
""";

@Override
public ChatClientRequest before(ChatClientRequest chatClientRequest, AdvisorChain advisorChain) {
// 1. 用户提示词
String contents = chatClientRequest.prompt().getContents();

String re2InputQuery=PromptTemplate.builder().template(DEFAULT_USER_TEXT_ADVISE).build()
.render(Map.of("re2_input_query", contents));

ChatClientRequest clientRequest = chatClientRequest.mutate()
.prompt(Prompt.builder()
.content(re2InputQuery)
.build())
.build();
return clientRequest;
}

@Override
public ChatClientResponse after(ChatClientResponse chatClientResponse, AdvisorChain advisorChain) {
return chatClientResponse;
}

@Override
public int getOrder() {
return 0;
}
}

 

5、controller
import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatModel;
import com.sb.dashscope18081.tool.ReReadingAdvisor;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.PromptChatMemoryAdvisor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.memory.MessageWindowChatMemory;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;

@RequestMapping("/openai")
@ResponseBody
@Controller
public class ChatMemoryController {
@Autowired
private ChatClient.Builder chatClientBuilder;

@Autowired
private ChatMemory chatMemory; // 自动注入的MessageWindowChatMemory

@Autowired
DashScopeChatModel chatModel;

@Autowired
//保留最近 10 条消息。若超出则删除最早的消息
private ChatMemory chatMemoryMax;

@Autowired
//保留最近 10 条消息。若超出则删除最早的消息
//JDBC chatMemoryJdbc
private ChatMemory chatMemoryJdbc;

@Autowired
//Redis chatMemoryRedis
private ChatMemory chatMemoryRedis;

/**
* 基于 ChatMemoryredis 历史对话
*/
@GetMapping("/simple/chatmemoryredis")
public String chatmemoryredis () {
String conversationId = "redis001";
ChatClient chatClient = ChatClient.builder(chatModel)
.defaultAdvisors(
PromptChatMemoryAdvisor.builder(chatMemoryRedis).build()
)
.build();

String content= chatClient.prompt()
.user("你好,我叫杨坚!")
.advisors(new ReReadingAdvisor())
.advisors(advisorSpec->advisorSpec.param(ChatMemory.CONVERSATION_ID,conversationId))
.call()
.content();
System.out.println("content:" + content);

String content2= chatClient.prompt()
.user("我叫什么?")
.advisors(new ReReadingAdvisor())
.advisors(advisorSpec->advisorSpec.param(ChatMemory.CONVERSATION_ID,conversationId))
.call()
.content();
System.out.println("content2:" + content2);
return "【ChatMemoryredis历史对话】content:" +content+" content2:" +content2;
}

}


6、http://localhost:18081/openai/simple/chatmemoryredis

image

image