# AI 知识库 RAG 功能 - 前端联调方案 ## 涉及页面 - **API 密钥管理**:`ai/views/apikey/` — 管理 AI 平台 API 密钥 - **模型管理**:`ai/views/model/` — 管理 AI 模型配置(聊天、向量化等) - **知识库管理**:`ai/views/knowledge/` — 知识库 CRUD、文档上传、分段管理、RAG 检索 ## 业务流程与数据带入 ``` 步1: 配置 API 密钥(一次性) └─ 在「API 密钥管理」页配置通义千问 API Key → 获得 apiKeyId 步2: 配置向量化模型(一次性) └─ 在「模型管理」页新建 Embedding 模型 → keyId 从步1带入 └─ 模型标识填 "text-embedding-v3",平台选 "TongYi",类型选 "EMBEDDING(5)" └─ 获得 embeddingModelId 步3: 创建知识库 └─ 在「知识库管理」页新建知识库 → embeddingModelId 从步2带入 └─ 可设置 topK 和相似度阈值 步4: 创建文档 └─ 在知识库详情页上传文档(提供名称和 URL) └─ 后端自动下载文档、提取文本内容(Tika 解析) 步5: 处理文档(分段+向量化) └─ 在文档列表点击「处理」按钮 └─ 后端将文档内容切片、调用向量模型生成 Embedding、写入 Milvus 步6: RAG 检索 └─ 在知识库详情页输入检索内容 → 后端向量检索 + 相似度过滤 └─ 返回最匹配的分段及相似度分数 ``` --- ## API 接口 ### 1. API 密钥管理 **基础路径**:`/ai/api-key` | 方法 | 路径 | 说明 | |------|------|------| | POST | `/ai/api-key/create` | 创建 API 密钥 | | PUT | `/ai/api-key/update` | 更新 API 密钥 | | DELETE | `/ai/api-key/delete` | 删除 API 密钥 | | GET | `/ai/api-key/get` | 获取单个 API 密钥 | | GET | `/ai/api-key/page` | 分页查询 API 密钥 | **POST /create 请求参数:** | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | name | String | 是 | 密钥名称,如"通义千问" | | apiKey | String | 是 | API 密钥字符串 | | platform | String | 是 | 平台:`TongYi`(通义千问) | | url | String | 否 | API 地址(一般留空) | | status | Integer | 否 | 状态:0=启用,1=禁用 | **响应:** `{ "code": 0, "data": 1 }` (返回密钥 ID) --- ### 2. 模型管理 **基础路径**:`/ai/model` | 方法 | 路径 | 说明 | |------|------|------| | POST | `/ai/model/create` | 创建 AI 模型 | | PUT | `/ai/model/update` | 更新 AI 模型 | | DELETE | `/ai/model/delete` | 删除 AI 模型 | | GET | `/ai/model/get` | 获取单个模型 | | GET | `/ai/model/page` | 分页查询模型 | **POST /create 请求参数:** | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | keyId | Long | 是 | API 密钥 ID(从上一步带入) | | name | String | 是 | 模型名称,如"通义千问向量化" | | model | String | 是 | 模型标识,向量化模型填 `text-embedding-v3` | | platform | String | 是 | 平台,固定 `TongYi` | | type | Integer | 是 | 模型类型:1=CHAT,5=EMBEDDING | | sort | Integer | 否 | 排序 | | status | Integer | 否 | 状态:0=启用 | | temperature | Double | 否 | 温度(Embedding 类型不需要) | | maxTokens | Integer | 否 | 最大 Token | | maxContexts | Integer | 否 | 最大上下文 | **模型类型枚举:** | type 值 | 说明 | |---------|------| | 1 | CHAT(聊天) | | 5 | EMBEDDING(向量化) | **平台枚举:** | platform | 说明 | |----------|------| | TongYi | 通义千问 | --- ### 3. 知识库管理 **基础路径**:`/ai/knowledge` | 方法 | 路径 | 说明 | |------|------|------| | POST | `/ai/knowledge/create` | 创建知识库 | | PUT | `/ai/knowledge/update` | 更新知识库 | | DELETE | `/ai/knowledge/delete` | 删除知识库 | | GET | `/ai/knowledge/get` | 获取单个知识库 | | GET | `/ai/knowledge/page` | 分页查询知识库 | | POST | `/ai/knowledge/document/create` | 创建文档(批量) | **POST /create 请求参数:** | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | name | String | 是 | 知识库名称 | | description | String | 否 | 知识库描述 | | embeddingModelId | Long | 是 | 向量模型 ID(从模型管理页带入) | | topK | Integer | 否 | 检索返回条数,默认 3 | | similarityThreshold | Double | 否 | 相似度阈值,默认 0.7 | | status | Integer | 否 | 状态:0=启用 | **提示**:创建知识库前,需要先有一个 `type=5 (EMBEDDING)` 的模型。前端应在选择向量模型时过滤只显示 `type=5` 的模型。 **POST /document/create 请求参数:** | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | knowledgeId | Long | 是 | 知识库 ID | | names | List\ | 是 | 文档名称列表,如 `["产品手册.pdf", "API文档.docx"]` | | urls | List\ | 是 | 文档 URL 列表(与 names 一一对应) | --- ### 4. 文档管理 **基础路径**:`/ai/knowledge/document` | 方法 | 路径 | 说明 | |------|------|------| | PUT | `/ai/knowledge/document/update` | 更新文档 | | DELETE | `/ai/knowledge/document/delete` | 删除文档(含分段+向量) | | GET | `/ai/knowledge/document/get` | 获取单个文档 | | GET | `/ai/knowledge/document/page` | 分页查询文档 | | PUT | `/ai/knowledge/document/update-status` | 更新文档状态 | | POST | `/ai/knowledge/document/process/{id}` | 处理文档(分段+向量化) | | GET | `/ai/knowledge/document/progress` | 查询文档处理进度 | **PUT /update 请求参数:** | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | id | Long | 是 | 文档 ID | | name | String | 否 | 文档名称 | | url | String | 否 | 文档 URL | **POST /process/{id}**:将文档内容切片并写入 Milvus 向量库。处理完才能被检索到。 **GET /progress 请求参数:** | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | documentIds | List\ | 是 | 文档 ID 列表 | **GET /progress 响应新增字段:** | 字段 | 类型 | 说明 | |------|------|------| | documentId | Long | 文档 ID | | count | Long | 分段总数 | | embeddingCount | Long | 已向量化数量 | --- ### 5. 分段管理 & RAG 检索 **基础路径**:`/ai/knowledge/segment` | 方法 | 路径 | 说明 | |------|------|------| | GET | `/ai/knowledge/segment/get` | 获取单个分段 | | GET | `/ai/knowledge/segment/page` | 分页查询分段 | | **GET** | **`/ai/knowledge/segment/split`** | **文档切分预览(处理前预览切分效果)** | | PUT | `/ai/knowledge/segment/update-status` | 更新分段状态 | | **POST** | **`/ai/knowledge/segment/search`** | **RAG 向量检索(核心接口)** | ### GET /ai/knowledge/segment/split 用于在文档处理前预览切分效果,不保存任何数据。 **请求参数:** | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | url | String | 是 | 文档 URL | | name | String | 是 | 文档名称(用于判断文件类型) | | segmentMaxTokens | Integer | 否 | 分段最大 Token 数,默认 800 | **响应示例:** ```json { "code": 0, "data": [ { "content": "第一段内容...", "contentLength": 256, "tokens": 180 }, { "content": "第二段内容...", "contentLength": 300, "tokens": 210 } ] } ``` --- ## RAG 检索(核心功能) ### POST /ai/knowledge/segment/search **请求参数:** | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | knowledgeId | Long | 是 | 知识库 ID | | content | String | 是 | 检索内容(自然语言) | | topK | Integer | 否 | 返回条数,默认取知识库配置的 topK | | similarityThreshold | Double | 否 | 相似度阈值,默认取知识库配置的阈值 | **响应:** ```json { "code": 0, "data": [ { "id": 100, "documentId": 10, "knowledgeId": 1, "content": "分段内容文本...", "contentLength": 256, "tokens": 180, "score": 0.85 } ] } ``` **响应字段说明:** | 字段 | 类型 | 说明 | |------|------|------| | id | Long | 分段 ID | | documentId | Long | 所属文档 ID | | knowledgeId | Long | 所属知识库 ID | | content | String | 分段内容文本 | | contentLength | Integer | 内容字符长度 | | tokens | Integer | 估算 Token 数 | | score | Double | 相似度分数(0~1),越高越相关 | --- ## 字段展示规则 ### 知识库列表/详情 | 字段 | 展示位置 | 说明 | |------|----------|------| | name | 列表、详情 | 知识库名称 | | description | 详情 | 知识库描述 | | embeddingModel | 列表、详情 | 显示模型标识如 `text-embedding-v3` | | topK | 详情 | 检索返回最大条数 | | similarityThreshold | 详情 | 相似度阈值(0~1) | | status | 列表、详情 | 启用/禁用 | | createTime | 列表 | 创建时间 | ### 文档列表/详情 | 字段 | 展示位置 | 说明 | |------|----------|------| | name | 列表、详情 | 文档名称 | | url | 详情 | 文档 URL | | contentLength | 详情 | 内容长度 | | tokens | 详情 | Token 数 | | retrievalCount | 详情 | 被检索命中次数 | | status | 列表(tag) | 状态标签 | ### 分段列表 | 字段 | 展示位置 | 说明 | |------|----------|------| | documentId | 列表 | 所属文档 ID | | content | 列表(截断) | 分段内容(可截断显示前 100 字) | | contentLength | 列表 | 内容长度 | | tokens | 列表 | Token 数 | | vectorId | 列表/详情 | 向量 ID(非空表示已向量化) | | retrievalCount | 列表 | 检索命中次数 | ### RAG 检索结果 | 字段 | 展示位置 | 说明 | |------|----------|------| | content | 结果卡片 | 分段全文内容 | | score | 结果卡片 | 相似度分数,建议用进度条或颜色标识(>0.8 绿色,0.6~0.8 黄色,<0.6 灰色) | | documentId | 辅助信息 | 可点击跳转到来源文档 | | contentLength | 辅助信息 | 内容长度 | --- ## 业务规则说明 | 场景 | 规则 | |------|------| | 创建文档 | 后端自动下载 URL 文件并提取文本。支持 `txt/md/json/xml/csv/yaml/yml`(直接读取)和其他格式(Tika 解析) | | 文档处理 | 必须先 `POST /process/{id}` 处理后,文档内容才会被检索到 | | 文档分段 | 后端使用 `TokenTextSplitter` 自动切片,默认每段 800 tokens | | 向量写入 | 处理文档时自动调用 Embedding 模型生成向量并写入 Milvus | | 删除文档 | 同时删除文档记录、所有分段记录和 Milvus 中对应向量 | | 检索相似度 | 返回结果按相似度降序排列,低于 `similarityThreshold` 的结果不会被返回 | | 检索计数器 | 每次检索命中后,自动更新对应分段和文档的 `retrievalCount` | | API 密钥 | 创建知识库前,必须先创建 API 密钥和 Embedding 模型 | --- ## 接口调用时序 ### 创建知识库完整流程 ``` 1. POST /ai/api-key/create → apiKeyId 2. POST /ai/model/create → modelId (type=5, keyId=apiKeyId) 3. POST /ai/knowledge/create → knowledgeId (embeddingModelId=modelId) 4. POST /ai/knowledge/document/create → documentIds 5. POST /ai/knowledge/document/process/{documentId} → 向量化 6. GET /ai/knowledge/document/progress?documentIds=... → 检查进度 7. POST /ai/knowledge/segment/search → RAG 检索 ``` ### 检索流程(已配置好的知识库) ``` 1. POST /ai/knowledge/segment/search { knowledgeId, content, topK?, similarityThreshold? } ↓ 后端: 查询向量 → Milvus相似度检索 → 过滤低于阈值的结果 → 更新检索计数 ↓ 返回搜索结果列表 ``` --- ## 注意事项 - 知识库创建时必须选择 `type=5 (EMBEDDING)` 的模型,前端获取模型列表后需要过滤 - 文档上传后**不会自动处理**,需要在文档列表点击「处理」按钮调用 `POST /process/{id}` - 处理进度可通过 `GET /progress` 轮询查询(`embeddingCount >= count` 表示处理完成) - 检索的 `similarityThreshold` 建议默认 0.7,可根据实际效果调整 - `vectorId` 为空(`""`)的分段表示尚未写入向量库,不会被检索到 - 删除知识库时,后端当前实现只删除知识库记录本身,需确认是否需要级联删除文档和分段