当前位置: 首页 > news >正文

Spring AI Alibaba 学习记录(记忆功能实现)

1. “记忆”到底是什么

大语言模型本身通常是“无状态”的:每次请求只看得到你这一次发给它的内容。

之所以看起来“记得之前说过什么”,本质是应用在每次请求时,把一段历史对话一起带给模型

一个直观例子:

  • 第 1 轮
    • 问:10 个苹果分给 2 个人,每人多少个?
    • 模型看到:10 个苹果分给 2 个人,每人多少个?
    • 模型答:5 个
  • 第 2 轮
    • 问:如果有 5 个人呢?
    • 模型看到:10 个苹果分给 2 个人... + 模型答 5 个 + 如果有 5 个人呢?
    • 模型答:2 个

所以:把所有问题都塞在同一个对话里,历史越长,token 消耗越快,成本也越高。

2. Spring AI 的“记忆”怎么做

Spring AI 通常把“记忆”拆成三件事:

  • 存放聊天记录的地方:内存 / 数据库 / 其他存储
  • 控制取多少历史:常见是“只取最近 N 条”
  • 自动读写历史:每次调用模型前取历史、调用后把新消息写回去

需要特别记住一个概念:会话 ID(conversationId)

  • 这是用来区分“这一段对话属于谁/属于哪个聊天窗口”的标识
  • 每次请求都必须传同一个 conversationId,才能续上上一轮的历史

3. 存到内存(适合学习 / 开发)

3.1 手动管理(更直观,但不够优雅)

importorg.springframework.ai.chat.memory.ChatMemory;importorg.springframework.ai.chat.memory.MessageWindowChatMemory;importorg.springframework.ai.chat.messages.UserMessage;importorg.springframework.ai.chat.model.ChatModel;importorg.springframework.ai.chat.model.ChatResponse;importorg.springframework.ai.chat.prompt.Prompt;publicclassMemoryDemo{privatefinalChatModelchatModel;publicMemoryDemo(ChatModelchatModel){this.chatModel=chatModel;}publicvoidrun(){ChatMemorychatMemory=MessageWindowChatMemory.builder().maxMessages(10).build();StringconversationId="007";chatMemory.add(conversationId,newUserMessage("My name is James Bond"));ChatResponseres1=chatModel.call(newPrompt(chatMemory.get(conversationId)));chatMemory.add(conversationId,res1.getResult().getOutput());chatMemory.add(conversationId,newUserMessage("What is my name?"));ChatResponseres2=chatModel.call(newPrompt(chatMemory.get(conversationId)));chatMemory.add(conversationId,res2.getResult().getOutput());}}

3.2 自动管理(更常用、更优雅)

核心思路:给ChatClient加一个“记忆增强器”,让它自动做:

  • 调用前:按 conversationId 取历史
  • 调用后:把新消息写回去
importorg.springframework.ai.chat.client.ChatClient;importorg.springframework.ai.chat.client.advisor.memory.MessageChatMemoryAdvisor;importorg.springframework.ai.chat.memory.ChatMemory;importorg.springframework.ai.chat.memory.MessageWindowChatMemory;importorg.springframework.ai.chat.model.ChatModel;publicclassChatService{privatefinalChatClientchatClient;privatefinalStringconversationId="007";publicChatService(ChatModelchatModel){ChatMemorychatMemory=MessageWindowChatMemory.builder().maxMessages(10).build();this.chatClient=ChatClient.builder(chatModel).defaultAdvisors(MessageChatMemoryAdvisor.builder(chatMemory).build()).build();}@GetMapping("/ai")publicStringchat(StringuserInput){returnchatClient.prompt().user(userInput).advisors(a->a.param(ChatMemory.CONVERSATION_ID,conversationId)).call().content();}}

4. 存到数据库(JDBC,适合生产)

当你希望“重启不丢”“多实例共享”“可追溯”,就要把聊天记录存到数据库。

4.1 引入依赖

Maven:

<dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter-model-chat-memory-repository-jdbc</artifactId></dependency>

4.2 建表(很关键)

JDBC 方式会用一张表保存聊天记录(默认表名SPRING_AI_CHAT_MEMORY)。

默认情况下,只有“内嵌数据库”才会自动建表。对于 MySQL / PostgreSQL 这类常见数据库,一般需要显式开启:

spring.ai.chat.memory.repository.jdbc.initialize-schema=always

4.3 配置代码:把“窗口记忆”绑定到“JDBC 存储”

