第3章:SpringAI进阶之会话记忆实战

AI大模型调用日志监控-Advisor环绕通知

什么是AI大模型的调用日志监控:

  • 是SpringAI框架提供的内置日志拦截器,基于AOP机制实现对AI交互请求的日志记录。
  • 通过拦截AI模型的调用过程,自动记录用户输入,系统指令,AI响应等关键信息,适用与开发调试和生产监控场景。

核心功能:

  1. 请求/响应追踪:记录用户输入文本,系统预设指令以及AI生成的完整响应内容。
  2. 默认日志级别:基于SLF4J输出DEBUG级别的日志,但是需要手动调整日志配置才会在默认环境下显示。

案例:

ChatClient初始时通过defaultAdvisors()方法添加。这里我们设置简单日志级别就行。

复制代码
@Configuration
public class Config {

    @Bean
    ChatClient chatClient(ChatClient.Builder builder){
        return builder
                .defaultSystem("你是guslegend团队的智能学习助手,你可以回答各种各样关于it的问题")
                .defaultAdvisors(new SimpleLoggerAdvisor())
                .build();
    }
}

然后我们需要开启DEBUG日志,否则SimpleLoggerAdvisor输出看不见。

复制代码
logging:
  level:
    org.springframework.ai.chat.client.advisor: debug

2025-11-22T09:49:08.503+08:00 DEBUG 41332 --- [SpringAI] [nio-8080-exec-4] o.s.a.c.c.advisor.SimpleLoggerAdvisor    : response: {
  "result" : {
    "output" : {
      "messageType" : "ASSISTANT",
      "metadata" : {
        "role" : "ASSISTANT",
        "messageType" : "ASSISTANT",
        "refusal" : "",
        "finishReason" : "STOP",
        "annotations" : [ ],
        "index" : 0,
        "id" : "44d7ed80-cc24-430e-9dae-3e54e9f683e5"
      },
      "toolCalls" : [ ],
      "media" : [ ],
      "text" : "你好!我是你的智能学习助手,来自guslegend团队。我可以帮助你解答关于IT领域的各种问题,比如编程、网络、数据库、人工智能等等。如果你有任何疑问或需要学习资源,随时告诉我,我会尽力协助你!😊 有什么我可以帮你的吗?"
    },
    "metadata" : {
      "finishReason" : "STOP",
      "contentFilters" : [ ],
      "empty" : true
    }
  },
  "metadata" : {
    "id" : "44d7ed80-cc24-430e-9dae-3e54e9f683e5",
    "model" : "deepseek-chat",
    "rateLimit" : {
      "requestsLimit" : null,
      "requestsRemaining" : null,
      "requestsReset" : null,
      "tokensLimit" : null,
      "tokensRemaining" : null,
      "tokensReset" : null
    },
    "usage" : {
      "promptTokens" : 21,
      "completionTokens" : 57,
      "totalTokens" : 78,
      "nativeUsage" : {
        "completion_tokens" : 57,
        "prompt_tokens" : 21,
        "total_tokens" : 78,
        "prompt_tokens_details" : {
          "cached_tokens" : 0
        }
      }
    },
    "promptMetadata" : [ ],
    "empty" : false
  },
  "results" : [ {
    "output" : {
      "messageType" : "ASSISTANT",
      "metadata" : {
        "role" : "ASSISTANT",
        "messageType" : "ASSISTANT",
        "refusal" : "",
        "finishReason" : "STOP",
        "annotations" : [ ],
        "index" : 0,
        "id" : "44d7ed80-cc24-430e-9dae-3e54e9f683e5"
      },
      "toolCalls" : [ ],
      "media" : [ ],
      "text" : "你好!我是你的智能学习助手,来自guslegend团队。我可以帮助你解答关于IT领域的各种问题,比如编程、网络、数据库、人工智能等等。如果你有任何疑问或需要学习资源,随时告诉我,我会尽力协助你!😊 有什么我可以帮你的吗?"
    },
    "metadata" : {
      "finishReason" : "STOP",
      "contentFilters" : [ ],
      "empty" : true
    }
  } ]
}

我们通过观察可以发现输出内容为:请求阶段(用户输入文本,系统指令,上下文对话),响应阶段(AI生成的完整内容,token 消耗,模型名称和参数)。

SprinAI整合ChatModel对话记忆存储

什么是会话基于ChatMemory:是AI对话系统的大脑,通过存储和服用历史对话内容,使模型能够理解上下文关联,实现连贯的多轮交互。

核心价值:

  • 避免失忆:解决大模型无状态特性导致上下文丢失问题。
  • 提升效率:减少用户重复输入,降低模型Token 消耗(每次请求仅需要传递关键增量信息)。
  • 支持复杂流程:如多步骤任务引导(填写表单,故障排查),个性化服务(基于历史偏好推荐)。

