lovekeji-ai/keji-skills/ai-news-keji

Claude Code and agent skill by lovekeji-ai/keji-skills

Trust tier 3
  • community
Source check pending

Checking that the SKILL.md file is still in the repository.

生成 AI/科技新闻日报:从已配置的 Newsletter、RSS、可选外部来源和网站来源抓取、去重、评分并生成 Markdown。触发:用户说"生成日报 / AI日报 / 今日新闻 / 刷新日报 / fetch news / /ai-news-keji",或要求重新配置本 skill("改输出目录 / 重新配置 Newsletter / 重新选外部集成 / 更新个人偏好")。不触发:单纯"看看 BestBlogs 推荐"、"我关注的 AI builder"等请求,应交给对应的独立 skill。

Install

npx vskill@latest install lovekeji-ai/keji-skills/ai-news-keji

SKILL.md

AI 科技新闻日报

从用户配置的信息源生成适合 Obsidian 使用的 AI/科技新闻原始稿和摘要稿。

交互语言

所有面向用户的说明、进度更新、错误解释和最终回复都必须使用中文。命令、文件名、配置键、环境变量、URL、产品名和 Newsletter 名称保持原样。

启动工作流时不要用英文开场,例如不要说 “I'll start...”。应使用类似“我先检查 ai-news-keji 的初始化状态。”这样的中文说明。

运行约束(重要)

  • 所有 Python 命令默认使用 repo-local `.venv/bin/python`,优先从实际开发仓库根目录运行,而不是盲目假设 ~/.hermes/skills/... 就是可执行 repo。先用 scripts/doctor.py 确认当前环境指向的真实仓库路径;如果 doctor 输出了开发仓库(例如 ~/Code/ai-news-keji),后续 init.py / check-run-state.py / build-summary-context.py / fetch 脚本都从那个 repo root 执行,确保使用同一份 .venv、prompts/summary-template.md 和最新脚本。
  • 凭据只走环境变量:IMAP 账号/密码/授权码绝不写入 config.yaml,只通过 email.imap.username_env / password_env 指定的环境变量提供。
  • 不要把整份 raw JSON / normalized JSON / 原始稿 / transcript 直接喂给模型。heavy source 必须先 deterministic normalization,再构建 compact context,最后才进入 LLM 总结步骤。
  • cron / 无人值守场景下的 partial-run 默认策略:如果 check-run-state.py 显示 has_existing=true,且现有产物只有缓存、原始稿/摘要稿缺失,这类情况默认视为“补充抓取 / 补全产物”,优先复用已有缓存、补抓当前可用来源、重建 summary-context.md,然后补写原始稿和摘要稿;不要把这种 cache-only partial run 直接当成需要覆盖重跑的信号。
  • 网站来源与 compact context 的一致性要显式验证:抓到 websites.json 之后,必须确认当前 build-summary-context.py 是否真的把网站条目纳入 summary-context.md。如果没有纳入,就要么先补齐脚本/流程再依赖这些网站条目,要么明确把网站来源降级为“已缓存但未进入本轮 compact context”,不要声称它已经参与了原始稿/摘要稿生成。
  • email.mode = mcp 且目标时区为亚洲早晨时,Newsletter 搜索默认用近 2–3 天窗口再过滤目标日期:不要只按“目标日期当天”搜索 Gmail,因为美区 newsletter 经常在上海上午之前仍落在前一自然日或跨日边界。抓取后只保留命中白名单来源、且实际属于本轮日报的结构化条目。
  • 缓存结构化邮件或网页摘要前,先做不可见字符清洗:去掉零宽字符、方向控制符等隐形字符,再写 email-raw.json / 其他缓存,避免安全扫描把结构化缓存误判为可疑内容。

路径

所有文件都相对于 skill 目录解析,也就是包含 SKILL.md 的目录。

  • 本地配置:config.yaml
  • 公开配置模板:config.example.yaml
  • 本地来源:sources.yaml
  • 公开来源模板:sources.example.yaml
  • 初始化入口:scripts/init.py
  • 初始化向导:scripts/init_wizard.py
  • 运行状态检查:scripts/check-run-state.py
  • 摘要模板:prompts/summary-template.md
  • 健康检查:scripts/doctor.py
  • AI HOT 抓取脚本:scripts/fetch-aihot.py
  • RSS 抓取脚本:scripts/fetch-rss.py
  • IMAP 邮件抓取脚本:scripts/fetch-email-imap.py
  • 外部重型来源 normalization:scripts/normalize-external-source.py

