Skip to content

文档、知识与评测 API ​

知识不是聊天记录。文档要先入库、确认索引,才能被 knowledge_worker 检索;评测是质量工具,不是对话历史。

源码:app/routers/documents.py、app/routers/rag.py、app/routers/eval.py、app/routers/eval_dataset.py、app/routers/attachments.py、agents/graph/knowledge.py、rag/。

角色通过知识空间隔离资料。检索合同由代码约束,客户端不要让模型直接拼 SQL 或文件路径。

文档处理 ​

文档任务挂在知识空间与 job 上,而不是“上传完立刻可搜”。

方法路径作用
POST/api/knowledge-spaces/{space_id}/documents/upload上传并创建处理任务
GET/api/knowledge-spaces/{space_id}/documents/report空间级文档报告
GET/api/documents/{job_id}单个处理任务
GET/api/documents/{job_id}/report任务报告
POST/api/documents/{job_id}/confirm确认索引
POST/api/documents/{job_id}/retry-index重试索引
DELETE/api/documents/{job_id}删除任务/文档
GET/api/personas/{persona_id}/documents角色可见文档

大文件和解析是异步的。客户端必须保存 job_id。

典型顺序:

text
upload
→ GET /api/documents/{job_id} 直到处理完成
→ POST /api/documents/{job_id}/confirm
→ 角色对话里提问
→ 回答带引用;不足时说明 insufficient,不编造

未确认索引的文档不应出现在检索结果里。换 Embedding 模型后,旧集合维度可能不匹配,需要新集合,不能“接着用昨天的向量”。

对话附件要进知识库时,走 POST /api/conversations/{conversation_id}/attachments/{file_id}/send-to-rag,仍然使用 file_id / attachment_id,不传本机路径。

RAG 查询 ​

app/routers/rag.py 挂在 /api/personas:

方法路径作用
POST/api/personas/{persona_id}/rag/query按角色知识空间检索
GET/api/personas/{persona_id}/rag/queries历史查询
POST/api/personas/{persona_id}/rag/queries/{query_id}/feedback记录反馈
GET/api/personas/{persona_id}/rag/report检索质量/覆盖报告

对话里的知识问题通常不由前端直接打 RAG 路由,而是:

text
POST /api/personas/{persona_id}/agent/stream
→ Supervisor 委派 knowledge_worker
→ search_persona_knowledge / 结构化查询
→ finalize 校验
→ 引用回到同一条会话

调试检索、做评测、看报告时才直接打 /rag/*。结构化查询必须走受限合同(agents/tools/structured_query.py),禁止把任意 SQL 交给模型执行。

检索失败的合法结果包括:没有命中、证据不足、空间未就绪。这些不是 500。

评测运行 ​

/api/eval(app/routers/eval.py)跑的是知识质量,不是一次闲聊。

方法路径作用
POST/api/eval/run启动评测,通常 202
GET/api/eval/status当前运行状态
GET/api/eval/results结果
GET/api/eval/history历史
GET/api/eval/history/{run_id}单次历史
GET/api/eval/export导出
POST/api/eval/analyze分析一次运行

评测 run_id 和 Agent run_id 不要混用。评测失败要看数据集、Embedding、集合名,而不是重发同一句角色对话。

评测数据集 ​

app/routers/eval_dataset.py:

方法路径作用
GET/api/knowledge-spaces/{space_id}/eval-cases用例列表
POST/api/knowledge-spaces/{space_id}/eval-cases新建用例
GET/api/knowledge-spaces/{space_id}/eval-cases/{case_id}单条
PATCH/api/knowledge-spaces/{space_id}/eval-cases/{case_id}修改
DELETE/api/knowledge-spaces/{space_id}/eval-cases/{case_id}删除
GET/api/knowledge-spaces/{space_id}/eval-candidates候选问答
POST/api/knowledge-spaces/{space_id}/eval-candidates/sync从对话/检索同步候选
POST.../eval-candidates/{candidate_id}/approve批准进用例
POST.../eval-candidates/{candidate_id}/reject拒绝

候选不是标准答案。批准之前不要拿候选去“证明系统已经会了”。

角色侧文档列表 ​

GET /api/personas/{persona_id}/documents 给工作台知识页用。删除或重试仍应打 documents 路由,不要在前端直接操作向量库。

失败怎么读 ​

现象先看
上传后问不到job 是否完成、是否 confirm
维度错误Embedding 是否更换、集合名是否仍是旧的
insufficient证据不足,属于正常拒答
结构化查询被拒合同不允许该表/该语句
评测一直排队/api/eval/status 与 Embedding 资源状态

相关页面 ​

源码合同(中档补全) ​

文档 job 状态机 ​

ingestion/document_jobs.py:

text
converting → preview_ready → indexing → indexed
                              ↘ index_failed
  • POST /api/documents/{job_id}/confirm 调用 prepare_index:仅 status == preview_ready 且已有 markdown_path,否则 409 Invalid document state
  • POST /api/documents/{job_id}/retry-index(或仓库中的 retry 入口)调用 prepare_retry:仅 index_failed 且已有 markdown,否则同样 409
  • 进行中统计把 converting 与 indexing 算 in_progress,preview_ready 单独计数

删除处于 indexing / indexed / index_failed 的文档时会尝试 MilvusRagStore.delete_document,失败 502,避免孤儿向量。

体积上限不是同一套 ​

  • 知识库文档:Settings.max_upload_mb,默认环境变量 MAX_UPLOAD_MB=50,换算 MAX_UPLOAD_BYTES = max_upload_mb * 1024 * 1024
  • 对话附件:app/attachments.py MAX_ATTACHMENT_BYTES = 512 * 1024 * 1024,超限 ValueError("文件超过 512 MB 限制"),路由映射为 413
  • Voice Studio 表单分片同样 512MB(MAX_FORM_PART_BYTES)
  • 空文件 422 属于语音/音频(Audio file is empty / Audio request is empty),不是文档 job。文档上传空列表是 422 At least one file is required

知识空间 404 文案:Knowledge space not found。客户端不要对模型拼 SQL 或绝对路径。

转换失败与范围 ​

create_conversion_job 对不支持的类型抛 ValueError,路由按文案映射 4xx,不要把任意解析异常当成 500。索引范围是 DocumentScope(workspace_id, knowledge_space_id, document_id),Milvus 删除必须带同一 scope,防止删错集合。

暂存目录在 data/staging。删除文档时若 source_path 落在 staging 下会一并清理;不要手动往 staging 丢文件指望它变成知识。结构化摘录走 delete_structured_document,与向量删除是两步。