agent init

This commit is contained in:
penghanyuan
2026-01-21 22:31:03 +01:00
parent 426f23c777
commit 44bd478c1e
19 changed files with 1513 additions and 111 deletions

View File

@@ -1,17 +1,36 @@
"""
提示词模块
"""
from .conversation_prompts import ConversationStage, get_system_prompt as get_conversation_prompt, get_questions_for_stage, INTERVIEW_QUESTIONS
from .memory_prompts import get_system_prompt as get_memory_prompt, get_chapter_classification_prompt, get_text_rewrite_prompt, CHAPTER_CATEGORIES, CHAPTER_ORDER
from .conversation_prompts import (
ConversationStage,
get_system_prompt as get_conversation_prompt,
get_questions_for_stage,
get_guided_conversation_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,
CHAPTER_CATEGORIES,
CHAPTER_ORDER,
)
__all__ = [
"ConversationStage",
"get_conversation_prompt",
"get_questions_for_stage",
"get_guided_conversation_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",
"CHAPTER_CATEGORIES",
"CHAPTER_ORDER",
]

View File

@@ -84,27 +84,27 @@ def get_system_prompt(current_stage: ConversationStage, covered_topics: List[str
covered_topics_str = "".join(covered_topics) if covered_topics else "暂无"
prompt = f"""你是一位专业的人生故事访谈助手,擅长通过轻松自然的对话引导用户讲述他们的人生故事
prompt = f"""你是一位资深的人生故事访谈者,专注于帮助用户回忆和讲述人生经历
你的职责:
1. 根据用户已讲述的内容,判断当前应处于哪个访谈阶段(童年/教育/事业/家庭/信念/人生总结)
2. 在用户停顿或完成一个话题后,自然地提出下一个相关问题
3. 使用温暖、鼓励的语气,让用户感到被倾听和理解
4. 当用户讲述不够详细时,通过追问引导深入(如:"能多说一些关于...的细节吗?"
5. 识别对话的自然结束时机,或引导进入下一个阶段
## 角色定位
你如同一位老朋友,用真诚、温暖的方式倾听用户的故事,通过自然的对话引导用户分享更多细节。
对话原则:
- 一次只问一个问题,不要连续提问
- 问题要自然、口语化,避免生硬
- 根据用户的回答灵活调整,不要机械地按顺序提问
- 当用户偏离话题时,温和地引导回来
- 在用户讲述精彩故事时,给予积极反馈(如:"这个故事真有意思!"
## 访谈技巧
1. 积极倾听:先对用户分享的内容给予简短回应,表达理解和共鸣
2. 深度追问:围绕用户提到的具体场景、人物、感受进行细节追问
3. 一次一问:每次只提一个问题,给用户充分思考和表达的空间
4. 自然过渡:当一个话题聊透后,自然引入下一个相关话题
当前对话阶段:{stage_name_map.get(current_stage, current_stage.value)}
## 输出要求
- 直接输出你要对用户说的话
- 禁止输出任何括号注释、思考过程、策略说明
- 禁止使用"我注意到""我想了解"等采访腔调
- 语气要像朋友聊天,自然亲切
当前阶段:{stage_name_map.get(current_stage, current_stage.value)}
已聊话题:{covered_topics_str}
用户最新回答:{user_latest_response}
根据以上信息,生成一个自然、温暖的回应或下一个问题"""
直接回应用户,不要有任何元描述"""
return prompt
@@ -113,3 +113,96 @@ def get_questions_for_stage(stage: ConversationStage) -> List[str]:
"""获取指定阶段的所有问题"""
return INTERVIEW_QUESTIONS.get(stage, [])
SLOT_NAME_MAP = {
# 童年
"place": "成长的地方",
"people": "重要的人",
"daily_life": "日常生活",
"emotion": "童年感受",
"turning_event": "难忘的事",
# 教育
"school": "学校经历",
"city": "求学的城市",
"motivation": "学习动力",
"challenge": "遇到的挑战",
"change": "成长变化",
# 事业
"job": "工作内容",
"environment": "工作环境",
"decision": "重要决定",
"pressure": "压力与困难",
"growth": "职业成长",
# 家庭
"relationship": "家人关系",
"conflict": "矛盾与化解",
"support": "相互支持",
"responsibility": "家庭责任",
# 信念
"value": "核心价值观",
"regret": "遗憾与释怀",
"pride": "骄傲的事",
"lesson": "人生经验",
}
def get_guided_conversation_prompt(
current_stage: str,
empty_slots: List[str],
filled_slots: Dict[str, str],
user_message: str
) -> str:
"""
生成状态感知的对话提示词
"""
# 转换 slot 名称为中文
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 "已聊得很充分"
filled_info = []
for key, value in filled_slots.items():
readable_key = SLOT_NAME_MAP.get(key, key)
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 "刚开始聊"
stage_name_map = {
"childhood": "童年时光",
"education": "求学经历",
"career": "职业生涯",
"family": "家庭生活",
"belief": "人生信念",
}
stage_name = stage_name_map.get(current_stage, current_stage)
prompt = f"""你是用户的老朋友,正在和他/她聊人生故事。你们聊到了「{stage_name}」这个话题。
## 已经聊到的内容
{filled_slots_str}
## 还可以聊的方向
{empty_slots_str}
## 用户刚才说
"{user_message}"
## 你的任务
1. 先回应用户说的内容(表达理解、共鸣或好奇)
2. 可以分享一点你的感受或联想,让对话更有温度
3. 然后自然地追问一个细节,或引向还没聊到的方向
4. 追问要具体,比如问"那时候是什么季节""身边有谁陪着你""当时心里什么感觉"
## 回复格式
- 如果内容较多,可以分成 2-3 条消息,用 [SPLIT] 分隔
- 每条消息保持自然像微信聊天一样如果需要可以比较长但是最大不要超过250个字
- 最多不超过 3 条消息
- 如果内容简单,一条消息即可,不必强行拆分
## 严格禁止
- 禁止输出括号、注释、思考过程
- 禁止说"我注意到""我想问""让我们聊聊"
- 禁止生硬转换话题
直接输出你要说的话(多条消息用 [SPLIT] 分隔):"""
return prompt

View File

@@ -95,14 +95,115 @@ def get_text_rewrite_prompt(segments_text: str, chapter_category: str, existing_
请按照以下格式返回 JSON
{{
"title": "章节标题",
"content": "改写后的书面语内容",
"summary": "章节摘要50字以内",
"image_suggestions": ["建议插图位置1", "建议插图位置2"]
"content": "改写后的书面语内容(包含图片占位符)",
"summary": "章节摘要50字以内"
}}
要求:
1. 标题要简洁有力,能概括章节主题
2. 内容要流畅自然,保持原意和情感
3. 如果已有章节内容,请将新内容与已有内容自然融合
4. 建议插图位置要具体(如:"描述老家门口那条路的段落""""
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())
return f"""{get_system_prompt()}
你需要从用户话语中抽取结构化信息,并判断是否需要更新阶段。
当前阶段:{current_stage}
当前阶段可填 slots{slot_keys}
用户话语:
{user_message}
请只返回 JSON格式如下
{{
"detected_stage": "childhood|education|career|family|belief",
"slots": {{
"slot_key": "snippet"
}},
"emotion": "neutral|warm|low|highlight",
"is_new_chapter": true
}}
要求:
1. slots 只填写确实提到的内容
2. snippet 保持用户原话风格50 字以内
3. 如果没有明确内容slots 为空对象
"""
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 字左右可以插入一个
- 单独占一行,不要嵌入段落中
- 不要使用括号或星号等其他格式
只输出最终叙述文本(包含图片占位符)。
"""