运行工作流前:

  1. 在 skill 目录运行 .venv/bin/python scripts/init.py --check。
  2. 如果检查因为缺少 PyYAML 失败,运行 .venv/bin/python -m pip install -r requirements.txt,然后重试一次检查。
  3. 如果检查提示首次启动、缺少 config.yaml、缺少 sources.yaml、setup.initialized is not true,或“尚未完成初始化向导”,进入 Agent 分步初始化流程。优先使用 init.py --check 输出里的“建议开场”和“第 1 步问题”作为下一条用户消息;如果检查输出里没有这两段,运行 .venv/bin/python scripts/init.py 获取同样的分步提示。
  4. 初始化首轮消息固定只包含开场和第 1 步外部集成问题。第 1 步完成前,当前轮不读取 config.example.yaml 或 sources.example.yaml,也不展示 Newsletter、IMAP、输出目录或个人偏好问题。
  5. 分步初始化每轮只处理当前步骤;每一步都先用一句话说明这一步的作用,然后必须调用 `AskUserQuestion` 让用户用选项卡形式作答,不要让用户在普通对话里手敲文字回答。每步的选项设计、字段、文案细节见 references/init-flow.md;以 init.py / init_wizard.py 输出的"建议开场"和分步问题为准。用户提交答案后再推进下一步。
  6. 收集完全部答案后,把答案写入临时 JSON 文件,然后运行 .venv/bin/python scripts/init.py --answers-file <answers.json>。JSON 字段:external_skills、newsletter.choice、newsletter.host、newsletter.folder、newsletter.username_env、newsletter.password_env、output_dir、preferences。
  7. 写入配置后再次运行 .venv/bin/python scripts/init.py --check。只有检查通过后,才继续读取 config.yaml、sources.yaml 并抓取新闻。
  8. 可选外部 skills 或 CLI 只根据用户在初始化回答里的选择安装。

8.1 用户事后想改某一步配置("重新配置 Newsletter / 改输出目录 / 改个人偏好 / 重新选外部集成"),走 --reconfigure:先运行 .venv/bin/python scripts/init.py --reconfigure {external_skills|newsletter|output_dir|preferences} 获取该步的 AskUserQuestion 指令,收集答案后运行 .venv/bin/python scripts/init.py --answers-file <answers.json> --reconfigure <section> 写回 config.yaml,其他步骤保持原值不动。区分:仅追加安装一个外部 skill(不改任何已有答案)才用 --skills <name>;任何涉及"重新选 / 改回答"的场景都走 --reconfigure。

  1. 解析路径时展开 ~ 和环境变量。
  2. 不要把私有输出、原始邮件缓存、token 或用户专属配置写进准备发布的文件。

配置

使用 config.yaml 控制行为:

  • paths.output_dir:原始稿和摘要 Markdown 的写入目录
  • paths.filter_rules:评分规则和兴趣画像;未设置或文件缺失时使用内置示例
  • paths.cache_dir:原始来源数据和滚动去重状态的缓存目录
  • settings.default_date:yesterday 或 today
  • settings.retention_days:缓存清理窗口
  • settings.dedup_window_days:跨天去重窗口
  • settings.timezone:日期过滤时区
  • pipeline.enabled_sources:要尝试的来源组,例如 aihot、rss、email、external_skills、websites
  • pipeline.skip_unavailable_sources:缺少工具或凭据时跳过对应来源,而不是直接失败
  • email.mode:none、imap 或 mcp
  • email.imap.*:IMAP host、folder 和凭据环境变量名
  • external_skills.*:可选命令;只运行 enabled: true 的条目
  • notification.method:none、macos 或其他用户配置方式

配置不确定时,运行健康检查:

bash
.venv/bin/python scripts/doctor.py

缺少本地配置时,在 Agent 对话中收集初始化答案,然后写入临时 JSON 并运行:

bash
.venv/bin/python scripts/init.py --answers-file <answers.json>

抓取来源前,工作流必须通过这个检查:

bash
.venv/bin/python scripts/init.py --check

初始化检查通过后、抓取任何来源前,必须检查目标日期是否已经有运行产物:

bash
.venv/bin/python scripts/check-run-state.py --date YYYY-MM-DD --config config.yaml