importorg.springframework.ai.chat.client.ChatClient;importorg.springframework.ai.chat.client.advisor.memory.MessageChatMemoryAdvisor;importorg.springframework.ai.chat.memory.ChatMemory;importorg.springframework.ai.chat.memory.MessageWindowChatMemory;importorg.springframework.ai.chat.memory.repository.ChatMemoryRepository;importorg.springframework.ai.chat.model.ChatModel;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;@ConfigurationpublicclassAiMemoryConfig{@BeanpublicChatMemorychatMemory(ChatMemoryRepositorychatMemoryRepository){returnMessageWindowChatMemory.builder().chatMemoryRepository(chatMemoryRepository).maxMessages(10).build();}@BeanpublicChatClientchatClient(ChatModelchatModel,ChatMemorychatMemory){returnChatClient.builder(chatModel).defaultAdvisors(MessageChatMemoryAdvisor.builder(chatMemory).build()).build();}}

说明:

  • ChatMemoryRepository会由 JDBC starter 自动装配成数据库实现
  • MessageWindowChatMemory负责“只拿最近 N 条”,避免 token 失控

4.4 Controller 调用:每次都带 conversationId

importorg.springframework.ai.chat.client.ChatClient;importorg.springframework.ai.chat.memory.ChatMemory;importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.RequestParam;importorg.springframework.web.bind.annotation.RestController;@RestControllerpublicclassAIController{privatefinalChatClientchatClient;publicAIController(ChatClientchatClient){this.chatClient=chatClient;}@GetMapping("/ai")publicStringgeneration(@RequestParamStringuserInput,@RequestParamStringconversationId){returnthis.chatClient.prompt().user(userInput).advisors(a->a.param(ChatMemory.CONVERSATION_ID,conversationId)).call().content();}}

PS:由于本人学习的不够深刻可能会出现错误,请多多包涵

http://www.jsqmd.com/news/475850/

相关文章:

  • 使用Kubernetes管理FireRedASR-AED-L集群的最佳实践
  • 比迪丽LoRA模型Matlab仿真接口初探:科研可视化中的艺术化表达
  • 比迪丽SDXL模型多场景落地:电商同人周边、社群配图、创作素材库
  • 提升算法调试效率:基于快马平台快速迭代evomap可视化方案
  • Super Resolution处理结果保存:输出路径与命名规则说明
  • ollama运行Phi-4-mini-reasoning效果实测:在形式化验证、类型推导等硬核场景表现
  • 从Perfetto视角看Audio异常underrun问题的表现
  • [Redis小技巧11]Redis Key 过期策略与内存淘汰机制:深度解析与实战指南
  • 基于龙卷风优化算法(TOC) 的多个无人机协同路径规划(可以自定义无人机数量及起始点)附Matlab代码
  • 2026年知名的防水行程开关厂家推荐:2NC 1NO行程开关/TUV认证行程开关厂家热卖产品推荐(近期) - 品牌宣传支持者
  • 2025年全国行业职业技能竞赛第四届全国数据安全职业技能竞赛暨第四届安防行业职业技能竞赛“美亚柏科杯“数据安全管理员样题
  • 工业数字化提速,边缘计算存储如何减负?天硕工业级固态硬盘给出答案
  • 哪款减肥产品掉秤快还安全?2026 高性价比减脂代餐推荐:懒人“躺瘦”不反弹指南 - 企业推荐官【官方】
  • YOLO12教学演示指南:Gradio界面动态调参+检测效果对比教学
  • Fish-Speech-1.5与Vue.js前端集成:实时语音预览功能实现
  • 网络基础干货|域名/DNS/URL 一篇吃透
  • 提升效率:用快马生成Python脚本自动批量下载推特媒体
  • 纯硬件嵌入式鞭炮声播放系统设计
  • 哪款减肥代餐好用又安全?腰纪线(MetaSlim)全营养代餐,以精准控热+代谢重启,解锁长效减脂 - 企业推荐官【官方】
  • 红区之困:分布式光伏爆发背后的“逆流危机”
  • DDrawCompat深度剖析:经典游戏现代重生的技术解密
  • LuckyLilliaBot三阶配置能力提升指南:从基础搭建到企业级部署
  • 全球海运业趋势晴雨表——能源与数字转型进展评估 劳氏船级社 2025-3
  • 2026年质量好的球磨铁铸件品牌推荐:铸铁平台铸件/泊头机床床身铸件高口碑品牌推荐 - 品牌宣传支持者
  • 主板风扇控制异常深度解决方案:从硬件原理到智能调校
  • Phi-3-mini-128k-instruct行业应用:医疗问诊摘要、患者教育材料生成实践
  • 立知重排序模型在Dify上的应用:搭建智能搜索引擎优化工作流
  • 2026年靠谱的高端同步隐藏轨品牌推荐:缓冲同步隐藏轨/品牌同步隐藏轨/三节同步隐藏轨厂家口碑推荐汇总 - 品牌宣传支持者
  • 2026年口碑好的品牌厨房拉篮品牌推荐:橱柜厨房拉篮/调味厨房拉篮厂家实力参考 - 品牌宣传支持者
  • 1亿次真实操作训练出来的自动装卸车AI,有了!