Chat 访谈 - 新增 persona 系统(default / warm_listener / curious_guide)与 background_voice 语气层 - 回复长度由 compute_reply_plan 统一决策(brief / standard / expanded),融合信息密度启发式 - 输入净稿(input_normalize):编排层可选 rules/llm 归一用户口语后再喂模型与记忆检索 - 记忆证据注入:按用户话检索 memory evidence 并注入 prompt Memoir 回忆录 - 口述归一(oral_normalize):segment 原文保留,story 管线取派生净稿作叙事输入 - segment 入队批次门闸:累计字数 + 最长等待秒数,减少零碎提交 - fidelity_check / prompts / narrative_agent 微调 - Alembic 0005:清理跨章节 story 外键 Infra - Dockerfile 加入 ffmpeg - pyproject.toml 新增依赖并同步 uv.lock - .env.example / .env.production 补全新配置项 Tests - 新增 test_background_voice、test_chat_input_normalize、test_experience_regressions - 扩展 test_interview_prompts、test_interview_reply_length、test_story_route_oral_invariant Made-with: Cursor
60 lines
1.9 KiB
Python
60 lines
1.9 KiB
Python
"""ClassificationAgent:零散档案启发式与 none→summary 兜底(纯函数/无 LLM)。"""
|
||
|
||
import pytest
|
||
|
||
from app.agents.memoir.classification_agent import (
|
||
ClassificationAgent,
|
||
_looks_like_fragment_only,
|
||
_parse_category_from_llm_response,
|
||
)
|
||
|
||
|
||
@pytest.mark.parametrize(
|
||
"text,expected_fragment",
|
||
[
|
||
("", True),
|
||
(" ", True),
|
||
("我1999年出生", True),
|
||
("1999年出生。", True),
|
||
("1999年出生!", True),
|
||
("我是云南人", True),
|
||
("我是北京籍。", True),
|
||
("小学二年级那次下雨爷爷背我过河,鞋全湿了。", False),
|
||
("我出生在农村,家里养过一头黄牛。", False),
|
||
("我是北京人,后来去上海读了大学。", False),
|
||
],
|
||
)
|
||
def test_looks_like_fragment_only(text: str, expected_fragment: bool) -> None:
|
||
assert _looks_like_fragment_only(text) is expected_fragment
|
||
|
||
|
||
def test_classify_maps_birth_year_fragment_to_summary_without_llm() -> None:
|
||
agent = ClassificationAgent()
|
||
result = agent.classify("1999年出生", fallback_stage="childhood", llm=None)
|
||
assert result.category == "summary"
|
||
assert result.llm_said_none is False
|
||
|
||
|
||
@pytest.mark.parametrize(
|
||
"raw,expected",
|
||
[
|
||
('{"category": "childhood"}', "childhood"),
|
||
('```json\n{"category": "none"}\n```', "none"),
|
||
("childhood", "childhood"),
|
||
('"education"', "education"),
|
||
],
|
||
)
|
||
def test_parse_category_from_llm_response(raw: str, expected: str) -> None:
|
||
assert _parse_category_from_llm_response(raw) == expected
|
||
|
||
|
||
def test_classify_fallback_when_no_llm_and_narrative_snippet() -> None:
|
||
agent = ClassificationAgent()
|
||
out = agent.classify(
|
||
"小学二年级的时候我在操场上摔了一跤,膝盖流了很多血,是老师背我去医务室的。",
|
||
fallback_stage="childhood",
|
||
llm=None,
|
||
)
|
||
assert out.category == "education"
|
||
assert out.llm_said_none is False
|