MessageChatMemoryAdvisor + MongoDB 完整配置指南

MessageChatMemoryAdvisor 默认使用内存存储,生产环境需配置 MongoDB 实现持久化。以下是完整配置方案


步骤1:添加 Maven 依赖

pom.xml 中添加 Spring AI 官方提供的 MongoDB 存储 starter:

复制代码
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-model-chat-memory-repository-mongodb</artifactId>
</dependency>

同时确保已添加 Spring Data MongoDB 依赖:

复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

步骤2:配置 MongoDB 连接

application.yml 中配置 MongoDB 连接信息:

复制代码
spring:
  data:
    mongodb:
      uri: mongodb://localhost:27017/chat_memory_db
      # 或分步配置
      # host: localhost
      # port: 27017
      # database: chat_memory_db
      # username: your_username
      # password: your_password

步骤3:配置 ChatMemory Bean

提供 两种配置方式(推荐自动配置):

方式A:自动配置(推荐)

Spring AI 会自动配置 MongoChatMemoryRepository,只需在配置文件中开启:

复制代码
spring:
  ai:
    chat:
      memory:
        repository:
          mongo:
            create-indices: true  # 启动时自动创建索引
            ttl: 86400           # 可选:消息TTL(秒),86400=24小时,0=永久存储

然后在 Java 配置类中注入即可:

复制代码
@Configuration
public class ChatMemoryConfig {

    @Autowired
    private MongoChatMemoryRepository mongoChatMemoryRepository; // 自动注入

    @Bean
    public ChatMemory chatMemory() {
        return MessageWindowChatMemory.builder()
                .chatMemoryRepository(mongoChatMemoryRepository)
                .maxMessages(30)  // 保留最近30条消息
                .build();
    }
}

方式B:手动配置

如需自定义,可手动创建 MongoChatMemoryRepository

复制代码
@Configuration
public class ChatMemoryConfig {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Bean
    public ChatMemory chatMemory() {
        // 手动创建 Repository
        MongoChatMemoryRepository repository = MongoChatMemoryRepository.builder()
                .mongoTemplate(mongoTemplate)
                .build();

        return MessageWindowChatMemory.builder()
                .chatMemoryRepository(repository)
                .maxMessages(30)
                .build();
    }
}

步骤4:配置 MessageChatMemoryAdvisor 并集成到 ChatClient

复制代码
@Configuration
public class AIConfig {

    @Bean
    public ChatClient chatClient(ChatModel chatModel, ChatMemory chatMemory) {
        return ChatClient.builder(chatModel)
                .defaultSystem("你是专业的智能客服助手")
                .defaultAdvisors(
                    MessageChatMemoryAdvisor.builder(chatMemory)
                            .conversationId("default")
                            .build()
                )
                .build();
    }
}

步骤5:Controller 中使用(关键:传递 conversationId)

复制代码
@RestController
@RequestMapping("/chat")
public class ChatController {
    
    private final ChatClient chatClient;

    public ChatController(ChatClient.Builder builder, ChatMemory chatMemory) {
        this.chatClient = builder
                .defaultAdvisors(
                    MessageChatMemoryAdvisor.builder(chatMemory).build()
                )
                .build();
    }

    @PostMapping
    public String chat(@RequestBody ChatRequest request) {
        return chatClient.prompt(request.getMessage())
                .advisors(advisor -> 
                    advisor.param(ChatMemory.CONVERSATION_ID, request.getChatId())
                )
                .call()
                .content();
    }
}

@Data
class ChatRequest {
    private String chatId;    // 用户会话ID(必须传递)
    private String message;   // 用户消息
}

步骤6:高级配置与注意事项

6.1 数据存储结构

MongoDB 中会自动创建集合 ai_chat_memory ,文档格式如下:

复制代码
{
  "_id": "conversationId::timestamp",
  "conversationId": "user123",
  "messages": [
    {
      "type": "user",
      "text": "你好",
      "metadata": {}
    },
    {
      "type": "assistant", 
      "text": "你好!有什么可以帮助你的?",
      "metadata": {}
    }
  ],
  "createdAt": ISODate("2025-12-01T10:30:00.000Z")
}

6.2 索引配置问题

重要 :根据 GitHub Issue #4839,当前版本(1.1.0)的 TTL 索引配置可能存在问题。建议:

  1. 手动创建索引:在 MongoDB Shell 中执行:

    use chat_memory_db;
    db.ai_chat_memory.createIndex(
    { "createdAt": 1 },
    { expireAfterSeconds: 86400 }
    );

  2. 验证索引是否生效

    db.ai_chat_memory.getIndexes();

6.3 最大消息数建议

根据实际场景设置 maxMessages

场景 推荐值 说明
简单问答 10-20 节省 token 成本
复杂任务 30-50 保留更多上下文
长文档分析 50-100 需监控 token 消耗

6.4 性能优化

  • 批量操作MongoChatMemoryRepository 支持批量插入,减少网络开销

  • 索引优化 :确保 conversationIdcreatedAt 字段有索引

  • 连接池:调整 Spring Data MongoDB 的连接池大小


完整配置示例

复制代码
// 完整配置类示例
@Configuration
public class AIApplicationConfig {

    // 1. 配置 MongoDB 存储的 ChatMemory
    @Bean
    public ChatMemory chatMemory(MongoChatMemoryRepository repository) {
        return MessageWindowChatMemory.builder()
                .chatMemoryRepository(repository)
                .maxMessages(50)
                .build();
    }

    // 2. 配置 ChatClient
    @Bean
    public ChatClient chatClient(ChatModel chatModel, ChatMemory chatMemory) {
        return ChatClient.builder(chatModel)
                .defaultAdvisors(
                    MessageChatMemoryAdvisor.builder(chatMemory)
                            .conversationId("default")
                            .order(-2147482648)  // 确保优先执行
                            .build()
                )
                .build();
    }

    // 3. 可选:配置 TTL 索引(如果自动配置失效)
    @Bean
    public CommandLineRunner createMongoIndexes(MongoTemplate mongoTemplate) {
        return args -> {
            mongoTemplate.indexOps("ai_chat_memory")
                .ensureIndex(
                    new Index().on("createdAt", Direction.ASC)
                              .expire(86400)  // 24小时过期
                );
        };
    }
}

验证是否生效

发送几条消息后,在 MongoDB 中查询:

复制代码
// 查看所有会话
db.ai_chat_memory.find().pretty()

// 查看特定会话
db.ai_chat_memory.find({conversationId: "user123"}).pretty()

// 查看集合统计
db.ai_chat_memory.stats()
相关推荐
徒 花30 分钟前
数据库知识复习07
数据库·作业
素玥1 小时前
实训5 python连接mysql数据库
数据库·python·mysql
jnrjian1 小时前
text index 查看index column index定义 index 刷新频率 index视图
数据库·oracle
瀚高PG实验室1 小时前
审计策略修改
网络·数据库·瀚高数据库
言慢行善2 小时前
sqlserver模糊查询问题
java·数据库·sqlserver
韶博雅2 小时前
emcc24ai
开发语言·数据库·python
有想法的py工程师2 小时前
PostgreSQL 分区表排序优化:Append Sort 优化为 Merge Append
大数据·数据库·postgresql
迷枫7122 小时前
达梦数据库的体系架构
数据库·oracle·架构
夜晚打字声3 小时前
9(九)Jmeter如何连接数据库
数据库·jmeter·oracle
Chasing__Dreams3 小时前
Mysql--基础知识点--95--为什么避免使用长事务
数据库·mysql