2026-01-07 11:56:53 +08:00
|
|
|
|
"""
|
|
|
|
|
|
回忆录整理 Agent 提示词模板
|
|
|
|
|
|
"""
|
2026-02-13 21:45:56 +01:00
|
|
|
|
import json
|
2026-01-07 11:56:53 +08:00
|
|
|
|
|
|
|
|
|
|
# 章节分类映射
|
|
|
|
|
|
CHAPTER_CATEGORIES = {
|
|
|
|
|
|
"childhood": "童年与成长背景",
|
|
|
|
|
|
"education": "教育经历与青年时期",
|
|
|
|
|
|
"career_early": "崭露头角",
|
|
|
|
|
|
"career_achievement": "主要成就与巅峰时刻",
|
|
|
|
|
|
"career_challenge": "挫折、挑战与重大转折",
|
|
|
|
|
|
"family": "家庭与情感",
|
|
|
|
|
|
"beliefs": "信念与价值观",
|
|
|
|
|
|
"summary": "人生总结",
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# 章节顺序
|
|
|
|
|
|
CHAPTER_ORDER = [
|
|
|
|
|
|
"childhood",
|
|
|
|
|
|
"education",
|
|
|
|
|
|
"career_early",
|
|
|
|
|
|
"career_achievement",
|
|
|
|
|
|
"career_challenge",
|
|
|
|
|
|
"family",
|
|
|
|
|
|
"beliefs",
|
|
|
|
|
|
"summary",
|
|
|
|
|
|
]
|
|
|
|
|
|
|
2026-02-13 21:45:56 +01:00
|
|
|
|
# 统一的阶段名 → 排序索引映射
|
|
|
|
|
|
# 兼容 5 阶段简化名(conversation/state 模型)和 8 分类详细名(chapter 模型)
|
|
|
|
|
|
STAGE_TO_ORDER = {
|
|
|
|
|
|
"childhood": 0,
|
|
|
|
|
|
"education": 1,
|
|
|
|
|
|
"career": 2, # 5-stage 简化名
|
|
|
|
|
|
"career_early": 2, # 8-category 详细名
|
|
|
|
|
|
"career_achievement": 3,
|
|
|
|
|
|
"career_challenge": 4,
|
|
|
|
|
|
"family": 5,
|
|
|
|
|
|
"belief": 6, # 5-stage 简化名(单数)
|
|
|
|
|
|
"beliefs": 6, # 8-category 详细名(复数)
|
|
|
|
|
|
"summary": 7,
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-01-07 11:56:53 +08:00
|
|
|
|
|
|
|
|
|
|
def get_system_prompt() -> str:
|
|
|
|
|
|
"""获取整理 Agent 的系统提示词"""
|
|
|
|
|
|
return """你是一位专业的传记作家和文字编辑,擅长将口语化的对话内容整理成优雅的书面语回忆录章节。
|
|
|
|
|
|
|
|
|
|
|
|
你的任务:
|
|
|
|
|
|
1. 接收对话段落文本(口语化)
|
|
|
|
|
|
2. 识别内容主题,归类到对应章节(童年/教育/事业/家庭/信念/总结)
|
|
|
|
|
|
3. 将口语化表达改写为书面语,保持原意和情感
|
|
|
|
|
|
4. 生成合适的章节标题和段落结构
|
|
|
|
|
|
5. 提取关键信息,形成连贯的叙述
|
|
|
|
|
|
6. 建议插图位置(在描述场景、人物、地点的地方)
|
|
|
|
|
|
|
|
|
|
|
|
改写原则:
|
|
|
|
|
|
- 保持用户的真实声音和情感
|
|
|
|
|
|
- 使用优雅但不失亲切的书面语
|
|
|
|
|
|
- 适当添加过渡句,使段落连贯
|
|
|
|
|
|
- 保留生动的细节和对话
|
|
|
|
|
|
- 去除口语中的"嗯"、"那个"等填充词
|
|
|
|
|
|
- 保持时间顺序和逻辑清晰
|
|
|
|
|
|
|
|
|
|
|
|
章节分类规则:
|
|
|
|
|
|
- 童年相关 → "童年与成长背景"
|
|
|
|
|
|
- 学校、老师、同学 → "教育经历与青年时期"
|
|
|
|
|
|
- 工作、职业、成就 → "主要成就与巅峰时刻" 或 "崭露头角"
|
|
|
|
|
|
- 困难、挫折 → "挫折、挑战与重大转折"
|
|
|
|
|
|
- 伴侣、孩子、家庭生活 → "家庭与情感"
|
|
|
|
|
|
- 价值观、信念、座右铭 → "信念与价值观"
|
|
|
|
|
|
- 总结、感悟、展望 → "人生总结"
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_chapter_classification_prompt(segments_text: str) -> str:
|
|
|
|
|
|
"""获取章节分类的提示词"""
|
|
|
|
|
|
return f"""{get_system_prompt()}
|
|
|
|
|
|
|
|
|
|
|
|
请分析以下对话内容,判断应该归类到哪个章节类别:
|
|
|
|
|
|
- childhood: 童年与成长背景
|
|
|
|
|
|
- education: 教育经历与青年时期
|
|
|
|
|
|
- career_early: 崭露头角(早期事业)
|
|
|
|
|
|
- career_achievement: 主要成就与巅峰时刻
|
|
|
|
|
|
- career_challenge: 挫折、挑战与重大转折
|
|
|
|
|
|
- family: 家庭与情感
|
|
|
|
|
|
- beliefs: 信念与价值观
|
|
|
|
|
|
- summary: 人生总结
|
|
|
|
|
|
|
|
|
|
|
|
对话内容:
|
|
|
|
|
|
{segments_text}
|
|
|
|
|
|
|
|
|
|
|
|
请只返回章节类别(如:childhood),不要返回其他内容。"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_text_rewrite_prompt(segments_text: str, chapter_category: str, existing_content: str = "") -> str:
|
|
|
|
|
|
"""获取文本改写的提示词"""
|
|
|
|
|
|
chapter_name = CHAPTER_CATEGORIES.get(chapter_category, chapter_category)
|
|
|
|
|
|
|
|
|
|
|
|
existing_section = f"\n\n已有章节内容:\n{existing_content}" if existing_content else ""
|
|
|
|
|
|
|
|
|
|
|
|
return f"""{get_system_prompt()}
|
|
|
|
|
|
|
|
|
|
|
|
请将以下口语化的对话内容改写为书面语,归类到"{chapter_name}"章节。
|
|
|
|
|
|
|
|
|
|
|
|
对话内容:
|
|
|
|
|
|
{segments_text}
|
|
|
|
|
|
{existing_section}
|
|
|
|
|
|
|
|
|
|
|
|
请按照以下格式返回 JSON:
|
|
|
|
|
|
{{
|
|
|
|
|
|
"title": "章节标题",
|
2026-01-21 22:31:03 +01:00
|
|
|
|
"content": "改写后的书面语内容(包含图片占位符)",
|
|
|
|
|
|
"summary": "章节摘要(50字以内)"
|
2026-01-07 11:56:53 +08:00
|
|
|
|
}}
|
|
|
|
|
|
|
|
|
|
|
|
要求:
|
|
|
|
|
|
1. 标题要简洁有力,能概括章节主题
|
|
|
|
|
|
2. 内容要流畅自然,保持原意和情感
|
|
|
|
|
|
3. 如果已有章节内容,请将新内容与已有内容自然融合
|
2026-01-21 22:31:03 +01:00
|
|
|
|
4. 在内容中适当位置插入图片占位符
|
|
|
|
|
|
|
|
|
|
|
|
## 图片占位符格式
|
|
|
|
|
|
在描述场景、人物、重要时刻的段落后,插入:
|
|
|
|
|
|
{{{{IMAGE:具体的图片描述}}}}
|
|
|
|
|
|
|
|
|
|
|
|
示例:
|
|
|
|
|
|
{{{{IMAGE:南方小镇的青石板路,两旁是白墙黑瓦的老房子}}}}
|
|
|
|
|
|
{{{{IMAGE:奶奶坐在院子里的藤椅上,手里摇着蒲扇}}}}
|
|
|
|
|
|
|
|
|
|
|
|
占位符单独占一行,描述要具体有画面感。"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_state_extraction_prompt(user_message: str, current_stage: str, stage_slots: dict) -> str:
|
|
|
|
|
|
"""抽取结构化信息并判断阶段"""
|
|
|
|
|
|
slot_keys = list(stage_slots.keys())
|
2026-02-13 21:45:56 +01:00
|
|
|
|
|
|
|
|
|
|
# 提供所有阶段的 slot 参考,帮助 LLM 将内容归类到正确的阶段
|
|
|
|
|
|
all_stage_slots = {
|
|
|
|
|
|
"childhood": ["place", "people", "daily_life", "emotion", "turning_event"],
|
|
|
|
|
|
"education": ["school", "city", "motivation", "challenge", "change"],
|
|
|
|
|
|
"career": ["job", "environment", "decision", "pressure", "growth"],
|
|
|
|
|
|
"family": ["relationship", "conflict", "support", "responsibility", "change"],
|
|
|
|
|
|
"belief": ["value", "regret", "pride", "lesson"],
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-01-21 22:31:03 +01:00
|
|
|
|
return f"""{get_system_prompt()}
|
|
|
|
|
|
|
2026-02-13 21:45:56 +01:00
|
|
|
|
你需要从用户话语中抽取结构化信息,并判断用户实际在谈论哪个人生阶段。
|
|
|
|
|
|
|
|
|
|
|
|
系统当前跟踪的阶段:{current_stage}
|
|
|
|
|
|
该阶段可填 slots:{slot_keys}
|
2026-01-21 22:31:03 +01:00
|
|
|
|
|
2026-02-13 21:45:56 +01:00
|
|
|
|
所有阶段及其 slots 参考:
|
|
|
|
|
|
{json.dumps(all_stage_slots, ensure_ascii=False, indent=2)}
|
2026-01-21 22:31:03 +01:00
|
|
|
|
|
|
|
|
|
|
用户话语:
|
|
|
|
|
|
{user_message}
|
|
|
|
|
|
|
|
|
|
|
|
请只返回 JSON,格式如下:
|
|
|
|
|
|
{{
|
|
|
|
|
|
"detected_stage": "childhood|education|career|family|belief",
|
|
|
|
|
|
"slots": {{
|
|
|
|
|
|
"slot_key": "snippet"
|
|
|
|
|
|
}},
|
|
|
|
|
|
"emotion": "neutral|warm|low|highlight",
|
|
|
|
|
|
"is_new_chapter": true
|
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
|
|
|
|
要求:
|
2026-02-13 21:45:56 +01:00
|
|
|
|
1. **detected_stage 必须根据用户话语的实际内容判断**,不要默认沿用系统当前阶段。用户可能在聊不同阶段的事情。
|
|
|
|
|
|
2. slots 的 key 必须属于 detected_stage 对应的 slot 列表
|
|
|
|
|
|
3. slots 只填写确实提到的内容
|
|
|
|
|
|
4. snippet 保持用户原话风格,50 字以内
|
|
|
|
|
|
5. 如果没有明确内容,slots 为空对象
|
2026-01-21 22:31:03 +01:00
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_creative_title_prompt(stage: str, emotion: str, slots: dict) -> str:
|
|
|
|
|
|
"""生成有创意的章节标题"""
|
|
|
|
|
|
return f"""{get_system_prompt()}
|
|
|
|
|
|
|
|
|
|
|
|
请根据阶段和情绪生成 1 个有创意的章节标题。
|
|
|
|
|
|
阶段:{stage}
|
|
|
|
|
|
情绪:{emotion}
|
|
|
|
|
|
可用信息:{slots}
|
|
|
|
|
|
|
|
|
|
|
|
要求:
|
|
|
|
|
|
1. 标题 12-18 字以内
|
|
|
|
|
|
2. 情绪 + 人生阶段 + 意象
|
|
|
|
|
|
3. 示例风格:
|
|
|
|
|
|
- 《那个夏天,我第一次离开家》
|
|
|
|
|
|
- 《在陌生城市站稳脚跟》
|
|
|
|
|
|
- 《不是所有选择都被理解》
|
|
|
|
|
|
- 《慢下来,人生开始发声》
|
|
|
|
|
|
|
|
|
|
|
|
只输出标题文字,不要加引号或其他内容。
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_narrative_prompt(stage: str, slots: dict, new_content: str, existing_content: str = "") -> str:
|
|
|
|
|
|
"""将对话改写为叙述,并增量更新"""
|
|
|
|
|
|
existing_section = f"\n\n已有内容:\n{existing_content}" if existing_content else ""
|
|
|
|
|
|
return f"""{get_system_prompt()}
|
|
|
|
|
|
|
|
|
|
|
|
请将以下对话内容整理为第一人称叙述,并与已有内容自然融合。
|
|
|
|
|
|
阶段:{stage}
|
|
|
|
|
|
可用信息:{slots}
|
|
|
|
|
|
|
|
|
|
|
|
新的对话内容:
|
|
|
|
|
|
{new_content}
|
|
|
|
|
|
{existing_section}
|
|
|
|
|
|
|
|
|
|
|
|
要求:
|
|
|
|
|
|
1. 使用第一人称叙述
|
|
|
|
|
|
2. 保留少量原话(引用)
|
|
|
|
|
|
3. 增量追加,不重写全文
|
|
|
|
|
|
4. 语气自然,有情绪
|
|
|
|
|
|
5. 在适合配图的地方插入图片占位符
|
|
|
|
|
|
|
|
|
|
|
|
## 图片占位符格式
|
|
|
|
|
|
在描述场景、人物、重要时刻的段落后,插入图片占位符,格式为:
|
|
|
|
|
|
{{{{IMAGE:图片描述}}}}
|
|
|
|
|
|
|
|
|
|
|
|
示例:
|
|
|
|
|
|
- {{{{IMAGE:南方小镇的青石板路,两旁是白墙黑瓦的老房子}}}}
|
|
|
|
|
|
- {{{{IMAGE:奶奶坐在院子里的藤椅上,手里摇着蒲扇}}}}
|
|
|
|
|
|
- {{{{IMAGE:少年背着书包站在火车站台上,回望身后的小镇}}}}
|
|
|
|
|
|
- {{{{IMAGE:泛黄的大学录取通知书,压在一摞旧课本下}}}}
|
|
|
|
|
|
|
|
|
|
|
|
图片占位符要求:
|
|
|
|
|
|
- 描述要具体、有画面感,便于后续生成或匹配图片
|
|
|
|
|
|
- 每 200-300 字左右可以插入一个
|
|
|
|
|
|
- 单独占一行,不要嵌入段落中
|
|
|
|
|
|
- 不要使用括号或星号等其他格式
|
|
|
|
|
|
|
|
|
|
|
|
只输出最终叙述文本(包含图片占位符)。
|
|
|
|
|
|
"""
|
2026-01-07 11:56:53 +08:00
|
|
|
|
|