Install
openclaw skills install @nemocccc/keep-me-updateDaily tech/AI/geek news digest powered by RSS + web search. 基于 RSS 和网络搜索的每日科技/AI/极客新闻摘要。触发后先交互配置,再自动生成。
openclaw skills install @nemocccc/keep-me-update每天从 RSS 源 + 网络搜索双渠道获取最新科技/AI/极客新闻,经筛选编排后生成「导读 + 链接」风格的摘要。
不依赖固定的配置文件,首次使用通过问答引导用户完成配置,配置存储在本地
user_config.yaml,后续自动复用。
"今天有啥新鲜事" / "keep me updated" / "最近科技圈发生了什么" / "latest tech news" / "what's new in AI"
持久化方案:用户配置写入 {skill_dir}/user_config.yaml,不依赖 agent 上下文和 memory。
关于交互配置模式的设计思路和复用方法,参见
references/config-flow.md。
# user_config.yaml 示例
language: zh
timezone: Asia/Shanghai
output_mode: terminal
output_dir: ~/DailyENews/
retention_days: 7
arxiv_retry: true
注意:
feeds_path不存储在配置中——脚本硬编码读取{skill_dir}/scripts/rss_feeds.json,首次使用需复制rss_feeds.default.json。
首次触发时,agent 按如下顺序依次询问用户。已有完整配置则跳过此步骤,直接进入 Step 1。
先尝试通过以下方式获取默认语言(按优先级):
locale 命令输出中的 LANG=zh_CN / LANG=en_US问题:"你要中文还是 English?(zh/en)"
先尝试读取系统时区:
readlink /etc/localtime 或 systemsetup -gettimezonetimedatectl show --value -p Timezone 或 /etc/timezone问题:"你在哪个时区?(如 Asia/Shanghai, America/New_York, Europe/London)"
问题:"摘要怎么给你?"
~/DailyENews/)。如选 file,补问路径。按用户回答设置 output_dir。
问题:"用我内置的源列表,还是你有自己的源要加?"
scripts/rss_feeds.default.json,包含 28 个高质量科技源(HN、TechCrunch、Ars Technica、36氪、IT之家、GitHub Trending、arXiv 等)。内置源分中英文两组,根据 language 自动选择。curl -sL -o /dev/null -w "%{http_code}" 检查 HTTP 状态码 + 确认返回 XML/RSS 格式)后加入 user_config.yaml。高级选项(可选询问):
配置写入后立即生效。后续触发时 agent 先读取 user_config.yaml,缺字段才补问。
python3 {skill_dir}/scripts/rss_fetch.py
⚠️ 首次使用前:确保
{skill_dir}/scripts/rss_feeds.json存在。默认源文件名为rss_feeds.default.json,首次运行需复制一份:bash cp {skill_dir}/scripts/rss_feeds.default.json {skill_dir}/scripts/rss_feeds.json脚本硬编码读取
rss_feeds.json(而非rss_feeds.default.json),user_config.yaml中的feeds_path字段仅作记录,不被脚本读取。
输出 JSON 到 stdout,包含 cache_file 路径和 total_articles。读取缓存文件获取完整文章列表。
注意: stderr 输出进度日志。JSON 在 stdout。如因控制字符解析失败,用 Python 直接
open(cache_file)读取。⚠️ URL 可能已过时:缓存中的 URL 路径可能在发布后发生变化(slug 被编辑、站点迁移、文章下架)。Ars Technica、DeepMind、TechCrunch 等源尤其常见。Step 5 生成导读时应基于 RSS 的
title和summary字段,不要依赖 URL 中的文字来推断新闻内容。Step 6.5 会做全量 HTTP 验证捕获失效链接。
arXiv 延迟: arXiv cs.AI 源首次抓取常返回
count: 0,同天稍后重试会正常。如arxiv_retry: true且total_articles< 50,建议重新拉取一次(脚本会自动跳过已读文章,通过seen_guids.json跟踪)。
如果 RSS 返回 total_articles = 0 或非常少(< 5):
rss_empty = true 供后续步骤知晓 RSS 池为空。因此,即使 RSS 无数据,仍必须执行 web search 兜底。Step 5.5 的链接验证池会仅包含 web search 结果。
运行 web_search,至少搜 3 组不同角度。根据 config 的 language 字段选择搜索词语言:
中文模式(language=zh):
"AI 人工智能 大模型 最新 2026"
"科技 数码 硬件 芯片 手机 新能源 汽车 评测"
"开源 GitHub 编程 开发者工具 框架 语言"
"互联网 科技公司 融资 IPO 财报 收购"
"网络安全 数据隐私 漏洞 攻击"
"机器人 具身智能 自动驾驶 航天 卫星"
英文模式(language=en):
"latest AI news today 2026"
"tech hardware gadgets chip smartphone EV"
"open source developer tools programming language framework"
"cybersecurity data breach vulnerability zero day"
"startup funding IPO acquisition tech companies"
"robotics autonomous driving space launch satellite"
"cloud computing infrastructure devops kubernetes"
如果 web_search 搜索返回空(DDG 被限流),切换到直接抓取知名新闻源首页:
# Hacker News 首页(开发者社区最热)
python3 {skill_dir}/scripts/search_web_stdlib.py "https://news.ycombinator.com" --fetch
# TechCrunch 首页(创业/科技商业)
python3 {skill_dir}/scripts/search_web_stdlib.py "https://techcrunch.com" --fetch
# Ars Technica 首页(深度科技)
python3 {skill_dir}/scripts/search_web_stdlib.py "https://arstechnica.com" --fetch
# The Verge 首页(消费电子/科技文化)
python3 {skill_dir}/scripts/search_web_stdlib.py "https://www.theverge.com" --fetch
# Wired 首页(科技文化/趋势)
python3 {skill_dir}/scripts/search_web_stdlib.py "https://www.wired.com" --fetch
提取技巧:HN 内容格式为
序号. 标题 ( 域名 )+分数 points by 用户 时间 ago,可用正则提取。TechCrunch 和 Ars 为文章标题列表。各源 --fetch 一次即可获取完整首页内容,比反复试搜索词更高效。⚠️ 重要:HN --fetch 不输出 URL。
search_web_stdlib.py --fetch提取的 HN 首页内容仅包含标题、域名、分数和评论数,不包含每条故事的实际链接(无论是 original URL 还是 HN 讨论页 URL)。因此从 HN --fetch 得到的标题不能直接使用——必须到 RSS 缓存或 web 搜索结果中交叉查找验证过的 URL。见 Step 3 的详细规则。
这是本技能最重要的质量关卡。
链接保真规则:
每条新闻的原文链接必须使用 RSS 或 web_search 返回的原始 URL。不得猜测、不得替换、不得凭记忆编写。
https://news.ycombinator.com/item?id=12345(HN 讨论页),链接就用这个。不要替换成所谓「原文」。https://techcrunch.com/...,链接就用 TechCrunch。不要替换成公司官网。uddg= 参数,解析出真实 URL 再使用。🚨 关键陷阱:非 HN 聚合源的 URL 同样可能不准确
Lobsters、Linux Reddit 等聚合源的 RSS 返回的 URL 通常是原始文章链接(Patreon、OMG Ubuntu、个人博客等),而非聚合站本身的讨论页。不得将 来源 字段标注为聚合源名称——必须标注 URL 实际指向的网站域名。
例如:
https://www.omgubuntu.co.uk/2026/06/audacity-4-0-beta → 来源写 OMG Ubuntu,不能写 Lobstershttps://github.com/... → 来源写 GitHub,不能写 Reddit处理方式同 HN --fetch 规则:从 RSS 缓存中按标题 keywords 提取真实 URL,或 web_search 搜索。都无法验证则放弃。
🚨 关键陷阱:HN --fetch 无 URL 问题
search_web_stdlib.py --fetch 抓取 HN 首页时,返回的内容中每条故事只有标题、域名和分数——没有可点击的 URL。这常引诱 agent 凭标题猜测 URL(如生成虚构的 news.ycombinator.com/item?id=XXXXXXXX)。
正确的处理流程:
articles_YYYY-MM-DD.json)中按标题关键词搜索,提取 RSS 返回的真实 URL自检方法(写入文件前必须执行):
# 检查是否有虚构链接残留
import re
content = open(filepath).read()
fake_patterns = ['item?id=48571526', 'item?id=12345678', '12345678', '23456789']
for p in fake_patterns:
if p in content:
raise ValueError(f"FAKE URL DETECTED: {p} — STOP. Do not write file.")
🔑 核心原则:链接就是信任。一条没有可验证 URL 的新闻,比一条有假 URL 的新闻好一百倍。宁可漏掉一条好新闻,也不要让读者点进一个不相干的页面。
按内容分配到 5 个板块。判断依据(按优先级从上到下):
| 板块 | 图标 | 判断逻辑 |
|---|---|---|
| 今日头条 / Top Headlines | 🔥 | 影响面广、跨领域。来源权重高(TechCrunch/Ars/HN首页/36氪头条)且标题无明显分类倾向 |
| AI 前沿 / AI & Models | 🤖 | 标题含 AI/模型/智能/LLM/Agent/机器人;来源为 arXiv/DeepMind/Nature AI |
| 极客开源 / OSS & Dev | ⚡ | 标题含 开源/GitHub/编程/框架/库/工具;来源为 GitHub Blog/Mozilla/Cloudflare |
| 科技公司 / Companies | 🏢 | 标题含 融资/收购/上市/财报/股价/IPO |
| 硬件消费电子 / Hardware | 📱 | 标题含 芯片/手机/iPhone/Mac/GPU/CPU/显示器/硬件 |
分类技巧:同一篇文章匹配多个分类时,按表从上到下优先级判断。AI 芯片归 AI 前沿而非硬件。
各板块建议条数:总计 15-25 条,按当日热度动态分配。
每条新闻写 1-2 句导读。风格(按配置语言):
中文示例:
Anthropic 发布 Claude Fable 5,首款公众可用的 Mythos 级模型。
华为 HDC 开幕,大会议程涉及「全新 UI design kit」,基本确认鸿蒙 7。
英文示例:
Anthropic launches Claude Fable 5, the first publicly accessible Mythos-tier model.
Huawei HDC kicks off with a 'new UI design kit' session, basically confirming HarmonyOS 7.
要点:为什么值得关注 + 核心信息。不要超过两句话。
程序化验证——不是建议,必须执行。在 Step 5 生成导读后、Step 6 写入前执行。
原理:收集 Step 1(RSS 缓存)和 Step 2(web search / --fetch)中所有出现过的真实 URL 构建来源池,检查每条待发表新闻的 URL 是否在池中。不在池中 = 可能是 agent 凭空生成的幻觉链接。
source_urls = set()
for a in rss_articles: source_urls.add(a['url'])
for e in websearch_results: source_urls.add(e['url']) # uddg= 已解析
for f in fetch_results: source_urls.add(f['url'])
for item in selected_articles[:]: # 遍历副本以便删除
url = item['url']
if url in source_urls:
continue
# 不在来源池——尝试按标题关键词模糊匹配
keywords = item['title'].split()[:4]
matched = [su for su in source_urls if any(k in su for k in keywords)]
if matched:
item['url'] = matched[0]
else:
selected_articles.remove(item) # 宁缺毋滥
此验证自动覆盖:编造 HN 讨论页 URL、混淆文章标题和链接、Lobsters 短链接错误展开等所有场景。无需额外规则。
根据 user_config.yaml 中的 output_mode:
terminal 模式:直接打印到 stdout。按模板格式输出完整内容。
模板文件位于
{skill_dir}/templates/report.{language}.md,包含以下占位符,agent 写入前必须全部替换:
{datetime}— 当前日期时间,含时区(如 2026-06-16 09:45 CST){total_articles}— RSS 新增文章总数{rss_ok}— 成功抓取的 RSS 源数{rss_total}— 总 RSS 源数{date_info}— 日期信息描述{headlines}/{ai_news}/{oss_news}/{biz_news}/{hardware_news}— 各板块新闻列表{selected_count}— 最终收录的文章数{extra_sources}— 额外数据源描述(如 "HN/TC/Ars --fetch")每板块内的新闻条目格式:
markdown ### {序号}. {标题} {1-2 句导读} > 来源: {来源名} · [原文链接]({URL})
file 模式:
import os, json, subprocess
from datetime import datetime, timezone, timedelta
# 1. 用 tz_offset.py 获取准确时区偏移
result = subprocess.run(
['python3', '{skill_dir}/scripts/tz_offset.py', config.timezone],
capture_output=True, text=True, timeout=10
)
tz_info = json.loads(result.stdout)
offset_hours = tz_info['offset_hours']
# 2. 计算本地时间
tz = timezone(timedelta(hours=offset_hours))
now = datetime.now(tz)
date_str = now.strftime('%Y-%m-%d')
time_str = now.strftime('%H%M')
# 3. 写入文件
base = os.path.expanduser(config.output_dir)
daily_dir = os.path.join(base, date_str)
os.makedirs(daily_dir, exist_ok=True)
filepath = os.path.join(daily_dir, f"KeepMeUpdate-{time_str}.md")
try:
with open(filepath, 'w', encoding='utf-8') as f:
f.write(content)
print(f"✅ 已写入: {filepath}")
except (OSError, PermissionError) as e:
# 4. 降级到 terminal 模式
print(f"⚠️ 文件写入失败 ({e}),降级到终端输出:")
print(content)
时区偏移量通过
tz_offset.py脚本计算,支持任意 IANA 时区名。如果文件写入失败(无权限、磁盘满等),自动降级到 terminal 模式并提示用户。
写入文件后,必须对每条链接执行 HTTP GET 验证,确认可达。这是防链接失真的最后一道物理防线。
优先使用可复用的验证脚本(比内联代码更健壮,不会被跳过):
python3 {skill_dir}/scripts/verify_links.py <filepath>
脚本功能:
⚠️ 常见失败模式:RSS 缓存的 URL 可能因 slug 变更、站点迁移或文章下架而 404。验证失败的链接必须回 RSS 缓存跨源匹配正确 URL(同一标题可能在另一个 feed 中有不同路径),无法匹配则移除整条新闻。
触发
raise后流程立即中止,必须先修复或移除断裂链接后重新验证。不得在验证失败的情况下交付摘要。
脚本使用 {skill_dir}/scripts/seen_guids.json 自动跟踪已读文章。无需额外操作——每次 rss_fetch.py 运行时,已抓取过的文章 GUID 会被记录,下次自动跳过。
如果需要强制重新抓取所有文章(例如首次配置后或想刷新 arXiv 数据),删除
seen_guids.json再运行脚本即可。
删除 output_dir 下超过 retention_days 天的旧目录。
注意: 跳过当天日期目录。先列出
output_dir下所有日期子目录,排除当天(datetime.now(TZ).strftime('%Y-%m-%d')),再逐个检查过期时间。
user_config.yaml 的 language 字段:zh 用中文输出,en 用英文输出以下规则固化在 SKILL.md 中,agent 每次执行都应遵守:
这些规则不依赖配置,是技能的核心质量标准。
关于交互配置模式的设计思路和复用方法,参见
references/config-flow.md。
{skill_dir}/
├── SKILL.md # 本文件
├── README.md # 用户指引
├── skill.json # ClawHub 元信息
├── scripts/
│ ├── rss_fetch.py # RSS 抓取引擎(stdlib only)
│ ├── rss_feeds.default.json # 默认 28 源列表
│ ├── search_web_stdlib.py # web 搜索兜底脚本(stdlib fallback)
│ ├── tz_offset.py # 时区偏移计算脚本
│ └── verify_links.py # 链接全量验证器(Step 6.5)
├── templates/
│ ├── report.zh.md # 中文输出模板
│ └── report.en.md # 英文输出模板
├── references/
│ └── config-flow.md # 交互配置模式说明
└── user_config.yaml # 用户配置(首次交互后生成,.gitignore 排除)
web_search 工具(DDG 搜索补充,可选 — 兜底方案纯 stdlib)