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

83 lines
2.7 KiB
Python
Raw Normal View History

"""评测用对话文本格式化(稳定 Turn 标签、便于评审引用)。"""
from __future__ import annotations
from typing import Any, Protocol
class _MessageLike(Protocol):
role: str | None
content: str | None
def assistant_text_for_eval_display(raw: str) -> str:
"""评审与 transcript 展示:避免字面量 [SPLIT] 干扰 judge 阅读。"""
return (raw or "").replace("[SPLIT]", "\n")
def format_eval_turn_block(turn_index_0: int, user: str, assistant: str) -> str:
"""单轮回放/节选:`[Turn k]` 从 1 起计。"""
u = (user or "").strip()
a = assistant_text_for_eval_display(assistant).strip()
k = int(turn_index_0) + 1
return f"[Turn {k}]\n用户: {u}\nAI: {a}"
def format_export_turns_with_labels(turns: list[tuple[str, str]]) -> str:
"""用户导出 fixture每轮 (user, ai)。"""
parts: list[str] = []
for i, (u, ai) in enumerate(turns):
parts.append(format_eval_turn_block(i, u, ai))
return "\n\n".join(parts)
def pair_session_messages_to_turns(
messages: list[_MessageLike] | list[Any],
) -> list[tuple[str, str]]:
"""将对话消息序列为 (user, assistant) 轮次列表,语义与 `format_session_messages_with_turn_labels` 一致。
末尾仅有 human无紧随 assistant 补一轮 (user, "") UI 与评审对齐
"""
out: list[tuple[str, str]] = []
pending_user: str | None = None
for m in messages:
r = (getattr(m, "role", None) or "").lower()
body = (getattr(m, "content", None) or "").strip()
if r == "system":
continue
if not body and r != "human":
continue
if r == "human":
pending_user = body
elif r in ("ai", "assistant"):
u = (pending_user or "").strip()
pending_user = None
out.append((u, body))
if pending_user is not None:
out.append((pending_user.strip(), ""))
return out
def format_session_messages_with_turn_labels(
messages: list[_MessageLike] | list[Any],
) -> str:
"""会话消息序列:按出现顺序将相邻 human→assistant 合并为一轮。"""
blocks: list[str] = []
turn_idx = 0
pending_user: str | None = None
for m in messages:
r = (getattr(m, "role", None) or "").lower()
body = (getattr(m, "content", None) or "").strip()
if not body and r != "human":
continue
if r == "human":
pending_user = body
elif r in ("ai", "assistant", "system"):
if r == "system":
continue
u = (pending_user or "").strip()
pending_user = None
blocks.append(format_eval_turn_block(turn_idx, u, body))
turn_idx += 1
return "\n\n".join(blocks)