docs: add rag dataset document management notes
This commit is contained in:
@@ -0,0 +1,383 @@
|
||||
# RAG 知识库文档管理接口与行为变更说明
|
||||
|
||||
> 最后整理:2026-05-11
|
||||
> 对应后端提交:`8206ed7`
|
||||
> 对应控制器:`fastapi_modules/fastapi_leaudit/controllers/ragChatController.py`
|
||||
> 对应服务:`fastapi_modules/fastapi_leaudit/services/impl/ragDatasetServiceImpl.py`
|
||||
> 统一前缀:`/api/v3/rag`
|
||||
|
||||
## 1. 目标
|
||||
|
||||
本文档说明本次 RAG 知识库“文档管理”相关后端改动,重点覆盖:
|
||||
|
||||
- 知识库文档批量删除
|
||||
- 删除结果明细返回
|
||||
- 处理中 / 索引中文档删除限制
|
||||
- 文档上传改为异步处理
|
||||
- 文档重处理改为异步处理
|
||||
- 前端轮询所依赖的状态流转
|
||||
- 向量化调用的分批与错误处理
|
||||
|
||||
不在本文范围内:
|
||||
|
||||
- 聊天接口
|
||||
- 应用管理接口
|
||||
- 知识库基础 CRUD
|
||||
- 子分段 / 分段编辑细节
|
||||
|
||||
## 2. 相关权限
|
||||
|
||||
本次涉及的接口主要使用以下权限:
|
||||
|
||||
| 接口 | 权限 |
|
||||
|------|------|
|
||||
| `GET /api/v3/rag/datasets/{DatasetId}/documents/{DocumentId}/indexing-status` | `rag:dataset:read` |
|
||||
| `POST /api/v3/rag/datasets/{DatasetId}/documents` | `rag:dataset:update` |
|
||||
| `POST /api/v3/rag/datasets/{DatasetId}/documents/{DocumentId}/update-by-file` | `rag:dataset:update` |
|
||||
| `DELETE /api/v3/rag/datasets/{DatasetId}/documents/{DocumentId}` | `rag:dataset:delete` |
|
||||
| `POST /api/v3/rag/datasets/{DatasetId}/documents/batch-delete` | `rag:dataset:delete` |
|
||||
|
||||
补充:
|
||||
|
||||
- 后端控制器层会先检查权限键。
|
||||
- 服务层还会继续校验角色范围。
|
||||
- 当前允许执行文档上传 / 删除的角色范围仍为:
|
||||
- `provincial_admin`
|
||||
- `super_admin`
|
||||
- `admin`
|
||||
|
||||
## 3. 本次行为变化总览
|
||||
|
||||
### 3.1 批量删除
|
||||
|
||||
新增接口:
|
||||
|
||||
- `POST /api/v3/rag/datasets/{DatasetId}/documents/batch-delete`
|
||||
|
||||
行为:
|
||||
|
||||
- 支持单请求删除多个文档
|
||||
- 返回删除成功数量、跳过数量、已删除 ID、跳过原因明细
|
||||
|
||||
### 3.2 删除限制
|
||||
|
||||
删除接口不再允许删除“处理中”的文档。
|
||||
|
||||
当前视为处理中、不可删除的状态:
|
||||
|
||||
- `waiting`
|
||||
- `parsing`
|
||||
- `cleaning`
|
||||
- `splitting`
|
||||
- `indexing`
|
||||
|
||||
当前允许删除的状态:
|
||||
|
||||
- `completed`
|
||||
- `error`
|
||||
- `paused`
|
||||
|
||||
### 3.3 上传与重处理改为异步
|
||||
|
||||
此前:
|
||||
|
||||
- 上传接口会等完整解析、切分、向量化完成后才返回
|
||||
|
||||
现在:
|
||||
|
||||
- 上传接口创建文档记录后立即返回
|
||||
- 后台使用异步任务继续完成后续处理
|
||||
- 前端通过 `indexing-status` 接口轮询状态
|
||||
|
||||
### 3.4 向量化调用分批
|
||||
|
||||
此前:
|
||||
|
||||
- 一次性将全部 chunk 发给 embedding 接口
|
||||
|
||||
现在:
|
||||
|
||||
- 按 `RAG_CONFIG["EMBED_BATCH_SIZE"]` 分批提交
|
||||
- 默认值由配置控制,未配置时使用 `10`
|
||||
|
||||
目的:
|
||||
|
||||
- 降低 DashScope / embedding 服务因单次输入过大返回 `400 Bad Request` 的概率
|
||||
|
||||
## 4. 接口说明
|
||||
|
||||
### 4.1 上传知识库文档
|
||||
|
||||
`POST /api/v3/rag/datasets/{DatasetId}/documents`
|
||||
|
||||
请求:
|
||||
|
||||
- `multipart/form-data`
|
||||
- `file`: 文件内容
|
||||
- `data`: 可选,JSON 字符串,表示处理配置
|
||||
|
||||
当前支持格式:
|
||||
|
||||
- `.pdf`
|
||||
- `.docx`
|
||||
- `.txt`
|
||||
- `.md`
|
||||
- `.json`
|
||||
|
||||
成功响应示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "success",
|
||||
"data": {
|
||||
"document": {
|
||||
"id": "12",
|
||||
"name": "示例文档.pdf",
|
||||
"indexing_status": "indexing",
|
||||
"word_count": 0,
|
||||
"hit_count": 0,
|
||||
"enabled": true
|
||||
},
|
||||
"batch": "12"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
说明:
|
||||
|
||||
- 返回时不代表向量化已经完成。
|
||||
- `batch` 当前等同于 `documentId`,前端可直接拿去轮询状态。
|
||||
|
||||
### 4.2 重处理知识库文档
|
||||
|
||||
`POST /api/v3/rag/datasets/{DatasetId}/documents/{DocumentId}/update-by-file`
|
||||
|
||||
行为与上传接口一致:
|
||||
|
||||
- 先把文档状态置为 `indexing`
|
||||
- 清理旧向量
|
||||
- 立即返回
|
||||
- 后台异步重建 chunk 与向量
|
||||
|
||||
成功响应示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "success",
|
||||
"data": {
|
||||
"document": {
|
||||
"id": "12",
|
||||
"name": "示例文档.pdf",
|
||||
"indexing_status": "indexing",
|
||||
"word_count": 0,
|
||||
"hit_count": 0,
|
||||
"enabled": true
|
||||
},
|
||||
"batch": "12"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4.3 查询文档处理状态
|
||||
|
||||
`GET /api/v3/rag/datasets/{DatasetId}/documents/{DocumentId}/indexing-status`
|
||||
|
||||
成功响应示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "success",
|
||||
"data": [
|
||||
{
|
||||
"id": "12",
|
||||
"indexing_status": "splitting",
|
||||
"processing_started_at": 1778490000,
|
||||
"parsing_completed_at": 1778490003,
|
||||
"cleaning_completed_at": 1778490005,
|
||||
"splitting_completed_at": null,
|
||||
"completed_at": null,
|
||||
"paused_at": null,
|
||||
"error": null,
|
||||
"stopped_at": null,
|
||||
"completed_segments": 0,
|
||||
"total_segments": 24
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
状态流转顺序:
|
||||
|
||||
- `indexing`(创建记录后的初始状态)
|
||||
- `parsing`
|
||||
- `cleaning`
|
||||
- `splitting`
|
||||
- `indexing`(写入向量阶段)
|
||||
- `completed`
|
||||
|
||||
失败时:
|
||||
|
||||
- 状态会更新为 `error`
|
||||
- `error` 字段会记录截断后的错误信息
|
||||
|
||||
### 4.4 单文档删除
|
||||
|
||||
`DELETE /api/v3/rag/datasets/{DatasetId}/documents/{DocumentId}`
|
||||
|
||||
行为:
|
||||
|
||||
- 实际内部复用批量删除逻辑
|
||||
- 如果目标文档处于处理中状态,会直接返回 400
|
||||
|
||||
错误示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 400,
|
||||
"msg": "文档仍在处理中,暂不允许删除",
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
### 4.5 批量删除文档
|
||||
|
||||
`POST /api/v3/rag/datasets/{DatasetId}/documents/batch-delete`
|
||||
|
||||
请求体:
|
||||
|
||||
```json
|
||||
{
|
||||
"document_ids": [12, 13, 14]
|
||||
}
|
||||
```
|
||||
|
||||
成功响应示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "success",
|
||||
"data": {
|
||||
"result": "success",
|
||||
"requestedCount": 3,
|
||||
"deletedCount": 2,
|
||||
"skippedCount": 1,
|
||||
"deletedIds": [12, 13],
|
||||
"skipped": [
|
||||
{
|
||||
"id": 14,
|
||||
"name": "处理中示例.pdf",
|
||||
"reason": "文档仍在处理中,暂不允许删除"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
说明:
|
||||
|
||||
- 后端会先查询所有目标文档
|
||||
- 对可删除文档:
|
||||
- 删除 Chroma 中对应向量
|
||||
- 删除 OSS 对象
|
||||
- 逻辑删除 `rag_document`
|
||||
- 完成后统一回写:
|
||||
- `rag_dataset.document_count`
|
||||
- `rag_dataset.total_chunks`
|
||||
|
||||
## 5. 后端内部状态处理说明
|
||||
|
||||
### 5.1 异步处理任务
|
||||
|
||||
上传 / 重处理现在通过内部异步任务 `_run_document_indexing_task(...)` 执行后续工作。
|
||||
|
||||
任务步骤:
|
||||
|
||||
1. 更新状态为 `parsing`
|
||||
2. 提取文本
|
||||
3. 更新状态为 `cleaning`
|
||||
4. 构建 chunk
|
||||
5. 更新状态为 `splitting`
|
||||
6. 调 embedding 接口生成向量
|
||||
7. 更新状态为 `indexing`
|
||||
8. 写入 Chroma
|
||||
9. 更新状态为 `completed`
|
||||
10. 同步 `rag_dataset` 统计字段
|
||||
|
||||
异常时:
|
||||
|
||||
- 状态写为 `error`
|
||||
- `indexing_error` 写入错误摘要
|
||||
|
||||
### 5.2 向量化分批
|
||||
|
||||
方法:
|
||||
|
||||
- `_embed_texts(texts, model_name)`
|
||||
|
||||
变化:
|
||||
|
||||
- 以前单次请求提交全部文本
|
||||
- 现在按批次循环提交
|
||||
|
||||
错误处理:
|
||||
|
||||
- 若 embedding 服务返回 HTTP 错误
|
||||
- 服务层会转成:
|
||||
|
||||
```text
|
||||
向量化服务调用失败: <上游错误文本>
|
||||
```
|
||||
|
||||
以便前端直接显示可读错误
|
||||
|
||||
## 6. 前后端联调注意事项
|
||||
|
||||
### 6.1 上传成功不等于处理完成
|
||||
|
||||
前端不能再以“上传接口返回 200”判断文档已经可检索。
|
||||
|
||||
正确做法:
|
||||
|
||||
1. 调上传接口
|
||||
2. 读取响应中的 `batch`
|
||||
3. 轮询 `indexing-status`
|
||||
4. 直到状态变为:
|
||||
- `completed`
|
||||
- 或 `error`
|
||||
|
||||
### 6.2 批量删除要接删除明细
|
||||
|
||||
前端不应只提示“删除成功”。
|
||||
|
||||
建议按以下优先级展示:
|
||||
|
||||
- 全部删除成功:提示删除数量
|
||||
- 部分删除成功:提示成功数 + 跳过数
|
||||
- 全部跳过:提示未删除,并展示跳过原因
|
||||
|
||||
### 6.3 处理中状态要禁用删除入口
|
||||
|
||||
虽然服务端已经拦截,但前端仍应同步禁用:
|
||||
|
||||
- 单删按钮
|
||||
- 批量多选框
|
||||
|
||||
避免用户误操作后频繁打到 400
|
||||
|
||||
## 7. 对应提交
|
||||
|
||||
本次后端变更对应提交:
|
||||
|
||||
- `8206ed7` `feat: improve rag dataset document management`
|
||||
|
||||
如果后续继续扩展:
|
||||
|
||||
- 文档状态更多细粒度字段
|
||||
- chunk 统计维度
|
||||
- 删除结果补充更多结构化信息
|
||||
|
||||
建议继续更新本文,而不是另起一份零散说明。
|
||||
Reference in New Issue
Block a user