From a0e4d5ea385b192b64f755aff02d62fbca076393 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A2=A8=E6=A2=93=E6=9F=92?= <1787882683@qq.com> Date: Thu, 10 Apr 2025 22:31:22 +0800 Subject: [PATCH 1/7] =?UTF-8?q?=E6=9B=B4=E6=96=B0README=EF=BC=8C=E5=92=8CD?= =?UTF-8?q?ev=E5=88=86=E6=94=AF=E4=BF=9D=E6=8C=81=E4=B8=80=E8=87=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 325e3ad22..beea5757f 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@
- ![Python Version](https://img.shields.io/badge/Python-3.10+-blue) + ![Python Version](https://img.shields.io/badge/Python-3.9+-blue) ![License](https://img.shields.io/github/license/SengokuCola/MaiMBot?label=协议) ![Status](https://img.shields.io/badge/状态-开发中-yellow) ![Contributors](https://img.shields.io/github/contributors/MaiM-with-u/MaiBot.svg?style=flat&label=贡献者) @@ -37,7 +37,7 @@

-## 新版0.6.x部署前先阅读:https://docs.mai-mai.org/manual/usage/mmc_q_a +## 新版0.6.0部署前先阅读:https://docs.mai-mai.org/manual/usage/mmc_q_a ## 📝 项目简介 @@ -60,6 +60,23 @@
+### 📢 版本信息 + +- 💭 **智能对话系统**:基于LLM的自然语言交互 +- 🤔 **实时思维系统**:模拟人类思考过程 +- 💝 **情感表达系统**:丰富的表情包和情绪表达 +- 🧠 **持久记忆系统**:基于MongoDB的长期记忆存储 +- 🔄 **动态人格系统**:自适应的性格特征 + +
+ + 麦麦演示视频 +
+ 👆 点击观看麦麦演示视频 👆 +
+
+ + ### 📢 版本信息 **最新版本: v0.6.2** ([查看更新日志](changelogs/changelog.md)) @@ -86,7 +103,7 @@ ### ⚠️ 重要提示 -- 升级到v0.6.x版本前请务必阅读:[升级指南](https://docs.mai-mai.org/manual/usage/mmc_q_a) +- 升级到v0.6.0版本前请务必阅读:[升级指南](https://docs.mai-mai.org/manual/usage/mmc_q_a) - 本版本基于MaiCore重构,通过nonebot插件与QQ平台交互 - 项目处于活跃开发阶段,功能和API可能随时调整 @@ -115,22 +132,21 @@ | 模块 | 主要功能 | 特点 | |------|---------|------| -| 💬 聊天系统 | • 心流/推理聊天
• 关键词主动发言
• 多模型支持
• 动态prompt构建
• 私聊功能(PFC) | 拟人化交互 | -| 🧠 心流系统 | • 实时思考生成
• 自动启停机制
• 日程系统联动
• 工具调用能力 | 智能化决策 | -| 🧠 记忆系统 | • 优化记忆抽取
• 海马体记忆机制
• 聊天记录概括 | 持久化记忆 | -| 😊 表情系统 | • 情绪匹配发送
• GIF支持
• 自动收集与审查 | 丰富表达 | +| 💬 聊天系统 | • 思维流/推理聊天
• 关键词主动发言
• 多模型支持
• 动态prompt构建
• 私聊功能(PFC) | 拟人化交互 | +| 🧠 思维流系统 | • 实时思考生成
• 自动启停机制
• 日程系统联动 | 智能化决策 | +| 🧠 记忆系统 2.0 | • 优化记忆抽取
• 海马体记忆机制
• 聊天记录概括 | 持久化记忆 | +| 😊 表情包系统 | • 情绪匹配发送
• GIF支持
• 自动收集与审查 | 丰富表达 | | 📅 日程系统 | • 动态日程生成
• 自定义想象力
• 思维流联动 | 智能规划 | -| 👥 关系系统 | • 关系管理优化
• 丰富接口支持
• 个性化交互 | 深度社交 | +| 👥 关系系统 2.0 | • 关系管理优化
• 丰富接口支持
• 个性化交互 | 深度社交 | | 📊 统计系统 | • 使用数据统计
• LLM调用记录
• 实时控制台显示 | 数据可视 | | 🔧 系统功能 | • 优雅关闭机制
• 自动数据保存
• 异常处理完善 | 稳定可靠 | -| 🛠️ 工具系统 | • 知识获取工具
• 自动注册机制
• 多工具支持 | 扩展功能 | ## 📐 项目架构 ```mermaid graph TD A[MaiCore] --> B[对话系统] - A --> C[心流系统] + A --> C[思维流系统] A --> D[记忆系统] A --> E[情感系统] B --> F[多模型支持] From 3a04e8a6ba295f33f8459760681cb36cf044087d Mon Sep 17 00:00:00 2001 From: Ark-Hakobune Date: Tue, 15 Apr 2025 21:58:20 +0800 Subject: [PATCH 2/7] =?UTF-8?q?=E7=A7=BB=E9=99=A4=20maim=5Fmessage=20?= =?UTF-8?q?=E7=9B=AE=E5=BD=95=E8=B7=9F=E8=B8=AA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plugins/willing/mode_llmcheck.py | 164 +++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 src/plugins/willing/mode_llmcheck.py diff --git a/src/plugins/willing/mode_llmcheck.py b/src/plugins/willing/mode_llmcheck.py new file mode 100644 index 000000000..62a8cedba --- /dev/null +++ b/src/plugins/willing/mode_llmcheck.py @@ -0,0 +1,164 @@ +import time +from loguru import logger +from ..schedule.schedule_generator import bot_schedule +from ..models.utils_model import LLM_request + +from ..config.config import global_config +from ..chat.chat_stream import ChatStream +from .mode_classical import WillingManager +from ..chat.utils import get_recent_group_detailed_plain_text + + +import re +from src.common.logger import get_module_logger, CHAT_STYLE_CONFIG, LogConfig + +# 定义日志配置 +chat_config = LogConfig( + # 使用消息发送专用样式 + console_format=CHAT_STYLE_CONFIG["console_format"], + file_format=CHAT_STYLE_CONFIG["file_format"], +) + +# 配置主程序日志格式 +logger = get_module_logger("llm_willing", config=chat_config) + +class WillingManager_llm(WillingManager): + + def __init__(self): + super().__init__() + self.model_v3 = LLM_request(model=global_config.llm_normal, temperature=0.3) + + async def change_reply_willing_received(self, chat_stream: ChatStream, is_mentioned_bot: bool = False, config=None, + is_emoji: bool = False, interested_rate: float = 0, sender_id: str = None, + **kwargs) -> float: + stream_id = chat_stream.stream_id + if chat_stream.group_info and config: + if chat_stream.group_info.group_id not in config.talk_allowed_groups: + reply_probability = 0 + return reply_probability + + current_date = time.strftime("%Y-%m-%d", time.localtime()) + current_time = time.strftime("%H:%M:%S", time.localtime()) + bot_schedule_now_time, bot_schedule_now_activity = bot_schedule.get_current_task() + + chat_in_group = True + chat_talking_prompt = "" + if stream_id: + chat_talking_prompt = get_recent_group_detailed_plain_text( + stream_id, limit=5, combine=True + ) + if chat_stream.group_info: + if str(config.BOT_QQ) in chat_talking_prompt: + pass + # logger.info(f"{chat_talking_prompt}") + # logger.info(f"bot在群聊中5条内发过言,启动llm计算回复概率") + else: + return self.default_change_reply_willing_received( + chat_stream=chat_stream, + is_mentioned_bot=is_mentioned_bot, + config=config, + is_emoji=is_emoji, + interested_rate=interested_rate, + sender_id=sender_id, + ) + else: + chat_in_group = False + chat_talking_prompt = chat_talking_prompt + # print(f"\033[1;34m[调试]\033[0m 已从数据库获取群 {group_id} 的消息记录:{chat_talking_prompt}") + + # if is_mentioned_bot: + # return 1.0 + prompt = f""" + 假设你正在查看一个群聊,你在这个群聊里的网名叫{global_config.BOT_NICKNAME},你还有很多别名: {"/".join(global_config.BOT_ALIAS_NAMES)}, + 现在群里聊天的内容是{chat_talking_prompt}, + 今天是{current_date},现在是{current_time},你现在正在{bot_schedule_now_activity}。 + 综合群内的氛围和你自己之前的发言,给出你认为**最新的消息**需要你回复的概率,数值在0到1之间。请注意,群聊内容杂乱,很多时候对话连续,但很可能不是在和你说话。 + 如果最新的消息和你之前的发言在内容上连续,或者提到了你的名字或者称谓,将其视作明确指向你的互动,给出高于0.8的概率。如果现在是睡眠时间,直接概率为0。如果话题内容与你之前不是紧密相关,请不要给出高于0.1的概率。 + 请注意是判断概率,而不是编写回复内容, + 仅输出在0到1区间内的概率值,不要给出你的判断依据。 + """ + + # 非群聊的意愿管理 未来可能可以用对话缓冲区来确定合适的回复时机 + if not chat_in_group: + prompt = f""" + 假设你在和网友聊天,网名叫{global_config.BOT_NICKNAME},你还有很多别名: {"/".join(global_config.BOT_ALIAS_NAMES)}, + 现在你和朋友私聊的内容是{chat_talking_prompt}, + 今天是{current_date},现在是{current_time},你现在正在{bot_schedule_now_activity}。 + 综合以上的内容,给出你认为最新的消息是在和你交流的概率,数值在0到1之间。如果现在是个人休息时间,直接概率为0,请注意是决定是否需要发言,而不是编写回复内容, + 仅输出在0到1区间内的概率值,不要给出你的判断依据。 + """ + content_check, reasoning_check, _ = await self.model_v3.generate_response(prompt) + # logger.info(f"{prompt}") + logger.info(f"{content_check} {reasoning_check}") + probability = self.extract_marked_probability(content_check) + if probability <= 0.1: + probability = min(0.03, probability) + if probability >= 0.8: + probability = max(probability, 0.90) + # 兴趣系数修正 无关激活效率太高,暂时停用,待新记忆系统上线后调整 + # probability += (interested_rate * 0.25) + # probability = min(1.0, probability) + # 当前表情包理解能力较差,少说就少错 + if is_emoji: + probability *= 0.1 + + return probability + + @staticmethod + def extract_marked_probability(text): + """提取带标记的概率值 该方法主要用于测试微调prompt阶段""" + text = text.strip() + pattern = r'##PROBABILITY_START##(.*?)##PROBABILITY_END##' + match = re.search(pattern, text, re.DOTALL) + if match: + prob_str = match.group(1).strip() + # 处理百分比(65% → 0.65) + if '%' in prob_str: + return float(prob_str.replace('%', '')) / 100 + # 处理分数(2/3 → 0.666...) + elif '/' in prob_str: + numerator, denominator = map(float, prob_str.split('/')) + return numerator / denominator + # 直接处理小数 + else: + return float(prob_str) + + percent_match = re.search(r'(\d{1,3})%', text) # 65% + decimal_match = re.search(r'(0\.\d+|1\.0+)', text) # 0.65 + fraction_match = re.search(r'(\d+)/(\d+)', text) # 2/3 + try: + if percent_match: + prob = float(percent_match.group(1)) / 100 + elif decimal_match: + prob = float(decimal_match.group(0)) + elif fraction_match: + numerator, denominator = map(float, fraction_match.groups()) + prob = numerator / denominator + else: + return 0 # 无匹配格式 + + # 验证范围是否合法 + if 0 <= prob <= 1: + return prob + return 0 + except (ValueError, ZeroDivisionError): + return 0 + + def default_change_reply_willing_received(self, chat_stream: ChatStream, is_mentioned_bot: bool = False, config=None, + is_emoji: bool = False, interested_rate: float = 0, sender_id: str = None, + **kwargs) -> float: + + current_willing = self.chat_reply_willing.get(chat_stream.stream_id, 0) + interested_rate = interested_rate * config.response_interested_rate_amplifier + if interested_rate > 0.4: + current_willing += interested_rate - 0.3 + if is_mentioned_bot and current_willing < 1.0: + current_willing += 1 + elif is_mentioned_bot: + current_willing += 0.05 + if is_emoji: + current_willing *= 0.5 + self.chat_reply_willing[chat_stream.stream_id] = min(current_willing, 3.0) + reply_probability = min(max((current_willing - 0.5), 0.01) * config.response_willing_amplifier * 2, 1) + + return reply_probability From be3c1e167a5e73dbae8c70b7801e4c2945b03484 Mon Sep 17 00:00:00 2001 From: Ark-Hakobune Date: Mon, 14 Apr 2025 11:39:22 +0800 Subject: [PATCH 3/7] =?UTF-8?q?=E5=AE=8C=E6=88=90Maicore=E9=80=82=E9=85=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker-compose.yml | 28 ++++++++++++++++++++++++++++ src/plugins/willing/mode_llmcheck.py | 15 +++++++-------- 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 000d00c35..807114674 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -25,9 +25,37 @@ services: # ports: # - "8000:8000" volumes: +<<<<<<< HEAD - ./docker-config/mmc/.env:/MaiMBot/.env # 持久化env配置文件 - ./docker-config/mmc:/MaiMBot/config # 持久化bot配置文件 - ./data/MaiMBot:/MaiMBot/data # NapCat 和 NoneBot 共享此卷,否则发送图片会有问题 +======= + - ./config_ai/.env:/MaiMBot/.env # 持久化env配置文件 + - ./config_ai:/MaiMBot/config # 持久化bot配置文件 + - ./data_ai:/MaiMBot/data # NapCat 和 NoneBot 共享此卷,否则发送图片会有问题 + - ./src:/MaiMBot/src + restart: always + depends_on: + - mongodb + networks: + - maim_bot + + core_reimu: + container_name: reimu + image: mmc:local + # image: infinitycat/maimbot:main + environment: + - TZ=Asia/Shanghai + - EULA_AGREE=35362b6ea30f12891d46ef545122e84a # 同意EULA + - PRIVACY_AGREE=2402af06e133d2d10d9c6c643fdc9333 # 同意EULA + # ports: + # - "8001:8000" + volumes: + - ./config_reimu/.env:/MaiMBot/.env # 持久化env配置文件 + - ./config_reimu:/MaiMBot/config # 持久化bot配置文件 + - ./data_reimu/MaiMBot:/MaiMBot/data # NapCat 和 NoneBot 共享此卷,否则发送图片会有问题 + - ./src:/MaiMBot/src +>>>>>>> 7535f02 (完成Maicore适配) restart: always depends_on: - mongodb diff --git a/src/plugins/willing/mode_llmcheck.py b/src/plugins/willing/mode_llmcheck.py index 62a8cedba..6c3e135f9 100644 --- a/src/plugins/willing/mode_llmcheck.py +++ b/src/plugins/willing/mode_llmcheck.py @@ -22,7 +22,7 @@ chat_config = LogConfig( # 配置主程序日志格式 logger = get_module_logger("llm_willing", config=chat_config) -class WillingManager_llm(WillingManager): +class WillingManager(WillingManager): def __init__(self): super().__init__() @@ -39,8 +39,6 @@ class WillingManager_llm(WillingManager): current_date = time.strftime("%Y-%m-%d", time.localtime()) current_time = time.strftime("%H:%M:%S", time.localtime()) - bot_schedule_now_time, bot_schedule_now_activity = bot_schedule.get_current_task() - chat_in_group = True chat_talking_prompt = "" if stream_id: @@ -71,7 +69,7 @@ class WillingManager_llm(WillingManager): prompt = f""" 假设你正在查看一个群聊,你在这个群聊里的网名叫{global_config.BOT_NICKNAME},你还有很多别名: {"/".join(global_config.BOT_ALIAS_NAMES)}, 现在群里聊天的内容是{chat_talking_prompt}, - 今天是{current_date},现在是{current_time},你现在正在{bot_schedule_now_activity}。 + 今天是{current_date},现在是{current_time}。 综合群内的氛围和你自己之前的发言,给出你认为**最新的消息**需要你回复的概率,数值在0到1之间。请注意,群聊内容杂乱,很多时候对话连续,但很可能不是在和你说话。 如果最新的消息和你之前的发言在内容上连续,或者提到了你的名字或者称谓,将其视作明确指向你的互动,给出高于0.8的概率。如果现在是睡眠时间,直接概率为0。如果话题内容与你之前不是紧密相关,请不要给出高于0.1的概率。 请注意是判断概率,而不是编写回复内容, @@ -83,7 +81,7 @@ class WillingManager_llm(WillingManager): prompt = f""" 假设你在和网友聊天,网名叫{global_config.BOT_NICKNAME},你还有很多别名: {"/".join(global_config.BOT_ALIAS_NAMES)}, 现在你和朋友私聊的内容是{chat_talking_prompt}, - 今天是{current_date},现在是{current_time},你现在正在{bot_schedule_now_activity}。 + 今天是{current_date},现在是{current_time}。 综合以上的内容,给出你认为最新的消息是在和你交流的概率,数值在0到1之间。如果现在是个人休息时间,直接概率为0,请注意是决定是否需要发言,而不是编写回复内容, 仅输出在0到1区间内的概率值,不要给出你的判断依据。 """ @@ -91,13 +89,14 @@ class WillingManager_llm(WillingManager): # logger.info(f"{prompt}") logger.info(f"{content_check} {reasoning_check}") probability = self.extract_marked_probability(content_check) + # 兴趣系数修正 无关激活效率太高,暂时停用,待新记忆系统上线后调整 + probability += (interested_rate * 0.25) + probability = min(1.0, probability) if probability <= 0.1: probability = min(0.03, probability) if probability >= 0.8: probability = max(probability, 0.90) - # 兴趣系数修正 无关激活效率太高,暂时停用,待新记忆系统上线后调整 - # probability += (interested_rate * 0.25) - # probability = min(1.0, probability) + # 当前表情包理解能力较差,少说就少错 if is_emoji: probability *= 0.1 From 9dc4c4f5ac774e0183dfcf008dc6c453c257a827 Mon Sep 17 00:00:00 2001 From: Ark-Hakobune Date: Tue, 15 Apr 2025 22:13:18 +0800 Subject: [PATCH 4/7] =?UTF-8?q?chore:=20=E5=90=8C=E6=AD=A5=E4=B8=8A?= =?UTF-8?q?=E6=B8=B8=20README=20=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 36 ++++++++++-------------------------- 1 file changed, 10 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index beea5757f..325e3ad22 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@
- ![Python Version](https://img.shields.io/badge/Python-3.9+-blue) + ![Python Version](https://img.shields.io/badge/Python-3.10+-blue) ![License](https://img.shields.io/github/license/SengokuCola/MaiMBot?label=协议) ![Status](https://img.shields.io/badge/状态-开发中-yellow) ![Contributors](https://img.shields.io/github/contributors/MaiM-with-u/MaiBot.svg?style=flat&label=贡献者) @@ -37,7 +37,7 @@

-## 新版0.6.0部署前先阅读:https://docs.mai-mai.org/manual/usage/mmc_q_a +## 新版0.6.x部署前先阅读:https://docs.mai-mai.org/manual/usage/mmc_q_a ## 📝 项目简介 @@ -60,23 +60,6 @@
-### 📢 版本信息 - -- 💭 **智能对话系统**:基于LLM的自然语言交互 -- 🤔 **实时思维系统**:模拟人类思考过程 -- 💝 **情感表达系统**:丰富的表情包和情绪表达 -- 🧠 **持久记忆系统**:基于MongoDB的长期记忆存储 -- 🔄 **动态人格系统**:自适应的性格特征 - -
- - 麦麦演示视频 -
- 👆 点击观看麦麦演示视频 👆 -
-
- - ### 📢 版本信息 **最新版本: v0.6.2** ([查看更新日志](changelogs/changelog.md)) @@ -103,7 +86,7 @@ ### ⚠️ 重要提示 -- 升级到v0.6.0版本前请务必阅读:[升级指南](https://docs.mai-mai.org/manual/usage/mmc_q_a) +- 升级到v0.6.x版本前请务必阅读:[升级指南](https://docs.mai-mai.org/manual/usage/mmc_q_a) - 本版本基于MaiCore重构,通过nonebot插件与QQ平台交互 - 项目处于活跃开发阶段,功能和API可能随时调整 @@ -132,21 +115,22 @@ | 模块 | 主要功能 | 特点 | |------|---------|------| -| 💬 聊天系统 | • 思维流/推理聊天
• 关键词主动发言
• 多模型支持
• 动态prompt构建
• 私聊功能(PFC) | 拟人化交互 | -| 🧠 思维流系统 | • 实时思考生成
• 自动启停机制
• 日程系统联动 | 智能化决策 | -| 🧠 记忆系统 2.0 | • 优化记忆抽取
• 海马体记忆机制
• 聊天记录概括 | 持久化记忆 | -| 😊 表情包系统 | • 情绪匹配发送
• GIF支持
• 自动收集与审查 | 丰富表达 | +| 💬 聊天系统 | • 心流/推理聊天
• 关键词主动发言
• 多模型支持
• 动态prompt构建
• 私聊功能(PFC) | 拟人化交互 | +| 🧠 心流系统 | • 实时思考生成
• 自动启停机制
• 日程系统联动
• 工具调用能力 | 智能化决策 | +| 🧠 记忆系统 | • 优化记忆抽取
• 海马体记忆机制
• 聊天记录概括 | 持久化记忆 | +| 😊 表情系统 | • 情绪匹配发送
• GIF支持
• 自动收集与审查 | 丰富表达 | | 📅 日程系统 | • 动态日程生成
• 自定义想象力
• 思维流联动 | 智能规划 | -| 👥 关系系统 2.0 | • 关系管理优化
• 丰富接口支持
• 个性化交互 | 深度社交 | +| 👥 关系系统 | • 关系管理优化
• 丰富接口支持
• 个性化交互 | 深度社交 | | 📊 统计系统 | • 使用数据统计
• LLM调用记录
• 实时控制台显示 | 数据可视 | | 🔧 系统功能 | • 优雅关闭机制
• 自动数据保存
• 异常处理完善 | 稳定可靠 | +| 🛠️ 工具系统 | • 知识获取工具
• 自动注册机制
• 多工具支持 | 扩展功能 | ## 📐 项目架构 ```mermaid graph TD A[MaiCore] --> B[对话系统] - A --> C[思维流系统] + A --> C[心流系统] A --> D[记忆系统] A --> E[情感系统] B --> F[多模型支持] From 307f6707191d7c92b149babeedd0256b7df67f35 Mon Sep 17 00:00:00 2001 From: Ark-Hakobune Date: Tue, 15 Apr 2025 22:15:19 +0800 Subject: [PATCH 5/7] =?UTF-8?q?chore:=20=E5=90=8C=E6=AD=A5=E4=B8=8A?= =?UTF-8?q?=E6=B8=B8docker-compose=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker-compose.yml | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 807114674..000d00c35 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -25,37 +25,9 @@ services: # ports: # - "8000:8000" volumes: -<<<<<<< HEAD - ./docker-config/mmc/.env:/MaiMBot/.env # 持久化env配置文件 - ./docker-config/mmc:/MaiMBot/config # 持久化bot配置文件 - ./data/MaiMBot:/MaiMBot/data # NapCat 和 NoneBot 共享此卷,否则发送图片会有问题 -======= - - ./config_ai/.env:/MaiMBot/.env # 持久化env配置文件 - - ./config_ai:/MaiMBot/config # 持久化bot配置文件 - - ./data_ai:/MaiMBot/data # NapCat 和 NoneBot 共享此卷,否则发送图片会有问题 - - ./src:/MaiMBot/src - restart: always - depends_on: - - mongodb - networks: - - maim_bot - - core_reimu: - container_name: reimu - image: mmc:local - # image: infinitycat/maimbot:main - environment: - - TZ=Asia/Shanghai - - EULA_AGREE=35362b6ea30f12891d46ef545122e84a # 同意EULA - - PRIVACY_AGREE=2402af06e133d2d10d9c6c643fdc9333 # 同意EULA - # ports: - # - "8001:8000" - volumes: - - ./config_reimu/.env:/MaiMBot/.env # 持久化env配置文件 - - ./config_reimu:/MaiMBot/config # 持久化bot配置文件 - - ./data_reimu/MaiMBot:/MaiMBot/data # NapCat 和 NoneBot 共享此卷,否则发送图片会有问题 - - ./src:/MaiMBot/src ->>>>>>> 7535f02 (完成Maicore适配) restart: always depends_on: - mongodb From 7b261078b5877e091c8c5e396d58bf7b99d220c0 Mon Sep 17 00:00:00 2001 From: Ark-Hakobune Date: Tue, 15 Apr 2025 22:50:04 +0800 Subject: [PATCH 6/7] =?UTF-8?q?0.6.2=E7=9A=84=E6=84=8F=E6=84=BF=E6=96=87?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plugins/willing/mode_llmcheck.py | 141 +++++++++++++-------------- 1 file changed, 69 insertions(+), 72 deletions(-) diff --git a/src/plugins/willing/mode_llmcheck.py b/src/plugins/willing/mode_llmcheck.py index 6c3e135f9..4f472e87f 100644 --- a/src/plugins/willing/mode_llmcheck.py +++ b/src/plugins/willing/mode_llmcheck.py @@ -1,68 +1,87 @@ +""" +llmcheck 模式: +此模式的一些参数不会在配置文件中显示,要修改请在可变参数下修改 +此模式的特点: +1.在群聊内的连续对话场景下,使用大语言模型来判断回复概率 +2.非连续对话场景,使用mxp模式的意愿管理器(可另外配置) +3.默认配置的是model_v3,当前参数适用于deepseek-v3-0324 + +继承自其他模式,实质上仅重写get_reply_probability方法,未来可能重构成一个插件,可方便地组装到其他意愿模式上。 +目前的使用方式是拓展到其他意愿管理模式 + +""" import time from loguru import logger -from ..schedule.schedule_generator import bot_schedule from ..models.utils_model import LLM_request - from ..config.config import global_config from ..chat.chat_stream import ChatStream -from .mode_classical import WillingManager from ..chat.utils import get_recent_group_detailed_plain_text - - +from .willing_manager import BaseWillingManager +from .mode_mxp import MxpWillingManager import re -from src.common.logger import get_module_logger, CHAT_STYLE_CONFIG, LogConfig +from functools import wraps -# 定义日志配置 -chat_config = LogConfig( - # 使用消息发送专用样式 - console_format=CHAT_STYLE_CONFIG["console_format"], - file_format=CHAT_STYLE_CONFIG["file_format"], -) -# 配置主程序日志格式 -logger = get_module_logger("llm_willing", config=chat_config) +def is_continuous_chat(self, message_id: str): + # 判断是否是连续对话,出于成本考虑,默认限制5条 + willing_info = self.ongoing_messages[message_id] + chat_id = willing_info.chat_id + group_info = willing_info.chat_id + config = self.global_config + length = 5 + if chat_id: + chat_talking_text = get_recent_group_detailed_plain_text( + chat_id, limit=length, combine=True + ) + if group_info: + if str(config.BOT_QQ) in chat_talking_text: + return True + else: + return False + return False -class WillingManager(WillingManager): +def llmcheck_decorator(trigger_condition_func): + def decorator(func): + @wraps(func) + def wrapper(self, message_id: str): + if trigger_condition_func(self, message_id): + # 满足条件,走llm流程 + return self.get_llmreply_probability(message_id) + else: + # 不满足条件,走默认流程 + return func(self, message_id) + return wrapper + return decorator + + +class LlmcheckWillingManager(MxpWillingManager): def __init__(self): super().__init__() self.model_v3 = LLM_request(model=global_config.llm_normal, temperature=0.3) - async def change_reply_willing_received(self, chat_stream: ChatStream, is_mentioned_bot: bool = False, config=None, - is_emoji: bool = False, interested_rate: float = 0, sender_id: str = None, - **kwargs) -> float: - stream_id = chat_stream.stream_id - if chat_stream.group_info and config: - if chat_stream.group_info.group_id not in config.talk_allowed_groups: + + + async def get_llmreply_probability(self, message_id: str): + message_info = self.ongoing_messages[message_id] + chat_id = message_info.chat_id + config = self.global_config + # 获取信息的长度 + length = 5 + if message_info.group_info and config: + if message_info.group_info.group_id not in config.talk_allowed_groups: reply_probability = 0 return reply_probability current_date = time.strftime("%Y-%m-%d", time.localtime()) current_time = time.strftime("%H:%M:%S", time.localtime()) - chat_in_group = True chat_talking_prompt = "" - if stream_id: + if chat_id: chat_talking_prompt = get_recent_group_detailed_plain_text( - stream_id, limit=5, combine=True + chat_id, limit=length, combine=True ) - if chat_stream.group_info: - if str(config.BOT_QQ) in chat_talking_prompt: - pass - # logger.info(f"{chat_talking_prompt}") - # logger.info(f"bot在群聊中5条内发过言,启动llm计算回复概率") - else: - return self.default_change_reply_willing_received( - chat_stream=chat_stream, - is_mentioned_bot=is_mentioned_bot, - config=config, - is_emoji=is_emoji, - interested_rate=interested_rate, - sender_id=sender_id, - ) - else: - chat_in_group = False - chat_talking_prompt = chat_talking_prompt - # print(f"\033[1;34m[调试]\033[0m 已从数据库获取群 {group_id} 的消息记录:{chat_talking_prompt}") + else: + return 0 # if is_mentioned_bot: # return 1.0 @@ -76,21 +95,12 @@ class WillingManager(WillingManager): 仅输出在0到1区间内的概率值,不要给出你的判断依据。 """ - # 非群聊的意愿管理 未来可能可以用对话缓冲区来确定合适的回复时机 - if not chat_in_group: - prompt = f""" - 假设你在和网友聊天,网名叫{global_config.BOT_NICKNAME},你还有很多别名: {"/".join(global_config.BOT_ALIAS_NAMES)}, - 现在你和朋友私聊的内容是{chat_talking_prompt}, - 今天是{current_date},现在是{current_time}。 - 综合以上的内容,给出你认为最新的消息是在和你交流的概率,数值在0到1之间。如果现在是个人休息时间,直接概率为0,请注意是决定是否需要发言,而不是编写回复内容, - 仅输出在0到1区间内的概率值,不要给出你的判断依据。 - """ content_check, reasoning_check, _ = await self.model_v3.generate_response(prompt) # logger.info(f"{prompt}") logger.info(f"{content_check} {reasoning_check}") probability = self.extract_marked_probability(content_check) # 兴趣系数修正 无关激活效率太高,暂时停用,待新记忆系统上线后调整 - probability += (interested_rate * 0.25) + probability += (message_info.interested_rate * 0.25) probability = min(1.0, probability) if probability <= 0.1: probability = min(0.03, probability) @@ -98,8 +108,8 @@ class WillingManager(WillingManager): probability = max(probability, 0.90) # 当前表情包理解能力较差,少说就少错 - if is_emoji: - probability *= 0.1 + if message_info.is_emoji: + probability *= global_config.emoji_response_penalty return probability @@ -143,21 +153,8 @@ class WillingManager(WillingManager): except (ValueError, ZeroDivisionError): return 0 - def default_change_reply_willing_received(self, chat_stream: ChatStream, is_mentioned_bot: bool = False, config=None, - is_emoji: bool = False, interested_rate: float = 0, sender_id: str = None, - **kwargs) -> float: - - current_willing = self.chat_reply_willing.get(chat_stream.stream_id, 0) - interested_rate = interested_rate * config.response_interested_rate_amplifier - if interested_rate > 0.4: - current_willing += interested_rate - 0.3 - if is_mentioned_bot and current_willing < 1.0: - current_willing += 1 - elif is_mentioned_bot: - current_willing += 0.05 - if is_emoji: - current_willing *= 0.5 - self.chat_reply_willing[chat_stream.stream_id] = min(current_willing, 3.0) - reply_probability = min(max((current_willing - 0.5), 0.01) * config.response_willing_amplifier * 2, 1) - - return reply_probability + @llmcheck_decorator(is_continuous_chat) + def get_reply_probability(self, message_id): + return super().get_reply_probability( + message_id + ) From 37c58e8b7a02de9ad7ece253901e5cc523b56986 Mon Sep 17 00:00:00 2001 From: Ark-Hakobune Date: Tue, 15 Apr 2025 23:02:43 +0800 Subject: [PATCH 7/7] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=BD=B1=E5=93=8D?= =?UTF-8?q?=E7=A7=81=E8=81=8A=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plugins/willing/mode_llmcheck.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/willing/mode_llmcheck.py b/src/plugins/willing/mode_llmcheck.py index 4f472e87f..d4e867a37 100644 --- a/src/plugins/willing/mode_llmcheck.py +++ b/src/plugins/willing/mode_llmcheck.py @@ -26,7 +26,7 @@ def is_continuous_chat(self, message_id: str): # 判断是否是连续对话,出于成本考虑,默认限制5条 willing_info = self.ongoing_messages[message_id] chat_id = willing_info.chat_id - group_info = willing_info.chat_id + group_info = willing_info.group_info config = self.global_config length = 5 if chat_id: