
CREATE TABLE IF NOT EXISTS SPRING_AI_CHAT_MEMORY ( `conversation_id` VARCHAR(36) NOT NULL, `content` TEXT NOT NULL, `type` ENUM('USER', 'ASSISTANT', 'SYSTEM', 'TOOL') NOT NULL, `timestamp` TIMESTAMP NOT NULL, INDEX `SPRING_AI_CHAT_MEMORY_CONVERSATION_ID_TIMESTAMP_IDX` (`conversation_id`, `timestamp`));
字段
类型
说明
conversation_id
VARCHAR
会话 ID(如用户 ID)
type
ENUM
类型:USER,ASSISTANT,SYSTEM,TOOL
content
TEXT
消息内容
timestamp
TIMESTAMP
创建时间
此时只需要在数据库中执行这个脚本即可。
还有一种方式就是在配置文件中,指定schema在项目启动的时候,让它自动创建。
spring: ai: chat: memory: repository: jdbc: initialize-schema: always # 自动建表 schema: classpath:org/springframework/ai/chat/memory/repository/jdbc/schema-mysql.sql
这里我们采用手动创建的方式。
5.5 Advisor核心机制有了记忆窗口和记忆存储,还需要将这些存储起来的记忆作为 Prompt消息发送给大模型,所以Spring AI 创建了 Advisor机制。
真正让 AI 在每次调用时自动携带上下文 的关键组件是 **Advisor** —— 它是 Spring AI 中用于增强 Prompt 的核心设计模式。
5.5.1 什么是Advisor? 它解决了什么问题?通俗理解:AI 对话的“上下文注入器”
你可以把 Advisor 想象成一个“智能助手”,它在你每次向 AI 发送请求前,自动帮你做几件事:
“这个用户之前聊过什么?”“要不要把之前的对话加到这次请求里?”“怎么组织这些信息才最有效?”Advisor 就是负责这些逻辑的组件。它会在 ChatClient 发送请求前,自动修改 Prompt,加入必要的上下文信息。
5.5.2 BaseChatMemoryAdvisorBaseChatMemoryAdvisor这个聊天记忆的 Advisor 接口,这个接口其实是 Advisor的子接口,它有两个实现类MessageChatMemoryAdvisor和 PromptChatMemoryAdvisor. 下面的类图中省略了 Advisor接口
MessageChatMemoryAdvisor:以消息形式注入上下文。这是最直观的记忆方式 —— 将历史对话作为 消息列表 注入,LLM 会看到完整的对话历史,自然能记住上下文。[用户输入] → [Advisor 查找历史消息] → [构造完整消息链] → [发送给 LLM]例如:[ {"role": "user", "content": "我叫小明"}, {"role": "assistant", "content": "你好,小明!"}, {"role": "user", "content": "我昨天去了北京"}]PromptChatMemoryAdvisor:以系统提示词形式注入。这种方式不把历史作为“消息”,而是将其拼接到 系统提示词(System Prompt) 中。
系统提示:你是我的助手。以下是我们的对话历史:"用户:我叫小明""AI:你好,小明!"---当前问题:我昨天去了北京5.6 实战:构建一个支持多种记忆策略的聊天系统
本小节将构建一个多种记忆的聊天系统。本次将使用MySQL 数据库来存储历史聊天记录,所以需要按照 5.4 小节的描述,引入依赖和配置,以及创建数据库表.
5.6.1 记忆存储仓库。本次使用的是spring-ai-starter-model-chat-memory-repository-jdbc,前面提到,org.springframework.ai.model.chat.memory.repository.jdbc.autoconfigure.JdbcChatMemoryRepositoryAutoConfiguration自动配置中已经配置了bean:
public class JdbcChatMemoryRepositoryAutoConfiguration { ... @Bean @ConditionalOnMissingBean JdbcChatMemoryRepository jdbcChatMemoryRepository(JdbcTemplate jdbcTemplate, DataSource dataSource) { JdbcChatMemoryRepositoryDialect dialect = JdbcChatMemoryRepositoryDialect.from(dataSource); return JdbcChatMemoryRepository.builder().jdbcTemplate(jdbcTemplate).dialect(dialect).build(); } ...}5.6.2 记忆
ChatMemory自动配置类 org.springframework.ai.model.chat.memory.autoconfigure.ChatMemoryAutoConfiguration配置了 ChatMemory 这个Bean,我们可以自己写一个配置,让ChatMemory这个Bean使用 JdbcChatMemoryRepository
// chapter05/src/main/java/com/kaifamiao/chapter05/configuration/ChatMemoryConfiguration.javapublic class ChatMemoryConfiguration { // 让ChatMemory 使用 JdbcChatMemoryRepository @Bean ChatMemory chatMemory(JdbcChatMemoryRepository chatMemoryRepository) { return MessageWindowChatMemory.builder().chatMemoryRepository(chatMemoryRepository).build(); }}5.6.3 记忆advisor
创建一个Controller,在Controller中创建 advisor, 并配置到 chatClient中:
// chapter05/src/main/java/com/kaifamiao/chapter05/MemoryController.java@RestControllerpublic class MemoryController { private final ChatClient chatClient; @Autowired public MemoryController(ChatClient.Builder chatClientBuilder , ChatMemory chatMemory) { // 通过不同角色Message方式传递聊天记忆 Advisor chatMemoryAdvisor = MessageChatMemoryAdvisor.builder(chatMemory).build(); // 通过提示词的方式传递聊天记忆 //Advisor promptChatMemoryAdvisor = MessageChatMemoryAdvisor.builder(chatMemory).build(); this.chatClient = chatClientBuilder // 通过Advisors设置聊天记忆 .defaultAdvisors(chatMemoryAdvisor) .build(); } /** * @param question 问题 * @param conversationId 聊天记忆的id */ // http://localhost:8080/chat/memory?question=我是小明,为我推荐10部周星驰的电影&conversationId=1001 @GetMapping(value = "/chat/memory", produces = "text/html;charset=UTF-8") public Flux memory(@RequestParam(value = "question", required = true) String question , @RequestParam(value = "conversationId", required = true) Integer conversationId) { return this.chatClient.prompt() .user(question) // conversationId 很重要,多次提问时,请确保conversationId一致。这与 WEB应用中的session概念一致。 .advisors(a -> a.param(ChatMemory.CONVERSATION_ID, conversationId)) .stream() .content(); }}5.6.4 启动测试验证
开始测试之前,先检查数据库SPRING_AI_CHAT_MEMORY表中的数据,此时是空的。启动服务:
第一次请求GET http://localhost:8080/chat/memory?question=我是小明,为我推荐10部周星驰的电影&conversationId=1001AI 输出:你好,小明!周星驰是华语影坛最具影响力的喜剧演员和导演之一,他的电影融合无厘头幽默、深刻情感与社会讽刺,深受观众喜爱。.....祝你观影愉快,笑口常开,小明!
现在查看数据库,数据库中已经存储了发送给AI的问题和AI回答的内容:
相关文章









猜你喜欢
成员 网址收录40418 企业收录2986 印章生成263572 电子证书1157 电子名片68 自媒体91237