Files
diary-news/news-aggregator-plan.md

614 lines
24 KiB
Markdown
Raw Normal View History

# 私人新闻汇总系统 · 方案设计 v0.1
> 适用环境:香港云服务器 / Ubuntu 24.04 LTS / Intel E5·Platinum / 30G SSD / IP 直访
> 目标受众:自己 + 家人/小圈子(2~10 人)
> 设计原则:**轻量、可控、可扩展、不被反爬干掉**
---
## 0. TL;DR(一页版)
- **架构**:前后端分离 + 单一 API 网关,采集 → 入库 → 翻译 → API → 前后端展示。
- **存储**:PostgreSQL 主库 + 本地文件(原文/图片)+ Redis 缓存。**30G SSD 是硬约束**,所以图片默认只存外链,正文做"近 30 天热保留 + 冷归档"两段式。
- **采集**:凌晨分波次拉取,每源独立 cron 表达式;RSS 走 `feedparser`,非 RSS 走 `trafilatura`/`playwright`
- **翻译**:腾讯云为主(500 万字符配额),超额走本地 `LibreTranslate`/`NLLB`;`title/summary/正文` 分块,字符用滑动窗口月度计数。
- **展示**:网页默认"过去 24h"瀑布流(原文 + 译文并列),Android(Kotlin · Jetpack Compose)走同套 API。
- **预留**:`category` / `commentary` / `entities` / `sentiment` 字段先建好,模型后插。
---
## 1. 系统总览
### 1.1 业务目标(为什么做)
1. **破除信息茧房**:同源 + 异源对照,可选集成 Ground News 立场标记。
2. **抗审查 / 抗算法推荐**:原始列表流,不做兴趣推荐(至少 MVP 不做)。
3. **可读可搜可归档**:私有领域做"个人情报库",不是又一个今日头条。
4. **成本可控**:跑在一台 30G 香港 VPS 上,月费用 ≤ 50 HKD。
### 1.2 非目标(明确不做)
- ❌ 不做内容创作/UGC
- ❌ 不做用户关注关系、社交
- ❌ MVP 不做推荐/个性化(后续可选)
- ❌ 不做 iOS 端(用户明确)
- ❌ 不做爬虫对抗到极致(愿意被 ban IP 就 ban)
### 1.3 用户与权限
| 角色 | 权限 |
| --- | --- |
| Owner(你) | 全部 + 源管理 + 翻译配额监控 + 用户管理 |
| Member(家人/朋友) | 只读 + 收藏 + 关键词订阅 |
| Guest(可后续加) | 只读 + 24h 滑窗 |
鉴权用 JWT + HTTP-Only Cookie(网页)/ Bearer Token(APP),密码 bcrypt。
---
## 2. 整体架构
### 2.1 分层(逻辑视图)
```
┌──────────────────────────────────────────────────────────┐
│ 表现层(Presentation) │
│ ├─ Web (Vue 3 / Vite, PWA, 自适应) │
│ └─ Android (Kotlin / Jetpack Compose, Material 3) │
└──────────────────┬───────────────────────────────────────┘
│ HTTPS / JSON (统一 API)
┌──────────────────▼───────────────────────────────────────┐
│ API 网关层 (FastAPI) │
│ ├─ /v1/articles /v1/sources /v1/subscriptions │
│ ├─ /v1/auth /v1/me /v1/search │
│ └─ /v1/admin/* (源/翻译/任务) │
└──────────────────┬───────────────────────────────────────┘
┌──────────────────▼───────────────────────────────────────┐
│ 业务服务层 (Service) │
│ ├─ article_service source_service │
│ ├─ translation_service (配额/降级/缓存) │
│ ├─ search_service subscription_service │
│ └─ enrichment_service (分类/点评/实体)预留 │
└──────────────────┬───────────────────────────────────────┘
┌──────────────────▼───────────────────────────────────────┐
│ 数据访问层 (Repository / ORM) │
│ └─ SQLAlchemy 2.0 (async) · Alembic 迁移 │
└──────────────────┬───────────────────────────────────────┘
┌──────────────────▼───────────────────────────────────────┐
│ 存储层 │
│ ├─ PostgreSQL 16 (结构化 + 全文检索) │
│ ├─ Redis 7 (缓存 / 队列 / 限流) │
│ └─ 本地文件系统 (HTML 快照 / 图片,可选) │
└──────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────┐
│ 后台层 (Background / Off-band) │
│ ├─ Scheduler (APScheduler) → 触发各源采集 │
│ ├─ Worker (asyncio task pool) → 解析/翻译/入库存 │
│ └─ Watchdog (健康检查 + 失败重试 + 告警) │
└──────────────────────────────────────────────────────────┘
```
### 2.2 部署视图(单机,30G 强约束)
```
┌──────── 香港 VPS (30G SSD) ────────┐
│ Docker Compose │
│ ├─ caddy (反代 + HTTPS) │
│ ├─ api (FastAPI) │
│ ├─ worker (后台 worker) │
│ ├─ scheduler (APScheduler) │
│ ├─ postgres (主库) │
│ ├─ redis (缓存) │
│ └─ meilisearch (可选,全文搜索) │
└────────────────────────────────────┘
```
- 数据卷预估(30G 总盘):
- 系统 + Docker images ≈ 5G
- PostgreSQL 30 天热数据 ≈ 3G(压缩 + 文本截断 8KB/篇上限)
- Redis 内存上限 256MB
- HTML 快照(可选,默认关闭)≈ 1G/30天
- 留 10G 以上 buffer → ✅ 余量充足
### 2.3 数据流(单篇文章生命周期)
```
[源站] → RSS/HTTP → 抓取器(原文 HTML)
解析(title/body/url/published_at/source)
去重(url hash + title simhash)
入 articles 表(原文)
翻译任务入队 → Tencent API → 译文回写
(可选)分类 / 实体 / 摘要任务
API 可被消费
```
---
## 3. 技术选型(明确推荐 + 备选)
| 层 | 推荐 | 备选 | 选它的理由 |
| --- | --- | --- | --- |
| 后端框架 | **Python 3.12 + FastAPI** | Node.js Nest / Go Fiber | 爬虫/解析/ML 库生态最好;中文分词/jieba 顺手 |
| ORM | SQLAlchemy 2.0(async) + Alembic | Tortoise ORM | 生态最熟,迁移稳 |
| 数据库 | **PostgreSQL 16** | SQLite | 全文检索 / JSONB / FTS 都好;SQLite 不支持并发写 |
| 缓存/队列 | **Redis 7** | dramatiq 单机 | 后续好扩;BullMQ 思路熟悉 |
| 任务调度 | APScheduler(进程内) | Celery beat | 30G 单机不需要重型 Celery |
| RSS 解析 | feedparser | — | 工业标准 |
| HTML 抽取 | **trafilatura** | newspaper3k / readability | 多语种 + 准确率高 + 快 |
| 动态渲染 | playwright(按需) | — | 仅对 JS 站点启用 |
| 翻译 SDK | tencentcloud-sdk-python | — | 官方 |
| 本地翻译 | **NLLB-200-distilled-1.3B**(INT8) | LibreTranslate | 离线 fallback |
| 网页前端 | **Vue 3 + Vite + Pinia + Naive UI** | Nuxt / SvelteKit | 学习成本低,产物轻 |
| Android | **Kotlin + Compose + Hilt + Retrofit + Room** | — | 你定 Kotlin |
| 反代 | Caddy | Nginx | 自动 HTTPS,配置短 |
| 监控 | Uptime Kuma(可选容器) | — | 1 个 docker,UI 美 |
> 30G 硬盘上不跑 ML 模型服务(太大)。本地翻译做成"按需调用小模型"或"调用本机 HTTP 接口",模型文件按需下载或不放服务器。
---
## 4. 采集层详细设计
### 4.1 源的分类(决定采集器)
| 类别 | 例子 | 采集器 |
| --- | --- | --- |
| RSS 完整 | Reuters / AP / BBC / Al Jazeera / NHK / DW / France24 | `feedparser` |
| RSS 部分 | NYT / Guardian(部分 RSS) | `feedparser` + 抓详情 |
| HTML 列表页 | Ground News / Bing News | `trafilatura` + 列表抽取 |
| Twitter/X | 暂不接(反爬代价高) | — |
| Telegram Channel | 用户后续可加 | Telethon 客户端 |
### 4.2 源配置(数据库表)
```sql
CREATE TABLE sources (
id BIGSERIAL PRIMARY KEY,
name TEXT NOT NULL, -- 'Reuters World'
slug TEXT UNIQUE NOT NULL, -- 'reuters-world'
kind TEXT NOT NULL, -- 'rss' | 'html_list' | 'tg_channel'
url TEXT NOT NULL, -- RSS URL 或 列表 URL
detail_selector JSONB, -- 详情页抽取规则(非RSS)
fetch_interval_min INT NOT NULL DEFAULT 60,
fetch_cron TEXT, -- 可选,覆盖 interval,例 '15 2 * * *'
translate_to TEXT NOT NULL DEFAULT 'zh', -- 目标语言
enabled BOOLEAN NOT NULL DEFAULT TRUE,
region TEXT, -- 'global' | 'eu' | 'cn' | ...
language_src TEXT, -- 源语种 'en' | 'auto'
priority INT DEFAULT 50, -- 1-100,影响翻译优先级
headers_json JSONB, -- 自定义 UA/Cookie
last_fetched_at TIMESTAMPTZ,
last_status TEXT, -- 'ok' | 'fail:timeout' ...
created_at TIMESTAMPTZ DEFAULT now()
);
```
> **手工配合实现 RSS 源预定**:暴露 `/v1/admin/sources` 的 CRUD + 网页表单,你手工一条条加。MVP 不做 OPML 导入,但保留口子。
### 4.3 调度策略
- **错峰**:不一次性 wake-up 全部源。按源的 `priority` + `region` 哈希,凌晨分散到不同分钟。
- **分层时间窗**:
- `priority ≥ 80`:每 30 分钟
- `priority 50~79`:每 2 小时
- `priority < 50`:每 6 小时 / 每日
- **退避**:某源连续 3 次失败,自动把 `fetch_interval_min` × 2,封顶 720min;成功一次后恢复。
- **统一超时**:单源 fetch ≤ 20s,parse ≤ 10s,失败即记日志,不入主流程。
### 4.4 去重
三层去重,严格度递减:
1. **URL 规范化 hash**(主键之 `url_hash` UNIQUE):去除 `utm_*`、hash fragment、尾斜杠。
2. **title simhash**:相同事件不同 URL 合并(MVP 标 `duplicate_of` 字段)。
3. **嵌入向量余弦**(后续):同主题聚类展示。
### 4.5 抓取器容错
- 限速:全局 QPS ≤ 4(礼貌),单源失败重试 3 次,指数退避。
- 代理:暂不用,先直连。香港出去对欧美/日本都通。
- 反爬:合规 UA + 极简 Cookie;若某源 `403/429` 高发,接 `playwright` 兜底。
- 法律:每篇保留来源链接 + 发布时间,不做全文二改,只翻译展示。
---
## 5. 翻译层详细设计
### 5.1 翻译策略(总分总)
| 字段 | 是否翻译 | 说明 |
| --- | --- | --- |
| title | ✅ 强制 | 优先级最高 |
| summary(若有) | ✅ 强制 | 摘要抽取后续接 |
| body(HTML→纯文本) | ✅ 强制 | 截断 8000 字/篇,超过分段 |
| 段落内嵌 HTML 标签 | ❌ 保留 | 翻译完按位置回插(用 `data-idx` 占位) |
**分块规则**:
- 按段落切分(双换行)
- 单段 > 1500 字符 → 强制按句号再切
- 单次 API 请求 body ≤ 5000 字符(腾讯 TMT 限制)
- 译文回写时按 `data-idx` 还原 DOM 结构
### 5.2 字符计量(关键:别超 500 万/月)
```python
# 月度计数器(Redis)
translation:month:202606 = 124533 # 当月已用
# 公式
total_chars = sum(len(seg.encode('utf-8')) // 2 + 1 for seg in segments)
# 用 Unicode 码点近似,腾讯 TMT 实际按"字符数"计
# 流程
pre_check(待翻译字符数) → if (已用+本次) < 500万 → 走腾讯
else → 走本地 NLLB
```
- **保留 5% 缓冲**:到达 475 万字符,自动切本地。
- **每月 1 日 00:00 HKT** 重置(用 cron + Redis SET)。
### 5.3 翻译缓存(白嫖配额)
- 缓存键:`sha1(source_id + url_hash + lang_pair + text)`
- 命中直接返回,不计字符。
- 命中率经验值:同源同事件重复抓 30~60%,月省 30%+ 字符。
### 5.4 失败降级
| 失败类型 | 处置 |
| --- | --- |
| 腾讯 TMT 429/5xx | 重试 2 次,仍失败 → 写 `translation_status='pending'`,后台重排 |
| 配额耗尽 | 切本地 NLLB(离线 INT8 模型) |
| 模型文件缺失 | 直接用原文 + 文末 `[本条未翻译]` 标记 |
| 段落超长截断 | 截断后用 `[...]` 占位,用户可点"展开"看原文 |
### 5.5 译文表结构(节选)
```sql
CREATE TABLE articles (
id BIGSERIAL PRIMARY KEY,
source_id BIGINT REFERENCES sources(id) ON DELETE CASCADE,
url TEXT NOT NULL,
url_hash CHAR(40) NOT NULL UNIQUE,
title TEXT NOT NULL,
title_zh TEXT,
body_html TEXT, -- 抽取后保留结构
body_text TEXT NOT NULL, -- 纯文本
body_zh_html TEXT,
body_zh_text TEXT,
lang_src TEXT, -- 'en' | 'ja' | ...
published_at TIMESTAMPTZ,
fetched_at TIMESTAMPTZ DEFAULT now(),
translated_at TIMESTAMPTZ,
translation_status TEXT DEFAULT 'pending', -- pending|ok|partial|failed|n/a
translation_engine TEXT, -- 'tencent' | 'nllb' | 'cache'
translation_chars INT DEFAULT 0,
category TEXT, -- 预留
commentary TEXT, -- 预留
entities JSONB, -- 预留
sentiment REAL, -- 预留 -1..1
duplicate_of BIGINT REFERENCES articles(id),
is_starred BOOLEAN DEFAULT FALSE,
created_at TIMESTAMPTZ DEFAULT now()
);
CREATE INDEX articles_published_at_idx ON articles (published_at DESC);
CREATE INDEX articles_source_id_idx ON articles (source_id);
CREATE INDEX articles_fts_idx ON articles
USING GIN (to_tsvector('simple', coalesce(title,'') || ' ' || coalesce(body_text,'')));
```
---
## 6. 数据层
### 6.1 PostgreSQL 必备扩展
- `pg_trgm`:title 相似度去重
- `btree_gin` / `pg_stat_statements`:性能/诊断
- `uuid-ossp`:不必须,主键用 BIGSERIAL
### 6.2 核心表(全清单)
```
sources 采集源配置
articles 文章主表(原文 + 译文)
article_media 文章图片/附件(默认只存 url)
users 用户
subscriptions 关键词订阅
bookmarks 收藏
read_history 阅读历史(可后续分析)
api_tokens API token(给 Android 用)
audit_logs 关键操作审计
```
### 6.3 备份
- `pg_dump` 每日凌晨 4 点 → 压缩到本地 `/var/backups/pg/`
- 保留 7 天滚动
- 强烈建议再 push 到一个外部对象存储(腾讯云 COS/阿里云 OSS)做异地灾备
- 30G 盘放不下 7 天全量 dump → 增量 + 每周一全量
### 6.4 冷热分层(防 30G 撑爆)
- 热数据:`published_at > now() - 30 day` 全字段
- 冷数据:`published_at <= now() - 30 day` 只保留 `title`/`title_zh`/`url`/`body_zh_text`(丢弃 `body_html` 原文)
- 90 天以上:进入"归档表" `articles_archive`,主表查询更轻
---
## 7. API 设计(RESTful + JSON)
### 7.1 设计原则
- 资源用复数名词:`/v1/articles`
- 时间分页用 `?since=<rfc3339>&until=...&limit=...&cursor=...`
- 错误用 RFC 7807 `application/problem+json`
- 列表返回精简字段,详情返回全字段
- 所有时间 ISO8601 + UTC(前端自行渲染本地)
### 7.2 鉴权
- 登录:`POST /v1/auth/login` → 返回 access(15min) + refresh(7d)
- APP:用长期 API Token(`api_tokens` 表),可撤销
- Admin 接口:`/v1/admin/*` 强制 `role=owner`
### 7.3 核心端点(MVP)
| Method | Path | 说明 |
| --- | --- | --- |
| `GET` | `/v1/articles` | 列表,默认过去 24h。支持 `source` / `lang` / `q` / `cursor` |
| `GET` | `/v1/articles/{id}` | 详情(原文 + 译文 + 媒体 + 实体) |
| `GET` | `/v1/sources` | 源列表(已登录用户) |
| `GET` | `/v1/me` | 当前用户信息 + 翻译配额 |
| `POST` | `/v1/bookmarks` / `DELETE /v1/bookmarks/{article_id}` | 收藏 |
| `POST` | `/v1/subscriptions` | 创建关键词订阅(正则/简单词) |
| `GET` | `/v1/search?q=...` | 全文检索 |
| `GET` | `/v1/stats/usage` | 翻译字符用量,管理端可见 |
| `POST` | `/v1/admin/sources` | 新增/更新源 |
| `POST` | `/v1/admin/refresh/{source_id}` | 手动触发某源抓取 |
| `POST` | `/v1/admin/translation/rerun/{article_id}` | 重译 |
### 7.4 示例
```http
GET /v1/articles?since=2026-06-07T00:00:00Z&limit=50&source=reuters,bbc
Authorization: Bearer <token>
200 OK
{
"items": [
{
"id": 1234,
"source": {"id": 1, "name": "Reuters", "region": "global"},
"title": "Fed signals ...",
"title_zh": "美联储暗示 ...",
"published_at": "2026-06-07T08:32:00Z",
"lang_src": "en",
"translation_status": "ok",
"summary_zh": "...",
"category": "finance",
"has_commentary": false
}
],
"next_cursor": "eyJ..."
}
```
---
## 8. 表现层
### 8.1 网页(Web)
- **首屏**:过去 24h 卡片瀑布,按时间倒序。可切"按源" / "按地区"。
- **详情页**:左原文 / 右译文并列,可关一侧;底部"分类 / 点评 / 实体 / 相关"预留位。
- **暗模式**:跟随系统。
- **PWA**:可"添加到主屏幕",离线缓存最近 50 篇。
- **技术**:Vue 3 + Vite + Pinia + Vue Router + Naive UI;纯静态构建,首次加载 < 200KB gzip。
### 8.2 Android App
- **架构**:Clean Architecture(Compose UI → ViewModel → UseCase → Repository → Retrofit/Room)
- **关键页面**:
1. Feed(24h 列表,下拉刷新、无限滚动)
2. 详情(原文/译文 Tab 切换,字号调节,长按收藏,生词本高亮)
3. 源管理(只读 + 启停)
4. 订阅/收藏
5. 搜索
6. 设置(主题、语种、配额、API 地址)
- **关键库**:Hilt、Retrofit + OkHttp、Kotlinx Serialization、Room(本地缓存)、WorkManager(周期同步 + 推送通道预留)、DataStore(偏好)
- **目标**:APK < 10MB,minSdk 26。
---
## 9. 机器学习/智能功能(预留接口,MVP 不实现)
| 功能 | 字段 | 触发 | 模型 |
| --- | --- | --- | --- |
| 自动分类 | `category` | 入库后 | zero-shot:MDeBERTa / bge 嵌入 + 简单聚类 |
| 一句话点评 | `commentary` | 入库后 | 小尺寸 instruct LLM,本地或 API |
| 实体识别 | `entities`(人/地/机) | 入库后 | GLiNER / spaCy |
| 情感 | `sentiment` | 入库后 | twitter-roberta |
| 摘要 | `summary_zh` | 入库后 | 抽取式(首段+关键句)优先 |
| 主题聚类 | `topic_id` | 每日跑 | DBSCAN / HDBSCAN |
| 跨源立场 | `bias_left/center/right` | 后续 | 对接 Ground News 数据 |
所有这些做成 **enrichment pipeline**,在 worker 里顺序挂 hook,MVP 全部 `null`,字段都在。
---
## 10. 部署与运维
### 10.1 目录结构
```
/srv/news/
├─ docker-compose.yml
├─ .env # 密钥
├─ caddy/Caddyfile
├─ api/
├─ worker/
├─ scheduler/
├─ migrations/ # alembic
└─ data/
├─ postgres/
└─ backups/
```
### 10.2 .env(示例,不要提交)
```
POSTGRES_PASSWORD=***
REDIS_PASSWORD=***
TENCENTCLOUD_SECRET_ID=***
TENCENTCLOUD_SECRET_KEY=***
TENCENTCLOUD_REGION=ap-hongkong
TENCENT_TMT_QUOTA_MONTH=5_000_000
JWT_SECRET=***
DOMAIN=news.example.com # 或裸 IP
```
### 10.3 启动
```bash
docker compose up -d
docker compose exec api alembic upgrade head
docker compose exec api python -m app.scripts.seed_sources
```
### 10.4 监控
- Uptime Kuma:Docker 一行,UI 看 API/Postgres/Redis 状态
- API 自带 `/healthz``/metrics`(Prometheus 格式,可选)
- 翻译配额告警:每 6h 检查,> 80% 推送到 Telegram bot
### 10.5 安全
- Caddy 自动 HTTPS(域名)或自签(裸 IP)
- Fail2ban 守护 SSH
- 数据库/Redis 不暴露 5432/6379 端口
- API 限流:每用户 60 req/min(IP + user 双维度)
- 密码 bcrypt cost=12
---
## 11. 开发路线图(我自己拍的时间,别太较真)
### Phase 0 · 立项(1 天)
- 决策:技术栈 + 服务器初始化
- 建仓 + CI 草稿
### Phase 1 · MVP(2~3 周)
- ✅ 采集器(RSS 5 个源,跑通)
- ✅ 入库 + 翻译(腾讯云,带缓存)
- ✅ 网页:列表 + 详情
- ✅ 鉴权(单用户,自用)
- ✅ 凌晨调度跑通
### Phase 2 · 扩源 + 体验(2 周)
- 源扩到 20+,加 HTML 列表
- 网页:筛选、搜索、PWA
- 配额监控 + 告警
- 备份脚本
### Phase 3 · Android(2~3 周)
- APP 端到端
- 推送通道(可选 FCM / WebPush → Telegram)
- 离线阅读
### Phase 4 · 智能增强(2 周+)
- 分类/摘要/实体
- 主题聚类 + 周报邮件
- 跨源立场
---
## 12. 补充功能(你可能没想到的,先列给你筛)
### 12.1 内容维度
- **全文搜索** + 高亮(网页 + APP 双端)
- **关键词订阅**:命中即通知/邮件
- **收藏 + 标签**:自建标签,可视化分类
- **阅读历史 + 统计**:今日/本周阅读时长
- **导出**:单篇 Markdown / 批量 CSV / 邮件简报
- **每日精选邮件**(凌晨 7 点,前 24h 摘要)
- **实体时间线**:同一人物/机构多源跟踪
- **反信息茧房视图**:同一事件并排多源报道
- **媒体偏见可视化**(后续接 Ground News 数据)
### 12.2 系统维度
- **RSS 源管理 UI**(代替手工 SQL)
- **翻译配额仪表盘**(用量趋势/剩余天数)
- **源健康看板**(抓取成功率、平均延迟)
- **手动重抓 / 重译**
- **内容删除/合规** 工具(被 DMCA 时一键下架)
- **多用户**:家人/朋友的子账号 + 独立收藏
- **iOS PWA**:用网页 PWA 顶一下,先不写原生
- **Telegram 推送机器人**:最简通知渠道
- **2FA / Passkey**:管理员登录加一道锁
- **API Token**:给 Android 用,可独立撤销
- **审计日志**:谁看了什么(隐私 vs 共享的可调)
- **全文快照开关**:合规要求下可一键保留 HTML 留证
### 12.3 体验维度
- **暗模式**(网页 + APP)
- **字号/行距** 调节
- **TTS 朗读**(浏览器 `SpeechSynthesis` 一行调用)
- **生词本 / 翻译对照高亮**
- **滑动操作**(APP 端快速收藏/已读)
- **桌面小组件**(APP)
- **侧边栏:今日摘要 + 配额 + 源状态**
- **快捷键**(网页 j/k 上下条,o 打开,s 收藏)
### 12.4 还没想清楚(留个尾巴)
- **法律边界**:翻译展示是否构成"公开展示"?如果是私人圈(2~10 人)风险低;但要避免做"开放注册"
- **内容版权**:只展示摘要 + 链接,正文翻译控制在合理比例(MVP 设 8KB 上限,实际只占原文 30~60%)
- **是否做付费墙破解**:❌ 不做,放弃相应源
---
## 13. 风险与对策
| 风险 | 概率 | 影响 | 对策 |
| --- | --- | --- | --- |
| 源站改版,抓取失效 | 高 | 中 | 解析器独立可热更新;失败率高自动暂停源 |
| 腾讯翻译额度爆 | 中 | 中 | 本地 NLLB 兜底;每日用量监控 |
| 香港 VPS 被墙/限速 | 中 | 高 | 多源冗余;备选新加坡/日本节点 |
| 30G 硬盘撑爆 | 低 | 高 | 冷热分层 + 外部备份 |
| 源站发律师函 | 低 | 高 | 摘要化展示 + 链接跳转原文 |
| 多人共用导致配额紧张 | 中 | 低 | 默认每日 10 万字符上限,可调 |
---
## 14. 第一次跑起来你要做的事
1. 服务器初始化(Ubuntu 24 + Docker + Caddy)
2. 注册腾讯云账号,开通文本翻译 TMT,拿 Secret
3. 选 5 个最常用的源(我建议:Reuters、BBC World、Al Jazeera、NHK World、DW),先把 RSS URL 备齐
4. 我这边起仓写代码,3 周后跑 MVP
5. 跑稳后加 Android + 智能功能
---
**下一步**:你看完这个方案,挑几个点:
- ① 哪些功能要砍/加?
- ② 技术栈有没有要换的(比如你就是想用 NestJS 不用 FastAPI)?
- ③ MVP 的 5 个源定哪几个?
- ④ 想不想让我现在就开始 Phase 1 的代码?
回我一句就行。