- main.py: 去掉 emoji 避免 GBK 编码崩溃 - docs/curl测试手册.md: 更新模型名和测试日期 - docs/代码审查报告_2026-06-05.md: 删除过期报告 - docs/main分支独有功能说明.md: 新增 - docs/出题系统逻辑.md: 新增
51 KiB
RAG API curl 测试手册
基于
后端对接规范.md,所有 curl 命令均在生产模式 (APP_ENV=prod) 下验证通过。测试日期:2026-06-10(最近更新)| 生产服务器:
47.116.16.222| 服务地址:http://127.0.0.1:5001当前部署模型:
qwen-turbo(DashScope)| 嵌入模型:bge-base-zh-v1.5(本地 CPU)| Rerank:qwen3-rerank(DashScope 云端 API)
目录
- 1. 基础信息
- 2. 健康检查
- 3. 问答接口
- 4. 检索接口
- 5. 向量库管理
- 6. 文档管理
- 7. 切片管理
- 8. 同步服务
- 9. 反馈系统
- 10. FAQ 管理
- 11. 出题系统
- 12. 图片服务
- 13. 报告服务
- 14. 知识库路由
- 15. 异步任务查询
- 16. 认证系统
- 17. 其他端点
- 附录. 已知问题
1. 基础信息
认证方式
生产模式 (APP_ENV=prod) 下无需认证 Header,直接放行。用户信息使用默认值:
{"user_id": "backend-caller", "username": "后端调用", "role": "user", "department": ""}
中文编码注意
Windows bash 中 curl 传递中文 JSON 需使用文件方式:
# 方式一:使用临时文件(推荐)
echo '{"query":"中文内容"}' > /tmp/test.json
curl -s -X POST http://localhost:5001/search -H "Content-Type: application/json" -d @/tmp/test.json
# 方式二:英文可直接传递
curl -s -X POST http://localhost:5001/search -H "Content-Type: application/json" -d '{"query":"hello"}'
通用响应格式
所有接口返回 JSON,成功时 HTTP 200,错误时返回对应 HTTP 状态码。
2. 健康检查
GET /health
检查服务运行状态。
curl -s http://localhost:5001/health
响应示例:
{
"bm25_index": "动态按需加载",
"knowledge_base": "多向量库模式 (按集合提供服务)",
"mode": "Agentic RAG",
"status": "ok"
}
验证结果:✅ 通过
3. 问答接口
POST /rag
知识库问答(SSE 流式返回)。
echo '{"message":"三峡工程","chat_history":[]}' > /tmp/rag.json
curl -s -X POST http://localhost:5001/rag \
-H "Content-Type: application/json" \
-d @/tmp/rag.json
请求体:
| 字段 | 类型 | 必需 | 说明 |
|---|---|---|---|
message |
string | ✅ | 用户消息 |
chat_history |
array | ✅(生产模式) | 对话历史 |
collections |
string[] | ❌ | 知识库列表,默认 ["public_kb"] |
session_id |
string | ❌ | 会话 ID |
chat_history 格式:
[
{"role": "user", "content": "之前的问题"},
{"role": "assistant", "content": "之前的回答"}
]
SSE 事件序列:
data: {"type": "start", "message": "正在检索知识库..."}
data: {"type": "sources", "sources": [...]}
data: {"type": "chunk", "content": "每个token"}
data: {"type": "finish", "answer": "完整回答[ref:chunk_id]", "sources": [...], "citations": [...]}
finish 事件中 citations 结构(引用溯源,用于前端跳转定位):
{
"citations": [
{
"chunk_id": "3.docx_33",
"chunk_index": 33,
"source": "3.docx",
"collection": "public_kb",
"doc_type": "word",
"section": "第五篇 投入管理 > 一、零售终端建设投入标准",
"preview": "内容摘要...",
"content": "切片内容(截断 300 字)",
"chunk_type": "text",
"page": null,
"page_end": null
}
]
}
| citations 字段 | 说明 |
|---|---|
chunk_id |
切片唯一标识,格式 {文件名}_{序号} |
chunk_index |
全局切片序号(从 chunk_id 提取),用于文档预览跳转 |
source |
来源文件名 |
collection |
所属向量库名称,用于定位文档所在知识库 |
doc_type |
文档类型:pdf、word、excel |
section |
章节路径(已清洗,过滤掉正文内容) |
page / page_end |
页码(仅 PDF) |
bbox / bbox_mode |
坐标定位(仅 PDF) |
section_chunk_id |
章节内段落序号(仅 Word) |
带 collections 参数:
echo '{"message":"三峡工程","chat_history":[],"collections":["public_kb"]}' > /tmp/rag.json
curl -s -X POST http://localhost:5001/rag \
-H "Content-Type: application/json" \
-d @/tmp/rag.json
⚠️ 重要:指定知识库必须使用
collections数组参数(如["dept_tech"]),而非collection单数参数。 使用单数collection参数会被忽略,导致默认检索public_kb。
多向量库同时查询:
# 同时检索多个知识库
echo '{"message":"信息安全","collections":["dept_tech","public_kb"],"chat_history":[]}' > /tmp/rag.json
curl -s -X POST http://localhost:5001/rag \
-H "Content-Type: application/json" \
-d @/tmp/rag.json
验证结果:✅ 通过
POST /chat
普通聊天模式(非知识库)。
echo '{"message":"你好","chat_history":[]}' > /tmp/chat.json
curl -s -X POST http://localhost:5001/chat \
-H "Content-Type: application/json" \
-d @/tmp/chat.json
请求体:
| 字段 | 类型 | 必需 | 说明 |
|---|---|---|---|
message |
string | ✅ | 用户消息 |
chat_history |
array | ❌ | 对话历史 |
响应示例:
{
"answer": "你好!很高兴见到你~",
"mode": "chat",
"sources": [],
"web_searched": false
}
验证结果:✅ 通过
4. 检索接口
POST /search
混合检索(向量 + BM25),供 Dify 工作流调用。
echo '{"query":"三峡工程","top_k":3}' > /tmp/search.json
curl -s -X POST http://localhost:5001/search \
-H "Content-Type: application/json" \
-d @/tmp/search.json
请求体:
| 字段 | 类型 | 必需 | 说明 |
|---|---|---|---|
query |
string | ✅ | 查询文本 |
top_k |
int | ❌ | 返回数量,默认 5 |
collections |
string[] | ❌ | 知识库列表,默认 ["public_kb"] |
响应示例:
{
"contexts": ["综述\n三峡工程是国之重器..."],
"metadatas": [
{
"_collection": "public_kb",
"chunk_id": "三峡公报_1-15页.pdf_text_8",
"chunk_type": "text",
"collection": "public_kb",
"doc_type": "pdf",
"page": 5,
"page_end": 6,
"section": "三峡工程公报 > 综述",
"source": "三峡公报_1-15页.pdf",
"status": "active",
"version": "v1"
}
],
"scores": [0.9975]
}
scores 说明:相似度分数,范围 0-1,越高越相关(已从距离转换)。
验证结果:✅ 通过
5. 向量库管理
GET /collections
获取向量库列表。
curl -s http://localhost:5001/collections
响应示例:
{
"collections": [
{
"created_at": "2026-06-02T21:35:43.839864",
"department": "",
"description": "所有人可访问的公开文档",
"display_name": "公开知识库",
"document_count": 824,
"name": "public_kb"
},
{
"created_at": "2026-06-04T06:15:52.556940",
"department": "",
"description": "",
"display_name": "dept_1_kb",
"document_count": 500,
"name": "dept_1_kb"
},
{
"created_at": "2026-06-10T03:04:20.619279",
"department": "",
"description": "",
"display_name": "resources",
"document_count": 0,
"name": "resources"
}
],
"total": 3
}
验证结果:✅ 通过
POST /collections
创建新向量库。
echo '{"name":"test_kb","display_name":"测试库","department":"测试部","description":"测试描述"}' > /tmp/create.json
curl -s -X POST http://localhost:5001/collections \
-H "Content-Type: application/json" \
-d @/tmp/create.json
请求体:
| 字段 | 类型 | 必需 | 说明 |
|---|---|---|---|
name |
string | ✅ | 向量库名称(字母、数字、下划线、连字符) |
display_name |
string | ❌ | 显示名称 |
department |
string | ❌ | 所属部门 |
description |
string | ❌ | 描述 |
响应示例:
{
"message": "向量库 'test_kb' 创建成功",
"name": "test_kb",
"success": true
}
验证结果:✅ 通过
PUT /collections/<name>
修改向量库信息。
echo '{"display_name":"新名称","description":"新描述"}' > /tmp/update.json
curl -s -X PUT http://localhost:5001/collections/test_kb \
-H "Content-Type: application/json" \
-d @/tmp/update.json
请求体:
| 字段 | 类型 | 必需 | 说明 |
|---|---|---|---|
display_name |
string | ❌ | 显示名称 |
description |
string | ❌ | 描述 |
验证结果:✅ 通过
DELETE /collections/<name>
删除向量库。
curl -s -X DELETE http://localhost:5001/collections/test_kb
查询参数:
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
delete_documents |
boolean | ❌ | 是否删除文档源文件,默认 false |
带参数示例:
curl -s -X DELETE "http://localhost:5001/collections/test_kb?delete_documents=true"
验证结果:✅ 通过
GET /collections/<kb_name>/documents
获取向量库内的文档列表。
curl -s "http://localhost:5001/collections/public_kb/documents"
响应示例:
{
"collection": "public_kb",
"documents": [
{
"chunks": 69,
"source": "3.txt"
},
{
"chunks": 12,
"source": "1.txt"
}
],
"total": 10
}
验证结果:✅ 通过
GET /collections/<kb_name>/chunks
获取向量库切片列表。
curl -s "http://localhost:5001/collections/public_kb/chunks?limit=2&offset=0"
查询参数:
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
document_id |
string | ❌ | 过滤指定文档的切片 |
limit |
int | ❌ | 返回数量,默认 100 |
offset |
int | ❌ | 偏移量,默认 0 |
响应示例:
{
"collection": "public_kb",
"chunks": [
{
"id": "三峡公报_1-15页.pdf_text_0",
"document": "三峡公报_1-15页.pdf",
"content": "切片内容...",
"metadata": {
"chunk_id": "三峡公报_1-15页.pdf_text_0",
"chunk_type": "text",
"collection": "public_kb",
"page": 1,
"source": "三峡公报_1-15页.pdf",
"status": "active",
"version": "v1"
},
"score": null
}
],
"total": 150
}
验证结果:✅ 通过
GET /collections/<kb_name>/documents/<filename>/versions
获取文档版本历史。
# URL 编码文件名中的特殊字符
curl -s "http://localhost:5001/collections/public_kb/documents/%E4%B8%89%E5%B3%A1%E5%85%AC%E6%8A%A5_1-15%E9%A1%B5.pdf/versions?limit=5"
查询参数:
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
limit |
int | ❌ | 返回数量,默认 10 |
响应示例:
{
"success": true,
"document_id": "三峡公报_1-15页.pdf",
"collection": "public_kb",
"versions": [
{
"version": "v1",
"status": "active",
"effective_date": "2026-04-14T21:03:06",
"deprecated_date": null,
"chunk_count": 120
}
],
"total": 1
}
验证结果:✅ 通过
POST /collections/<kb_name>/update-image-descriptions
更新图片切片描述(重新生成)。
curl -s -X POST "http://localhost:5001/collections/public_kb/update-image-descriptions"
响应示例:
{
"success": true,
"message": "图片描述更新完成",
"updated": 5
}
验证结果:✅ 通过
6. 文档管理
GET /documents/list
获取文档列表。
curl -s "http://localhost:5001/documents/list?collection=public_kb"
查询参数:
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
collection |
string | ❌ | 知识库名称(也可用 kb_name),默认返回全部 |
注意:该接口不支持分页,返回指定知识库的全部文档列表。
响应示例:
{
"documents": [
{
"collection": "public_kb",
"filename": "三峡公报_1-15页.pdf",
"last_modified": "2026-04-14T21:03:06",
"path": "public_kb/三峡公报_1-15页.pdf",
"size": 2773520
}
],
"total": 8
}
验证结果:✅ 通过
GET /documents/<path>/status
获取文档处理状态。
# URL 编码路径中的斜杠
curl -s "http://localhost:5001/documents/public_kb%2Ftest.txt/status"
响应示例:
{
"success": true,
"status": "active",
"chunk_count": 105,
"last_processed": null
}
验证结果:✅ 通过
POST /documents/upload
上传单个文件。
echo "测试文档内容" > /tmp/test.txt
curl -s -X POST http://localhost:5001/documents/upload \
-F "file=@/tmp/test.txt" \
-F "collection=public_kb"
表单字段:
| 字段 | 类型 | 必需 | 说明 |
|---|---|---|---|
file |
file | ✅ | 上传文件 |
collection |
string | ✅ | 目标知识库(也可用 kb_name) |
响应示例:
{
"success": true,
"status": "success",
"status_code": 2002,
"message": "文件上传成功,已保存并添加到向量库",
"data": {
"file": {
"filename": "test.txt",
"collection": "public_kb",
"path": "public_kb/test.txt",
"size": 18
},
"sync_status": "已保存并添加到向量库"
}
}
说明:文件保存和向量化均为同步操作,响应时文件已处理完成。不包含
task_id字段(异步任务系统仅 main 分支可用)。同名文件处理:上传同名文件时,旧版本的切片会被自动清理后覆盖,不会生成时间戳后缀文件。
验证结果:✅ 通过
POST /documents/batch-upload
批量上传文件。
echo "文件1内容" > /tmp/file1.txt
echo "文件2内容" > /tmp/file2.txt
curl -s -X POST http://localhost:5001/documents/batch-upload \
-F "files=@/tmp/file1.txt" \
-F "files=@/tmp/file2.txt" \
-F "collection=public_kb"
响应示例:
{
"success": true,
"status": "success",
"status_code": 2003,
"message": "批量上传完成,成功 2/2 个文件",
"data": {
"total": 2,
"success_count": 2,
"results": [
{"filename": "file1.txt", "path": "public_kb/file1.txt", "status": "success"},
{"filename": "file2.txt", "path": "public_kb/file2.txt", "status": "success"}
]
}
}
说明:批量上传为同步操作,响应时所有文件已处理完成。不包含
task_id字段(异步任务系统仅 main 分支可用)。同名文件处理:与单文件上传相同,批量上传中遇到同名文件也会自动覆盖旧版本。
验证结果:✅ 通过
PUT /documents/<path>
更新/替换文档。
echo "更新后的文档内容" > /tmp/updated.txt
curl -s -X PUT "http://localhost:5001/documents/public_kb%2Ftest.txt" \
-F "file=@/tmp/updated.txt"
表单字段:
| 字段 | 类型 | 必需 | 说明 |
|---|---|---|---|
file |
file | ✅ | 替换的文件 |
响应示例:
{
"success": true,
"message": "文件已更新"
}
验证结果:✅ 通过
DELETE /documents/<path>
删除文档。
# URL 编码路径中的斜杠
curl -s -X DELETE "http://localhost:5001/documents/public_kb%2Ftest.txt"
响应示例:
{
"message": "文档已删除",
"success": true
}
验证结果:✅ 通过
POST /collections/<kb_name>/documents/<filename>/deprecate
废弃文档版本。
curl -s -X POST "http://localhost:5001/collections/public_kb/documents/test.txt/deprecate"
验证结果:✅ 通过(接口存在)
POST /collections/<kb_name>/documents/<filename>/restore
恢复文档版本。
curl -s -X POST "http://localhost:5001/collections/public_kb/documents/test.txt/restore"
验证结果:✅ 通过(接口存在)
🛠️ DEV GET /documents/<path>/preview
开发环境自用接口,后端组无需调用。 仅供 dev-ui 内部前端实现引用溯源跳转使用。后端组可根据
/rag返回的citations中的chunk_index、page、bbox等字段自行实现文档定位。
文档预览(支持按切片序号跳转),用于引用溯源点击后定位到文档中的具体位置。
# 跳转到指定切片(前后各取 2 个上下文切片)
curl -s "http://localhost:5001/documents/public_kb%2F1.docx/preview?chunk_index=33&context=2"
# 不指定 chunk_index,返回前 5 个切片作为概览
curl -s "http://localhost:5001/documents/public_kb%2F1.docx/preview"
查询参数:
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
chunk_index |
int | ✅ | 目标切片序号(来自 citations 的 chunk_index 字段) |
context |
int | ✅ | 上下文切片数,默认 2(前后各取 2 个) |
响应示例:
{
"success": true,
"collection": "public_kb",
"source": "1.docx",
"total_chunks": 105,
"target_index": 33,
"chunks": [
{"id": "1.docx_31", "content": "...", "metadata": {...}, "is_target": false},
{"id": "1.docx_32", "content": "...", "metadata": {...}, "is_target": false},
{"id": "1.docx_33", "content": "...", "metadata": {...}, "is_target": true},
{"id": "1.docx_34", "content": "...", "metadata": {...}, "is_target": false},
{"id": "1.docx_35", "content": "...", "metadata": {...}, "is_target": false}
]
}
说明:
is_target: true的切片即为引用定位目标,前端可高亮显示并滚动到该位置。
7. 切片管理
GET /documents/<path>/chunks
获取文档切片列表。
# URL 编码路径
curl -s "http://localhost:5001/documents/dept_hr%2F%E4%BA%BA%E5%91%98%E5%90%8D%E5%86%8C.txt/chunks"
注意:该接口不支持分页或过滤参数,返回指定文档的全部切片。
响应示例:
{
"chunks": [
{
"document": "# 智启科技有限公司人员名册\n\n**更新日期**:2024年6月...",
"id": "人员名册.txt_text_0",
"metadata": {
"chunk_id": "人员名册.txt_text_0",
"chunk_index": 0,
"chunk_type": "text",
"collection": "dept_hr",
"doc_type": "other",
"page": 1,
"page_end": 1,
"preview": "# 智启科技有限公司人员名册...",
"section": "人员名册",
"source": "人员名册.txt",
"has_table": false,
"status": "active",
"version": "v1"
},
"status": "active",
"version": "v1"
}
],
"collection": "dept_hr",
"document_id": "dept_hr/人员名册.txt",
"success": true,
"total": 4
}
切片字段说明:
| 字段 | 说明 |
|---|---|
id / chunk_id |
切片唯一标识,格式:{文件名}_{类型}_{序号} |
document |
切片完整内容(重要:用于增删改查) |
chunk_type |
切片类型:text(文本)、table(表格)、image(图片) |
source |
来源文件名 |
page / page_end |
起止页码 |
section |
所属章节路径 |
preview |
内容预览(截断版,用于列表展示) |
has_table |
是否包含表格 |
验证结果:✅ 通过
POST /chunks
新增切片。
echo '{"collection":"public_kb","content":"测试切片内容","metadata":{"section":"测试章节"}}' > /tmp/chunk.json
curl -s -X POST http://localhost:5001/chunks \
-H "Content-Type: application/json" \
-d @/tmp/chunk.json
请求体:
| 字段 | 类型 | 必需 | 说明 |
|---|---|---|---|
collection |
string | ✅ | 向量库名称 |
content |
string | ✅ | 切片内容 |
metadata |
object | ❌ | 元数据 |
验证结果:✅ 通过
PUT /chunks/<id>
修改切片。
echo '{"collection":"dept_hr","content":"更新后的内容"}' > /tmp/update_chunk.json
curl -s -X PUT "http://localhost:5001/chunks/人员名册.txt_text_0" \
-H "Content-Type: application/json" \
-d @/tmp/update_chunk.json
请求体:
| 字段 | 类型 | 必需 | 说明 |
|---|---|---|---|
collection |
string | ✅ | 向量库名称 |
content |
string | ❌ | 新内容 |
metadata |
object | ❌ | 新元数据 |
验证结果:✅ 通过
DELETE /chunks/<id>
删除切片。
curl -s -X DELETE "http://localhost:5001/chunks/人员名册.txt_text_0?collection=dept_hr"
查询参数:
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
collection |
string | ✅ | 向量库名称 |
验证结果:✅ 通过
8. 同步服务
POST /sync
触发文档同步(异步任务)。
curl -s -X POST http://localhost:5001/sync \
-H "Content-Type: application/json"
响应示例:
{
"success": true,
"status": "success",
"status_code": 2010,
"message": "同步完成",
"data": {
"result": {
"documents_processed": 20,
"documents_added": 3,
"documents_modified": 2,
"documents_deleted": 0,
"errors": []
}
}
}
说明:此接口为同步操作,请求会阻塞直到同步完成(可能需要较长时间)。响应中
data.result包含完整的同步结果。不包含task_id字段(异步任务系统仅 main 分支可用)。冲突检测:如果已有同步任务正在运行,返回 HTTP 409:
{"error": "TASK_RUNNING", "message": "同步任务正在执行中,请等待完成"}
验证结果:✅ 通过
GET /sync/status
获取同步状态。
curl -s http://localhost:5001/sync/status
响应示例:
{
"documents_tracked": 0,
"enabled": true,
"last_sync": null,
"monitoring": false
}
验证结果:✅ 通过
GET /sync/history
获取同步历史。
curl -s http://localhost:5001/sync/history
响应示例:
{
"history": []
}
验证结果:✅ 通过
GET /sync/changes
获取待同步变更。
curl -s http://localhost:5001/sync/changes
响应示例:
{
"changes": []
}
验证结果:✅ 通过
POST /sync/start
启动文件监控。
curl -s -X POST http://localhost:5001/sync/start
响应示例:
{
"message": "文件监控已启动",
"status": "success",
"status_code": 2010
}
验证结果:✅ 通过
POST /sync/stop
停止文件监控。
curl -s -X POST http://localhost:5001/sync/stop
响应示例:
{
"message": "文件监控已停止",
"status": "success",
"status_code": 2010
}
验证结果:✅ 通过
9. 反馈系统
POST /feedback
提交反馈。
echo '{"session_id":"test-session","query":"测试问题","answer":"测试回答","rating":1,"reason":"测试原因"}' > /tmp/feedback.json
curl -s -X POST http://localhost:5001/feedback \
-H "Content-Type: application/json" \
-d @/tmp/feedback.json
请求体:
| 字段 | 类型 | 必需 | 说明 |
|---|---|---|---|
session_id |
string | ✅ | 会话 ID |
query |
string | ✅ | 用户问题 |
answer |
string | ❌ | 系统回答(可为空) |
rating |
int | ✅ | 评分(1=赞,-1=踩) |
reason |
string | ❌ | 原因 |
响应示例:
{
"faq_suggested": true,
"feedback_id": 7,
"success": true,
"suggestion_id": 6
}
验证结果:✅ 通过
GET /feedback/list
获取反馈列表。
curl -s "http://localhost:5001/feedback/list?limit=5"
查询参数:
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
limit |
int | ❌ | 返回数量,默认 100 |
rating |
int | ❌ | 按评分过滤(1=赞,-1=踩) |
user_id |
string | ❌ | 按用户 ID 过滤 |
start_date |
string | ❌ | 起始日期 |
end_date |
string | ❌ | 结束日期 |
注意:该接口不支持
page/page_size分页,使用limit控制返回数量。
响应示例:
{
"feedbacks": [
{
"answer": "测试回答",
"created_at": "2026-05-04T01:45:35",
"id": 7,
"query": "测试问题",
"rating": 1,
"reason": "测试原因",
"session_id": "test-session",
"sources": [],
"user_id": ""
}
],
"success": true,
"total": 7
}
验证结果:✅ 通过
GET /feedback/stats
获取反馈统计。
curl -s http://localhost:5001/feedback/stats
响应示例:
{
"stats": {
"avg_rating": 1.0,
"negative_count": 0,
"positive_count": 8,
"satisfaction_rate": 100.0,
"total_feedback": 8
},
"success": true
}
验证结果:✅ 通过
GET /feedback/bad-cases
获取差评案例列表。
curl -s http://localhost:5001/feedback/bad-cases
响应示例:
{
"bad_cases": [],
"blacklisted_sources": [],
"success": true,
"suggestions": [
"补充到知识库(针对知识盲区)",
"添加到 Query Rewrite 规则(针对表达歧义)"
]
}
验证结果:✅ 通过
GET /feedback/blacklist
获取切片黑名单。
curl -s http://localhost:5001/feedback/blacklist
响应示例:
{
"blacklist": [],
"count": 0,
"success": true,
"usage": "在检索时过滤这些来源以提升回答质量"
}
验证结果:✅ 通过
10. FAQ 管理
GET /faq
获取 FAQ 列表。
curl -s "http://localhost:5001/faq?limit=5"
查询参数:
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
status |
string | ❌ | 按状态过滤(如 approved、draft) |
limit |
int | ❌ | 返回数量,默认 50 |
响应示例:
{
"faqs": [
{
"answer": "根据参考资料...",
"avg_rating": 1.0,
"created_at": "2026-04-19T11:27:15",
"frequency": 1,
"id": 1,
"question": "C类吸烟区域",
"source_documents": null,
"status": "approved",
"updated_at": "2026-04-19T11:27:15"
}
],
"success": true,
"total": 3
}
验证结果:✅ 通过
POST /faq
创建新 FAQ。
curl -s -X POST http://localhost:5001/faq \
-H "Content-Type: application/json" \
-d "{\"question\":\"FAQ question\",\"answer\":\"FAQ answer\"}"
请求体:
| 字段 | 类型 | 必需 | 说明 |
|---|---|---|---|
question |
string | ✅ | 问题内容 |
answer |
string | ✅ | 答案内容 |
响应示例:
{
"faq_id": 7,
"message": "FAQ已创建,请通过 /faq/<id>/approve 接口确认后生效",
"status": "draft",
"success": true
}
验证结果:✅ 通过
PUT /faq/<id>
修改 FAQ。
curl -s -X PUT "http://localhost:5001/faq/7" \
-H "Content-Type: application/json" \
-d "{\"question\":\"updated question\",\"answer\":\"updated answer\"}"
请求体:
| 字段 | 类型 | 必需 | 说明 |
|---|---|---|---|
question |
string | ❌ | 新问题内容 |
answer |
string | ❌ | 新答案内容 |
响应示例:
{
"message": "FAQ更新成功",
"success": true,
"sync_status": "skipped"
}
验证结果:✅ 通过
DELETE /faq/<id>
删除 FAQ。
curl -s -X DELETE "http://localhost:5001/faq/7"
响应示例:
{
"message": "FAQ删除成功",
"success": true
}
验证结果:✅ 通过
GET /faq/suggestions
获取 FAQ 建议列表。
curl -s "http://localhost:5001/faq/suggestions?status=pending&limit=5"
查询参数:
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
status |
string | ❌ | 按状态过滤,默认 pending |
limit |
int | ❌ | 返回数量,默认 50 |
响应示例:
{
"success": true,
"suggestions": [
{
"answer": "",
"avg_rating": 1.0,
"created_at": "2026-04-29T20:49:38",
"frequency": 2,
"id": 5,
"query": "test",
"status": "pending"
}
],
"total": 3
}
验证结果:✅ 通过
POST /faq/suggestions/<id>/approve
批准 FAQ 建议(需 admin 角色)。
curl -s -X POST "http://localhost:5001/faq/suggestions/6/approve" \
-H "Content-Type: application/json" \
-d '{}'
请求体(可选,用于修改答案):
{"answer": "管理员修改后的答案"}
注意:必须传递请求体(至少空对象 {}),否则返回 400 错误。
验证结果:✅ 通过
POST /faq/suggestions/<id>/reject
拒绝 FAQ 建议(需 admin 角色)。
curl -s -X POST "http://localhost:5001/faq/suggestions/6/reject" \
-H "Content-Type: application/json" \
-d '{}'
验证结果:✅ 通过
POST /faq/<id>/approve
直接批准 FAQ(非从建议列表)。
curl -s -X POST "http://localhost:5001/faq/1/approve" \
-H "Content-Type: application/json" \
-d '{}'
注意:此端点与
POST /faq/suggestions/<id>/approve不同,后者用于审批用户提交的 FAQ 建议。
验证结果:✅ 通过(路由存在)
11. 出题系统
出题架构说明(v2)
v2 重构后采用 4 阶段出题架构,确保题目质量和多样性:
| 阶段 | 说明 | 改进点 |
|---|---|---|
| Phase 1 | 文档结构分析 | 按章节分组,统计内容量 |
| Phase 2 | 知识点规划 | 全局唯一,避免跨章节重复 |
| Phase 3 | 精准出题 | 每个知识点单独检索,确保上下文充足 |
| Phase 4 | 质量校验 | 去重 + 数量校正,零重复率 |
支持的题型:
| 题型 key | 中文名 | answer 格式 |
|---|---|---|
single_choice |
单选题 | 单个选项字母(如 "B") |
multiple_choice |
多选题 | 选项字母列表(如 ["A","B"]) |
true_false |
判断题 | 布尔值或字符串(如 true/"true") |
fill_blank |
填空题 | 嵌套列表(如 "答案1"],["答案2") |
subjective |
简答题 | 参考答案字符串 |
GET /exam/health
出题服务健康检查。
curl -s http://localhost:5001/exam/health
响应示例:
{
"service": "exam-api",
"status": "ok",
"version": "2.0"
}
验证结果:✅ 通过
POST /exam/generate
生成考题(指定题型和数量)。
特点:
- 需要手动指定
question_types(每种题型的数量) - 适合有明确需求的场景(如"出 5 道单选题")
入参校验:
question_types中每个题型必须属于:single_choice,multiple_choice,true_false,fill_blank,subjective- 每种题型数量必须为非负整数
difficulty必须为 1-5 的整数- 总题数上限 20 道(所有题型数量之和不能超过 20)
- 校验失败返回 HTTP 400,error_code 为
INVALID_PARAMS
curl -s -X POST http://localhost:5001/exam/generate \
-H "Content-Type: application/json" \
-d '{"file_path":"public_kb/1.docx","collection":"public_kb","question_types":{"single_choice":5,"true_false":3,"fill_blank":2}}'
请求体:
| 字段 | 类型 | 必需 | 说明 |
|---|---|---|---|
file_path |
string | ✅ | 文档路径(格式:collection/filename) |
collection |
string 或 string[] | ✅ | 知识库名称,支持数组(按优先级排序) |
question_types |
object | ✅ | 题型数量配置 |
difficulty |
int | ❌ | 难度等级(1-5),默认 3 |
options |
object | ❌ | 附加选项(如 max_source_chunks) |
request_id |
string | ❌ | 请求 ID(幂等性) |
exclude_stems |
string[] | ❌ | 已有题目题干列表(跨调用去重,最多 100 条) |
注意:生产模式(
DEV_MODE=false)下无需传Authorizationheader,直接放行。开发模式下可传Authorization: Bearer mock-token-admin模拟管理员身份。
question_types 配置示例:
{
"single_choice": 5,
"multiple_choice": 2,
"true_false": 3,
"fill_blank": 2,
"subjective": 1
}
响应示例:
{
"success": true,
"status": "success",
"status_code": 2020,
"message": "出题成功",
"data": {
"questions": [
{
"content": {
"stem": "重购率的定义是下列哪一项?",
"answer": "B",
"data": {
"options": [
{"content": "选项A内容", "key": "A"},
{"content": "品规连续两周订货客户数/上周订货客户数*100%", "key": "B"}
]
},
"explanation": "重购率的定义是..."
},
"difficulty": 3,
"question_type": "single_choice",
"source_trace": {
"chunk_ids": ["1.docx_76"],
"document_name": "public_kb/1.docx",
"page_numbers": [1],
"sources": [...]
}
}
],
"request_id": null,
"source_chunks_used": 15,
"success": true,
"total": 10,
"requested_types": {"single_choice": 5, "true_false": 3, "fill_blank": 2},
"actual_types": {"single_choice": 5, "true_false": 3, "fill_blank": 2},
"warnings": []
}
}
说明:此接口为同步操作,请求会阻塞直到出题完成(通常需要 30-60 秒)。响应中
data直接包含完整出题结果。不包含task_id字段(异步任务系统仅 main 分支可用)。注意:
warnings字段在某题型实际生成数量少于请求数量时返回提示信息。
验证结果:✅ 通过(2026-06-05)
POST /exam/generate-smart
AI 智能出题 - 自动分析文件并决定题型和数量。
特点:
- 不需要传
question_types,AI 自动分析文档后决定 - 返回格式与旧端口完全兼容,额外包含
ai_analysis字段 - 适合不想费脑子的场景
curl -s -X POST http://localhost:5001/exam/generate-smart \
-H "Content-Type: application/json" \
-d '{"file_path":"public_kb/1.docx","collection":"public_kb"}'
请求体:
| 字段 | 类型 | 必需 | 说明 |
|---|---|---|---|
file_path |
string | ✅ | 文档路径(格式:collection/filename) |
collection |
string 或 string[] | ✅ | 知识库名称,支持数组(按优先级排序) |
difficulty |
int | ❌ | 难度等级(1-5),默认 3 |
options |
object | ❌ | 附加选项 |
响应示例:
{
"success": true,
"status": "success",
"status_code": 2020,
"message": "AI 智能出题成功",
"data": {
"ai_analysis": {
"total_knowledge_points": 21,
"suitable_types": ["single_choice", "multiple_choice", "true_false", "subjective"],
"question_types": {
"single_choice": 8,
"multiple_choice": 6,
"true_false": 4,
"fill_blank": 0,
"subjective": 3
},
"reason": "文档包含21个知识点,涵盖术语定义、流程步骤、数值标准..."
},
"questions": [...],
"request_id": null,
"source_chunks_used": 15,
"success": true,
"total": 16
}
}
说明:此接口为同步操作,请求会阻塞直到出题完成。响应中
data直接包含完整出题结果(含ai_analysis字段)。不包含task_id字段(异步任务系统仅 main 分支可用)。
注意事项:
- 实际出题数量 ≤ min(文档知识点数, AI 推荐数量)
- 如果文档知识点较少,生成的题目数量会相应减少
- 生产模式下无需传
Authorizationheader
支持的题型:
| 题型 key | 中文名 | 说明 |
|---|---|---|
single_choice |
单选题 | content.answer 为单个选项字母 |
multiple_choice |
多选题 | content.answer 为选项字母列表 |
true_false |
判断题 | content.answer 为布尔值或字符串 |
fill_blank |
填空题 | content.answer 为嵌套列表 |
subjective |
简答题 | content.answer 为参考答案 |
验证结果:✅ 通过
POST /exam/grade
批阅答案。
echo '{"answers":[{"question_id":"q1","question_type":"single_choice","content":{"answer":"B"},"student_answer":"B","max_score":2}]}' > /tmp/grade.json
curl -s -X POST http://localhost:5001/exam/grade \
-H "Content-Type: application/json" \
-d @/tmp/grade.json
请求体:
| 字段 | 类型 | 必需 | 说明 |
|---|---|---|---|
answers |
array | ✅ | 答案数组 |
answers 数组元素:
| 字段 | 类型 | 必需 | 说明 |
|---|---|---|---|
question_id |
string | ✅ | 题目 ID |
question_type |
string | ✅ | 题型 |
content |
object | ✅ | 题目内容(与出题接口返回的 content 字段结构一致,后端可直接透传) |
student_answer |
string/array | ✅ | 学生答案 |
max_score |
int | ✅ | 满分 |
注意:
question_type必须为以下值之一:single_choice,multiple_choice,true_false,fill_blank,subjective。传入无效类型返回 HTTP 400。
响应示例:
{
"success": true,
"status": "success",
"status_code": 2021,
"message": "批阅完成",
"data": {
"request_id": null,
"results": [
{
"question_id": "q1",
"score": 2,
"max_score": 2,
"grading_status": "success",
"details": {
"correct": true,
"student_answer": "B",
"correct_answer": "B",
"feedback": "正确!"
}
}
],
"score_rate": 100.0,
"success": true,
"total_max_score": 2,
"total_score": 2
}
}
说明:此接口为同步操作,响应中
data直接包含完整批阅结果。不包含task_id字段(异步任务系统仅 main 分支可用)。
grading_status 取值说明:
success:评分成功failed:评分失败(主观题 LLM 解析失败或超时),此时details包含error字段
注意:当主观题缺少
scoring_points评分标准时,details.warnings会包含警告信息,评分结果仅供参考。
验证结果:✅ 通过(2026-06-05)
12. 图片服务
GET /images/list
获取图片列表。
curl -s "http://localhost:5001/images/list?limit=5&offset=0"
查询参数:
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
limit |
int | ❌ | 返回数量,默认 50 |
offset |
int | ❌ | 偏移量,默认 0 |
响应示例:
{
"images": [
{
"image_id": "0569dd285537",
"size_bytes": 169818,
"url": "/images/0569dd285537"
}
],
"limit": 5,
"offset": 0,
"total": 67
}
验证结果:✅ 通过
GET /images/<id>
获取单张图片。
curl -s -o image.jpg http://localhost:5001/images/0569dd285537
响应:返回图片文件(HTTP 200)
验证结果:✅ 通过
GET /images/<id>/info
获取图片元数据。
curl -s "http://localhost:5001/images/0569dd285537/info"
响应示例:
{
"format": "JPEG",
"height": 1357,
"image_id": "0569dd285537",
"mode": "RGB",
"size_bytes": 169818,
"url": "/images/0569dd285537",
"width": 1023
}
验证结果:✅ 通过
GET /images/stats
获取图片统计。
curl -s http://localhost:5001/images/stats
响应示例:
{
"format_counts": {
".jpg": 46,
".png": 21
},
"supported_formats": [".jpeg", ".gif", ".bmp", ".jpg", ".webp", ".png"],
"total_images": 67,
"total_size_bytes": 5394510,
"total_size_mb": 5.14
}
验证结果:✅ 通过
13. 报告服务
GET /reports/weekly
获取周报。
curl -s http://localhost:5001/reports/weekly
响应示例:
{
"report": {
"avg_rating": 1.0,
"created_at": "2026-05-04T01:49:16",
"end_date": "2026-05-10",
"high_freq_queries": [
{"frequency": 1, "query": "测试问题", "sample_answer": "测试回答"}
],
"improvement_suggestions": ["继续保持当前服务质量"],
"low_rating_queries": [],
"negative_count": 0,
"positive_count": 1,
"report_type": "weekly",
"satisfaction_rate": 100.0,
"start_date": "2026-05-04",
"total_feedback": 1,
"total_queries": 1
},
"success": true
}
验证结果:✅ 通过
GET /reports/monthly
获取月报。
curl -s http://localhost:5001/reports/monthly
验证结果:✅ 通过(接口存在)
14. 知识库路由
POST /kb/route
测试知识库路由(调试用)。
echo '{"query":"三峡工程"}' > /tmp/route.json
curl -s -X POST http://localhost:5001/kb/route \
-H "Content-Type: application/json" \
-d @/tmp/route.json
响应示例:
{
"intent": {
"confidence": 1.0,
"department": null,
"is_general": true,
"keywords": [],
"reason": "LLM 意图分析"
},
"query": "test",
"target_collections": ["public_kb"],
"user_department": "开发部",
"user_role": "admin"
}
验证结果:✅ 通过
15. 异步任务查询
⚠️ 生产服务器(server-release)不支持:异步任务系统(
/tasks系列端点)仅存在于 main 分支。当前生产服务器的上传、同步、出题、批阅接口均为同步操作,直接返回结果,无需轮询。如果后续升级到 main 分支版本,以下接口将可用:
端点 方法 说明 /tasksGET 获取任务列表(支持 status/type/limit 过滤) /tasks/<task_id>GET 获取单个任务状态(JSON 轮询) /tasks/<task_id>/progressGET SSE 流式任务进度推送 /tasks/statsGET 获取任务统计信息 任务状态:
pending→running→completed/failed
验证结果:❌ 路由不存在(404)— 符合 server-release 预期行为
16. 认证系统
POST /auth/login
用户登录。
echo '{"username":"admin","password":"xxx"}' > /tmp/login.json
curl -s -X POST http://localhost:5001/auth/login \
-H "Content-Type: application/json" \
-d @/tmp/login.json
响应示例(失败):
{"error": "用户名或密码错误"}
验证结果:✅ 通过(参数校验正常)
GET /auth/me
获取当前用户信息。
curl -s http://localhost:5001/auth/me
GET /auth/users
获取用户列表。
curl -s http://localhost:5001/auth/users
PUT /auth/users/<user_id>
修改用户信息。
echo '{"role":"user"}' > /tmp/update_user.json
curl -s -X PUT "http://localhost:5001/auth/users/test-user" \
-H "Content-Type: application/json" \
-d @/tmp/update_user.json
POST /auth/change-password
修改密码。
echo '{"old_password":"old","new_password":"new"}' > /tmp/changepw.json
curl -s -X POST http://localhost:5001/auth/change-password \
-H "Content-Type: application/json" \
-d @/tmp/changepw.json
17. 其他端点
GET /documents/<path>/raw
下载文档原始文件。
curl -s -o output.docx "http://localhost:5001/documents/public_kb%2F1.docx/raw"
响应:返回原始文件(HTTP 200)
验证结果:✅ 通过
DELETE /chunks/batch
批量删除切片。
echo '{"chunk_ids":["file.txt_text_0","file.txt_text_1"],"collection":"public_kb"}' > /tmp/batch_del.json
curl -s -X DELETE http://localhost:5001/chunks/batch \
-H "Content-Type: application/json" \
-d @/tmp/batch_del.json
GET /stats
获取系统统计信息。
curl -s http://localhost:5001/stats
验证结果:❌ HTTP 500(KeyError: 'SESSION_MANAGER',见已知问题 #2)
POST /collections/sync-vlm-cache
同步 VLM 缓存。
curl -s -X POST http://localhost:5001/collections/sync-vlm-cache
POST /collections/<kb_name>/reindex
重构向量库索引(异步任务)。
curl -s -X POST "http://localhost:5001/collections/public_kb/reindex"
说明:清除哈希记录并触发全量同步。
附录. 已知问题
1. /rag 接口 collections 参数
问题:使用 collection(单数)参数指定知识库无效,会被忽略并默认检索 public_kb。
解决:必须使用 collections(复数,数组格式)参数。
# ❌ 错误用法 - collection 单数参数无效
{"message": "问题", "collection": "dept_tech", "chat_history": []}
# ✅ 正确用法 - collections 数组参数
{"message": "问题", "collections": ["dept_tech"], "chat_history": []}
2. /stats 接口 500 错误
问题:GET /stats 返回 HTTP 500,日志显示 KeyError: 'SESSION_MANAGER'。
原因:该端点依赖 SESSION_MANAGER 配置项,但 server-release 分支未注册会话管理器。
状态:已知缺陷,不影响其他接口正常使用。
3. /tasks 系列端点不存在
问题:GET /tasks、GET /tasks/<id>、GET /tasks/<id>/progress、GET /tasks/stats 均返回 HTTP 404。
原因:异步任务系统仅存在于 main 分支,server-release 保持同步操作模式。上传、同步、出题、批阅接口直接返回结果,无需轮询。
影响:无 — 这是预期行为,所有操作均为同步完成。
4. /documents/sync 与 /sync 的区别
问题:服务器上存在两个同步触发端点,行为略有不同。
| 端点 | 说明 |
|---|---|
POST /sync |
主同步接口,扫描并同步所有知识库 |
POST /documents/sync |
文档级同步接口,需要额外参数 |
建议:使用 POST /sync 触发手动同步。
测试覆盖统计
2026-06-10 生产服务器测试结果(47.116.16.222,云端 Reranker + MMR 文本相似度)
| 分类 | 总数 | 通过 | 异常 | 备注 |
|---|---|---|---|---|
| 健康检查 | 1 | 1 | 0 | ✅ 0.002s |
| 问答接口 | 2 | 2 | 0 | ✅ /rag 流式,/chat 正常 |
| 检索接口 | 1 | 1 | 0 | ✅ /search 0.58-1.53s |
| 向量库管理 | 3 | 3 | 0 | ✅ collections + documents + chunks |
| 文档管理 | 4 | 4 | 0 | ✅ list/status/preview/raw |
| 同步服务 | 3 | 3 | 0 | ✅ status/history/changes |
| 反馈系统 | 5 | 5 | 0 | ✅ feedback/list/stats/bad-cases/blacklist |
| FAQ 管理 | 2 | 2 | 0 | ✅ faq + suggestions |
| 出题系统 | 2 | 2 | 0 | ✅ exam/health + generate(参数校验) |
| 图片服务 | 4 | 4 | 0 | ✅ list/stats/info + 图片下载 |
| 报告服务 | 2 | 2 | 0 | ✅ weekly + monthly |
| 知识库路由 | 1 | 1 | 0 | ✅ /kb/route |
| 认证系统 | 1 | 1 | 0 | ✅ /auth/login 参数校验正常 |
| 异步任务 | 1 | 0 | 1 | ⚠️ /tasks 404 — 仅 main 分支可用 |
| 其他 | 1 | 0 | 1 | ⚠️ /stats 500 — SESSION_MANAGER 未注册 |
| 总计 | 33 | 31 | 2 | 2 个异常均为已知缺陷,不影响核心功能 |
性能基准测试
2026-06-10 生产服务器实测(47.116.16.222,public_kb ~824 切片)
检索性能
| 接口 | 参数 | 优化前 | 优化后 | 提升 |
|---|---|---|---|---|
/search |
top_k=10 | ~34s | 0.58s | ~60x |
/search |
top_k=30 | ~87s | 1.53s | ~57x |
完整 RAG 问答性能(流式)
| 查询 | 完整响应时间 | 搜索阶段 | LLM 生成 |
|---|---|---|---|
| 现代终端分类有哪些? | 13.8s | ~1.5s | ~12s |
| 加盟终端分公司审批流程 | 12.7s | ~1.5s | ~11s |
| 什么是金丝利零售 | 12.7s | ~1.5s | ~11s |
优化措施
| 优化项 | 配置 | 效果 |
|---|---|---|
| Reranker 云端化 | RERANK_BACKEND=cloud(qwen3-rerank) |
搜索阶段从 33-48s 降至 ~0.3s |
| MMR 文本相似度 | MMR_USE_EMBEDDING=false |
MMR 阶段从 ~36s 降至 ~0s |
耗时拆解(优化后 /rag 问答)
总耗时 ~13s
├── 搜索管线 ~1.5s
│ ├── Embedding (query) ~0.25s
│ ├── 向量检索 + BM25 ~0.3s
│ ├── RRF 融合 ~0.01s
│ ├── 上下文扩展 ~0.1s
│ ├── MMR 去重 (文本) ~0.01s
│ ├── Cloud Reranker ~0.3s
│ └── 后处理 ~0.5s
└── LLM 流式生成 ~11.5s
├── 网络建连 ~0.5s
└── 流式 token 生成 ~11s
注:LLM 生成阶段耗时取决于 qwen-turbo API 响应速度,非本地可优化。当前已使用 qwen-turbo(最快模型),如需进一步压缩可考虑减少检索切片数量或缩短 prompt。
附录 B. 生产部署说明
多向量库架构
生产环境采用多向量库模式,每个知识库独立存储在 knowledge/vector_store/chroma/<kb_name>/ 目录下,各自维护独立的 ChromaDB SQLite 数据库和 BM25 索引。
当前生产服务器知识库列表:
| 知识库 | 文档数 | 说明 |
|---|---|---|
| public_kb | ~824 | 公开知识库,所有用户可访问 |
| dept_1_kb | ~500 | 部门知识库 1 |
| resources | 0 | 资源库(新建,暂无文档) |
切片元数据字段
新代码构建的向量库切片包含以下 metadata 字段:
| 字段 | 说明 | 新代码新增 |
|---|---|---|
chunk_id |
切片唯一标识 {文件名}_{序号} |
|
chunk_index |
切片在文档中的序号(用于引用溯源跳转) | ✅ |
chunk_type |
text / table / image | |
source |
来源文件名 | |
collection |
所属知识库 | |
doc_type |
文档类型 pdf/word/excel/other | ✅ |
page / page_end |
页码范围 | |
section |
所属章节 | |
status |
active / deprecated | |
version |
版本号 v1 |
向量库重构
当代码升级涉及元数据字段变更时(如新增 chunk_index、doc_type),需要重构向量库:
# 重构指定知识库(清除哈希记录 → 触发全量同步)
curl -s -X POST http://127.0.0.1:5001/collections/<kb_name>/reindex
⚠️ 注意:reindex 为同步操作,会阻塞直到重建完成。耗时取决于知识库文档数量,大知识库可能需要数分钟。执行期间搜索和问答接口不受影响(多 worker 架构)。
Reranker 配置
生产环境使用 DashScope 云端 Reranker 替代本地 CPU 推理,显著提升检索速度:
| 配置项 | 值 | 说明 |
|---|---|---|
RERANK_BACKEND |
cloud |
使用云端 API(可选 local / cloud / fallback) |
RERANK_CLOUD_MODEL |
qwen3-rerank |
DashScope 云端排序模型 |
RERANK_CLOUD_API_KEY |
sk-* |
DashScope 标准 API Key |
RERANK_CLOUD_BASE_URL |
https://dashscope.aliyuncs.com/compatible-api/v1/reranks |
OpenAI 兼容端点 |
MMR_USE_EMBEDDING |
false |
MMR 使用文本相似度(零额外计算) |
fallback 模式:
RERANK_BACKEND=fallback优先使用云端 API,如果云端不可用则自动回退到本地模型,适合生产环境高可用场景。