如果输出里的 has_existing 为 true,除非用户在原始请求中明确说“强制刷新 / 覆盖重跑 / 忽略已有文件”,否则必须先停下来询问用户如何处理,不要直接抓取。除了 existing_kinds,还要检查:

  • is_partial_run
  • partial_reasons
  • source_states

用单选提问,先说明检测到哪些已有产物、哪些来源只跑了一半,再提供这些选项:

  • 使用已有结果:不抓取新数据。若摘要稿已存在,直接报告原始稿和摘要稿路径;若只有原始稿存在,则基于已有原始稿生成摘要。
  • 补充抓取:保留已有原始稿和缓存,只抓取当前可用来源的新内容;如果某个 heavy external source 只有 raw cache、还没完成 normalization,这个选项也负责先补完 normalization,再追加新条目并重写摘要。
  • 重新抓取并覆盖:清空目标日期缓存并覆盖当天原始稿和摘要稿;这个选项会覆盖已有结果,必须在说明里明确提醒。

频率规则

sources.yaml 里的每个来源都可以包含 frequency:

frequencyrule
daily每次运行都检查。
weekday目标日期是周六或周日时跳过。
3x_week每次运行都检查;没有新内容是正常情况。
weekly如果缓存显示最近 7 天已成功抓取,则跳过。
irregular每次运行都检查;经常没有新内容是正常情况。

被跳过的来源不是失败,也不应该生成空章节。

工作流

默认使用 settings.default_date 选择的日期。如果用户指定了日期,使用用户指定的日期。

1. 检查已有产物

先运行:

bash
.venv/bin/python scripts/check-run-state.py --date YYYY-MM-DD --config config.yaml

如果目标日期已经存在原始稿、摘要稿或缓存:

  1. 用中文告诉用户检测到的已有产物,例如“检测到 2026-04-25 已经有原始稿和 RSS 缓存”。
  2. 询问用户选择 使用已有结果、补充抓取 或 重新抓取并覆盖。
  3. 用户未选择前,不抓取 RSS、Email、外部 skills 或网站来源。
  4. 选择 使用已有结果 时,不改写已有原始稿;如摘要稿存在,直接结束并报告路径;如摘要稿不存在,只执行“生成摘要”步骤。
  5. 选择 补充抓取 时,继续后续抓取流程;若 partial_reasons 显示某个来源只有 raw cache,则先基于现有 raw cache 补跑 normalization,再决定是否需要重抓上游。写入原始稿时只追加新增内容,不删除已有内容。
  6. 选择 重新抓取并覆盖 时,先说明会覆盖目标日期文件;只有用户明确选择后,才清空 {paths.cache_dir}/YYYY-MM-DD/ 并覆盖 {paths.output_dir}/YYYY-MM-DD.md 与摘要稿。

如果没有已有产物,继续正常抓取。

2. 抓取来源

工具可用时,并行抓取已启用的来源组。

AI HOT

如果 pipeline.enabled_sources 启用了 aihot,优先把 AI HOT 作为无需 token 的原生 API 来源抓取。不要安装或调用 AI HOT 的独立 Agent Skill;当前 skill 已经通过稳定 REST API 接入。

bash
.venv/bin/python scripts/fetch-aihot.py --date YYYY-MM-DD --output {cache_dir}/YYYY-MM-DD/aihot.json
.venv/bin/python scripts/normalize-external-source.py --source aihot --input {cache_dir}/YYYY-MM-DD/aihot.json --output {cache_dir}/YYYY-MM-DD/aihot-normalized.json

默认抓 items?mode=selected,脚本会自动带 AI HOT API 要求的浏览器式 User-Agent,并按目标日期过滤 publishedAt。不要手写 curl 省略 UA,也不要把整份 API raw JSON 直接喂给 LLM;后续只让 build-summary-context.py 读取 aihot-normalized.json。

RSS

在 skill 目录运行:

bash
.venv/bin/python scripts/fetch-rss.py --date YYYY-MM-DD --config sources.yaml

如果缺少 sources.yaml,脚本会回退到 sources.example.yaml。

Email Newsletter

只有当 pipeline.enabled_sources 启用了 email 时,才使用已配置的 email 来源白名单。

