Skip to content

Conversation

Copy link

Copilot AI commented Nov 26, 2025

  • Analyze repository structure and existing codebase
  • Add Spring AI dependencies to pom.xml
    • Added spring-ai-openai-spring-boot-starter and spring-ai-ollama-spring-boot-starter
    • Updated to Spring AI 1.0.0 stable release (from milestone 1.0.0-M4)
    • Removed Spring Milestones repository (no longer needed for stable release)
  • Create AI configuration package (com.jmal.clouddisk.ai)
    • Create AiProperties.java - AI configuration properties with provider, API key, model settings
    • Create AiConfig.java - AI main configuration class supporting OpenAI and Ollama
  • Implement Embedding Service
    • Create EmbeddingService.java - Generate text vectors with chunking for large texts
  • Implement Vector Store Service
    • Create VectorStoreService.java - Store and search vectors with Lucene KnnVectorField
  • Implement AI Search Service
    • Create AiSearchService.java - Natural language and semantic/hybrid search
  • Implement File Summary Service
    • Create FileSummaryService.java - Generate file summaries with AI
  • Implement File Classification Service
    • Create FileClassificationService.java - Auto classify and tag files
  • Create VO classes for API responses
    • Create FileSummaryVO.java
    • Create FileClassificationVO.java
    • Create TagSuggestionVO.java
  • Implement REST API Controller
    • Create AiController.java with all endpoints under /api/ai
  • Add default AI configuration to application.yml
  • Update data models
    • Add summary field to FileDocument
    • Add summary field to FileMetadataDO
    • Add new IFileDAO methods for search and summary operations
    • Implement MongoDB and JPA DAO methods
  • Code review and security check passed
Original prompt

需求概述

在现有的 JmalCloud 私有云存储项目中集成 Spring AI,实现以下 AI 智能功能:

  1. 自然语言搜索文件 - 用户可以使用自然语言描述来搜索文件
  2. 向量化 - 对文件内容进行向量化存储,支持语义搜索
  3. 文件总结 - 自动生成文件内容摘要
  4. 智能分类 - 自动对文件进行分类和打标签

技术实现要求

1. 添加 Spring AI 依赖配置

pom.xml 中添加以下依赖:

  • spring-ai-openai-spring-boot-starter - OpenAI 支持
  • spring-ai-ollama-spring-boot-starter - Ollama 本地部署支持
  • 相关的向量存储依赖

2. 创建 AI 配置类

创建 src/main/java/com/jmal/clouddisk/ai/ 包,包含:

  • AiConfig.java - AI 主配置类,支持多种 LLM 提供商切换
  • AiProperties.java - AI 配置属性类,包含:
    • provider - 提供商类型(openai/ollama)
    • apiKey - API 密钥
    • baseUrl - API 基础 URL
    • model - 模型名称
    • embeddingModel - 向量模型名称
    • temperature - 温度参数
    • maxTokens - 最大 token 数
    • enabled - 是否启用 AI 功能
    • vectorDimension - 向量维度(默认 1536)

3. 实现向量存储服务 - 基于 Lucene 的向量索引

