From 748ac8482a34f0251aaf3102fbbf55a208d37b3d Mon Sep 17 00:00:00 2001 From: SengokuCola <1026294844@qq.com> Date: Thu, 24 Apr 2025 16:35:05 +0800 Subject: [PATCH] =?UTF-8?q?better=EF=BC=9A=E4=BC=98=E5=8C=96Prompt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/heart_flow/mai_state_manager.py | 6 +-- src/heart_flow/mind.py | 3 -- src/heart_flow/sub_mind.py | 17 +++--- src/plugins/heartFC_chat/heartFC_chat.py | 53 +++++++++---------- .../heartFC_chat/heartflow_prompt_builder.py | 27 ++++++++-- src/plugins/heartFC_chat/normal_chat.py | 14 +++++ 6 files changed, 75 insertions(+), 45 deletions(-) diff --git a/src/heart_flow/mai_state_manager.py b/src/heart_flow/mai_state_manager.py index 7df55d6f0..6f645f670 100644 --- a/src/heart_flow/mai_state_manager.py +++ b/src/heart_flow/mai_state_manager.py @@ -39,7 +39,7 @@ class MaiState(enum.Enum): if self == MaiState.OFFLINE: return 0 elif self == MaiState.PEEKING: - return 1 + return 2 elif self == MaiState.NORMAL_CHAT: return 3 elif self == MaiState.FOCUSED_CHAT: @@ -53,11 +53,11 @@ class MaiState(enum.Enum): if self == MaiState.OFFLINE: return 0 elif self == MaiState.PEEKING: - return 0 + return 1 elif self == MaiState.NORMAL_CHAT: return 1 elif self == MaiState.FOCUSED_CHAT: - return 2 + return 3 class MaiStateInfo: diff --git a/src/heart_flow/mind.py b/src/heart_flow/mind.py index 6ca03c212..e806d18ae 100644 --- a/src/heart_flow/mind.py +++ b/src/heart_flow/mind.py @@ -22,9 +22,6 @@ class Mind: self.subheartflow_manager = subheartflow_manager self.llm_model = llm_model self.individuality = Individuality.get_instance() - # Main mind state is still managed by Heartflow for now - # self.current_mind = "你什么也没想" - # self.past_mind = [] async def do_a_thinking(self, current_main_mind: str, mai_state_info: "MaiStateInfo", schedule_info: str): """ diff --git a/src/heart_flow/sub_mind.py b/src/heart_flow/sub_mind.py index 4bde47275..c7baa91ed 100644 --- a/src/heart_flow/sub_mind.py +++ b/src/heart_flow/sub_mind.py @@ -30,12 +30,13 @@ def init_prompt(): prompt += "-----------------------------------\n" prompt += "现在是{time_now},你正在上网,和qq群里的网友们聊天,群里正在聊的话题是:\n{chat_observe_info}\n" prompt += "\n你现在{mood_info}\n" - # prompt += "你注意到{sender_name}刚刚说:{message_txt}\n" - prompt += "现在请你根据刚刚的想法继续思考,思考时可以想想如何对群聊内容进行回复,要不要对群里的话题进行回复,关注新话题,可以适当转换话题,大家正在说的话才是聊天的主题。\n" - prompt += "回复的要求是:平淡一些,简短一些,说中文,如果你要回复,最好只回复一个人的一个话题\n" - prompt += "请注意不要输出多余内容(包括前后缀,冒号和引号,括号, 表情,等),不要带有括号和动作描写。不要回复自己的发言,尽量不要说你说过的话。\n" - prompt += "现在请你先{hf_do_next},不要分点输出,生成内心想法,文字不要浮夸" - prompt += "在输出完想法后,请你思考应该使用什么工具。如果你需要做某件事,来对消息和你的回复进行处理,请使用工具。\n" + prompt += "现在请你生成你的内心想法,要求思考群里正在进行的话题,之前大家聊过的话题,群里成员的关系。" + prompt += "请你思考,要不要对群里的话题进行回复,以及如何对群聊内容进行回复\n" + prompt += "回复的要求是:平淡一些,简短一些,如果你要回复,最好只回复一个人的一个话题\n" + prompt += "请注意不要输出多余内容(包括前后缀,冒号和引号,括号, 表情,等),不要回复自己的发言\n" + prompt += "现在请你先输出想法,{hf_do_next},不要分点输出,文字不要浮夸" + prompt += "在输出完想法后,请你思考应该使用什么工具。工具可以帮你取得一些你不知道的信息,或者进行一些操作。" + prompt += "如果你需要做某件事,来对消息和你的回复进行处理,请使用工具。\n" Prompt(prompt, "sub_heartflow_prompt_before") @@ -116,9 +117,9 @@ class SubMind: # 思考指导选项和权重 hf_options = [ - ("继续生成你在这个聊天中的想法,在原来想法的基础上继续思考", 0.7), + ("继续生成你在这个聊天中的想法,在原来想法的基础上继续思考,但是不要纠结于同一个话题", 0.6), ("生成你在这个聊天中的想法,在原来的想法上尝试新的话题", 0.1), - ("生成你在这个聊天中的想法,不要太深入", 0.1), + ("生成你在这个聊天中的想法,不要太深入", 0.2), ("继续生成你在这个聊天中的想法,进行深入思考", 0.1), ] diff --git a/src/plugins/heartFC_chat/heartFC_chat.py b/src/plugins/heartFC_chat/heartFC_chat.py index 33fe01095..8735ff7df 100644 --- a/src/plugins/heartFC_chat/heartFC_chat.py +++ b/src/plugins/heartFC_chat/heartFC_chat.py @@ -19,6 +19,7 @@ from src.plugins.chat.emoji_manager import emoji_manager from src.plugins.utils.json_utils import process_llm_tool_response # 导入新的JSON工具 from src.heart_flow.sub_mind import SubMind from src.heart_flow.observation import Observation +from src.plugins.heartFC_chat.heartflow_prompt_builder import global_prompt_manager # --- End import --- @@ -594,39 +595,36 @@ class HeartFChatting: self, observed_messages_str: str, current_mind: Optional[str], structured_info: Dict[str, Any] ) -> str: """构建 Planner LLM 的提示词""" - - prompt = f"你的名字是 {global_config.BOT_NICKNAME}。是一个女大二学生,正在QQ聊天,正在决定是否以及如何回应当前的聊天。\n" - + + # 准备结构化信息块 + structured_info_block = "" if structured_info: - prompt += f"以下是一些额外的信息:\n{structured_info}\n" - + structured_info_block = f"以下是一些额外的信息:\n{structured_info}\n" + + # 准备聊天内容块 + chat_content_block = "" if observed_messages_str: - prompt += "观察到的最新聊天内容如下 (最近的消息在最后):\n---\n" - prompt += observed_messages_str - prompt += "\n---" + chat_content_block = "观察到的最新聊天内容如下 (最近的消息在最后):\n---\n" + chat_content_block += observed_messages_str + chat_content_block += "\n---" else: - prompt += "当前没有观察到新的聊天内容。\n" - - prompt += "\n看了以上内容,你产生的内心想法是:" + chat_content_block = "当前没有观察到新的聊天内容。\n" + + # 准备当前思维块 + current_mind_block = "" if current_mind: - prompt += f"\n---\n{current_mind}\n---\n\n" + current_mind_block = f"\n---\n{current_mind}\n---\n\n" else: - prompt += " [没有特别的想法] \n\n" - - prompt += ( - "请结合你的内心想法和观察到的聊天内容,分析情况并使用 'decide_reply_action' 工具来决定你的最终行动。\n" - "决策依据:\n" - "1. 如果聊天内容无聊、与你无关、或者你的内心想法认为不适合回复(例如在讨论你不懂或不感兴趣的话题),选择 'no_reply'。\n" - "2. 如果聊天内容值得回应,且适合用文字表达(参考你的内心想法),选择 'text_reply'。如果你有情绪想表达,想在文字后追加一个表达情绪的表情,请同时提供 'emoji_query' (例如:'开心的'、'惊讶的')。\n" - "3. 如果聊天内容或你的内心想法适合用一个表情来回应(例如表示赞同、惊讶、无语等),选择 'emoji_reply' 并提供表情主题 'emoji_query'。\n" - "4. 如果最后一条消息是你自己发的,并且之后没有人回复你,通常选择 'no_reply',除非有特殊原因需要追问。\n" - "5. 除非大家都在这么做,或者有特殊理由,否则不要重复别人刚刚说过的话或简单附和。\n" - "6. 表情包是用来表达情绪的,不要直接回复或评价别人的表情包,而是根据对话内容和情绪选择是否用表情回应。\n" - "7. 如果观察到的内容只有你自己的发言,选择 'no_reply'。\n" - "8. 不要回复你自己的话,不要把自己的话当做别人说的。\n" - "必须调用 'decide_reply_action' 工具并提供 'action' 和 'reasoning'。如果选择了 'emoji_reply' 或者选择了 'text_reply' 并想追加表情,则必须提供 'emoji_query'。" + current_mind_block = " [没有特别的想法] \n\n" + + # 获取提示词模板并填充数据 + prompt = (await global_prompt_manager.get_prompt_async("planner_prompt")).format( + bot_name=global_config.BOT_NICKNAME, + structured_info_block=structured_info_block, + chat_content_block=chat_content_block, + current_mind_block=current_mind_block, ) - + return prompt # --- 回复器 (Replier) 的定义 --- # @@ -698,7 +696,6 @@ class HeartFChatting: return None chat = anchor_message.chat_stream - # Access MessageManager directly container = await message_manager.get_container(chat.stream_id) thinking_message = None diff --git a/src/plugins/heartFC_chat/heartflow_prompt_builder.py b/src/plugins/heartFC_chat/heartflow_prompt_builder.py index 880d0a27d..2c2a961ef 100644 --- a/src/plugins/heartFC_chat/heartflow_prompt_builder.py +++ b/src/plugins/heartFC_chat/heartflow_prompt_builder.py @@ -26,16 +26,37 @@ def init_prompt(): {chat_target} {chat_talking_prompt} 现在你想要在群里发言或者回复。\n -你的网名叫{bot_name},{prompt_personality} {prompt_identity}。 -你正在{chat_target_2},现在请你读读之前的聊天记录,然后给出日常且口语化的回复,平淡一些, +你需要扮演一位网名叫{bot_name}的人进行回复,这个人的特点是:"{prompt_personality} {prompt_identity}"。 +你正在{chat_target_2},现在请你读读之前的聊天记录,然后给出日常且口语化的回复,平淡一些,你可以参考贴吧,小红书或者微博的回复风格。 你刚刚脑子里在想: {current_mind_info} {reason} 回复尽量简短一些。请注意把握聊天内容,不要回复的太有条理,可以有个性。请一次只回复一个话题,不要同时回复多个人,不用指出你回复的是谁。{prompt_ger} -请回复的平淡一些,简短一些,说中文,不要刻意突出自身学科背景,尽量不要说你说过的话 ,注意只输出回复内容。 +请回复的平淡一些,简短一些,说中文,不要刻意突出自身学科背景,不要说你说过的话题 ,注意只输出回复内容。 {moderation_prompt}。注意:不要输出多余内容(包括前后缀,冒号和引号,括号,表情包,at或 @等 )。""", "heart_flow_prompt", ) + + # Planner提示词 + Prompt( + """你的名字是 {bot_name}。是一个女大二学生,正在QQ聊天,正在决定是否以及如何回应当前的聊天。 +{structured_info_block} +{chat_content_block} +看了以上内容,你产生的内心想法是: +{current_mind_block} +请结合你的内心想法和观察到的聊天内容,分析情况并使用 'decide_reply_action' 工具来决定你的最终行动。 +决策依据: +1. 如果聊天内容无聊、与你无关、或者你的内心想法认为不适合回复(例如在讨论你不懂或不感兴趣的话题),选择 'no_reply'。 +2. 如果聊天内容值得回应,且适合用文字表达(参考你的内心想法),选择 'text_reply'。如果你有情绪想表达,想在文字后追加一个表达情绪的表情,请同时提供 'emoji_query' (例如:'开心的'、'惊讶的')。 +3. 如果聊天内容或你的内心想法适合用一个表情来回应(例如表示赞同、惊讶、无语等),选择 'emoji_reply' 并提供表情主题 'emoji_query'。 +4. 如果最后一条消息是你自己发的,观察到的内容只有你自己的发言,并且之后没有人回复你,通常选择 'no_reply',除非有特殊原因需要追问。 +5. 如果聊天记录中最新的消息是你自己发送的,并且你还想继续回复,你应该紧紧衔接你发送的消息,进行话题的深入,补充,或追问等等;。 +6. 表情包是用来表达情绪的,不要直接回复或评价别人的表情包,而是根据对话内容和情绪选择是否用表情回应。 +7. 不要回复你自己的话,不要把自己的话当做别人说的。 +必须调用 'decide_reply_action' 工具并提供 'action' 和 'reasoning'。如果选择了 'emoji_reply' 或者选择了 'text_reply' 并想追加表情,则必须提供 'emoji_query'。""", + "planner_prompt", + ) + Prompt("你正在qq群里聊天,下面是群里在聊的内容:", "chat_target_group1") Prompt("和群里聊天", "chat_target_group2") Prompt("你正在和{sender_name}聊天,这是你们之前聊的内容:", "chat_target_private1") diff --git a/src/plugins/heartFC_chat/normal_chat.py b/src/plugins/heartFC_chat/normal_chat.py index c020b4076..a3aaf3a0b 100644 --- a/src/plugins/heartFC_chat/normal_chat.py +++ b/src/plugins/heartFC_chat/normal_chat.py @@ -402,3 +402,17 @@ class NormalChat: # 确保任务状态更新,即使等待出错 (回调函数也会尝试更新) if self._chat_task is task: self._chat_task = None + + # 清理所有未处理的思考消息 + try: + container = await message_manager.get_container(self.stream_id) + if container: + # 查找并移除所有 MessageThinking 类型的消息 + thinking_messages = [msg for msg in container.messages[:] if isinstance(msg, MessageThinking)] + if thinking_messages: + for msg in thinking_messages: + container.messages.remove(msg) + logger.info(f"[{self.stream_name}] 清理了 {len(thinking_messages)} 条未处理的思考消息。") + except Exception as e: + logger.error(f"[{self.stream_name}] 清理思考消息时出错: {e}") + logger.error(traceback.format_exc())