SpringAI针对会话内容存储做了封装其中关键组件:

  1. ChatMemory接口:定义存储/检索对话历史的核心方法(add/get/clear)。
  2. ChatMemoryRepository:底层存储实现,默认提供内容,好处是方便开箱即用,缺点是数据不持久化,重启后丢失。还可以数据库,Redis等方案。
  1. MessageWindowChatMemory:默认对话历史管理器,采用滑动窗口策略(默认保留20条消息),自动过滤旧消息以控制内存占用。
  2. MessageChatMemoryAdvisor:SpringAI拦截器,自动将历史对话附加到模型请求中,无需手动维护上下文数组。

案例实战:

首先需要配置存储方案

复制代码
@Configuration
public class Config {

    @Bean
    ChatClient chatClient(ChatClient.Builder builder, ChatMemory chatMemory){
        return builder
                .defaultSystem("你是guslegend团队的智能学习助手,你可以回答各种各样关于it的问题")
                .defaultAdvisors(new SimpleLoggerAdvisor(), MessageChatMemoryAdvisor.builder(chatMemory).build())
                .build();
    }
}

对话接口整合

复制代码
@RestController
@RequestMapping("/ai")
public class MemoryController {

    @Autowired
    private ChatClient chatClient;

    @GetMapping("/memory")
    public String chat(@RequestParam(name = "msg")String msg,@RequestParam(name = "conversationId")String conversationId){
        String res = this.chatClient.prompt()
                .user(msg)
                .advisors(a ->a.param(ChatMemory.CONVERSATION_ID, conversationId))
                .call()
                .content();
        return res;
    }
}

那么为什么大模型可以记住历史对话?

主要是通过ChatMemory.CONVERSATION_ID参数来指定对话会话ID的。ChatClient自动从memory中检索到历史消息并添加到prompt提示词中,再给大模型进行整合回答。响应后自动将对话记录存储到memory中,存储起来。

CharModel对话记存储常见问题

内存泄漏

问题表现**:**为长期运行后内存占用时间持续增长。

解决方法**:** 配置滑动窗口大小MessageWindowChatMemory.builder().maxMessages(20).build();定期清理过期会话(如Redis设置TTL)。

上下文冗余token消化大

问题表现:模型响应包含过时信息。

解决方法:自动过滤旧消息,根据历史对话,提取关键信息,生成摘要;调用LLM对历史对话生成摘要,后续交互仅传递摘要而非完整历史;结合业务逻辑动态调整上下文(如用户切换话题时清空历史)。

存储性能瓶颈

问题表现:高并发场景下数据库写入延迟高。

解决方案(混合存储方案):读取分离(读请求走Redis,写请求异步写入数据库);批量操作(使用Redis管道Pipeline或MySQL批量插入);热数据也叫近期对话(使用Redis缓存,保证高并发场景下的读写性能);冷数据也叫历史对话:归档到Mysql,支持长期查询和审计。 你

相关推荐
Yao.Li34 分钟前
PVN3D ORT CUDA Custom Ops 实现与联调记录
人工智能·3d·具身智能
诺伦37 分钟前
LocalClaw 在智能制造的新机会:6部门AI+电商政策下的工厂AI升级方案
人工智能·制造
小陈工3 小时前
Python Web开发入门(十七):Vue.js与Python后端集成——让前后端真正“握手言和“
开发语言·前端·javascript·数据库·vue.js·人工智能·python
墨染天姬7 小时前
【AI】端侧AIBOX可以部署哪些智能体
人工智能
AI成长日志7 小时前
【Agentic RL】1.1 什么是Agentic RL:从传统RL到智能体学习
人工智能·学习·算法
2501_948114247 小时前
2026年大模型API聚合平台技术评测:企业级接入层的治理演进与星链4SAPI架构观察
大数据·人工智能·gpt·架构·claude
小小工匠7 小时前
LLM - awesome-design-md 从 DESIGN.md 到“可对话的设计系统”:用纯文本驱动 AI 生成一致 UI 的新范式
人工智能·ui
黎阳之光7 小时前
黎阳之光:视频孪生领跑者,铸就中国数字科技全球竞争力
大数据·人工智能·算法·安全·数字孪生
小超同学你好8 小时前
面向 LLM 的程序设计 6:Tool Calling 的完整生命周期——从定义、决策、执行到观测回注
人工智能·语言模型
智星云算力8 小时前
本地GPU与租用GPU混合部署:混合算力架构搭建指南
人工智能·架构·gpu算力·智星云·gpu租用