支持的模式:

  • none:跳过邮件来源。
  • imap:运行内置 IMAP 抓取脚本。凭据必须来自 email.imap.username_env 和 email.imap.password_env 指定的环境变量。
  • mcp:当当前 Agent 运行环境提供 email/Gmail MCP 工具时使用该工具。

使用 IMAP 时,在 skill 目录运行:

bash
.venv/bin/python scripts/fetch-email-imap.py --date YYYY-MM-DD --config config.yaml --sources sources.yaml

IMAP 抓取脚本会搜索目标日期,用 BODY.PEEK[] 读取邮件以避免标记为已读,根据配置的发件人和可选 subject_contains 过滤邮件,尽可能提取纯文本,并把 JSON 输出到 stdout。

使用 MCP 时,搜索目标日期的邮件,根据配置的发件人和可选 subject 规则过滤,读取匹配邮件,并跳过欢迎邮件、订阅确认、纯赞助邮件、广告和招聘内容。

如果 IMAP 凭据或 MCP 工具不可用,且 pipeline.skip_unavailable_sources 为 true,则跳过邮件来源,并记录该来源组不可用。

外部 skills 和 CLI

对每个 enabled: true 的 external_skills.* 条目,运行其配置的命令。命令缺失、目录缺失或非零退出都视为来源失败;如果 pipeline.skip_unavailable_sources 为 true,则跳过并记录原因。

当前柯基的运行配置里,follow-builders 已从 ai-news-keji 主日报来源中移出,改由 Hermes cron follow-builders-standalone-daily 每天 07:00 单独抓取、推送,并写入 每日新闻/Follow Builders/YYYY-MM-DD.md;08:15 的 sync-follow-builders-to-ai-news-summary 会把该 section 同步进当天 YYYY-MM-DD 摘要.md。因此主日报流程不要因为 follow-builders 已安装就主动运行它;只有当 external_skills.follow-builders.enabled: true 时才按下面 heavy-source 流程处理。

对外部 skills 的结果要做可落库性检查。对 aihot、follow-builders(仅当配置显式启用)、bestblogs、ak-rss-digest 这类 heavy external source,必须先缓存 raw,再运行 deterministic normalization,最后才把 normalized items 带进写稿与摘要流程:

bash
.venv/bin/python scripts/normalize-external-source.py --source aihot --input {cache_dir}/YYYY-MM-DD/aihot.json --output {cache_dir}/YYYY-MM-DD/aihot-normalized.json
.venv/bin/python scripts/normalize-external-source.py --source follow-builders --input {cache_dir}/YYYY-MM-DD/follow-builders.json --output {cache_dir}/YYYY-MM-DD/follow-builders-normalized.json
.venv/bin/python scripts/normalize-external-source.py --source bestblogs --input {cache_dir}/YYYY-MM-DD/bestblogs.json --output {cache_dir}/YYYY-MM-DD/bestblogs-normalized.json --deep-read-bestblogs
.venv/bin/python scripts/normalize-external-source.py --source ak-rss-digest --input {cache_dir}/YYYY-MM-DD/ak-rss.json --output {cache_dir}/YYYY-MM-DD/ak-rss-digest-normalized.json

