Files
kplam 83eb8d0dd0 feat: 新增 QMDSearch Agent Skill 包与下载入口
- 新增 skills/qmdsearch-agent(SKILL.md + references/api-examples.md),文档化
  AI Agent 鉴权、文本/文件上传入库(异步轮询)与分层检索调用方式
- 打包 QMDSearch-Agent-Skill.zip 至 app/static/agent-skill/
- 后端新增 GET /agent-skill 免登录下载路由(随 ./app 卷挂载,restart 即生效)
- 前端 API 说明页新增「AI Agent Skill 下载」卡片,链接至 /agent-skill
2026-08-01 00:11:05 +08:00

6.6 KiB
Raw Permalink Blame History

name, description, metadata
name description metadata
qmdsearch-agent 通过 QMDSearch REST API 让 AI Agent 上传文档(文本/文件)并执行分层检索查询。配置服务地址与 Bearer Token 后,即可在对话中入库知识库并检索答案。
clawdbot
emoji
📚

QMDSearch Agent 接入 Skill

本 skill 指导 AI Agent 调用 QMDSearch(面向 AI Agent 的分层信息检索服务)的 HTTP API,完成两类核心操作:

  1. 上传文档:把文本或文件送入知识库(异步入库,自动三级总结 + 向量化)。
  2. 查询 / 检索:对知识库做分层语义检索,返回最相关原文 chunk。

何时使用

  • 用户希望把一份文档 / 笔记 / 网页内容加入知识库 → 调用上传接口。
  • 用户就知识库内容提问 → 调用检索接口。
  • 用户想确认文档是否入库成功 → 轮询任务状态。
  • 需要列出 / 删除知识库文档、查看统计 → 调用对应只读 / 管理接口。

前置配置(必须)

启用前先确定:

  • QMDSEARCH_BASE_URL:服务基地址,例如 http://localhost:8000 或 NAS 地址 http://<nas-ip>:8000
  • QMDSEARCH_TOKENBearer Token。通过 POST {BASE}/api/v1/auth/login(用户名 + 密码)获取;session TTL 12h,失效后重新登录。

所有变更类请求(上传 / 删除)与检索请求都必须在 Header 携带 Authorization: Bearer <token>。 当前代码实现中,查询类只读接口(文档列表 / 详情 / 类目 / 统计 / 健康)同样要求 Bearer(与登录态绑定),请始终携带 token 以避免 1005 未认证。

统一约定

  • 路径前缀:{BASE}/api/v1
  • 响应体:{ "code": 0, "data": {...}, "message": "ok" }code=0 成功;1xxx 客户端错误;2xxx 服务端错误。
  • 入库是异步的:上传返回 202 + task_id,需轮询 GET /documents/tasks/{task_id} 直到 status=done(或 failed)。

1. 获取 Token

curl -X POST {BASE}/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"<password>"}'
# → {"code":0,"data":{"token":"<JWT>","username":"admin","role":"admin","must_change_password":false},"message":"ok"}

must_change_password=true 时,登录成功但调用其他接口会返回 1006,需先 POST /api/v1/auth/password 改密。

2. 上传文档(文本)

POST {BASE}/api/v1/documentsJSON body {text, title?, source?, metadata?}

curl -X POST {BASE}/api/v1/documents \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"text":"QMDSearch 支持 L1/L2/L3 分层检索……", "title":"QMDSearch 介绍", "source":"notes"}'
# → 202 {"code":0,"data":{"task_id":"<uuid>","status":"pending"},"message":"ok"}
  • text 必填且非空;title / source 可选;metadatadict[str,str]
  • 相同 sha256(text) 会命中去重,直接复用旧文档(datadeduplicated=true)。

3. 上传文件

POST {BASE}/api/v1/documents/uploadmultipart/form-data

  • file:必填,支持 .txt .md .html .htm .pdf .docx
  • title / source:可选(默认取原文件名)
  • metadata:可选 JSON 字符串
curl -X POST {BASE}/api/v1/documents/upload \
  -H "Authorization: Bearer <token>" \
  -F "file=@document.pdf" \
  -F "source=manual"
# → 202 {"code":0,"data":{"task_id":"<uuid>","status":"pending","saved_path":"..."},"message":"ok"}

服务端按扩展名提取纯文本(PDF 扫描件自动 OCR 降级),再复用同一入库流水线。

4. 轮询入库任务

GET {BASE}/api/v1/documents/tasks/{task_id}(无需鉴权):

curl {BASE}/api/v1/documents/tasks/<task_id>
# done   → {"code":0,"data":{"task_id":...,"status":"done","result":{...文档ID/总结/分类...},"created_at":...,"updated_at":...}}
# failed → {"code":0,"data":{"task_id":...,"status":"failed","error":"..."}}

建议:提交后每 12s 轮询,直到 status∈{done,failed}doneresult.document_id 即入库文档 ID。

5. 检索(查询)

POST {BASE}/api/v1/searchJSON {query, top_k?, summarize?}

curl -X POST {BASE}/api/v1/search \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"query":"如何配置 Redis 缓存","top_k":5,"summarize":false}'

返回 data{query, hits[], routed_categories[], fallback, extracted_info, summary?}。 每个 hit{text, doc_id, title, section_path, score, doc_summary}

  • top_k:返回条数(默认 RETRIEVAL_FINAL_K,通常 5)。
  • summarize=true:额外返回 summary(对检索结果做 AI 总结)。
  • fallback=true:走了全库兜底(未走类目路由),召回较广。
  • extracted_info:query 解析出的关键词 / 实体 / 意图 / 命中类目。

6. 其他管理接口(按需)

方法 路径 说明
POST /documents 文本入库(202 + task_id
POST /documents/upload 文件入库(202 + task_id
GET /documents/tasks/{task_id} 任务状态(done / failed
GET /documents?limit=&offset= 文档列表(分页游标)
GET /documents/{doc_id} 文档详情(L1 + L2/L3 + chunks 数)
GET /documents/{doc_id}/file 下载原始文件
DELETE /documents/{doc_id} 删除文档(幂等)
GET /knowledge/categories 知识分类类目集
GET /knowledge/stats 统计(四层点数 + 类目分布)
GET /health 健康检查

错误码速查

  • 1001 参数 / 格式错误(空文本、不支持的类型、弱密码、超大小)
  • 1004 资源不存在(task / doc 不存在)
  • 1005 未认证或凭证无效 / 账号已禁用
  • 1006 权限不足 / 首次登录须先改密
  • 2000 服务端内部错误(检索 / 入库 / 列表失败)
  • 2001 认证服务暂不可用

Agent 最佳实践

  1. 先登录拿 token,缓存 12h,失效再用 /auth/login 刷新。
  2. 上传走异步:拿到 task_id 后轮询,不要在对话里阻塞等待,可告诉用户“正在入库,稍后查询”。
  3. 去重友好:重复提交同文本会自动复用,不必担心重复。
  4. 大文件 / 批量:逐文件上传并各自轮询;注意 UPLOAD_MAX_SIZE_MB(默认 20MB)。
  5. 检索调参:召回不足调大 top_k;需要摘要设 summarize=true;关注 fallback 判断是否需要改写 query。
  6. 凭证安全:token 等同会话,不要写入日志或外发。

完整请求 / 响应示例(含 Python 客户端封装)见 references/api-examples.md