problem

记忆管理系统 (Memory System) - 改进计划文档

📋 目录

  1. P0 严重问题
  2. P1 重要问题
  3. P2 中等问题
  4. P3 优化建议

🔴 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;
    }
}

实施步骤:

  1. 创建 LLMClientConfig.java,定义 LLMClient Bean
  2. 创建 QdrantClientConfig.java,定义 QdrantLocalClient Bean
  3. 创建 EmbeddingServiceConfig.java,定义 EmbeddingService Bean
  4. 修改所有 Service 类使用构造器注入
  5. 删除 MessageUpdateStage 中的 new 调用

预计工作量: 2-3 小时 优先级: 最高(必须完成)


2. 配置类注解错误

问题描述:

  • LLMClient.javaQdrantLocalClient.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);
    }
}

实施步骤:

  1. 删除 LLMClient.java 中的 @Configuration
  2. 删除 QdrantLocalClient.java 中的 @Configuration
  3. 创建对应的配置类
  4. 验证编译

预计工作量: 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();
    }
}

实施步骤:

  1. 创建 config 包下的配置类
  2. 定义所有需要的 Bean
  3. 在每个配置类上添加 @Configuration 和 @Bean 注解
  4. 使用 @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;
    }
    
    // ... 其他属性类
}

实施步骤:

  1. 创建 MemorySystemProperties.java 配置类
  2. 修改 application.yaml 添加所有参数
  3. 注入 MemorySystemProperties 到需要的类
  4. 替换所有硬编码值

预计工作量: 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           # 常见问题

每个文档的内容:

  1. README.md - 项目快速入门
  2. ARCHITECTURE.md - 系统架构、模块设计、数据流
  3. API.md - 详细的 API 使用文档
  4. DEVELOPMENT.md - 本地开发环境搭建
  5. DEPLOYMENT.md - 生产环境部署
  6. 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 版本控制
  • 规范化日志
  • 更新依赖版本
  • 完成文档

📞 联系方式

如有问题或需要澄清,请参考项目架构文档或联系开发团队。

← 返回首页