Files
PlantAI-rag-new/bioflow_service/tests/test_intent.py
adminandClaude Fable 5 bd011650f6 fix(bioflow): 意图分流收窄 v1.1——仅明确分析指令进生信流,问答句一律 qa
用户反馈:不是所有对话都走生信编排,只有「用xxx进行分析」「帮我分析xxx」
类明确指令才是生信流程;「水稻SPL基因家族的最新研究进展有哪些?」
等问答句必须走原正常问答流程。

- intent.py/intent.js 同表双跑:任务动词+对象 / 前缀分析句式 / 分析链句式
  三通道;新增疑问引导词+问答主题词两道拦截;「研究」移出任务动词
  (「帮我研究一下水稻SPL家族」经前缀通道仍保 bioflow)
- cases_bioflow_intent.md 升 v1.1:40+15 用例,新增 #41-#55 问答句收窄
- test_intent.py 补 v1.1 用例,50 条全绿;PRD FR-BIO-001 同步收窄
- 部署:8098 已重启,ui/dist 重建同步 deploy-unified,浏览器端到端验证 PASS
  (问答句走 /api/qa/chat/stream,分析指令走 /api/bioflow/chat/stream 出路径卡)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-07 18:13:52 +08:00

115 lines
4.1 KiB
Python

"""tests/test_intent.py —— 意图分流词典(cases_bioflow_intent.md 冻结表)后端同表双跑。
覆盖词典 §2 判定顺序 + 用例表关键行 + 复用句式(TC-BIO-INTENT 对应后端行)。
"""
from __future__ import annotations
import pytest
from app.services.bioflow.intent import extract_reuse_name, route
pytestmark = pytest.mark.bioflow_unit
@pytest.mark.parametrize("text", [
"帮我跑水稻 SPL 家族鉴定",
"跑一下拟南芥 MADS-box 家族分析",
"请帮我鉴定水稻 SPL 家族",
"识别玉米 bZIP 家族成员",
"帮我研究一下水稻 SPL 基因家族",
"分析小麦 WRKY 转录因子家族",
"做个大豆 NAC 家族分析",
"跑 SPL 家族",
"水稻 SPL 家族,帮我跑",
"基因家族鉴定:水稻 SPL",
"帮我跑水稻叶片 RNA-seq 差异表达分析",
"帮我做水稻全基因组变异检测",
"帮我跑水稻产量性状 GWAS 关联分析",
"Please run rice SPL family identification",
"跑水稻 spl 家族鉴定",
# v1.1 新增:明确分析指令仍进生信
"帮我分析水稻SPL基因家族",
"帮我做一下水稻全基因组变异检测",
"帮我分析鉴定水稻 SPL 家族",
])
def test_bioflow_hits(text):
assert route(text) == "bioflow"
@pytest.mark.parametrize("text", [
"什么是基因家族?",
"帮我跑一下",
"SPL 家族",
"今天天气不错",
"跑 SPL 家族鉴定需要准备什么输入?",
"帮我跑一个数据分析",
"你好呀",
"",
" ",
"帮我跑香蕉 XYK 家族鉴定",
"这个 SPL 会议帮我跑一下流程",
"用 XXX 存档任务的方法",
"用 XXX 存档任务的方法帮我跑 yyy",
# v1.1 新增:问答句一律 qa(用户 2026-09-07 反馈收窄)
"水稻SPL基因家族的最新研究进展有哪些?",
"水稻 SPL 基因家族最新研究进展",
"水稻SPL基因家族研究进展如何?",
"水稻SPL基因家族有哪些最新的研究成果?",
"SPL 基因家族有什么新的发现吗?",
"怎么用 PlantAI 分析水稻 SPL 家族",
"如何跑水稻 SPL 家族鉴定",
"什么软件做全基因组注释",
"帮我分析水稻 SPL 家族的最新研究进展",
"水稻 SPL 家族研究综述",
"帮我看看水稻 SPL 家族",
])
def test_qa_fallback(text):
assert route(text) == "qa"
def test_docgen_first():
assert route("帮我生成一份水稻 SPL 家族分析报告") == "docgen"
assert route("帮我写一篇水稻基因家族研究论文") == "docgen"
def test_docgen_attachment():
assert route("帮我整理一份材料", has_attachments=True) == "docgen"
def test_export_priority():
assert route("导出成 PDF", has_active_artifact=True) == "export"
def test_edit_priority():
assert route("把这句话改成红色", has_active_artifact=True) == "edit"
def test_chart_word_skips_edit_goes_bioflow():
# 图表调整走生信(FR-BIO-019):edit 规则被 CHART_WORD 排除
assert route("xxx 图表颜色换成红色", has_active_artifact=True) == "bioflow"
def test_bioflow_qa_in_context():
assert route("identify 需要什么输入", has_bioflow_context=True) == "bioflow_qa"
# 无上下文 → qa
assert route("identify 需要什么输入") == "qa"
def test_reuse_patterns():
for text in [
"用 XXX 存档任务的方法帮我跑水稻 SPL 家族鉴定",
"根据 XXX 存档任务的方法帮我跑一下玉米 bZIP",
"参考 XXX 存档的方法再跑一个水稻 SPL",
"用《XXX》存档任务的方法帮我跑小麦 WRKY 家族",
]:
assert route(text) == "bioflow"
def test_extract_reuse_name():
assert extract_reuse_name("用 XXX 存档任务的方法帮我跑水稻 SPL 家族鉴定") == "XXX"
assert extract_reuse_name("根据水稻SPL存档 存档任务的方法帮我跑玉米 bZIP") is not None
assert extract_reuse_name("帮我跑水稻 SPL 家族鉴定") is None
# 方法名长度 3-20 截取
name = extract_reuse_name("用 水稻SPL家族鉴定流程 存档任务的方法帮我跑玉米 bZIP")
assert name is not None and 3 <= len(name) <= 20