diff --git a/src/heart_flow/mai_state_manager.py b/src/heart_flow/mai_state_manager.py index 1743df167..0888ae1fd 100644 --- a/src/heart_flow/mai_state_manager.py +++ b/src/heart_flow/mai_state_manager.py @@ -8,8 +8,8 @@ from src.plugins.moods.moods import MoodManager logger = get_logger("mai_state") -enable_unlimited_hfc_chat = True -# enable_unlimited_hfc_chat = False +# enable_unlimited_hfc_chat = True +enable_unlimited_hfc_chat = False class MaiState(enum.Enum): diff --git a/src/heart_flow/sub_mind.py b/src/heart_flow/sub_mind.py index 639791427..bccead7dd 100644 --- a/src/heart_flow/sub_mind.py +++ b/src/heart_flow/sub_mind.py @@ -22,6 +22,7 @@ def init_prompt(): prompt += "{extra_info}\n" prompt += "{prompt_personality}\n" prompt += "{last_loop_prompt}\n" + prompt += "{cycle_info_block}\n" prompt += "现在是{time_now},你正在上网,和qq群里的网友们聊天,以下是正在进行的聊天内容:\n{chat_observe_info}\n" prompt += "\n你现在{mood_info}\n" prompt += ( @@ -66,7 +67,7 @@ class SubMind: self.past_mind = [] self.structured_info = {} - async def do_thinking_before_reply(self, last_cycle: CycleInfo = None): + async def do_thinking_before_reply(self, history_cycle: list[CycleInfo] = None): """ 在回复前进行思考,生成内心想法并收集工具调用结果 @@ -130,6 +131,7 @@ class SubMind: ("进行深入思考", 0.2), ] + last_cycle = history_cycle[-1] if history_cycle else None # 上一次决策信息 if last_cycle != None: last_action = last_cycle.action_type @@ -151,6 +153,49 @@ class SubMind: else: last_loop_prompt = "" + # 准备循环信息块 (分析最近的活动循环) + recent_active_cycles = [] + for cycle in reversed(history_cycle): + # 只关心实际执行了动作的循环 + if cycle.action_taken: + recent_active_cycles.append(cycle) + # 最多找最近的3个活动循环 + if len(recent_active_cycles) == 3: + break + + cycle_info_block = "" + consecutive_text_replies = 0 + responses_for_prompt = [] + + # 检查这最近的活动循环中有多少是连续的文本回复 (从最近的开始看) + for cycle in recent_active_cycles: + if cycle.action_type == "text_reply": + consecutive_text_replies += 1 + # 获取回复内容,如果不存在则返回'[空回复]' + response_text = cycle.response_info.get("response_text", []) + # 使用简单的 join 来格式化回复内容列表 + formatted_response = "[空回复]" if not response_text else " ".join(response_text) + responses_for_prompt.append(formatted_response) + else: + # 一旦遇到非文本回复,连续性中断 + break + + # 根据连续文本回复的数量构建提示信息 + # 注意: responses_for_prompt 列表是从最近到最远排序的 + if consecutive_text_replies >= 3: # 如果最近的三个活动都是文本回复 + cycle_info_block = f'你已经连续回复了三条消息(最近: "{responses_for_prompt[0]}",第二近: "{responses_for_prompt[1]}",第三近: "{responses_for_prompt[2]}")。你回复的有点多了,请注意' + elif consecutive_text_replies == 2: # 如果最近的两个活动是文本回复 + cycle_info_block = f'你已经连续回复了两条消息(最近: "{responses_for_prompt[0]}",第二近: "{responses_for_prompt[1]}"),请注意' + elif consecutive_text_replies == 1: # 如果最近的一个活动是文本回复 + cycle_info_block = f'你刚刚已经回复一条消息(内容: "{responses_for_prompt[0]}")' + + # 包装提示块,增加可读性,即使没有连续回复也给个标记 + if cycle_info_block: + cycle_info_block = f"\n【近期回复历史】\n{cycle_info_block}\n" + else: + # 如果最近的活动循环不是文本回复,或者没有活动循环 + cycle_info_block = "\n【近期回复历史】\n(最近没有连续文本回复)\n" + # 加权随机选择思考指导 hf_do_next = local_random.choices( [option[0] for option in hf_options], weights=[option[1] for option in hf_options], k=1 @@ -167,6 +212,7 @@ class SubMind: mood_info=mood_info, hf_do_next=hf_do_next, last_loop_prompt=last_loop_prompt, + cycle_info_block=cycle_info_block, ) # logger.debug(f"[{self.subheartflow_id}] 心流思考提示词构建完成") diff --git a/src/plugins/heartFC_chat/heartFC_chat.py b/src/plugins/heartFC_chat/heartFC_chat.py index 7fd2cb80d..1237378a4 100644 --- a/src/plugins/heartFC_chat/heartFC_chat.py +++ b/src/plugins/heartFC_chat/heartFC_chat.py @@ -705,12 +705,14 @@ class HeartFChatting: await observation.observe() # 获取上一个循环的信息 - last_cycle = self._cycle_history[-1] if self._cycle_history else None + # last_cycle = self._cycle_history[-1] if self._cycle_history else None with Timer("思考", cycle_timers): # 获取上一个循环的动作 # 传递上一个循环的信息给 do_thinking_before_reply - current_mind, _past_mind = await self.sub_mind.do_thinking_before_reply(last_cycle=last_cycle) + current_mind, _past_mind = await self.sub_mind.do_thinking_before_reply( + history_cycle=self._cycle_history + ) return current_mind except Exception as e: logger.error(f"{self.log_prefix}[SubMind] 思考失败: {e}") @@ -787,7 +789,7 @@ class HeartFChatting: # 使用辅助函数处理工具调用响应 print(1111122222222222) print(response) - + success, arguments, error_msg = process_llm_tool_response( response, expected_tool_name="decide_reply_action", log_prefix=f"{self.log_prefix}[Planner] " ) @@ -998,7 +1000,7 @@ class HeartFChatting: current_mind_block = f"{current_mind}" else: current_mind_block = "[没有特别的想法]" - + # 准备循环信息块 (分析最近的活动循环) recent_active_cycles = [] for cycle in reversed(self._cycle_history): @@ -1028,19 +1030,19 @@ class HeartFChatting: # 根据连续文本回复的数量构建提示信息 # 注意: responses_for_prompt 列表是从最近到最远排序的 - if consecutive_text_replies >= 3: # 如果最近的三个活动都是文本回复 + if consecutive_text_replies >= 3: # 如果最近的三个活动都是文本回复 cycle_info_block = f'你已经连续回复了三条消息(最近: "{responses_for_prompt[0]}",第二近: "{responses_for_prompt[1]}",第三近: "{responses_for_prompt[2]}")。你回复的有点多了,请注意' - elif consecutive_text_replies == 2: # 如果最近的两个活动是文本回复 + elif consecutive_text_replies == 2: # 如果最近的两个活动是文本回复 cycle_info_block = f'你已经连续回复了两条消息(最近: "{responses_for_prompt[0]}",第二近: "{responses_for_prompt[1]}"),请注意' - elif consecutive_text_replies == 1: # 如果最近的一个活动是文本回复 + elif consecutive_text_replies == 1: # 如果最近的一个活动是文本回复 cycle_info_block = f'你刚刚已经回复一条消息(内容: "{responses_for_prompt[0]}")' # 包装提示块,增加可读性,即使没有连续回复也给个标记 if cycle_info_block: - cycle_info_block = f'\n【近期回复历史】\n{cycle_info_block}\n' + cycle_info_block = f"\n【近期回复历史】\n{cycle_info_block}\n" else: # 如果最近的活动循环不是文本回复,或者没有活动循环 - cycle_info_block = '\n【近期回复历史】\n(最近没有连续文本回复)\n' + cycle_info_block = "\n【近期回复历史】\n(最近没有连续文本回复)\n" # 获取提示词模板并填充数据 prompt = (await global_prompt_manager.get_prompt_async("planner_prompt")).format( diff --git a/src/plugins/utils/json_utils.py b/src/plugins/utils/json_utils.py index b46ac7510..a76c83e39 100644 --- a/src/plugins/utils/json_utils.py +++ b/src/plugins/utils/json_utils.py @@ -215,7 +215,7 @@ def process_llm_tool_calls(response: List[Any], log_prefix: str = "") -> Tuple[b # 确保响应格式正确 print(response) print(11111111111111111) - + if len(response) != 3: return False, [], f"LLM响应元素数量不正确: 预期3个元素,实际{len(response)}个" @@ -280,7 +280,9 @@ def process_llm_tool_response( # 新增检查:确保响应包含预期的工具调用部分 if len(normalized_response) != 3: # 如果长度不为3,说明LLM响应不包含工具调用部分,这在期望工具调用的上下文中是错误的 - error_msg = f"LLM响应未包含预期的工具调用部分: 元素数量{len(normalized_response)},响应内容:{normalized_response}" + error_msg = ( + f"LLM响应未包含预期的工具调用部分: 元素数量{len(normalized_response)},响应内容:{normalized_response}" + ) logger.warning(f"{log_prefix}{error_msg}") return False, {}, error_msg