11 KiB
TEST_REPORT_PRIV_R1 —— 私有资料问答轮次测试 R1
docs/team/TEST_REPORT_PRIV_R1.md | T1 执行 2026-09-07 | 用例表 docs/team/TEST_CASES_PRIVATE.md(92 条) 基线:feature/bioflow-conversation-orchestration @ 6bf1182(A1 实现
e783a26+ T1 骨架修正 6bf1182) L4 浏览器冒烟本轮跳过(TL 终验执行)。
1. 执行摘要
- L1 单元:vstore pytest 101/101 全绿;sdk pytest 225 passed / 38 errors(errors 全部为预存基线问题,见 §5);前端 vitest 全量 373 + private_docs 23 = 396 全绿。
- L2 接口:vstore search-chunks 三态/阈值两侧/top_k clamp/doc_ids/exclude_template/rebuild-chunks/health 全部通过;BFF /api/qa/private 命中/未命中(min_score)/422(缺参)/docgen 上传→检索→删除闭环全部通过;发现 3 个缺陷(响应缺 ok 键、空 question 未 422、默认阈值下无关查询 hit:true)。
- Lr 红线:QA 8091、前端红线、vstore 红线、sdk 红线、compile_sdk.sh、新模块 yield 检查——diff 全部为空,改动文件 19 个全部在清单内。
- 缺陷:3 个(BUG-PRIV-R1-01/02/03,均一般级,无阻断);预存基线问题 1 项(sdk 38 errors,非本次引入);观察项 2 项。
2. 环境
- 仓库 /home/xzq/5090/teamWorkspace/zh/PlantAI-rag-new @ 6bf1182;venv = plantai-rag-new-venv/bin/python(3.12)。
- 部署环境:vstore 127.0.0.1:8094(chunk_count=210);BFF 127.0.0.1:8090;前端 dist 已构建。
- 全程只读+curl;未重启服务、未 commit;一次性测试资料上传后已删除(health 回 210)。
3. L1 单元测试明细
3.1 vstore(仓库根)
命令:cd /home/xzq/5090/teamWorkspace/zh/PlantAI-rag-new && venv/bin/python -m pytest vstore/tests/ -q
| 结果 | 数量 | 备注 |
|---|---|---|
| passed | 101 | 含 T1 新增 test_chunks.py 27 条 + 既有回归(test_vault/test_retrieval/test_embed/test_api 等) |
| failed | 0 | |
| warnings | 2 | fastapi on_event DeprecationWarning(预存,与本次无关) |
关键输出摘录:101 passed, 2 warnings in 25.14s
3.2 sdk(sdk/ 目录)
命令:cd sdk && venv/bin/python -m pytest -q
| 结果 | 数量 | 备注 |
|---|---|---|
| passed | 225 | |
| failed | 0 | A1 报告所述「3 failed 预存」未复现——实际为 0 failed + 38 errors(口径见 §5) |
| errors | 38 | 全部为 app/routers/test_docgen_api.py collection ERROR,预存基线问题(§5 有 dea4640 同环境对照证据) |
分区分证:pytest app/services -q → 158 passed(privateqa/schemas 相关路径零异常,本次 BFF 改动无测试回归)。
3.3 前端(ui/)
命令:cd ui && npx vitest run(全量)+ npx vitest run --config tests/private_docs/vitest.config.js
| 套件 | 结果 |
|---|---|
| 既有全量(tests/frontend/unit b1/b2/b3/bioflow) | 27 files / 373 passed(与 A1 报告 373 一致) |
| T1 新增 private_docs(chat.private 12 / components.private 4 / privateLibraryPane 4 / docPaneMount 3) | 4 files / 23 passed |
| 合计 | 396 passed / 0 failed |
4. L2 接口测试明细(curl 部署环境)
4.1 vstore 8094
| 项 | TC | 命令要点 | 实际结果 | 判定 |
|---|---|---|---|---|
| health chunk_count | L2-08 | GET /api/vstore/health | {ok:true,count:210,backend:"local",chunk_count:210} |
PASS |
| search-chunks 命中 | L2-01 | q=水稻 top_k=3 | mode:"vector", count:1, 含 chunk_id/doc_id/seq/snippet/score(0.34)/doc_name/... 全字段 | PASS |
| 阈值下侧 0.29 | L2-01/判据 | q=水稻 min_score=0.29 | mode:"vector", count:3(≥0.29 全收) | PASS |
| 阈值上侧 empty | L2-02/判据 | q=水稻 min_score=0.90 | mode:"empty", count:0, items:[](无降级档) |
PASS |
| top_k clamp | L2-04 | top_k=99 / top_k=0 | 99→返回 20 条;0→返回 1 条(clamp 1..20) | PASS |
| doc_ids 过滤 | L2-05 | doc_ids=单个 uuid | 仅该 doc 命中 | PASS |
| exclude_template | L2-06 | exclude_template=true | items 无 as_template 行 | PASS |
| rebuild-chunks | L2-07 | POST /api/vstore/rebuild-chunks | {ok:true,docs:210,chunks:210,duration_ms:135682} |
PASS(见观察 O-1) |
| 无关查询(默认阈值) | L2-02 | q="xyzzyquuxblargh_完全无关词" | mode:"vector", count:5, score 0.37(真实 bge-m3 底噪 >0.30) | 行为观察(BUG-R1-03 关联) |
4.2 BFF 8090
| 项 | TC | 命令要点 | 实际结果 | 判定 |
|---|---|---|---|---|
| /api/qa/private 命中 | L2-10 | question="测试文档8的内容是什么" | hit:true, mode:"vector", items:8(ref/score/snippet 齐全), answer 81 字(≤300 ✓), elapsed_ms≈2s | PASS(响应键缺失 ok → BUG-R1-01) |
| 未命中(高 min_score) | L2-11 | min_score=0.95 | hit:false, mode:"empty", answer:"", items:0 |
PASS |
| 缺 question 参数 | L2-12 | body={} | HTTP 422 {ok:false,error:{code:"VALIDATION",...}} |
PASS |
| 空 question | L2-12 | body={"question":""} | HTTP 200 {hit:false,mode:"empty",answer:"",items:[]}(未走 422) |
FAIL(轻微)→ BUG-R1-02 |
| 无关问题(默认阈值) | L2-11/L4-03 | question="zqxwcrvtnmkjhgfdsp 完全无关的问题xyz" | hit:true, mode:"vector", items:8, answer="资料中未找到相关信息。"(LLM 正确自谦,但前端会出块) | FAIL(观察级)→ BUG-R1-03 |
4.3 docgen library 回归(一次性资料,已删除)
| 项 | TC | 实际结果 | 判定 |
|---|---|---|---|
| GET /api/docgen/library | L2-17 | ok:true, items:7, 字段全集(id/name/category/tags/description/as_template/active/created_at) | PASS |
| POST 上传 | L2-15 | 201 语义 {ok:true, items:[{library_id,name,size,as_template}]};health 210→211(count 与 chunk_count 同步 +1) | PASS |
| 新资料 search-chunks 命中 | L2-16/20 | mode:"vector",新 doc_id 在命中列表(score 0.43) | PASS |
| DELETE | L2-18 | HTTP 204;health 211→210(doc 级 + chunk 级联动删除);再检索该资料不再命中 | PASS |
4.4 doc 级 /search 逐字段回归(L2-21)
- 响应顶层键:
{ok, mode, items}与改动前一致;item 12 键全集一致(id/name/category/tags/description/as_template/enc_path/embed_chunks/embed_sha 等价字段/keywords/size/created_at/row_id)。 - 代码级证据:
git diff dea4640 HEAD -- vstore/vault.py仅+_chunked_embed、+rebuild_chunks、delete docstring 一行改动——doc 级 search/add_item 路径零改动。PASS。
5. 预存基线问题(非本次缺陷)
sdk app/routers/test_docgen_api.py 38 个 collection ERROR
- 现象:
AttributeError: <module 'app.routers.docgen'> has no attribute 'is_docgen_intent'——test 文件(2026-09-03 提交 5888e1d)在 autouse fixture 里 monkeypatch 的桩名is_docgen_intent已随 docgen 护栏重构(4749f77「意图护栏:按端点类型传参」)被移除。 - 基线证据:
git diff dea4640 HEAD -- sdk/app/routers/docgen.py为空(docgen.py 本次零改动);git diff dea4640 HEAD -- test_docgen_api.py为空(测试文件本次零改动);在git archive dea4640提取的基线树同环境跑pytest -q结果同样为 225 passed, 38 errors——与当前工作树完全一致。 - 结论:38 errors 预存于
dea4640基线,与 FR-PRIV 改动无关;A1 报告「3 failed 预存」口径与实际不符(实际 0 failed + 38 collection errors),建议 TL 修订基线记录口径。按纪律不修产品代码、也不修该测试文件(不在清单内),留 TL 裁决是否另开任务修复。
6. 缺陷清单
BUG-PRIV-R1-01(一般)|/api/qa/private 响应缺 ok:true 键
- 对应 TC:TC-PRIV-L2-10、TC-PRIV-L2-11。
- 复现步骤:
curl -X POST http://127.0.0.1:8090/api/qa/private -d '{"question":"测试文档8"}' - 预期:任务书 P2.5 契约
{ok:true, hit:true, mode, answer, items, elapsed_ms}。 - 实际:
{"hit":true,"mode":"vector","answer":...,"items":[...],"elapsed_ms":1553}——无 ok 键(未命中态同样缺 ok)。 - 影响:前端
_firePrivate判payload.ok === false(undefined !== false),功能不受损;但 BFF 全部既有端点响应带 ok,本端点偏离统一信封惯例,且与任务书契约文字不符。 - 建议:router 层包一层
{"ok": True, **result}(或 ask_private 返回体补 ok)。
BUG-PRIV-R1-02(一般)|空 question 未走 422 VALIDATION
- 对应 TC:TC-PRIV-L2-12。
- 复现步骤:
curl -X POST /api/qa/private -d '{"question":""}' - 预期:统一 VALIDATION 信封 422(缺 question 已正确 422)。
- 实际:HTTP 200
{hit:false,mode:"empty",answer:"",items:[]}——空串绕过 pydantic 必填语义直通 vstore(空查询无 chunk 命中恰巧返回 empty)。 - 影响:入口校验不严(空串请求白白打一次 vstore 嵌入+检索);契约不一致。
- 建议:
PrivateQARequest.question加min_length=1(或 router 层显式 strip 校验)。
BUG-PRIV-R1-03(一般/待裁决)|默认 min_score=0.30 下无关查询 hit:true,前端会出块
- 对应 TC:TC-PRIV-L2-11、TC-PRIV-L4-03(「未命中无感」验收口径)。
- 复现步骤:
curl -X POST /api/qa/private -d '{"question":"zqxwcrvtnmkjhgfdsp 完全无关的问题xyz"}';vstore 侧 q=同无关串 score 0.37 > 0.30。 - 预期:FR-PRIV-003「未命中或服务故障用户无感」。
- 实际:hit:true + 8 个 items(真实 bge-m3 余弦底噪 0.3~0.37 越线)→ 前端将展示「私有资料参考」块;LLM 答语正确为「资料中未找到相关信息。」,但块已出现,与「零痕迹」目标冲突。当前库内 210 条多为压测/占位短文本,真实客户资料底噪分布待 L4 观察。
- 裁决建议(TL):a) 维持契约(threshold 语义正确,答语自谦属可接受形态);b) 提高默认 min_score(如 0.35/0.40,需重跑样例评分分布);c) BFF 层对 answer=="资料中未找到相关信息。" 时改回 hit:false。无论哪种,用例表 TC-PRIV-L4-03 判据需 TL 确认后回写。
7. 观察项(非缺陷)
- O-1:POST /api/vstore/rebuild-chunks 同步耗时 135.7s(210 docs)——设计意图即「存量重建走 CLI 不进 HTTP」(FR-PRIV-007),HTTP 端点行为正确但运维上应避免直连调用(BFF 透传路径无此端点,风险仅限人工 curl)。本次误触发一次,结果正确(210/210),已确认后续不再直连。
- O-2:命中样例 answer 81 字、elapsed_ms 1.5~2.1s,40s 超时参数(PRIVATE_QA_LLM_TIMEOUT=40)未在实测路径触发(正常响应),该路径由 L1 单测(TC-PRIV-L1-26 参数断言)覆盖。
8. 统计汇总
| 层 | 总数 | 通过 | 失败/缺陷 | 备注 |
|---|---|---|---|---|
| L1 vstore pytest | 101 | 101 | 0 | 全量含既有回归 |
| L1 sdk pytest | 263 | 225 | 0 failed / 38 errors | errors 全部预存基线(§5) |
| L1 前端 vitest | 396 | 396 | 0 | 既有 373 + 新增 23 |
| L2 vstore curl | 9 项 | 9 | 0 | 1 项行为观察(O/BUG-03 关联) |
| L2 BFF curl | 5 项 | 4 | 2(BUG-01 键缺失、BUG-02 空串)+ 1 观察(BUG-03) | |
| L2 docgen 回归 | 5 项 | 5 | 0 | 上传→删除闭环 net 零扰动 |
| Lr 红线 | 6 项 | 6 | 0 | 全部 diff 空 |
| L4 浏览器 | 跳过 | — | — | TL 终验 |
9. 结论
R1 无阻断缺陷。3 个缺陷均为一般级契约/阈值问题,修复面小(schemas 加 min_length、router 包 ok、阈值/答语裁决)。sdk 38 errors 为预存基线问题(有 dea4640 对照证据),与本次改动无关。建议 TL 裁决 BUG-R1-03 的阈值策略后,交 A1 修复 01/02(+03 视裁决),再开 R2 复测。