Files
leaudit-platform-backend/docs/RAG/RAG聊天接口.md
T

12 KiB
Raw Blame History

RAG 聊天接口

最后整理:2026-05-11 本文已按当前后端实现逐项核对 对应后端:fastapi_modules/fastapi_leaudit/controllers/ragChatController.py 统一前缀:/api/v3/rag

1. 目标与范围

本组接口用于替代旧的 dify_chat/* 对话代理,直接提供自有 RAG 聊天能力。

当前已落地能力:

  • 获取当前用户可见的 RAG 应用
  • 获取默认 RAG 应用
  • 获取当前用户可见知识库
  • 获取聊天页面参数
  • 发起流式对话
  • 查询会话列表
  • 查询会话消息
  • 重命名会话
  • 删除会话
  • 消息反馈

当前不在本文档范围内:

  • 知识库 CRUD 管理
  • 文档切分 / 入库任务
  • Chroma 集合构建脚本

2. 鉴权与权限

2.1 鉴权方式

所有接口都要求请求头带:

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:userag: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. 通用返回格式

除流式接口外,统一返回:

{
  "code": 200,
  "msg": "success",
  "data": {}
}

权限不足时通常返回:

{
  "code": 403,
  "msg": "当前用户没有对应权限",
  "data": null
}

4. 接口列表

4.1 获取可见应用列表

GET /api/v3/rag/apps

用途:

  • 聊天页面加载应用下拉
  • 根据地区 / 省级角色做应用可见性过滤

请求参数:无

成功响应示例:

{
  "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

用途:

  • 聊天页初始化默认应用

请求参数:无

成功响应示例:

{
  "code": 200,
  "msg": "success",
  "data": {
    "appId": "1",
    "appName": "法务问答",
    "description": "默认烟草法务知识问答",
    "isDefault": true
  }
}

补充说明:

  • 如果没有显式默认应用,会退回到当前用户可见的第一条应用。
  • 如果完全没有可见应用,返回 data: null

4.3 获取当前用户可见知识库

GET /api/v3/rag/datasets/my

用途:

  • 聊天页展示“当前可用知识库”时使用

请求参数:无

成功响应示例:

{
  "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;不传则取默认应用

用途:

  • 初始化开场白
  • 初始化建议问题
  • 初始化上传能力配置

成功响应示例:

{
  "code": 200,
  "msg": "success",
  "data": {
    "openingStatement": "你好,我可以帮你解答烟草行业法务问题。",
    "suggestedQuestions": [
      "烟草专卖许可延续的法定条件是什么?",
      "行政处罚文书审查重点有哪些?"
    ],
    "userInputForm": [],
    "fileUpload": {
      "image": {
        "enabled": false
      }
    }
  }
}

补充说明:

  • 如果 appId 不存在、不可见,或者系统默认应用 / 排序第一条应用均不可见,当前实现不会报 404,而是返回一个空参数对象:
{
  "code": 200,
  "msg": "success",
  "data": {
    "openingStatement": "",
    "suggestedQuestions": [],
    "userInputForm": [],
    "fileUpload": {
      "image": {
        "enabled": false
      }
    }
  }
}

4.5 发起流式对话

POST /api/v3/rag/chat/messages

请求体:

{
  "query": "烟草专卖许可证延续申请的审查要点是什么?",
  "conversationId": null,
  "appId": 1
}

字段说明:

字段 类型 必填 说明
query string 用户问题,不能为空
conversationId string | null 会话 ID;新对话可传 null、不传,当前实现也把 "-1" 视为新对话
appId int | null 应用 ID;不传则自动回退默认应用

返回类型:

  • text/event-stream

SSE 事件 1:流式正文片段

data: {"event":"message","task_id":"...","message_id":"...","conversation_id":"...","answer":"第一段内容","created_at":1746580000}

SSE 事件 2:流式结束

data: {"event":"message_end","task_id":"...","message_id":"...","conversation_id":"...","metadata":{"usage":{"total_tokens":1234},"retriever_resources":[...],"suggested_questions":["问题1","问题2"]}}

SSE 事件 3:模型异常

data: {"event":"error","task_id":"...","message_id":"...","code":"llm_error","message":"..."}

服务端行为说明:

  • conversationId 为空,会自动创建新会话
  • conversationId 为空,会自动创建新会话,默认标题为 新对话
  • 会先落一条 role = user 消息,再流式生成回答
  • 流结束后会落一条 role = assistant 消息
  • 若命中知识库,会把引用结果写入 sources / metadata
  • 会根据对话内容追加 suggested_questions
  • 首轮回答完成后,后端会异步尝试生成会话标题
  • 当前应用解析顺序是:指定 appId -> 任意默认应用 -> 排序第一条应用;每一步都只检查当前命中的那一条记录是否可见,不会遍历全部可见应用

4.6 获取会话列表

GET /api/v3/rag/chat/conversations

查询参数:

参数 类型 必填 默认值 说明
appId int - 按应用过滤
page int 1 页码,从 1 开始
pageSize int 20 每页数量,最大 100

成功响应示例:

{
  "code": 200,
  "msg": "success",
  "data": {
    "data": [
      {
        "id": "b17d3b0b-xxxx-xxxx",
        "name": "烟草专卖法中的烟草定义",
        "introduction": "",
        "titleSource": "auto",
        "createdAt": 1746580000,
        "updatedAt": 1746580066,
        "lastMessageAt": 1746580066
      }
    ],
    "hasMore": false,
    "limit": 20
  }
}

补充说明:

  • titleSource 取值:
    • default:默认标题,例如 新对话
    • auto:系统自动生成标题
    • manual:用户手动重命名
  • 会话列表排序按 COALESCE(last_message_at, updated_at) DESC, updated_at DESC
  • 自动标题更新不应该被前端视作“新消息到达”

4.7 获取会话消息

GET /api/v3/rag/chat/conversations/{ConversationId}/messages

路径参数:

参数 类型 说明
ConversationId string 会话 ID

查询参数:

参数 类型 必填 默认值
page int 1
pageSize int 20

成功响应示例:

{
  "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
  }
}

补充说明:

  • 手动重命名会将该会话的标题来源标记为 manual
  • 已手动重命名的会话,后续自动标题任务不得覆盖

说明:

  • 返回结构是按“问答对”聚合后的结果,不是底层 rag_message 原始逐条结果。
  • 分页查询实际先按底层 rag_message 行分页,再在服务层折叠成“用户问 + 助手答”结构,所以单页返回条数可能少于 pageSize

4.8 重命名会话

PATCH /api/v3/rag/chat/conversations/{ConversationId}

请求体:

{
  "name": "许可证延续审查要点"
}

成功响应示例:

{
  "code": 200,
  "msg": "success",
  "data": {
    "result": "success",
    "name": "许可证延续审查要点"
  }
}

4.9 删除会话

DELETE /api/v3/rag/chat/conversations/{ConversationId}

成功响应示例:

{
  "code": 200,
  "msg": "success",
  "data": {
    "result": "success"
  }
}

说明:

  • 逻辑删除,实际是设置 rag_conversation.deleted_at

4.10 消息反馈

POST /api/v3/rag/chat/messages/{MessageId}/feedback

请求体:

{
  "rating": "like"
}

约定值:

  • like
  • dislike
  • null

补充说明:

  • 当前 DTO 仅声明 rating: str | null,后端不会强校验枚举,除 null 外其余字符串也会被写入 rag_message.feedback

成功响应示例:

{
  "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 由二次模型调用生成,失败时会降级为空数组
  • GET /chat/parameters / POST /chat/messages 的应用回退逻辑目前不是“从全部可见应用里挑第一条”,而是“默认应用优先,其次全表第一条”;当默认应用或首条应用不可见时,可能出现空参数或 未配置可用聊天应用

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 是否有效
  • 403rag:* 权限是否已写入并分配
  • 500LLM、数据库、Chroma、知识库配置是否可用