From dbdf650b1d766fbf6cd658d6580ae0d4a9d29045 Mon Sep 17 00:00:00 2001 From: SengokuCola <1026294844@qq.com> Date: Thu, 2 Oct 2025 20:11:44 +0800 Subject: [PATCH] =?UTF-8?q?ref=EF=BC=9A=E4=BF=AE=E6=94=B9=E4=BA=86plan?= =?UTF-8?q?=E7=9A=84=E6=89=A7=E8=A1=8C=E8=AE=B0=E5=BD=95=E5=B1=95=E7=A4=BA?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F=EF=BC=8C=E7=8E=B0=E5=9C=A8=E6=AF=8F=E4=B8=AA?= =?UTF-8?q?=E5=8A=A8=E4=BD=9C=E7=9A=84=E6=89=A7=E8=A1=8C=E9=83=BD=E4=BC=9A?= =?UTF-8?q?=E8=A2=AB=E8=AE=B0=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- changelogs/changelog.md | 17 +- changelogs/changelog_config.md | 51 --- scripts/expression_scatter_analysis.py | 334 ++++++++++++++++++ src/chat/brain_chat/brain_chat.py | 14 +- src/chat/brain_chat/brain_planner.py | 18 +- src/chat/heart_flow/heartFC_chat.py | 78 ++-- src/chat/planner_actions/action_manager.py | 6 +- src/chat/planner_actions/planner.py | 99 +++--- src/chat/utils/chat_message_builder.py | 6 +- src/common/data_models/database_data_model.py | 2 + src/common/data_models/info_data_model.py | 1 + src/common/database/database_model.py | 2 + src/common/logger.py | 2 +- src/plugin_system/apis/database_api.py | 4 +- src/plugin_system/base/base_action.py | 80 ++--- src/plugins/built_in/MaiCurious/plugin.py | 4 +- src/plugins/built_in/emoji_plugin/plugin.py | 2 +- src/plugins/built_in/memory/plugin.py | 2 +- template/bot_config_template.toml | 6 +- 19 files changed, 521 insertions(+), 207 deletions(-) delete mode 100644 changelogs/changelog_config.md create mode 100644 scripts/expression_scatter_analysis.py diff --git a/changelogs/changelog.md b/changelogs/changelog.md index ab5f86ad..a35f2ef6 100644 --- a/changelogs/changelog.md +++ b/changelogs/changelog.md @@ -1,8 +1,21 @@ # Changelog -## [0.10.4] - 2025-9-22 -表达方式优化 +## [0.11.0] - 2025-9-22 +### 🌟 主要功能更改 +- 重构记忆系统,新的记忆系统更可靠,记忆能力更强大 +- 麦麦好奇功能,麦麦会自主提出问题 +- 添加deepthink插件(默认关闭),让麦麦可以深度思考一些问题 +- 添加表情包管理插件 +### 细节功能更改 +- 修复配置文件转义问题 +- 情绪系统现在可以由配置文件控制开关 +- 修复平行动作控制失效的问题 +- 添加planner防抖,防止短时间快速消耗token +- 修复吞字问题 +- 更新依赖表 +- 修复负载均衡 +- 优化了对gemini和不同模型的支持 ## [0.10.3] - 2025-9-22 ### 🌟 主要功能更改 diff --git a/changelogs/changelog_config.md b/changelogs/changelog_config.md deleted file mode 100644 index 5aa5fb92..00000000 --- a/changelogs/changelog_config.md +++ /dev/null @@ -1,51 +0,0 @@ -# Changelog - -## [1.0.3] - 2025-3-31 -### Added -- 新增了心流相关配置项: - - `heartflow` 配置项,用于控制心流功能 - -### Removed -- 移除了 `response` 配置项中的 `model_r1_probability` 和 `model_v3_probability` 选项 -- 移除了次级推理模型相关配置 - -## [1.0.1] - 2025-3-30 -### Added -- 增加了流式输出控制项 `stream` -- 修复 `LLM_Request` 不会自动为 `payload` 增加流式输出标志的问题 - -## [1.0.0] - 2025-3-30 -### Added -- 修复了错误的版本命名 -- 杀掉了所有无关文件 - -## [0.0.11] - 2025-3-12 -### Added -- 新增了 `schedule` 配置项,用于配置日程表生成功能 -- 新增了 `response_splitter` 配置项,用于控制回复分割 -- 新增了 `experimental` 配置项,用于实验性功能开关 -- 新增了 `llm_observation` 和 `llm_sub_heartflow` 模型配置 -- 新增了 `llm_heartflow` 模型配置 -- 在 `personality` 配置项中新增了 `prompt_schedule_gen` 参数 - -### Changed -- 优化了模型配置的组织结构 -- 调整了部分配置项的默认值 -- 调整了配置项的顺序,将 `groups` 配置项移到了更靠前的位置 -- 在 `message` 配置项中: - - 新增了 `model_max_output_length` 参数 -- 在 `willing` 配置项中新增了 `emoji_response_penalty` 参数 -- 将 `personality` 配置项中的 `prompt_schedule` 重命名为 `prompt_schedule_gen` - -### Removed -- 移除了 `min_text_length` 配置项 -- 移除了 `cq_code` 配置项 -- 移除了 `others` 配置项(其功能已整合到 `experimental` 中) - -## [0.0.5] - 2025-3-11 -### Added -- 新增了 `alias_names` 配置项,用于指定麦麦的别名。 - -## [0.0.4] - 2025-3-9 -### Added -- 新增了 `memory_ban_words` 配置项,用于指定不希望记忆的词汇。 \ No newline at end of file diff --git a/scripts/expression_scatter_analysis.py b/scripts/expression_scatter_analysis.py new file mode 100644 index 00000000..f6243ada --- /dev/null +++ b/scripts/expression_scatter_analysis.py @@ -0,0 +1,334 @@ +import time +import sys +import os +import matplotlib.pyplot as plt +import matplotlib.dates as mdates +from datetime import datetime +from typing import List, Tuple +import numpy as np + +# Add project root to Python path +project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +sys.path.insert(0, project_root) + +from src.common.database.database_model import Expression, ChatStreams + +# 设置中文字体 +plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei', 'DejaVu Sans'] +plt.rcParams['axes.unicode_minus'] = False + + +def get_chat_name(chat_id: str) -> str: + """Get chat name from chat_id by querying ChatStreams table directly""" + try: + chat_stream = ChatStreams.get_or_none(ChatStreams.stream_id == chat_id) + if chat_stream is None: + return f"未知聊天 ({chat_id})" + + if chat_stream.group_name: + return f"{chat_stream.group_name} ({chat_id})" + elif chat_stream.user_nickname: + return f"{chat_stream.user_nickname}的私聊 ({chat_id})" + else: + return f"未知聊天 ({chat_id})" + except Exception: + return f"查询失败 ({chat_id})" + + +def get_expression_data() -> List[Tuple[float, float, str, str]]: + """获取Expression表中的数据,返回(create_date, count, chat_id, expression_type)的列表""" + expressions = Expression.select() + data = [] + + for expr in expressions: + # 如果create_date为空,跳过该记录 + if expr.create_date is None: + continue + + data.append(( + expr.create_date, + expr.count, + expr.chat_id, + expr.type + )) + + return data + + +def create_scatter_plot(data: List[Tuple[float, float, str, str]], save_path: str = None): + """创建散点图""" + if not data: + print("没有找到有效的表达式数据") + return + + # 分离数据 + create_dates = [item[0] for item in data] + counts = [item[1] for item in data] + chat_ids = [item[2] for item in data] + expression_types = [item[3] for item in data] + + # 转换时间戳为datetime对象 + dates = [datetime.fromtimestamp(ts) for ts in create_dates] + + # 计算时间跨度,自动调整显示格式 + time_span = max(dates) - min(dates) + if time_span.days > 30: # 超过30天,按月显示 + date_format = '%Y-%m-%d' + major_locator = mdates.MonthLocator() + minor_locator = mdates.DayLocator(interval=7) + elif time_span.days > 7: # 超过7天,按天显示 + date_format = '%Y-%m-%d' + major_locator = mdates.DayLocator(interval=1) + minor_locator = mdates.HourLocator(interval=12) + else: # 7天内,按小时显示 + date_format = '%Y-%m-%d %H:%M' + major_locator = mdates.HourLocator(interval=6) + minor_locator = mdates.HourLocator(interval=1) + + # 创建图形 + fig, ax = plt.subplots(figsize=(12, 8)) + + # 创建散点图 + scatter = ax.scatter(dates, counts, alpha=0.6, s=30, c=range(len(dates)), cmap='viridis') + + # 设置标签和标题 + ax.set_xlabel('创建日期 (Create Date)', fontsize=12) + ax.set_ylabel('使用次数 (Count)', fontsize=12) + ax.set_title('表达式使用次数随时间分布散点图', fontsize=14, fontweight='bold') + + # 设置x轴日期格式 - 根据时间跨度自动调整 + ax.xaxis.set_major_formatter(mdates.DateFormatter(date_format)) + ax.xaxis.set_major_locator(major_locator) + ax.xaxis.set_minor_locator(minor_locator) + plt.xticks(rotation=45) + + # 添加网格 + ax.grid(True, alpha=0.3) + + # 添加颜色条 + cbar = plt.colorbar(scatter) + cbar.set_label('数据点顺序', fontsize=10) + + # 调整布局 + plt.tight_layout() + + # 显示统计信息 + print(f"\n=== 数据统计 ===") + print(f"总数据点数量: {len(data)}") + print(f"时间范围: {min(dates).strftime('%Y-%m-%d %H:%M:%S')} 到 {max(dates).strftime('%Y-%m-%d %H:%M:%S')}") + print(f"使用次数范围: {min(counts):.1f} 到 {max(counts):.1f}") + print(f"平均使用次数: {np.mean(counts):.2f}") + print(f"中位数使用次数: {np.median(counts):.2f}") + + # 保存图片 + if save_path: + plt.savefig(save_path, dpi=300, bbox_inches='tight') + print(f"\n散点图已保存到: {save_path}") + + # 显示图片 + plt.show() + + +def create_grouped_scatter_plot(data: List[Tuple[float, float, str, str]], save_path: str = None): + """创建按聊天分组的散点图""" + if not data: + print("没有找到有效的表达式数据") + return + + # 按chat_id分组 + chat_groups = {} + for item in data: + chat_id = item[2] + if chat_id not in chat_groups: + chat_groups[chat_id] = [] + chat_groups[chat_id].append(item) + + # 计算时间跨度,自动调整显示格式 + all_dates = [datetime.fromtimestamp(item[0]) for item in data] + time_span = max(all_dates) - min(all_dates) + if time_span.days > 30: # 超过30天,按月显示 + date_format = '%Y-%m-%d' + major_locator = mdates.MonthLocator() + minor_locator = mdates.DayLocator(interval=7) + elif time_span.days > 7: # 超过7天,按天显示 + date_format = '%Y-%m-%d' + major_locator = mdates.DayLocator(interval=1) + minor_locator = mdates.HourLocator(interval=12) + else: # 7天内,按小时显示 + date_format = '%Y-%m-%d %H:%M' + major_locator = mdates.HourLocator(interval=6) + minor_locator = mdates.HourLocator(interval=1) + + # 创建图形 + fig, ax = plt.subplots(figsize=(14, 10)) + + # 为每个聊天分配不同颜色 + colors = plt.cm.Set3(np.linspace(0, 1, len(chat_groups))) + + for i, (chat_id, chat_data) in enumerate(chat_groups.items()): + create_dates = [item[0] for item in chat_data] + counts = [item[1] for item in chat_data] + dates = [datetime.fromtimestamp(ts) for ts in create_dates] + + chat_name = get_chat_name(chat_id) + # 截断过长的聊天名称 + display_name = chat_name[:20] + "..." if len(chat_name) > 20 else chat_name + + ax.scatter(dates, counts, alpha=0.7, s=40, + c=[colors[i]], label=f"{display_name} ({len(chat_data)}个)", + edgecolors='black', linewidth=0.5) + + # 设置标签和标题 + ax.set_xlabel('创建日期 (Create Date)', fontsize=12) + ax.set_ylabel('使用次数 (Count)', fontsize=12) + ax.set_title('按聊天分组的表达式使用次数散点图', fontsize=14, fontweight='bold') + + # 设置x轴日期格式 - 根据时间跨度自动调整 + ax.xaxis.set_major_formatter(mdates.DateFormatter(date_format)) + ax.xaxis.set_major_locator(major_locator) + ax.xaxis.set_minor_locator(minor_locator) + plt.xticks(rotation=45) + + # 添加图例 + ax.legend(bbox_to_anchor=(1.05, 1), loc='upper left', fontsize=8) + + # 添加网格 + ax.grid(True, alpha=0.3) + + # 调整布局 + plt.tight_layout() + + # 显示统计信息 + print(f"\n=== 分组统计 ===") + print(f"总聊天数量: {len(chat_groups)}") + for chat_id, chat_data in chat_groups.items(): + chat_name = get_chat_name(chat_id) + counts = [item[1] for item in chat_data] + print(f"{chat_name}: {len(chat_data)}个表达式, 平均使用次数: {np.mean(counts):.2f}") + + # 保存图片 + if save_path: + plt.savefig(save_path, dpi=300, bbox_inches='tight') + print(f"\n分组散点图已保存到: {save_path}") + + # 显示图片 + plt.show() + + +def create_type_scatter_plot(data: List[Tuple[float, float, str, str]], save_path: str = None): + """创建按表达式类型分组的散点图""" + if not data: + print("没有找到有效的表达式数据") + return + + # 按type分组 + type_groups = {} + for item in data: + expr_type = item[3] + if expr_type not in type_groups: + type_groups[expr_type] = [] + type_groups[expr_type].append(item) + + # 计算时间跨度,自动调整显示格式 + all_dates = [datetime.fromtimestamp(item[0]) for item in data] + time_span = max(all_dates) - min(all_dates) + if time_span.days > 30: # 超过30天,按月显示 + date_format = '%Y-%m-%d' + major_locator = mdates.MonthLocator() + minor_locator = mdates.DayLocator(interval=7) + elif time_span.days > 7: # 超过7天,按天显示 + date_format = '%Y-%m-%d' + major_locator = mdates.DayLocator(interval=1) + minor_locator = mdates.HourLocator(interval=12) + else: # 7天内,按小时显示 + date_format = '%Y-%m-%d %H:%M' + major_locator = mdates.HourLocator(interval=6) + minor_locator = mdates.HourLocator(interval=1) + + # 创建图形 + fig, ax = plt.subplots(figsize=(12, 8)) + + # 为每个类型分配不同颜色 + colors = plt.cm.tab10(np.linspace(0, 1, len(type_groups))) + + for i, (expr_type, type_data) in enumerate(type_groups.items()): + create_dates = [item[0] for item in type_data] + counts = [item[1] for item in type_data] + dates = [datetime.fromtimestamp(ts) for ts in create_dates] + + ax.scatter(dates, counts, alpha=0.7, s=40, + c=[colors[i]], label=f"{expr_type} ({len(type_data)}个)", + edgecolors='black', linewidth=0.5) + + # 设置标签和标题 + ax.set_xlabel('创建日期 (Create Date)', fontsize=12) + ax.set_ylabel('使用次数 (Count)', fontsize=12) + ax.set_title('按表达式类型分组的散点图', fontsize=14, fontweight='bold') + + # 设置x轴日期格式 - 根据时间跨度自动调整 + ax.xaxis.set_major_formatter(mdates.DateFormatter(date_format)) + ax.xaxis.set_major_locator(major_locator) + ax.xaxis.set_minor_locator(minor_locator) + plt.xticks(rotation=45) + + # 添加图例 + ax.legend(bbox_to_anchor=(1.05, 1), loc='upper left') + + # 添加网格 + ax.grid(True, alpha=0.3) + + # 调整布局 + plt.tight_layout() + + # 显示统计信息 + print(f"\n=== 类型统计 ===") + for expr_type, type_data in type_groups.items(): + counts = [item[1] for item in type_data] + print(f"{expr_type}: {len(type_data)}个表达式, 平均使用次数: {np.mean(counts):.2f}") + + # 保存图片 + if save_path: + plt.savefig(save_path, dpi=300, bbox_inches='tight') + print(f"\n类型散点图已保存到: {save_path}") + + # 显示图片 + plt.show() + + +def main(): + """主函数""" + print("开始分析表达式数据...") + + # 获取数据 + data = get_expression_data() + + if not data: + print("没有找到有效的表达式数据(create_date不为空的数据)") + return + + print(f"找到 {len(data)} 条有效数据") + + # 创建输出目录 + output_dir = os.path.join(project_root, "data", "temp") + os.makedirs(output_dir, exist_ok=True) + + # 生成时间戳用于文件名 + timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") + + # 1. 创建基础散点图 + print("\n1. 创建基础散点图...") + create_scatter_plot(data, os.path.join(output_dir, f"expression_scatter_{timestamp}.png")) + + # 2. 创建按聊天分组的散点图 + print("\n2. 创建按聊天分组的散点图...") + create_grouped_scatter_plot(data, os.path.join(output_dir, f"expression_scatter_by_chat_{timestamp}.png")) + + # 3. 创建按类型分组的散点图 + print("\n3. 创建按类型分组的散点图...") + create_type_scatter_plot(data, os.path.join(output_dir, f"expression_scatter_by_type_{timestamp}.png")) + + print("\n分析完成!") + + +if __name__ == "__main__": + main() diff --git a/src/chat/brain_chat/brain_chat.py b/src/chat/brain_chat/brain_chat.py index 36f78af4..04ae5d3e 100644 --- a/src/chat/brain_chat/brain_chat.py +++ b/src/chat/brain_chat/brain_chat.py @@ -282,7 +282,7 @@ class BrainChatting: prompt_info = (modified_message.llm_prompt, prompt_info[1]) with Timer("规划器", cycle_timers): - action_to_use_info, _ = await self.action_planner.plan( + action_to_use_info = await self.action_planner.plan( loop_start_time=self.last_read_time, available_actions=available_actions, ) @@ -413,8 +413,8 @@ class BrainChatting: logger.warning(f"{self.log_prefix} 未能创建动作处理器: {action}") return False, "", "" - # 处理动作并获取结果 - result = await action_handler.execute() + # 处理动作并获取结果(固定记录一次动作信息) + result = await action_handler.run() success, action_text = result command = "" @@ -481,11 +481,11 @@ class BrainChatting: try: with Timer(f"动作{action_planner_info.action_type}", cycle_timers): if action_planner_info.action_type == "no_reply": - # 直接处理no_action逻辑,不再通过动作系统 + # 直接处理no_reply逻辑,不再通过动作系统 reason = action_planner_info.reasoning or "选择不回复" # logger.info(f"{self.log_prefix} 选择不回复,原因: {reason}") - # 存储no_action信息到数据库 + # 存储no_reply信息到数据库 await database_api.store_action_info( chat_stream=self.chat_stream, action_build_into_prompt=False, @@ -493,9 +493,9 @@ class BrainChatting: action_done=True, thinking_id=thinking_id, action_data={"reason": reason}, - action_name="no_action", + action_name="no_reply", ) - return {"action_type": "no_action", "success": True, "reply_text": "", "command": ""} + return {"action_type": "no_reply", "success": True, "reply_text": "", "command": ""} elif action_planner_info.action_type == "reply": try: diff --git a/src/chat/brain_chat/brain_planner.py b/src/chat/brain_chat/brain_planner.py index 5c4f969c..35cdf172 100644 --- a/src/chat/brain_chat/brain_planner.py +++ b/src/chat/brain_chat/brain_planner.py @@ -152,10 +152,10 @@ class BrainPlanner: action_planner_infos = [] try: - action = action_json.get("action", "no_action") + action = action_json.get("action", "no_reply") reasoning = action_json.get("reason", "未提供原因") action_data = {key: value for key, value in action_json.items() if key not in ["action", "reason"]} - # 非no_action动作需要target_message_id + # 非no_reply动作需要target_message_id target_message = None if target_message_id := action_json.get("target_message_id"): @@ -215,12 +215,11 @@ class BrainPlanner: self, available_actions: Dict[str, ActionInfo], loop_start_time: float = 0.0, - ) -> Tuple[List[ActionPlannerInfo], Optional["DatabaseMessages"]]: + ) -> List[ActionPlannerInfo]: # sourcery skip: use-named-expression """ 规划器 (Planner): 使用LLM根据上下文决定做出什么动作。 """ - target_message: Optional["DatabaseMessages"] = None # 获取聊天上下文 message_list_before_now = get_raw_msg_before_timestamp_with_chat( @@ -274,12 +273,7 @@ class BrainPlanner: loop_start_time=loop_start_time, ) - # 获取target_message(如果有非no_action的动作) - non_no_actions = [a for a in actions if a.action_type != "no_reply"] - if non_no_actions: - target_message = non_no_actions[0].action_message - - return actions, target_message + return actions async def build_planner_prompt( self, @@ -489,7 +483,7 @@ class BrainPlanner: else: actions = self._create_no_reply("规划器没有获得LLM响应", available_actions) - # 添加循环开始时间到所有非no_action动作 + # 添加循环开始时间到所有非no_reply动作 for action in actions: action.action_data = action.action_data or {} action.action_data["loop_start_time"] = loop_start_time @@ -501,7 +495,7 @@ class BrainPlanner: return actions def _create_no_reply(self, reasoning: str, available_actions: Dict[str, ActionInfo]) -> List[ActionPlannerInfo]: - """创建no_action""" + """创建no_reply""" return [ ActionPlannerInfo( action_type="no_reply", diff --git a/src/chat/heart_flow/heartFC_chat.py b/src/chat/heart_flow/heartFC_chat.py index a3bab239..9745fd81 100644 --- a/src/chat/heart_flow/heartFC_chat.py +++ b/src/chat/heart_flow/heartFC_chat.py @@ -98,6 +98,8 @@ class HeartFChatting: self.last_read_time = time.time() - 2 self.no_reply_until_call = False + + self.is_mute = False async def start(self): @@ -175,6 +177,8 @@ class HeartFChatting: ) if len(recent_messages_list) >= 1: + # for message in recent_messages_list: + # print(message.processed_plain_text) # !处理no_reply_until_call逻辑 if self.no_reply_until_call: for message in recent_messages_list: @@ -185,6 +189,7 @@ class HeartFChatting: or time.time() - self.last_read_time > 600 ): self.no_reply_until_call = False + self.last_read_time = time.time() break # 没有提到,继续保持沉默 if self.no_reply_until_call: @@ -333,7 +338,7 @@ class HeartFChatting: prompt_info = (modified_message.llm_prompt, prompt_info[1]) with Timer("规划器", cycle_timers): - action_to_use_info, _ = await self.action_planner.plan( + action_to_use_info = await self.action_planner.plan( loop_start_time=self.last_read_time, available_actions=available_actions, ) @@ -450,7 +455,7 @@ class HeartFChatting: async def _handle_action( self, action: str, - reasoning: str, + action_reasoning: str, action_data: dict, cycle_timers: Dict[str, float], thinking_id: str, @@ -461,11 +466,11 @@ class HeartFChatting: 参数: action: 动作类型 - reasoning: 决策理由 + action_reasoning: 决策理由 action_data: 动作数据,包含不同动作需要的参数 cycle_timers: 计时器字典 thinking_id: 思考ID - + action_message: 消息数据 返回: tuple[bool, str, str]: (是否执行了动作, 思考消息ID, 命令) """ @@ -475,11 +480,11 @@ class HeartFChatting: action_handler = self.action_manager.create_action( action_name=action, action_data=action_data, - reasoning=reasoning, cycle_timers=cycle_timers, thinking_id=thinking_id, chat_stream=self.chat_stream, log_prefix=self.log_prefix, + action_reasoning=action_reasoning, action_message=action_message, ) except Exception as e: @@ -491,7 +496,7 @@ class HeartFChatting: logger.warning(f"{self.log_prefix} 未能创建动作处理器: {action}") return False, "", "" - # 处理动作并获取结果 + # 处理动作并获取结果(固定记录一次动作信息) result = await action_handler.execute() success, action_text = result command = "" @@ -558,42 +563,67 @@ class HeartFChatting: """执行单个动作的通用函数""" try: with Timer(f"动作{action_planner_info.action_type}", cycle_timers): + # 直接当场执行no_reply逻辑 if action_planner_info.action_type == "no_reply": - # 直接处理no_action逻辑,不再通过动作系统 + # 直接处理no_reply逻辑,不再通过动作系统 reason = action_planner_info.reasoning or "选择不回复" # logger.info(f"{self.log_prefix} 选择不回复,原因: {reason}") - # 存储no_action信息到数据库 await database_api.store_action_info( chat_stream=self.chat_stream, action_build_into_prompt=False, action_prompt_display=reason, action_done=True, thinking_id=thinking_id, - action_data={"reason": reason}, - action_name="no_action", + action_data={}, + action_name="no_reply", + action_reasoning=reason, ) - return {"action_type": "no_action", "success": True, "reply_text": "", "command": ""} - elif action_planner_info.action_type == "wait_time": - action_planner_info.action_data = action_planner_info.action_data or {} - logger.info(f"{self.log_prefix} 等待{action_planner_info.action_data['time']}秒后回复") - await asyncio.sleep(action_planner_info.action_data["time"]) - return {"action_type": "wait_time", "success": True, "reply_text": "", "command": ""} + + return {"action_type": "no_reply", "success": True, "reply_text": "", "command": ""} elif action_planner_info.action_type == "no_reply_until_call": + # 直接当场执行no_reply_until_call逻辑 logger.info(f"{self.log_prefix} 保持沉默,直到有人直接叫的名字") + reason = action_planner_info.reasoning or "选择不回复" + self.no_reply_until_call = True + await database_api.store_action_info( + chat_stream=self.chat_stream, + action_build_into_prompt=False, + action_prompt_display=reason, + action_done=True, + thinking_id=thinking_id, + action_data={}, + action_name="no_reply_until_call", + action_reasoning=reason, + ) + + return {"action_type": "no_reply_until_call", "success": True, "reply_text": "", "command": ""} elif action_planner_info.action_type == "reply": + # 直接当场执行reply逻辑 try: + reason = action_planner_info.reasoning or "选择回复" + await database_api.store_action_info( + chat_stream=self.chat_stream, + action_build_into_prompt=False, + action_prompt_display=reason, + action_done=True, + thinking_id=thinking_id, + action_data={}, + action_name="reply", + action_reasoning=reason, + ) + success, llm_response = await generator_api.generate_reply( chat_stream=self.chat_stream, reply_message=action_planner_info.action_message, available_actions=available_actions, chosen_actions=chosen_action_plan_infos, - reply_reason=action_planner_info.reasoning or "", + reply_reason=reason, enable_tool=global_config.tool.enable_tool, request_type="replyer", from_plugin=False, @@ -627,18 +657,16 @@ class HeartFChatting: "reply_text": reply_text, "loop_info": loop_info, } - - # 其他动作 else: # 执行普通动作 with Timer("动作执行", cycle_timers): success, reply_text, command = await self._handle_action( - action_planner_info.action_type, - action_planner_info.reasoning or "", - action_planner_info.action_data or {}, - cycle_timers, - thinking_id, - action_planner_info.action_message, + action = action_planner_info.action_type, + action_reasoning = action_planner_info.action_reasoning or "", + action_data = action_planner_info.action_data or {}, + cycle_timers = cycle_timers, + thinking_id = thinking_id, + action_message= action_planner_info.action_message, ) return { "action_type": action_planner_info.action_type, diff --git a/src/chat/planner_actions/action_manager.py b/src/chat/planner_actions/action_manager.py index 013d78e1..287d4063 100644 --- a/src/chat/planner_actions/action_manager.py +++ b/src/chat/planner_actions/action_manager.py @@ -32,7 +32,7 @@ class ActionManager: self, action_name: str, action_data: dict, - reasoning: str, + action_reasoning: str, cycle_timers: dict, thinking_id: str, chat_stream: ChatStream, @@ -46,7 +46,7 @@ class ActionManager: Args: action_name: 动作名称 action_data: 动作数据 - reasoning: 执行理由 + action_reasoning: 执行理由 cycle_timers: 计时器字典 thinking_id: 思考ID chat_stream: 聊天流 @@ -77,7 +77,7 @@ class ActionManager: # 创建动作实例 instance = component_class( action_data=action_data, - reasoning=reasoning, + action_reasoning=action_reasoning, cycle_timers=cycle_timers, thinking_id=thinking_id, chat_stream=chat_stream, diff --git a/src/chat/planner_actions/planner.py b/src/chat/planner_actions/planner.py index 10bb53dc..2e642d9d 100644 --- a/src/chat/planner_actions/planner.py +++ b/src/chat/planner_actions/planner.py @@ -44,10 +44,7 @@ def init_prompt(): **聊天内容** {chat_content_block} -**动作记录** -{actions_before_now_block} - -**可用的action** +**可选的action** reply 动作描述: 1.你可以选择呼叫了你的名字,但是你没有做出回应的消息进行回复 @@ -76,7 +73,10 @@ no_reply_until_call {action_options_text} -请选择合适的action,并说明触发action的消息id和选择该action的原因。消息id格式:m+数字 +**你之前的action执行和思考记录** +{actions_before_now_block} + +请选择**可选的**且符合使用条件的action,并说明触发action的消息id(消息id格式:m+数字) 先输出你的选择思考理由,再输出你选择的action,理由是一段平文本,不要分点,精简。 **动作选择要求** 请你根据聊天内容,用户的最新消息和以下标准选择合适的动作: @@ -99,9 +99,7 @@ no_reply_until_call "target_message_id":"触发动作的消息id", //对应参数 }} -``` - -""", +```""", "planner_prompt", ) @@ -133,6 +131,9 @@ class ActionPlanner: self.last_obs_time_mark = 0.0 + + self.plan_log:List[Tuple[str,str,ActionPlannerInfo]] = [] + def find_message_by_id( self, message_id: str, message_id_list: List[Tuple[str, "DatabaseMessages"]] ) -> Optional["DatabaseMessages"]: @@ -157,15 +158,16 @@ class ActionPlanner: action_json: dict, message_id_list: List[Tuple[str, "DatabaseMessages"]], current_available_actions: List[Tuple[str, ActionInfo]], + extracted_reasoning: str = "", ) -> List[ActionPlannerInfo]: """解析单个action JSON并返回ActionPlannerInfo列表""" action_planner_infos = [] try: - action = action_json.get("action", "no_action") + action = action_json.get("action", "no_reply") reasoning = action_json.get("reason", "未提供原因") action_data = {key: value for key, value in action_json.items() if key not in ["action", "reason"]} - # 非no_action动作需要target_message_id + # 非no_reply动作需要target_message_id target_message = None if target_message_id := action_json.get("target_message_id"): @@ -202,6 +204,7 @@ class ActionPlanner: action_data=action_data, action_message=target_message, available_actions=available_actions_dict, + action_reasoning=extracted_reasoning if extracted_reasoning else None, ) ) @@ -216,6 +219,7 @@ class ActionPlanner: action_data={}, action_message=None, available_actions=available_actions_dict, + action_reasoning=extracted_reasoning if extracted_reasoning else None, ) ) @@ -225,12 +229,11 @@ class ActionPlanner: self, available_actions: Dict[str, ActionInfo], loop_start_time: float = 0.0, - ) -> Tuple[List[ActionPlannerInfo], Optional["DatabaseMessages"]]: + ) -> List[ActionPlannerInfo]: # sourcery skip: use-named-expression """ 规划器 (Planner): 使用LLM根据上下文决定做出什么动作。 """ - target_message: Optional["DatabaseMessages"] = None # 获取聊天上下文 message_list_before_now = get_raw_msg_before_timestamp_with_chat( @@ -276,7 +279,7 @@ class ActionPlanner: ) # 调用LLM获取决策 - actions = await self._execute_main_planner( + reasoning, actions = await self._execute_main_planner( prompt=prompt, message_id_list=message_id_list, filtered_actions=filtered_actions, @@ -284,12 +287,22 @@ class ActionPlanner: loop_start_time=loop_start_time, ) - # 获取target_message(如果有非no_action的动作) - non_no_actions = [a for a in actions if a.action_type != "no_reply"] - if non_no_actions: - target_message = non_no_actions[0].action_message + self.add_plan_log(reasoning, actions) + + return actions + + def add_plan_log(self, reasoning: str, actions: List[ActionPlannerInfo]): + self.plan_log.append((reasoning, time.time(), actions)) + if len(self.plan_log) > 100: + self.plan_log.pop(0) + + def get_plan_log_str(self) -> str: + plan_log_str = "" + for reasoning, time, actions in self.plan_log: + time = datetime.fromtimestamp(time).strftime("%H:%M:%S") + plan_log_str += f"{time}:{reasoning}|使用了{','.join([action.action_type for action in actions])}\n" + return plan_log_str - return actions, target_message async def build_planner_prompt( self, @@ -302,18 +315,8 @@ class ActionPlanner: ) -> tuple[str, List[Tuple[str, "DatabaseMessages"]]]: """构建 Planner LLM 的提示词 (获取模板并填充数据)""" try: - # 获取最近执行过的动作 - actions_before_now = get_actions_by_timestamp_with_chat( - chat_id=self.chat_id, - timestamp_start=time.time() - 600, - timestamp_end=time.time(), - limit=6, - ) - actions_before_now_block = build_readable_actions(actions=actions_before_now) - if actions_before_now_block: - actions_before_now_block = f"你刚刚选择并执行过的action是:\n{actions_before_now_block}" - else: - actions_before_now_block = "" + + actions_before_now_block=self.get_plan_log_str() # 构建聊天上下文描述 chat_context_description = "你现在正在一个群聊中" @@ -447,7 +450,7 @@ class ActionPlanner: filtered_actions: Dict[str, ActionInfo], available_actions: Dict[str, ActionInfo], loop_start_time: float, - ) -> List[ActionPlannerInfo]: + ) -> Tuple[str,List[ActionPlannerInfo]]: """执行主规划器""" llm_content = None actions: List[ActionPlannerInfo] = [] @@ -456,8 +459,8 @@ class ActionPlanner: # 调用LLM llm_content, (reasoning_content, _, _) = await self.planner_llm.generate_response_async(prompt=prompt) - # logger.info(f"{self.log_prefix}规划器原始提示词: {prompt}") - # logger.info(f"{self.log_prefix}规划器原始响应: {llm_content}") + logger.info(f"{self.log_prefix}规划器原始提示词: {prompt}") + logger.info(f"{self.log_prefix}规划器原始响应: {llm_content}") if global_config.debug.show_prompt: logger.info(f"{self.log_prefix}规划器原始提示词: {prompt}") @@ -472,7 +475,7 @@ class ActionPlanner: except Exception as req_e: logger.error(f"{self.log_prefix}LLM 请求执行失败: {req_e}") - return [ + return f"LLM 请求失败,模型出现问题: {req_e}",[ ActionPlannerInfo( action_type="no_reply", reasoning=f"LLM 请求失败,模型出现问题: {req_e}", @@ -485,11 +488,12 @@ class ActionPlanner: # 解析LLM响应 if llm_content: try: - if json_objects := self._extract_json_from_markdown(llm_content): + json_objects, extracted_reasoning = self._extract_json_from_markdown(llm_content) + if json_objects: logger.debug(f"{self.log_prefix}从响应中提取到{len(json_objects)}个JSON对象") filtered_actions_list = list(filtered_actions.items()) for json_obj in json_objects: - actions.extend(self._parse_single_action(json_obj, message_id_list, filtered_actions_list)) + actions.extend(self._parse_single_action(json_obj, message_id_list, filtered_actions_list, extracted_reasoning)) else: # 尝试解析为直接的JSON logger.warning(f"{self.log_prefix}LLM没有返回可用动作: {llm_content}") @@ -502,17 +506,17 @@ class ActionPlanner: else: actions = self._create_no_reply("规划器没有获得LLM响应", available_actions) - # 添加循环开始时间到所有非no_action动作 + # 添加循环开始时间到所有非no_reply动作 for action in actions: action.action_data = action.action_data or {} action.action_data["loop_start_time"] = loop_start_time logger.debug(f"{self.log_prefix}规划器选择了{len(actions)}个动作: {' '.join([a.action_type for a in actions])}") - return actions + return extracted_reasoning,actions def _create_no_reply(self, reasoning: str, available_actions: Dict[str, ActionInfo]) -> List[ActionPlannerInfo]: - """创建no_action""" + """创建no_reply""" return [ ActionPlannerInfo( action_type="no_reply", @@ -523,15 +527,26 @@ class ActionPlanner: ) ] - def _extract_json_from_markdown(self, content: str) -> List[dict]: + def _extract_json_from_markdown(self, content: str) -> Tuple[List[dict], str]: # sourcery skip: for-append-to-extend - """从Markdown格式的内容中提取JSON对象""" + """从Markdown格式的内容中提取JSON对象和推理内容""" json_objects = [] + reasoning_content = "" # 使用正则表达式查找```json包裹的JSON内容 json_pattern = r"```json\s*(.*?)\s*```" matches = re.findall(json_pattern, content, re.DOTALL) + # 提取JSON之前的内容作为推理文本 + if matches: + # 找到第一个```json的位置 + first_json_pos = content.find("```json") + if first_json_pos > 0: + reasoning_content = content[:first_json_pos].strip() + # 清理推理内容中的注释标记 + reasoning_content = re.sub(r"^//\s*", "", reasoning_content, flags=re.MULTILINE) + reasoning_content = reasoning_content.strip() + for match in matches: try: # 清理可能的注释和格式问题 @@ -549,7 +564,7 @@ class ActionPlanner: logger.warning(f"解析JSON块失败: {e}, 块内容: {match[:100]}...") continue - return json_objects + return json_objects, reasoning_content init_prompt() diff --git a/src/chat/utils/chat_message_builder.py b/src/chat/utils/chat_message_builder.py index 89c84001..31d40e74 100644 --- a/src/chat/utils/chat_message_builder.py +++ b/src/chat/utils/chat_message_builder.py @@ -216,6 +216,7 @@ def get_actions_by_timestamp_with_chat( chat_id=action.chat_id, chat_info_stream_id=action.chat_info_stream_id, chat_info_platform=action.chat_info_platform, + action_reasoning=action.action_reasoning, ) for action in actions ] @@ -559,14 +560,12 @@ def build_readable_actions(actions: List[DatabaseActionRecords], mode: str = "re output_lines = [] current_time = time.time() - # The get functions return actions sorted ascending by time. Let's reverse it to show newest first. - # sorted_actions = sorted(actions, key=lambda x: x.get("time", 0), reverse=True) for action in actions: action_time = action.time or current_time action_name = action.action_name or "未知动作" # action_reason = action.get(action_data") - if action_name in ["no_action", "no_action"]: + if action_name in ["no_reply", "no_reply"]: continue action_prompt_display = action.action_prompt_display or "无具体内容" @@ -588,6 +587,7 @@ def build_readable_actions(actions: List[DatabaseActionRecords], mode: str = "re line = f"{time_ago_str},你使用了“{action_name}”,具体内容是:“{action_prompt_display}”" output_lines.append(line) + return "\n".join(output_lines) diff --git a/src/common/data_models/database_data_model.py b/src/common/data_models/database_data_model.py index 18465b00..8b2e94c3 100644 --- a/src/common/data_models/database_data_model.py +++ b/src/common/data_models/database_data_model.py @@ -220,6 +220,7 @@ class DatabaseActionRecords(BaseDataModel): chat_id: str, chat_info_stream_id: str, chat_info_platform: str, + action_reasoning:str ): self.action_id = action_id self.time = time @@ -234,3 +235,4 @@ class DatabaseActionRecords(BaseDataModel): self.chat_id = chat_id self.chat_info_stream_id = chat_info_stream_id self.chat_info_platform = chat_info_platform + self.action_reasoning = action_reasoning \ No newline at end of file diff --git a/src/common/data_models/info_data_model.py b/src/common/data_models/info_data_model.py index 156f021c..24cbc640 100644 --- a/src/common/data_models/info_data_model.py +++ b/src/common/data_models/info_data_model.py @@ -24,3 +24,4 @@ class ActionPlannerInfo(BaseDataModel): action_message: Optional["DatabaseMessages"] = None available_actions: Optional[Dict[str, "ActionInfo"]] = None loop_start_time: Optional[float] = None + action_reasoning: Optional[str] = None diff --git a/src/common/database/database_model.py b/src/common/database/database_model.py index d3704890..de8eb950 100644 --- a/src/common/database/database_model.py +++ b/src/common/database/database_model.py @@ -185,6 +185,8 @@ class ActionRecords(BaseModel): action_id = TextField(index=True) # 消息 ID (更改自 IntegerField) time = DoubleField() # 消息时间戳 + action_reasoning = TextField(null=True) + action_name = TextField() action_data = TextField() action_done = BooleanField(default=False) diff --git a/src/common/logger.py b/src/common/logger.py index df042b4f..86c39f75 100644 --- a/src/common/logger.py +++ b/src/common/logger.py @@ -406,7 +406,7 @@ MODULE_COLORS = { "tts_action": "\033[38;5;58m", # 深黄色 "doubao_pic_plugin": "\033[38;5;64m", # 深绿色 # Action组件 - "no_action_action": "\033[38;5;214m", # 亮橙色,显眼但不像警告 + "no_reply_action": "\033[38;5;214m", # 亮橙色,显眼但不像警告 "reply_action": "\033[38;5;46m", # 亮绿色 "base_action": "\033[38;5;250m", # 浅灰色 # 数据库和消息 diff --git a/src/plugin_system/apis/database_api.py b/src/plugin_system/apis/database_api.py index be087914..bb96aeb3 100644 --- a/src/plugin_system/apis/database_api.py +++ b/src/plugin_system/apis/database_api.py @@ -309,6 +309,7 @@ async def store_action_info( thinking_id: str = "", action_data: Optional[dict] = None, action_name: str = "", + action_reasoning: str = "", ) -> Optional[Dict[str, Any]]: """存储动作信息到数据库 @@ -322,7 +323,7 @@ async def store_action_info( thinking_id: 关联的思考ID action_data: 动作数据字典 action_name: 动作名称 - + action_reasoning: 动作执行理由 Returns: Dict[str, Any]: 保存的记录数据 None: 如果保存失败 @@ -348,6 +349,7 @@ async def store_action_info( "action_name": action_name, "action_data": json.dumps(action_data or {}, ensure_ascii=False), "action_done": action_done, + "action_reasoning": action_reasoning, "action_build_into_prompt": action_build_into_prompt, "action_prompt_display": action_prompt_display, } diff --git a/src/plugin_system/base/base_action.py b/src/plugin_system/base/base_action.py index e48181e2..61036748 100644 --- a/src/plugin_system/base/base_action.py +++ b/src/plugin_system/base/base_action.py @@ -34,11 +34,10 @@ class BaseAction(ABC): def __init__( self, action_data: dict, - reasoning: str, + action_reasoning: str, cycle_timers: dict, thinking_id: str, chat_stream: ChatStream, - log_prefix: str = "", plugin_config: Optional[dict] = None, action_message: Optional["DatabaseMessages"] = None, **kwargs, @@ -60,10 +59,11 @@ class BaseAction(ABC): if plugin_config is None: plugin_config = {} self.action_data = action_data - self.reasoning = reasoning + self.reasoning = "" self.cycle_timers = cycle_timers self.thinking_id = thinking_id - self.log_prefix = log_prefix + + self.action_reasoning = action_reasoning self.plugin_config = plugin_config or {} """对应的插件配置""" @@ -76,14 +76,6 @@ class BaseAction(ABC): self.action_parameters: dict = getattr(self.__class__, "action_parameters", {}).copy() self.action_require: list[str] = getattr(self.__class__, "action_require", []).copy() - # 设置激活类型实例属性(从类属性复制,提供默认值) - self.focus_activation_type = getattr( - self.__class__, "focus_activation_type", ActionActivationType.ALWAYS - ) # 已弃用 - """FOCUS模式下的激活类型""" - self.normal_activation_type = getattr( - self.__class__, "normal_activation_type", ActionActivationType.ALWAYS - ) # 已弃用 """NORMAL模式下的激活类型""" self.activation_type = getattr(self.__class__, "activation_type", self.focus_activation_type) """激活类型""" @@ -115,44 +107,32 @@ class BaseAction(ABC): self.user_nickname = None self.is_group = False self.target_id = None - self.has_action_message = False - if self.action_message: - self.has_action_message = True - if self.action_name != "no_action": - self.group_id = ( - str(self.action_message.chat_info.group_info.group_id) - if self.action_message.chat_info.group_info - else None - ) - self.group_name = ( - self.action_message.chat_info.group_info.group_name - if self.action_message.chat_info.group_info - else None - ) + self.group_id = ( + str(self.action_message.chat_info.group_info.group_id) + if self.action_message.chat_info.group_info + else None + ) + self.group_name = ( + self.action_message.chat_info.group_info.group_name + if self.action_message.chat_info.group_info + else None + ) + + self.user_id = str(self.action_message.user_info.user_id) + self.user_nickname = self.action_message.user_info.user_nickname + + if self.group_id: + self.is_group = True + self.target_id = self.group_id + self.log_prefix = f"[{self.group_name}]" + else: + self.is_group = False + self.target_id = self.user_id + self.log_prefix = f"[{self.user_nickname} 的 私聊]" - self.user_id = str(self.action_message.user_info.user_id) - self.user_nickname = self.action_message.user_info.user_nickname - if self.group_id: - self.is_group = True - self.target_id = self.group_id - else: - self.is_group = False - self.target_id = self.user_id - else: - if self.chat_stream.group_info: - self.group_id = self.chat_stream.group_info.group_id - self.group_name = self.chat_stream.group_info.group_name - self.is_group = True - self.target_id = self.group_id - else: - self.user_id = self.chat_stream.user_info.user_id - self.user_nickname = self.chat_stream.user_info.user_nickname - self.is_group = False - self.target_id = self.user_id - logger.debug(f"{self.log_prefix} Action组件初始化完成") logger.debug( f"{self.log_prefix} 聊天信息: 类型={'群聊' if self.is_group else '私聊'}, 平台={self.platform}, 目标={self.target_id}" ) @@ -441,6 +421,7 @@ class BaseAction(ABC): thinking_id=self.thinking_id, action_data=self.action_data, action_name=self.action_name, + action_reasoning=self.action_reasoning, ) async def wait_for_new_message(self, timeout: int = 1200) -> Tuple[bool, str]: @@ -467,11 +448,6 @@ class BaseAction(ABC): wait_start_time = asyncio.get_event_loop().time() while True: - # 检查关闭标志 - # shutting_down = self.get_action_context("shutting_down", False) - # if shutting_down: - # logger.info(f"{self.log_prefix} 等待新消息时检测到关闭信号,中断等待") - # return False, "" # 检查新消息 current_time = time.time() @@ -530,8 +506,6 @@ class BaseAction(ABC): name=name, component_type=ComponentType.ACTION, description=getattr(cls, "action_description", "Action动作"), - focus_activation_type=focus_activation_type, - normal_activation_type=normal_activation_type, activation_type=activation_type, activation_keywords=getattr(cls, "activation_keywords", []).copy(), keyword_case_sensitive=getattr(cls, "keyword_case_sensitive", False), diff --git a/src/plugins/built_in/MaiCurious/plugin.py b/src/plugins/built_in/MaiCurious/plugin.py index 891b3c67..901d8de5 100644 --- a/src/plugins/built_in/MaiCurious/plugin.py +++ b/src/plugins/built_in/MaiCurious/plugin.py @@ -35,7 +35,7 @@ class CuriousAction(BaseAction): # 动作参数定义 action_parameters = { - "question": "对存在疑问的信息提出一个问题,描述全面,使用无人称陈述句", + "question": "对存在疑问的信息提出一个问题,描述全面", } # 动作使用场景 @@ -64,7 +64,7 @@ class CuriousAction(BaseAction): logger.info(f"已存储问题到冲突追踪器: {question}") await self.store_action_info( action_build_into_prompt=True, - action_prompt_display=f"你产生了一个问题:{question},尝试向其他人提问或回忆吧", + action_prompt_display=f"你产生了一个问题:{question},尝试向其他人提问或回忆", action_done=True, ) return True, "问题已记录" diff --git a/src/plugins/built_in/emoji_plugin/plugin.py b/src/plugins/built_in/emoji_plugin/plugin.py index b7afc522..98b1e01a 100644 --- a/src/plugins/built_in/emoji_plugin/plugin.py +++ b/src/plugins/built_in/emoji_plugin/plugin.py @@ -1,7 +1,7 @@ """ 核心动作插件 -将系统核心动作(reply、no_action、emoji)转换为新插件系统格式 +将系统核心动作(reply、no_reply、emoji)转换为新插件系统格式 这是系统的内置插件,提供基础的聊天交互功能 """ diff --git a/src/plugins/built_in/memory/plugin.py b/src/plugins/built_in/memory/plugin.py index 3258ebb2..c3045fdc 100644 --- a/src/plugins/built_in/memory/plugin.py +++ b/src/plugins/built_in/memory/plugin.py @@ -48,7 +48,7 @@ class MemoryBuildPlugin(BasePlugin): # --- 根据配置注册组件 --- components = [] - components.append((GetMemoryAction.get_action_info(), GetMemoryAction)) + # components.append((GetMemoryAction.get_action_info(), GetMemoryAction)) components.append((GetMemoryTool.get_tool_info(), GetMemoryTool)) return components diff --git a/template/bot_config_template.toml b/template/bot_config_template.toml index e046fdb4..81ef5447 100644 --- a/template/bot_config_template.toml +++ b/template/bot_config_template.toml @@ -1,5 +1,5 @@ [inner] -version = "6.18.0" +version = "6.18.1" #----以下是给开发人员阅读的,如果你只是部署了麦麦,不需要阅读---- #如果你想要修改配置文件,请递增version的值 @@ -28,7 +28,7 @@ reply_style = "请回复的平淡一些,简短一些,说中文,不要刻 interest = "对技术相关话题,游戏和动漫相关话题感兴趣,也对日常话题感兴趣,不喜欢太过沉重严肃的话题" # 麦麦的说话规则,行为风格: -plan_style = """请你根据聊天内容,用户的最新消息和以下标准选择合适的动作: +plan_style = """ 1.思考**所有**的可用的action中的**每个动作**是否符合当下条件,如果动作使用条件符合聊天内容就使用 2.如果相同的内容已经被执行,请不要重复执行 3.请控制你的发言频率,不要太过频繁的发言 @@ -40,7 +40,7 @@ visual_style = "请用中文描述这张图片的内容。如果有文字,请 # 麦麦私聊的说话规则,行为风格: -private_plan_style = """请你根据聊天内容,用户的最新消息和以下标准选择合适的动作: +private_plan_style = """ 1.思考**所有**的可用的action中的**每个动作**是否符合当下条件,如果动作使用条件符合聊天内容就使用 2.如果相同的内容已经被执行,请不要重复执行 3.某句话如果已经被回复过,不要重复回复"""