refactor(eval+memoir):精简内部评测路由与服务,composite/对话摘要与 judge 能力补强

- 访谈:新增 interview_state_hints,联动 orchestrator 与提示词
- 回忆录:story_pipeline_sync/state/memory/post_commit 与 Celery 任务调整
- 基建:开发用 celery broker、compose/development 脚本、依赖注入
- eval-web:移除数据集/实验/版本等页面与流式轮询,突出 Playground
- 文档与单测同步
This commit is contained in:
Kevin
2026-04-08 21:36:12 +08:00
parent 2a0c80987d
commit 064ad2161d
64 changed files with 3412 additions and 3068 deletions

View File

@@ -10,6 +10,11 @@ from langchain_core.messages import HumanMessage, SystemMessage
from app.agents.chat.agent_turn import AgentChatTurn
from app.agents.chat.helpers import format_history_string, get_history_with_window
from app.agents.chat.interview_state_hints import (
apply_duplicate_question_guard,
extract_recent_questions,
update_recent_questions,
)
from app.agents.chat.personas import normalize_interview_persona
from app.agents.chat.prompt_context import ChatPromptContext
from app.agents.chat.prompts_conversation import (
@@ -103,7 +108,7 @@ class InterviewAgent:
text_for_model = self._resolve_text_for_model(
user_message, normalized_user_message
)
empty_slots = memoir_state.empty_slots_for_current_stage()
empty_slots = memoir_state.prompt_empty_slots_for_current_stage()
filled_slots = {
key: value.snippet
for key, value in memoir_state.slots.get(
@@ -120,6 +125,7 @@ class InterviewAgent:
max_pairs=settings.chat_history_max_pairs,
max_chars=settings.chat_history_max_chars,
)
recent_questions = extract_recent_questions(hw.window)
conversation_turn_total = hw.turn_total
all_stages_coverage = memoir_state.all_stages_coverage()
persona = normalize_interview_persona(settings.chat_interview_persona)
@@ -140,6 +146,9 @@ class InterviewAgent:
occupation=occupation,
profile_birth_year=profile_birth_year,
profile_era_place=profile_era_place,
known_facts=memoir_state.known_facts,
persona_threads=memoir_state.persona_threads,
recent_questions=recent_questions or memoir_state.recent_questions,
)
system_prompt = ctx.guided_system_prompt()
messages: List[Any] = [SystemMessage(content=system_prompt)]
@@ -204,6 +213,15 @@ class InterviewAgent:
if not out:
out = [response_text.strip()[:max_chars]]
out = nonempty_segments_or_fallback(out, fallback=_FALLBACK_REPLY)
out, deduped = apply_duplicate_question_guard(
out,
state=memoir_state,
recent_questions=recent_questions or memoir_state.recent_questions,
)
updated_recent_questions = update_recent_questions(
recent_questions or memoir_state.recent_questions,
out,
)
log_agent_summary(
logger,
"InterviewAgent.generate_response segments={} conversation_id={} "
@@ -212,7 +230,14 @@ class InterviewAgent:
conversation_id,
max_tokens,
)
return AgentChatTurn(messages=out, skip_tts=False)
return AgentChatTurn(
messages=out,
skip_tts=False,
interview_state_meta={
"recent_questions": updated_recent_questions,
"duplicate_question_guard_triggered": deduped,
},
)
except Exception as e:
logger.error("生成回应失败: {}", e, exc_info=True)
return AgentChatTurn(messages=[_FALLBACK_REPLY], skip_tts=True)
@@ -231,7 +256,7 @@ class InterviewAgent:
if not self.llm:
return ["你好呀~ 又见面了,今天有没有哪段回忆或近况想聊聊?"]
try:
empty_slots = memoir_state.empty_slots_for_current_stage()
empty_slots = memoir_state.prompt_empty_slots_for_current_stage()
empty_slots_readable = [SLOT_NAME_MAP.get(s, s) for s in empty_slots]
persona = normalize_interview_persona(settings.chat_interview_persona)
prompt = get_opening_prompt(