Files
life-echo/api/tests/test_interview_prompts.py
Kevin 064ad2161d refactor(eval+memoir):精简内部评测路由与服务,composite/对话摘要与 judge 能力补强
- 访谈:新增 interview_state_hints,联动 orchestrator 与提示词
- 回忆录:story_pipeline_sync/state/memory/post_commit 与 Celery 任务调整
- 基建:开发用 celery broker、compose/development 脚本、依赖注入
- eval-web:移除数据集/实验/版本等页面与流式轮询,突出 Playground
- 文档与单测同步
2026-04-08 21:36:12 +08:00

256 lines
8.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""访谈提示词:精简结构与人格/语气融合回归。"""
from langchain_core.messages import AIMessage, HumanMessage, SystemMessage
from app.agents.chat.interview_state_hints import (
apply_duplicate_question_guard,
extract_scene_cues,
)
from app.agents.state_schema import KnownFact, MemoirStateSchema, PersonaThread, default_slots
from app.agents.chat.helpers import format_history_string
from app.agents.chat.personas import normalize_interview_persona
from app.agents.chat.prompts_conversation import (
get_guided_conversation_prompt,
get_opening_prompt,
)
def test_guided_prompt_does_not_embed_raw_user_message_in_system_text():
p = get_guided_conversation_prompt(
current_stage="childhood",
empty_slots=["place"],
filled_slots={},
detected_user_stage="childhood",
user_profile_context="",
persona="default",
)
assert "__USER_SECRET_PHRASE_XYZ__" not in p
# Signature no longer takes user_message; secret would only leak via profile
p2 = get_guided_conversation_prompt(
current_stage="childhood",
empty_slots=["place"],
filled_slots={},
detected_user_stage="childhood",
user_profile_context="__USER_SECRET_PROFILE__",
persona="default",
)
assert "__USER_SECRET_PROFILE__" in p2
def test_guided_prompt_mentions_empathy_and_scene_strategy():
p = get_guided_conversation_prompt(
current_stage="childhood",
empty_slots=["place"],
filled_slots={},
detected_user_stage="childhood",
user_profile_context="",
persona="default",
)
assert "接住" in p
assert "画面" in p or "细节" in p
assert "深挖" in p
assert "串联" in p
def test_guided_prompt_era_popculture_open_questions_when_birth_year():
p = get_guided_conversation_prompt(
current_stage="childhood",
empty_slots=["place"],
filled_slots={},
detected_user_stage="childhood",
user_profile_context="",
persona="default",
profile_birth_year=1985,
profile_era_place="潍坊",
)
assert "时代与氛围参考" in p
assert "流行文化" in p
assert "开放式" in p
def test_opening_prompt_includes_era_task_when_birth_year_configured():
p = get_opening_prompt(
current_stage="childhood",
empty_slots_readable=["成长的地方"],
user_profile_context="出生年份1985年",
persona="default",
profile_birth_year=1985,
profile_era_place="潍坊",
)
assert "年代氛围" in p
def test_guided_prompt_persona_tone_warm_listener():
p = get_guided_conversation_prompt(
current_stage="education",
empty_slots=["school"],
filled_slots={},
detected_user_stage="education",
user_profile_context="",
persona="warm_listener",
)
assert "倾听" in p or "柔和" in p
def test_guided_prompt_persona_curious_guide():
p = get_guided_conversation_prompt(
current_stage="education",
empty_slots=["school"],
filled_slots={},
detected_user_stage="education",
user_profile_context="",
persona="curious_guide",
)
assert "细节" in p
def test_normalize_interview_persona_unknown_falls_back():
assert normalize_interview_persona("not_a_real_persona") == "default"
assert normalize_interview_persona("") == "default"
def test_guided_prompt_contains_memory_section_when_evidence():
p = get_guided_conversation_prompt(
current_stage="childhood",
empty_slots=["place"],
filled_slots={},
detected_user_stage="childhood",
user_profile_context="",
persona="default",
memory_evidence_text="[摘要:rolling] 1990年生于上海。",
)
assert "相关记忆摘录" in p
assert "过往口述" in p
assert "1990年生于上海" in p
def test_guided_prompt_military_tone_in_system():
p = get_guided_conversation_prompt(
current_stage="childhood",
empty_slots=["place"],
filled_slots={},
detected_user_stage="childhood",
user_profile_context="",
persona="default",
background_voice="military",
)
assert "简洁" in p or "利落" in p or "得体" in p
def test_guided_prompt_includes_known_facts_persona_threads_and_recent_questions():
p = get_guided_conversation_prompt(
current_stage="career",
empty_slots=["job", "decision"],
filled_slots={"growth": "越做越确定自己适合产品"},
detected_user_stage="career",
user_profile_context="",
persona="default",
known_facts=[
KnownFact(label="本轮新信息", value="我后来去了瑞士读书", stage="education"),
],
persona_threads=[
PersonaThread(trait="执着坚持", evidence="为了训练咬牙坚持了很多年"),
],
recent_questions=["你当时为什么会想去瑞士?"],
)
assert "已确认事实" in p
assert "我后来去了瑞士读书" in p
assert "人物主线" in p
assert "执着坚持" in p
assert "最近已经问过的问题" in p
assert "为什么会想去瑞士" in p
def test_prompt_empty_slots_excludes_slots_already_covered_by_known_facts():
state = MemoirStateSchema(
stage_order=["education"],
current_stage="education",
covered_stages=[],
slots={"education": default_slots()["education"]},
known_facts=[
KnownFact(
label="求学城市",
value="后来在瑞士读书",
stage="education",
slot_name="city",
)
],
)
assert "city" not in state.prompt_empty_slots_for_current_stage()
assert "school" in state.prompt_empty_slots_for_current_stage()
def test_duplicate_question_guard_downgrades_recent_repeat_question():
state = MemoirStateSchema(
stage_order=["education"],
current_stage="education",
covered_stages=[],
slots={"education": default_slots()["education"]},
known_facts=[
KnownFact(label="本轮新信息", value="我后来去了瑞士读书", stage="education")
],
)
cleaned, touched = apply_duplicate_question_guard(
["我记住了。你后来去了瑞士读书吗?"],
state=state,
recent_questions=["你后来去了瑞士读书吗?"],
)
assert touched is True
assert cleaned == ["我记住了。"]
def test_extract_scene_cues_picks_up_sensory_keywords():
cues = extract_scene_cues("我们小时候在河里游泳,冬天溜冰")
assert any("" in c or "" in c for c in cues)
assert any("" in c or "咔嚓" in c for c in cues)
def test_extract_scene_cues_empty_for_abstract_text():
assert extract_scene_cues("我觉得人生需要坚持") == []
def test_default_persona_now_has_tone_hint():
from app.agents.chat.personas import get_interview_persona_tone_hint
hint = get_interview_persona_tone_hint("default")
assert hint
assert "画面" in hint or "细节" in hint
def test_opening_prompt_military_style_rules_not_dialogue_samples() -> None:
p = get_opening_prompt(
current_stage="childhood",
empty_slots_readable=["成长的地方"],
user_profile_context="",
persona="default",
background_voice="military",
)
assert "军队相关" in p
assert "示例" not in p
def test_format_history_string_includes_system_for_debug_logs() -> None:
s = format_history_string(
[
SystemMessage(content="SYS_INSTRUCTIONS"),
HumanMessage(content="hi"),
AIMessage(content="hello"),
]
)
assert "System: SYS_INSTRUCTIONS" in s
assert "Human: hi" in s
assert "Assistant: hello" in s
def test_format_history_string_omit_system_body() -> None:
s = format_history_string(
[
SystemMessage(content="SYS_INSTRUCTIONS"),
HumanMessage(content="hi"),
],
omit_system_body=True,
)
assert "SYS_INSTRUCTIONS" not in s
assert "System: <omitted total_len=16" in s
assert "sha12=" in s
assert "Human: hi" in s