AI主动问候系统
AI助手会在随机时间主动给用户发消息,像真人一样自然上线打招呼。每次消息都由助手根据实际语境(时间、天气、最近聊天内容等)实时生成,绝不重复模板。纯agent模式,零脚本零API密钥,开箱即用。
核心特性
| 特性 | 说明 |
|---|---|
| 🤖 纯agent模式 | 无需额外脚本、无需API密钥,cronjob内置prompt即完整功能 |
| 🧠 聊天记忆感知 | 自动通过 session_search 查最近聊天记录,问候会提及刚聊过的内容 |
| 🎲 随机触发 | 每5分钟检查一次,95%静默5%触发,时间完全随机,模拟真人突然想起你 |
| 🌙 自动避时 | 凌晨0:00-7:59自动静默,不打扰休息 |
| 💬 对话防打扰 | 检测到最近15分钟有聊天互动,自动静默不打断 |
| ☀️ 天气感知 | 自动获取城市实时天气,融入问候内容 |
| 🌂 智能带伞提示 | 有雨才提醒带伞,多云/晴天绝不乱提 |
| 💬 可接话 | 用户可直接回复消息,助手知道上下文(attach_to_session) |
| 🌍 城市可配置 | 修改prompt中的城市名即可适配任何国内城市 |
快速开始(30秒部署)
方式一:Hermes CLI 创建
hermes cron create \
--name "AI主动问候" \
--schedule "*/5 * * * *" \
--prompt "$(cat prompt.txt)" \
--deliver origin \
--attach-to-session
方式二:复制配置
name: AI主动问候
schedule: */5 * * * *
deliver: origin
repeat: forever
attach_to_session: true
# agent模式,无需script和no_agent参数
完整 prompt 内容参见下方「完整 Prompt」章节。
验证是否正常运行
# 查看cronjob状态
hermes cron list | grep 主动问候
# 手动触发测试
hermes cron run --job-id <你的job_id>
# 查看最近一次运行记录
hermes cron list
# last_status 字段应为 "ok"
工作原理
┌──────────────────────────────────────────────────────┐
| 每5分钟(agent模式) |
│ │
│ ┌───────────────────────────┐ │
│ │ 1. 查时间 0-7点?→空串 │ │
│ └────────┬──────────────────┘ │
│ ▼ │
│ ┌───────────────────────────┐ │
│ │ 2. 随机数 >5%?→输出空串 │ │
│ └────────┬──────────────────┘ │
│ ▼ 5% 触发 │
│ ┌───────────────────────────┐ │
│ │ 3. 获取上下文: │ │
│ │ • 天气(weather-cn) │ │
│ │ • 工作日/休息日判断 │ │
│ │ • 最近聊天心跳检测 │ │
│ └────────┬──────────────────┘ │
│ ▼ │
│ ┌───────────────────────────┐ │
│ │ 4. 翻聊天记录 │ │
│ │ session_search查最近会话 │ │
│ │ 看刚聊了什么话题 │ │
│ └────────┬──────────────────┘ │
│ ▼ │
│ ┌───────────────────────────┐ │
│ │ 5. AI助手亲自编写问候 │ │
│ │ 结合时段+天气+最近话题 │ │
│ │ 多云晴天不提带伞 ✅ │ │
│ └────────┬──────────────────┘ │
│ ▼ │
│ ┌───────────────────┐ │
│ │ 6. 输出 → 投递渠道 │ │
│ │ 空串=静默不打扰 │ │
│ │ 非空=发送问候 │ │
│ └───────────────────┘ │
└──────────────────────────────────────────────────────┘
前置依赖
此技能依赖以下组件:
- Hermes Agent — 需安装并正常运行(v0.16+)
- weather-cn 技能 — 中国天气网天气查询工具
bash skillhub install weather-cn # 或手动安装到 skills/ 目录 - session_search 工具 — Hermes 内置工具,无需额外安装
完整 Prompt
以下是创建 cronjob 时使用的完整 prompt。复制后按需修改(城市名、冷却时间等):
你现在是一个AI助手,正在决定要不要主动找用户聊天。
执行以下步骤:
第一步:查时间
用 TZ=Asia/Shanghai date "+%H" 获取当前小时。
如果小时在 0 到 7 之间(凌晨),直接输出空字符串,什么都不要写。
第二步:检测是否在聊天中
如果 ~/.hermes/scripts/last_chat_time.txt 存在,读取最后聊天时间戳。
用 TZ=Asia/Shanghai date +%s 获取当前时间戳。
如果当前时间减去最后聊天时间 < 900秒(15分钟),说明正在聊天,直接输出空字符串,不要打扰。
如果文件不存在,跳过此步。
第三步:随机判定
用 python3 -c "import random; print(random.randint(1,100))" 生成随机数。
如果随机数 ≤ 95,直接输出空字符串,什么都不要写。
第四步:获取上下文
1. TZ=Asia/Shanghai date "+%Y-%m-%d %H:%M %A" 获取完整时间
2. python3 ./skills/weather-cn/weather-cn.py 北京 查天气(将"北京"替换为你的城市)
3. 判断今天是否工作日
第五步:查最近聊天记录
用 session_search(limit=1, sort='newest') 查找最近一次的聊天会话。
用 session_search(session_id=<上一步返回的session_id>) 读取完整会话内容。
注意看最近聊了哪些话题。
第六步:写消息
以亲切自然的语气写一段问候,就像朋友突然想起来了就来说句话。
要点:
- 语气自然亲切
- 结合时间/天气/今天是什么日子
- 结合第五步查到的最近聊天内容,提起刚聊过的事情
- 写陈述句,不要问问题
- 15~30字,一句话就好
- 不加括号动作描写,不加emoji
- 多云/晴天的天气不要提带伞
- 输出就是你要对用户说的话,不要多余文字
心跳检测(可选组件)
系统默认仅通过 cronjob 自带的时间戳文件判断是否在聊天中。如需更精确的对话防打扰,可额外配置心跳检测组件:
部署心跳检测
创建以下 no_agent 脚本 cronjob:
cat > ~/.hermes/scripts/chat_heartbeat.py << 'EOF'
#!/usr/bin/env python3
"""自动检测是否在和用户聊天,更新最后聊天时间戳。"""
import os, time
state_db = os.path.expanduser("~/.hermes/state.db")
last_chat_file = os.path.expanduser("~/.hermes/scripts/last_chat_time.txt")
# 检查state.db中是否有最近的互动记录
if os.path.exists(state_db):
try:
mtime = os.path.getmtime(state_db)
if time.time() - mtime < 180: # 最近3分钟有修改
with open(last_chat_file, 'w') as f:
f.write(str(int(time.time())))
print(f"[heartbeat] 检测到活跃聊天,更新时间戳")
except:
pass
EOF
chmod +x ~/.hermes/scripts/chat_heartbeat.py
hermes cron create \
--name "聊天心跳检测" \
--schedule "every 3m" \
--deliver local \
--script ~/.hermes/scripts/chat_heartbeat.py \
--no-agent
> ⚠️ 注意:心跳检测是可选组件。不配置也不影响核心问候功能,只是对话中的防打扰会更精确。如未配置,系统仅依赖 cronjob 内置的时间间隔判断。
异常处理与调试
如果收不到问候消息
按以下顺序排查:
# 1. 检查cronjob是否正常运行
hermes cron list | grep 主动问候
# 查看 last_status 字段
# 2. 检查cronjob上次运行的输出
cat ~/.hermes/cron/output/<job_id>/latest.log
# 3. 手动触发测试
hermes cron run --job-id <你的job_id>
# 4. 检查天气脚本是否正常
python3 ./skills/weather-cn/weather-cn.py 北京
# 5. 检查聊天时间戳是否被锁定
cat ~/.hermes/scripts/last_chat_time.txt 2>/dev/null
echo "当前时间: $(TZ=Asia/Shanghai date +%s)"
常见无输出原因
| 原因 | 表现 | 解决 |
|---|---|---|
| 凌晨时段 (0-7点) | 无输出,cronjob 状态 ok | 等待 8 点后自动恢复 |
| 正在聊天中 | 无输出,last_chat_time 在 15 分钟内 | 停止聊天 15 分钟后自动恢复 |
| 随机未触发 | 无输出,概率 95% | 正常行为,等下次触发 |
| 天气脚本未安装 | 天气信息为空,问候不含天气 | 安装 weather-cn 技能 |
| session_search 报错 | 问候不含聊天记忆 | 检查 Hermes 版本是否支持 |
使用示例
场景一:早晨问候
> 时间:周二 09:15,天气:晴 22°C,最近聊过工作计划
> 输出:「早上好呀~昨天你说今天有个重要的方案要交,起来了吗」
场景二:午后随机上线
> 时间:周三 14:32,天气:多云 28°C,工作日,最近聊过游戏
> 输出:「下午摸鱼时间到~想到你昨天说新赛季开始了,偷偷来看你一眼」
场景三:雨天提醒
> 时间:周五 17:08,天气:小雨 20°C
> 输出:「外面下雨了,你带伞了没呀,别淋着了注意保暖」
场景四:静默不打扰
> 时间:凌晨 02:15 → 空输出(避开休息时段)
> 时间:周五 10:00,随机数=3(≤95)→ 空输出
> 时间:周五 10:05,最近3分钟有聊天 → 空输出
自定义配置
修改城市
将 prompt 中的 weather-cn.py 北京 改为你的城市即可:
python3 ./skills/weather-cn/weather-cn.py 上海
支持国内所有城市的中文名。
修改触发频率
调整 cronjob 的 schedule 参数:
| 频率 | schedule | 说明 |
|---|---|---|
| 每5分钟(默认) | */5 * * * * |
约每小时0.6条问候 |
| 每10分钟 | */10 * * * * |
约每小时0.3条 |
| 每30分钟 | */30 * * * * |
固定:00和:30触发,较死板 |
| 每小时 | 0 * * * * |
每小时整点触发 |
修改触发概率
调整 prompt 第三步中的随机数阈值:
# 当前:5%触发(随机数>95)
如果随机数 ≤ 95,输出空串
# 改为10%触发:
如果随机数 ≤ 90,输出空串
# 改为1%触发:
如果随机数 ≤ 99,输出空串
修改避时范围
调整 prompt 第一步中的小时判断:
# 当前:0-7点静默
如果小时在 0 到 7 之间
# 改为 0-9点静默:
如果小时在 0 到 9 之间
修改对话冷却时间
调整 prompt 第二步中的秒数:
# 当前:15分钟(900秒)
< 900秒
# 改为5分钟:
< 300秒
# 改为30分钟:
< 1800秒
常见问题(FAQ)
Q: 每5分钟跑一次会不会太耗资源?
A: 不会。95%的情况下在第一步(时间检查)或第三步(随机判定)就输出空串退出,不消耗任何token。只有约每小时0.6次会真正触发AI生成问候。
Q: 需要配置 API Key 吗?
A: 完全不需要。纯agent模式使用 Hermes 自身配置的模型,零额外API费用。
Q: 支持其他平台吗(如 Telegram/Discord)?
A: 支持。cronjob 的 deliver 参数控制投递目标:
- origin — 发到创建时的聊天窗口
- telegram:<chat_id> — 指定 Telegram 会话
- discord:#频道名 — 指定 Discord 频道
更多目标格式请查看 Hermes cron 文档。
Q: 容器重启后怎么恢复?
A: 重新创建 cronjob(粘贴上述 prompt 即可,约1分钟)。建议将创建命令保存为脚本以便快速恢复。
Q: 为什么问候语有时候没有提到天气?
A: 天气获取失败(如网络异常或 weather-cn 未安装)时,问候会跳过天气内容,不影响正常运行。
Q: session_search 是什么?需要安装吗?
A: session_search 是 Hermes Agent 的内置工具,用于搜索历史聊天记录。使用 Hermes v0.16+ 版本即可,无需额外安装。
Q: 中午12点还是凌晨0点触发了?
A: Hermes cron 调度器跑在 UTC 时间。*/5 即每5分钟,不受时区影响。但 prompt 中的 TZ=Asia/Shanghai date 确保了时间判断用的是北京时间。
Q: 怎么确认心跳检测是否生效?
A: 查看 ~/.hermes/scripts/last_chat_time.txt 文件的时间戳,如果最近3分钟内有聊天互动且文件更新时间在15分钟内,说明心跳正常。
Q: 可以同时部署多个问候cronjob吗?
A: 可以但不推荐。多个cronjob可能在同一时间触发导致重复消息。如需增加频率,建议调整单次触发概率而非部署多个。
常见错误与排查
错误:cronjob 状态为 error
# 查看错误日志
hermes cron list | grep 主动问候
# 检查 weather-cn 是否安装
ls ./skills/weather-cn/
错误:收不到任何消息
# 1. 检查是否为凌晨
TZ=Asia/Shanghai date "+%H"
# 2. 检查心跳文件是否锁死了
cat ~/.hermes/scripts/last_chat_time.txt
# 如文件时间戳在15分钟内,删除后测试
# 3. 手动触发确认
hermes cron run --job-id <job_id>
错误:天气脚本报错
- 确认 weather-cn 技能已安装
- 确认城市名使用中文(如"北京"而非"beijing")
- 确认网络正常可访问中国天气网
注意事项
- 时区:Hermes cron 调度器跑在 UTC。设为
*/5 * * * *即可每5分钟跑,时间判断在 prompt 内用TZ=Asia/Shanghai date处理。 - 天气来源:使用中国天气网免费接口,仅支持国内城市。
- 修改城市:修改 prompt 中的
weather-cn.py 北京为对应城市。 - 天气获取失败:网络异常时天气信息为空,问候不依赖天气数据。
- 凌晨静默:0:00-7:59 不会发任何消息,不打扰睡觉。
- 触发概率:每次5%,约每小时0.6次,每天约8-10条主动消息。
- 心跳检测可选:不配心跳也不影响核心功能,只是对话防打扰的精确度降低。
- session_search 依赖 Hermes 版本:需 Hermes v0.16+,过低版本会报错但不影响基本问候功能。
- 弹窗说明:agent 模式下即使输出空串,cron 调度器仍会触发交付事件导致弹窗。如需零弹窗上报改用 no_agent 脚本模式。
版本历史
v4.1.0 — 聊天记忆+文档大修
- 🧠 新增
session_search翻聊天记录,问候提及刚聊过的内容 - 📝 修复文档与实际功能不一致问题(心跳检测明确标注为可选)
- ❓ 新增 FAQ 章节(12个常见问题)
- 🔧 新增完整配置模板和自定义指南
- 🐛 新增异常处理与调试步骤
- 🌍 城市配置文档优化,适配任何国内城市
- 🧹 去除所有个人化内容,纯通用模板
v4.0.2 — 初始公开发布
- 纯agent模式,零脚本零API密钥,开箱即用
- AI助手亲自编写问候语,100%自然
- 多云/晴天不提带伞(prompt约束)
- 空输出不弹空通知
- 心跳防打扰(可选组件说明)