Files
PlantAI-dev/docs/subfamily_evidence_scope_manifest_case_2026-05-28.md
2026-08-03 18:42:47 +08:00

11 KiB
Executable File
Raw Permalink Blame History

亚家族确认证据图 scope/manifest 修订案例总结

日期:2026-05-28
关联问题:亚家族确认弹窗中已经生成 combo 图,但右侧证据区域显示“未找到 combo PNG”。

1. 本次遇到的问题

用户在执行 Lc 的 SPL 亚家族分类相关流程后,final/ 中已经存在 combo 图:

Lc.SPL.target_plus_reference.combo.png

但在亚家族确认弹窗中,右侧“矩形树 + 亚家族 + Motif/Structure/Domain”证据区显示:

未找到 combo PNG

进一步检查当前 job:

job_id = job_1779966938704_aa384a

真实文件和 manifest 中存在两套前缀:

亚家族预测/确认 prefix:
Target.SPL.target-Lc.ref-At.subfamily_prediction

传统/分物种 combo 文件:
Lc.SPL.target_plus_reference.combo.png

共同 scope_id:
SPL.target-Lc.ref-At.target_plus_reference

也就是说,combo 图不是没有生成,而是弹窗读取证据图时只用当前 prefix 做 glob:

Target.SPL.target-Lc.ref-At.subfamily_prediction*combo*.png

这个模式当然找不到:

Lc.SPL.target_plus_reference.combo.png

2. 为什么不能继续用 prefix fallback 修

最初直觉可能是增加 fallback:

Target.SPL.target-Lc.ref-At.subfamily_prediction
  -> Lc.SPL
  -> Lc.SPL.target_plus_reference.combo.png

但这会重新走回历史问题:不同模块根据文件名互相猜 prefix。

这样做的问题:

  • 容易把 target/reference/comparative 角色重新写进临时字符串规则。
  • 多物种、比较物种、确认后分析、子集分析会继续出现新的特殊分支。
  • 与 2026-05-26 和 2026-05-27 两份命名/scope 文档的方向相反。

因此本次修订不能做“猜另一个 prefix”的补丁,而应回到文档确定的原则:scope/manifest 是机器身份,文件名只是用户可读显示名。

3. 26 日文档给出的原则

参考:

  • docs/gene_family_stage_naming_scope_rules_2026-05-26.md
  • docs/gene_family_unified_rules_summary_2026-05-26.md
  • docs/stage_requirements_agent_refactor_plan_2026-05-26.md

关键原则如下。

3.1 scope 不能取消

scope_id、scope_mode、target_species、reference_species、comparative_species 必须保留,因为它们描述一次分析的真实范围。

本案例中,真实范围是:

family = SPL
target_species = Lc
reference_species = At
scope_mode = target_plus_reference
scope_id = SPL.target-Lc.ref-At.target_plus_reference

所以判断两个结果是否属于同一次分析范围,应该看 scope_id,而不是只看文件名前缀。

3.2 文件名不应完整暴露 scope_id

26 日文档明确指出,不应继续把:

prefix + scope_id

直接拼成用户主文件名,例如:

Lc.SPL.SPL.target-Lc.ref-At.target_plus_reference.structure.png

scope 应进入 manifest,而不是污染用户可见文件名。

3.3 结果展示应读 manifest,而不是各自 glob

stage_requirements_agent_refactor_plan_2026-05-26.md 中已经明确:

  • stage_identity.py 管阶段身份;
  • stage_status.py 管完成状态;
  • artifact_resolver.py 管候选 artifact;
  • stage_requirements.py 管输入需求;
  • 结果展示和诊断不应各自私有 glob 文件名。

本案例中的错误正是结果展示层仍在私有 glob。

4. 27 日文档给出的更完整方向

参考:

  • docs/gene_family_unified_naming_full_revision_plan_2026-05-27.md
  • docs/subfamily_species_selection_unified_revision_plan_2026-05-27.md

27 日文档进一步明确了三类前缀和 manifest 职责。

4.1 三类前缀必须分清

名称 用途 示例
species_prefix 单物种成员和传统分析主体 Lc.SPL
scope_prefix 用户可读范围前缀 Target.SPL.target-Lc.ref-At.subfamily_prediction
legacy_scope_prefix 旧系统兼容前缀 Lc.SPL.SPL.target-Lc.ref-At.target_plus_reference

本案例中:

species_prefix = Lc.SPL
scope_prefix = Target.SPL.target-Lc.ref-At.subfamily_prediction
scope_id = SPL.target-Lc.ref-At.target_plus_reference

弹窗证据图不能假定 scope_prefix 和 combo 图文件名前缀完全一致。

4.2 manifest 承担完整身份

27 日文档要求 manifest 中记录:

{
  "scope_id": "...",
  "scope_mode": "...",
  "analysis_route": "...",
  "member_set_id": "...",
  "result_group": "...",
  "output_prefix": "...",
  "artifacts": {}
}

状态判断、结果展示、依赖解析必须读这些字段,不能再依赖文件名是否包含 target_plus_reference。

4.3 亚家族预测、证据图、确认后分析要区分

27 日文档把这些场景拆开:

  • subfamily_prediction:参考亚家族迁移/预测;
  • subfamily_evidence:确认前辅助判断的 motif/domain/structure/combo 证据;
  • confirmed_subfamily:人工确认后的正式分析。

本案例的 combo 是确认前证据,应由亚家族确认弹窗读取为 evidence asset,而不是和普通传统 combo 结果混为一谈。

5. 本次真实证据链

当前 aggregate reference_classification manifest:

Lc.SPL.SPL.target-Lc.ref-At.target_plus_reference.reference_classification.manifest.json

其中包含:

{
  "output_prefix": "Target.SPL.target-Lc.ref-At.subfamily_prediction",
  "legacy_output_prefix": "Lc.SPL.SPL.target-Lc.ref-At.target_plus_reference",
  "scope_id": "SPL.target-Lc.ref-At.target_plus_reference",
  "analysis_route": "subfamily_prediction",
  "per_species_results": [
    {
      "species": "Lc",
      "prefix": "Lc.SPL",
      "combo": ".../final/Lc.SPL.target_plus_reference.combo.png"
    }
  ]
}

同时 per-species manifest:

Lc.SPL.target_plus_reference.reference_classification.manifest.json

也包含:

{
  "scope_id": "SPL.target-Lc.ref-At.target_plus_reference",
  "artifacts": {
    "evidence_combo_png": {
      "path": "final/Lc.SPL.target_plus_reference.combo.png",
      "type": "image"
    }
  }
}

因此,正确读取路径已经在 manifest 中,不需要再猜文件名。

6. 最终修订思路

本次修订边界:

  • 只修读侧:/api/subfamily/review 如何收集 evidence assets。
  • 不改 CLI 输出命名。
  • 不改 run_combo.py。
  • 不推进全局命名迁移。
  • 不新增 prefix 猜测规则。

核心改法:

  1. _subfamily_evidence_assets(job_id, prefix) 先读取当前 reference_classification manifest。
  2. 从 manifest 中收集:
    • artifacts[*combo*]
    • artifacts[*tree*]
    • per_species_results[*].combo
    • per_species_results[*].tree
    • per_species_results[*].circular_tree
  3. 从当前 manifest 读取 scope_id。
  4. 再扫描同 scope_id 的 reference_classification / combo manifest。
  5. 从同 scope manifest 的 artifacts 中继续收集证据图。
  6. 只有 manifest 找不到时,才使用旧的 prefix glob fallback。

新增 helper:

_manifest_scope_id()
_final_artifact_path()
_iter_scope_matched_manifests()

7. 修订后的验证结果

真实 API 验证:

/api/subfamily/review?job_id=job_1779966938704_aa384a&prefix=Target.SPL.target-Lc.ref-At.subfamily_prediction

修订后返回:

success True
prefix Target.SPL.target-Lc.ref-At.subfamily_prediction
missing []
rect_combo file  Lc.SPL.target_plus_reference.combo.pdf
rect_combo image Lc.SPL.target_plus_reference.combo.png
circular_tree image Target.SPL.target-Lc.ref-At.subfamily_prediction.reference_classification.tree.circular_tree.png
tree image Target.SPL.target-Lc.ref-At.subfamily_prediction.reference_classification.tree.png

这说明弹窗已经能通过 manifest/scope 找到同 scope combo 图。

新增回归检查:

scripts/check_subfamily_evidence_scope.py
tests/unit/test_subfamily_evidence_scope.py

验证命令:

/home/xia-lab/miniconda3/envs/test4py311/bin/python scripts/check_subfamily_evidence_scope.py
/home/xia-lab/miniconda3/envs/test4py311/bin/python -m pytest -q tests/unit/test_subfamily_evidence_scope.py

8. 这个案例对后续修订的指导意义

8.1 不要把“短期读侧修复”和“全局命名迁移”混淆

本案例属于读侧修复:

已有 artifact 存在,但展示层没有按 scope/manifest 找到。

因此可以先修 /api/subfamily/review,不需要等 identify 全局迁移完成。

但这不代表可以跳过 27 日文档中的全局主线:

命名 helper -> identify -> StageRequirements -> PlanningAgent/web plan -> pipeline_backend -> CLI 第二批 -> result/diagnosis/reproducibility

8.2 能读 manifest 就不要猜文件名

后续遇到类似问题时,判断顺序应是:

  1. manifest 中是否已有 artifact path?
  2. manifest 是否有 scope_id 可以关联同 scope 的其他 manifest?
  3. scope 文件是否能补充 target/reference/comparative?
  4. artifact resolver 是否已有候选?
  5. 最后才考虑 legacy glob。

不要优先写:

if prefix startswith Target... then try Species.Family...

这类规则会重新引入历史混乱。

8.3 历史文档的使用方式

建议把几份文档按层级使用:

文件 用途
gene_family_stage_naming_scope_rules_2026-05-26.md 判断 scope 和用户文件名边界:scope 保留,文件名不暴露完整 scope
gene_family_unified_rules_summary_2026-05-26.md 判断规则是否有唯一来源,避免前端/后端/CLI 重复识别
stage_requirements_agent_refactor_plan_2026-05-26.md 判断职责边界:identity/status/artifact/requirements/diagnosis 各司其职
gene_family_unified_naming_full_revision_plan_2026-05-27.md 全局命名迁移的主计划,尤其是三类 prefix、manifest 字段、阶段迁移顺序
subfamily_species_selection_unified_revision_plan_2026-05-27.md 亚家族分类中物种选择、target/reference/comparative 同步规则

8.4 后续修订前必须先判断问题类型

每次修订前先归类:

问题类型 修订策略
产物命名不符合新规则 走 27 日全局命名迁移,不临时改单脚本
展示层找不到已存在结果 manifest/scope-first 读侧修复
规划物种列表不一致 按 27 日 subfamily species selection 文档同步 plan/intent/stages_detail
输入缺失或依赖误判 走 StageRequirements,不在 PlanningAgent/main.py 私有 glob
自动填表识别错误 只改 run_config_autofill.py 或 run_samples_autofill.py,不在前端写第二套规则

8.5 本案例的原则总结

一句话:

如果 artifact 已经存在,展示层必须通过 manifest/scope 找到它;不能因为用户可读 prefix 不一致就显示缺失。

这正是 26/27 日文档要解决的问题之一。