Files
life-echo/api/app/features/evaluation/candidate_runner.py

84 lines
2.9 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.
"""独立候选回放:多轮 user 链式调用 LLM不走路由 WS / ChatOrchestrator。"""
from __future__ import annotations
import time
from typing import Any
from app.core.logging import get_logger
logger = get_logger(__name__)
def _system_prompt_for_eval(version_config: dict | None) -> str:
cfg = version_config or {}
extra = (cfg.get("system_prompt_suffix") or "").strip()
base = """你是「岁月留书」老年友好访谈员。语气温暖、耐心,先承接情绪再 gently 追问事实与感受;回答简洁分段,避免术语。"""
if extra:
return f"{base}\n\n{extra}"
return base
def _model_override(version_config: dict | None) -> str | None:
if not version_config:
return None
m = version_config.get("model")
return str(m).strip() if m else None
class EvalCandidateRunner:
"""使用 LangChain Chat 模型回放用户轮次。"""
def __init__(self, llm: Any) -> None:
self._llm = llm
async def replay_utterances(
self,
utterances: list[str],
*,
version_config: dict | None = None,
temperature: float = 0.7,
) -> tuple[list[str], list[int]]:
"""返回每轮 assistant 回复与耗时 ms。"""
if not self._llm:
raise RuntimeError(" replay: llm 未配置")
from langchain_core.messages import AIMessage, HumanMessage, SystemMessage
sys_prompt = _system_prompt_for_eval(version_config)
model = _model_override(version_config)
lc_messages: list = [SystemMessage(content=sys_prompt)]
replies: list[str] = []
latencies: list[int] = []
bound = (
self._llm.bind(model=model, temperature=temperature)
if model
else self._llm.bind(temperature=temperature)
)
for u in utterances:
text = (u or "").strip()
if not text:
continue
lc_messages.append(HumanMessage(content=text))
t0 = time.perf_counter()
result = await bound.ainvoke(lc_messages)
elapsed_ms = int((time.perf_counter() - t0) * 1000)
reply = str(getattr(result, "content", "") or "").strip()
replies.append(reply)
latencies.append(elapsed_ms)
lc_messages.append(AIMessage(content=reply))
return replies, latencies
def simple_memoir_from_transcript(utterances: list[str], replies: list[str]) -> str:
"""轻量成稿:供评审用占位(非生产叙事管线)。"""
lines = ["# 访谈摘录整理(评测占位稿)", ""]
for i, u in enumerate(utterances):
lines.append(f"## 片段 {i + 1}")
lines.append("")
lines.append(f"**用户:** {u.strip()}")
if i < len(replies):
lines.append("")
lines.append(f"**访谈者:** {replies[i].strip()}")
lines.append("")
return "\n".join(lines)