db568740c5
- 新增 Ingest.vue 独立入库页(文本/文件/批量 + 任务进度列表),移除入库 Drawer - 导航栏去掉「入库进度」,新增「文档入库」入口;知识库页「入库」跳转独立页 - API 说明页接口清单与后端对齐(补齐用户管理/上传批量/任务重试删除/reingest 等,修正鉴权标注) - 更新 qmdsearch-agent skill 与 api-examples(鉴权说明、会话 token、新端点示例)
158 lines
7.6 KiB
Markdown
158 lines
7.6 KiB
Markdown
---
|
||
name: qmdsearch-agent
|
||
description: 通过 QMDSearch REST API 让 AI Agent 上传文档(文本/文件)并执行分层检索查询。配置服务地址与 Bearer Token 后,即可在对话中入库知识库并检索答案。
|
||
metadata: {"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_TOKEN`:Bearer Token。通过 `POST {BASE}/api/v1/auth/login`(用户名 + 密码)获取;session TTL 12h,失效后重新登录。
|
||
|
||
> 变更类请求(上传 / 删除 / 重试 / 用户管理)必须携带 `Authorization: Bearer <token>`。
|
||
> 查询类只读接口(检索 / 文档列表 / 详情 / 下载 / 类目 / 统计 / 健康 / 任务状态)免登录,无需携带 token。
|
||
|
||
## 统一约定
|
||
|
||
- 路径前缀:`{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
|
||
|
||
```bash
|
||
curl -X POST {BASE}/api/v1/auth/login \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"username":"admin","password":"<password>"}'
|
||
# → {"code":0,"data":{"token":"<session-token>","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/documents`,JSON body `{text, title?, source?, metadata?}`。
|
||
|
||
```bash
|
||
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` 可选;`metadata` 为 `dict[str,str]`。
|
||
- 相同 `sha256(text)` 会命中**去重**,直接复用旧文档(`data` 中 `deduplicated=true`)。
|
||
|
||
## 3. 上传文件
|
||
|
||
`POST {BASE}/api/v1/documents/upload`,`multipart/form-data`:
|
||
|
||
- `file`:必填,支持 `.txt .md .html .htm .pdf .docx`
|
||
- `title` / `source`:可选(默认取原文件名)
|
||
- `metadata`:可选 JSON 字符串
|
||
|
||
```bash
|
||
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}`(无需鉴权):
|
||
|
||
```bash
|
||
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":"..."}}
|
||
```
|
||
|
||
建议:提交后每 1–2s 轮询,直到 `status∈{done,failed}`;`done` 的 `result.document_id` 即入库文档 ID。
|
||
|
||
## 5. 检索(查询)
|
||
|
||
`POST {BASE}/api/v1/search`,JSON `{query, top_k?, summarize?}`:
|
||
|
||
```bash
|
||
curl -X POST {BASE}/api/v1/search \
|
||
-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) | Bearer |
|
||
| POST | `/documents/upload` | 文件入库(202 + task_id) | Bearer |
|
||
| POST | `/documents/upload-batch` | 批量文件入库(202,逐文件建任务) | Bearer |
|
||
| GET | `/documents/tasks` | 入库任务列表(按时间降序) | Bearer |
|
||
| GET | `/documents/tasks/{task_id}` | 任务状态(done / failed) | 免登录 |
|
||
| POST | `/documents/tasks/{task_id}/retry` | 重试入库任务(返回新 task_id) | Bearer |
|
||
| DELETE | `/documents/tasks/{task_id}` | 删除入库任务(幂等) | Bearer |
|
||
| GET | `/documents?limit=&offset=` | 文档列表(分页游标) | 免登录 |
|
||
| GET | `/documents/{doc_id}` | 文档详情(L1 + L2/L3 + chunks 数) | 免登录 |
|
||
| GET | `/documents/{doc_id}/file` | 下载原始文件 | 免登录 |
|
||
| POST | `/documents/{doc_id}/reingest` | 重新摘要入库(读原文件→删旧→重跑) | Bearer |
|
||
| DELETE | `/documents/{doc_id}` | 删除文档(幂等) | Bearer |
|
||
| GET | `/knowledge/categories` | 知识分类类目集 | 免登录 |
|
||
| GET | `/knowledge/stats` | 统计(四层点数 + 类目分布) | 免登录 |
|
||
| GET | `/health` | 健康检查 | 免登录 |
|
||
| POST | `/auth/logout` | 退出登录 | Bearer |
|
||
| POST | `/auth/password` | 修改自己的密码 | Bearer |
|
||
| GET | `/auth/me` | 当前用户信息(脱敏) | Bearer |
|
||
| GET | `/auth/users` | 用户列表(脱敏) | Bearer + admin |
|
||
| POST | `/auth/users` | 创建用户 | Bearer + admin |
|
||
| PATCH | `/auth/users/{username}` | 更新用户角色 / 启用状态 | Bearer + admin |
|
||
| POST | `/auth/users/{username}/password` | 重置指定用户密码 | Bearer + admin |
|
||
| DELETE | `/auth/users/{username}` | 删除用户 | Bearer + admin |
|
||
|
||
## 错误码速查
|
||
|
||
- `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`。
|