- main.py: 去掉 emoji 避免 GBK 编码崩溃 - docs/curl测试手册.md: 更新模型名和测试日期 - docs/代码审查报告_2026-06-05.md: 删除过期报告 - docs/main分支独有功能说明.md: 新增 - docs/出题系统逻辑.md: 新增
13 KiB
main 分支独有功能与端点说明
本文档记录
main分支(本地最新版本)相对于server-release(生产服务器版本)的独有功能和端点差异。更新日期:2026-06-10 | 对比基准:
origin/server-release(commit15c0aec) vsmain(commitedaef7a)
一、新增端点(仅 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 响应示例:
{
"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 响应示例:
{
"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 响应示例:
{
"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 响应示例:
{
"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> 响应示例:
{
"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 | ❌ | 按操作类型过滤 |
响应示例:
{
"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):
{
"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):
{
"contexts": ["..."],
"metadatas": [...],
"scores": [0.99]
}
main 分支响应格式(统一封装):
{
"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 分支部署到服务器,需要注意:
-
后端适配:后端组需要修改调用方式,从同步等待结果改为轮询
GET /tasks/<task_id>。建议轮询间隔 1-2 秒。 -
响应格式:所有接口响应统一为
{success, status, status_code, message, data}格式,前端/后端需要从data字段读取实际数据。 -
配置项:新增
ENABLE_SESSION、ENABLE_FEEDBACK等开关,需要确认生产环境配置。 -
RAG 管道差异:main 和 server-release 的 RAG 增强方向不同(main 侧重语义缓存/表格救援,server-release 侧重模块化查询改写/上下文压缩),但不影响 API 端口兼容性。迁移时两者的检索效果可能略有差异,需要做效果对比测试。
-
兼容性:如果暂不迁移后端,可以只在 main 分支上保持同步模式(通过环境变量开关),避免 breaking change。