Skip to content

YeeKal/ai-daily

Repository files navigation

AI Daily

筛选值得关注的 AI 信号

License: MIT Python 3.12+ uv managed RSS 400+ systemd

AI Daily Banner

AI 驱动的资讯聚合与推送系统|RSS · GitHub Trending · Hacker News 三大板块|LLM 智能评分|推送到 Discord / 飞书


核心特性

  • 🗞️ 三大内容板块 —— RSS 资讯(400+ 源)+ GitHub Trending + Hacker News 热帖,从媒体、开源、社区三个维度立体捕获 AI 动态
  • 🧠 LLM 智能筛选 —— 评分过滤 + 跨日去重,只留下值得读的
  • 即时推送 —— 热点新闻(≥90 分)实时触达,重大发布不错过
  • 📬 每日汇总 —— 定时早晚报,早报叠加跨板块洞察段
  • 🔌 多平台推送 —— 飞书、Discord 开箱即用,可扩展自定义平台
  • 🛠️ 零运维部署 —— systemd timer 一键安装,开机自启、故障重启

三大内容板块

📰 RSS 资讯聚合

聚合全球主流 AI 媒体、博客、Twitter 账号,默认 OPML 包含约 420 个优质源(源自 BestBlogs)。LLM 逐条评分,只保留高质量内容。

  • 默认 60 分钟轮询,异步并发抓取
  • 评分维度:相关度、信息密度、时效性
  • 跨日上下文去重,同一事件不重复推送

⭐ GitHub Trending

抓取 GitHub trending 页面,LLM 深读 README / topics / metadata,从昙花一现的玩具仓库里挑出真正值得关注的项目。

  • 从 top 10 候选中精选 3 个(可配置)
  • 输出 deep-dive 摘要,附技术亮点与上手建议
  • 历史去重索引,推过的项目不再出现

💬 Hacker News 热帖

跟踪 HN 首页 AI 相关讨论,整合外链正文 + 顶层评论树,产出"内容总结 + 社区观点"双段式摘要。

  • 轻量 LLM 从首页 30 条中选出最值得读的故事
  • 抓取 L1 顶层评论 + L2 关键回复,字符预算受控
  • 外链通过 Jina Reader 拉取 markdown 正文

系统架构

flowchart TB
    subgraph Sources["📥 数据源"]
        RSS["RSS Feeds<br/>400+ sources"]
        GH["GitHub Trending"]
        HN["Hacker News<br/>Front Page"]
    end

    subgraph Fetch["⚙️ Fetch 阶段"]
        F1["RSS Fetcher<br/>asyncio + feedparser"]
        F2["GH Scraper<br/>README deep-dive"]
        F3["HN Crawler<br/>Algolia + Jina Reader"]
    end

    subgraph LLMStage["🧠 LLM 评分与摘要"]
        Score["score / score_batch"]
        Digest["digest / immediate_push"]
        Insight["跨板块 insights"]
    end

    subgraph Store["💾 存储"]
        Files["news-data/<br/>fetch-*.json<br/>push-*.md"]
    end

    subgraph PushStage["📤 推送渠道"]
        Discord["Discord Webhook"]
        Feishu["飞书 Webhook"]
    end

    RSS --> F1 --> Score
    GH --> F2 --> Score
    HN --> F3 --> Score
    Score --> Digest
    Score --> Insight
    Digest --> Files
    Insight --> Files
    Files --> Discord
    Files --> Feishu
Loading

调度说明

  • dnews-fetch.service(默认每 60 分钟):抓取 RSS → 评分 → 命中 ≥90 分立即推送
  • dnews-push.service(按 push_cron):生成 digest 推送;当天最早一次额外触发 GitHub / HN / 跨板块洞察

快速开始

环境要求

  • Python 3.12+
  • uv (Python 包管理器)
  • Linux + systemd(推荐使用一键部署)

1. 配置环境变量

在项目根目录创建 .env 文件,添加以下配置:

# LLM API( OpenAI API 兼容接口)
DEEPSEEK_API_KEY=your_api_key_here

