feat:更精准的表情包匹配

This commit is contained in:
SengokuCola
2025-07-10 03:19:04 +08:00
parent 9eeff628b8
commit 76f2054cbc
3 changed files with 640 additions and 28 deletions

View File

@@ -86,3 +86,535 @@
8.65717782684436
8.65717782684436
0.020373848987042205
2.593162350695633
0.03203964454588806
0.030243923387959913
0.0416831084528021
0.030906331331691177
0.02988194581614903
0.018026305204928966
0.11700260384441222
0.030906331331691177
0.027344556981661584
0.02126634371149695
0.2834179621067139
0.02388322700338219
0.03203964454588806
0.03507388656058557
0.02789637960584667
0.038092068217251376
6.085021562321503
6.257759651223436
6.257759651223436
6.261399141577353
0.0233314043791971
0.21168647349950526
0.19712509049144
5.316296238400273
6.257759651223436
6.087979117713658
0.03203964454588806
0.02949581907331921
6.085021562321503
0.030416764741305155
0.11267641525791106
0.12199466703464368
0.1143420240782623
0.19440388446077916
0.2843589069495348
5.99521828087802
0.026403612138840668
0.02203945780739345
6.086687171141854
0.2843589069495348
0.018026305204928966
0.043042772233490977
0.018026305204928966
0.027047581355656602
0.19440388446077916
6.093047867526432
6.087979117713658
2.594083296363619
2.585705989429707
2.585705989429707
8.653593741270736
2.826573104095818
2.826573104095818
0.03822619982285357
0.019318251776732617
0.019318251776732617
0.02969210076377482
0.027344556981661584
0.014013152602464482
0.0233314043791971
0.020373848987042205
1.5677584375174967
1.5677584375174967
0.024387001589506692
0.03203964454588806
0.02203945780739345
0.03654584002545838
0.027627040096074675
0.028153744436359526
0.025279496313961432
0.024387001589506692
0.03203964454588806
0.025279496313961432
0.02126634371149695
0.024387001589506692
0.020373848987042205
0.027344556981661584
0.0233314043791971
0.02567894816131034
0.018026305204928966
0.027344556981661584
0.19440388446077916
0.02605261040985793
1.6115788768356085
1.4640532917116755
0.5632634498831727
1.610569413378218
0.018026305204928966
6.257759651223436
0.03203964454588806
0.56584734302678
0.018026305204928966
1.4672933302182436
2.5897191420321715
0.02203945780739345
0.026403612138840668
1.6115788768356085
0.18909878528651103
0.5588766350321606
0.032987018878939844
0.02567894816131034
1.4784402933011822
0.02988194581614903
0.0366628087583942
0.019318251776732617
0.025279496313961432
0.035988106471349056
0.028400154191971172
1.6131862966701032
0.19273827564042792
0.019318251776732617
0.016360696384577725
0.0339877364806524
0.03203964454588806
0.026734545371619928
1.6124381923554625
0.02203945780739345
0.03203964454588806
0.018026305204928966
1.5959562832018463
0.02203945780739345
0.03551382637263636
0.037267027716268906
3.124491258589239
0.610536110598576
0.566399165650965
0.018026305204928966
0.03203964454588806
0.5704647145871191
0.02485042928512086
0.03731895412135488
0.037267027716268906
0.026734545371619928
0.019318251776732617
3.825397466366432
0.03203964454588806
0.026403612138840668
0.03229141270573031
0.19827045314881617
0.036365833132389225
0.027627040096074675
0.026734545371619928
0.03624264220072675
0.11700260384441222
0.03507388656058557
0.11700260384441222
0.03229141270573031
0.03605279714835254
0.0361800496412885
0.019318251776732617
0.03507388656058557
0.03514957071487914
0.03241330679443565
0.018026305204928966
0.03795475533019785
0.019318251776732617
0.022721392769155448
0.018026305204928966
0.02388322700338219
0.02126634371149695
0.033201478780114806
0.03203964454588806
0.03897162493552239
0.03705453578090416
0.03624264220072675
0.03605279714835254
0.02605261040985793
0.024387001589506692
0.018026305204928966
0.019318251776732617
0.026403612138840668
0.02789637960584667
0.025279496313961432
0.03203964454588806
0.02203945780739345
0.03203964454588806
0.028153744436359526
0.03121112566969858
0.028400154191971172
0.03203964454588806
0.5695382791300162
0.1937590804309808
0.565933984965691
0.03813712490657174
0.5715465770356281
0.03121112566969858
0.020373848987042205
0.025279496313961432
0.019318251776732617
0.018026305204928966
0.03203964454588806
0.02388322700338219
0.26173176064750214
0.03203964454588806
0.025279496313961432
0.5602977928297127
0.19159146701500568
0.02203945780739345
0.11253719536395454
0.21313854738561544
0.028400154191971172
0.02988194581614903
0.018026305204928966
0.6417882275234562
0.02605261040985793
5.977571304755818
0.025279496313961432
0.19325707583535692
0.02126634371149695
0.11534816684168195
0.014013152602464482
0.019318251776732617
0.016360696384577725
0.11655034796641901
0.5509394882379124
0.02567894816131034
0.022721392769155448
0.02388322700338219
0.037908251021078
0.020373848987042205
0.027344556981661584
0.03203964454588806
0.022721392769155448
0.036604619772537636
0.022721392769155448
0.024387001589506692
0.19401122364832826
0.02485042928512086
1.3250588305259812
0.02988194581614903
0.016360696384577725
0.028400154191971172
2.693552043972918
1.3895563870015402
0.03578958112445851
0.18870612447406013
0.5708924583987018
6.024690626754802
0.0233314043791971
0.19456304627251336
0.02126634371149695
0.8999568498738115
0.0233314043791971
0.02789637960584667
0.03203964454588806
0.018026305204928966
0.03203964454588806
0.018026305204928966
0.03705453578090416
0.019318251776732617
0.019318251776732617
0.019318251776732617
0.02863650355346524
0.02567894816131034
0.2849203145574192
0.02485042928512086
0.02126634371149695
0.0233314043791971
0.024387001589506692
0.026403612138840668
0.020373848987042205
0.19456304627251336
0.030243923387959913
0.02126634371149695
0.02949581907331921
0.026403612138840668
0.03203964454588806
0.022721392769155448
0.014013152602464482
0.03203964454588806
6.1175478095986575
0.02203945780739345
0.0233314043791971
0.027344556981661584
0.020373848987042205
0.03203964454588806
0.02126634371149695
0.02908208915373317
0.014013152602464482
0.19401122364832826
0.018026305204928966
0.02126634371149695
0.019318251776732617
0.020373848987042205
0.02203945780739345
0.02988194581614903
0.03203964454588806
0.7418853136518697
0.02203945780739345
1.3342940300608033
0.1927893605828308
0.02605261040985793
7.413181479797994
0.1899783891051034
0.014013152602464482
0.014013152602464482
0.014013152602464482
0.03203964454588806
0.03203964454588806
0.014013152602464482
6.2640940646555245
2.328988930886535
0.022721392769155448
0.026734545371619928
0.018026305204928966
6.264094064655525
5.1914900462266145
0.12023955698857974
0.9447480869881139
0.02789637960584667
6.107820928916661
0.5743239036953584
0.022721392769155448
0.02789637960584667
0.03642645939690014
0.019318251776732617
0.018026305204928966
0.030065763012322416
0.026403612138840668
0.19528348827937153
0.014013152602464482
0.020373848987042205
5.953352859746529
0.02988194581614903
0.03654584002545838
6.093433927327155
6.1081945911652085
0.1273249173506878
0.019318251776732617
0.016360696384577725
0.4644360345195811
6.2640940646555245
0.016360696384577725
0.5000527117671028
0.03203964454588806
0.018026305204928966
0.019318251776732617
0.19528348827937153
0.03705453578090416
0.016360696384577725
6.094489524537464
0.022721392769155448
0.02908208915373317
6.096155133357815
0.018026305204928966
0.03425707599042439
0.02126634371149695
0.1264437639723824
6.098502677139929
1.0349194839341556
6.1079166295311955
0.0363045653081948
6.099794623711732
0.19528348827937153
0.02388322700338219
0.02388322700338219
0.02388322700338219
0.02388322700338219
1.5937175408447852
1.0238832270033822
6.264094064655525
0.18831278028475215
0.18831278028475215
0.18920527500920692
0.18831278028475215
0.18831278028475215
6.264094064655525
6.264094064655525
6.264094064655525
6.270918188735718
6.270918188735718
6.270918188735718
0.1284929405276288
0.024387001589506692
0.03203964454588806
0.014013152602464482
0.018026305204928966
0.1927893605828308
0.02485042928512086
0.03642645939690014
0.016360696384577725
0.03203964454588806
0.03203964454588806
0.19528348827937153
0.028153744436359526
0.02203945780739345
0.022721392769155448
0.03203964454588806
0.024387001589506692
0.036889887092514305
0.03203964454588806
0.02126634371149695
0.016360696384577725
0.024387001589506692
0.027047581355656602
0.02126634371149695
0.026403612138840668
0.03203964454588806
0.03203964454588806
0.020373848987042205
0.02567894816131034
0.02203945780739345
0.020373848987042205
0.03642645939690014
0.12550917108780713
0.022721392769155448
0.02126634371149695
0.020373848987042205
0.02203945780739345
0.02126634371149695
0.032987018878939844
0.020373848987042205
0.02388322700338219
0.019318251776732617
0.02908208915373317
0.03203964454588806
0.02388322700338219
0.0233314043791971
0.022721392769155448
0.019318251776732617
0.02969210076377482
0.016360696384577725
0.022721392769155448
0.03544278553831089
0.018026305204928966
0.018026305204928966
0.022721392769155448
0.02126634371149695
0.019318251776732617
0.19657532621243082
0.034597748090694054
0.03203964454588806
0.03203964454588806
0.02485042928512086
0.03241330679443565
0.02203945780739345
0.014013152602464482
0.020373848987042205
0.027627040096074675
1.4066375852507782
0.02126634371149695
0.03710839435866214
0.11715812159281318
0.024387001589506692
0.014013152602464482
0.028400154191971172
0.03800088908311688
0.022721392769155448
0.02126634371149695
0.016360696384577725
0.018026305204928966
0.03203964454588806
0.018026305204928966
1.4606587109145759
0.027344556981661584
0.027047581355656602
0.19631537111376607
0.03522427827216307
0.019318251776732617
0.03203964454588806
0.019318251776732617
0.03529803411491245
0.02203945780739345
0.024387001589506692
0.19788719264057633
0.019318251776732617
0.025279496313961432
0.19788719264057633
0.03203964454588806
0.037267027716268906
1.9426549475864308
0.02863650355346524
0.19788719264057633
0.025279496313961432
0.040617772375002116
0.014013152602464482
0.042059810740987885
0.03203964454588806
0.022721392769155448
0.19788719264057633
0.04192140362354248
0.02789637960584667
0.02203945780739345
0.033800953980773776
2.5587523795311893
0.036833946992045466
0.19788719264057633
6.05966908428223
0.033800953980773776
6.06239029031289
6.05966908428223
0.0363045653081948
0.1953930649440356
0.014013152602464482
0.018026305204928966
1.4384500897093555
1.6635593742584274
0.02203945780739345
8.603668187263336
0.02126634371149695
6.05966908428223
6.067398413861153
1.0334082777402342
0.014013152602464482
0.014013152602464482
0.014013152602464482
0.014013152602464482
0.014013152602464482
0.014013152602464482
0.014013152602464482
0.014013152602464482
0.014013152602464482
0.014013152602464482
6.070042933269272
0.0233314043791971
0.8090676524802475
6.069846651578816
6.071411566463618
0.025279496313961432
0.19788719264057633
0.016360696384577725
1.0342570759904244
0.026403612138840668
0.016360696384577725
0.019318251776732617
0.014013152602464482
0.03537086218659055
0.018026305204928966
6.234776695167793
6.327799950981746
6.234224872543608

View File

@@ -8,7 +8,7 @@
count = emoji_api.get_count()
"""
from typing import Optional, Tuple
from typing import Optional, Tuple, List
from src.common.logger import get_logger
from src.chat.emoji_system.emoji_manager import get_emoji_manager
from src.chat.utils.utils_image import image_path_to_base64
@@ -55,14 +55,20 @@ async def get_by_description(description: str) -> Optional[Tuple[str, str, str]]
return None
async def get_random() -> Optional[Tuple[str, str, str]]:
"""随机获取表情包
async def get_random(count: int = 1) -> Optional[List[Tuple[str, str, str]]]:
"""随机获取指定数量的表情包
Args:
count: 要获取的表情包数量默认为1
Returns:
Optional[Tuple[str, str, str]]: (base64编码, 表情包描述, 随机情感标签)None
Optional[List[Tuple[str, str, str]]]: 包含(base64编码, 表情包描述, 随机情感标签)的元组列表,如果失败则为None
"""
if count <= 0:
return []
try:
logger.info("[EmojiAPI] 随机获取表情包")
logger.info(f"[EmojiAPI] 随机获取 {count}表情包")
emoji_manager = get_emoji_manager()
all_emojis = emoji_manager.emoji_objects
@@ -77,23 +83,35 @@ async def get_random() -> Optional[Tuple[str, str, str]]:
logger.warning("[EmojiAPI] 没有有效的表情包")
return None
if len(valid_emojis) < count:
logger.warning(f"[EmojiAPI] 有效表情包数量 ({len(valid_emojis)}) 少于请求的数量 ({count}),将返回所有有效表情包")
count = len(valid_emojis)
# 随机选择
import random
selected_emoji = random.choice(valid_emojis)
selected_emojis = random.sample(valid_emojis, count)
results = []
for selected_emoji in selected_emojis:
emoji_base64 = image_path_to_base64(selected_emoji.full_path)
if not emoji_base64:
logger.error(f"[EmojiAPI] 无法转换表情包为base64: {selected_emoji.full_path}")
return None
continue
matched_emotion = random.choice(selected_emoji.emotion) if selected_emoji.emotion else "随机表情"
# 记录使用次数
emoji_manager.record_usage(selected_emoji.hash)
results.append((emoji_base64, selected_emoji.description, matched_emotion))
logger.info(f"[EmojiAPI] 成功获取随机表情包: {selected_emoji.description}")
return emoji_base64, selected_emoji.description, matched_emotion
if not results and count > 0:
logger.warning("[EmojiAPI] 随机获取表情包失败,没有一个可以成功处理")
return None
logger.info(f"[EmojiAPI] 成功获取 {len(results)} 个随机表情包")
return results
except Exception as e:
logger.error(f"[EmojiAPI] 获取随机表情包失败: {e}")

