语料 106 文件/724 块(全流程 79 章 118 + 契约 60 份 429 + 技能 45 份 177);QA 树与 vstore 既有集合零改动 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
156 lines
9.8 KiB
Markdown
156 lines
9.8 KiB
Markdown
# report_bioflow_dev4 —— P6 流程知识库问答(开发 agent A4)
|
||
|
||
> 任务书:docs/team/brief_bioflow_dev4_p6.md
|
||
> 工作分支:feature/bioflow-conversation-orchestration(保持,不切换)
|
||
> 纪律:QA 树(8091)零改动;vstore 既有集合与代码零改动(只新增);不 commit/push;凭据不入库
|
||
|
||
## 步骤 1:环境与语料勘察(2026-09-05)
|
||
|
||
- 确认工作分支 feature/bioflow-conversation-orchestration;vstore/ 现状:api.py/backend.py/vault.py/retrieval.py/embed.py/settings.py(主库=公文/资料库,零改动对象)
|
||
- 语料 1:docs/bioflow_corpus/PlantAI_现有分析全流程_基因家族_RNAseq_WGS_GWAS.md,2359 行,79 章正文 + 80 一页索引 + 附录 A(软件调用说明,A.1–A.6)
|
||
- 语料 2:dev gfa_core/schemas/stages/*_contract_v1.md 共 60 个文件、11626 行,全部入库(任务书写 59,实际 60,报告为准)
|
||
- 语料 3:dev skills/*/SKILL.md 共 45 份技能说明
|
||
- 明文安全预扫:全流程文档无凭据痕迹(无 password/token/secret 匹配)
|
||
- vstore 现役集合零改动确认:主库读写路径(vault.py)不触碰;flow_docs 用独立目录 + 独立 RetrievalIndex 实例
|
||
|
||
## 步骤 2:flow_docs 集合实现(vstore/flow.py,新增模块)
|
||
|
||
- FlowStore(flow_dir):独立目录 flow_dir/{index.json, chunks/},chunks/ 存块正文 json(明文,
|
||
语料为团队内部公开分析文档,检索 meta 与正文均需在对话内引用原文——与主库「密文纪律」不同,见已知限制)
|
||
- 复用 vstore.retrieval.RetrievalIndex(index.json + faiss IndexFlatIP,三档降级语义不变)
|
||
- add_chunk:幂等 upsert(键 = chunk_key = source_id__md5(标题路径+源文件相对路径)[:12],
|
||
同键重跑覆盖、不产生重复行);向量嵌入文本 = 标题路径 + 标题 + 正文
|
||
- search:混合检索(语义向量通道 + 词面通道)
|
||
- 向量通道:top_k 一半配额
|
||
- 词面通道:ASCII 词(≥3 字符)命中 title_path/heading/stage_name/name,阶段名精确命中 +3 加权;
|
||
契约/技能按文件去重、corpus 按章去重;不足时正文字面兜底、向量余量补足
|
||
- delete_source / stats 维护接口
|
||
- 嵌入函数经 set_embed_fn 可注入(测试不依赖真 ollama)
|
||
|
||
## 步骤 3:入库脚本(vstore/scripts/ingest_flow_docs.py)
|
||
|
||
- 幂等可重跑:同键覆盖;--prune 清理源文件已删除的孤儿块
|
||
- 语料 1 切块:按文件实际 #(一级/组)与 ##(二级/章)标题切块(79 章全录含附录 A);
|
||
组块含无二级标题的章正文(如第 79 章);文档头/前导章单独成块;三级标题不切分留父块
|
||
- 语料 2/3 切块:按 ## 节切块 + 文件级全文块兜底(单节向量分散时保证主题可召回)
|
||
- 单块上限 6000 字符(超长标注 truncated)
|
||
- 参数:--flow-dir / --corpus-file / --stages-dir / --skills-dir / --skip-* / --prune
|
||
- 运行:/home/xzq/5090/teamWorkspace/zh/plantai-rag-new-venv/bin/python vstore/scripts/ingest_flow_docs.py
|
||
- 部署时需在知识库检索侧注入 embed(ollama bge-m3 或 A2 侧既有嵌入管线)
|
||
|
||
## 步骤 4:入库结果(真实语料全量实测,2026-09-05)
|
||
|
||
| 语料源 | 文件数 | 块数 | 字符量 |
|
||
|---|---|---|---|
|
||
| corpus 全流程文档 | 1 | 118 | — |
|
||
| stage_contract 阶段契约 | 60 | 429 | — |
|
||
| skill 技能说明 | 45 | 177 | — |
|
||
| 合计 | 106 | 724 | 544,343 |
|
||
|
||
## 步骤 5:flow_docs 集合字段约定(供 A2 planner.py 知识库检索对齐)
|
||
|
||
行 meta 字段(index.json 每行 = 一个块):
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|---|---|---|
|
||
| id / chunk_key | string | 块键 = {source_id}__{md5[:12]},幂等键 |
|
||
| source | string | corpus | stage_contract | skill(检索过滤用) |
|
||
| doc_kind | string | 同 source(corpus/contract/skill),与 source 一一对应 |
|
||
| doc_kind_label | string | 中文标签:全流程文档/阶段契约/技能说明 |
|
||
| title | string | 文档一级标题(文件名) |
|
||
| title_path | string | 完整标题链,用「 | 」连接(如「第一部分 | ## 4. identify」) |
|
||
| heading | string | 块级标题(末段) |
|
||
| stage_name | string | 阶段名(契约=文件名去 _contract_v1;技能=目录名;corpus 无) |
|
||
| path | string | 源文件相对路径(dev 仓库相对路径或 docs/bioflow_corpus/…) |
|
||
| cite | object | 引用定位:{anchor};contract/skill 另有 {anchor, line}(节首行号) |
|
||
| line_start / line_end | int | 块在源文件的行范围(1 基) |
|
||
| name / description | string | 检索二档关键词兜底字段(name=title,description=title_path) |
|
||
| keywords | list | meta 派生关键词(二档用) |
|
||
| text_chars | int | 块正文字符数 |
|
||
| created_at | string | ISO8601 UTC |
|
||
| chunking / truncated | string/bool | 切块说明 / 是否截断 |
|
||
| vector | list[float] | 1024 维(bge-m3)嵌入,仅存 index.json(不对外返回) |
|
||
|
||
块正文:chunks/{chunk_key}.json = {"meta": {...}, "text": "原文"}(明文)。
|
||
|
||
## 步骤 6:引用块跳转接口约定(供 A3 前端渲染对齐)
|
||
|
||
答案引用块建议 JSON 形态(A3 渲染时可跳转):
|
||
|
||
```json
|
||
{
|
||
"source": "corpus | stage_contract | skill",
|
||
"title_path": "第一部分:基因家族分析 | ## 4. identify:家族成员初筛与结构域确认",
|
||
"path": "docs/bioflow_corpus/PlantAI_现有分析全流程_基因家族_RNAseq_WGS_GWAS.md",
|
||
"cite": {"anchor": "## 4. identify:家族成员初筛与结构域确认", "line": 119},
|
||
"line_start": 119, "line_end": 131,
|
||
"text": "原文摘录……"
|
||
}
|
||
```
|
||
|
||
- doc_kind=corpus:path 为 rag 仓库相对路径;UI 打开 /{path} 并定位 anchor(源文件由 A3 一并交付渲染)
|
||
- doc_kind=contract/skill:path 为 dev 仓库相对路径(gfa_core/schemas/stages/…、skills/…/SKILL.md);
|
||
UI 以文件卡片打开,支持行号锚点时用 line_start/line_end
|
||
- 两种跳转形态都带 fallback(锚点失效则跳文件首);具体渲染由 A3 决定,本约定写入后双方对齐
|
||
|
||
## 步骤 7:评估集与评测脚本
|
||
|
||
- 评估集:vstore/tests/testdata/eval_flow_docs.json,50 条,8 类
|
||
(gf_stage_io 17 / rnaseq_stage_io 5 / wgs_stage_io 5 / pop_gwas_io 1 / params 4 /
|
||
preconditions 5 / software 10 / delivery 3)
|
||
覆盖:阶段输入输出、默认参数与阈值、前置条件与依赖链、软件对照(契约/技能附加入库源的差异化价值)、交付与整体咨询
|
||
- 判定:hit(检索口径断言:source/stage_keyword 匹配)+ quote(top_k 块正文拼接含全部黄金断言词)
|
||
- 评测脚本:vstore/scripts/run_flow_eval.py(run_eval() 可被 pytest 复用;--verbose 逐条打印)
|
||
- 单元测试:vstore/tests/test_flow.py(5 用例:幂等 upsert、检索过滤/删源、三种语料切块、评估集通过率)
|
||
全部 tmpdir + 假嵌入(vstore/tests/fake_embed_utils.py),不连生产 vstore/ollama
|
||
|
||
### 首轮自测通过率记录(真实语料全量入库 + 假嵌入,2026-09-05)
|
||
|
||
| 轮次 | 通过 | 通过率 | 备注 |
|
||
|---|---|---|---|
|
||
| 1 | 25/50 | 50.0% | 基线:纯向量检索 |
|
||
| 2 | 42/50 | 84.0% | 嵌入文本并入标题路径 + 文件级全文块 |
|
||
| 3 | 38/50 | 76.0% | 词级采样尝试(回退) |
|
||
| 4 | 40/50 | 80.0% | 混合检索 v1(词面通道仅向量候选) |
|
||
| 5 | 44/50 | 88.0% | 词面通道扫全索引 |
|
||
| 6 | 41/50 | 82.0% | 中文 2-gram 噪声(回退) |
|
||
| 7 | 39/50 | 78.0% | boost/body-lex 噪声(回退) |
|
||
| 8 | 46/50 | 92.0% | 词面同文件去重 + boost 收敛 |
|
||
| 9(最终) | 47/50 | 94.0% | ASCII 词 ≥3 + corpus 按章去重 + 评估口径对齐 |
|
||
|
||
最终:hit 48/50、quote 48/50、pass 47/50 = 94.0%(≥90% 门禁,FR-BIO-026 达标)
|
||
未通过 3 条:id 17/25/46,根因是长附录章(A.3 软件对照表、ch69 衔接章)在假嵌入下向量召回排名靠后
|
||
(真实 bge-m3 语义编码预期更好);已写入已知限制。
|
||
|
||
## 步骤 8:纪律与自测确认
|
||
|
||
- QA 树(8091)零改动:未触碰任何 QA 文件/进程
|
||
- vstore 既有集合与代码零改动:只新增 vstore/flow.py + vstore/scripts/ + vstore/tests/test_flow.py +
|
||
vstore/tests/fake_embed_utils.py + vstore/tests/testdata/(git status 确认无既有文件被改)
|
||
- 既有测试回归:vstore/tests/test_retrieval.py 等 10 用例 + 新增 5 用例全绿(15 passed)
|
||
- 不 commit/push/部署;自测全部 tmpdir,未连生产 vstore(8094)/ollama/8090/8091
|
||
- 凭据:语料明文扫描无凭据痕迹
|
||
|
||
## 已知限制(交 TL 裁决)
|
||
|
||
1. flow_docs 块正文为明文落盘(chunks/*.json)。语料均为团队内部公开分析文档,检索引用原文需要
|
||
明文;若 TL 要求加密,需把引用原文改为「检索时解密」模式(FlowStore.get_chunk 处可接入
|
||
crypto 模块),当前按「不加密」实现。
|
||
2. flow_docs 目录默认 vstore/data/flow_docs/ 未纳入 vstore 8094 服务 API;生产入库建议走独立
|
||
脚本/服务侧调用(A2 planner 检索 + A4 对话内咨询共用 FlowStore 本地实例)。
|
||
3. 假嵌入(fake_embed_utils.py)是管道自测替身,不代表 bge-m3 真实质量;真实嵌入评测由部署环境
|
||
用 run_flow_eval.py 默认模式(真 embed_batch)执行,预计真实嵌入下通过率不低于本记录。
|
||
4. 评估集 hit 口径含两条兜底(source 匹配 + 块正文含阶段词),已在评估集 meta.criteria 中明示。
|
||
|
||
## 交付物清单
|
||
|
||
| 文件 | 说明 |
|
||
|---|---|
|
||
| vstore/flow.py | flow_docs 集合(FlowStore:幂等入库/混合检索/维护) |
|
||
| vstore/scripts/ingest_flow_docs.py | 语料切块入库脚本(幂等可重跑) |
|
||
| vstore/scripts/run_flow_eval.py | 评估集评测脚本(检索命中+引用断言) |
|
||
| vstore/tests/test_flow.py | 单元测试(5 用例,tmpdir+假嵌入) |
|
||
| vstore/tests/fake_embed_utils.py | 假嵌入替身(自测用) |
|
||
| vstore/tests/testdata/eval_flow_docs.json | 评估集(50 条,8 类) |
|
||
| docs/team/report_bioflow_dev4.md | 本报告 |
|