# 飞书 Webhook
FEISHU_WEBHOOK_URL=your_feishu_webhook_url_here

从模板拷贝一份本地配置(config.json 已加入 .gitignore,不会提交):

cp config.json.example config.json

然后在 config.json 中修改 llmpush

{
    "llm": {
        "provider": "<whatever>",  # openai compatiable 
        "model": "<model id>",
        "baseUrl": "<base url>",
        "apiKeyName": "DEEPSEEK_API_KEY", #your api key name in .env>
    },
    "push": {
        "feishu": {
            "enabled": true,
            "apiKeyName": "FEISHU_WEBHOOK_URL"
        }
    },

}

获取飞书群机器人 Webhook

详细教程参考:我用 RSS + LLM 搭建了一个 AI 热点追踪系统

  1. 群组右上角设置 → 群机器人 → 添加机器人
  2. 选择 自定义机器人 → 点击 添加 → 复制 Webhook URL

获取 Discord Webhook:

  1. 进入 Discord 服务器设置 →
  2. 整合 → Webhooks
  3. 创建新 Webhook,复制 URL

2. 一键部署(推荐)

将程序作为 systemd timer 部署,由系统负责定时触发、故障重启、开机自启。

./scripts/install.sh

脚本会自动同步依赖、安装 systemd 服务并按 config.json 中的调度配置启动定时任务,机器重启后自动恢复。安装成功后无需额外操作。

3. 手动运行(可选)

若不使用 systemd,也可以手动运行程序。先同步依赖(uv 会自动创建 .venv):

uv sync

程序提供的子命令:

uv run python -m src.main check    # 校验 LLM 接口可达性(部署期使用)
uv run python -m src.main fetch    # 单次抓取后退出(systemd timer 调用)
uv run python -m src.main push     # 单次推送后退出(systemd timer 调用)
uv run python -m src.main loop     # 长跑模式(本地开发/调试用)
uv run python -m src.main github       # 单跑 GitHub Trending 板块,打印不推送
uv run python -m src.main hackernews   # 单跑 Hacker News 板块,打印不推送

首次运行会自动创建 news-data/ 目录并开始抓取数据。

若未配置推送渠道,则可以在 news-data 目录查看生成的push信息


系统服务管理

部署完成后,使用以下命令管理服务。

常用命令

安装后 daily-news 进入系统 PATH,可在任意目录调用:

daily-news status [N]      # 查看 timer/service 状态 + 最近 N 行日志(默认 15)
daily-news logs            # 实时跟随日志(Ctrl+C 退出)
daily-news start           # 启动两个 timer
daily-news stop            # 停止两个 timer
daily-news restart         # 重启两个 timer(仅重置调度,不立即触发任务)
daily-news help            # 用法说明

手动立即触发一次任务(不影响下次调度):

sudo systemctl start dnews-fetch.service
sudo systemctl start dnews-push.service

修改配置后

./scripts/install.sh   # 重新跑一次即可,幂等(重新渲染单元 + restart timer)

修改 config.json 中的 schedulelog.retention_days 等需要重装;修改 .env 只需 daily-news restart

卸载

./scripts/uninstall.sh

卸载会移除 systemd 单元、/usr/local/bin/daily-news 和日志保留 drop-in;不会删除 news-data/ 数据。

日志保留

日志通过 systemd journald 命名空间 dnews 隔离,保留天数由 config.json 中的 log.retention_days 控制(默认 7 天)。不影响系统其他服务的日志。

日志查询

daily-news logs                                     # 实时跟随两个 service 的日志
daily-news status [N]                               # 查看状态 + 最近 N 行日志(默认 15)

journalctl --namespace=dnews -f                     # 实时跟随命名空间内全部日志
journalctl --namespace=dnews -u dnews-fetch -f      # 仅跟随 fetch service
journalctl --namespace=dnews -u dnews-push -f       # 仅跟随 push service
journalctl --namespace=dnews --since "1 hour ago"   # 查询近 1 小时日志
journalctl --namespace=dnews --since today          # 查询今日日志
journalctl --namespace=dnews -p err                 # 仅查询 error 级别及以上
journalctl --namespace=dnews --vacuum-time=1s       # 手动清空命名空间日志

