Files
leaudit-platform-backend/docs/RAG/RAG聊天接口.md
T
2026-05-09 20:04:08 +08:00

494 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# RAG 聊天接口
> 最后整理:2026-05-07
> 对应后端:`fastapi_modules/fastapi_leaudit/controllers/ragChatController.py`
> 统一前缀:`/api/v3/rag`
## 1. 目标与范围
本组接口用于替代旧的 `dify_chat/*` 对话代理,直接提供自有 RAG 聊天能力。
当前已落地能力:
- 获取当前用户可见的 RAG 应用
- 获取默认 RAG 应用
- 获取当前用户可见知识库
- 获取聊天页面参数
- 发起流式对话
- 查询会话列表
- 查询会话消息
- 重命名会话
- 删除会话
- 消息反馈
当前不在本文档范围内:
- 知识库 CRUD 管理
- 文档切分 / 入库任务
- Chroma 集合构建脚本
## 2. 鉴权与权限
### 2.1 鉴权方式
所有接口都要求请求头带:
```http
Authorization: Bearer <access_token>
```
JWT 解析逻辑见:
- `fastapi_common/fastapi_common_security/security.py`
- `fastapi_common/fastapi_common_security/jwtService.py`
JWT payload 至少会被后端消费这些字段:
- `user_id`
- `username`
- `area`
- `user_role`
- `type`,必须为 `access`
### 2.2 权限键
| 接口 | 权限 |
|------|------|
| `GET /api/v3/rag/apps` | `rag:app:read` |
| `GET /api/v3/rag/apps/default` | `rag:app:read` |
| `GET /api/v3/rag/datasets/my` | `rag:dataset:read` |
| `GET /api/v3/rag/chat/parameters` | `rag:chat:use``rag:app:read` 其一即可 |
| `POST /api/v3/rag/chat/messages` | `rag:chat:use` |
| `GET /api/v3/rag/chat/conversations` | `rag:conversation:read` |
| `GET /api/v3/rag/chat/conversations/{ConversationId}/messages` | `rag:conversation:read` |
| `PATCH /api/v3/rag/chat/conversations/{ConversationId}` | `rag:conversation:update` |
| `DELETE /api/v3/rag/chat/conversations/{ConversationId}` | `rag:conversation:delete` |
| `POST /api/v3/rag/chat/messages/{MessageId}/feedback` | `rag:message:feedback` |
说明:
- 权限检查使用 `HasAnyPermission`,即“列表中的任一权限命中即可通过”。
- 具体实现见 `fastapi_modules/fastapi_leaudit/services/impl/permissionServiceImpl.py`
## 3. 通用返回格式
除流式接口外,统一返回:
```json
{
"code": 200,
"msg": "success",
"data": {}
}
```
权限不足时通常返回:
```json
{
"code": 403,
"msg": "当前用户没有对应权限",
"data": null
}
```
## 4. 接口列表
### 4.1 获取可见应用列表
`GET /api/v3/rag/apps`
用途:
- 聊天页面加载应用下拉
- 根据地区 / 省级角色做应用可见性过滤
请求参数:无
成功响应示例:
```json
{
"code": 200,
"msg": "success",
"data": {
"data": [
{
"appId": "1",
"appName": "法务问答",
"description": "默认烟草法务知识问答",
"isDefault": true
}
],
"total": 1
}
}
```
可见性规则:
- `provincial_admin` 可见全部启用应用
- 其他角色仅可见:
- `rag_chat_app.area = 用户 area`
- `rag_chat_app.area = '省级'`
- `rag_chat_app.area = ''`
- 或关联数据集 `rag_dataset.is_public = true`
### 4.2 获取默认应用
`GET /api/v3/rag/apps/default`
用途:
- 聊天页初始化默认应用
请求参数:无
成功响应示例:
```json
{
"code": 200,
"msg": "success",
"data": {
"appId": "1",
"appName": "法务问答",
"description": "默认烟草法务知识问答",
"isDefault": true
}
}
```
补充说明:
- 如果没有显式默认应用,会退回到当前用户可见的第一条应用。
- 如果完全没有可见应用,返回 `data: null`
### 4.3 获取当前用户可见知识库
`GET /api/v3/rag/datasets/my`
用途:
- 聊天页展示“当前可用知识库”时使用
请求参数:无
成功响应示例:
```json
{
"code": 200,
"msg": "success",
"data": {
"data": [
{
"id": 1,
"name": "广东烟草法规库",
"description": "省级法规与制度",
"area": "省级",
"isPublic": true,
"isDefault": true,
"documentCount": 120,
"totalChunks": 8345,
"status": 1
}
],
"total": 1
}
}
```
### 4.4 获取聊天参数
`GET /api/v3/rag/chat/parameters`
查询参数:
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `appId` | int | 否 | 指定应用 ID;不传则取默认应用 |
用途:
- 初始化开场白
- 初始化建议问题
- 初始化上传能力配置
成功响应示例:
```json
{
"code": 200,
"msg": "success",
"data": {
"openingStatement": "你好,我可以帮你解答烟草行业法务问题。",
"suggestedQuestions": [
"烟草专卖许可延续的法定条件是什么?",
"行政处罚文书审查重点有哪些?"
],
"userInputForm": [],
"fileUpload": {
"image": {
"enabled": false
}
}
}
}
```
### 4.5 发起流式对话
`POST /api/v3/rag/chat/messages`
请求体:
```json
{
"query": "烟草专卖许可证延续申请的审查要点是什么?",
"conversationId": null,
"appId": 1
}
```
字段说明:
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `query` | string | 是 | 用户问题,不能为空 |
| `conversationId` | string \| null | 否 | 会话 ID;新对话可传 `null` 或不传 |
| `appId` | int \| null | 否 | 应用 ID;不传则自动回退默认应用 |
返回类型:
- `text/event-stream`
SSE 事件 1:流式正文片段
```text
data: {"event":"message","task_id":"...","message_id":"...","conversation_id":"...","answer":"第一段内容","created_at":1746580000}
```
SSE 事件 2:流式结束
```text
data: {"event":"message_end","task_id":"...","message_id":"...","conversation_id":"...","metadata":{"usage":{"total_tokens":1234},"retriever_resources":[...],"suggested_questions":["问题1","问题2"]}}
```
SSE 事件 3:模型异常
```text
data: {"event":"error","task_id":"...","message_id":"...","code":"llm_error","message":"..."}
```
服务端行为说明:
-`conversationId` 为空,会自动创建新会话
- 会先落一条 `role = user` 消息,再流式生成回答
- 流结束后会落一条 `role = assistant` 消息
- 若命中知识库,会把引用结果写入 `sources / metadata`
- 会根据对话内容追加 `suggested_questions`
### 4.6 获取会话列表
`GET /api/v3/rag/chat/conversations`
查询参数:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|------|------|------|--------|------|
| `appId` | int | 否 | - | 按应用过滤 |
| `page` | int | 否 | `1` | 页码,从 1 开始 |
| `pageSize` | int | 否 | `20` | 每页数量,最大 100 |
成功响应示例:
```json
{
"code": 200,
"msg": "success",
"data": {
"data": [
{
"id": "b17d3b0b-xxxx-xxxx",
"name": "新对话",
"introduction": "",
"createdAt": 1746580000,
"updatedAt": 1746580066
}
],
"hasMore": false,
"limit": 20
}
}
```
### 4.7 获取会话消息
`GET /api/v3/rag/chat/conversations/{ConversationId}/messages`
路径参数:
| 参数 | 类型 | 说明 |
|------|------|------|
| `ConversationId` | string | 会话 ID |
查询参数:
| 参数 | 类型 | 必填 | 默认值 |
|------|------|------|--------|
| `page` | int | 否 | `1` |
| `pageSize` | int | 否 | `20` |
成功响应示例:
```json
{
"code": 200,
"msg": "success",
"data": {
"data": [
{
"id": "assistant-message-id",
"conversationId": "b17d3b0b-xxxx-xxxx",
"query": "烟草专卖许可证延续申请的审查要点是什么?",
"answer": "先核对主体资格,再核对经营条件……",
"feedback": {
"rating": "like"
},
"retrieverResources": [
{
"position": 1,
"dataset_id": "1",
"dataset_name": "广东烟草法规库",
"document_id": "12",
"document_name": "行政许可审查规范.pdf",
"segment_id": "chunk-1",
"score": 0.9132
}
],
"createdAt": 1746580000
}
],
"hasMore": false,
"limit": 20
}
}
```
说明:
- 返回结构是按“问答对”聚合后的结果,不是底层 `rag_message` 原始逐条结果。
### 4.8 重命名会话
`PATCH /api/v3/rag/chat/conversations/{ConversationId}`
请求体:
```json
{
"name": "许可证延续审查要点"
}
```
成功响应示例:
```json
{
"code": 200,
"msg": "success",
"data": {
"result": "success",
"name": "许可证延续审查要点"
}
}
```
### 4.9 删除会话
`DELETE /api/v3/rag/chat/conversations/{ConversationId}`
成功响应示例:
```json
{
"code": 200,
"msg": "success",
"data": {
"result": "success"
}
}
```
说明:
- 逻辑删除,实际是设置 `rag_conversation.deleted_at`
### 4.10 消息反馈
`POST /api/v3/rag/chat/messages/{MessageId}/feedback`
请求体:
```json
{
"rating": "like"
}
```
可选值:
- `like`
- `dislike`
- `null`
成功响应示例:
```json
{
"code": 200,
"msg": "success",
"data": {
"result": "success"
}
}
```
## 5. 数据表对应关系
| 表 | 用途 |
|----|------|
| `rag_dataset` | 知识库定义、地区可见性、检索参数 |
| `rag_document` | 知识库文档、启停状态、命中次数 |
| `rag_chat_app` | 聊天应用配置、默认应用、应用绑定知识库 |
| `rag_conversation` | 用户会话 |
| `rag_message` | 底层消息落库,包含引用与反馈 |
## 6. 当前实现约束
- 当前只提供 `GET /datasets/my`,不提供知识库管理 CRUD
- `fileUpload.image.enabled` 固定为 `false`
- 检索依赖 Chroma;Chroma 不可用时,接口仍可回答,但会退化成无知识库上下文
- 建议问题 `suggestedQuestions` 由二次模型调用生成,失败时会降级为空数组
## 7. 联调建议
最小联调顺序:
1. `GET /api/v3/rag/apps`
2. `GET /api/v3/rag/apps/default`
3. `GET /api/v3/rag/chat/parameters`
4. `POST /api/v3/rag/chat/messages`
5. `GET /api/v3/rag/chat/conversations`
6. `GET /api/v3/rag/chat/conversations/{ConversationId}/messages`
优先检查:
- 401JWT 是否有效
- 403`rag:*` 权限是否已写入并分配
- 500LLM、数据库、Chroma、知识库配置是否可用