# ruoyi-ai 能力分片迁移计划 目标:逐步吸收 `ageerle/ruoyi-ai` 的知识库、模型配置、文档解析、RAG 和 chat 能力,但保留本项目 `ruoyi-aihr` 的业务边界,不整包搬入 `ruoyi-chat`。 ## 迁移原则 - 业务落点仍是 `backend/ruoyi-modules/ruoyi-aihr`,包名使用 `org.dromara.aihr`。 - 数据表使用 `aihr_knowledge_*`、`aihr_model_*` 前缀,避免和未来上游模块或系统表撞名。 - `/api/knowledge/search` 保持当前契约:真实 RAG 优先,失败回退 seed。 - 先只接一条 SOP 知识库链路;模型能力先走 OpenAI-compatible 边界,再扩展到案例、陪练和 chat。 ## 分片顺序 | 阶段 | 搬什么 | 不搬什么 | 验收 | |---|---|---|---| | 1. 知识库 schema | `knowledge_info / attach / fragment` 改造为 `aihr_knowledge_*` | 向量库、LLM、上传 UI | SQL 可导入,seed API 不受影响 | | 2. 模型能力 | `chat_provider / chat_model` 改造为 `aihr_model_*`,最小 OpenAI-compatible 调用边界 | 多模型市场、图像、SSE、成本看板 | 模型列表可查;数据库配置后可调用 `/chat/completions` | | 3. 文档解析 | 文本/Markdown/PDF/Word/Excel/PPT loader、OSS-first 上传与分片 | 异步重试队列、图片智能分析 | txt/md/PDF/Word/Excel/PPT 文件可落 OSS 并解析为 fragment | | 4. 检索与 embedding | MySQL Fulltext + OpenAI-compatible embedding + Qdrant 最小向量召回 | Milvus/Weaviate 全量适配、独立向量库后台 | 同一问题返回带分数片段,配置 vector 模型后片段有 embedding,Qdrant 可用时参与 RRF 融合 | | 5. 资料处理状态 | 解析任务状态页、资料分类、处理链路、多文件/ZIP 异步上传、单文件重试、服务端运维目录导入接口 | 分布式队列 | 能查看等待解析/解析中/已完成/失败、片段数、向量化状态,并从页面批量导入 MVP 样例文件 | | 6. RAG 回答 | 带引用回答、训练题生成 | 多模型市场、成本看板 | SOP 页面展示真实引用 | | 7. Chat | 最小会话、消息、引用来源 | 多智能体、工作流、MCP、Skills | 可围绕 SOP 连续追问 | ## 来源映射 | ruoyi-ai 来源 | 本项目落点 | |---|---| | `ruoyi-modules/ruoyi-chat/controller/knowledge` | `ruoyi-aihr/controller` 下只保留业务 API | | `KnowledgeAttachServiceImpl` | 文档上传、解析、分片、入库服务 | | `KnowledgeRetrievalServiceImpl` | 检索服务,先保留 fulltext,再接向量 | | `VectorStoreService` | 暂不抽独立 service,先在 `AihrSopSeedService` 用 Qdrant REST 做最小闭环 | | `chat_model / chat_provider` | `aihr_model_config / aihr_model_provider` | | `CustomApiServiceImpl / OpenAIServiceImpl` | 先落 `AihrModelSeedService` 的 OpenAI-compatible HTTP 边界 | | `EmbeddingModelFactory / RerankModelFactory` | 后续接向量化与重排序时再搬 provider adapter | ## 当前第一片 - 新增 MySQL 8 DDL:`backend/script/sql/aihr_knowledge_mysql8.sql` - 先定义 `aihr_knowledge_info`、`aihr_knowledge_attach`、`aihr_knowledge_fragment` - DDL 已包含住宅类 SOP seed 数据;`scripts/reset-dev-db.sh` 会导入。 ## 当前第二片 - 新增 MySQL 8 DDL:`backend/script/sql/aihr_model_mysql8.sql` - 先定义 `aihr_model_provider`、`aihr_model_config` - 新增后端 API:`GET /api/aihr/model/providers`、`GET /api/aihr/model/configs`、`POST /api/aihr/model/chat` - `POST /api/aihr/model/chat` 优先读取 `aihr_model_config`,并从 `aihr_model_provider` 继承 `api_host/api_key`;未配置时返回 seed fallback,不向接口响应暴露密钥。 ## 当前第三片 - 新增后端 API:`POST /api/knowledge/doc/upload` - SOP 页面已提供“上传文档”入口,支持 `.txt/.md/.markdown/.pdf/.doc/.docx/.xls/.xlsx/.ppt/.pptx`。 - 上传时先复用若依 `sys_oss` 写入 MinIO,再按 `category` 找到或创建 `aihr_knowledge_info`,在 `aihr_knowledge_attach` 绑定 `oss_id/doc_id`,最后写入 `aihr_knowledge_fragment`。 - 当前限制 100MB 内;同一知识库同名文件会复用 `doc_id` 并替换旧片段。 - PDF/Word 解析走 Tika core + PDF/Microsoft 模块,不整包引入标准解析器集合。 - 暂不引入图片智能分析和异步解析任务;这些进入后续片。 ## 当前第四片 - `/api/knowledge/search` 已优先查询 `aihr_knowledge_fragment`。 - 检索方式先迁移 `ruoyi-ai` 的 MySQL Fulltext 关键词召回:`MATCH(content) AGAINST(...)`。 - MySQL 未命中或表未导入时仍回退当前 seed,保证 MVP 页面不断。 - `aihr_knowledge_fragment` 已增加 `embedding_json/embedding_model/embedding_time`。 - 若数据库启用 `category=vector` 的模型配置,上传后会同步调用 OpenAI-compatible `/embeddings` 并写入片段向量。 - Qdrant 已接入本地开发编排;embedding 写入 MySQL 后尽力 upsert 到默认 collection `aihr_knowledge`。 - `/api/knowledge/search` 在 vector 模型和 Qdrant 可用时会生成 query embedding,走 Qdrant 召回后回 MySQL hydrate 片段,并与 MySQL Fulltext 用 RRF 融合。 - Qdrant 不可用或 vector 模型未配置时,仍走 MySQL Fulltext / LIKE / seed fallback。 - 新增 `GET /api/knowledge/doc/vector-index-status` 和 `POST /api/knowledge/doc/rebuild-vector-index`,模型配置页可检查当前 vector 模型维度、Qdrant collection 维度、点数和片段向量数,并按当前模型清空旧 embedding 后重建。 - 外部 embedding 成功但 Qdrant 维度不匹配时不再静默降级为本地 hash 向量,避免同一资料在模型切换后出现“数据库有向量、索引不可用”的假成功。 ## 当前第五片 - 新增后端 API:`GET /api/knowledge/processing/overview`。 - 新增前端页面:`/knowledge/processing`,菜单名“资料处理”;`SOP知识库` 菜单保持独立不改名。 - 页面聚合展示资料总量、已完成、处理中、失败、资料分类、解析任务表、处理链路、规则风险和事件列表;解析任务表按当前筛选结果前端分页,默认 10 条/页,可切换 20/50 条,筛选或刷新时回到第一页。 - 页面批量导入走 `POST /api/knowledge/doc/upload-async`,支持多文件和 ZIP,按批次轮询并可单文件重试;不提供浏览器目录选择。 - `POST /api/knowledge/doc/import-local-task`、`GET /api/knowledge/doc/import-tasks`、`POST /api/knowledge/doc/import-tasks/{id}/cancel` 和同步 `POST /api/knowledge/doc/import-local` 仅保留为运维/调试接口,不在资料处理页暴露。 ## 当前第六片 - 新增图片文件支持(jpg/jpeg/png/gif/webp/bmp),纳入 `supportedFile()` 和上传入口。 - 上传图片时,若数据库配置了 `category='vision'` 或 `category='chat'` 的启用模型,会将图片编码为 base64 data URL,调用同一供应商的 OpenAI-compatible `/chat/completions` 做视觉 OCR,提取图片文字写入 fragment;无视觉模型时返回空字符串,fragment 为 0,不影响其他格式上传。 - `visionRuntime()` 优先查 `category='vision'`,无则回退 `category='chat'`,复用 `chatRuntime()` 同一查询模式。 - `ProcessingRulesResponse.imageOcrEnabled` 改为动态值 `visionRuntime().isPresent()`,前端“图片 OCR”开关随模型配置实时反映;未配置时灰显并显示“即将支持”标签。 - 不依赖 Tesseract,零服务器安装依赖;识别精度与中文复杂版面质量由所配置的视觉 LLM 决定。 ## 暂缓项 - 完整 `ruoyi-chat` 模块 - Vben Admin 前端 - Milvus/Weaviate/pgvector 等多向量库同时支持 - 工作流、多智能体、MCP、Skills - 全量模型管理后台 - 完整流式 chat 与消息持久化 - 导入任务暂停、分布式队列 - 大规模资料的异步向量重建进度条