| """IntentClassifier 测试(intent-understanding-layer 任务 5)。 |
| |
| 覆盖需求 3.1–3.4:描述性 / 货架期 / 未知分类,LLM 提示优先与关键词兜底。 |
| """ |
|
|
| from __future__ import annotations |
|
|
| from kernel.task_sheet import DocumentProfile, Intent |
| from kernel.understanding import IntentClassifier |
|
|
|
|
| def _empty_profile(): |
| return DocumentProfile() |
|
|
|
|
| def test_descriptive_by_keyword(): |
| c = IntentClassifier(llm=None) |
| assert c.classify("请帮我梳理各规格样品的质量属性规律", _empty_profile()) is Intent.DESCRIPTIVE_SUMMARY |
|
|
|
|
| def test_shelf_life_by_keyword(): |
| c = IntentClassifier(llm=None) |
| assert c.classify("请预测该产品的货架期", _empty_profile()) is Intent.SHELF_LIFE |
| assert c.classify("外推 36 个月的稳定性", _empty_profile()) is Intent.SHELF_LIFE |
|
|
|
|
| def test_unknown_when_no_keyword(): |
| c = IntentClassifier(llm=None) |
| assert c.classify("这是什么", _empty_profile()) is Intent.UNKNOWN |
|
|
|
|
| def test_unknown_when_ambiguous_both(): |
| c = IntentClassifier(llm=None) |
| |
| assert c.classify("梳理数据并预测货架期", _empty_profile()) is Intent.UNKNOWN |
|
|
|
|
| def test_llm_hint_takes_precedence(): |
| c = IntentClassifier(llm=None) |
| out = c.classify("随便什么", _empty_profile(), llm_hint="descriptive_summary") |
| assert out is Intent.DESCRIPTIVE_SUMMARY |
|
|
|
|
| def test_invalid_llm_hint_falls_back_to_keyword(): |
| c = IntentClassifier(llm=None) |
| out = c.classify("预测货架期", _empty_profile(), llm_hint="nonsense") |
| assert out is Intent.SHELF_LIFE |
|
|
|
|
| def test_compatibility_by_keyword(): |
| c = IntentClassifier(llm=None) |
| assert c.classify("评估原料药与辅料的相容性", _empty_profile()) is Intent.COMPATIBILITY |
| assert c.classify("API 与乳糖的配伍风险", _empty_profile()) is Intent.COMPATIBILITY |
|
|
|
|
| def test_compatibility_by_input_signature(): |
| """SMILES + 辅料同时存在 → 相容性强信号(优先于关键词)。""" |
| c = IntentClassifier(llm=None) |
| out = c.classify("", _empty_profile(), has_smiles=True, has_excipient=True) |
| assert out is Intent.COMPATIBILITY |
|
|
|
|
| def test_smiles_only_leans_compatibility(): |
| c = IntentClassifier(llm=None) |
| out = c.classify("", _empty_profile(), has_smiles=True) |
| assert out is Intent.COMPATIBILITY |
|
|
|
|
| def test_compatibility_llm_hint(): |
| c = IntentClassifier(llm=None) |
| out = c.classify("随便", _empty_profile(), llm_hint="compatibility") |
| assert out is Intent.COMPATIBILITY |
|
|
|
|
| def test_shelf_life_not_overridden_by_compat_signal(): |
| """明确外推意图时不被相容性关键词误夺(无 smiles+excipient 双信号)。""" |
| c = IntentClassifier(llm=None) |
| assert c.classify("预测货架期", _empty_profile()) is Intent.SHELF_LIFE |
|
|