二、数据库、缓存与存储
项目仓库:https://github.com/vasc-language/ai-code-mother
项目预览:https://www.joinoai.cloud
9. AI 零代码应用生成项目中,为什么要从数据库加载对话历史到记忆中?完整流程是怎样的?
为什么需要加载对话历史
1. 上下文连续性
- AI对话需要理解前面的交流内容
- 保持多轮对话的逻辑一致性
- 避免重复询问已经回答过的问题
2. 个性化体验
- 记住用户的偏好和需求
- 基于历史对话优化生成策略
- 提供更精准的代码生成服务
3. 会话恢复
- 用户刷新页面或重新登录后能继续之前的对话
- 跨设备访问时保持对话状态
- 防止因网络中断导致的上下文丢失
完整流程实现
1. 数据库存储结构
sql
CREATE TABLE chat_history (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
app_id BIGINT NOT NULL,
user_id BIGINT NOT NULL,
message TEXT NOT NULL,
message_type VARCHAR(10) NOT NULL, -- 'USER' 或 'AI'
create_time DATETIME DEFAULT CURRENT_TIMESTAMP,
INDEX idx_app_id_create_time (app_id, create_time)
);
2. 加载流程
java
// 在AiCodeGeneratorServiceFactory中的实现
public int loadChatHistoryToMemory(Long appId, MessageWindowChatMemory chatMemory, int maxCount) {
// 1. 从数据库查询历史记录(按时间倒序,限制数量)
QueryWrapper queryWrapper = QueryWrapper.create()
.eq(ChatHistory::getAppId, appId)
.orderBy(ChatHistory::getCreateTime, false)
.limit(1, maxCount);
List<ChatHistory> historyList = this.list(queryWrapper);
// 2. 反转列表,确保按时间正序(老的在前,新的在后)
historyList = historyList.reversed();
// 3. 清理现有缓存,防止重复加载
chatMemory.clear();
// 4. 按顺序添加到记忆中
for (ChatHistory history : historyList) {
if (ChatHistoryMessageTypeEnum.USER.getValue().equals(history.getMessageType())) {
chatMemory.add(UserMessage.from(history.getMessage()));
} else if (ChatHistoryMessageTypeEnum.AI.getValue().equals(history.getMessageType())) {
chatMemory.add(AiMessage.from(history.getMessage()));
}
}
return loadedCount;
}
3. 记忆管理策略
java
// 创建带记忆的AI服务
MessageWindowChatMemory chatMemory = MessageWindowChatMemory
.builder()
.id(appId) // 每个应用独立的记忆空间
.chatMemoryStore(redisChatMemoryStore) // Redis持久化存储
.maxMessages(20) // 最多保留20条消息
.build();
// 从数据库加载历史对话到记忆中
chatHistoryService.loadChatHistoryToMemory(appId, chatMemory, 20);
4. 数据流转过程
用户发起对话 → 检查Redis缓存 → 缓存未命中 → 从MySQL加载历史 →
构建MessageWindowChatMemory → 添加到Redis → AI服务使用记忆 →
生成回复 → 保存新消息到MySQL → 更新Redis缓存
10. AI 零代码应用生成项目中,你如何配置 Caffeine 的缓存策略?
Caffeine缓存配置
1. AI服务实例缓存
java
// 在AiCodeGeneratorServiceFactory中的配置
private final Cache<String, AiCodeGeneratorService> serviceCache = Caffeine.newBuilder()
.maximumSize(1000) // 最大缓存1000个实例
.expireAfterWrite(Duration.ofMinutes(30)) // 写入后30分钟过期
.expireAfterAccess(Duration.ofMinutes(10)) // 访问后10分钟过期
.removalListener((key, value, cause) -> {
log.debug("AI 服务实例被移除,缓存键: {}, 原因: {}", key, cause);
})
.build();
2. 缓存策略说明
大小限制策略
maximumSize(1000)
: 限制最大缓存条目数,防止内存溢出- 基于LRU算法淘汰最少使用的条目
过期策略
expireAfterWrite
: 写入后过期,适用于数据时效性要求expireAfterAccess
: 访问后过期,适用于热点数据保持
监听器配置
removalListener
: 监控缓存条目移除事件- 用于调试和性能分析
3. 缓存使用模式
java
// 获取缓存的AI服务实例
public AiCodeGeneratorService getAiCodeGeneratorService(long appId, CodeGenTypeEnum codeGenType) {
String cacheKey = buildCacheKey(appId, codeGenType);
// 如果缓存存在直接返回,不存在则创建新实例并缓存
return serviceCache.get(cacheKey, key -> createAiCodeGeneratorService(appId, codeGenType));
}
private String buildCacheKey(long appId, CodeGenTypeEnum codeGenType) {
return appId + "_" + codeGenType.getValue();
}
4. 性能优化考虑
- 内存效率: 限制缓存大小,避免OOM
- 并发安全: Caffeine天然支持高并发访问
- 热点数据: 访问后过期策略保持活跃实例
- 资源清理: 移除监听器确保资源正确释放
11. 在实现 AI 的对话记录时,为什么选择 Redis 进行持久化?
Redis选择的原因
1. 性能优势
java
// Redis内存存储,访问速度极快
RedisChatMemoryStore redisChatMemoryStore = RedisChatMemoryStore.builder()
.host(host)
.port(port)
.password(password)
.ttl(ttl) // 支持TTL自动过期
.build();
优势对比:
- Redis: 内存存储,微秒级响应
- MySQL: 磁盘存储,毫秒级响应
- 文件系统: 磁盘IO,响应时间不稳定
2. 数据结构适配
java
// LangChain4j的ChatMemoryStore接口天然支持Redis
MessageWindowChatMemory chatMemory = MessageWindowChatMemory
.builder()
.chatMemoryStore(redisChatMemoryStore) // 直接使用Redis存储
.maxMessages(20)
.build();
3. 会话特性匹配
- 临时性: 对话记忆通常是临时的,Redis的TTL机制完美匹配
- 高频访问: AI对话过程中需要频繁读取历史消息
- 结构化: Redis支持复杂数据结构,适合存储消息对象
4. 扩展性考虑
- 分布式: Redis集群支持水平扩展
- 持久化: RDB+AOF双重保障数据安全
- 高可用: 主从复制+哨兵模式保证服务可用性
架构设计
1. 双重存储策略
实时对话记忆: Redis (快速访问)
↓
历史记录归档: MySQL (长期存储)
2. 数据生命周期
java
// 对话过程中的数据流
用户消息 → 保存到MySQL → 加载到Redis → AI处理 →
AI回复 → 保存到MySQL → 更新Redis → 返回用户
3. 缓存策略
- 写入策略: Write-Through(同时写入Redis和MySQL)
- 读取策略: Cache-Aside(优先从Redis读取,未命中则从MySQL加载)
- 过期策略: TTL自动过期 + 手动清理
12. AI 零代码应用生成项目中,Redis 主要用在哪些场景?
Redis使用场景详解
1. 对话记忆存储
java
// LangChain4j集成的Redis对话存储
@Bean
public RedisChatMemoryStore redisChatMemoryStore() {
return RedisChatMemoryStore.builder()
.host(host)
.port(port)
.password(password)
.ttl(ttl)
.build();
}
- 用途: 存储AI对话的上下文记忆
- 特点: 支持TTL自动过期,高频读写
- 数据结构: Hash结构存储消息列表
2. 用户会话管理
java
// Spring Session集成Redis
// 在pom.xml中配置
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
- 用途: 存储用户登录状态和会话信息
- 特点: 支持分布式会话共享
- 数据结构: String/Hash存储会话数据
3. 应用数据缓存
java
// Spring Cache集成Redis
@Cacheable(
value = "good_app_page",
key = "T(com.spring.aicodemother.utils.CacheKeyUtils).generateKey(#appQueryRequest)",
condition = "#appQueryRequest.pageNum <= 10"
)
public BaseResponse<Page<AppVO>> listGoodAppVOByPage(@RequestBody AppQueryRequest appQueryRequest) {
// 精选应用列表缓存
}
- 用途: 缓存热点应用数据,减少数据库压力
- 配置: 5分钟过期时间
- 优化: 只缓存前10页数据
4. 分布式限流
java
// 使用Redisson实现分布式限流
@Before("@annotation(rateLimit)")
public void doBefore(JoinPoint point, RateLimit rateLimit) {
String key = generateRateLimitKey(point, rateLimit);
RRateLimiter rateLimiter = redissonClient.getRateLimiter(key);
// 设置限流参数
rateLimiter.trySetRate(RateType.OVERALL,
rateLimit.rate(),
rateLimit.rateInterval(),
RateIntervalUnit.SECONDS);
// 尝试获取令牌
if (!rateLimiter.tryAcquire(1)) {
throw new BusinessException(ErrorCode.TOO_MANY_REQUEST);
}
}
- 用途: API接口限流,防止恶意请求
- 算法: 令牌桶算法
- 粒度: 支持用户级、IP级、接口级限流
5. 缓存管理配置
java
@Bean
public CacheManager cacheManager() {
RedisCacheConfiguration defaultConfig = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofMinutes(30)) // 默认30分钟过期
.disableCachingNullValues() // 禁用null值缓存
.serializeKeysWith(RedisSerializationContext.SerializationPair
.fromSerializer(new StringRedisSerializer()));
return RedisCacheManager.builder(redisConnectionFactory)
.cacheDefaults(defaultConfig)
// 针对不同业务配置不同过期时间
.withCacheConfiguration("good_app_page",
defaultConfig.entryTtl(Duration.ofMinutes(5)))
.build();
}
Redis在项目中的架构角色
1. 性能层
- 作为MySQL的缓存层,提升查询性能
- 减少数据库压力,提高系统吞吐量
2. 会话层
- 管理用户登录状态
- 支持分布式部署的会话共享
3. 限流层
- 实现分布式限流
- 保护系统免受恶意攻击
4. 记忆层
- 存储AI对话上下文
- 支持智能对话的连续性
总结:
Redis在AI零代码生成项目中扮演着多重角色,从性能优化到业务功能支撑,是系统架构中不可或缺的组件。其高性能、丰富的数据结构和完善的生态支持,使其成为处理实时数据和缓存场景的最佳选择。
📞 联系我们
如果您有任何问题或建议,请随时联系我们:
- 提交 Issue
- 发送邮件至: zrt3ljnygz@163.com
- 微信联系: Join2049