第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,支持长期查询和审计。 你

相关推荐
会飞的老朱2 小时前
医药集团数智化转型,智能综合管理平台激活集团管理新效能
大数据·人工智能·oa协同办公
聆风吟º4 小时前
CANN runtime 实战指南:异构计算场景中运行时组件的部署、调优与扩展技巧
人工智能·神经网络·cann·异构计算
Codebee6 小时前
能力中心 (Agent SkillCenter):开启AI技能管理新时代
人工智能
聆风吟º7 小时前
CANN runtime 全链路拆解:AI 异构计算运行时的任务管理与功能适配技术路径
人工智能·深度学习·神经网络·cann
uesowys7 小时前
Apache Spark算法开发指导-One-vs-Rest classifier
人工智能·算法·spark
AI_56787 小时前
AWS EC2新手入门:6步带你从零启动实例
大数据·数据库·人工智能·机器学习·aws
User_芊芊君子7 小时前
CANN大模型推理加速引擎ascend-transformer-boost深度解析:毫秒级响应的Transformer优化方案
人工智能·深度学习·transformer
智驱力人工智能7 小时前
小区高空抛物AI实时预警方案 筑牢社区头顶安全的实践 高空抛物检测 高空抛物监控安装教程 高空抛物误报率优化方案 高空抛物监控案例分享
人工智能·深度学习·opencv·算法·安全·yolo·边缘计算
qq_160144877 小时前
亲测!2026年零基础学AI的入门干货,新手照做就能上手
人工智能
Howie Zphile7 小时前
全面预算管理难以落地的核心真相:“完美模型幻觉”的认知误区
人工智能·全面预算