- Drop interview_reply_length and utterance_substance; always run stage LLM and memory retrieval when enabled; trim Settings fields and .env.example. - Replace guided/opening prompts with compact fact blocks plus unified behavior guidance; slim background_voice and persona to tone hints. - InterviewAgent uses fixed chat_interview max_tokens/chars/segments. Also includes stacked work: profile followup/extract path, evaluation rubric and judge schema updates, transcript SPLIT handling in execution service, user export markdown split tests, and golden case fixture.
141 lines
4.2 KiB
Python
141 lines
4.2 KiB
Python
"""访谈提示词:精简结构与人格/语气融合回归。"""
|
|
|
|
from langchain_core.messages import AIMessage, HumanMessage, SystemMessage
|
|
|
|
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_self_judgment():
|
|
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
|
|
|
|
|
|
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_opening_prompt_military_has_examples_note() -> None:
|
|
p = get_opening_prompt(
|
|
current_stage="childhood",
|
|
empty_slots_readable=["成长的地方"],
|
|
user_profile_context="",
|
|
persona="default",
|
|
background_voice="military",
|
|
)
|
|
assert "军队语境" 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
|