配置详解(config.json)

完整的配置文件结构如下,每个字段都有详细说明:

{
    // 订阅源管理
    "sources": {
        "base_opml": "resources/rss.opml",  // 基础OPML文件,包含400+预设源
        "add": [  // 自定义添加的RSS源
            {
                "title": "OpenAI News",
                "xmlUrl": "https://openai.com/news/rss.xml",
                "category": "AI"
            }
        ],
        "block": [  // 手动屏蔽的源,精确匹配xmlUrl
            {
                "title": "Google Developers Blog",
                "xmlUrl": "https://developers.googleblog.com/feeds/posts/default"
            }
        ],
        "block_domains": ["*.substack.com", "*.youtube.com"]  // 域名屏蔽,支持通配符
    },

    // 内容过滤
    "filter": {
        "min_score": 60,  // 最低评分阈值,低于此分不推送
        "hot_threshold": 90,  // 热点阈值,达到立即即时推送
        "context_days": 3,  // 汇总时参考的历史天数
        "keep_days": 7,  // 数据保留天数
        "push_context_days": 5,  // 汇总推送去重的上下文有效天数
        "no_content_marker": "[NO_NEW_CONTENT]"  // LLM返回的无内容标记,用于判断是否跳过推送
    },

    // 日志配置(仅对 systemd 部署生效)
    "log": {
        "retention_days": 7  // journald 命名空间 dnews 的日志保留天数
    },

    // 调度配置
    "schedule": {
        "fetch_interval_minutes": 30,  // RSS抓取间隔(分钟)
        "fetch_lookback_minutes": 120,  // RSS冗余缓存时间(分钟),必须大于fetch_interval_minutes,用于防止RSS延迟导致漏读
        "push_cron": ["0 8 * * *", "0 17 * * *"],  // 定时推送cron表达式
        "timezone_hours": 8  // 时区偏移(8=北京时间)
    },

    // 抓取配置
    "fetch": {
        "max_workers": 10,  // 最大并发数
        "timeout": 10  // 单请求超时(秒)
    },

    // LLM配置
    "llm": {
        "provider": "openai",  // 提供商类型,openai只是知名该api接口时openai接口兼容,代码中并无实际使用
        "model": "x-ai/grok-4.1-fast",  // 模型名称
        "baseUrl": "https://openrouter.ai/api/v1",  // API端点
        "apiKeyName": "OPENROUTER_API_KEY",  // 环境变量名
        "max_prompt_chars": 128000,  // 单次prompt最大字符数
        "max_concurrent_batches": 3,  // 最大并发批次数
        "prompts": {  // prompt文件路径
            "score": "prompts/score.txt",
            "score_batch": "prompts/score_batch.txt",
            "immediate_push": "prompts/immediate_push.txt",
            "digest": "prompts/digest.txt"
        }
    },

    // 推送配置
    "push": {
        "discord": {
            "enabled": true,  // 是否启用
            "apiKeyName": "DISCORD_WEBHOOK_URL"  // Webhook环境变量名
        },
        "feishu": {
            "enabled": false,
            "apiKeyName": "FEISHU_WEBHOOK_URL"
        }
    }
}

sources —— 订阅源管理

