feat(reminder): 提升提醒功能的用户识别与意图理解

为提升提醒插件的可用性和准确性,进行了两项主要增强:

1.  **优化意图提取Prompt**:向LLM提供了Bot自身名称,并增加了示例,指导其更准确地识别提醒的真正目标,避免将Bot误认为被提醒人。
2.  **引入多级用户匹配机制**:在原有的精确名称匹配基础上,增加了子字符串包含匹配和基于`difflib`的模糊匹配,大幅提高了在用户名称输入不完全或有误时成功设置提醒的概率。
This commit is contained in:
tt-P607
2025-09-16 14:37:34 +08:00
parent 890cedc1ed
commit 3603d5ec61

View File

@@ -100,15 +100,23 @@ class RemindAction(BaseAction):
raise ValueError("未找到 'planner' 决策模型配置,无法解析时间") raise ValueError("未找到 'planner' 决策模型配置,无法解析时间")
model_to_use = available_models["planner"] model_to_use = available_models["planner"]
bot_name = self.chat_stream.user_info.user_nickname
prompt = f""" prompt = f"""
从以下用户输入中提取提醒事件的关键信息。 从以下用户输入中提取提醒事件的关键信息。
用户输入: "{self.chat_stream.context.message.processed_plain_text}" 用户输入: "{self.chat_stream.context.message.processed_plain_text}"
Bot的名字是: "{bot_name}"
请仔细分析句子结构以确定谁是提醒的真正目标。Bot自身不应被视为被提醒人。
请以JSON格式返回提取的信息包含以下字段: 请以JSON格式返回提取的信息包含以下字段:
- "user_name": 需要被提醒的人的姓名。如果未指定,则默认为"自己" - "user_name": 需要被提醒的人的姓名。如果未指定,则默认为"自己"
- "remind_time": 描述提醒时间的自然语言字符串。 - "remind_time": 描述提醒时间的自然语言字符串。
- "event_details": 需要提醒的具体事件内容。 - "event_details": 需要提醒的具体事件内容。
示例:
- 用户输入: "提醒我十分钟后开会" -> {{"user_name": "自己", "remind_time": "十分钟后", "event_details": "开会"}}
- 用户输入: "{bot_name},提醒一闪一分钟后睡觉" -> {{"user_name": "一闪", "remind_time": "一分钟后", "event_details": "睡觉"}}
如果无法提取完整信息请返回一个包含空字符串的JSON对象例如{{"user_name": "", "remind_time": "", "event_details": ""}} 如果无法提取完整信息请返回一个包含空字符串的JSON对象例如{{"user_name": "", "remind_time": "", "event_details": ""}}
""" """
@@ -209,13 +217,36 @@ class RemindAction(BaseAction):
user_id_to_remind = self.user_id user_id_to_remind = self.user_id
user_name_to_remind = self.user_nickname user_name_to_remind = self.user_nickname
else: else:
# 1. 精确匹配
user_info = await person_manager.get_person_info_by_name(user_name) user_info = await person_manager.get_person_info_by_name(user_name)
# 2. 包含匹配
if not user_info:
for person_id, name in person_manager.person_name_list.items():
if user_name in name:
user_info = await person_manager.get_values(person_id, ["user_id", "user_nickname"])
break
# 3. 模糊匹配 (此处简化为字符串相似度)
if not user_info:
best_match = None
highest_similarity = 0
for person_id, name in person_manager.person_name_list.items():
import difflib
similarity = difflib.SequenceMatcher(None, user_name, name).ratio()
if similarity > highest_similarity:
highest_similarity = similarity
best_match = person_id
if best_match and highest_similarity > 0.6: # 相似度阈值
user_info = await person_manager.get_values(best_match, ["user_id", "user_nickname"])
if not user_info or not user_info.get("user_id"): if not user_info or not user_info.get("user_id"):
logger.warning(f"[ReminderPlugin] 找不到名为 '{user_name}' 的用户") logger.warning(f"[ReminderPlugin] 找不到名为 '{user_name}' 的用户")
await self.send_text(f"抱歉,我的联系人里找不到叫做 '{user_name}' 的人,提醒设置失败。") await self.send_text(f"抱歉,我的联系人里找不到叫做 '{user_name}' 的人,提醒设置失败。")
return False, f"用户 '{user_name}' 不存在" return False, f"用户 '{user_name}' 不存在"
user_id_to_remind = user_info.get("user_id") user_id_to_remind = user_info.get("user_id")
user_name_to_remind = user_name user_name_to_remind = user_info.get("user_nickname") or user_name
# 3. 创建并调度异步任务 # 3. 创建并调度异步任务
try: try: