"""partition_entry_text grounding: paraphrased percentages must survive (截图 GPA 丢失根因).""" from __future__ import annotations from app.claim_validator import partition_entry_text FACTS = [{"id": "entry_description", "field": "description", "text": "学习数据结构、计算机视觉课程。GPA: 4.3/5.0,排名前百分之10。"}] def test_percentage_paraphrase_is_not_quarantined() -> None: """LLM 把「前百分之10」改写成「前 10%」是同一事实,不得隔离。""" candidate = "主修数据结构、计算机视觉等课程。GPA 4.3/5.0,年级排名前 10%。" optimized, suggestions, _warnings = partition_entry_text(candidate, FACTS) assert "10%" in optimized assert "4.3" in optimized assert suggestions == [] def test_truly_new_numbers_remain_visible_and_require_confirmation() -> None: """用户没提过的数字(如「提升 37%」)必须继续被隔离。""" facts = [{"id": "entry_description", "field": "description", "text": "完成数据库课程项目。"}] optimized, suggestions, _warnings = partition_entry_text("完成数据库课程项目,性能提升 37%。", facts) assert "37" in optimized assert suggestions assert _warnings == ["candidate_requires_confirmation"] def test_bullet_line_structure_is_preserved() -> None: """LLM 按行输出的 bullet 不得在防虚构分区时被拍平成一行(前端排版根因)。""" facts = [{"id": "entry_description", "field": "description", "text": "负责需求分析与全链路开发。使用 LangGraph 编排优化流程。完成部署上线。"}] candidate = "• 负责需求分析与全链路开发。\n• 使用 LangGraph 编排优化流程。\n• 完成部署上线。" optimized, _suggestions, _warnings = partition_entry_text(candidate, facts) assert optimized == candidate