"""候选抽取 prompt 构建(纯函数,无 IO)。 接收 ``(role, content)`` 元组列表(由 application 从 ORM 转换),产出 ``(system, user)`` 消息对,喂给模型网关。模型返回的 JSON 由 ``extract`` 模块解析。 """ from collections.abc import Sequence PROFILE_FIELDS = ( "display_name", "birthday", "height", "weight", "background", "speaking_style", ) MEMORY_TYPES = ( "user", "preference", "event", "relationship", "skill", "goal", "other", ) PERSONALITY_FIELDS = ( "identity_profile", "role_destiny", "personality_seed", "expression_style", "relationship_pattern", "traits", "values", "emotion_baseline", ) def _format_items(items: Sequence[tuple[str, str]]) -> str: lines = [f"[{idx}] ({role}) {content}" for idx, (role, content) in enumerate(items)] return "\n".join(lines) def build_profile_extraction_messages( items: Sequence[tuple[str, str]], ) -> tuple[str, str]: system = ( "你是资料分析助手。从用户提供的资料中提取人物档案字段候选,只提取明确出现的信息。" f"field 取自:{', '.join(PROFILE_FIELDS)}。" '以 JSON 数组返回,每个元素:{"field": str, "value": str, "confidence": 0~1, ' '"reason": str, "evidence": [条目序号]}。' "evidence 为资料条目序号([0]/[1]…)列表。若资料无档案信息,返回 []。" "只返回 JSON 数组,不要解释或 markdown。" ) return system, f"资料:\n{_format_items(items)}" def build_memory_extraction_messages( items: Sequence[tuple[str, str]], ) -> tuple[str, str]: system = ( "你是记忆分析助手。从用户提供的资料中提取值得长期记住的记忆候选。" f"type 取自:{', '.join(MEMORY_TYPES)}。" '以 JSON 数组返回:{"type": str, "title": str, "content": str, ' '"importance": 0~1, "sensitivity": "low|medium|high", "reason": str, ' '"evidence": [条目序号]}。' "只提取有长期价值的非琐碎信息。若无可提取返回 []。只返回 JSON 数组。" ) return system, f"资料:\n{_format_items(items)}" def build_personality_extraction_messages( items: Sequence[tuple[str, str]], personality_summary: str ) -> tuple[str, str]: system = ( "你是人格分析助手。基于用户提供的资料和当前人格,提出人格完善建议。" f"field 取自:{', '.join(PERSONALITY_FIELDS)}。" '以 JSON 数组返回:{"field": str, "change": str, "reason": str, ' '"evidence": [条目序号]}。' "change 为建议写入该字段的新内容。只在资料充分支撑时提议。若无需完善返回 []。" "只返回 JSON 数组。" ) user = ( f"当前人格摘要:\n{personality_summary or '(尚未形成)'}\n\n资料:\n{_format_items(items)}" ) return system, user