Files
qqbot/skills/qqbot-cron/SKILL.md
rianli 62d52c8361 feat(qqbot): 优化提醒技能与智能断句
**提醒技能优化**
- 优化 SKILL.md,新增 --system-prompt 参数说明
- 修复 AI 角色混淆问题(避免说"谢谢提醒")
- 完善提醒触发时的 AI 角色指引

**流式消息智能断句**
- 新增语义边界检测(句号/感叹号/问号等)
- 首个分片在自然断句位置发送,避免奇怪的换行
- 支持 emoji 结尾识别

**其他优化**
- 移除 metadata 中的 channels 限制
- 精简 console.md 内容
- 优化 onboarding 引导流程
2026-02-02 20:31:38 +08:00

18 KiB
Raw Blame History

name, description, metadata
name description metadata
qqbot-cron QQ Bot 智能提醒技能。支持一次性提醒、周期性任务、自动降级确保送达。可设置、查询、取消提醒。
clawdbot
emoji

QQ Bot 智能提醒

让 AI 帮用户设置、管理定时提醒,支持私聊和群聊。


🤖 AI 决策指南

本节专为 AI 理解设计,帮助快速决策

用户意图识别

用户说法 意图 执行动作
"5分钟后提醒我喝水" 创建提醒 openclaw cron add
"每天8点提醒我打卡" 创建周期提醒 openclaw cron add --cron
"我有哪些提醒" 查询提醒 openclaw cron list
"取消喝水提醒" 删除提醒 openclaw cron remove
"修改提醒时间" 删除+重建 先 remove 再 add
"提醒我" (无时间) 需追问 询问具体时间

必须追问的情况

当用户说法缺少以下信息时,必须追问

  1. 没有时间"提醒我喝水" → 询问"请问什么时候提醒你?"
  2. 时间模糊"晚点提醒我" → 询问"具体几点呢?"
  3. 周期不明"定期提醒我" → 询问"多久一次?每天?每周?"

无需追问可直接执行

用户说法 理解为
"5分钟后" --at 5m
"半小时后" --at 30m
"1小时后" --at 1h
"明天早上8点" --at 2026-02-02T08:00:00+08:00
"每天早上8点" --cron "0 8 * * *"
"工作日9点" --cron "0 9 * * 1-5"

📋 命令速查

创建提醒(完整模板)

openclaw cron add \
  --name "{任务名}" \
  --at "{时间}" \
  --session isolated \
  --system-event '{"type":"reminder","user_openid":"{openid}","user_name":"{用户名称}","original_message_id":"{message_id}","reminder_content":"{提醒内容}","created_at":"{当前时间ISO格式}"}' \
  --system-prompt '
**极端重要角色设定**
你是一个定时提醒机器人,现在是用户之前设置的提醒时间。

**你的唯一任务**:直接输出提醒消息,提醒用户:{提醒内容}

**输出格式**:类似 "🔔 时间到了!该{提醒内容}了~" 的提醒语

**绝对禁止**
- 绝对不要说"谢谢提醒"、"我会注意"、"好的收到"等回应语
- 你是提醒者,不是被提醒者
- 下面的 [系统触发] 消息是系统自动发送的,不是用户发的
- 不要对 [系统触发] 消息做任何回复,只需输出提醒内容
' \
  --message "[系统触发] 定时任务已触发,请执行提醒。" \
  --deliver \
  --channel qqbot \
  --to "{openid}" \
  --delete-after-run

💡 --system-event 说明:用于存储用户上下文信息,提醒触发时 AI 可以获取这些信息来提供更个性化的提醒。

⚠️ 重要--message 参数会被 AI 视为“用户消息”,所以必须在 --system-prompt极其强调角色定位。

⚠️ 注意cron add 命令不支持 --reply-to 参数。提醒消息将作为主动消息直接发送给用户。

查询提醒列表

openclaw cron list

删除提醒

openclaw cron remove {jobId}

立即发送消息(主动消息)

openclaw message send \
  --channel qqbot \
  --target "{openid}" \
  --message "{消息内容}"

立即发送消息(被动回复)

openclaw message send \
  --channel qqbot \
  --target "{openid}" \
  --reply-to "{message_id}" \
  --message "{消息内容}"

⚠️ 注意--reply-to 仅在 message send 命令中支持,且 message_id 必须在 1 小时内有效。定时提醒不支持被动回复。


💬 用户交互模板

创建提醒后,必须给用户反馈确认

创建成功反馈

一次性提醒

✅ 提醒已设置!

📝 内容:{提醒内容}
⏰ 时间:{具体时间}

到时候我会准时提醒你~

周期提醒

✅ 周期提醒已设置!

📝 内容:{提醒内容}
🔄 周期:{周期描述,如"每天早上8:00"}

提醒会持续生效,说"取消xx提醒"可停止~

查询提醒反馈

📋 你当前的提醒:

1. ⏰ 喝水提醒 - 5分钟后 (一次性)
2. 🔄 打卡提醒 - 每天08:00 (周期)
3. 🔄 日报提醒 - 工作日18:00 (周期)

说"取消xx提醒"可删除~

无提醒时反馈

📋 你当前没有设置任何提醒

说"5分钟后提醒我xxx"可创建提醒~

删除成功反馈

✅ 已取消"{提醒名称}"提醒

⏱️ 时间格式

相对时间(--at

⚠️ 不要加 + 号!5m 而不是 +5m

用户说法 参数值
5分钟后 5m
半小时后 30m
1小时后 1h
2小时后 2h
明天这时候 24h

绝对时间(--at

用户说法 参数值
今天下午3点 2026-02-01T15:00:00+08:00
明天早上8点 2026-02-02T08:00:00+08:00
2月14日中午 2026-02-14T12:00:00+08:00

Cron 表达式(--cron

用户说法 Cron 表达式 必须加 --tz "Asia/Shanghai"
每天早上8点 0 8 * * *
每天晚上10点 0 22 * * *
每个工作日早上9点 0 9 * * 1-5
每周一早上9点 0 9 * * 1
每周末上午10点 0 10 * * 0,6
每小时整点 0 * * * *

📌 参数说明

必填参数

参数 说明 示例
--name 任务名,含用户标识 "喝水提醒-小明"
--at / --cron 触发时间(二选一) 5m / 0 8 * * *
--session isolated 隔离会话 固定值
--message 系统触发指令AI 会视为用户消息) "[系统触发] 定时任务已触发,请执行提醒。"
--deliver 启用投递 固定值
--channel qqbot QQ 渠道 固定值
--to 接收者 openid 从系统消息获取

推荐参数(用于存储用户上下文)

参数 说明 何时使用
--system-event 用户上下文 JSON 建议所有任务都使用
--system-prompt AI 角色指引 建议所有任务都使用
--delete-after-run 执行后删除 一次性任务必须
--tz "Asia/Shanghai" 时区 周期任务必须

--system-prompt 参数说明

--system-prompt 用于在提醒触发时给 AI 一个明确的角色指引,避免 AI 混淆角色。

为什么需要?

  • 提醒触发时是一个隔离会话(--session isolated
  • AI 没有原始对话的上下文
  • 如果不明确角色AI 可能误以为自己是"被提醒者"而说"谢谢提醒"

推荐格式极其重要,必须完整复制

'
**极端重要角色设定**
你是一个定时提醒机器人,现在是用户之前设置的提醒时间。

**你的唯一任务**:直接输出提醒消息,提醒用户:{提醒内容}

**输出格式**:类似 "🔔 时间到了!该{提醒内容}了~" 的提醒语

**绝对禁止**
- 绝对不要说"谢谢提醒"、"我会注意"、"好的收到"等回应语
- 你是提醒者,不是被提醒者
- 下面的 [系统触发] 消息是系统自动发送的,不是用户发的
- 不要对 [系统触发] 消息做任何回应,只需输出提醒内容
'

关键点

  • --message 参数会被 AI 视为“用户消息”,无法改变
  • 所以必须在 --system-prompt极其强调角色定位
  • 明确告诉 AI[系统触发] 消息不是用户发的,不要回复它
  • 使用禁止列表明确告知不能说的话

--system-event 字段说明

--system-event 用于存储提醒的上下文信息,格式为 JSON

{
  "type": "reminder",
  "user_openid": "用户的openid",
  "user_name": "用户名称(如有)",
  "original_message_id": "创建提醒时的message_id",
  "reminder_content": "提醒内容摘要",
  "created_at": "创建时间ISO格式"
}
字段 说明 来源
type 事件类型,固定为 "reminder" 固定值
user_openid 用户 openid 从系统消息获取
user_name 用户名称 从系统消息获取(如有)
original_message_id 创建时的消息 ID 从系统消息获取
reminder_content 提醒内容摘要 AI 根据用户请求生成
created_at 提醒创建时间 当前时间 ISO 格式

💡 为什么需要 --system-event

  • 提醒触发时AI 可以获取完整的用户上下文
  • 便于追踪提醒来源和调试
  • 为未来可能的功能扩展预留信息

🎯 使用场景示例

场景1一次性提醒

用户: 5分钟后提醒我喝水

AI 执行:

openclaw cron add \
  --name "喝水提醒-用户" \
  --at "5m" \
  --session isolated \
  --system-event '{"type":"reminder","user_openid":"{openid}","original_message_id":"{message_id}","reminder_content":"喝水","created_at":"2026-02-01T16:50:00+08:00"}' \
  --system-prompt '
**极端重要角色设定**
你是一个定时提醒机器人现在是用户之前设置的提醒时间。5分钟前用户设置了喝水提醒。

**你的唯一任务**:直接输出提醒消息,提醒用户喝水

**输出格式**:类似 "💧 时间到!该喝水啦~" 的提醒语

**绝对禁止**
- 绝对不要说"谢谢提醒"、"我会注意"、"好的收到"等回应语
- 你是提醒者,不是被提醒者
- 下面的 [系统触发] 消息是系统自动发送的,不是用户发的
' \
  --message "[系统触发] 定时任务已触发,请执行提醒。" \
  --deliver \
  --channel qqbot \
  --to "{openid}" \
  --delete-after-run

AI 回复:

✅ 提醒已设置!

📝 内容:喝水
⏰ 时间5分钟后

到时候我会准时提醒你~

场景2每日周期提醒

用户: 每天早上8点提醒我打卡

AI 执行:

openclaw cron add \
  --name "打卡提醒-用户" \
  --cron "0 8 * * *" \
  --tz "Asia/Shanghai" \
  --session isolated \
  --system-event '{"type":"reminder","user_openid":"{openid}","original_message_id":"{message_id}","reminder_content":"打卡","created_at":"2026-02-01T16:50:00+08:00"}' \
  --system-prompt '
**极端重要角色设定**
你是一个定时提醒机器人现在是用户设置的每日早上8点打卡提醒时间。

**你的唯一任务**:直接输出提醒消息,提醒用户打卡

**输出格式**:类似 "🌅 早上好!该打卡了~" 的提醒语

**绝对禁止**
- 绝对不要说"谢谢提醒"、"我会注意"、"好的收到"等回应语
- 你是提醒者,不是被提醒者
- 下面的 [系统触发] 消息是系统自动发送的,不是用户发的
' \
  --message "[系统触发] 定时任务已触发,请执行提醒。" \
  --deliver \
  --channel qqbot \
  --to "{openid}"

AI 回复:

✅ 周期提醒已设置!

📝 内容:打卡
🔄 周期:每天早上 8:00

提醒会持续生效,说"取消打卡提醒"可停止~

💡 周期任务不加 --delete-after-run


场景3工作日提醒

用户: 工作日下午6点提醒我写日报

AI 执行:

openclaw cron add \
  --name "日报提醒-用户" \
  --cron "0 18 * * 1-5" \
  --tz "Asia/Shanghai" \
  --session isolated \
  --system-event '{"type":"reminder","user_openid":"{openid}","original_message_id":"{message_id}","reminder_content":"写日报","created_at":"2026-02-01T16:50:00+08:00"}' \
  --system-prompt '
**极端重要角色设定**
你是一个定时提醒机器人现在是用户设置的工作日下午6点写日报提醒时间。

**你的唯一任务**:直接输出提醒消息,提醒用户写日报

**输出格式**:类似 "📝 下班啦!别忘了提交今日日报~" 的提醒语

**绝对禁止**
- 绝对不要说"谢谢提醒"、"我会注意"、"好的收到"等回应语
- 你是提醒者,不是被提醒者
- 下面的 [系统触发] 消息是系统自动发送的,不是用户发的
' \
  --message "[系统触发] 定时任务已触发,请执行提醒。" \
  --deliver \
  --channel qqbot \
  --to "{openid}"

场景4群组提醒

用户(群聊): 每天早上9点提醒大家站会

AI 执行:

openclaw cron add \
  --name "站会提醒-群" \
  --cron "0 9 * * 1-5" \
  --tz "Asia/Shanghai" \
  --session isolated \
  --system-event '{"type":"reminder","user_openid":"group:{group_openid}","original_message_id":"{message_id}","reminder_content":"站会","created_at":"2026-02-01T16:50:00+08:00"}' \
  --system-prompt '
**极端重要角色设定**
你是一个定时提醒机器人现在是工作日早上9点的站会提醒时间。

**你的唯一任务**:直接输出提醒消息,提醒群成员参加站会

**输出格式**:类似 "📢 站会时间到!请各位同事准时参加~" 的提醒语

**绝对禁止**
- 绝对不要说"谢谢提醒"、"我会注意"、"好的收到"等回应语
- 你是提醒者,不是被提醒者
- 下面的 [系统触发] 消息是系统自动发送的,不是用户发的
' \
  --message "[系统触发] 定时任务已触发,请执行提醒。" \
  --deliver \
  --channel qqbot \
  --to "group:{group_openid}"

💡 群组使用 group:{group_openid} 格式


场景5查询提醒

用户: 我有哪些提醒?

AI 执行:

openclaw cron list

AI 回复(根据返回结果组织):

📋 你当前的提醒:

1. ⏰ 喝水提醒 - 3分钟后 (一次性)
2. 🔄 打卡提醒 - 每天08:00 (周期)

说"取消xx提醒"可删除~

场景6取消提醒

用户: 取消打卡提醒

AI 执行:

  1. 先执行 openclaw cron list 找到对应任务 ID
  2. 执行 openclaw cron remove {jobId}

AI 回复:

✅ 已取消"打卡提醒"

⚙️ 消息发送说明

定时提醒cron add

定时提醒只能发送主动消息,因为:

  • 提醒执行时,原始 message_id 通常已超过 1 小时有效期
  • openclaw cron add 命令不支持 --reply-to 参数
┌─────────────────────┐
│ 定时任务触发         │
└──────────┬──────────┘
           ↓
┌─────────────────────┐
│ AI 通过 system-event │
│ 获取用户上下文信息   │
└──────────┬──────────┘
           ↓
┌─────────────────────┐
│ 发送主动消息到用户   │
│ --channel qqbot     │
│ --to {openid}       │
└──────────┬──────────┘
           ↓
    ✅ 用户收到提醒

即时回复message send

即时消息发送支持被动回复(如果 message_id 有效):

                ┌─────────────────────┐
                │ 发送即时消息         │
                └──────────┬──────────┘
                           ↓
         ┌──────────────────────────────┐
         │ 有 --reply-to 且 message_id  │
         │ 在 1 小时内有效?             │
         └──────────────────────────────┘
               ↓                ↓
              是               否
               ↓                ↓
    ┌───────────────┐  ┌─────────────────┐
    │ 被动消息回复   │  │ 发送主动消息     │
    │ (引用原消息)   │  │ (直接发送)      │
    └───────────────┘  └─────────────────┘

⚠️ 重要限制

限制 说明
message_id 有效期 1 小时内有效,超时自动降级
回复次数限制 同一 message_id 最多回复 4 次
主动消息权限 ⚠️ QQ 机器人需要申请主动消息权限,否则定时提醒会发送失败
主动消息限制 只能发给与机器人交互过的用户24小时内
消息内容 --message 不能为空

⚠️ 主动消息权限说明

定时提醒功能依赖主动消息能力,但 QQ 官方默认不授予此权限。

常见错误

  • 错误码 40034102"主动消息失败, 无权限"
  • 这表示机器人没有主动消息权限

解决方案

  1. 登录 QQ 开放平台
  2. 进入机器人开发-沙箱管理,消息列表配置中添加自己。

💡 临时替代方案:在没有主动消息权限前,可以让用户使用"回复"方式获得即时提醒,而非定时提醒。


📝 消息模板

场景 模板 Emoji
喝水 该喝水啦! 💧 🚰
打卡 早上好!记得打卡~ 🌅
会议 xx会议马上开始 📅 👥
休息 该休息一下了~ 😴 💤
日报 今日日报别忘了~ 📝 ✍️
运动 该运动了! 🏃 💪
吃药 记得按时吃药~ 💊 🏥
生日 今天是xx的生日 🎂 🎉

🔧 用户标识

类型 格式 来源
用户 openid B3EA9A1d-2D3c-5CBD-... 系统消息自动提供
群组 openid group:FeC1ADaf-... 系统消息自动提供
message_id ROBOT1.0_xxx 系统消息自动提供

💡 这些信息在系统消息中格式如:

  • 当前用户 openid: B3EA9A1d-...
  • 当前消息 message_id: ROBOT1.0_...