然后再继续下面这些规则:

  • 默认优先保留带直达原文链接的候选;有链接的条目在排序、归并和摘要时优先级更高。
  • 如果外部输出是超长转录、整段 Prompt、整份 digest 或明显未结构化的大块文本,先做源适配和事实抽取;如果当前轮做不到稳定抽取,就整源跳过并记录原因,不要把长噪音直接带进日报。
  • follow-builders 一类含长 podcast transcript / prompt 模板 / 汇总摘要的来源,默认不能整段直写,必须先拆成独立事件或明确跳过。
  • bestblogs 的 discover ... --json 结果里,readUrl 可能为 null。不要因为首层 JSON 没给链接就判定“无原文链接”。如果条目带有 resourceId,必须先尝试运行 bestblogs read deep <resourceId> 拉取详情;这个详情通常会返回可落库的 canonical URL 和正文 Markdown。
  • 如果通过 bestblogs read deep <resourceId> 成功拿到 URL,就按正常有链接条目处理,并优先使用 deep read 返回的 URL 作为原始稿和摘要稿链接。
  • 如果 bestblogs read deep <resourceId> 命中 RATE_LIMITED / 429,不要误记为“BestBlogs 无链接”。应把该来源标记为“本轮 deep read 受限流影响,待下轮补抓”,并保留 discover 层候选信息,方便下一轮或次日重试。
  • 解析 bestblogs read deep <resourceId> --json 时,先看 data.meta 是否已经给出 canonical URL / readUrl,再做 RATE_LIMITED / 429 字符串兜底判断;正文或支持链接里可能天然带有 429 数字,不能因此把成功的 deep-read 误判成限流。
  • 只有在 readUrl 为空、resourceId 不可用,或 bestblogs read deep <resourceId> 明确失败且不是限流时,才把该条目当作 BestBlogs 推荐摘要写入;此时必须明确标注它来自 BestBlogs 推荐、属于二手摘要、缺少直达原文链接,不要把它伪装成已核验的一手来源。
  • 对仍然没有原文链接的外部候选,摘要时应降低置信度和优先级;优先保留那些标题具体、摘要信息量足够、并且和用户关注方向强相关的条目。
  • 把 aihot、follow-builders、bestblogs、ak-rss-digest 视为 heavy external source:先缓存 raw,再做 deterministic normalization,再把 normalized items 交给去重/评分/写稿流程;不要把整段 transcript、tweet dump、prompt 或聚合摘要直接喂进日报。
  • check-run-state.py 返回 is_partial_run / partial_reasons / source_states 时,优先把它解释为“该日期可能只跑了一半”。如果用户没明确要求覆盖,先选择补完 normalization 或补生成摘要,而不是直接重抓覆盖。
  • 对这类改造或流程重构,默认由代理自己完成验证:至少跑 byte-compile、doctor.py、AI HOT 实网抓取 smoke test、heavy-source normalization 样本,以及 check-run-state.py 的 partial/complete 两种 fixture。
  • 如果修的是 BestBlogs deep-read / normalization 逻辑,额外保留一个最小回归:构造“stdout 是成功 JSON、data.meta.url 存在,但 markdown/帮助链接里带 429 数字”的样本;该样本必须仍被判定为成功,不能回退成 rate_limited。
  • 不要让“同厂商的次级生态消息”替代“当天真正的主发布”。如果同一天既出现某家前沿模型公司的旗舰发布(如新模型/新产品线/重大版本)又出现该公司的生态接入、SDK、平台集成、Framework 适配等消息,写稿前必须显式核对:日报是否已经覆盖了那条主发布。如果已经写了 Claude / OpenAI / Gemini / Grok / DeepSeek 的生态接入条目,但没写同日更大的旗舰发布,这应视为选题漏检,而不是合理取舍。
  • 对 Anthropic、OpenAI、Google、xAI、Meta、DeepSeek 等头部厂商,最终落稿前要做一次“厂商主发布 sanity check”:如果当天素材里出现该厂商名称,至少确认一次是否存在更高优先级的发布新闻被相邻条目(如 Apple framework 接入、SDK 发布、X 讨论、Benchmark 帖子)遮蔽。必要时保留两条,但不能只保留次级条目而漏掉主发布。

用户明确选择外部 skills 后,可通过初始化答案写入配置;如果只是追加安装某个外部 skill,可运行:

bash
.venv/bin/python scripts/init.py --skills follow-builders,bestblogs,ak-rss-digest

初始化脚本会把原始外部仓库安装到 external_skills.install_dir 下,并把选择的 skills 软链到 external_skills.link_targets。

它可以安装并启用:

  • follow-builders:把 zarazhangrui/follow-builders clone 到受管理的外部 skill 目录,在其 scripts/ 目录运行 npm install,并软链到已配置的 agent skill 目录。
  • bestblogs:安装 @bestblogs/cli,并提示用户运行 bestblogs auth login;不安装 BestBlogs 对话式 agent skills。
  • ak-rss-digest:clone rookie-ricardo/erduo-skills,把其中的 skills/ak-rss-digest 子 skill 链接到受管理的外部 skill 目录,并软链到已配置的 agent skill 目录。

网站来源

对 Readwise Weekly 等已配置网站来源,仅在浏览器或 web-fetch 能力可用时抓取。使用缓存避免重复抓取同一期周报。

3. 缓存原始数据

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 95 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
50
Repository forks
5
7-day trend score
0

Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/lovekeji-ai/keji-skills/ai-news-keji/badge)](https://verified-skill.com/skills/lovekeji-ai/keji-skills/ai-news-keji)

Something wrong with this skill or its page? Tell us.