refactor(proactive_thinker): 将提示词构建逻辑迁移至独立的prompt模块
将 `ProactiveThinkerExecutor` 中用于构建决策(decision)和计划(plan)的提示词字符串的逻辑,提取并重构到新的 `prompts.py` 模块中。 这一重构旨在: - **提升可维护性**:将复杂的提示词模板与核心业务逻辑分离,使代码结构更清晰。 - **简化代码**:`proactive_thinker_executor.py` 的代码量大幅减少,职责更加单一,专注于执行流程。 - **便于管理**:集中管理所有相关的提示词模板,方便未来进行统一的调整和优化。
This commit is contained in:
@@ -9,6 +9,7 @@ from src.chat.utils.prompt import Prompt
|
|||||||
from src.common.logger import get_logger
|
from src.common.logger import get_logger
|
||||||
from src.config.config import global_config, model_config
|
from src.config.config import global_config, model_config
|
||||||
from src.mood.mood_manager import mood_manager
|
from src.mood.mood_manager import mood_manager
|
||||||
|
from .prompts import DECISION_PROMPT, PLAN_PROMPT
|
||||||
from src.person_info.person_info import get_person_info_manager
|
from src.person_info.person_info import get_person_info_manager
|
||||||
from src.plugin_system.apis import (
|
from src.plugin_system.apis import (
|
||||||
chat_api,
|
chat_api,
|
||||||
@@ -80,7 +81,51 @@ class ProactiveThinkerExecutor:
|
|||||||
)
|
)
|
||||||
logger.info(f"决策结果为:回复。话题: {topic}")
|
logger.info(f"决策结果为:回复。话题: {topic}")
|
||||||
|
|
||||||
plan_prompt = self._build_plan_prompt(context, start_mode, topic, reason)
|
# 根据聊天类型构建特定上下文
|
||||||
|
if context["chat_type"] == "private":
|
||||||
|
user_info = context["user_info"]
|
||||||
|
relationship = context["relationship"]
|
||||||
|
target_user_or_group = f"你的朋友 '{user_info.user_nickname}'"
|
||||||
|
context_specific_block = f"""
|
||||||
|
1. **你的日程**:
|
||||||
|
{context["schedule_context"]}
|
||||||
|
2. **你和Ta的关系**:
|
||||||
|
- 详细印象: {relationship["impression"]}
|
||||||
|
- 好感度: {relationship["attitude"]}/100
|
||||||
|
3. **最近的聊天摘要**:
|
||||||
|
{context["recent_chat_history"]}
|
||||||
|
4. **你最近的相关动作**:
|
||||||
|
{context["action_history_context"]}
|
||||||
|
"""
|
||||||
|
else: # group
|
||||||
|
group_info = context["group_info"]
|
||||||
|
target_user_or_group = f"群聊 '{group_info['group_name']}'"
|
||||||
|
context_specific_block = f"""
|
||||||
|
1. **你的日程**:
|
||||||
|
{context["schedule_context"]}
|
||||||
|
2. **群聊信息**:
|
||||||
|
- 群名称: {group_info["group_name"]}
|
||||||
|
3. **最近的聊天摘要**:
|
||||||
|
{context["recent_chat_history"]}
|
||||||
|
4. **你最近的相关动作**:
|
||||||
|
{context["action_history_context"]}
|
||||||
|
"""
|
||||||
|
|
||||||
|
plan_prompt = PLAN_PROMPT.format(
|
||||||
|
bot_nickname=global_config.bot.nickname,
|
||||||
|
persona_core=context["persona"]["core"],
|
||||||
|
persona_side=context["persona"]["side"],
|
||||||
|
identity=context["persona"]["identity"],
|
||||||
|
current_time=context["current_time"],
|
||||||
|
target_user_or_group=target_user_or_group,
|
||||||
|
reason=reason,
|
||||||
|
topic=topic,
|
||||||
|
context_specific_block=context_specific_block,
|
||||||
|
mood_state=context["mood_state"],
|
||||||
|
)
|
||||||
|
|
||||||
|
if global_config.debug.show_prompt:
|
||||||
|
logger.info(f"主动思考回复器原始提示词:{plan_prompt}")
|
||||||
|
|
||||||
is_success, response, _, _ = await llm_api.generate_with_model(
|
is_success, response, _, _ = await llm_api.generate_with_model(
|
||||||
prompt=plan_prompt, model_config=model_config.model_task_config.replyer
|
prompt=plan_prompt, model_config=model_config.model_task_config.replyer
|
||||||
@@ -222,42 +267,19 @@ class ProactiveThinkerExecutor:
|
|||||||
logger.warning(f"Stream {stream_id} 既没有 group_info 也没有 user_info")
|
logger.warning(f"Stream {stream_id} 既没有 group_info 也没有 user_info")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def _build_decision_prompt(self, context: dict[str, Any], start_mode: str) -> str:
|
async def _make_decision(self, context: dict[str, Any], start_mode: str) -> dict[str, Any] | None:
|
||||||
"""
|
"""
|
||||||
根据收集到的上下文信息,构建用于决策的提示词。
|
调用 LLM 进行决策,判断是否应该主动发起对话,以及聊什么话题。
|
||||||
|
|
||||||
Args:
|
|
||||||
context: 包含所有上下文信息的字典。
|
|
||||||
start_mode: 启动模式 ('cold_start' 或 'wake_up')。
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
构建完成的决策提示词字符串。
|
|
||||||
"""
|
"""
|
||||||
chat_type = context["chat_type"]
|
if context["chat_type"] not in ["private", "group"]:
|
||||||
persona = context["persona"]
|
return {"should_reply": False, "reason": "未知的聊天类型"}
|
||||||
|
|
||||||
# 构建通用头部
|
# 根据聊天类型构建特定上下文
|
||||||
prompt = f"""
|
if context["chat_type"] == "private":
|
||||||
# 角色
|
|
||||||
你的名字是{global_config.bot.nickname},你的人设如下:
|
|
||||||
- 核心人设: {persona["core"]}
|
|
||||||
- 侧面人设: {persona["side"]}
|
|
||||||
- 身份: {persona["identity"]}
|
|
||||||
|
|
||||||
你的当前情绪状态是: {context["mood_state"]}
|
|
||||||
|
|
||||||
# 你最近的相关决策历史 (供参考)
|
|
||||||
{context["action_history_context"]}
|
|
||||||
"""
|
|
||||||
# 根据聊天类型构建任务和情境
|
|
||||||
if chat_type == "private":
|
|
||||||
user_info = context["user_info"]
|
user_info = context["user_info"]
|
||||||
relationship = context["relationship"]
|
relationship = context["relationship"]
|
||||||
prompt += f"""
|
target_user_or_group = f"用户 '{user_info.user_nickname}'"
|
||||||
# 任务
|
context_specific_block = f"""
|
||||||
现在是 {context["current_time"]},你需要根据当前的情境,决定是否要主动向用户 '{user_info.user_nickname}' 发起对话。
|
|
||||||
|
|
||||||
# 情境分析
|
|
||||||
1. **启动模式**: {start_mode} ({"初次见面/很久未见" if start_mode == "cold_start" else "日常唤醒"})
|
1. **启动模式**: {start_mode} ({"初次见面/很久未见" if start_mode == "cold_start" else "日常唤醒"})
|
||||||
2. **你的日程**:
|
2. **你的日程**:
|
||||||
{context["schedule_context"]}
|
{context["schedule_context"]}
|
||||||
@@ -270,13 +292,10 @@ class ProactiveThinkerExecutor:
|
|||||||
5. **最近的聊天摘要**:
|
5. **最近的聊天摘要**:
|
||||||
{context["recent_chat_history"]}
|
{context["recent_chat_history"]}
|
||||||
"""
|
"""
|
||||||
elif chat_type == "group":
|
else: # group
|
||||||
group_info = context["group_info"]
|
group_info = context["group_info"]
|
||||||
prompt += f"""
|
target_user_or_group = f"群聊 '{group_info['group_name']}'"
|
||||||
# 任务
|
context_specific_block = f"""
|
||||||
现在是 {context["current_time"]},你需要根据当前的情境,决定是否要主动向群聊 '{group_info["group_name"]}' 发起对话。
|
|
||||||
|
|
||||||
# 情境分析
|
|
||||||
1. **启动模式**: {start_mode} ({"首次加入/很久未发言" if start_mode == "cold_start" else "日常唤醒"})
|
1. **启动模式**: {start_mode} ({"首次加入/很久未发言" if start_mode == "cold_start" else "日常唤醒"})
|
||||||
2. **你的日程**:
|
2. **你的日程**:
|
||||||
{context["schedule_context"]}
|
{context["schedule_context"]}
|
||||||
@@ -285,87 +304,17 @@ class ProactiveThinkerExecutor:
|
|||||||
4. **最近的聊天摘要**:
|
4. **最近的聊天摘要**:
|
||||||
{context["recent_chat_history"]}
|
{context["recent_chat_history"]}
|
||||||
"""
|
"""
|
||||||
# 构建通用尾部
|
prompt = DECISION_PROMPT.format(
|
||||||
prompt += """
|
bot_nickname=global_config.bot.nickname,
|
||||||
# 决策目标
|
persona_core=context["persona"]["core"],
|
||||||
你的最终目标是根据你的角色和当前情境,做出一个最符合人类社交直觉的决策,以求:
|
persona_side=context["persona"]["side"],
|
||||||
- **(私聊)深化关系**: 通过展现你的关心、记忆和个性来拉近与对方的距离。
|
identity=context["persona"]["identity"],
|
||||||
- **(群聊)活跃气氛**: 提出能引起大家兴趣的话题,促进群聊的互动。
|
mood_state=context["mood_state"],
|
||||||
- **提供价值**: 你的出现应该是有意义的,无论是情感上的温暖,还是信息上的帮助。
|
action_history_context=context["action_history_context"],
|
||||||
- **保持自然**: 避免任何看起来像机器人或骚扰的行为。
|
current_time=context["current_time"],
|
||||||
|
target_user_or_group=target_user_or_group,
|
||||||
# 决策指令
|
context_specific_block=context_specific_block,
|
||||||
请综合以上所有信息,以稳定、真实、拟人的方式做出决策。你的决策需要以JSON格式输出,包含以下字段:
|
)
|
||||||
- `should_reply`: bool, 是否应该发起对话。
|
|
||||||
- `topic`: str, 如果 `should_reply` 为 true,你打算聊什么话题?
|
|
||||||
- `reason`: str, 做出此决策的简要理由,需体现你对上述目标的考量。
|
|
||||||
|
|
||||||
# 决策流程与核心原则
|
|
||||||
1. **检查对话状态**:
|
|
||||||
- **最后发言者**: 查看【最近的聊天摘要】。如果最后一条消息是你发的,且对方尚未回复,**通常应选择不回复**。这是最重要的原则,以避免打扰。
|
|
||||||
- **例外**: 只有在等待时间足够长(例如超过数小时),或者你有非常重要且有时效性的新话题(例如,“你昨晚说的那个电影我刚看了!”)时,才考虑再次发言。
|
|
||||||
- **无人发言**: 如果最近的聊天记录里只有你一个人在说话,**绝对不要回复**,以防刷屏。
|
|
||||||
|
|
||||||
2. **寻找话题切入点 (如果可以回复)**:
|
|
||||||
- **强关联优先**: 优先从【情境分析】中寻找最自然、最相关的话题。顺序建议:`最近的聊天摘要` > `你和Ta的关系` > `你的日程`。一个好的话题往往是对最近对话的延续。
|
|
||||||
- **展现个性**: 结合你的【人设】和【情绪】,思考你会如何看待这些情境信息,并从中找到话题。例如,如果你是一个活泼的人,看到对方日程很满,可以说:“看你今天日程满满,真是活力四射的一天呀!”
|
|
||||||
- **备选方案**: 如果实在没有强关联的话题,可以发起一个简单的日常问候,如“在吗?”或“下午好”。
|
|
||||||
|
|
||||||
3. **最终决策**:
|
|
||||||
- **权衡频率**: 查看【你最近的相关决策历史】。如果你在短时间内已经主动发起过多次对话,即使现在有话题,也应倾向于**不回复**,保持一定的社交距离。
|
|
||||||
- **质量胜于数量**: 宁可错过一次普通的互动机会,也不要进行一次尴尬或生硬的对话。
|
|
||||||
|
|
||||||
|
|
||||||
---
|
|
||||||
示例1 (基于上下文):
|
|
||||||
{{
|
|
||||||
"should_reply": true,
|
|
||||||
"topic": "关心一下Ta昨天提到的那个项目进展如何了",
|
|
||||||
"reason": "用户昨天在聊天中提到了一个重要的项目,现在主动关心一下进展,会显得很体贴,也能自然地开启对话。"
|
|
||||||
}}
|
|
||||||
|
|
||||||
示例2 (简单问候):
|
|
||||||
{{
|
|
||||||
"should_reply": true,
|
|
||||||
"topic": "打个招呼,问问Ta现在在忙些什么",
|
|
||||||
"reason": "最近没有聊天记录,日程也很常规,没有特别的切入点。一个简单的日常问候是最安全和自然的方式来重新连接。"
|
|
||||||
}}
|
|
||||||
|
|
||||||
示例3 (不应回复 - 过于频繁):
|
|
||||||
{{
|
|
||||||
"should_reply": false,
|
|
||||||
"topic": null,
|
|
||||||
"reason": "虽然群里很活跃,但现在是深夜,而且最近的聊天话题我也不熟悉,没有合适的理由去打扰大家。"
|
|
||||||
}}
|
|
||||||
|
|
||||||
示例4 (不应回复 - 等待回应):
|
|
||||||
{{
|
|
||||||
"should_reply": false,
|
|
||||||
"topic": null,
|
|
||||||
"reason": "我注意到上一条消息是我几分钟前主动发送的,对方可能正在忙。为了表现出耐心和体贴,我现在最好保持安静,等待对方的回应。"
|
|
||||||
}}
|
|
||||||
---
|
|
||||||
|
|
||||||
请输出你的决策:
|
|
||||||
"""
|
|
||||||
return prompt
|
|
||||||
|
|
||||||
async def _make_decision(self, context: dict[str, Any], start_mode: str) -> dict[str, Any] | None:
|
|
||||||
"""
|
|
||||||
调用 LLM 进行决策,判断是否应该主动发起对话,以及聊什么话题。
|
|
||||||
|
|
||||||
Args:
|
|
||||||
context: 包含所有上下文信息的字典。
|
|
||||||
start_mode: 启动模式。
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
一个包含决策结果的字典 (例如: {"should_reply": bool, "topic": str, "reason": str}),
|
|
||||||
如果决策过程失败则返回 None 或包含错误信息的字典。
|
|
||||||
"""
|
|
||||||
if context["chat_type"] not in ["private", "group"]:
|
|
||||||
return {"should_reply": False, "reason": "未知的聊天类型"}
|
|
||||||
|
|
||||||
prompt = self._build_decision_prompt(context, start_mode)
|
|
||||||
|
|
||||||
if global_config.debug.show_prompt:
|
if global_config.debug.show_prompt:
|
||||||
logger.info(f"主动思考决策器原始提示词:{prompt}")
|
logger.info(f"主动思考决策器原始提示词:{prompt}")
|
||||||
@@ -385,160 +334,3 @@ class ProactiveThinkerExecutor:
|
|||||||
except orjson.JSONDecodeError:
|
except orjson.JSONDecodeError:
|
||||||
logger.error(f"决策LLM返回的JSON格式无效: {response}")
|
logger.error(f"决策LLM返回的JSON格式无效: {response}")
|
||||||
return {"should_reply": False, "reason": "决策模型返回格式错误"}
|
return {"should_reply": False, "reason": "决策模型返回格式错误"}
|
||||||
|
|
||||||
def _build_private_plan_prompt(self, context: dict[str, Any], start_mode: str, topic: str, reason: str) -> str:
|
|
||||||
"""
|
|
||||||
为私聊场景构建生成对话内容的规划提示词。
|
|
||||||
|
|
||||||
Args:
|
|
||||||
context: 上下文信息字典。
|
|
||||||
start_mode: 启动模式。
|
|
||||||
topic: 决策模块决定的话题。
|
|
||||||
reason: 决策模块给出的理由。
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
构建完成的私聊规划提示词字符串。
|
|
||||||
"""
|
|
||||||
user_info = context["user_info"]
|
|
||||||
relationship = context["relationship"]
|
|
||||||
if start_mode == "cold_start":
|
|
||||||
return f"""
|
|
||||||
# 任务
|
|
||||||
你需要主动向一个新朋友 '{user_info.user_nickname}' 发起对话。这是你们的第一次交流,或者很久没聊了。
|
|
||||||
|
|
||||||
# 决策上下文
|
|
||||||
- **决策理由**: {reason}
|
|
||||||
|
|
||||||
# 情境分析
|
|
||||||
1. **你的日程**:
|
|
||||||
{context["schedule_context"]}
|
|
||||||
2. **你和Ta的关系**:
|
|
||||||
- 简短印象: {relationship["short_impression"]}
|
|
||||||
- 详细印象: {relationship["impression"]}
|
|
||||||
- 好感度: {relationship["attitude"]}/100
|
|
||||||
3. **和Ta在别处的讨论摘要**:
|
|
||||||
{context["cross_context_block"]}
|
|
||||||
4. **最近的聊天摘要**:
|
|
||||||
{context["recent_chat_history"]}
|
|
||||||
5. **你最近的相关动作**:
|
|
||||||
{context["action_history_context"]}
|
|
||||||
|
|
||||||
# 对话指引
|
|
||||||
- 你的目标是“破冰”,让对话自然地开始。
|
|
||||||
- 你应该围绕这个话题展开: {topic}
|
|
||||||
- 你的语气应该符合你的人设和你当前的心情({context["mood_state"]}),友好且真诚。
|
|
||||||
"""
|
|
||||||
else: # wake_up
|
|
||||||
return f"""
|
|
||||||
# 任务
|
|
||||||
现在是 {context["current_time"]},你需要主动向你的朋友 '{user_info.user_nickname}' 发起对话。
|
|
||||||
|
|
||||||
# 决策上下文
|
|
||||||
- **决策理由**: {reason}
|
|
||||||
|
|
||||||
# 情境分析
|
|
||||||
1. **你的日程**:
|
|
||||||
{context["schedule_context"]}
|
|
||||||
2. **你和Ta的关系**:
|
|
||||||
- 详细印象: {relationship["impression"]}
|
|
||||||
- 好感度: {relationship["attitude"]}/100
|
|
||||||
3. **最近的聊天摘要**:
|
|
||||||
{context["recent_chat_history"]}
|
|
||||||
4. **你最近的相关动作**:
|
|
||||||
{context["action_history_context"]}
|
|
||||||
|
|
||||||
# 对话指引
|
|
||||||
- 你决定和Ta聊聊关于“{topic}”的话题。
|
|
||||||
- **对话风格**:
|
|
||||||
- **自然开场**: 你可以根据话题和情境,选择最自然的开场方式。可以直接切入话题(如果话题关联性很强),也可以先用一句简单的问候(如“在吗?”、“下午好”)作为过渡。**不要总是使用同一种开场白**。
|
|
||||||
- **融合情境**: 将【情境分析】中的信息(如你的心情、日程、对Ta的印象)巧妙地融入到对话中,让你的话语听起来更真实、更有依据。
|
|
||||||
- **符合人设**: 你的语气、用词、甚至表情符号的使用,都应该完全符合你的【角色】设定和当前【情绪】({context["mood_state"]})以及你对Ta的好感度。
|
|
||||||
- 请结合以上所有情境信息,自然地开启对话。
|
|
||||||
"""
|
|
||||||
|
|
||||||
def _build_group_plan_prompt(self, context: dict[str, Any], topic: str, reason: str) -> str:
|
|
||||||
"""
|
|
||||||
为群聊场景构建生成对话内容的规划提示词。
|
|
||||||
|
|
||||||
Args:
|
|
||||||
context: 上下文信息字典。
|
|
||||||
topic: 决策模块决定的话题。
|
|
||||||
reason: 决策模块给出的理由。
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
构建完成的群聊规划提示词字符串。
|
|
||||||
"""
|
|
||||||
group_info = context["group_info"]
|
|
||||||
return f"""
|
|
||||||
# 任务
|
|
||||||
现在是 {context["current_time"]},你需要主动向群聊 '{group_info["group_name"]}' 发起对话。
|
|
||||||
|
|
||||||
# 决策上下文
|
|
||||||
- **决策理由**: {reason}
|
|
||||||
|
|
||||||
# 情境分析
|
|
||||||
1. **你的日程**:
|
|
||||||
你当前的心情({context["mood_state"]}
|
|
||||||
{context["schedule_context"]}
|
|
||||||
2. **群聊信息**:
|
|
||||||
- 群名称: {group_info["group_name"]}
|
|
||||||
3. **最近的聊天摘要**:
|
|
||||||
{context["recent_chat_history"]}
|
|
||||||
4. **你最近的相关动作**:
|
|
||||||
{context["action_history_context"]}
|
|
||||||
|
|
||||||
# 对话指引
|
|
||||||
- 你决定和大家聊聊关于“{topic}”的话题。
|
|
||||||
- **对话风格**:
|
|
||||||
- **自然开场**: 你可以根据话题和情境,选择最自然的开场方式。可以直接切入话题(如果话题关联性很强),也可以先用一句简单的问候(如“哈喽,大家好呀~”、“下午好!”)作为过渡。**不要总是使用同一种开场白**。
|
|
||||||
- **融合情境**: 将【情境分析】中的信息(如你的心情、日程)巧妙地融入到对话中,让你的话语听起来更真实、更有依据。
|
|
||||||
- **符合人设**: 你的语气、用词、甚至表情符号的使用,都应该完全符合你的【角色】设定和当前【情绪】({context["mood_state"]})。语气应该更活泼、更具包容性,以吸引更多群成员参与讨论。
|
|
||||||
- 请结合以上所有情境信息,自然地开启对话。
|
|
||||||
- 可以分享你的看法、提出相关问题,或者开个合适的玩笑。
|
|
||||||
"""
|
|
||||||
|
|
||||||
def _build_plan_prompt(self, context: dict[str, Any], start_mode: str, topic: str, reason: str) -> str:
|
|
||||||
"""
|
|
||||||
根据聊天类型、启动模式和决策结果,构建最终生成对话内容的规划提示词。
|
|
||||||
|
|
||||||
Args:
|
|
||||||
context: 上下文信息字典。
|
|
||||||
start_mode: 启动模式。
|
|
||||||
topic: 决策模块决定的话题。
|
|
||||||
reason: 决策模块给出的理由。
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
最终的规划提示词字符串。
|
|
||||||
"""
|
|
||||||
persona = context["persona"]
|
|
||||||
chat_type = context["chat_type"]
|
|
||||||
|
|
||||||
# 1. 构建通用角色头部
|
|
||||||
prompt = f"""
|
|
||||||
# 角色
|
|
||||||
你的名字是{global_config.bot.nickname},你的人设如下:
|
|
||||||
- 核心人设: {persona["core"]}
|
|
||||||
- 侧面人设: {persona["side"]}
|
|
||||||
- 身份: {persona["identity"]}
|
|
||||||
"""
|
|
||||||
# 2. 根据聊天类型构建特定内容
|
|
||||||
if chat_type == "private":
|
|
||||||
prompt += self._build_private_plan_prompt(context, start_mode, topic, reason)
|
|
||||||
elif chat_type == "group":
|
|
||||||
prompt += self._build_group_plan_prompt(context, topic, reason)
|
|
||||||
|
|
||||||
# 3. 添加通用结尾
|
|
||||||
final_instructions = """
|
|
||||||
|
|
||||||
# 输出要求
|
|
||||||
- **简洁**: 不要输出任何多余内容(如前缀、后缀、冒号、引号、at/@等)。
|
|
||||||
- **原创**: 不要重复之前的内容,即使意思相近也不行。
|
|
||||||
- **直接**: 只输出最终的回复文本本身。
|
|
||||||
- **风格**: 回复需简短、完整且口语化。
|
|
||||||
|
|
||||||
现在,你说:"""
|
|
||||||
prompt += final_instructions
|
|
||||||
|
|
||||||
if global_config.debug.show_prompt:
|
|
||||||
logger.info(f"主动思考回复器原始提示词:{prompt}")
|
|
||||||
return prompt
|
|
||||||
|
|||||||
97
src/plugins/built_in/proactive_thinker/prompts.py
Normal file
97
src/plugins/built_in/proactive_thinker/prompts.py
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
from src.chat.utils.prompt import Prompt
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# 决策阶段 (Decision Phase)
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
DECISION_PROMPT = Prompt(
|
||||||
|
name="proactive_thinker_decision",
|
||||||
|
template="""
|
||||||
|
# 角色
|
||||||
|
你的名字是{bot_nickname},你的人设如下:
|
||||||
|
- 核心人设: {persona_core}
|
||||||
|
- 侧面人设: {persona_side}
|
||||||
|
- 身份: {identity}
|
||||||
|
|
||||||
|
你的当前情绪状态是: {mood_state}
|
||||||
|
|
||||||
|
# 你最近的相关决策历史 (供参考)
|
||||||
|
{action_history_context}
|
||||||
|
|
||||||
|
# 任务
|
||||||
|
现在是 {current_time},你需要根据当前的情境,决定是否要主动向{target_user_or_group}发起对话。
|
||||||
|
|
||||||
|
# 情境分析
|
||||||
|
{context_specific_block}
|
||||||
|
|
||||||
|
# 决策目标
|
||||||
|
你的最终目标是根据你的角色和当前情境,做出一个最符合人类社交直觉的决策,以求:
|
||||||
|
- **(私聊)深化关系**: 通过展现你的关心、记忆和个性来拉近与对方的距离。
|
||||||
|
- **(群聊)活跃气氛**: 提出能引起大家兴趣的话题,促进群聊的互动。
|
||||||
|
- **提供价值**: 你的出现应该是有意义的,无论是情感上的温暖,还是信息上的帮助。
|
||||||
|
- **保持自然**: 避免任何看起来像机器人或骚扰的行为。
|
||||||
|
|
||||||
|
# 决策指令
|
||||||
|
请综合以上所有信息,以稳定、真实、拟人的方式做出决策。你的决策需要以JSON格式输出,包含以下字段:
|
||||||
|
- `should_reply`: bool, 是否应该发起对话。
|
||||||
|
- `topic`: str, 如果 `should_reply` 为 true,你打算聊什么话题?
|
||||||
|
- `reason`: str, 做出此决策的简要理由,需体现你对上述目标的考量。
|
||||||
|
|
||||||
|
# 决策流程与核心原则
|
||||||
|
1. **检查对话状态**:
|
||||||
|
- **最后发言者**: 查看【最近的聊天摘要】。如果最后一条消息是你发的,且对方尚未回复,**通常应选择不回复**。这是最重要的原则,以避免打扰。
|
||||||
|
- **例外**: 只有在等待时间足够长(例如超过数小时),或者你有非常重要且有时效性的新话题时,才考虑再次发言。
|
||||||
|
- **无人发言**: 如果最近的聊天记录里只有你一个人在说话,**绝对不要回复**,以防刷屏。
|
||||||
|
|
||||||
|
2. **寻找话题切入点 (如果可以回复)**:
|
||||||
|
- **强关联优先**: 优先从【情境分析】中寻找最自然、最相关的话题。顺序建议:`最近的聊天摘要` > `你和Ta的关系` > `你的日程`。
|
||||||
|
- **展现个性**: 结合你的【人设】和【情绪】,思考你会如何看待这些情境信息,并从中找到话题。
|
||||||
|
- **备选方案**: 如果实在没有强关联的话题,可以发起一个简单的日常问候。
|
||||||
|
|
||||||
|
3. **最终决策**:
|
||||||
|
- **权衡频率**: 查看【你最近的相关决策历史】。如果你在短时间内已经主动发起过多次对话,也应倾向于**不回复**,保持一定的社交距离。
|
||||||
|
- **质量胜于数量**: 宁可错过一次普通的互动机会,也不要进行一次尴尬或生硬的对话。
|
||||||
|
|
||||||
|
---
|
||||||
|
请输出你的决策:
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# 回复规划阶段 (Plan Phase)
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
PLAN_PROMPT = Prompt(
|
||||||
|
name="proactive_thinker_plan",
|
||||||
|
template="""
|
||||||
|
# 角色
|
||||||
|
你的名字是{bot_nickname},你的人设如下:
|
||||||
|
- 核心人设: {persona_core}
|
||||||
|
- 侧面人设: {persona_side}
|
||||||
|
- 身份: {identity}
|
||||||
|
|
||||||
|
# 任务
|
||||||
|
现在是 {current_time},你需要主动向{target_user_or_group}发起对话。
|
||||||
|
|
||||||
|
# 决策上下文
|
||||||
|
- **决策理由**: {reason}
|
||||||
|
|
||||||
|
# 情境分析
|
||||||
|
{context_specific_block}
|
||||||
|
|
||||||
|
# 对话指引
|
||||||
|
- 你决定和Ta聊聊关于“{topic}”的话题。
|
||||||
|
- **对话风格**:
|
||||||
|
- **自然开场**: 你可以根据话题和情境,选择最自然的开场方式。可以直接切入话题(如果话题关联性很强),也可以先用一句简单的问候作为过渡。**不要总是使用同一种开场白**。
|
||||||
|
- **融合情境**: 将【情境分析】中的信息巧妙地融入到对话中,让你的话语听起来更真实、更有依据。
|
||||||
|
- **符合人设**: 你的语气、用词、甚至表情符号的使用,都应该完全符合你的【角色】设定和当前【情绪】({mood_state})。
|
||||||
|
|
||||||
|
# 输出要求
|
||||||
|
- **简洁**: 不要输出任何多余内容(如前缀、后缀、冒号、引号、at/@等)。
|
||||||
|
- **原创**: 不要重复之前的内容,即使意思相近也不行。
|
||||||
|
- **直接**: 只输出最终的回复文本本身。
|
||||||
|
- **风格**: 回复需简短、完整且口语化。
|
||||||
|
|
||||||
|
现在,你说:
|
||||||
|
"""
|
||||||
|
)
|
||||||
Reference in New Issue
Block a user