feat(reminder): 增强提醒功能,可将“我”识别为目标用户

通过向LLM提示词中传递消息发送者昵称,系统现在能够正确解析包含第一人称代词(如“我”)的提醒任务。这解决了之前无法为用户设置“提醒我”这类个人提醒的问题,使其交互更加自然。

此外,还优化了`@user`插件中生成提醒内容的提示词,明确指示LLM不要在回复中包含`@`或用户名,以避免系统自动@后出现重复的用户名,提升了提醒消息的质量。
This commit is contained in:
tt-P607
2025-09-10 17:10:24 +08:00
parent 8e2aa53252
commit 2e6c628cb9
3 changed files with 21 additions and 9 deletions

View File

@@ -133,7 +133,8 @@ class ProactiveThinker:
full_content = trigger_event.reason
logger.info(f"{self.context.log_prefix} 解析提醒内容: '{full_content}'")
target_user_name = await self._extract_target_user_with_llm(full_content)
sender_name = metadata.get("sender_name")
target_user_name = await self._extract_target_user_with_llm(full_content, sender_name)
if not target_user_name:
logger.warning(f"无法从提醒 '{reminder_content}' 中确定目标用户,回退")
@@ -198,12 +199,13 @@ class ProactiveThinker:
except Exception as e:
logger.error(f"{self.context.log_prefix} 主动思考执行异常: {e}")
logger.error(traceback.format_exc())
async def _extract_target_user_with_llm(self, reminder_content: str) -> str:
async def _extract_target_user_with_llm(self, reminder_content: str, sender_name: str) -> str:
"""
使用LLM从提醒内容中提取目标用户名
Args:
reminder_content: 完整的提醒内容
sender_name: 消息发送者的昵称
Returns:
提取出的用户名如果找不到则返回None
@@ -216,20 +218,23 @@ class ProactiveThinker:
user_extraction_prompt = f'''
从以下提醒消息中提取需要被提醒的目标用户名。
**重要认知**:你的名字是"{bot_name}"。当消息中提到"{bot_name}"时,通常是在称呼你,而不是要提醒的目标。你需要找出除了你自己之外的那个目标用户。
**重要认知**:
- 你的名字是"{bot_name}"。当消息中提到"{bot_name}"时,通常是在称呼你。
- 消息的发送者是"{sender_name}"。当消息中出现""""等第一人称代词时,指代的就是"{sender_name}"
提醒消息: "{reminder_content}"
规则:
1. 用户名通常在"提醒""艾特"""等动词后面
2. **绝对不能**提取你自己的名字("{bot_name}")作为目标
3. 只提取最关键的人名,不要包含多余的词语(比如时间、动作)
4. 如果消息中除了你自己的名字外,没有明确提到其他目标用户名,请回答""
1. 分析消息,找出真正需要被提醒的人
2. 如果提醒目标是第一人称(如""),那么目标就是发送者"{sender_name}"
3. **绝对不能**提取你自己的名字("{bot_name}")作为目标
4. 只提取最关键的人名,不要包含多余的词语
5. 如果没有明确的提醒目标(既不是其他人,也不是发送者自己),请回答""
示例:
- 消息: "定时提醒:{bot_name}10分钟后提醒我去打深渊" -> "{sender_name}"
- 消息: "定时提醒:{bot_name},提醒阿范一分钟后去写模组" -> "阿范"
- 消息: "定时提醒:一分钟后提醒一闪喝水" -> "一闪"
- 消息: "定时提醒:艾特绿皮" -> "绿皮"
- 消息: "定时提醒:喝水" -> ""
- 消息: "定时提醒:{bot_name},记得休息" -> ""

View File

@@ -199,6 +199,7 @@ class HeartFCMessageReceiver:
metadata = {
"type": "reminder",
"user_id": reminder_event.user_id,
"sender_name": userinfo.user_nickname, # 添加发送者昵称
"platform": chat.platform,
"chat_id": chat.stream_id,
"content": reminder_event.content,

View File

@@ -131,7 +131,13 @@ class AtAction(BaseAction):
reminder_task = at_message.replace("定时提醒:", "").strip()
extra_info = f"""你之前记下了一个提醒任务:'{reminder_task}'
现在时间到了,你需要去提醒用户 '{user_name}'
请像一个朋友一样,自然地完成这个提醒,而不是生硬地复述任务。"""
**重要规则**
- 你的任务**只**是生成提醒的**内容**。
- **绝对不要**在你的回复中包含任何`@`符号或者目标用户的名字。真正的@操作会由系统自动完成。
- 像一个朋友一样,自然地完成这个提醒,而不是生硬地复述任务。
请直接输出提醒的**内容**。"""
success, llm_response, _ = await replyer.generate_reply_with_context(
reply_to=f"是时候提醒'{user_name}'", # 内部上下文,更符合执行任务的语境