problem
记忆管理系统 (Memory System) - 改进计划文档
📋 目录
🔴 P0 严重问题
1. 依赖注入混乱 - 重复使用 new 创建对象
问题描述:
- 在 Service 类中硬编码
new关键字创建对象,违反了 Spring 容器管理原则 - 这些对象无法被 Spring 容器管理,无法进行 AOP、代理、事务处理等
受影响的文件:
- GlobalSummaryServiceImpl.java: new LLMClient()
- FactExtractorServiceImpl.java: new LLMClient()
- ConversationEnhancerServiceImpl.java: new LLMClient()
- MemoryUpdateServiceImpl.java: new QdrantLocalClient()
- MessageUpdateStage.java: new EmbeddingService(), new LLMClient()
改进策略:
方案1:使用 @Autowired 自动注入
方案2:使用构造器注入(推荐)
方案3:创建 @Bean 配置类统一管理这些对象
改进方法:
// ❌ 错误做法
@Service
public class GlobalSummaryServiceImpl implements GlobalSummaryService {
private final LLMClient llmClient = new LLMClient(...); // 硬编码
}
// ✅ 正确做法 - 构造器注入
@Service
public class GlobalSummaryServiceImpl implements GlobalSummaryService {
private final LLMClient llmClient;
public GlobalSummaryServiceImpl(LLMClient llmClient) {
this.llmClient = llmClient;
}
}
实施步骤:
- 创建 LLMClientConfig.java,定义 LLMClient Bean
- 创建 QdrantClientConfig.java,定义 QdrantLocalClient Bean
- 创建 EmbeddingServiceConfig.java,定义 EmbeddingService Bean
- 修改所有 Service 类使用构造器注入
- 删除 MessageUpdateStage 中的
new调用
预计工作量: 2-3 小时 优先级: 最高(必须完成)
2. 配置类注解错误
问题描述:
LLMClient.java和QdrantLocalClient.java不应该有@Configuration注解- 这些是工具类/客户端,不是配置类
@Configuration只应该用于配置类
受影响的文件:
- LLMClient.java: @Configuration(不应该有)
- QdrantLocalClient.java: @Configuration(不应该有)
改进方法:
// ❌ 错误
@Configuration
public class LLMClient {
// ...
}
// ✅ 正确
public class LLMClient {
// ...
}
// ✅ 在配置类中定义 Bean
@Configuration
public class LLMClientConfig {
@Bean
public LLMClient llmClient() {
return new LLMClient(LLMConfig.getApiKey(), LLMConfig.DEFAULT_MODEL);
}
}
实施步骤:
- 删除 LLMClient.java 中的 @Configuration
- 删除 QdrantLocalClient.java 中的 @Configuration
- 创建对应的配置类
- 验证编译
预计工作量: 1 小时 优先级: 最高
3. 缺少 Spring Bean 配置类
问题描述:
- 没有专门的配置类来管理复杂对象的创建
- 难以追踪依赖关系
- 无法灵活切换实现类
需要创建的配置类:
- LLMClientConfig.java
- QdrantClientConfig.java
- EmbeddingServiceConfig.java
- RepositoryConfig.java
改进方法:
@Configuration
@EnableConfigurationProperties(MemorySystemProperties.class)
public class LLMClientConfig {
@Bean
public LLMClient llmClient(LLMProperties props) {
return new LLMClient(props.getApiKey(), props.getDefaultModel());
}
}
@Configuration
public class QdrantClientConfig {
@Bean
public QdrantLocalClient qdrantLocalClient() {
return new QdrantLocalClient();
}
}
@Configuration
public class RepositoryConfig {
@Bean
public MessagePairRepository messagePairRepository() {
return new MessagePairRepository();
}
@Bean
public GlobalSummaryRepository globalSummaryRepository() {
return new GlobalSummaryRepository();
}
}
实施步骤:
- 创建 config 包下的配置类
- 定义所有需要的 Bean
- 在每个配置类上添加 @Configuration 和 @Bean 注解
- 使用 @EnableConfigurationProperties 引入属性类
预计工作量: 2 小时 优先级: 最高
🟡 P1 重要问题
4. 缺少统一的异常处理
问题描述:
- 所有异常都用 RuntimeException,没有业务异常分类
- 没有统一的异常处理机制
- 错误信息对用户不友好
改进策略: 创建异常体系结构
改进方法:
// 1. 创建异常基类
public class MemorySystemException extends RuntimeException {
private int errorCode;
private String errorMessage;
public MemorySystemException(int errorCode, String message) {
super(message);
this.errorCode = errorCode;
this.errorMessage = message;
}
}
// 2. 创建具体异常类
public class LLMServiceException extends MemorySystemException {
public LLMServiceException(String message) {
super(5001, message);
}
}
public class RepositoryException extends MemorySystemException {
public RepositoryException(String message) {
super(5002, message);
}
}
public class SessionNotFoundException extends MemorySystemException {
public SessionNotFoundException(String sessionId) {
super(4001, "会话不存在: " + sessionId);
}
}
// 3. 全局异常处理
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
@ExceptionHandler(SessionNotFoundException.class)
public ResponseEntity<ErrorResponse> handleSessionNotFound(SessionNotFoundException e) {
log.error("会话未找到: {}", e.getMessage());
return ResponseEntity.status(HttpStatus.NOT_FOUND)
.body(new ErrorResponse(e.getErrorCode(), e.getMessage()));
}
@ExceptionHandler(LLMServiceException.class)
public ResponseEntity<ErrorResponse> handleLLMException(LLMServiceException e) {
log.error("LLM 服务异常: {}", e.getMessage());
return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE)
.body(new ErrorResponse(e.getErrorCode(), e.getMessage()));
}
@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse> handleGenericException(Exception e) {
log.error("未知异常: {}", e.getMessage(), e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(new ErrorResponse(5000, "系统内部错误"));
}
}
新建文件列表:
com/memosystem/exception/
├── MemorySystemException.java // 异常基类
├── LLMServiceException.java // LLM 异常
├── RepositoryException.java // 数据库异常
├── SessionNotFoundException.java // 会话异常
└── ValidationException.java // 验证异常
com/memosystem/common/
├── ErrorResponse.java // 错误响应 DTO
└── ApiResponse.java // 通用响应 DTO
预计工作量: 3 小时 优先级: 高
5. 缺少单元测试和集成测试
问题描述:
- 项目中没有任何测试代码
- 无法验证功能正确性
- 无法进行回归测试
- 代码覆盖率为 0%
改进策略: 建立完整的测试框架
改进方法:
// 1. 单元测试
@SpringBootTest
class MessageProcessServiceImplTest {
@Autowired
private MessageProcessService messageProcessService;
@Test
void testParseMessageWithChineseText() {
ParsedMessage result = messageProcessService.parseMessage("你好");
assertNotNull(result);
assertEquals("zh-CN", result.getLanguage());
}
@Test
void testEmptyMessage() {
assertTrue(messageProcessService.isEmptyMessage(""));
assertTrue(messageProcessService.isEmptyMessage(" "));
}
}
// 2. Mock 测试
@SpringBootTest
class GlobalSummaryServiceImplTest {
@MockBean
private LLMClient llmClient;
@Autowired
private GlobalSummaryServiceImpl summaryService;
@Test
void testUpdateGlobalSummary() throws Exception {
when(llmClient.generateResponse(anyString()))
.thenReturn("更新后的摘要");
summaryService.updateGlobalSummary("session-123");
verify(llmClient, times(1)).generateResponse(anyString());
}
}
// 3. 集成测试
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class ConversationControllerIntegrationTest {
@LocalServerPort
private int port;
@Autowired
private TestRestTemplate restTemplate;
@Test
void testCreateSessionAndChat() {
// 1. 创建会话
ResponseEntity<SessionResponse> sessionRes =
restTemplate.postForEntity("http://localhost:" + port + "/api/conversation/session/create",
null, SessionResponse.class);
assertEquals(HttpStatus.OK, sessionRes.getStatusCode());
// 2. 发送消息
String sessionId = sessionRes.getBody().getSessionId();
ResponseEntity<ConversationResult> chatRes =
restTemplate.postForEntity("http://localhost:" + port + "/api/conversation/chat?sessionId=" + sessionId + "&message=你好",
null, ConversationResult.class);
assertEquals(HttpStatus.OK, chatRes.getStatusCode());
}
}
新建文件列表:
src/test/java/com/memosystem/
├── service/
│ ├── MessageProcessServiceImplTest.java
│ ├── GlobalSummaryServiceImplTest.java
│ ├── MemoryRetrieverServiceImplTest.java
│ └── ConversationServiceImplTest.java
├── controller/
│ └── ConversationControllerIntegrationTest.java
└── repository/
└── GlobalSummaryRepositoryTest.java
改进清单:
- 添加 JUnit 5 依赖
- 添加 Mockito 依赖
- 为每个 Service 创建单元测试
- 创建集成测试
- 配置 Maven Surefire 插件运行测试
- 添加代码覆盖率检查(JaCoCo)
预计工作量: 8-10 小时 优先级: 高
6. 硬编码的配置参数
问题描述:
- 大量参数硬编码在代码中
- 无法通过配置文件修改
- 不同环境需要修改源代码
受影响的参数:
- SEARCH_TOP_K: 3
- EMBEDDING_DIMENSION: 384
- API_TIMEOUT_SECONDS: 30
- CONNECT_TIMEOUT_SECONDS: 10
- LLM_MODEL: gpt-3.5-turbo
- 数据文件路径: ./qdrant, messages.json 等
改进方法:
# application.yaml
memory-system:
llm:
api-key: ${OPENAI_API_KEY}
default-model: gpt-3.5-turbo
conversation-model: gpt-3.5-turbo
extraction-model: gpt-3.5-turbo
temperature: 0.7
max-tokens: 2000
timeout-seconds: 30
vector-db:
type: qdrant-local
db-path: ./qdrant
collections-dir: ./qdrant/collections
memory:
search-top-k: 3
embedding-dimension: 384
summary-update-interval: 5000
repository:
data-dir: ./data
global-summary-file: global_summaries.json
messages-file: messages.json
session:
timeout-minutes: 30
max-inactive-sessions: 1000
@Configuration
@ConfigurationProperties(prefix = "memory-system")
@Data
public class MemorySystemProperties {
private LlmProperties llm;
private VectorDbProperties vectorDb;
private MemoryProperties memory;
private RepositoryProperties repository;
private SessionProperties session;
@Data
public static class LlmProperties {
private String apiKey;
private String defaultModel;
private String conversationModel;
private String extractionModel;
private double temperature;
private int maxTokens;
private int timeoutSeconds;
}
@Data
public static class VectorDbProperties {
private String type;
private String dbPath;
private String collectionsDir;
}
// ... 其他属性类
}
实施步骤:
- 创建 MemorySystemProperties.java 配置类
- 修改 application.yaml 添加所有参数
- 注入 MemorySystemProperties 到需要的类
- 替换所有硬编码值
预计工作量: 3 小时 优先级: 中高
🟢 P2 中等问题
7. 代码结构和包组织不规范
问题描述:
- 模型类、DTO、VO 混放在一个 model 包
- 缺少 common、constant、util 等通用包
- 没有明确的分层
改进方法:
src/main/java/com/memosystem/
├── common/ # 通用代码
│ ├── exception/ # 异常类
│ │ ├── MemorySystemException.java
│ │ ├── LLMServiceException.java
│ │ └── RepositoryException.java
│ ├── constant/ # 常量
│ │ ├── ErrorCodeConstant.java
│ │ └── MessageConstant.java
│ └── util/ # 工具类
│ ├── JsonUtil.java
│ └── DateUtil.java
│
├── config/ # 配置类
│ ├── LLMClientConfig.java
│ ├── QdrantClientConfig.java
│ ├── RepositoryConfig.java
│ ├── MemorySystemProperties.java
│ └── SwaggerConfig.java
│
├── client/ # 外部服务客户端
│ ├── LLMClient.java
│ ├── QdrantLocalClient.java
│ └── EmbeddingClient.java
│
├── model/ # 数据模型(JPA/数据库实体)
│ ├── MessagePair.java
│ ├── MemoryEntry.java
│ ├── CandidateMemory.java
│ └── GlobalSummaryEntry.java
│
├── dto/ # 数据传输对象
│ ├── ConversationDTO.java
│ ├── PromptDTO.java
│ └── SessionDTO.java
│
├── vo/ # 视图对象(返回给前端)
│ ├── ConversationResultVO.java
│ ├── PromptResponseVO.java
│ └── SessionResponseVO.java
│
├── controller/ # 控制层
│ ├── ConversationController.java
│ ├── SessionController.java
│ └── GlobalExceptionHandler.java # 异常处理
│
├── service/ # 业务层
│ ├── ConversationService.java
│ ├── GlobalSummaryService.java
│ ├── SessionService.java # 新增
│ │
│ └── impl/
│ ├── ConversationServiceImpl.java
│ ├── GlobalSummaryServiceImpl.java
│ ├── SessionServiceImpl.java
│ ├── MessageProcessServiceImpl.java
│ ├── MemoryRetrieverServiceImpl.java
│ ├── FactExtractorServiceImpl.java
│ ├── MemoryUpdateServiceImpl.java
│ ├── EmbeddingService.java
│ └── MessageUpdateStage.java
│
├── repository/ # 持久化层
│ ├── IRepository.java # 基础接口
│ ├── MessagePairRepository.java
│ ├── GlobalSummaryRepository.java
│ └── MemoryEntryRepository.java
│
└── MemorySystemApplication.java # 启动类
改进策略:
- 清晰的分层(Controller → Service → Repository)
- Model 专门存放实体类
- DTO 用于服务间通信
- VO 用于 API 返回值
- 通用代码集中在 common 包
预计工作量: 4-5 小时(重构) 优先级: 中
8. 缺少文档
问题描述:
- README 不完整
- 没有 API 使用文档
- 没有架构设计文档
- 没有开发者指南
改进方法:
# 项目文件结构
docs/
├── README.md # 项目介绍
├── ARCHITECTURE.md # 架构设计
├── API.md # API 文档
├── DEVELOPMENT.md # 开发指南
├── DEPLOYMENT.md # 部署指南
└── TROUBLESHOOTING.md # 常见问题
每个文档的内容:
- README.md - 项目快速入门
- ARCHITECTURE.md - 系统架构、模块设计、数据流
- API.md - 详细的 API 使用文档
- DEVELOPMENT.md - 本地开发环境搭建
- DEPLOYMENT.md - 生产环境部署
- TROUBLESHOOTING.md - 常见问题解决
预计工作量: 3-4 小时 优先级: 中
9. 缺少版本和构建信息管理
问题描述:
- 版本号硬编码
- 没有构建时间信息
- 无法追踪构建版本
改进方法:
<!-- pom.xml -->
<properties>
<project.version>1.0.0</project.version>
<maven.build.timestamp.format>yyyy-MM-dd HH:mm:ss</maven.build.timestamp.format>
</properties>
<build>
<plugins>
<!-- 版本号替换 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<configuration>
<delimiters>
<delimiter>@</delimiter>
</delimiters>
</configuration>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
# application.yaml 中使用占位符
app:
version: @project.version@
build-time: @maven.build.timestamp@
build-number: @buildNumber@
预计工作量: 1 小时 优先级: 低
🔵 P3 优化建议
10. API 接口版本控制
问题描述:
- 没有 API 版本前缀
- 升级时容易破坏现有客户端
改进方法:
@RequestMapping("/api/v1/conversation")
public class ConversationController {
// ...
}
@RequestMapping("/api/v1/session")
public class SessionController {
// ...
}
11. 日志记录规范化
问题描述:
- 日志级别不一致
- 可能记录敏感信息
- 没有结构化日志
改进方法:
// 统一使用 @Slf4j
// DEBUG: 开发调试信息
// INFO: 重要业务操作
// WARN: 警告信息
// ERROR: 错误信息
log.debug("处理用户消息: {}", message.substring(0, 50) + "...");
log.info("会话 {} 创建成功", sessionId);
log.warn("LLM 调用超时,使用备选策略");
log.error("数据库操作失败", exception);
12. 依赖版本更新
问题描述:
- JSON 库版本过旧(20160810)
- 其他依赖版本可能不是最新
改进方法:
<!-- 更新依赖版本 -->
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20231227</version> <!-- 最新版本 -->
</dependency>
<!-- 添加依赖版本管理 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>3.2.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
📊 改进优先级总结
| 优先级 | 项目 | 影响 | 预计工作量 | 状态 |
|---|---|---|---|---|
| P0 | 依赖注入混乱 | 无法编译 | 2-3h | ⏳ |
| P0 | 配置类注解错误 | 编译错误 | 1h | ⏳ |
| P0 | 缺少 Bean 配置 | Spring 管理失效 | 2h | ⏳ |
| P1 | 异常处理 | 系统不稳定 | 3h | ⏳ |
| P1 | 单元测试 | 无法验证 | 8-10h | ⏳ |
| P1 | 配置参数 | 灵活性差 | 3h | ⏳ |
| P2 | 代码结构 | 可维护性差 | 4-5h | ⏳ |
| P2 | 文档 | 难以使用 | 3-4h | ⏳ |
| P2 | 版本管理 | 难以追踪 | 1h | ⏳ |
| P3 | API 版本 | 长期维护 | 1h | ⏳ |
| P3 | 日志规范 | 难以调试 | 2h | ⏳ |
| P3 | 依赖更新 | 安全性 | 1h | ⏳ |
总计预计工作量: 30-35 小时
🚀 实施路线图
第一阶段(必须完成 - 2-3 天)
- 修复依赖注入问题
- 创建 Bean 配置类
- 移除错误的 @Configuration 注解
- 编译验证
第二阶段(重要 - 3-4 天)
- 创建异常体系
- 添加全局异常处理
- 创建配置属性类
- 更新 application.yaml
第三阶段(中等 - 2-3 天)
- 添加单元测试框架
- 为核心服务写测试
- 重构代码结构
- 添加基础文档
第四阶段(可选 - 1-2 天)
- 添加 API 版本控制
- 规范化日志
- 更新依赖版本
- 完成文档
📞 联系方式
如有问题或需要澄清,请参考项目架构文档或联系开发团队。