- main.py: 去掉 emoji 避免 GBK 编码崩溃 - docs/curl测试手册.md: 更新模型名和测试日期 - docs/代码审查报告_2026-06-05.md: 删除过期报告 - docs/main分支独有功能说明.md: 新增 - docs/出题系统逻辑.md: 新增
391 lines
13 KiB
Markdown
391 lines
13 KiB
Markdown
# 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 OK(task_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。
|