Files
kplam 51dc8dc4f6 Initial commit: QMDSearch 分层信息检索服务
- FastAPI + Qdrant + Redis + Ollama 技术栈
- L1→L2→L3→chunk 四层分层检索(dense + sparse RRF 融合)
- 文档三级总结与 2.5 级回退
- query 解析路由与分类
- /admin 管理页面
2026-07-29 21:24:40 +08:00

6.0 KiB
Raw Permalink Blame History

项目完整性补全:管理 API + 管理页面 + 单测补全 Spec

Why

分层 RAG 全链路已验收(149 测试全绿),但系统对外闭环不完整:已入库文档无法查看/管理(无列表/详情/删除 API),运维人员无 UI 可手工验证检索与入库,judge/response/ollama 客户端等模块无单测覆盖,Dockerfile 未打包评测脚本,CLAUDE.md 项目结构已过时。本变更补齐管理闭环与测试覆盖,使系统达到可运维状态。

What Changes

  • 文档管理 API(新增)GET /api/v1/documents(分页列表,源自 doc_l1 scroll)、GET /api/v1/documents/{doc_id}(详情:L1 总结 + L2/L3 节点 + chunk 数)、DELETE /api/v1/documents/{doc_id}(按 doc_id 过滤删除四层集合所有点,幂等)
  • 统计 API(新增)GET /api/v1/knowledge/stats(四层集合点数、类目分布、uncategorized 数量)
  • 管理页面(新增)FastAPI 托管静态单页 /admin,原生 JS + fetch 单文件实现(无 Node 构建链、镜像零新增依赖),含 概览 / 文档管理 / 文档入库 / 检索测试台 / 类目列表 五个区块;删除操作前端二次确认
  • 单元测试补全scripts/eval/judge.py、app/api/response.py、app/services/ollama.pyHTTP 行为)、scripts/eval/run_eval.py 可测纯函数、新增管理 API 端点测试、/admin 页面存在性测试
  • 完整性修补Dockerfile 增加 COPY scripts/ scripts/CLAUDE.md 项目结构与 API 清单更新至当前实现

无破坏性变更(现有 API 路径与响应结构不变,仅新增)。

Impact

  • Affected specs: 文档管理(新增)、统计概览(新增)、管理页面(新增)、测试覆盖、部署
  • Affected code:
    • 修改:qdrant.pyscroll/delete/count 管理操作)、main.py(挂载 /admin 静态页)、document.py(新增端点)、knowledge.pystats)、DockerfileCLAUDE.md
    • 新增:app/static/admin.htmltests/test_judge.pytests/test_response.pytests/test_ollama_client.pytests/test_run_eval.pytests/test_document_admin_api.pytests/test_admin_page.py

ADDED Requirements

Requirement: 文档列表与详情

系统 SHALL 提供 GET /api/v1/documents:基于 doc_l1 集合 scroll 分页返回文档摘要列表(doc_id、title、category、tags、总结层级推断、L1 总结摘要),支持 limit/offset 游标分页;并提供 GET /api/v1/documents/{doc_id} 返回单文档详情:L1 payload 全部字段、L2/L3 节点列表、chunk 数量。doc_id 不存在时返回 code=1004。

Scenario: 分页列表

  • WHEN 请求 GET /api/v1/documents?limit=20
  • THEN 返回 code=0data 含 items(每项 doc_id/title/category/tags/summary)与 next_offset(无更多为 null

Scenario: 详情与不存在

  • WHEN 请求已入库 doc_id 的详情
  • THEN 返回 L1 字段 + l2_nodes/l3_nodes 列表 + chunks_count;请求不存在的 doc_id 返回 code=1004

Requirement: 文档删除

系统 SHALL 提供 DELETE /api/v1/documents/{doc_id}:按 doc_id payload 过滤删除 doc_l1/doc_l2/doc_l3/chunks 四个集合中的全部点;删除不存在 doc_id 幂等返回成功(deleted_points=0);返回各集合删除点数统计。

Scenario: 删除已入库文档

  • WHEN 对已入库 doc_id 执行 DELETE
  • THEN 四层集合该 doc_id 的点全部被清除,再次 GET 详情返回 1004

Requirement: 统计概览

系统 SHALL 提供 GET /api/v1/knowledge/stats:返回四层集合各自点数、按 category 的文档分布、uncategorized 文档数。统计基于 Qdrant count 与 doc_l1 轻量 scroll 聚合(仅取 category 字段),属管理端低频接口。

Scenario: 概览数据

  • WHEN 请求 stats
  • THEN data 含 collections(四层点数)、categories(类目→文档数)、uncategorized_count

Requirement: 管理页面

系统 SHALL 在 /admin 提供静态单页管理界面(单 HTML 文件,内联 CSS/JS,无外部 CDN 依赖),包含五个区块:概览(stats 展示)、文档管理(列表 + 详情查看 + 删除,删除需二次确认)、文档入库(表单提交 text/title/source,展示分类与总结结果)、检索测试台(输入 query 展示 hits/routed_categories/fallback)、类目列表。页面调用同-origin /api/v1/*,统一处理 code≠0 的错误提示。

Scenario: 页面可用性

  • WHEN 浏览器访问 /admin
  • THEN 返回 200 HTML,包含五个功能区块与全部 fetch 调用指向 /api/v1/ 路径,无外部资源引用

Requirement: 单元测试补全

系统 SHALL 为以下模块补齐单测:judge.pymock Ollama:断言抽取/支持判定/解析失败返回 0.0)、response.pyok/error/ApiError 结构)、ollama.pymock httpxgenerate/json_mode payload/is_available 可达与异常分支)、run_eval.py 可测纯函数(格式化与门槛判定)、新增管理 API 与 /admin 页面存在性(TestClient 200 + 关键区块标记)。

Requirement: 部署与文档完整性

Dockerfile SHALL 打包 scripts/ 目录(镜像内可执行评测);CLAUDE.md SHALL 更新项目结构、API 清单与管理页面说明至当前实现。

MODIFIED Requirements

Requirement: QdrantService(新增管理操作)

QdrantService SHALL 新增:scroll_l1(limit, offset) -> (items, next_offset)(仅取列表所需 payload 字段)、get_doc_detail(doc_id) -> dict | NoneL1 + L2/L3 节点 + chunk 计数)、delete_by_doc_id(doc_id) -> dict[str, int](四集合按过滤删除,返回各集合删除数)、count(collection) -> int。均复用现有客户端与集合常量,不改变既有 upsert/查询行为。

REMOVED Requirements

无。