feat(chat): server-side interview turn plan (mode, anchor slot, snippet)

- Add plan_interview_turn: emotion_first / memoir_push / follow_user_only
- Inject hard directive block at top of guided system prompt
- Pass stage_switched_this_turn from ChatOrchestrator after stage detection
- Log interview_turn_plan for observability; add unit tests
This commit is contained in:
Kevin
2026-04-10 13:56:44 +08:00
parent df6eafeae2
commit 5ff495729e
6 changed files with 301 additions and 2 deletions

View File

@@ -15,6 +15,7 @@ from app.agents.chat.interview_state_hints import (
extract_recent_questions,
update_recent_questions,
)
from app.agents.chat.interview_turn_plan import plan_interview_turn
from app.agents.chat.personas import normalize_interview_persona
from app.agents.chat.prompt_context import ChatPromptContext
from app.agents.chat.prompts_conversation import (
@@ -99,6 +100,7 @@ class InterviewAgent:
occupation: str = "",
profile_birth_year: int | None = None,
profile_era_place: str = "",
stage_switched_this_turn: bool = False,
) -> AgentChatTurn:
"""生成状态感知的访谈回复,不持久化(由 Orchestrator 负责)"""
if not self.llm:
@@ -133,6 +135,20 @@ class InterviewAgent:
max_tokens = int(settings.chat_interview_max_tokens)
max_chars = int(settings.chat_interview_max_chars_per_segment)
turn_plan = plan_interview_turn(
current_stage=memoir_state.current_stage,
empty_slots=empty_slots,
normalized_user_message=text_for_model,
memory_evidence_text=memory_evidence_text,
stage_switched_this_turn=stage_switched_this_turn,
)
logger.info(
"event=interview_turn_plan mode={} anchor_slot={} snippet_len={}",
turn_plan.mode,
turn_plan.anchor_slot_key or "-",
len(turn_plan.anchor_snippet or ""),
)
ctx = ChatPromptContext(
current_stage=memoir_state.current_stage,
empty_slots=empty_slots,
@@ -149,6 +165,7 @@ class InterviewAgent:
known_facts=memoir_state.known_facts,
persona_threads=memoir_state.persona_threads,
recent_questions=recent_questions or memoir_state.recent_questions,
turn_plan=turn_plan,
)
system_prompt = ctx.guided_system_prompt()
messages: List[Any] = [SystemMessage(content=system_prompt)]