Files
PlantAI-rag-new/docs/team/report_bioflow_dev2.md
T

168 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# report_bioflow_dev2 —— P1 生信服务地基(开发 agent A2)
> 任务书:docs/team/brief_bioflow_dev2_p1.md
> 工作分支:feature/bioflow-conversation-orchestration(保持,不切换)
> 纪律:不 commit/push/部署;不碰生产服务(8090/8091);服务层零 pydantic;零硬编码
## 1. 交付概览
| 模块 | 说明 |
|---|---|
| bioflow_service/(新增,独立部署树) | 生信服务 8098:FastAPI + 独立 SQLite + docker 执行器 + 状态机 + 规划器 |
| sdk/app/routers/bioflow_proxy.py(新增) | BFF 流式反代 + 报告登记端点 |
| sdk/app/main.py(2 行改动) | BIOFLOW_ENABLED 开关注册反代路由 |
| sdk/app/config.py(2 键) | bioflow_enabled(默认 false)/ bioflow_service_url |
| docs/team/report_bioflow_dev2.md | 本报告 |
## 2. 模块清单(bioflow_service/app/)
**明文白名单(编译管线保留 .py)**
- `config.py` —— BIOFLOW_ 前缀配置(pydantic-settings):image_map_path(仓库内
bioflow_kernel/stage_image_map.json,按 __file__ 推导 repo 根)、data_root/
jobs_dir/db_path/archives_dir/flow_docs_dir(全部可覆盖,无写死宿主路径)、
concurrency=3、stage_timeout_sec、host_uid_env=BIOFLOW_HOST_UID(默认服务进程
os.getuid() 推导)、container_data_dir=/bioflow-data、upload 白名单、DOCGEN_LLM_*
沿用 docgen 直连模式;bba_env 属性从配置推导 BBA_PFAM_DIR/BBA_RAG_MAPPING_FILE。
- `schemas.py` —— pydantic 请求/响应模型(ChatStreamRequest/JobCreateRequest/
StageConfirmRequest/ArchiveCreateRequest 等 10 个;STAGE/JOB 状态 Literal)。
- `db.py` —— 独立 SQLite(WAL)三表 + 幂等迁移(CREATE IF NOT EXISTS + PRAGMA
table_info 增量列):bio_jobs/bio_stages/bio_archives(字段与实施计划 §六对齐);
bio_stages UNIQUE(job_id, stage),job 删除级联。
- `main.py` —— FastAPI 组装 + lifespan(init_db→init_context→recover→shutdown);
health 端点 /api/bioflow/health(db 连通状态字段,FR-BIO-025 探活用)。
**服务层(全部 dataclass/dict/stdlib,无 pydantic,Cython 编译)**
- `services/bioflow/kernel.py` —— Docker 执行器:读 A1 stage_image_map.json
(75 阶段/8 镜像),按阶段→镜像拼 docker run(--user uid/三目录挂载/BIOFLOW_DATA
只读/-e BBA_*/--cpus/--memory/--rm + `python -B -m cli.run_{stage}`,list 无 shell);
cpu/memory 白名单回落;超时 terminate→kill;日志落任务 logs/ + 尾 80 行截断;
跨环境 note 透传(编排层 P2 拆分依据)。
- `services/bioflow/runner.py` —— 任务状态机:created→await_inputs→running→
paused/done/failed/archived;阶段 waiting→await_files→waiting_confirm→queued→
running→done/failed/skipped;输入检查(FR-BIO-005)→确认门(FR-BIO-008,confirm
`_confirmed` 旁路防二次确认门)→并发信号量(BIOFLOW_CONCURRENCY 默认 3,
FIFO 排队)→docker→manifest 判成败(no_manifest/manifest_failed/timeout/
exit_code 四因);pause 停阶段边界、resume 不跳过确认、rerun/skip 状态校验;
重启恢复 recover():running 阶段按 manifest 判成败(有 success manifest→done
否则重跑)、done 不重跑(attempt 不变)、archived 跳过。
- `services/bioflow/catalog.py` —— 阶段目录(映射表驱动 + STAGE_INFO/STAGE_DEPENDENCIES
静态快照,不运行时反射);73 阶段(真实表 75 去重复校验)、基因家族链 21 阶段、
手写参数 schema(identify 11 参数含 default/source/help,source 标注
contract/user/runtime 供表单默认值来源可见);validate_chain 未知阶段拒绝 +
auto_fill_prerequisites 前置补全(拓扑排序依赖在前)。
- `services/bioflow/planner.py` —— 路径规划:复用句式(「用 XXX 存档任务的方法…」)
→ archive 直接装载;否则知识库检索(vstore/flow.py FlowStore 本地实例混合检索,
失败降级 llm_only)+ LLM 候选(DOCGEN_LLM_* 直连,JSON 模式 + 修复重试)→
catalog 硬校验(未知阶段拒绝、前置补全);PLAN_LLM_TIMEOUT/PLAN_UNAVAILABLE
降级内置兜底链。
- `services/bioflow/manifests.py` —— manifest 解析校验(manifest_v1.schema 必需字段;
定位 final/{prefix}.{stage}.manifest.json,无兜底防跨阶段误配);跨阶段输入定位
(artifacts full_path 解析 + 存在性检查)。
- `services/bioflow/events.py` —— 事件总线(12 类事件全集 + job_recovered):
进程内 pub/sub(SSE 订阅)+ 内存环形缓冲 + events/{job_id}.jsonl 持久
(重启回放)+ snapshot 首帧 + replay(after_seq) 断线回放。
- `services/bioflow/llm.py` —— LLM 直连(docgen 同款:指数退避 + JSON 修复 +
LLMTimeout/LLMUnavailable 分型)。
- `services/bioflow/params.py` —— 参数预填(契约文档参数解析 + BBA_* 默认值标注 +
存档参数预填)。
- `services/bioflow/reports.py` —— 报告登记(报告 HTML 定位/fig:// 图清单提取/
登记载荷(job_id/标题/md/图清单)+ 内部 HTTP 调 BFF 反代端点,BFF 不可达降级)。
- `services/bioflow/archive.py` —— 存档打包(final/结果+logs/过程+events.jsonl
过程记录+input 原始文件;include_intermediate 开关含中间文件;zip 下载)。
- `services/bioflow/store.py` —— 三表 CRUD(upsert/list/get/delete;归档精确优先
模糊匹配、reused_count 计数)。
- `services/bioflow/intent.py` —— 意图分流(cases_bioflow_intent.md 冻结词典同表:
export→edit→docgen→附件 docgen→bioflow_qa(FLOW_QA 命中即拦)→bioflow
(动词+家族语境词/分析对象)→qa 漏判安全;复用方法名提取 3-20 字符;
>2000 字符截断判定)。
**路由**
- `routers/bioflow.py` —— health/catalog(?stage=/?chain=gene_family)/
chat/stream(SSE:意图分流→plan_ready 候选→心跳;plan seq 编码 data 载荷直出)/
ask(知识库引用块:source/title_path/path/cite/line/text)。
- `routers/biojobs.py` —— jobs 全套(POST 201/列表 rowid 倒序分页过滤/详情/删除
running 409);files(multipart 流式逐块写盘 + 扩展名白名单 + 大小上限 413 +
server_path 登记限 data_root/任务目录白名单 403);stages confirm(参数校验
未知 422)/rerun(带参数→waiting_confirm)/skip/pause/resume/manifest(manifest
对象 + 日志尾 80 行);events SSE(snapshot 首帧 + 回放 + 实时订阅 + 任务终态
关闭 TC-BIO-API-081);report revise(最小接口:无图目标 422/绘图阶段定位)。
- `routers/bioarchives.py` —— archives 全套(存档 201 重名 409/列表/详情/删除
磁盘+行/run 复用/按名匹配 404 ARCHIVE_NOT_FOUND/download zip/report HTML);
reports/register(归一化 + 图清单回填,BFF 反代落 doc_artifacts)。
**构建与运维**
- `build.sh` —— 复制 tooling/compile/compile_sdk.sh 改白名单(明文:main.py/
config.py/schemas.py/db.py + __init__.py 规则;schemas= pydantic cyfunction 教训、
db= 断流崩溃根治教训);16 模块 Cython+GCC 全过(实测 /tmp 输出 16 .so,
编译树 import OK)。
- `restart.sh` —— 8098 重启(零硬编码:路径脚本位置推导 + 环境变量覆盖)。
- `tests/` —— pytest(-m bioflow_unit 127 用例 / -m bioflow_api 39 用例)。
## 3. 自测结果(2026-09-06,服务器 venv 3.12.13)
| 命令 | 结果 |
|---|---|
| `python -m pytest tests/ -q` | **166 passed**(15.7s,0 warnings) |
| `python -m pytest tests/ -q -m bioflow_unit` | 127 passed |
| `python -m pytest tests/ -q -m bioflow_api` | 39 passed |
| build.sh → /tmp 编译 + 编译树 import | 16 模块 .so,import OK |
| BFF BIOFLOW_ENABLED=false/true 双态 import | 均 OK(反代路由 2 条) |
| 真实 stage_image_map.json 加载 | 75 阶段/8 镜像/identify 11 参数/命令拼装正确 |
| /home/xzq 硬编码扫描(app+tests) | 0 处 |
全部 mock docker/LLM/vstore(tmpdir + fake 执行器),不连任何生产服务
(8090/8091/8094/8098 从未探测)。
## 4. 已知限制(交 TL 裁决)
1. **SSE 传输层测试法**:本环境 fastapi TestClient 的 sync stream 包装与 httpx
ASGITransport 对永不结束的 SSE 流均存在首帧不达/整流缓冲问题(dbg3/dbg6 最小
复现实证),SSE 用例改为端点直调迭代 body_iterator + 模块级共享 event loop
(anyio portal 绑定首个 loop,跨 loop 死锁实证)。生产部署(uvicorn 真实网络
SSE)不受影响;如 TL 要求 TestClient 原生流测试,需另行排查 fastapi/anyio
版本组合。
2. **catalog 阶段数口径**:任务书口径 73;A1 交付 stage_image_map.json 实为 75
阶段(含 module=null 的 synteny_plot_revise 与 executable=false 的 msa/
enrichment)。kernel 对 module=null 阶段拼命令前置拦截(UnknownStageError),
catalog 全量返回 75。以 A1 交付物为准,口径差异记录备查。
3. **gene_family 链为 21 阶段**(A1 family_chain 实测 21,任务书口径约 18);
以 stage_image_map.json family_chain 字段为唯一事实源。
4. **FlowStore 生产数据未入库**:vstore/data/flow_docs 目录当前不存在(A4 自测
在 tmpdir 完成;真实语料 106 文件/724 块需 TL 部署时跑
vstore/scripts/ingest_flow_docs.py 入库)。planner 已按本地实例对接(加载成功
零块时检索空 → LLM 候选照常,降级链完整);生产前入库即可获得 KB 增强
(llm_rag source)。
5. **chat/stream 是规划入口**:plan_ready 后保持心跳连接,任务创建走
POST /jobs(P1 契约);会话级任务事件经 /jobs/{id}/events 订阅。若 TL 要求
chat/stream 单流贯穿任务事件(A3 前端形态),需 P2 加会话级订阅联动。
6. **报告登记 BFF 侧 doc_artifacts 落库**:bioflow_proxy.register_report 字段
(job_id/session_id/标题/md_path/图清单)已按约定实现;图清单字段当前存于
请求体(doc_artifacts 表无 figures 列,如需持久化图清单需 TL 裁决加列——已
在 payload 透传中保留)。与 A3 report 模板的 fig:// 渲染协调点:报告 HTML 内
fig://id 引用清单由生信服务 reports.extract_figure_refs 提供。
7. **意图词典判定为启发式快照**:与 cases_bioflow_intent.md 冻结表逐条对齐
(40 用例表全过);家族名语境词规则(「SPL 会议」不命中)为词典实现注意第
1/4 条的工程化解读,最终同表双跑一致性以 TC-BIO-INTENT-047(L2 用例)验收。
8. **事件持久化目录**:events/{job_id}.jsonl 与任务目录分离(bioflow_data/
jobs/events/);归档时打包进档案根。任务删除不清理事件文件(留审计),
如需一并删除交 TL 裁决。
9. **镜像 tag 后缀**:docker_image_tag_suffix 默认 "dev"(A1 交付物 :dev);
发布流水线(P2 FR-BIO-032 compile_bioflow.sh)需按终态 tag 覆盖环境变量。
10. **pytest.ini python_files 陷阱**:本仓库 pytest 9.1.1 下 `python_files =
["test_*.py"]`(列表形式)会导致目录级收集 0 用例(单文件显式传参正常),
已用字符串形式 `python_files = test_*.py` 规避并实证;写报告备案防踩。
## 5. 交付物清单
| 文件 | 说明 |
|---|---|
| bioflow_service/app/{config,schemas,db,main,context}.py | 应用骨架(4 明文 + context) |
| bioflow_service/app/services/bioflow/*.py | 服务层 12 模块(零 pydantic) |
| bioflow_service/app/routers/{bioflow,biojobs,bioarchives}.py | 端点三层 |
| bioflow_service/build.sh / restart.sh | 编译白名单管线 / 重启脚本 |
| bioflow_service/pytest.ini | markers + python_files(字符串形式陷阱规避) |
| bioflow_service/tests/*.py | 10 文件 166 用例 |
| sdk/app/routers/bioflow_proxy.py | BFF 流式反代 + 报告登记 |
| sdk/app/main.py(+2 行)/ sdk/app/config.py(+2 键) | BFF 最小改动 |
| docs/team/report_bioflow_dev2.md | 本报告 |