字段 类型 说明
base_opml string 基础 OPML 文件路径,包含 400+ 预设 RSS 源
add array 自定义添加的 RSS 源,结构为 {title, xmlUrl, category}
block array 手动屏蔽的 RSS 源,精确匹配 xmlUrl
block_domains array 域名级别屏蔽,支持通配符(如 *.substack.com

filter —— 内容过滤

字段 类型 说明
min_score number 最低评分阈值,低于此分数的内容不参与推送(默认60)
hot_threshold number 热点阈值,达到此分数立即触发即时推送(默认90)
context_days number 上下文天数,汇总推送时参考的fetch数据历史天数(默认3天)
keep_days number 数据保留天数,超过天数的 JSON 文件会被清理
push_context_days number 汇总推送去重的历史push文件有效天数(默认5天)
no_content_marker string LLM 返回的无内容标记,当推送内容包含此字符串时跳过推送(默认"[NO_NEW_CONTENT]")

log —— 日志配置

仅对 scripts/install.sh 部署的 systemd 服务生效。

字段 类型 说明
retention_days number journald 命名空间 dnews 的日志保留天数(默认 7 天)。修改后需要重跑 ./scripts/install.sh

schedule —— 调度配置

字段 类型 说明
fetch_interval_minutes number RSS 抓取间隔,单位分钟(默认30分钟)
fetch_lookback_minutes number RSS 冗余缓存时间(分钟),必须大于 fetch_interval_minutes,用于防止 RSS 延迟导致漏读(默认120分钟)
push_cron array 定时推送的 cron 表达式数组,支持多个时间点。当天最早那次推送自动作为「早报」触发 GitHub / Hacker News / 跨板块洞察三段;其余时段为默认 RSS digest。若只配置一条 cron,则每次推送都视为早报
timezone_hours number 时区偏移小时数,用于时间显示(8 = UTC+8 北京时间)

cron 表达式说明:

表达式 含义
0 8 * * * 每天早上 8:00
0 17 * * * 每天下午 5:00
0 9,17 * * * 每天早上 9:00 和下午 5:00

格式:minute hour day month weekday

fetch —— 抓取配置

字段 类型 说明
max_workers number 最大并发数,同时抓取的 RSS 源数量
timeout number 单个请求超时时间,单位秒

llm —— 大语言模型配置

字段 类型 说明
provider string LLM 提供商(支持 openai 兼容接口)
model string 模型名称,如 x-ai/grok-4.1-fast
baseUrl string API 端点,如 https://openrouter.ai/api/v1
apiKeyName string 环境变量名称,系统会自动读取其值
max_prompt_chars number 单次 prompt 最大字符数,用于分批控制
max_concurrent_batches number 最大并发批次数
prompts object prompt 文件路径配置

push —— 推送平台配置

字段 类型 说明
discord.enabled boolean 是否启用 Discord 推送
discord.apiKeyName string Discord Webhook 的环境变量名
feishu.enabled boolean 是否启用飞书推送
feishu.apiKeyName string 飞书 Webhook 的环境变量名

sections (早报扩展板块)

仅在当天最早一次 push_cron 触发时生效(即「早报」时段)。详细设计见 docs/extra-sections-design.md

sections.github_trending

  • enabled: 是否启用
  • max_items: LLM 最终选出的项目数上限(默认 3)
  • max_deep_dive: 单次最多 deep-dive 的候选 repo 数(默认 10)
  • readme_max_chars: README 截断长度(默认 10000)
  • history_file: trending 去重索引文件路径
  • request_timeout: HTTP 超时秒
  • tokenName: GitHub token 环境变量名;不设时匿名调用(限 60 req/hr)

sections.hackernews

  • enabled: 是否启用
  • select_k: 轻 LLM 从首页 30 条中挑出的故事数(默认 1)
  • top_comments: 每个故事抓取的顶层(L1)评论数上限(默认 30)
  • top_l2_per_l1: 每条 L1 下挂的 L2 回复数上限(默认 3)
  • comment_max_chars: 单条评论(L1 或 L2) markdown 字符上限(默认 2000)
  • comments_total_chars: 整段评论树的总字符预算硬上限(默认 60000),防止离群 story 撑爆 prompt
  • link_content_max_chars: 外链正文截断长度(默认 50000)
  • request_timeout: HTTP 超时秒
  • algolia_base: Algolia API 基址
  • jinaTokenName: Jina Reader API key 环境变量名(默认 JINA_API_KEY);不设或对应环境变量为空时按匿名额度调用

sections.insights

  • enabled: 是否启用跨板块洞察段

扩展指南

添加新的 RSS 源

config.jsonsources.add 中添加:

"add": [
    {
        "title": "我的自定义源",
        "xmlUrl": "https://example.com/feed.xml",
        "category": "AI"
    }
]

添加新的推送平台

  1. src/push/ 目录下创建新文件,继承 PushPlatform 基类
  2. 实现 validate_config()send() 方法
  3. src/push/__init__.py 中注册

修改评分逻辑

编辑 prompts/score.txt,调整评分标准和权重。

自定义 LLM 模型

修改 config.json 中的 llm 配置:

"llm": {
    "model": "anthropic/claude-3-opus",
    "baseUrl": "https://openrouter.ai/api/v1",
    "apiKeyName": "OPENROUTER_API_KEY"
}

RSS 源说明

RSS 订阅源文件位于 resources/rss.opml,目前包含约 420 个订阅源。

RSS 订阅源初始整理自 ginobefun/BestBlogs,包含约 420 个 AI 领域优质信息源。

用户可自行配置 RSS 源文件,只需遵循 OPML 格,在 config.jsonsources.base_opml 修改文件路径即可。 同时用户可修改 sources.add或者 sources.block以在不破换OMPL文件的前提下对rss源进行增加或者删除。格式示例:

"sources": {
    "base_opml": "resources/rss.opml",
    "add": [
        {
            "title": "OpenAI News",
            "xmlUrl": "https://openai.com/news/rss.xml",
            "category": "AI"
        },
        {
            "title": "Chrome for Developers",
            "xmlUrl": "https://developer.chrome.com/static/blog/feed.xml",
            "category": "Chrome"
        }
    ],
    "block": [
        {
            "title": "Google Developers Blog",
            "xmlUrl": "https://developers.googleblog.com/feeds/posts/default"
        },
        {
            "title": "Microsoft for Developers",
            "xmlUrl": "https://devblogs.microsoft.com/landing"
        },
        {
            "title": "ElevenLabs Blog",
            "xmlUrl": "https://api.bestblogs.dev/feed/elevenLabsBlog"
        }
    ],
    "block_domains": ["*.substack.com", "*.youtube.com"]
}

常见问题 FAQ

LLM 调用费用大概多少?

取决于模型选择和源数量。以 OpenRouter 的 x-ai/grok-4.1-fast(便宜模型)为例,日均扫描 2000+ 条 RSS + GitHub + HN,单日成本约 ¥0.5-2 元。可通过 filter.min_scorellm.max_concurrent_batchesllm.max_prompt_chars 进一步控制。

如何只跑某一板块进行调试?
uv run python -m src.main github       # 只跑 GitHub Trending
uv run python -m src.main hackernews   # 只跑 Hacker News
uv run python -m src.main fetch        # 只跑 RSS fetch

打印结果到控制台,不触发实际推送。

抓取频率会不会被 RSS 站点封禁?

默认 30 分钟轮询一次,远低于大多数 RSS 服务的速率限制。fetch.max_workers 控制并发(默认 10),对单个站点的压力可忽略。

没配置推送渠道也能用吗?

可以。所有推送 markdown 都会落地到 news-data/push-*.md,即使所有推送平台 disabled 也可手动查看。

支持哪些 LLM 提供商?

任何 OpenAI API 兼容接口的服务:OpenAI、DeepSeek、OpenRouter、SiliconFlow、阿里云通义千问、Groq 等。修改 config.jsonllm.baseUrl / llm.model / llm.apiKeyName 即可切换。

GitHub Trending / Hacker News 为什么不出现?

它们只在当天最早一次 push_cron 触发时跑(即「早报」时段)。若 push_cron 只配了一条 cron,则每次推送都视为早报。详见「配置详解 → schedule」一节。

数据存储在哪里?多久清理?
  • 抓取数据:news-data/fetch-YYYY-MM-DD.json
  • 推送 markdown:news-data/push-YYYY-MM-DD-HH-MM-SS.md
  • 通知归档:news-data/notify-YYYY-MM-DD.md

超过 filter.keep_days(默认 7 天)的文件会自动清理;卸载脚本不会删除 news-data/


License

MIT License - see LICENSE file for details.

About

AI 驱动的新闻聚合与推送系统,筛选值得关注的 AI 信号

Topics

Resources

License

Stars

88 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors