🤖 AI 驱动的智能新闻聚合与摘要系统 —— 自动从多源抓取新闻,通过 LLM 进行价值评估、摘要生成和智能推荐。
多源聚合 — 支持 Hacker News、Lobsters、Reddit、RSS 等多种新闻源
AI 智能摘要 — 基于 LLM 自动生成中文摘要,并对每篇新闻进行价值评分 (1-10)
多渠道推送 — Web UI、终端 TUI、Slack、Telegram Bot 多通道分发
自动调度 — AgentManager 定时执行新闻采集与摘要,支持动态调整间隔
可观测性 — 内置 Prometheus Metrics + OpenTelemetry 分布式链路追踪
Telegram Bot — 支持命令控制 + 自然语言对话,随时查询最新摘要
┌─────────────────────────────────────────────────────────────────┐
│ index.ts (入口) │
│ 加载配置 → 初始化组件 → 启动 Agent & Web Server │
└──────────┬──────────────────────────────────────────┬───────────┘
│ │
▼ ▼
┌─────────────────────┐ ┌───────────────────────┐
│ AgentManager │ │ Delivery Layer │
│ (调度 & 生命周期) │ │ │
│ │ ┌──────────┐ │ ┌─── Web UI ───────┐ │
│ ┌───────────────┐ │ │ │ │ │ Bun.serve + SPA │ │
│ │ NewsAgent │──┼───▶│ NewsDB │◀──┼──│ REST API │ │
│ │ (AI 核心) │ │ │ (SQLite) │ │ └──────────────────┘ │
│ │ │ │ │ │ │ ┌─── Telegram Bot ──┐ │
│ │ Tools: │ │ └──────────┘ │ │ 长轮询 + LLM 对话 │ │
│ │ · fetch_news│ │ │ └──────────────────┘ │
│ │ · summarize │ │ │ ┌─── Slack ─────────┐ │
│ │ · categorize│ │ │ │ Webhook 推送 │ │
│ │ · recommend │ │ │ └──────────────────┘ │
│ └───────┬──────┘ │ │ ┌─── TUI ───────────┐ │
│ │ │ │ │ 终端渲染 │ │
└──────────┼─────────┘ │ └──────────────────┘ │
│ └───────────────────────┘
▼
┌─────────────────────────────────┐
│ Sources Layer │
│ ┌────────────┐ ┌────────────┐ │
│ │HackerNews │ │ Lobsters │ │
│ └────────────┘ └────────────┘ │
│ ┌────────────┐ ┌────────────┐ │
│ │ Reddit │ │ RSS │ │
│ └────────────┘ └────────────┘ │
└─────────────────────────────────┘
Sources → fetch_news → LLM 价值评估 & 摘要 → NewsDB → Delivery Channels
AgentManager 按配置间隔触发 NewsAgent.runDigest()
NewsAgent 通过 Tool Calling 驱动 LLM 自主决定:抓取哪些源、摘要什么、如何分类推荐
LLM 输出结构化 JSON(valuable 文章 + other 概述),解析后存入 NewsDB
完成后自动推送到已启用的 Delivery 渠道(Web / Telegram / Slack)
OpenNews/
├── index.ts # 应用入口:初始化并启动所有组件
├── config.json # 运行时配置(从 config.example.json 复制)
├── config.example.json # 配置模板
├── .env.example # 环境变量模板
│
├── src/
│ ├── config/
│ │ └── config.ts # 配置管理:类型定义、加载、env:前缀解析、源工厂
│ │
│ ├── agent/ # 🧠 AI Agent 核心
│ │ ├── agent.ts # NewsAgent - LLM 交互、Tool Calling、摘要生成
│ │ ├── manager.ts # AgentManager - 定时调度、生命周期管理
│ │ ├── tools.ts # Tool 定义:fetch_news / summarize / categorize / recommend
│ │ └── prompts.ts # 系统提示词:价值评分标准、输出格式要求
│ │
│ ├── sources/ # 📡 新闻源适配层
│ │ ├── types.ts # 接口定义:NewsItem, NewsSource, ProcessedNews, DigestResult
│ │ ├── hackernews.ts # Hacker News API 适配
│ │ ├── lobsters.ts # Lobsters API 适配
│ │ ├── reddit.ts # Reddit JSON API 适配
│ │ └── rss.ts # 通用 RSS/Atom Feed 解析
│ │
│ ├── storage/
│ │ └── db.ts # NewsDB - SQLite 存储(bun:sqlite)、去重、CRUD
│ │
│ ├── delivery/ # 📬 多渠道推送
│ │ ├── web.ts # Bun.serve Web UI + REST API
│ │ ├── telegram-bot.ts # Telegram Bot(长轮询 + 命令 + LLM 自然语言)
│ │ ├── telegram.ts # Telegram 消息推送工具函数
│ │ ├── slack.ts # Slack Webhook 推送
│ │ └── tui.ts # 终端 TUI 渲染
│ │
│ ├── scheduler/
│ │ └── scheduler.ts # Cron 调度器(简化版 cron 表达式解析)
│ │
│ ├── cli/ # CLI 入口脚本
│ │ ├── digest.ts # bun run digest - 单次执行摘要
│ │ ├── web.ts # bun run web - 仅启动 Web
│ │ └── tui.ts # bun run tui - 终端查看
│ │
│ ├── metrics.ts # Prometheus 指标(prom-client)
│ ├── telemetry.ts # OpenTelemetry 链路追踪
│ └── logger.ts # 统一日志(支持 --debug 模式)
│
├── web/ # 前端 SPA
│ ├── index.html # HTML 入口(Bun HTML Import)
│ ├── app.ts # 前端应用逻辑
│ └── styles.css # 样式
│
├── data/ # 运行时数据(SQLite DB)
└── docs/ # 项目文档
文件
职责
agent.ts
NewsAgent — 核心类。使用 @mariozechner/pi-ai 库与 LLM 交互,采用 Tool Calling 模式让 LLM 自主编排 fetch → summarize → categorize → recommend 流程
manager.ts
AgentManager — 管理 Agent 的生命周期与定时调度。支持 startAgent / stopAgent / runNow / updateInterval,执行完毕后再调度下一次(避免重叠)
tools.ts
定义 4 个 Tool 供 LLM 调用:fetch_news(抓取并去重存储)、summarize、categorize、recommend
prompts.ts
系统提示词。定义价值评分标准 (1-10)、可用分类标签、输出 JSON 格式要求
基于 NewsSource 接口的插件式设计,每个源实现 fetch(maxItems) 方法:
HackerNews — Top Stories API
Lobsters — Hottest API
Reddit — Subreddit JSON API(支持多 subreddit 配置)
RSS — 通用 RSS/Atom Feed 解析(支持多 feed URL)
NewsDB — 使用 bun:sqlite 的 SQLite 数据库
表:news_items(原始新闻)、processed_news(AI 处理结果)、digests(摘要记录)、agent_runs(Agent 运行历史)、app_config(运行时配置)
特性:WAL 模式、去重写入、崩溃恢复(清理 stale running 记录)
Delivery 层 (src/delivery/)
渠道
说明
Web UI
Bun.serve() 提供 SPA 前端 + REST API,支持 HMR 热更新
Telegram Bot
长轮询模式,支持 /digest、/run、/status 等命令,非命令消息走 LLM 自然语言对话
Slack
通过 Bot Token 推送格式化摘要到指定 Channel
TUI
终端渲染摘要结果,适合 CLI 使用
可观测性 (src/metrics.ts + src/telemetry.ts)
Prometheus Metrics (/metrics 端点):Digest 耗时、LLM 调用次数、工具执行时间、源抓取耗时、推送状态
OpenTelemetry Tracing :通过 withSpan() 包装关键路径生成分布式链路,支持 OTLP 导出到 Jaeger/Grafana
Bun v1.3.8+
至少一个 AI Provider 的 API Key(OpenRouter / Anthropic / OpenAI / DeepSeek)
# 复制配置模板
cp config.example.json config.json
# 编辑 config.json,填入 API Key 或使用 env: 前缀引用环境变量
# (可选)设置环境变量
cp .env.example .env
# 编辑 .env 填入 API Key
config.json 支持 env:VAR_NAME 语法自动从环境变量读取敏感信息。
# 启动完整服务(Web UI + Agent 定时调度)
bun run dev
# 或直接运行
bun run index.ts
# 立即执行一次摘要
bun run index.ts --now
# 仅终端查看最新摘要
bun run tui
参数
说明
--now / -n
启动后立即执行一次新闻摘要
--tui / -t
在终端显示最新摘要后退出
--debug / -d
开启调试模式(详细日志 + OpenTelemetry Console 输出)
启动后访问 http://localhost:3000,可用的 REST API:
端点
方法
说明
/api/digest
GET
获取最新摘要
/api/news/recent
GET
获取最近 24h 原始新闻
/api/agents
GET
获取所有 Agent 状态
/api/agents/:name/start
POST
启动 Agent
/api/agents/:name/stop
POST
停止 Agent
/api/agents/:name/run-now
POST
立即执行一次
/api/agents/:name/interval
PUT
更新执行间隔
/api/agents/history
GET / DELETE
Agent 运行历史
/api/config/telegram
GET / PUT
Telegram 配置
/metrics
GET
Prometheus 指标