fix(rag): keep practice headings with details
This commit is contained in:
@@ -21,6 +21,7 @@ from app.models.knowledge import (
|
||||
)
|
||||
from app.models.chat import ChatMessage
|
||||
from app.services.knowledge_agent_service import Candidate, KnowledgeAgentService
|
||||
from app.services.knowledge_pipeline_service import parse_sections
|
||||
|
||||
|
||||
def _database() -> Session:
|
||||
@@ -192,6 +193,10 @@ def test_homework_overview_expands_practice_terms_and_section_limit():
|
||||
assert KnowledgeAgentService._title_intent_boost("十七、练习一:风铃式静心", terms) == 20.0
|
||||
assert KnowledgeAgentService._title_intent_boost("完整练习的方向", terms) == 3.0
|
||||
assert KnowledgeAgentService._title_intent_boost("课程定位", terms) == 0.0
|
||||
assert KnowledgeAgentService._is_practice_overview("原生里的作业内容都有什么") is True
|
||||
assert KnowledgeAgentService._is_practice_overview(
|
||||
"关于“心光里都有什么功课”的追问:金色光练习具体内容是什么"
|
||||
) is False
|
||||
|
||||
|
||||
def test_homework_overview_keeps_all_numbered_practices_before_selection():
|
||||
@@ -264,3 +269,110 @@ def test_complete_section_includes_child_headings_but_stops_at_next_peer():
|
||||
|
||||
assert "鼻吸鼻呼" in content
|
||||
assert "下一项作业" not in content
|
||||
|
||||
|
||||
def test_same_level_practice_headings_are_read_as_one_semantic_unit():
|
||||
with _database() as db:
|
||||
knowledge = _add_published_knowledge(db, knowledge_id=1, name="心光课程")
|
||||
version_id = knowledge.current_version_id
|
||||
parent = db.scalar(select(KnowledgeSection).where(KnowledgeSection.version_id == version_id))
|
||||
assert parent is not None
|
||||
parent.title = "二十九、练习一:金色光欧姆静心"
|
||||
parent.content = "# 二十九、练习一:金色光欧姆静心"
|
||||
parent.sort_order = 1
|
||||
parent_chunk = db.scalar(select(KnowledgeChunk).where(KnowledgeChunk.section_id == parent.id))
|
||||
assert parent_chunk is not None
|
||||
parent_chunk.title = parent.title
|
||||
parent_chunk.content = parent.content
|
||||
parent_chunk.normalized_text = "金色光 欧姆 静心 练习"
|
||||
detail = KnowledgeSection(
|
||||
knowledge_id=knowledge.id,
|
||||
version_id=version_id,
|
||||
section_key="S0002",
|
||||
title="基础原则",
|
||||
content="# 基础原则\n练习时保持自然呼吸,不追求必须看见金色光。",
|
||||
source_start=10,
|
||||
source_end=50,
|
||||
sort_order=2,
|
||||
content_hash="detail",
|
||||
)
|
||||
db.add_all([
|
||||
parent,
|
||||
parent_chunk,
|
||||
detail,
|
||||
KnowledgeSection(
|
||||
knowledge_id=knowledge.id,
|
||||
version_id=version_id,
|
||||
section_key="S0003",
|
||||
title="三十、金色光练习的现实边界",
|
||||
content="# 三十、金色光练习的现实边界\n不能替代医疗诊断。",
|
||||
source_start=51,
|
||||
source_end=80,
|
||||
sort_order=3,
|
||||
content_hash="boundary",
|
||||
),
|
||||
KnowledgeSection(
|
||||
knowledge_id=knowledge.id,
|
||||
version_id=version_id,
|
||||
section_key="S0004",
|
||||
title="三十一、练习二:纠缠之心静心",
|
||||
content="# 三十一、练习二:纠缠之心静心\n下一项练习内容。",
|
||||
source_start=81,
|
||||
source_end=120,
|
||||
sort_order=4,
|
||||
content_hash="next",
|
||||
),
|
||||
])
|
||||
db.flush()
|
||||
db.add(
|
||||
KnowledgeChunk(
|
||||
knowledge_id=knowledge.id,
|
||||
version_id=version_id,
|
||||
section_id=detail.id,
|
||||
title=detail.title,
|
||||
content=detail.content,
|
||||
normalized_text="金色光 基础原则 自然呼吸 画面",
|
||||
keywords='["金色光","自然呼吸"]',
|
||||
synonyms="[]",
|
||||
source_start=detail.source_start,
|
||||
source_end=detail.source_end,
|
||||
sort_order=1,
|
||||
content_hash="detail-chunk",
|
||||
)
|
||||
)
|
||||
db.commit()
|
||||
|
||||
content = KnowledgeAgentService._read_complete_section(db, detail)
|
||||
result = asyncio.run(
|
||||
KnowledgeAgentService.build_result(db, question="金色光欧姆静心具体怎么练习?")
|
||||
)
|
||||
|
||||
assert "金色光欧姆静心" in content
|
||||
assert "保持自然呼吸" in content
|
||||
assert "不能替代医疗诊断" in content
|
||||
assert "下一项练习内容" not in content
|
||||
assert result.chunks
|
||||
assert "保持自然呼吸" in result.chunks[0].content
|
||||
|
||||
|
||||
def test_parser_merges_practice_title_and_same_level_detail_headings():
|
||||
source = """# 二十九、练习一:金色光欧姆静心
|
||||
# 练习定位
|
||||
帮助学员稳定注意力。
|
||||
# 基础原则
|
||||
保持自然呼吸,不追求画面。
|
||||
# 三十、金色光练习的现实边界
|
||||
不能替代医疗诊断。
|
||||
# 三十一、练习二:纠缠之心静心
|
||||
这是下一项练习。
|
||||
"""
|
||||
|
||||
sections = parse_sections(source)
|
||||
|
||||
assert [section.title for section in sections] == [
|
||||
"二十九、练习一:金色光欧姆静心",
|
||||
"三十一、练习二:纠缠之心静心",
|
||||
]
|
||||
assert "基础原则" in sections[0].content
|
||||
assert "现实边界" in sections[0].content
|
||||
assert "下一项练习" not in sections[0].content
|
||||
|
||||
Reference in New Issue
Block a user