View File

@@ -1,3 +1,4 @@
import random
from typing import Tuple
# 导入新插件系统
@@ -7,7 +8,7 @@ from src.plugin_system import BaseAction, ActionActivationType, ChatMode
from src.common.logger import get_logger
# 导入API模块 - 标准Python包方式
from src.plugin_system.apis import emoji_api
from src.plugin_system.apis import emoji_api, llm_api, message_api
from src.plugins.built_in.core_actions.no_reply import NoReplyAction
@@ -39,7 +40,7 @@ class EmojiAction(BaseAction):
"""
# 动作参数定义
action_parameters = {"description": "文字描述你想要发送的表情包内容"}
action_parameters = {"reason": "文字描述你想要发送的表情包原因"}
# 动作使用场景
action_require = [
@@ -56,18 +57,79 @@ class EmojiAction(BaseAction):
logger.info(f"{self.log_prefix} 决定发送表情")
try:
# 1. 根据描述选择表情包
description = self.action_data.get("description", "")
emoji_result = await emoji_api.get_by_description(description)
# 1. 获取发送表情的原因
reason = self.action_data.get("reason", "表达当前情绪")
logger.info(f"{self.log_prefix} 发送表情原因: {reason}")
if not emoji_result:
logger.warning(f"{self.log_prefix} 未找到匹配描述 '{description}' 的表情包")
return False, f"未找到匹配 '{description}' 的表情包"
# 2. 随机获取20个表情包
sampled_emojis = await emoji_api.get_random(30)
if not sampled_emojis:
logger.warning(f"{self.log_prefix} 无法获取随机表情包")
return False, "无法获取随机表情包"
emoji_base64, emoji_description, matched_emotion = emoji_result
logger.info(f"{self.log_prefix} 找到表达{matched_emotion}的表情包")
# 3. 准备情感数据
emotion_map = {}
for b64, desc, emo in sampled_emojis:
if emo not in emotion_map:
emotion_map[emo] = []
emotion_map[emo].append((b64, desc))
# 使用BaseAction的便捷方法发送表情包
available_emotions = list(emotion_map.keys())
if not available_emotions:
logger.warning(f"{self.log_prefix} 获取到的表情包均无情感标签, 将随机发送")
emoji_base64, emoji_description, _ = random.choice(sampled_emojis)
else:
# 获取最近的5条消息内容用于判断
recent_messages = message_api.get_recent_messages(chat_id=self.chat_id, limit=5)
messages_text = ""
if recent_messages:
# 使用message_api构建可读的消息字符串
messages_text = message_api.build_readable_messages(
messages=recent_messages,
timestamp_mode="normal_no_YMD",
truncate=False,
show_actions=False,
)
# 4. 构建prompt让LLM选择情感
prompt = f"""
你是一个正在进行聊天的网友,你需要根据一个理由和最近的聊天记录,从一个情感标签列表中选择最匹配的一个。
这是最近的聊天记录:
{messages_text}
这是理由:“{reason}
这里是可用的情感标签:{available_emotions}
请直接返回最匹配的那个情感标签,不要进行任何解释或添加其他多余的文字。
"""
logger.info(f"{self.log_prefix} 生成的LLM Prompt: {prompt}")
# 5. 调用LLM
models = llm_api.get_available_models()
chat_model_config = getattr(models, "utils_small", None) # 默认使用chat模型
if not chat_model_config:
logger.error(f"{self.log_prefix} 未找到'chat'模型配置无法调用LLM")
return False, "未找到'chat'模型配置"
success, chosen_emotion, _, _ = await llm_api.generate_with_model(prompt, model_config=chat_model_config, request_type="emoji")
if not success:
logger.error(f"{self.log_prefix} LLM调用失败: {chosen_emotion}")
return False, f"LLM调用失败: {chosen_emotion}"
chosen_emotion = chosen_emotion.strip().replace("\"", "").replace("'", "")
logger.info(f"{self.log_prefix} LLM选择的情感: {chosen_emotion}")
# 6. 根据选择的情感匹配表情包
if chosen_emotion in emotion_map:
emoji_base64, emoji_description = random.choice(emotion_map[chosen_emotion])
logger.info(f"{self.log_prefix} 找到匹配情感 '{chosen_emotion}' 的表情包: {emoji_description}")
else:
logger.warning(f"{self.log_prefix} LLM选择的情感 '{chosen_emotion}' 不在可用列表中, 将随机选择一个表情包")
emoji_base64, emoji_description, _ = random.choice(sampled_emojis)
# 7. 发送表情包
success = await self.send_emoji(emoji_base64)
if not success:
@@ -80,5 +142,5 @@ class EmojiAction(BaseAction):
return True, f"发送表情包: {emoji_description}"
except Exception as e:
logger.error(f"{self.log_prefix} 表情动作执行失败: {e}")
logger.error(f"{self.log_prefix} 表情动作执行失败: {e}", exc_info=True)
return False, f"表情发送失败: {str(e)}"