feat(emoji): 避免发送近期使用过的表情包以减少重复
为了提升表情包发送的自然度和多样性,引入了表情包历史记录机制。 该功能通过以下方式工作: - 在选择表情包之前,系统会获取当前会话最近发送过的表情包记录。 - 从候选表情包池中过滤掉这些近期已使用过的表情,从而鼓励使用更多不同的表情。 - 当一个表情包成功发送后,其描述会被添加到历史记录中,用于未来的筛选。
This commit is contained in:
59
src/chat/emoji_system/emoji_history.py
Normal file
59
src/chat/emoji_system/emoji_history.py
Normal file
@@ -0,0 +1,59 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
表情包发送历史记录模块
|
||||
"""
|
||||
import os
|
||||
from typing import List, Dict
|
||||
from collections import deque
|
||||
|
||||
from src.common.logger import get_logger
|
||||
|
||||
logger = get_logger("EmojiHistory")
|
||||
|
||||
MAX_HISTORY_SIZE = 5 # 每个聊天会话最多保留最近5条表情历史
|
||||
|
||||
# 使用一个全局字典在内存中存储历史记录
|
||||
# 键是 chat_id,值是一个 deque 对象
|
||||
_history_cache: Dict[str, deque] = {}
|
||||
|
||||
|
||||
def add_emoji_to_history(chat_id: str, emoji_description: str):
|
||||
"""
|
||||
将发送的表情包添加到内存历史记录中。
|
||||
|
||||
:param chat_id: 聊天会话ID (例如 "private_12345" 或 "group_67890")
|
||||
:param emoji_description: 发送的表情包的描述
|
||||
"""
|
||||
if not chat_id or not emoji_description:
|
||||
return
|
||||
|
||||
# 如果当前聊天还没有历史记录,则创建一个新的 deque
|
||||
if chat_id not in _history_cache:
|
||||
_history_cache[chat_id] = deque(maxlen=MAX_HISTORY_SIZE)
|
||||
|
||||
# 添加新表情到历史记录
|
||||
history = _history_cache[chat_id]
|
||||
history.append(emoji_description)
|
||||
|
||||
logger.debug(f"已将表情 '{emoji_description}' 添加到聊天 {chat_id} 的内存历史中")
|
||||
|
||||
|
||||
def get_recent_emojis(chat_id: str, limit: int = 5) -> List[str]:
|
||||
"""
|
||||
从内存中获取最近发送的表情包描述列表。
|
||||
|
||||
:param chat_id: 聊天会话ID
|
||||
:param limit: 获取的表情数量上限
|
||||
:return: 最近发送的表情包描述列表
|
||||
"""
|
||||
if not chat_id or chat_id not in _history_cache:
|
||||
return []
|
||||
|
||||
history = _history_cache[chat_id]
|
||||
|
||||
# 从 deque 的右侧(即最近添加的)开始取
|
||||
num_to_get = min(limit, len(history))
|
||||
recent_emojis = [history[-i] for i in range(1, num_to_get + 1)]
|
||||
|
||||
logger.debug(f"为聊天 {chat_id} 从内存中获取到最近 {len(recent_emojis)} 个表情: {recent_emojis}")
|
||||
return recent_emojis
|
||||
@@ -12,6 +12,7 @@ from src.plugin_system.apis import llm_api, message_api
|
||||
from src.chat.emoji_system.emoji_manager import get_emoji_manager, MaiEmoji
|
||||
from src.chat.utils.utils_image import image_path_to_base64
|
||||
from src.config.config import global_config
|
||||
from src.chat.emoji_system.emoji_history import get_recent_emojis, add_emoji_to_history
|
||||
|
||||
|
||||
logger = get_logger("emoji")
|
||||
@@ -74,7 +75,20 @@ class EmojiAction(BaseAction):
|
||||
logger.warning(f"{self.log_prefix} 无法获取任何带有描述的有效表情包")
|
||||
return False, "无法获取任何带有描述的有效表情包"
|
||||
|
||||
# 3. 准备情感数据和后备列表
|
||||
# 3. 根据历史记录筛选表情
|
||||
try:
|
||||
recent_emojis_desc = get_recent_emojis(self.chat_id, limit=10)
|
||||
if recent_emojis_desc:
|
||||
filtered_emojis = [emoji for emoji in all_emojis_obj if emoji.description not in recent_emojis_desc]
|
||||
if filtered_emojis:
|
||||
all_emojis_obj = filtered_emojis
|
||||
logger.info(f"{self.log_prefix} 根据历史记录过滤后,剩余 {len(all_emojis_obj)} 个表情可用")
|
||||
else:
|
||||
logger.warning(f"{self.log_prefix} 过滤后没有可用的表情包,将使用所有表情包")
|
||||
except Exception as e:
|
||||
logger.error(f"{self.log_prefix} 获取或处理表情发送历史时出错: {e}")
|
||||
|
||||
# 4. 准备情感数据和后备列表
|
||||
emotion_map = {}
|
||||
all_emojis_data = []
|
||||
|
||||
@@ -236,13 +250,20 @@ class EmojiAction(BaseAction):
|
||||
logger.error(f"{self.log_prefix} 无效的表情选择模式: {global_config.emoji.emoji_selection_mode}")
|
||||
return False, "无效的表情选择模式"
|
||||
|
||||
# 7. 发送表情包
|
||||
# 7. 发送表情包并记录历史
|
||||
success = await self.send_emoji(emoji_base64)
|
||||
|
||||
if not success:
|
||||
logger.error(f"{self.log_prefix} 表情包发送失败")
|
||||
await self.store_action_info(action_build_into_prompt = True,action_prompt_display =f"发送了一个表情包,但失败了",action_done= False)
|
||||
return False, "表情包发送失败"
|
||||
|
||||
# 发送成功后,记录到历史
|
||||
try:
|
||||
add_emoji_to_history(self.chat_id, emoji_description)
|
||||
except Exception as e:
|
||||
logger.error(f"{self.log_prefix} 添加表情到历史记录时出错: {e}")
|
||||
|
||||
await self.store_action_info(action_build_into_prompt = True,action_prompt_display =f"发送了一个表情包",action_done= True)
|
||||
|
||||
return True, f"发送表情包: {emoji_description}"
|
||||
|
||||
Reference in New Issue
Block a user