AI Agent工具链更新太快——Hermes Agent每2周一个版本,OpenClaw甚至更快。手动刷GitHub Releases页面?太慢了。本文教你用20行Python + Hermes Agent的定时任务,搭建一个24小时自动监控机器人,新版本发布后5分钟内推送到你的微信。
为什么你需要这个
做AI创业,信息差就是钱。一个工具的新功能可能意味着:
- 你可以抢在别人前面出教程(流量红利)
- 你发现了一个新能力可以整合进产品(功能壁垒)
- 你避开了别人踩过的坑(版本breaking change预警)
但现实是:Hermes Agent、OpenClaw、Claude Code、MCP生态...随便数数就有十几个项目要跟踪。纯手动根本跟不过来。
这个监控Agent的价值:把"被动刷页面"变成"主动推送"。你只需要设置一次,之后每次新版本发布,Agent会把更新摘要自动推送到你的微信草稿箱——你每天打开公众号后台就能看到。
整体架构
cron定时任务(每15分钟)
↓
Python脚本调用GitHub REST API
↓
对比上次记录的版本号/commit hash
↓ 发现更新
Hermes Agent生成更新摘要
↓
推送到微信草稿箱(Agent工坊模板)
第一步:获取GitHub数据(无需Token)
GitHub REST API对公开仓库的releases和commits端点不需要认证(有频率限制:60次/小时,对监控场景完全够用)。
import json, subprocess
from datetime import datetime, timezone
REPOS = [
("Hermes Agent", "NousResearch/hermes-agent"),
("OpenClaw", "openclaw/openclaw"),
("Claude Code", "anthropics/claude-code"), # 如果公开
]
def fetch_latest_release(owner_repo):
"""获取仓库最新release,无需API Key"""
url = f"https://api.github.com/repos/{owner_repo}/releases?per_page=1"
result = subprocess.run(
["curl", "-s", "-H", "Accept: application/vnd.github+json",
"-H", "User-Agent: ai-monitor-bot", url],
capture_output=True, text=True, timeout=15
)
data = json.loads(result.stdout)
if isinstance(data, list) and len(data) > 0:
release = data[0]
return {
"tag": release["tag_name"],
"name": release.get("name", release["tag_name"]),
"body": release.get("body", "")[:2000], # 截断,足够判断
"published_at": release["published_at"],
"html_url": release["html_url"]
}
return None
def fetch_latest_commits(owner_repo, since_hours=24):
"""获取最近N小时的commits(用于追踪未打tag的更新)"""
since = datetime.now(timezone.utc).isoformat()
url = (f"https://api.github.com/repos/{owner_repo}/commits"
f"?per_page=5")
result = subprocess.run(
["curl", "-s", "-H", "Accept: application/vnd.github+json",
"-H", "User-Agent: ai-monitor-bot", url],
capture_output=True, text=True, timeout=15
)
data = json.loads(result.stdout)
if isinstance(data, list):
return [{
"sha": c["sha"][:7],
"message": c["commit"]["message"].split("\n")[0],
"author": c["commit"]["author"]["name"],
"date": c["commit"]["author"]["date"]
} for c in data[:5]]
return []
关键点:-H "User-Agent: ai-monitor-bot" 是必须的——GitHub API要求所有请求带User-Agent头,否则返回403。
第二步:变更检测 + 去重
记录每个仓库"上次看到的版本",新数据来了做对比。
import os, json
from pathlib import Path
STATE_FILE = Path.home() / ".agent-monitor-state.json"
def load_state():
if STATE_FILE.exists():
return json.loads(STATE_FILE.read_text())
return {}
def save_state(state):
STATE_FILE.write_text(json.dumps(state, indent=2))
def check_for_updates(repos):
state = load_state()
updates = []
for name, owner_repo in repos:
print(f"🔍 Checking {name}...")
# 检查release
release = fetch_latest_release(owner_repo)
if release:
last_tag = state.get(f"{owner_repo}:tag", "")
if release["tag"] != last_tag:
updates.append({
"project": name,
"type": "release",
"tag": release["tag"],
"name": release["name"],
"body": release["body"],
"url": release["html_url"],
"published_at": release["published_at"]
})
state[f"{owner_repo}:tag"] = release["tag"]
# 检查commits(用于无release的项目)
commits = fetch_latest_commits(owner_repo)
if commits:
last_sha = state.get(f"{owner_repo}:sha", "")
if commits[0]["sha"] != last_sha:
# 只报告"新"的commits
new_commits = []
for c in commits:
if c["sha"] == last_sha:
break
new_commits.append(c)
if new_commits:
updates.append({
"project": name,
"type": "commits",
"commits": new_commits,
})
state[f"{owner_repo}:sha"] = commits[0]["sha"]
save_state(state)
return updates
设计要点:
- 用本地JSON文件存状态,不需要数据库
- 对比的是tag名称(不是日期),因为有时release会编辑更新
- commits追踪用于那些不打tag但持续更新的项目
第三步:生成更新摘要并推送
检测到更新后,生成一段摘要,调用微信草稿API推送。
WECHAT_APPID = "wxe3840e4d9c6e52ba"
WECHAT_SECRET = "51a81d46baf96d2c4b880148dbe69146"
def get_wechat_token():
"""获取微信stable_token"""
result = subprocess.run(
["curl", "-s", "-X", "POST",
"https://api.weixin.qq.com/cgi-bin/stable_token",
"-H", "Content-Type: application/json",
"-d", json.dumps({
"grant_type": "client_credential",
"appid": WECHAT_APPID,
"secret": WECHAT_SECRET
})],
capture_output=True, text=True
)
return json.loads(result.stdout).get("access_token")
def generate_summary_html(updates):
"""把更新列表转成微信草稿HTML"""
now = datetime.now().strftime("%Y-%m-%d %H:%M")
lines = [
'<div style="padding:24px 28px;font-family:\'PingFang SC\',\'Microsoft YaHei\',sans-serif;font-size:16px;color:#333;line-height:1.8">',
f'<p style="color:#888;font-size:14px">🤖 自动监控 · {now}</p>',
'<hr style="border:none;border-top:1px solid #eee;margin:16px 0">'
]
for u in updates:
if u["type"] == "release":
lines.append(
f'<h3 style="color:#1a73e8;margin-top:24px">'
f'📦 {u["project"]} {u["tag"]}</h3>'
)
lines.append(f'<p><strong>{u["name"]}</strong></p>')
# 取前500字作为摘要
body = u["body"].replace("\r", "")[:500]
lines.append(f'<pre style="background:#f5f5f5;padding:12px;'
f'border-radius:6px;font-size:14px;white-space:pre-wrap">'
f'{body}...</pre>')
lines.append(
f'<p><a href="{u["url"]}" style="color:#1a73e8">'
f'→ 查看完整Release Notes</a></p>'
)
elif u["type"] == "commits":
lines.append(
f'<h3 style="color:#1a73e8;margin-top:24px">'
f'🔧 {u["project"]} 新提交</h3>'
)
for c in u["commits"]:
lines.append(
f'<p style="margin:4px 0">'
f'<code>{c["sha"]}</code> {c["message"]} '
f'<span style="color:#999">— {c["author"]}</span></p>'
)
lines.append(
'<hr style="border:none;border-top:1px solid #eee;margin:16px 0">'
)
lines.append(
'<p style="color:#999;font-size:13px">'
'本监控由 Hermes Agent cron 定时任务自动生成</p>'
)
lines.append('</div>')
return "\n".join(lines)
def push_to_wechat_draft(title, html_content):
"""推送到微信草稿箱"""
token = get_wechat_token()
if not token:
print("❌ Failed to get WeChat token")
return False
payload = {
"articles": [{
"title": title,
"author": "AI创业内参",
"digest": "AI Agent工具链自动监控日报",
"content": html_content,
"content_source_url": "",
"thumb_media_id": "", # 监控日报不需要封面图
"need_open_comment": 0,
"only_fans_can_comment": 0
}]
}
result = subprocess.run(
["curl", "-s", "-X", "POST",
f"https://api.weixin.qq.com/cgi-bin/draft/add?access_token={token}",
"-H", "Content-Type: application/json; charset=utf-8",
"-d", json.dumps(payload, ensure_ascii=False)],
capture_output=True, text=True
)
resp = json.loads(result.stdout)
if "media_id" in resp:
print(f"✅ Draft submitted: {resp['media_id']}")
return True
else:
print(f"❌ Draft failed: {resp}")
return False
# ===== 主流程 =====
if __name__ == "__main__":
updates = check_for_updates(REPOS)
if not updates:
print("✅ No updates found. All quiet.")
exit(0)
print(f"🚨 Found {len(updates)} update(s)!")
for u in updates:
if u["type"] == "release":
print(f" 📦 {u['project']} → {u['tag']}")
else:
print(f" 🔧 {u['project']} → {len(u['commits'])} new commits")
title = f"🤖 AI工具链监控 {datetime.now().strftime('%m/%d %H:%M')}"
html = generate_summary_html(updates)
push_to_wechat_draft(title, html)
配置cron定时任务
把上面脚本保存为 ~/monitor-github.py,然后配置cron:
# 每15分钟运行一次
*/15 * * * * /usr/bin/python3 ~/monitor-github.py >> ~/monitor-github.log 2>&1
频率选择建议:
- 15分钟:适合快速响应的项目(Hermes Agent这种活跃更新的)
- 1小时:适合稳定项目
- 不要短于5分钟——GitHub API有频率限制,而且没必要
进阶扩展
扩展1:添加commit diff深度分析
当检测到新的commits时,可以拉取diff并让AI分析改动范围:
def fetch_commit_diff(owner_repo, sha):
url = f"https://api.github.com/repos/{owner_repo}/commits/{sha}"
result = subprocess.run(
["curl", "-s", "-H", "Accept: application/vnd.github+json",
"-H", "User-Agent: ai-monitor-bot", url],
capture_output=True, text=True, timeout=15
)
data = json.loads(result.stdout)
# files changed, additions, deletions
files = data.get("files", [])
stats = data.get("stats", {})
return {
"files_changed": len(files),
"additions": stats.get("additions", 0),
"deletions": stats.get("deletions", 0),
"changed_files": [f["filename"] for f in files[:10]]
}
如果 additions > 500 且涉及核心模块(如 hermes/agent/core.py),可以触发更高级别的告警。
扩展2:监控MCP生态
MCP Server的更新同样可以用这套框架追踪。维护一个MCP工具列表:
MCP_SERVERS = [
("Playwright MCP", "microsoft/playwright-mcp"),
("Filesystem MCP", "modelcontextprotocol/servers"),
("GitHub MCP", "modelcontextprotocol/servers"),
]
MCP生态变化往往意味着Agent能力边界的扩展——比如Playwright MCP加了新API,你的Agent就能做新的自动化操作。
扩展3:添加Discord/Slack通知
不想打开微信草稿箱?加一个webhook推送:
def notify_discord(webhook_url, message):
subprocess.run(
["curl", "-s", "-X", "POST", webhook_url,
"-H", "Content-Type: application/json",
"-d", json.dumps({"content": message})],
capture_output=True, timeout=10
)
常见问题
Q: GitHub API频率限制怎么办?
A: 未认证的请求限制是60次/小时。监控3个仓库、每15分钟一次 = 每小时12次请求,完全够用。如果监控10+个仓库,建议创建GitHub Personal Access Token(免费),限额提升到5000次/小时。
Q: 有些仓库用tag,有些用release,怎么统一?
A: 优先用releases端点(更结构化),fallback到tags端点。上面的代码已经处理了releases和commits两种模式。
Q: Release Notes太长怎么办?
A: 代码里已做500字截断。监控摘要的目的是"让你知道有更新",不是"替代阅读Release Notes"。摘要里保留链接,点击可以看完整的。
Q: 微信草稿箱的 thumb_media_id 为空可以吗?
A: 可以。微信允许不设置封面图,只是草稿箱列表里会显示默认图标。对监控日报这种功能型内容,没有封面图完全OK。
总结
这套监控Agent的底层逻辑非常朴素:定时拉数据 → 对比上次状态 → 发现变化就推送。你用任何语言都能实现,核心是三步:
- 数据获取:GitHub REST API,无需认证,curl就能调
- 变更检测:本地JSON文件记录"上次看到的版本"
- 结果推送:微信草稿箱API,走stable_token
最快15分钟就能跑起来。之后你只需要每天打开微信草稿箱看一眼——Agent帮你做完了所有繁琐的"刷GitHub"工作。
一个真实数据点:从2026年4月到6月,Hermes Agent发布了12个版本(v0.9.0 → v0.17.0),平均每5天一个版本。如果没有自动监控,你很可能错过其中一半。