refactor: 进一步重构agents目录结构 符合多agent架构
This commit is contained in:
@@ -6,7 +6,7 @@ from datetime import datetime
|
|||||||
from typing import Any, Dict, List, Optional
|
from typing import Any, Dict, List, Optional
|
||||||
|
|
||||||
from app.agents.chat.orchestrator import ChatOrchestrator
|
from app.agents.chat.orchestrator import ChatOrchestrator
|
||||||
from app.agents.prompts import ConversationStage
|
from app.agents.chat.prompts_conversation import ConversationStage
|
||||||
from app.agents.state_schema import MemoirStateSchema
|
from app.agents.state_schema import MemoirStateSchema
|
||||||
from app.core.redis import redis_service
|
from app.core.redis import redis_service
|
||||||
|
|
||||||
|
|||||||
@@ -8,8 +8,11 @@ from app.core.dependencies import get_llm_provider
|
|||||||
from app.core.logging import get_logger
|
from app.core.logging import get_logger
|
||||||
|
|
||||||
from app.agents.chat.helpers import format_history_string, get_history_messages
|
from app.agents.chat.helpers import format_history_string, get_history_messages
|
||||||
from app.agents.prompts import get_guided_conversation_prompt, get_opening_prompt
|
from app.agents.chat.prompts_conversation import (
|
||||||
from app.agents.prompts.conversation_prompts import SLOT_NAME_MAP
|
SLOT_NAME_MAP,
|
||||||
|
get_guided_conversation_prompt,
|
||||||
|
get_opening_prompt,
|
||||||
|
)
|
||||||
from app.agents.state_schema import MemoirStateSchema
|
from app.agents.state_schema import MemoirStateSchema
|
||||||
|
|
||||||
logger = get_logger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ class ChatOrchestrator:
|
|||||||
conversation.conversation_stage = state.current_stage
|
conversation.conversation_stage = state.current_stage
|
||||||
await db.commit()
|
await db.commit()
|
||||||
|
|
||||||
from app.agents.prompts.profile_prompts import format_user_profile_context
|
from app.agents.chat.prompts_profile import format_user_profile_context
|
||||||
|
|
||||||
user_profile_context = ""
|
user_profile_context = ""
|
||||||
if user:
|
if user:
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ from app.core.dependencies import get_llm_provider
|
|||||||
from app.core.logging import get_logger
|
from app.core.logging import get_logger
|
||||||
|
|
||||||
from app.agents.chat.helpers import format_history_string, get_history_messages
|
from app.agents.chat.helpers import format_history_string, get_history_messages
|
||||||
from app.agents.prompts.profile_prompts import (
|
from app.agents.chat.prompts_profile import (
|
||||||
get_profile_extraction_prompt,
|
get_profile_extraction_prompt,
|
||||||
get_profile_followup_prompt,
|
get_profile_followup_prompt,
|
||||||
get_profile_greeting_prompt,
|
get_profile_greeting_prompt,
|
||||||
|
|||||||
41
api/app/agents/chat/prompts.py
Normal file
41
api/app/agents/chat/prompts.py
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
"""
|
||||||
|
Chat 模块提示词:用户资料收集 + 对话访谈
|
||||||
|
"""
|
||||||
|
# Profile prompts(用户资料收集)
|
||||||
|
from app.agents.chat.prompts_profile import (
|
||||||
|
PROFILE_FIELD_NAMES,
|
||||||
|
format_user_profile_context,
|
||||||
|
get_missing_profile_fields,
|
||||||
|
get_profile_extraction_prompt,
|
||||||
|
get_profile_followup_prompt,
|
||||||
|
get_profile_greeting_prompt,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Conversation prompts(对话访谈)
|
||||||
|
from app.agents.chat.prompts_conversation import (
|
||||||
|
ConversationStage,
|
||||||
|
INTERVIEW_QUESTIONS,
|
||||||
|
SLOT_NAME_MAP,
|
||||||
|
get_conversation_prompt,
|
||||||
|
get_guided_conversation_prompt,
|
||||||
|
get_opening_prompt,
|
||||||
|
get_questions_for_stage,
|
||||||
|
get_system_prompt,
|
||||||
|
)
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"PROFILE_FIELD_NAMES",
|
||||||
|
"format_user_profile_context",
|
||||||
|
"get_missing_profile_fields",
|
||||||
|
"get_profile_extraction_prompt",
|
||||||
|
"get_profile_followup_prompt",
|
||||||
|
"get_profile_greeting_prompt",
|
||||||
|
"ConversationStage",
|
||||||
|
"INTERVIEW_QUESTIONS",
|
||||||
|
"SLOT_NAME_MAP",
|
||||||
|
"get_conversation_prompt",
|
||||||
|
"get_guided_conversation_prompt",
|
||||||
|
"get_opening_prompt",
|
||||||
|
"get_questions_for_stage",
|
||||||
|
"get_system_prompt",
|
||||||
|
]
|
||||||
@@ -65,12 +65,12 @@ INTERVIEW_QUESTIONS: Dict[ConversationStage, List[str]] = {
|
|||||||
def get_system_prompt(current_stage: ConversationStage, covered_topics: List[str], user_latest_response: str) -> str:
|
def get_system_prompt(current_stage: ConversationStage, covered_topics: List[str], user_latest_response: str) -> str:
|
||||||
"""
|
"""
|
||||||
生成对话 Agent 的系统提示词
|
生成对话 Agent 的系统提示词
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
current_stage: 当前对话阶段
|
current_stage: 当前对话阶段
|
||||||
covered_topics: 已聊过的话题列表
|
covered_topics: 已聊过的话题列表
|
||||||
user_latest_response: 用户最新回答
|
user_latest_response: 用户最新回答
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
系统提示词字符串
|
系统提示词字符串
|
||||||
"""
|
"""
|
||||||
@@ -82,9 +82,9 @@ def get_system_prompt(current_stage: ConversationStage, covered_topics: List[str
|
|||||||
ConversationStage.BELIEFS: "信念",
|
ConversationStage.BELIEFS: "信念",
|
||||||
ConversationStage.SUMMARY: "人生总结",
|
ConversationStage.SUMMARY: "人生总结",
|
||||||
}
|
}
|
||||||
|
|
||||||
covered_topics_str = "、".join(covered_topics) if covered_topics else "暂无"
|
covered_topics_str = "、".join(covered_topics) if covered_topics else "暂无"
|
||||||
|
|
||||||
prompt = f"""你是「岁月知己」,一位资深的人生故事访谈者,专注于帮助用户回忆和讲述人生经历。
|
prompt = f"""你是「岁月知己」,一位资深的人生故事访谈者,专注于帮助用户回忆和讲述人生经历。
|
||||||
|
|
||||||
## 角色定位
|
## 角色定位
|
||||||
@@ -106,7 +106,7 @@ def get_system_prompt(current_stage: ConversationStage, covered_topics: List[str
|
|||||||
已聊话题:{covered_topics_str}
|
已聊话题:{covered_topics_str}
|
||||||
|
|
||||||
请直接回应用户,不要有任何元描述。"""
|
请直接回应用户,不要有任何元描述。"""
|
||||||
|
|
||||||
return prompt
|
return prompt
|
||||||
|
|
||||||
|
|
||||||
@@ -116,46 +116,39 @@ def get_questions_for_stage(stage: ConversationStage) -> List[str]:
|
|||||||
|
|
||||||
|
|
||||||
SLOT_NAME_MAP = {
|
SLOT_NAME_MAP = {
|
||||||
# 童年
|
|
||||||
"place": "成长的地方",
|
"place": "成长的地方",
|
||||||
"people": "重要的人",
|
"people": "重要的人",
|
||||||
"daily_life": "日常生活",
|
"daily_life": "日常生活",
|
||||||
"emotion": "童年感受",
|
"emotion": "童年感受",
|
||||||
"turning_event": "难忘的事",
|
"turning_event": "难忘的事",
|
||||||
# 教育
|
|
||||||
"school": "学校经历",
|
"school": "学校经历",
|
||||||
"city": "求学的城市",
|
"city": "求学的城市",
|
||||||
"motivation": "学习动力",
|
"motivation": "学习动力",
|
||||||
"challenge": "遇到的挑战",
|
"challenge": "遇到的挑战",
|
||||||
"change": "成长变化",
|
"change": "成长变化",
|
||||||
# 事业
|
|
||||||
"job": "工作内容",
|
"job": "工作内容",
|
||||||
"environment": "工作环境",
|
"environment": "工作环境",
|
||||||
"decision": "重要决定",
|
"decision": "重要决定",
|
||||||
"pressure": "压力与困难",
|
"pressure": "压力与困难",
|
||||||
"growth": "职业成长",
|
"growth": "职业成长",
|
||||||
# 家庭
|
|
||||||
"relationship": "家人关系",
|
"relationship": "家人关系",
|
||||||
"conflict": "矛盾与化解",
|
"conflict": "矛盾与化解",
|
||||||
"support": "相互支持",
|
"support": "相互支持",
|
||||||
"responsibility": "家庭责任",
|
"responsibility": "家庭责任",
|
||||||
# 信念
|
|
||||||
"value": "核心价值观",
|
"value": "核心价值观",
|
||||||
"regret": "遗憾与释怀",
|
"regret": "遗憾与释怀",
|
||||||
"pride": "骄傲的事",
|
"pride": "骄傲的事",
|
||||||
"lesson": "人生经验",
|
"lesson": "人生经验",
|
||||||
}
|
}
|
||||||
|
|
||||||
# 阶段关联话题(用于自然过渡)
|
|
||||||
STAGE_RELATED_TOPICS = {
|
STAGE_RELATED_TOPICS = {
|
||||||
"childhood": ["family", "education"], # 童年可以自然聊到家庭、教育
|
"childhood": ["family", "education"],
|
||||||
"education": ["childhood", "career"], # 教育可以聊到童年、事业
|
"education": ["childhood", "career"],
|
||||||
"career": ["education", "family", "belief"], # 事业可以聊到教育、家庭、信念
|
"career": ["education", "family", "belief"],
|
||||||
"family": ["childhood", "career", "belief"], # 家庭可以聊到童年、事业、信念
|
"family": ["childhood", "career", "belief"],
|
||||||
"belief": ["career", "family"], # 信念可以聊到事业、家庭
|
"belief": ["career", "family"],
|
||||||
}
|
}
|
||||||
|
|
||||||
# 轻松话题(用于调节气氛)
|
|
||||||
LIGHT_TOPICS = [
|
LIGHT_TOPICS = [
|
||||||
"有什么爱好或者特别喜欢的消遣方式吗?",
|
"有什么爱好或者特别喜欢的消遣方式吗?",
|
||||||
"最近有什么让你开心的事吗?",
|
"最近有什么让你开心的事吗?",
|
||||||
@@ -163,13 +156,12 @@ LIGHT_TOPICS = [
|
|||||||
"平时喜欢看什么书或者电影吗?",
|
"平时喜欢看什么书或者电影吗?",
|
||||||
]
|
]
|
||||||
|
|
||||||
# 回应风格模板(增加多样性)
|
|
||||||
RESPONSE_STYLES = [
|
RESPONSE_STYLES = [
|
||||||
"empathy", # 共情式回应
|
"empathy",
|
||||||
"curious", # 好奇追问
|
"curious",
|
||||||
"reflection", # 感慨反思
|
"reflection",
|
||||||
"lighthearted", # 轻松调侃
|
"lighthearted",
|
||||||
"connection", # 关联自身(虚构)
|
"connection",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@@ -178,10 +170,7 @@ def get_opening_prompt(
|
|||||||
empty_slots_readable: List[str],
|
empty_slots_readable: List[str],
|
||||||
user_profile_context: str = "",
|
user_profile_context: str = "",
|
||||||
) -> str:
|
) -> str:
|
||||||
"""
|
"""空对话时 AI 先开口的提示词"""
|
||||||
空对话时 AI 先开口的提示词(用户通过「打个招呼」进入,尚未发送任何消息)。
|
|
||||||
要求 AI 先发一条问候 + 一个具体问题,引导用户开始分享。
|
|
||||||
"""
|
|
||||||
stage_name_map = {
|
stage_name_map = {
|
||||||
"childhood": "童年时光",
|
"childhood": "童年时光",
|
||||||
"education": "求学经历",
|
"education": "求学经历",
|
||||||
@@ -216,10 +205,7 @@ def get_opening_prompt(
|
|||||||
|
|
||||||
|
|
||||||
def _build_era_context(current_stage: str, user_profile_context: str) -> str:
|
def _build_era_context(current_stage: str, user_profile_context: str) -> str:
|
||||||
"""
|
"""根据用户的人生阶段和出生年份,生成对应时代的历史/政治/文化背景提示"""
|
||||||
根据用户的人生阶段和出生年份,生成对应时代的历史/政治/文化背景提示。
|
|
||||||
让 agent 在对话中自然融入时代感。
|
|
||||||
"""
|
|
||||||
if not user_profile_context:
|
if not user_profile_context:
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
@@ -250,7 +236,6 @@ def _build_era_context(current_stage: str, user_profile_context: str) -> str:
|
|||||||
era_end = birth_year + age_range[1]
|
era_end = birth_year + age_range[1]
|
||||||
|
|
||||||
era_events = []
|
era_events = []
|
||||||
|
|
||||||
decade_events = {
|
decade_events = {
|
||||||
1950: "新中国成立初期、土地改革、抗美援朝",
|
1950: "新中国成立初期、土地改革、抗美援朝",
|
||||||
1960: "大跃进、三年自然灾害、中苏关系变化",
|
1960: "大跃进、三年自然灾害、中苏关系变化",
|
||||||
@@ -270,7 +255,6 @@ def _build_era_context(current_stage: str, user_profile_context: str) -> str:
|
|||||||
return ""
|
return ""
|
||||||
|
|
||||||
place_hint = f"(用户来自{birth_place})" if birth_place else ""
|
place_hint = f"(用户来自{birth_place})" if birth_place else ""
|
||||||
|
|
||||||
return f"""
|
return f"""
|
||||||
## 时代背景参考{place_hint}
|
## 时代背景参考{place_hint}
|
||||||
用户在这个人生阶段大约经历了 {era_start}-{era_end} 年({age_range[0]}-{age_range[1]} 岁):
|
用户在这个人生阶段大约经历了 {era_start}-{era_end} 年({age_range[0]}-{age_range[1]} 岁):
|
||||||
@@ -293,20 +277,7 @@ def get_guided_conversation_prompt(
|
|||||||
detected_user_stage: str = "",
|
detected_user_stage: str = "",
|
||||||
user_profile_context: str = "",
|
user_profile_context: str = "",
|
||||||
) -> str:
|
) -> str:
|
||||||
"""
|
"""生成状态感知的对话提示词"""
|
||||||
生成状态感知的对话提示词
|
|
||||||
|
|
||||||
Args:
|
|
||||||
current_stage: 系统当前跟踪的阶段
|
|
||||||
empty_slots: 当前阶段未填充的槽位
|
|
||||||
filled_slots: 当前阶段已填充的槽位
|
|
||||||
user_message: 用户消息
|
|
||||||
conversation_turn: 总对话轮数
|
|
||||||
same_topic_turns: 同一话题的轮数
|
|
||||||
all_stages_coverage: 所有阶段的覆盖情况 {stage: {total, filled, empty, ratio}}
|
|
||||||
detected_user_stage: 检测到用户正在谈论的阶段(可能和 current_stage 不同)
|
|
||||||
user_profile_context: 用户基础资料上下文
|
|
||||||
"""
|
|
||||||
stage_name_map = {
|
stage_name_map = {
|
||||||
"childhood": "童年时光",
|
"childhood": "童年时光",
|
||||||
"education": "求学经历",
|
"education": "求学经历",
|
||||||
@@ -317,12 +288,8 @@ def get_guided_conversation_prompt(
|
|||||||
|
|
||||||
current_stage_name = stage_name_map.get(current_stage, current_stage)
|
current_stage_name = stage_name_map.get(current_stage, current_stage)
|
||||||
user_stage_name = stage_name_map.get(detected_user_stage, "") if detected_user_stage else ""
|
user_stage_name = stage_name_map.get(detected_user_stage, "") if detected_user_stage else ""
|
||||||
|
|
||||||
# 判断用户是否在聊一个不同于系统当前阶段的话题
|
|
||||||
user_jumped = detected_user_stage and detected_user_stage != current_stage
|
user_jumped = detected_user_stage and detected_user_stage != current_stage
|
||||||
|
|
||||||
# --- 构建当前聊天上下文 ---
|
|
||||||
# 转换 slot 名称为中文
|
|
||||||
empty_slots_readable = [SLOT_NAME_MAP.get(s, s) for s in empty_slots]
|
empty_slots_readable = [SLOT_NAME_MAP.get(s, s) for s in empty_slots]
|
||||||
empty_slots_str = "、".join(empty_slots_readable) if empty_slots_readable else "已聊得很充分"
|
empty_slots_str = "、".join(empty_slots_readable) if empty_slots_readable else "已聊得很充分"
|
||||||
|
|
||||||
@@ -332,7 +299,6 @@ def get_guided_conversation_prompt(
|
|||||||
filled_info.append(f"{readable_key}: {value[:50]}..." if len(value) > 50 else f"{readable_key}: {value}")
|
filled_info.append(f"{readable_key}: {value[:50]}..." if len(value) > 50 else f"{readable_key}: {value}")
|
||||||
filled_slots_str = "\n".join(filled_info) if filled_info else "刚开始聊"
|
filled_slots_str = "\n".join(filled_info) if filled_info else "刚开始聊"
|
||||||
|
|
||||||
# --- 构建全局进度概览 ---
|
|
||||||
progress_lines = []
|
progress_lines = []
|
||||||
uncovered_stages = []
|
uncovered_stages = []
|
||||||
if all_stages_coverage:
|
if all_stages_coverage:
|
||||||
@@ -350,17 +316,14 @@ def get_guided_conversation_prompt(
|
|||||||
progress_lines.append(f" {sname}:已聊得很充分 ✓")
|
progress_lines.append(f" {sname}:已聊得很充分 ✓")
|
||||||
progress_str = "\n".join(progress_lines) if progress_lines else ""
|
progress_str = "\n".join(progress_lines) if progress_lines else ""
|
||||||
|
|
||||||
# --- 动态策略 ---
|
|
||||||
filled_count = len(filled_slots)
|
filled_count = len(filled_slots)
|
||||||
should_switch_topic = same_topic_turns >= 3 or (filled_count >= 2 and same_topic_turns >= 2)
|
should_switch_topic = same_topic_turns >= 3 or (filled_count >= 2 and same_topic_turns >= 2)
|
||||||
should_lighten_mood = conversation_turn > 0 and conversation_turn % 5 == 0
|
should_lighten_mood = conversation_turn > 0 and conversation_turn % 5 == 0
|
||||||
should_try_new_stage = filled_count >= 3 and len(empty_slots) <= 2
|
should_try_new_stage = filled_count >= 3 and len(empty_slots) <= 2
|
||||||
|
|
||||||
# 获取相关阶段
|
|
||||||
related_stages = STAGE_RELATED_TOPICS.get(current_stage, [])
|
related_stages = STAGE_RELATED_TOPICS.get(current_stage, [])
|
||||||
related_stages_str = "、".join([stage_name_map.get(s, s) for s in related_stages])
|
related_stages_str = "、".join([stage_name_map.get(s, s) for s in related_stages])
|
||||||
|
|
||||||
# 选择回应风格
|
|
||||||
style = random.choice(RESPONSE_STYLES)
|
style = random.choice(RESPONSE_STYLES)
|
||||||
style_guidance = {
|
style_guidance = {
|
||||||
"empathy": "这次回应要特别体现共情,表达你能理解用户的感受",
|
"empathy": "这次回应要特别体现共情,表达你能理解用户的感受",
|
||||||
@@ -370,7 +333,6 @@ def get_guided_conversation_prompt(
|
|||||||
"connection": "这次回应可以分享一个类似的经历或感受(可以虚构)",
|
"connection": "这次回应可以分享一个类似的经历或感受(可以虚构)",
|
||||||
}.get(style, "")
|
}.get(style, "")
|
||||||
|
|
||||||
# --- 构建动态指导 ---
|
|
||||||
dynamic_guidance = ""
|
dynamic_guidance = ""
|
||||||
if user_jumped:
|
if user_jumped:
|
||||||
dynamic_guidance += f"""
|
dynamic_guidance += f"""
|
||||||
@@ -385,19 +347,15 @@ def get_guided_conversation_prompt(
|
|||||||
if should_try_new_stage and related_stages:
|
if should_try_new_stage and related_stages:
|
||||||
dynamic_guidance += f"\n- 如果自然的话,可以尝试聊聊相关的话题,比如{related_stages_str}"
|
dynamic_guidance += f"\n- 如果自然的话,可以尝试聊聊相关的话题,比如{related_stages_str}"
|
||||||
|
|
||||||
# --- 缺失章节补充提示(仅在用户没有跳转、且当前话题聊得差不多时) ---
|
|
||||||
uncovered_hint = ""
|
uncovered_hint = ""
|
||||||
if not user_jumped and uncovered_stages and should_try_new_stage:
|
if not user_jumped and uncovered_stages and should_try_new_stage:
|
||||||
uncovered_hint = f"\n- 还没聊到的人生阶段有:{'、'.join(uncovered_stages)},如果聊天中有自然的契机,可以轻轻带一句,但不要刻意"
|
uncovered_hint = f"\n- 还没聊到的人生阶段有:{'、'.join(uncovered_stages)},如果聊天中有自然的契机,可以轻轻带一句,但不要刻意"
|
||||||
|
|
||||||
# --- 组合 prompt ---
|
|
||||||
# 根据是否跳转,调整主题描述
|
|
||||||
if user_jumped:
|
if user_jumped:
|
||||||
topic_desc = f"你们原本在聊「{current_stage_name}」,但用户自然地聊到了「{user_stage_name}」的内容"
|
topic_desc = f"你们原本在聊「{current_stage_name}」,但用户自然地聊到了「{user_stage_name}」的内容"
|
||||||
else:
|
else:
|
||||||
topic_desc = f"你们聊到了「{current_stage_name}」这个话题"
|
topic_desc = f"你们聊到了「{current_stage_name}」这个话题"
|
||||||
|
|
||||||
# --- 用户资料和时代背景 ---
|
|
||||||
profile_section = ""
|
profile_section = ""
|
||||||
if user_profile_context:
|
if user_profile_context:
|
||||||
profile_section = f"\n## 用户基本信息\n{user_profile_context}\n"
|
profile_section = f"\n## 用户基本信息\n{user_profile_context}\n"
|
||||||
@@ -460,7 +418,6 @@ def get_guided_conversation_prompt(
|
|||||||
return prompt
|
return prompt
|
||||||
|
|
||||||
|
|
||||||
# 保留向后兼容的函数名
|
|
||||||
def get_conversation_prompt(current_stage: ConversationStage, covered_topics: List[str], user_latest_response: str) -> str:
|
def get_conversation_prompt(current_stage: ConversationStage, covered_topics: List[str], user_latest_response: str) -> str:
|
||||||
"""向后兼容的函数"""
|
"""向后兼容的函数"""
|
||||||
return get_system_prompt(current_stage, covered_topics, user_latest_response)
|
return get_system_prompt(current_stage, covered_topics, user_latest_response)
|
||||||
@@ -8,7 +8,7 @@ from typing import Any, Optional
|
|||||||
|
|
||||||
from app.core.logging import get_logger
|
from app.core.logging import get_logger
|
||||||
|
|
||||||
from app.agents.prompts.memory_prompts import (
|
from app.agents.memoir.prompts import (
|
||||||
CHAPTER_CATEGORIES,
|
CHAPTER_CATEGORIES,
|
||||||
get_chapter_classification_prompt,
|
get_chapter_classification_prompt,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ from typing import Any, Dict
|
|||||||
from app.core.logging import get_logger
|
from app.core.logging import get_logger
|
||||||
from app.features.memoir.memoir_images.json_payload import extract_json_payload
|
from app.features.memoir.memoir_images.json_payload import extract_json_payload
|
||||||
|
|
||||||
from app.agents.prompts.memory_prompts import get_state_extraction_prompt
|
from app.agents.memoir.prompts import get_state_extraction_prompt
|
||||||
|
|
||||||
logger = get_logger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|||||||
@@ -8,12 +8,12 @@ from typing import Dict, List, Optional
|
|||||||
from app.core.dependencies import get_llm_provider
|
from app.core.dependencies import get_llm_provider
|
||||||
from app.core.logging import get_logger
|
from app.core.logging import get_logger
|
||||||
|
|
||||||
from app.agents.prompts import (
|
from app.agents.memoir.prompts import (
|
||||||
|
CHAPTER_CATEGORIES,
|
||||||
|
STAGE_TO_ORDER,
|
||||||
get_chapter_classification_prompt,
|
get_chapter_classification_prompt,
|
||||||
get_text_rewrite_prompt,
|
get_text_rewrite_prompt,
|
||||||
inject_image_placeholder_template,
|
inject_image_placeholder_template,
|
||||||
CHAPTER_CATEGORIES,
|
|
||||||
STAGE_TO_ORDER,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
logger = get_logger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ from typing import Any, Dict, Optional
|
|||||||
|
|
||||||
from app.core.logging import get_logger
|
from app.core.logging import get_logger
|
||||||
|
|
||||||
from app.agents.prompts.memory_prompts import (
|
from app.agents.memoir.prompts import (
|
||||||
get_creative_title_prompt,
|
get_creative_title_prompt,
|
||||||
get_narrative_prompt,
|
get_narrative_prompt,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ PlaceholderInjectAgent:对 narrative 做占位符模板注入。
|
|||||||
对应现有逻辑:inject_image_placeholder_template
|
对应现有逻辑:inject_image_placeholder_template
|
||||||
纯函数式,无 LLM 调用。
|
纯函数式,无 LLM 调用。
|
||||||
"""
|
"""
|
||||||
from app.agents.prompts.memory_prompts import inject_image_placeholder_template
|
from app.agents.memoir.prompts import inject_image_placeholder_template
|
||||||
|
|
||||||
|
|
||||||
def inject_placeholders(content: str) -> str:
|
def inject_placeholders(content: str) -> str:
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ from app.core.logging import get_logger
|
|||||||
from app.core.task_tracker import task_tracker
|
from app.core.task_tracker import task_tracker
|
||||||
|
|
||||||
from app.agents.state_schema import MemoirStateSchema
|
from app.agents.state_schema import MemoirStateSchema
|
||||||
from app.agents.prompts.memory_prompts import (
|
from app.agents.memoir.prompts import (
|
||||||
get_creative_title_prompt,
|
get_creative_title_prompt,
|
||||||
get_narrative_prompt,
|
get_narrative_prompt,
|
||||||
get_state_extraction_prompt,
|
get_state_extraction_prompt,
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import json
|
|||||||
import re
|
import re
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
# 章节分类映射
|
|
||||||
CHAPTER_CATEGORIES = {
|
CHAPTER_CATEGORIES = {
|
||||||
"childhood": "童年与成长背景",
|
"childhood": "童年与成长背景",
|
||||||
"education": "教育经历与青年时期",
|
"education": "教育经历与青年时期",
|
||||||
@@ -17,7 +16,6 @@ CHAPTER_CATEGORIES = {
|
|||||||
"summary": "人生总结",
|
"summary": "人生总结",
|
||||||
}
|
}
|
||||||
|
|
||||||
# 章节顺序
|
|
||||||
CHAPTER_ORDER = [
|
CHAPTER_ORDER = [
|
||||||
"childhood",
|
"childhood",
|
||||||
"education",
|
"education",
|
||||||
@@ -29,22 +27,19 @@ CHAPTER_ORDER = [
|
|||||||
"summary",
|
"summary",
|
||||||
]
|
]
|
||||||
|
|
||||||
# 统一的阶段名 → 排序索引映射
|
|
||||||
# 兼容 5 阶段简化名(conversation/state 模型)和 8 分类详细名(chapter 模型)
|
|
||||||
STAGE_TO_ORDER = {
|
STAGE_TO_ORDER = {
|
||||||
"childhood": 0,
|
"childhood": 0,
|
||||||
"education": 1,
|
"education": 1,
|
||||||
"career": 2, # 5-stage 简化名
|
"career": 2,
|
||||||
"career_early": 2, # 8-category 详细名
|
"career_early": 2,
|
||||||
"career_achievement": 3,
|
"career_achievement": 3,
|
||||||
"career_challenge": 4,
|
"career_challenge": 4,
|
||||||
"family": 5,
|
"family": 5,
|
||||||
"belief": 6, # 5-stage 简化名(单数)
|
"belief": 6,
|
||||||
"beliefs": 6, # 8-category 详细名(复数)
|
"beliefs": 6,
|
||||||
"summary": 7,
|
"summary": 7,
|
||||||
}
|
}
|
||||||
|
|
||||||
# 图片占位符入库前拼接的固定提示词模板(与原先 prompt 中要求一致,改为代码侧统一拼接)
|
|
||||||
IMAGE_PLACEHOLDER_TEMPLATE = (
|
IMAGE_PLACEHOLDER_TEMPLATE = (
|
||||||
"温暖怀旧风格,年代感复古色调,柔和光影,朴素温馨氛围,安静治愈,低饱和度,"
|
"温暖怀旧风格,年代感复古色调,柔和光影,朴素温馨氛围,安静治愈,低饱和度,"
|
||||||
"质感柔和细腻,简约构图,充满岁月沉淀感与故事感,高清唯美插画封面,不要包含文字,"
|
"质感柔和细腻,简约构图,充满岁月沉淀感与故事感,高清唯美插画封面,不要包含文字,"
|
||||||
@@ -53,8 +48,6 @@ IMAGE_PLACEHOLDER_TEMPLATE = (
|
|||||||
"有朦胧怀旧的年代感。"
|
"有朦胧怀旧的年代感。"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
# 匹配任意层数的图片占位符(2/4/6/8...层花括号),整段替换为规范四层,避免多余花括号残留导致客户端显示异常
|
|
||||||
_IMAGE_PLACEHOLDER_ANY_BRACES_RE = re.compile(
|
_IMAGE_PLACEHOLDER_ANY_BRACES_RE = re.compile(
|
||||||
r"(\{\{)+IMAGE:\s*([^}]+)(\}\})+",
|
r"(\{\{)+IMAGE:\s*([^}]+)(\}\})+",
|
||||||
re.DOTALL,
|
re.DOTALL,
|
||||||
@@ -64,9 +57,7 @@ _IMAGE_PLACEHOLDER_ANY_BRACES_RE = re.compile(
|
|||||||
def inject_image_placeholder_template(content: str) -> str:
|
def inject_image_placeholder_template(content: str) -> str:
|
||||||
"""
|
"""
|
||||||
入库前对章节正文做占位符处理:用正则匹配所有图片占位符位置,拼上固定模板。
|
入库前对章节正文做占位符处理:用正则匹配所有图片占位符位置,拼上固定模板。
|
||||||
支持任意层数花括号(如 {{、{{{{、{{{{{{ 等),输出统一为四层大括号 + 固定模板 + 描述,
|
支持任意层数花括号,输出统一为四层大括号 + 固定模板 + 描述。
|
||||||
避免 LLM 输出花括号过多时只替换内层导致多余花括号残留在正文中、在手机端被原样显示。
|
|
||||||
若占位符内已包含固定模板前缀则不再重复拼接。
|
|
||||||
"""
|
"""
|
||||||
if not content or not content.strip():
|
if not content or not content.strip():
|
||||||
return content
|
return content
|
||||||
@@ -82,6 +73,8 @@ def inject_image_placeholder_template(content: str) -> str:
|
|||||||
|
|
||||||
content = _IMAGE_PLACEHOLDER_ANY_BRACES_RE.sub(replace_one, content)
|
content = _IMAGE_PLACEHOLDER_ANY_BRACES_RE.sub(replace_one, content)
|
||||||
return content
|
return content
|
||||||
|
|
||||||
|
|
||||||
def get_system_prompt() -> str:
|
def get_system_prompt() -> str:
|
||||||
"""获取整理 Agent 的系统提示词"""
|
"""获取整理 Agent 的系统提示词"""
|
||||||
return """你是一位专业的传记作家和文字编辑,擅长将口语化的对话内容整理成优雅的书面语回忆录章节。
|
return """你是一位专业的传记作家和文字编辑,擅长将口语化的对话内容整理成优雅的书面语回忆录章节。
|
||||||
@@ -156,9 +149,7 @@ def get_chapter_classification_prompt(segments_text: str) -> str:
|
|||||||
def get_text_rewrite_prompt(segments_text: str, chapter_category: str, existing_content: str = "") -> str:
|
def get_text_rewrite_prompt(segments_text: str, chapter_category: str, existing_content: str = "") -> str:
|
||||||
"""获取文本改写的提示词"""
|
"""获取文本改写的提示词"""
|
||||||
chapter_name = CHAPTER_CATEGORIES.get(chapter_category, chapter_category)
|
chapter_name = CHAPTER_CATEGORIES.get(chapter_category, chapter_category)
|
||||||
|
|
||||||
existing_section = f"\n\n已有章节内容:\n{existing_content}" if existing_content else ""
|
existing_section = f"\n\n已有章节内容:\n{existing_content}" if existing_content else ""
|
||||||
|
|
||||||
return f"""{get_system_prompt()}
|
return f"""{get_system_prompt()}
|
||||||
|
|
||||||
请将以下口语化的对话内容改写为书面语,归类到"{chapter_name}"章节。
|
请将以下口语化的对话内容改写为书面语,归类到"{chapter_name}"章节。
|
||||||
@@ -193,8 +184,6 @@ def get_text_rewrite_prompt(segments_text: str, chapter_category: str, existing_
|
|||||||
def get_state_extraction_prompt(user_message: str, current_stage: str, stage_slots: dict) -> str:
|
def get_state_extraction_prompt(user_message: str, current_stage: str, stage_slots: dict) -> str:
|
||||||
"""抽取结构化信息并判断阶段"""
|
"""抽取结构化信息并判断阶段"""
|
||||||
slot_keys = list(stage_slots.keys())
|
slot_keys = list(stage_slots.keys())
|
||||||
|
|
||||||
# 提供所有阶段的 slot 参考,帮助 LLM 将内容归类到正确的阶段
|
|
||||||
all_stage_slots = {
|
all_stage_slots = {
|
||||||
"childhood": ["place", "people", "daily_life", "emotion", "turning_event"],
|
"childhood": ["place", "people", "daily_life", "emotion", "turning_event"],
|
||||||
"education": ["school", "city", "motivation", "challenge", "change"],
|
"education": ["school", "city", "motivation", "challenge", "change"],
|
||||||
@@ -227,10 +216,10 @@ def get_state_extraction_prompt(user_message: str, current_stage: str, stage_slo
|
|||||||
}}
|
}}
|
||||||
|
|
||||||
要求:
|
要求:
|
||||||
1. **应的 slot 列表
|
1. **先忽略话语中的语气词、填充词、寒暄、与AI的交互指令等无关内容**,只关注涉及人生经历的实质信息
|
||||||
4. slots 只填写确实提到的、与人生经历相关的实先忽略话语中的语气词、填充词、寒暄、与AI的交互指令等无关内容**,只关注涉及人生经历的实质信息
|
|
||||||
2. **detected_stage 必须根据用户话语的实际内容判断**,不要默认沿用系统当前阶段。用户可能在聊不同阶段的事情
|
2. **detected_stage 必须根据用户话语的实际内容判断**,不要默认沿用系统当前阶段。用户可能在聊不同阶段的事情
|
||||||
3. slots 的 key 必须属于 detected_stage 对质内容
|
3. slots 的 key 必须属于 detected_stage 对应的 slot 列表
|
||||||
|
4. slots 只填写确实提到的、与人生经历相关的实质内容
|
||||||
5. **snippet 应是提炼后的核心信息**,去除语气词和冗余表达,50 字以内
|
5. **snippet 应是提炼后的核心信息**,去除语气词和冗余表达,50 字以内
|
||||||
6. 如果用户话语中没有任何与人生经历相关的实质内容(如纯粹的寒暄、指令、语气词),slots 为空对象
|
6. 如果用户话语中没有任何与人生经历相关的实质内容(如纯粹的寒暄、指令、语气词),slots 为空对象
|
||||||
"""
|
"""
|
||||||
@@ -275,7 +264,7 @@ def get_creative_title_prompt(
|
|||||||
return f"""{get_system_prompt()}
|
return f"""{get_system_prompt()}
|
||||||
|
|
||||||
请根据阶段和情绪生成 1 个有创意的章节标题。
|
请根据阶段和情绪生成 1 个有创意的章节标题。
|
||||||
阶段:{stage}
|
阶段:{stage}
|
||||||
情绪:{emotion}
|
情绪:{emotion}
|
||||||
可用信息:{slots}{profile_section}{time_section}
|
可用信息:{slots}{profile_section}{time_section}
|
||||||
|
|
||||||
@@ -307,9 +296,7 @@ def get_narrative_prompt(
|
|||||||
context_tail = ""
|
context_tail = ""
|
||||||
if existing_content:
|
if existing_content:
|
||||||
context_tail = existing_content[-300:] if len(existing_content) > 300 else existing_content
|
context_tail = existing_content[-300:] if len(existing_content) > 300 else existing_content
|
||||||
|
|
||||||
context_section = f"\n\n【衔接上下文(已有内容的末尾,仅供参考衔接,不要重复)】:\n{context_tail}" if context_tail else ""
|
context_section = f"\n\n【衔接上下文(已有内容的末尾,仅供参考衔接,不要重复)】:\n{context_tail}" if context_tail else ""
|
||||||
|
|
||||||
profile_section = f"\n\n用户基本信息:\n{user_profile}" if user_profile else ""
|
profile_section = f"\n\n用户基本信息:\n{user_profile}" if user_profile else ""
|
||||||
age_hint = _build_age_hint(stage, birth_year)
|
age_hint = _build_age_hint(stage, birth_year)
|
||||||
time_section = f"\n时间参考:{age_hint}" if age_hint else ""
|
time_section = f"\n时间参考:{age_hint}" if age_hint else ""
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
"""
|
|
||||||
提示词模块
|
|
||||||
"""
|
|
||||||
from .conversation_prompts import (
|
|
||||||
ConversationStage,
|
|
||||||
get_system_prompt as get_conversation_prompt,
|
|
||||||
get_questions_for_stage,
|
|
||||||
get_guided_conversation_prompt,
|
|
||||||
get_opening_prompt,
|
|
||||||
INTERVIEW_QUESTIONS,
|
|
||||||
)
|
|
||||||
from .memory_prompts import (
|
|
||||||
get_system_prompt as get_memory_prompt,
|
|
||||||
get_chapter_classification_prompt,
|
|
||||||
get_text_rewrite_prompt,
|
|
||||||
get_state_extraction_prompt,
|
|
||||||
get_creative_title_prompt,
|
|
||||||
get_narrative_prompt,
|
|
||||||
inject_image_placeholder_template,
|
|
||||||
CHAPTER_CATEGORIES,
|
|
||||||
CHAPTER_ORDER,
|
|
||||||
STAGE_TO_ORDER,
|
|
||||||
)
|
|
||||||
from .profile_prompts import (
|
|
||||||
get_profile_greeting_prompt,
|
|
||||||
get_profile_extraction_prompt,
|
|
||||||
get_profile_followup_prompt,
|
|
||||||
format_user_profile_context,
|
|
||||||
get_missing_profile_fields,
|
|
||||||
PROFILE_FIELD_NAMES,
|
|
||||||
)
|
|
||||||
|
|
||||||
__all__ = [
|
|
||||||
"ConversationStage",
|
|
||||||
"get_conversation_prompt",
|
|
||||||
"get_questions_for_stage",
|
|
||||||
"get_guided_conversation_prompt",
|
|
||||||
"get_opening_prompt",
|
|
||||||
"INTERVIEW_QUESTIONS",
|
|
||||||
"get_memory_prompt",
|
|
||||||
"get_chapter_classification_prompt",
|
|
||||||
"get_text_rewrite_prompt",
|
|
||||||
"get_state_extraction_prompt",
|
|
||||||
"get_creative_title_prompt",
|
|
||||||
"get_narrative_prompt",
|
|
||||||
"inject_image_placeholder_template",
|
|
||||||
"CHAPTER_CATEGORIES",
|
|
||||||
"CHAPTER_ORDER",
|
|
||||||
"STAGE_TO_ORDER",
|
|
||||||
"get_profile_greeting_prompt",
|
|
||||||
"get_profile_extraction_prompt",
|
|
||||||
"get_profile_followup_prompt",
|
|
||||||
"format_user_profile_context",
|
|
||||||
"get_missing_profile_fields",
|
|
||||||
"PROFILE_FIELD_NAMES",
|
|
||||||
]
|
|
||||||
|
|
||||||
@@ -6,7 +6,7 @@ from app.features.user.models import User
|
|||||||
|
|
||||||
def get_missing_profile_fields(user: User) -> list:
|
def get_missing_profile_fields(user: User) -> list:
|
||||||
"""检查用户缺失的资料字段"""
|
"""检查用户缺失的资料字段"""
|
||||||
from app.agents.prompts.profile_prompts import get_missing_profile_fields as _get_missing
|
from app.agents.chat.prompts_profile import get_missing_profile_fields as _get_missing
|
||||||
return _get_missing(
|
return _get_missing(
|
||||||
birth_year=user.birth_year,
|
birth_year=user.birth_year,
|
||||||
birth_place=user.birth_place,
|
birth_place=user.birth_place,
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ from datetime import datetime, timezone
|
|||||||
from fastapi import WebSocket, WebSocketDisconnect, status
|
from fastapi import WebSocket, WebSocketDisconnect, status
|
||||||
from starlette.websockets import WebSocketState
|
from starlette.websockets import WebSocketState
|
||||||
|
|
||||||
from app.agents.prompts.profile_prompts import format_user_profile_context
|
from app.agents.chat.prompts_profile import format_user_profile_context
|
||||||
from app.core.db import AsyncSessionLocal
|
from app.core.db import AsyncSessionLocal
|
||||||
from app.core.security import verify_token
|
from app.core.security import verify_token
|
||||||
from app.features.conversation.models import Conversation, Segment
|
from app.features.conversation.models import Conversation, Segment
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ from sqlalchemy import select
|
|||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
from sqlalchemy.orm import joinedload
|
from sqlalchemy.orm import joinedload
|
||||||
|
|
||||||
from app.agents.prompts.memory_prompts import (
|
from app.agents.memoir.prompts import (
|
||||||
CHAPTER_CATEGORIES,
|
CHAPTER_CATEGORIES,
|
||||||
CHAPTER_ORDER,
|
CHAPTER_ORDER,
|
||||||
STAGE_TO_ORDER,
|
STAGE_TO_ORDER,
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ from app.features.memoir.models import (
|
|||||||
from app.features.user.models import User
|
from app.features.user.models import User
|
||||||
from app.core.dependencies import get_llm_provider
|
from app.core.dependencies import get_llm_provider
|
||||||
from app.agents.state_schema import MemoirStateSchema, SlotData, default_state
|
from app.agents.state_schema import MemoirStateSchema, SlotData, default_state
|
||||||
from app.agents.prompts.memory_prompts import (
|
from app.agents.memoir.prompts import (
|
||||||
STAGE_TO_ORDER,
|
STAGE_TO_ORDER,
|
||||||
get_narrative_prompt,
|
get_narrative_prompt,
|
||||||
inject_image_placeholder_template,
|
inject_image_placeholder_template,
|
||||||
@@ -34,7 +34,7 @@ from app.agents.prompts.memory_prompts import (
|
|||||||
from app.agents.memoir import MemoirOrchestrator
|
from app.agents.memoir import MemoirOrchestrator
|
||||||
from app.agents.memoir.narrative_agent import NarrativeAgent
|
from app.agents.memoir.narrative_agent import NarrativeAgent
|
||||||
from app.agents.memoir.placeholder_agent import inject_placeholders
|
from app.agents.memoir.placeholder_agent import inject_placeholders
|
||||||
from app.agents.prompts.profile_prompts import format_user_profile_context
|
from app.agents.chat.prompts_profile import format_user_profile_context
|
||||||
from app.features.memoir.memoir_images.parser import (
|
from app.features.memoir.memoir_images.parser import (
|
||||||
build_initial_image_assets,
|
build_initial_image_assets,
|
||||||
parse_image_placeholders,
|
parse_image_placeholders,
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ from database import get_async_db
|
|||||||
from database.models import Chapter as ChapterModel, ChapterSection
|
from database.models import Chapter as ChapterModel, ChapterSection
|
||||||
from database.models import User as UserModel
|
from database.models import User as UserModel
|
||||||
from middleware.auth import get_current_user
|
from middleware.auth import get_current_user
|
||||||
from app.agents.prompts.memory_prompts import CHAPTER_CATEGORIES, CHAPTER_ORDER, STAGE_TO_ORDER
|
from app.agents.memoir.prompts import CHAPTER_CATEGORIES, CHAPTER_ORDER, STAGE_TO_ORDER
|
||||||
from services.memoir_images.schema import (
|
from services.memoir_images.schema import (
|
||||||
completed_image_assets,
|
completed_image_assets,
|
||||||
IMAGE_STATUS_COMPLETED,
|
IMAGE_STATUS_COMPLETED,
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ from database.models import User as UserModel
|
|||||||
from services.auth_service import verify_token
|
from services.auth_service import verify_token
|
||||||
from services.memoir_state_service import get_or_create_state
|
from services.memoir_state_service import get_or_create_state
|
||||||
from services import asr_service, redis_service
|
from services import asr_service, redis_service
|
||||||
from app.agents.prompts.profile_prompts import format_user_profile_context
|
from app.agents.chat.prompts_profile import format_user_profile_context
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
LEGACY_VOICE_SESSION_ID = "legacy"
|
LEGACY_VOICE_SESSION_ID = "legacy"
|
||||||
@@ -924,7 +924,7 @@ async def websocket_endpoint(
|
|||||||
|
|
||||||
def _get_missing_profile_fields(user: UserModel) -> list:
|
def _get_missing_profile_fields(user: UserModel) -> list:
|
||||||
"""检查用户缺失的资料字段"""
|
"""检查用户缺失的资料字段"""
|
||||||
from app.agents.prompts.profile_prompts import get_missing_profile_fields
|
from app.agents.chat.prompts_profile import get_missing_profile_fields
|
||||||
return get_missing_profile_fields(
|
return get_missing_profile_fields(
|
||||||
birth_year=user.birth_year,
|
birth_year=user.birth_year,
|
||||||
birth_place=user.birth_place,
|
birth_place=user.birth_place,
|
||||||
@@ -935,7 +935,7 @@ def _get_missing_profile_fields(user: UserModel) -> list:
|
|||||||
|
|
||||||
def _get_filled_profile_fields(user: UserModel) -> dict:
|
def _get_filled_profile_fields(user: UserModel) -> dict:
|
||||||
"""获取用户已有的资料字段(中文展示)"""
|
"""获取用户已有的资料字段(中文展示)"""
|
||||||
from app.agents.prompts.profile_prompts import PROFILE_FIELD_NAMES
|
from app.agents.chat.prompts_profile import PROFILE_FIELD_NAMES
|
||||||
filled = {}
|
filled = {}
|
||||||
if user.birth_year:
|
if user.birth_year:
|
||||||
filled["birth_year"] = str(user.birth_year)
|
filled["birth_year"] = str(user.birth_year)
|
||||||
@@ -1045,7 +1045,7 @@ async def process_user_message(
|
|||||||
# 构建用户资料上下文
|
# 构建用户资料上下文
|
||||||
user_profile_context = ""
|
user_profile_context = ""
|
||||||
if user:
|
if user:
|
||||||
from app.agents.prompts.profile_prompts import format_user_profile_context
|
from app.agents.chat.prompts_profile import format_user_profile_context
|
||||||
user_profile_context = format_user_profile_context(
|
user_profile_context = format_user_profile_context(
|
||||||
birth_year=user.birth_year,
|
birth_year=user.birth_year,
|
||||||
birth_place=user.birth_place,
|
birth_place=user.birth_place,
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ from app.features.memoir.models import Book, Chapter, ChapterSection, MemoirStat
|
|||||||
from app.features.user.models import User
|
from app.features.user.models import User
|
||||||
from app.core.dependencies import get_llm_provider
|
from app.core.dependencies import get_llm_provider
|
||||||
from app.agents.state_schema import MemoirStateSchema, SlotData, default_state
|
from app.agents.state_schema import MemoirStateSchema, SlotData, default_state
|
||||||
from app.agents.prompts.memory_prompts import (
|
from app.agents.memoir.prompts import (
|
||||||
get_creative_title_prompt,
|
get_creative_title_prompt,
|
||||||
get_narrative_prompt,
|
get_narrative_prompt,
|
||||||
get_state_extraction_prompt,
|
get_state_extraction_prompt,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
"""测试 memory_prompts.inject_image_placeholder_template:占位符花括号统一为四层,避免多余花括号残留"""
|
"""测试 memory_prompts.inject_image_placeholder_template:占位符花括号统一为四层,避免多余花括号残留"""
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from app.agents.prompts.memory_prompts import (
|
from app.agents.memoir.prompts import (
|
||||||
IMAGE_PLACEHOLDER_TEMPLATE,
|
IMAGE_PLACEHOLDER_TEMPLATE,
|
||||||
inject_image_placeholder_template,
|
inject_image_placeholder_template,
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user