Files
rag/docs/main分支独有功能说明.md
lacerate551 858ee40e5b chore: 同步项目状态
- main.py: 去掉 emoji 避免 GBK 编码崩溃
- docs/curl测试手册.md: 更新模型名和测试日期
- docs/代码审查报告_2026-06-05.md: 删除过期报告
- docs/main分支独有功能说明.md: 新增
- docs/出题系统逻辑.md: 新增
2026-06-19 15:25:57 +08:00

391 lines
13 KiB
Markdown
Raw Permalink 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.
# main 分支独有功能与端点说明
> 本文档记录 `main` 分支(本地最新版本)相对于 `server-release`(生产服务器版本)的**独有功能和端点差异**。
>
> 更新日期2026-06-10 | 对比基准:`origin/server-release` (commit `15c0aec`) vs `main` (commit `edaef7a`)
---
## 一、新增端点(仅 main 可用)
### 1. 异步任务查询系统
main 分支引入了完整的异步任务注册表(`core/task_registry.py`),将上传、同步、出题等长耗时操作改为后台线程执行,接口立即返回 `task_id`
| 端点 | 方法 | 说明 |
|------|------|------|
| `/tasks` | GET | 获取任务列表(支持 status/type/limit 过滤) |
| `/tasks/<task_id>` | GET | 获取单个任务状态JSON 轮询,后端组推荐) |
| `/tasks/<task_id>/progress` | GET | SSE 流式任务进度推送dev-ui 前端推荐) |
| `/tasks/stats` | GET | 获取任务统计信息 |
**GET /tasks 请求参数**
| 参数 | 类型 | 必需 | 说明 |
|------|------|------|------|
| `status` | string | ❌ | 过滤状态:`pending` / `running` / `completed` / `failed` |
| `type` | string | ❌ | 过滤类型:`sync` / `reindex` / `upload` / `batch_upload` / `exam_generate` / `exam_grade` |
| `limit` | int | ❌ | 返回数量限制(默认 50 |
**GET /tasks 响应示例**
```json
{
"success": true,
"status": "success",
"status_code": 2000,
"message": "查询成功",
"data": {
"tasks": [
{
"task_id": "a1b2c3d4e5f6",
"type": "sync",
"description": "文档同步",
"status": "running",
"progress": 45.0,
"current": 9,
"total": 20,
"stage": "处理文件",
"message": "已处理: 产品手册.pdf",
"created_at": "2026-06-05T10:30:00",
"started_at": "2026-06-05T10:30:01"
}
],
"total": 1
}
}
```
**GET /tasks/\<task_id\>/progress SSE 事件序列**
```
data: {"type": "start", "data": {"stage": "扫描文档"}}
data: {"type": "progress", "data": {"progress": 10.0, "current": 2, "total": 20, "stage": "处理文件", "message": "已处理: file1.pdf"}}
data: {"type": "progress", "data": {"progress": 25.0, "current": 5, "total": 20, "stage": "处理文件", "message": "已处理: file2.docx"}}
data: {"type": "complete", "data": {"task_id": "a1b2c3d4e5f6", "status": "completed", "result": {...}}}
```
> 心跳保活:每 1 秒发送 `: heartbeat`,防止连接超时。
**任务状态流转**
```
pending → running → completed
→ failed
```
---
### 2. 缓存管理接口
用于调试和监控 LRU 缓存与语义缓存的运行状态。
| 端点 | 方法 | 说明 |
|------|------|------|
| `/cache/stats` | GET | 获取所有缓存的命中统计 |
| `/cache/clear` | POST | 清空所有缓存 |
**GET /cache/stats 响应示例**
```json
{
"embedding_cache": {
"total_entries": 128,
"hits": 45,
"misses": 83,
"hit_rate": "35.16%",
"evictions": 0
},
"semantic_cache": {
"total_entries": 50,
"hits": 12,
"misses": 38,
"hit_rate": "24.00%"
},
"semantic_cache_intent": {
"total_entries": 30,
"hits": 8,
"misses": 22,
"hit_rate": "26.67%"
}
}
```
**POST /cache/clear 响应示例**
```json
{
"status": "ok",
"cleared": {
"lru_cache": "cleared",
"semantic_cache": "cleared"
}
}
```
---
### 3. 会话管理接口
需要 `ENABLE_SESSION=true` 配置项启用,使用 SQLite 存储会话历史。
| 端点 | 方法 | 说明 |
|------|------|------|
| `/sessions` | GET | 获取当前用户的会话列表 |
| `/history/<session_id>` | GET | 获取指定会话的聊天历史 |
| `/session/<session_id>` | DELETE | 删除指定会话 |
| `/clear/<session_id>` | POST | 清空指定会话的历史(保留会话) |
> **注意**:这些端点在 `ENABLE_SESSION=false`(生产模式默认值)时不注册,返回 404。
**GET /sessions 响应示例**
```json
{
"success": true,
"status": "success",
"status_code": 2000,
"data": {
"sessions": [
{
"session_id": "abc-123-def",
"created_at": "2026-06-05T10:30:00",
"last_active": "2026-06-05T11:00:00",
"preview": "用户最后一条消息的前50字..."
}
]
}
}
```
**GET /history/\<session_id\> 响应示例**
```json
{
"success": true,
"status": "success",
"status_code": 2000,
"data": {
"history": [
{"role": "user", "content": "你好", "created_at": "2026-06-05T10:30:00"},
{"role": "assistant", "content": "你好!有什么可以帮你的?", "created_at": "2026-06-05T10:30:01"}
]
}
}
```
---
### 4. 审计日志接口
需要 `ENABLE_SESSION=true` 配置项启用,查询用户操作审计记录。
| 端点 | 方法 | 说明 |
|------|------|------|
| `/audit/logs` | GET | 查询审计日志(管理员) |
**GET /audit/logs 请求参数**
| 参数 | 类型 | 必需 | 说明 |
|------|------|------|------|
| `limit` | int | ❌ | 返回条数(默认 50 |
| `days` | int | ❌ | 查询天数范围(默认 7 |
| `action` | string | ❌ | 按操作类型过滤 |
**响应示例**
```json
{
"success": true,
"status": "success",
"status_code": 2000,
"data": {
"logs": [
{
"id": 1,
"user_id": "admin001",
"username": "admin",
"action": "rag_query",
"query": "三峡工程",
"result_summary": "...",
"role": "admin",
"department": "管理部",
"ip_address": "127.0.0.1",
"duration_ms": 1234,
"timestamp": "2026-06-05T12:00:00"
}
],
"total": 100
}
}
```
---
### 5. 系统统计接口
| 端点 | 方法 | 说明 |
|------|------|------|
| `/stats` | GET | 获取系统综合统计 |
> **server-release 上此端点返回 500**`KeyError: 'SESSION_MANAGER'`因为会话管理器未初始化。main 分支在 `ENABLE_SESSION=true` 时正常工作。
---
## 二、已有端点的行为与内部逻辑差异
以下端点在 main 和 server-release 上 URL 相同,但**行为或内部逻辑有显著差异**。
### 1. 全面异步化
server-release 上为同步阻塞的操作,在 main 分支改为异步执行并返回 `task_id`
| 端点 | server-release 行为 | main 行为 |
|------|---------------------|-----------|
| `POST /documents/upload` | 同步保存+向量化,直接返回结果 | 同步保存,异步向量化,返回 `task_id` |
| `POST /documents/batch-upload` | 同步保存+向量化,直接返回结果 | 同步保存,异步向量化,返回 `task_id` |
| `POST /sync` | 同步阻塞直到完成 | 异步执行,立即返回 `task_id` |
| `POST /collections/<kb>/reindex` | 同步阻塞直到完成 | 异步执行,立即返回 `task_id` |
| `POST /exam/generate` | 同步阻塞30-60s | 异步执行,立即返回 `task_id` |
| `POST /exam/generate-smart` | 同步阻塞30-60s | 异步执行,立即返回 `task_id` |
| `POST /exam/grade` | 同步阻塞 | 异步执行,立即返回 `task_id` |
**main 分支上传响应示例**(对比 server-release
```json
{
"success": true,
"status": "success",
"status_code": 2002,
"message": "文件上传成功,已保存,向量化任务已启动",
"data": {
"file": {
"filename": "test.txt",
"collection": "public_kb",
"path": "public_kb/test.txt",
"size": 18,
"replaced": false
},
"sync_status": "已保存,向量化任务已启动",
"task_id": "a1b2c3d4e5f6"
}
}
```
> **新增字段**`task_id`(用于轮询进度)、`replaced`(是否为覆盖旧文件)。
> server-release 上这两个字段不存在。
**后端调用流程变更**
```
server-release: POST /upload → 等待 → 200 OK文件已处理
main: POST /upload → 立即 200 OKtask_id→ GET /tasks/<id> 轮询直到 completed
```
### 2. RAG 问答增强(不涉及端口变化)
`POST /rag` 端点在两个分支上 URL 和响应格式一致,但**内部管道逻辑**有差异。
**两个分支共有的能力engine.py 层,已同步)**
| 能力 | 说明 |
|------|------|
| Embedding 缓存 | `_encode_cached()` LRU 缓存,减少重复编码 |
| 表格邻居上下文扩展 | 表格切片自动扩展相邻文本上下文 |
| MMR 去重 | 文本相似度去重,减少冗余切片 |
| 子查询分解 | 复杂查询拆分为子查询提升召回 |
| 图片 P0 独立召回 | 图片切片独立通道检索 |
| 引用去重 | chunk_id 保序去重 |
**main 独有的增强chat_routes.py 层)**
| 能力 | 说明 | 涉及函数 |
|------|------|----------|
| 语义缓存闭环 | 相似问题命中缓存直接返回,跳过检索和生成 | 集成在 RAG 管道主流程中 |
| 表格救援 | 被预算截断的表格切片补回上下文 | `_rescue_table_chunks()` |
| 语义前缀精简 | 精简表格切片冗余语义前缀,保留章节标识 | `_strip_semantic_prefix()` |
| 层级章节相似度 | 数值精确匹配 + Jaccard 层级系数,用于图片/表格章节过滤 | `_section_similarity()` |
| 图片后置过滤 | 基于 LLM 回答关键词反向筛选图片 | `_filter_images_by_answer()` |
**server-release 独有的增强agentic*.py 模块化层)**
| 能力 | 说明 | 所在模块 |
|------|------|----------|
| 查询改写 | 口语→专业术语映射、实体补全、LLM 深度重写、图片指代识别 | `agentic_query.py` QueryRewriteMixin |
| 上下文压缩 | rerank 过滤、token 截断、去重 | `agentic_context.py` ContextMixin |
| 质量评估 | 置信度门控、答案反思 | `agentic_quality.py` QualityMixin |
| 受限文档检查 | 权限级别感知的文档过滤 | `engine.py` check_restricted_documents() |
> **总结**两个分支在引擎层engine.py的检索能力基本一致。差异在于上层管道编排——main 在 chat_routes.py 中增加了表格救援、语义缓存等管道函数server-release 则通过 AgenticRAG 模块化系统实现了查询改写、上下文压缩等能力。这些差异不影响 API 端口定义。
### 3. 认证增强
| 端点 | 变更说明 |
|------|----------|
| `POST /auth/login` | 新增 IP 速率限制(频繁登录返回 HTTP 429 |
| `POST /auth/change-password` | 新增旧密码验证server-release 不验证旧密码) |
---
## 三、全局响应格式变更
main 分支将所有端点的响应统一为 `success_response()` / `error_response()` 封装格式。
**server-release 响应格式**(部分端点使用原始 jsonify
```json
{
"contexts": ["..."],
"metadatas": [...],
"scores": [0.99]
}
```
**main 分支响应格式**(统一封装):
```json
{
"success": true,
"status": "success",
"status_code": 2000,
"message": "查询成功",
"data": {
"contexts": ["..."],
"metadatas": [...],
"scores": [0.99]
}
}
```
> **⚠️ Breaking Change**:如果后端直接读取响应顶层字段(如 `response.contexts`),迁移到 main 后需要改为 `response.data.contexts`。建议后端统一使用 `response.data` 访问实际数据。
---
## 四、新增状态码
| 状态码 | 常量名 | 说明 |
|--------|--------|------|
| 4014 | `TASK_NOT_FOUND` | 任务不存在 |
| 4015 | `TASK_CONFLICT` | 任务冲突(如重复触发同步) |
| 5040 | `REINDEX_ERROR` | 重建索引失败 |
---
## 五、架构差异总结
| 维度 | server-release | main |
|------|----------------|------|
| 长操作模式 | 同步阻塞 | 异步任务 + task_id 轮询 |
| 响应格式 | 混合jsonify + success_response | 统一 success_response 封装 |
| RAG 引擎层 | 相同engine.py 已同步) | 相同 |
| RAG 管道层 | AgenticRAG 模块化编排(查询改写/上下文压缩/质量评估) | chat_routes.py 单体管道(语义缓存/表格救援/图片过滤) |
| 会话管理 | 无状态 | SQLite 会话存储(可选) |
| 审计日志 | 无 | 操作审计记录 |
| 缓存系统 | LRU语义缓存已初始化但未接入流程 | LRU + 语义缓存(完整闭环) |
| 认证安全 | 基础 | IP 速率限制 + 旧密码验证 |
| 核心架构 | AgenticRAG 多模块 + engine.py | 统一 engine.py + chat_routes.py 管道 |
---
## 六、迁移注意事项
如果后续需要将 main 分支部署到服务器,需要注意:
1. **后端适配**:后端组需要修改调用方式,从同步等待结果改为轮询 `GET /tasks/<task_id>`。建议轮询间隔 1-2 秒。
2. **响应格式**:所有接口响应统一为 `{success, status, status_code, message, data}` 格式,前端/后端需要从 `data` 字段读取实际数据。
3. **配置项**:新增 `ENABLE_SESSION``ENABLE_FEEDBACK` 等开关,需要确认生产环境配置。
4. **RAG 管道差异**main 和 server-release 的 RAG 增强方向不同main 侧重语义缓存/表格救援server-release 侧重模块化查询改写/上下文压缩),但不影响 API 端口兼容性。迁移时两者的检索效果可能略有差异,需要做效果对比测试。
5. **兼容性**:如果暂不迁移后端,可以只在 main 分支上保持同步模式(通过环境变量开关),避免 breaking change。