创建以下类:

  • VectorStoreService.java - 向量存储服务

    • 使用 Lucene 的 KnnVectorField 存储文档向量
    • 在现有 LuceneService 的索引流程中集成向量化
    • 支持向量相似度搜索(使用 KnnVectorQuery
    • 方法:
      • storeVector(String fileId, float[] vector) - 存储向量
      • searchSimilar(float[] queryVector, int topK) - 相似度搜索
      • deleteVector(String fileId) - 删除向量
  • EmbeddingService.java - 向量生成服务

    • 调用 LLM 的 embedding API 生成向量
    • 支持文本分块处理(大文件内容分块后取平均向量)
    • 方法:
      • embed(String text) - 生成文本向量
      • embedBatch(List<String> texts) - 批量生成向量

4. 实现 AI 搜索服务 - 自然语言查询转换

创建 AiSearchService.java

  • 将用户的自然语言查询转换为结构化搜索条件
  • 结合向量搜索和关键词搜索实现混合搜索
  • 方法:
    • naturalLanguageSearch(String query, String userId) - 自然语言搜索
    • semanticSearch(String query, String userId, int topK) - 语义向量搜索
    • hybridSearch(String query, String userId) - 混合搜索(关键词+向量)

提示词模板示例:

你是一个文件搜索助手。用户会用自然语言描述他们要找的文件。
请分析用户的意图,提取关键信息:
- 文件类型(如:图片、文档、视频等)
- 时间范围(如:最近一周、上个月等)
- 关键词
- 其他条件

用户查询:{query}

请返回 JSON 格式:
{
  "fileTypes": ["image", "document"],
  "keywords": ["关键词1", "关键词2"],
  "timeRange": {"start": "2024-01-01", "end": "2024-12-31"},
  "sortBy": "updateDate",
  "sortOrder": "desc"
}

5. 实现文件总结服务 - 自动生成文件摘要

创建 FileSummaryService.java

  • 对文件内容生成摘要
  • 支持多种文件类型(利用现有 Tika 提取的内容)
  • 摘要存储在数据库中,避免重复生成
  • 方法:
    • generateSummary(String fileId) - 生成文件摘要
    • getSummary(String fileId) - 获取已有摘要
    • regenerateSummary(String fileId) - 重新生成摘要
    • batchGenerateSummary(List<String> fileIds) - 批量生成

提示词模板:

请对以下文件内容生成简洁的摘要(不超过200字):

文件名:{fileName}
文件类型:{fileType}
内容:
{content}

请用中文回复,摘要应该包含文件的主要内容和关键信息。

6. 实现智能分类服务 - 自动分类和标签

创建 FileClassificationService.java

  • 根据文件内容自动分类
  • 自动生成标签建议
  • 与现有的标签系统(TagService)集成
  • 方法:
    • classifyFile(String fileId) - 分类文件
    • suggestTags(String fileId) - 建议标签
    • autoTagFile(String fileId) - 自动打标签
    • batchClassify(List<String> fileIds) - 批量分类

预定义分类:

  • 工作文档
  • 个人照片
  • 视频媒体
  • 音乐音频
  • 代码项目
  • 学习资料
  • 财务文件
  • 其他

提示词模板:

请分析以下文件内容,给出分类和标签建议:

文件名:{fileName}
文件类型:{fileType}
内容摘要:
{contentSummary}

请返回 JSON 格式:
{
  "category": "分类名称",
  "tags": ["标签1", "标签2", "标签3"],
  "confidence": 0.95
}

可选分类:工作文档、个人照片、视频媒体、音乐音频、代码项目、学习资料、财务文件、其他

7. 添加 REST API 接口

创建 AiController.java(路径:/api/ai):

@RestController
@RequestMapping("/api/ai")
public class AiController {
    
    // 自然语言搜索
    @GetMapping("/search")
    public ResponseResult<List<FileIntroVO>> naturalLanguageSearch(
        @RequestParam String query,
        @RequestParam(required = false) Integer page,
        @RequestParam(required = false) Integer pageSize);
    
    // 语义搜索
    @GetMapping("/semantic-search")
    public ResponseResult<List<FileIntroVO>> semanticSearch(
        @RequestParam String query,
        @RequestParam(defaultValue = "10") Integer topK);
    
    // 获取文件摘要
    @GetMapping("/summary/{fileId}")
    public ResponseResult<FileSummaryVO> getFileSummary(@PathVariable String fileId);
    
    // 生成文件摘要
    @PostMapping("/summary/{fileId}")
    public ResponseResult<FileSummaryVO> generateFileSummary(@PathVariable String fileId);
    
    // 获取分类建议
    @GetMapping("/classify/{fileId}")
    public ResponseResult<FileClassificationVO> classifyFile(@PathVariable String fileId);
    
    // 获取标签建议
    @GetMapping("/suggest-tags/{fileId}")
    public ResponseResult<List<String>> suggestTags(@PathVariable String fileId);
    
    // 自动打标签
    @PostMapping("/auto-tag/{fileId}")
    public ResponseResult<Void> autoTagFile(@PathVariable String fileId);
    
    // 获取 AI 配置状态
    @GetMapping("/status")
    public ResponseResult<AiStatusVO> getAiStatus();
    
    // 更新 AI 配置
    @PutMapping("/config")
    public ResponseResult<Void> updateAiConfig(@RequestBody AiConfigDTO config);
}

8. 数据模型扩展

创建新的 VO/DTO 类:

  • FileSummaryVO.java - 文件摘要响应
  • FileClassificationVO.java - 文件分类响应
  • AiStatusVO.java - AI 状态响应
  • AiConfigDTO.java - AI 配置请求

在数据库中添加新字段(通过 MongoDB 文档或扩展现有模型):

  • summary - 文件摘要
  • aiCategory - AI 分类
  • aiTags - AI 建议的标签
  • embedding - 向量(可选,也可以存在 Lucene 中)

9. 在现有索引流程中集成向量化

修改 LuceneService.java

  • updateIndex 方法中,当读取文件内容后,调用 EmbeddingService 生成向量
  • 将向量存储到 Lucene 索引中(使用 KnnVectorField
  • 添加配置开关控制是否启用向量索引(考虑...

This pull request was created as a result of the following prompt from Copilot chat.

需求概述

在现有的 JmalCloud 私有云存储项目中集成 Spring AI,实现以下 AI 智能功能:

  1. 自然语言搜索文件 - 用户可以使用自然语言描述来搜索文件
  2. 向量化 - 对文件内容进行向量化存储,支持语义搜索
  3. 文件总结 - 自动生成文件内容摘要
  4. 智能分类 - 自动对文件进行分类和打标签

技术实现要求

1. 添加 Spring AI 依赖配置

pom.xml 中添加以下依赖:

  • spring-ai-openai-spring-boot-starter - OpenAI 支持
  • spring-ai-ollama-spring-boot-starter - Ollama 本地部署支持
  • 相关的向量存储依赖

2. 创建 AI 配置类

创建 src/main/java/com/jmal/clouddisk/ai/ 包,包含:

  • AiConfig.java - AI 主配置类,支持多种 LLM 提供商切换
  • AiProperties.java - AI 配置属性类,包含:
    • provider - 提供商类型(openai/ollama)
    • apiKey - API 密钥
    • baseUrl - API 基础 URL
    • model - 模型名称
    • embeddingModel - 向量模型名称
    • temperature - 温度参数
    • maxTokens - 最大 token 数
    • enabled - 是否启用 AI 功能
    • vectorDimension - 向量维度(默认 1536)

3. 实现向量存储服务 - 基于 Lucene 的向量索引

创建以下类:

  • VectorStoreService.java - 向量存储服务

    • 使用 Lucene 的 KnnVectorField 存储文档向量
    • 在现有 LuceneService 的索引流程中集成向量化
    • 支持向量相似度搜索(使用 KnnVectorQuery
    • 方法:
      • storeVector(String fileId, float[] vector) - 存储向量
      • searchSimilar(float[] queryVector, int topK) - 相似度搜索
      • deleteVector(String fileId) - 删除向量
  • EmbeddingService.java - 向量生成服务

    • 调用 LLM 的 embedding API 生成向量
    • 支持文本分块处理(大文件内容分块后取平均向量)
    • 方法:
      • embed(String text) - 生成文本向量
      • embedBatch(List<String> texts) - 批量生成向量

4. 实现 AI 搜索服务 - 自然语言查询转换

创建 AiSearchService.java

  • 将用户的自然语言查询转换为结构化搜索条件
  • 结合向量搜索和关键词搜索实现混合搜索
  • 方法:
    • naturalLanguageSearch(String query, String userId) - 自然语言搜索
    • semanticSearch(String query, String userId, int topK) - 语义向量搜索
    • hybridSearch(String query, String userId) - 混合搜索(关键词+向量)

提示词模板示例:

你是一个文件搜索助手。用户会用自然语言描述他们要找的文件。
请分析用户的意图,提取关键信息:
- 文件类型(如:图片、文档、视频等)
- 时间范围(如:最近一周、上个月等)
- 关键词
- 其他条件

用户查询:{query}

请返回 JSON 格式:
{
  "fileTypes": ["image", "document"],
  "keywords": ["关键词1", "关键词2"],
  "timeRange": {"start": "2024-01-01", "end": "2024-12-31"},
  "sortBy": "updateDate",
  "sortOrder": "desc"
}

5. 实现文件总结服务 - 自动生成文件摘要

创建 FileSummaryService.java

  • 对文件内容生成摘要
  • 支持多种文件类型(利用现有 Tika 提取的内容)
  • 摘要存储在数据库中,避免重复生成
  • 方法:
    • generateSummary(String fileId) - 生成文件摘要
    • getSummary(String fileId) - 获取已有摘要
    • regenerateSummary(String fileId) - 重新生成摘要
    • batchGenerateSummary(List<String> fileIds) - 批量生成

提示词模板:

请对以下文件内容生成简洁的摘要(不超过200字):

文件名:{fileName}
文件类型:{fileType}
内容:
{content}

请用中文回复,摘要应该包含文件的主要内容和关键信息。

6. 实现智能分类服务 - 自动分类和标签

创建 FileClassificationService.java

  • 根据文件内容自动分类
  • 自动生成标签建议
  • 与现有的标签系统(TagService)集成
  • 方法:
    • classifyFile(String fileId) - 分类文件
    • suggestTags(String fileId) - 建议标签
    • autoTagFile(String fileId) - 自动打标签
    • batchClassify(List<String> fileIds) - 批量分类

预定义分类:

  • 工作文档
  • 个人照片
  • 视频媒体
  • 音乐音频
  • 代码项目
  • 学习资料
  • 财务文件
  • 其他

提示词模板:

请分析以下文件内容,给出分类和标签建议:

文件名:{fileName}
文件类型:{fileType}
内容摘要:
{contentSummary}

请返回 JSON 格式:
{
  "category": "分类名称",
  "tags": ["标签1", "标签2", "标签3"],
  "confidence": 0.95
}

可选分类:工作文档、个人照片、视频媒体、音乐音频、代码项目、学习资料、财务文件、其他

7. 添加 REST API 接口

创建 AiController.java(路径:/api/ai):

@RestController
@RequestMapping("/api/ai")
public class AiController {
    
    // 自然语言搜索
    @GetMapping("/search")
    public ResponseResult<List<FileIntroVO>> naturalLanguageSearch(
        @RequestParam String query,
        @RequestParam(required = false) Integer page,
        @RequestParam(required = false) Integer pageSize);
    
    // 语义搜索
    @GetMapping("/semantic-search")
    public ResponseResult<List<FileIntroVO>> semanticSearch(
        @RequestParam String query,
        @RequestParam(defaultValue = "10") Integer topK);
    
    // 获取文件摘要
    @GetMapping("/summary/{fileId}")
    public ResponseResult<FileSummaryVO> getFileSummary(@PathVariable String fileId);
    
    // 生成文件摘要
    @PostMapping("/summary/{fileId}")
    public ResponseResult<FileSummaryVO> generateFileSummary(@PathVariable String fileId);
    
    // 获取分类建议
    @GetMapping("/classify/{fileId}")
    public ResponseResult<FileClassificationVO> classifyFile(@PathVariable String fileId);
    
    // 获取标签建议
    @GetMapping("/suggest-tags/{fileId}")
    public ResponseResult<List<String>> suggestTags(@PathVariable String fileId);
    
    // 自动打标签
    @PostMapping("/auto-tag/{fileId}")
    public ResponseResult<Void> autoTagFile(@PathVariable String fileId);
    
    // 获取 AI 配置状态
    @GetMapping("/status")
    public ResponseResult<AiStatusVO> getAiStatus();
    
    // 更新 AI 配置
    @PutMapping("/config")
    public ResponseResult<Void> updateAiConfig(@RequestBody AiConfigDTO config);
}

8. 数据模型扩展

创建新的 VO/DTO 类:

  • FileSummaryVO.java - 文件摘要响应
  • FileClassificationVO.java - 文件分类响应
  • AiStatusVO.java - AI 状态响应
  • AiConfigDTO.java - AI 配置请求

在数据库中添加新字段(通过 MongoDB 文档或扩展现有模型):

  • summary - 文件摘要
  • aiCategory - AI 分类
  • aiTags - AI 建议的标签
  • embedding - 向量(可选,也可以存在 Lucene 中)

9. 在现有索引流程中集成向量化

修改 LuceneService.java

  • updateIndex 方法中,当读取文件内容后,调用 EmbeddingService 生成向量
  • 将向量存储到 Lucene 索引中(使用 KnnVectorField
  • 添加配置开关控制是否启用向量索引(考虑性能和成本)

10. 配置文件示例

application.yml 中添加:

jmal:
  ai:
    enabled: true
    provider: openai  # openai 或 ollama
    api-key: ${AI_API_KEY:}
    base-url: ${AI_BASE_URL:https://api.openai.com}
    model: gpt-4o-mini
    embedding-model: text-embedding-3-small
    temperature: 0.7
    max-tokens: 2000
    vector-dimension: 1536
    # Ollama 配置
    ollama:
      base-url: http://localhost:11434
      model: llama3
      embedding-model: nomic-embed-text

注意事项

  1. 性能优化:向量化和 AI 调用应该异步处理,不阻塞主流程
  2. 成本控制:添加配置开关,允许用户选择性启用 AI 功能
  3. 错误处理:AI 服务不可用时应该优雅降级,不影响核心功能
  4. 缓存机制:摘要和分类结果应该缓存,避免重复调用
  5. 安全性:API 密钥应该通过环境变量配置,不硬编码
  6. 国际化:提示词应该支持中英文

文件结构

src/main/java/com/jmal/clouddisk/
├── ai/
│   ├── config/
│   │   ├── AiConfig.java
│   │   └── AiProperties.java
│   ├── service/
│   │   ├── EmbeddingService.java
│   │   ├── VectorStoreService.java
│   │   ├── AiSearchService.java
│   │   ├── FileSummaryService.java
│   │   └── FileClassificationService.java
│   ├── controller/
│   │   └── AiController.java
│   ├── dto/
│   │   ├── AiConfigDTO.java
│   │   ├── AiSearchResultDTO.java
│   │   └── NaturalLanguageQueryDTO.java
│   └── vo/
│       ├── FileSummaryVO.java
│       ├── FileClassificationVO.java
│       └── AiStatusVO.java

测试要求

  1. 单元测试覆盖所有 AI 服务类
  2. 集成测试验证与 LLM 的通信
  3. Mock 测试确保 AI 服务不可用时的降级处理

💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI and others added 2 commits November 26, 2025 03:37
Co-authored-by: jamebal <49510841+jamebal@users.noreply.github.com>
Co-authored-by: jamebal <49510841+jamebal@users.noreply.github.com>
Copilot AI changed the title [WIP] Integrate Spring AI features into JmalCloud Integrate Spring AI for intelligent file search, summarization, and classification Nov 26, 2025
Copilot AI requested a review from jamebal November 26, 2025 03:48
Copy link
Owner

@jamebal jamebal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

springboot 已经升级至
org.springframework.ai
spring-ai-client-chat
1.1.0

请参考: https://github.com/spring-projects/spring-ai

Co-authored-by: jamebal <49510841+jamebal@users.noreply.github.com>
Copy link
Author

Copilot AI commented Nov 26, 2025

springboot 已经升级至
org.springframework.ai
spring-ai-client-chat
...

Updated Spring AI from milestone 1.0.0-M4 to stable 1.0.0 release and removed the Spring Milestones repository since it's no longer needed. (01c6124)

Copilot AI requested a review from jamebal November 26, 2025 04:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants