添加AI代理模块
This commit is contained in:
11
api/agents/__init__.py
Normal file
11
api/agents/__init__.py
Normal file
@@ -0,0 +1,11 @@
|
||||
"""
|
||||
Agent 模块
|
||||
"""
|
||||
from .conversation_agent import ConversationAgent
|
||||
from .memory_agent import MemoryAgent
|
||||
|
||||
__all__ = [
|
||||
"ConversationAgent",
|
||||
"MemoryAgent",
|
||||
]
|
||||
|
||||
BIN
api/agents/__pycache__/__init__.cpython-312.pyc
Normal file
BIN
api/agents/__pycache__/__init__.cpython-312.pyc
Normal file
Binary file not shown.
BIN
api/agents/__pycache__/conversation_agent.cpython-312.pyc
Normal file
BIN
api/agents/__pycache__/conversation_agent.cpython-312.pyc
Normal file
Binary file not shown.
BIN
api/agents/__pycache__/memory_agent.cpython-312.pyc
Normal file
BIN
api/agents/__pycache__/memory_agent.cpython-312.pyc
Normal file
Binary file not shown.
155
api/agents/conversation_agent.py
Normal file
155
api/agents/conversation_agent.py
Normal file
@@ -0,0 +1,155 @@
|
||||
"""
|
||||
对话 Agent:基于访谈问题清单,动态选择问题,实时生成回应
|
||||
"""
|
||||
import os
|
||||
from typing import List, Optional
|
||||
|
||||
from langchain.chains import ConversationChain
|
||||
from langchain.memory import ConversationBufferMemory
|
||||
from langchain.prompts import PromptTemplate
|
||||
from langchain_openai import ChatOpenAI
|
||||
|
||||
from .prompts import ConversationStage, get_conversation_prompt
|
||||
|
||||
|
||||
class ConversationAgent:
|
||||
"""对话 Agent"""
|
||||
|
||||
def __init__(self):
|
||||
# 初始化 LLM(使用环境变量配置)
|
||||
# 优先使用 LLM_API_KEY 和 LLM_BASE_URL,如果没有则使用 OPENAI_API_KEY
|
||||
api_key = os.getenv("LLM_API_KEY") or os.getenv("OPENAI_API_KEY", "")
|
||||
base_url = os.getenv("LLM_BASE_URL", "")
|
||||
model_name = os.getenv("OPENAI_MODEL", "gpt-4o")
|
||||
|
||||
if not api_key:
|
||||
self.llm = None
|
||||
self.memories: dict[str, ConversationBufferMemory] = {}
|
||||
return
|
||||
|
||||
# 如果提供了 base_url,需要处理路径(langchain 会自动添加 /v1/chat/completions)
|
||||
llm_kwargs = {
|
||||
"temperature": 0.7,
|
||||
"model": model_name,
|
||||
"openai_api_key": api_key,
|
||||
}
|
||||
|
||||
if base_url:
|
||||
# 移除可能的 /v1/chat/completions 路径,langchain 会自动添加
|
||||
if base_url.endswith("/v1/chat/completions"):
|
||||
base_url = base_url[:-20] # 移除 "/v1/chat/completions"
|
||||
elif base_url.endswith("/v1"):
|
||||
base_url = base_url[:-3] # 移除 "/v1"
|
||||
# 确保 base_url 以 / 结尾(如果没有)
|
||||
if base_url and not base_url.endswith("/"):
|
||||
base_url += "/"
|
||||
llm_kwargs["openai_api_base"] = base_url
|
||||
|
||||
try:
|
||||
self.llm = ChatOpenAI(**llm_kwargs)
|
||||
except Exception:
|
||||
self.llm = None
|
||||
|
||||
# 对话记忆
|
||||
self.memories: dict[str, ConversationBufferMemory] = {}
|
||||
|
||||
# 对话记忆
|
||||
self.memories: dict[str, ConversationBufferMemory] = {}
|
||||
|
||||
def _get_memory(self, conversation_id: str) -> ConversationBufferMemory:
|
||||
"""获取或创建对话记忆"""
|
||||
if conversation_id not in self.memories:
|
||||
self.memories[conversation_id] = ConversationBufferMemory(
|
||||
return_messages=True,
|
||||
memory_key="history"
|
||||
)
|
||||
return self.memories[conversation_id]
|
||||
|
||||
def generate_response(
|
||||
self,
|
||||
conversation_id: str,
|
||||
user_message: str,
|
||||
current_stage: Optional[ConversationStage] = None,
|
||||
covered_topics: Optional[List[str]] = None
|
||||
) -> str:
|
||||
"""
|
||||
生成 Agent 回应
|
||||
|
||||
Args:
|
||||
conversation_id: 对话 ID
|
||||
user_message: 用户消息
|
||||
current_stage: 当前对话阶段
|
||||
covered_topics: 已聊过的话题列表
|
||||
|
||||
Returns:
|
||||
Agent 回应文本
|
||||
"""
|
||||
if current_stage is None:
|
||||
current_stage = ConversationStage.CHILDHOOD
|
||||
|
||||
if covered_topics is None:
|
||||
covered_topics = []
|
||||
|
||||
# 如果没有配置 LLM,返回默认回应
|
||||
if not self.llm:
|
||||
return "抱歉,LLM 服务未配置。请设置 LLM_API_KEY 或 OPENAI_API_KEY 环境变量。"
|
||||
|
||||
# 获取系统提示词
|
||||
system_prompt = get_conversation_prompt(current_stage, covered_topics, user_message)
|
||||
|
||||
# 获取对话记忆
|
||||
memory = self._get_memory(conversation_id)
|
||||
|
||||
# 创建对话链
|
||||
prompt_template = PromptTemplate(
|
||||
input_variables=["history", "input"],
|
||||
template=f"{system_prompt}\n\n{{history}}\n\nHuman: {{input}}\n\nAssistant:"
|
||||
)
|
||||
|
||||
chain = ConversationChain(
|
||||
llm=self.llm,
|
||||
prompt=prompt_template,
|
||||
memory=memory,
|
||||
verbose=False
|
||||
)
|
||||
|
||||
# 生成回应
|
||||
response = chain.predict(input=user_message)
|
||||
|
||||
return response
|
||||
|
||||
def detect_stage(self, conversation_id: str, user_message: str) -> ConversationStage:
|
||||
"""
|
||||
检测对话阶段
|
||||
|
||||
Args:
|
||||
conversation_id: 对话 ID
|
||||
user_message: 用户消息
|
||||
|
||||
Returns:
|
||||
检测到的对话阶段
|
||||
"""
|
||||
# 简单的关键词检测(实际应该使用更智能的方法)
|
||||
message_lower = user_message.lower()
|
||||
|
||||
if any(word in message_lower for word in ["童年", "小时候", "出生", "家庭背景"]):
|
||||
return ConversationStage.CHILDHOOD
|
||||
elif any(word in message_lower for word in ["上学", "学校", "老师", "同学", "教育"]):
|
||||
return ConversationStage.EDUCATION
|
||||
elif any(word in message_lower for word in ["工作", "职业", "事业", "公司", "同事"]):
|
||||
return ConversationStage.CAREER
|
||||
elif any(word in message_lower for word in ["伴侣", "孩子", "家庭", "家人", "结婚"]):
|
||||
return ConversationStage.FAMILY
|
||||
elif any(word in message_lower for word in ["信念", "价值观", "座右铭", "坚持", "原则"]):
|
||||
return ConversationStage.BELIEFS
|
||||
elif any(word in message_lower for word in ["总结", "回顾", "感激", "希望", "未来"]):
|
||||
return ConversationStage.SUMMARY
|
||||
else:
|
||||
# 默认返回当前阶段或童年阶段
|
||||
return ConversationStage.CHILDHOOD
|
||||
|
||||
def clear_memory(self, conversation_id: str):
|
||||
"""清除对话记忆"""
|
||||
if conversation_id in self.memories:
|
||||
del self.memories[conversation_id]
|
||||
|
||||
193
api/agents/memory_agent.py
Normal file
193
api/agents/memory_agent.py
Normal file
@@ -0,0 +1,193 @@
|
||||
"""
|
||||
回忆录整理 Agent:基于传记结构,将口语改写为书面语,归类到章节
|
||||
"""
|
||||
import os
|
||||
import json
|
||||
from typing import List, Dict, Optional
|
||||
from langchain_openai import ChatOpenAI
|
||||
from langchain.prompts import PromptTemplate
|
||||
|
||||
from .prompts import (
|
||||
get_memory_prompt,
|
||||
get_chapter_classification_prompt,
|
||||
get_text_rewrite_prompt,
|
||||
CHAPTER_CATEGORIES,
|
||||
CHAPTER_ORDER
|
||||
)
|
||||
|
||||
|
||||
class MemoryAgent:
|
||||
"""回忆录整理 Agent"""
|
||||
|
||||
def __init__(self):
|
||||
# 初始化 LLM
|
||||
# 优先使用 LLM_API_KEY 和 LLM_BASE_URL,如果没有则使用 OPENAI_API_KEY
|
||||
api_key = os.getenv("LLM_API_KEY") or os.getenv("OPENAI_API_KEY", "")
|
||||
base_url = os.getenv("LLM_BASE_URL", "")
|
||||
model_name = os.getenv("OPENAI_MODEL", "gpt-4o")
|
||||
|
||||
if not api_key:
|
||||
self.llm = None
|
||||
return
|
||||
|
||||
# 如果提供了 base_url,需要处理路径(langchain 会自动添加 /v1/chat/completions)
|
||||
llm_kwargs = {
|
||||
"temperature": 0.3, # 较低温度,更稳定
|
||||
"model": model_name,
|
||||
"openai_api_key": api_key,
|
||||
}
|
||||
|
||||
if base_url:
|
||||
# 移除可能的 /v1/chat/completions 路径,langchain 会自动添加
|
||||
if base_url.endswith("/v1/chat/completions"):
|
||||
base_url = base_url[:-20] # 移除 "/v1/chat/completions"
|
||||
elif base_url.endswith("/v1"):
|
||||
base_url = base_url[:-3] # 移除 "/v1"
|
||||
# 确保 base_url 以 / 结尾(如果没有)
|
||||
if base_url and not base_url.endswith("/"):
|
||||
base_url += "/"
|
||||
llm_kwargs["openai_api_base"] = base_url
|
||||
|
||||
try:
|
||||
self.llm = ChatOpenAI(**llm_kwargs)
|
||||
except Exception:
|
||||
self.llm = None
|
||||
|
||||
def classify_chapter(self, segments_text: str) -> str:
|
||||
"""
|
||||
分类章节
|
||||
|
||||
Args:
|
||||
segments_text: 对话段落文本
|
||||
|
||||
Returns:
|
||||
章节类别(如:childhood)
|
||||
"""
|
||||
if not self.llm:
|
||||
# 如果没有配置 LLM,返回默认类别
|
||||
return "childhood"
|
||||
|
||||
prompt = get_chapter_classification_prompt(segments_text)
|
||||
|
||||
response = self.llm.invoke(prompt)
|
||||
|
||||
# 提取类别
|
||||
category = response.content.strip().lower()
|
||||
|
||||
# 验证类别是否有效
|
||||
if category in CHAPTER_CATEGORIES:
|
||||
return category
|
||||
|
||||
# 默认返回 childhood
|
||||
return "childhood"
|
||||
|
||||
def rewrite_to_literary(
|
||||
self,
|
||||
segments_text: str,
|
||||
chapter_category: str,
|
||||
existing_content: Optional[str] = None
|
||||
) -> Dict:
|
||||
"""
|
||||
将口语改写为书面语
|
||||
|
||||
Args:
|
||||
segments_text: 对话段落文本
|
||||
chapter_category: 章节类别
|
||||
existing_content: 已有章节内容(可选)
|
||||
|
||||
Returns:
|
||||
包含 title, content, summary, image_suggestions 的字典
|
||||
"""
|
||||
if not self.llm:
|
||||
# 如果没有配置 LLM,返回基本结构
|
||||
return {
|
||||
"title": CHAPTER_CATEGORIES.get(chapter_category, "章节"),
|
||||
"content": segments_text,
|
||||
"summary": "",
|
||||
"image_suggestions": []
|
||||
}
|
||||
|
||||
prompt = get_text_rewrite_prompt(segments_text, chapter_category, existing_content or "")
|
||||
|
||||
response = self.llm.invoke(prompt)
|
||||
|
||||
# 尝试解析 JSON
|
||||
try:
|
||||
# 提取 JSON 部分
|
||||
content = response.content.strip()
|
||||
# 移除可能的 markdown 代码块标记
|
||||
if content.startswith("```json"):
|
||||
content = content[7:]
|
||||
if content.startswith("```"):
|
||||
content = content[3:]
|
||||
if content.endswith("```"):
|
||||
content = content[:-3]
|
||||
content = content.strip()
|
||||
|
||||
result = json.loads(content)
|
||||
return result
|
||||
except json.JSONDecodeError:
|
||||
# 如果解析失败,返回基本结构
|
||||
return {
|
||||
"title": CHAPTER_CATEGORIES.get(chapter_category, "章节"),
|
||||
"content": response.content,
|
||||
"summary": "",
|
||||
"image_suggestions": []
|
||||
}
|
||||
|
||||
def process_segments(
|
||||
self,
|
||||
segments: List[Dict],
|
||||
existing_chapters: Optional[Dict[str, Dict]] = None
|
||||
) -> Dict[str, Dict]:
|
||||
"""
|
||||
处理对话段落,生成或更新章节
|
||||
|
||||
Args:
|
||||
segments: 对话段落列表,每个包含 transcript_text
|
||||
existing_chapters: 已有章节字典,key 为 category
|
||||
|
||||
Returns:
|
||||
更新后的章节字典
|
||||
"""
|
||||
if existing_chapters is None:
|
||||
existing_chapters = {}
|
||||
|
||||
# 按章节分类组织段落
|
||||
segments_by_category: Dict[str, List[str]] = {}
|
||||
|
||||
for segment in segments:
|
||||
text = segment.get("transcript_text", "")
|
||||
if not text:
|
||||
continue
|
||||
|
||||
# 分类
|
||||
category = self.classify_chapter(text)
|
||||
|
||||
if category not in segments_by_category:
|
||||
segments_by_category[category] = []
|
||||
|
||||
segments_by_category[category].append(text)
|
||||
|
||||
# 为每个类别生成或更新章节
|
||||
updated_chapters = existing_chapters.copy()
|
||||
|
||||
for category, texts in segments_by_category.items():
|
||||
combined_text = "\n\n".join(texts)
|
||||
existing_content = existing_chapters.get(category, {}).get("content", "")
|
||||
|
||||
# 改写为书面语
|
||||
result = self.rewrite_to_literary(combined_text, category, existing_content)
|
||||
|
||||
# 更新章节
|
||||
updated_chapters[category] = {
|
||||
"title": result.get("title", CHAPTER_CATEGORIES.get(category, "章节")),
|
||||
"content": result.get("content", ""),
|
||||
"summary": result.get("summary", ""),
|
||||
"image_suggestions": result.get("image_suggestions", []),
|
||||
"category": category,
|
||||
"order_index": CHAPTER_ORDER.index(category) if category in CHAPTER_ORDER else 999
|
||||
}
|
||||
|
||||
return updated_chapters
|
||||
|
||||
18
api/agents/prompts/__init__.py
Normal file
18
api/agents/prompts/__init__.py
Normal file
@@ -0,0 +1,18 @@
|
||||
"""
|
||||
提示词模块
|
||||
"""
|
||||
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
|
||||
|
||||
__all__ = [
|
||||
"ConversationStage",
|
||||
"get_conversation_prompt",
|
||||
"get_questions_for_stage",
|
||||
"INTERVIEW_QUESTIONS",
|
||||
"get_memory_prompt",
|
||||
"get_chapter_classification_prompt",
|
||||
"get_text_rewrite_prompt",
|
||||
"CHAPTER_CATEGORIES",
|
||||
"CHAPTER_ORDER",
|
||||
]
|
||||
|
||||
BIN
api/agents/prompts/__pycache__/__init__.cpython-312.pyc
Normal file
BIN
api/agents/prompts/__pycache__/__init__.cpython-312.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
api/agents/prompts/__pycache__/memory_prompts.cpython-312.pyc
Normal file
BIN
api/agents/prompts/__pycache__/memory_prompts.cpython-312.pyc
Normal file
Binary file not shown.
115
api/agents/prompts/conversation_prompts.py
Normal file
115
api/agents/prompts/conversation_prompts.py
Normal file
@@ -0,0 +1,115 @@
|
||||
"""
|
||||
对话 Agent 提示词模板和访谈问题库
|
||||
"""
|
||||
from enum import Enum
|
||||
from typing import List, Dict
|
||||
|
||||
|
||||
class ConversationStage(str, Enum):
|
||||
"""对话阶段枚举"""
|
||||
CHILDHOOD = "childhood" # 童年
|
||||
EDUCATION = "education" # 教育
|
||||
CAREER = "career" # 事业
|
||||
FAMILY = "family" # 家庭
|
||||
BELIEFS = "beliefs" # 信念
|
||||
SUMMARY = "summary" # 人生总结
|
||||
|
||||
|
||||
# 访谈问题库
|
||||
INTERVIEW_QUESTIONS: Dict[ConversationStage, List[str]] = {
|
||||
ConversationStage.CHILDHOOD: [
|
||||
"你是在哪里长大的?小时候周围的环境是什么样的,有哪些让你印象深刻的童年记忆?",
|
||||
"童年时期的你是个怎样的孩子?有没有做过什么淘气或有趣的事情,现在想起来还会让你发笑?",
|
||||
"能聊聊你小时候的家庭吗?比如父母是怎样的人,他们对你的成长有什么影响吗?",
|
||||
"小时候你有过什么梦想?那时候你最想长大后做什么?",
|
||||
],
|
||||
ConversationStage.EDUCATION: [
|
||||
"上学的时候你是个怎么样的学生?你喜欢学校生活吗?",
|
||||
"在求学过程中,有没有哪位老师或同学对你影响特别大?能说说他们的故事吗?",
|
||||
"学生时代你参加过什么课外活动或者比赛吗?有没有哪段经历让你特别难忘?",
|
||||
"那时候你对未来有什么打算吗?比如毕业后想从事什么职业,或者希望过怎样的生活?",
|
||||
],
|
||||
ConversationStage.CAREER: [
|
||||
"第一次走出校园开始工作时,你还记得当时的情景吗?当时你的心情怎么样,有发生什么难忘的事吗?",
|
||||
"你当初是怎么选择进入现在这个行业的?其中有什么契机或故事吗?",
|
||||
"在工作中有没有遇到过特别大的挑战或低谷?当时你是怎么挺过来的?",
|
||||
"职业生涯中有没有哪个成就或时刻让你特别自豪?能跟我分享一下那个故事吗?",
|
||||
"在事业的发展过程中,有哪些重要的转折点?比如跳槽、升职或者创业,这些经历对你意味着什么?",
|
||||
"回顾这一路,有哪些人对你的事业帮助最大或者影响最深?有没有特别想感谢的贵人或伙伴?",
|
||||
],
|
||||
ConversationStage.FAMILY: [
|
||||
"可以聊聊你和你伴侣的故事吗?你们是怎么认识的,又是什么让你决定与他/她携手一生?",
|
||||
"孩子在你的生活中意味着什么?做父母的过程中,有没有让你特别骄傲或者难忘的瞬间?",
|
||||
"在家庭生活中,有没有什么传统或者特别的习惯,让你感到温馨和快乐?",
|
||||
"平时你和家人喜欢一起做些什么?周末或假日你们通常会怎么度过?",
|
||||
"你觉得家庭在你的人生中扮演了一个怎样的角色?",
|
||||
"工作和家庭要怎么兼顾呢?你是如何平衡事业和家庭的?在两边兼顾的时候有没有遇到困难,后来又是怎么克服的?",
|
||||
],
|
||||
ConversationStage.BELIEFS: [
|
||||
"你人生中有没有一些一直坚守的信念或者座右铭?这些信念给了你怎样的力量或者影响?",
|
||||
"对你来说,哪些价值观是最重要的?这些价值观是受到哪些人或经历的影响而形成的呢?",
|
||||
"当你遇到困难和低谷的时候,是什么支撑着你坚持下去?",
|
||||
"你如何看待‘成功’和‘幸福’?对你来说它们分别意味着什么?",
|
||||
],
|
||||
ConversationStage.SUMMARY: [
|
||||
"回顾你走过的路,你觉得这一生中最重要的经验或教训是什么?",
|
||||
"在你的生活中,你最感激的人和事有哪些?有没有特别觉得自己很幸运的地方?",
|
||||
"如果能对年轻时候的自己说几句话,你会想告诉他/她什么?",
|
||||
"展望未来,你还有什么愿望或目标吗?有没有一直想尝试但还没来得及做的事情?",
|
||||
"最后,你希望家人和后代记住你是一个怎样的人?",
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
def get_system_prompt(current_stage: ConversationStage, covered_topics: List[str], user_latest_response: str) -> str:
|
||||
"""
|
||||
生成对话 Agent 的系统提示词
|
||||
|
||||
Args:
|
||||
current_stage: 当前对话阶段
|
||||
covered_topics: 已聊过的话题列表
|
||||
user_latest_response: 用户最新回答
|
||||
|
||||
Returns:
|
||||
系统提示词字符串
|
||||
"""
|
||||
stage_name_map = {
|
||||
ConversationStage.CHILDHOOD: "童年",
|
||||
ConversationStage.EDUCATION: "教育",
|
||||
ConversationStage.CAREER: "事业",
|
||||
ConversationStage.FAMILY: "家庭",
|
||||
ConversationStage.BELIEFS: "信念",
|
||||
ConversationStage.SUMMARY: "人生总结",
|
||||
}
|
||||
|
||||
covered_topics_str = "、".join(covered_topics) if covered_topics else "暂无"
|
||||
|
||||
prompt = f"""你是一位专业的人生故事访谈助手,擅长通过轻松自然的对话引导用户讲述他们的人生故事。
|
||||
|
||||
你的职责:
|
||||
1. 根据用户已讲述的内容,判断当前应处于哪个访谈阶段(童年/教育/事业/家庭/信念/人生总结)
|
||||
2. 在用户停顿或完成一个话题后,自然地提出下一个相关问题
|
||||
3. 使用温暖、鼓励的语气,让用户感到被倾听和理解
|
||||
4. 当用户讲述不够详细时,通过追问引导深入(如:"能多说一些关于...的细节吗?")
|
||||
5. 识别对话的自然结束时机,或引导进入下一个阶段
|
||||
|
||||
对话原则:
|
||||
- 一次只问一个问题,不要连续提问
|
||||
- 问题要自然、口语化,避免生硬
|
||||
- 根据用户的回答灵活调整,不要机械地按顺序提问
|
||||
- 当用户偏离话题时,温和地引导回来
|
||||
- 在用户讲述精彩故事时,给予积极反馈(如:"这个故事真有意思!")
|
||||
|
||||
当前对话阶段:{stage_name_map.get(current_stage, current_stage.value)}
|
||||
已聊话题:{covered_topics_str}
|
||||
用户最新回答:{user_latest_response}
|
||||
|
||||
请根据以上信息,生成一个自然、温暖的回应或下一个问题。"""
|
||||
|
||||
return prompt
|
||||
|
||||
|
||||
def get_questions_for_stage(stage: ConversationStage) -> List[str]:
|
||||
"""获取指定阶段的所有问题"""
|
||||
return INTERVIEW_QUESTIONS.get(stage, [])
|
||||
|
||||
108
api/agents/prompts/memory_prompts.py
Normal file
108
api/agents/prompts/memory_prompts.py
Normal file
@@ -0,0 +1,108 @@
|
||||
"""
|
||||
回忆录整理 Agent 提示词模板
|
||||
"""
|
||||
|
||||
# 章节分类映射
|
||||
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",
|
||||
]
|
||||
|
||||
|
||||
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": "章节标题",
|
||||
"content": "改写后的书面语内容",
|
||||
"summary": "章节摘要(50字以内)",
|
||||
"image_suggestions": ["建议插图位置1", "建议插图位置2"]
|
||||
}}
|
||||
|
||||
要求:
|
||||
1. 标题要简洁有力,能概括章节主题
|
||||
2. 内容要流畅自然,保持原意和情感
|
||||
3. 如果已有章节内容,请将新内容与已有内容自然融合
|
||||
4. 建议插图位置要具体(如:"描述老家门口那条路的段落")"""
|
||||
|
||||
Reference in New Issue
Block a user