docs: 补充 README 说明文档(系统运转流程/配置/API/接入真实源指南)

This commit is contained in:
2026-08-28 15:31:55 +08:00
parent 5e0dbccc21
commit 2b8e78a4cc
+197
View File
@@ -0,0 +1,197 @@
# 📰 新闻智能跟踪系统(news-tracker
一款面向 AI 领域的**自动采集 → 智能分析 → 邮件推送**的新闻跟踪系统。后台定时从数据源采集资讯,先规则打分、再 LLM 深度分析,把与你兴趣画像相关且重要的资讯**实时发邮件提醒**,并每天 10:00 发一份**AI 资讯日报**。带完整网页管理台,兴趣画像/数据源/通知参数全部可配。
> 当前版本 v1.0.1(补充说明文档);当前数据源为**高仿真模拟数据**(simulate.py),全链路已跑通,接入真实源只需在 sources 适配层实现 `fetch()`。
---
## 系统运转流程(一张图看懂)
```
┌──────────┐ ┌──────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ 数据源 │ │ 后台调度器 │ │ 智能分析引擎 │ │ 邮件通知 │
│ sources │───▶│ scheduler │───▶│ analysis.py │───▶│ notifier.py │
│ (7个默认) │ │ (后台线程) │ │ (规则+LLM两级分析) │ │ (实时+日报) │
└──────────┘ └──────────────┘ └──────────────────┘ └─────────────────┘
模拟源 fetch() 每30分钟采集一次 规则打分→候选 LLM完成→重要度判定
simulate.py (scan_interval_min) →后台LLM深度分析 →发实时邮件
每天10:00日报 →实时/日报邮件
```
**完整链路:**
1. **采集**(每 `scan_interval_min` 分钟,默认 30):`scheduler.collect_once()``simulate.fetch_simulated()` 拉取新资讯 → 按 URL 去重 → 入库 `articles` 表。
2. **规则打分**(立即):`analysis.analyze_article()` 对每条新资讯算**兴趣相关度**(关键词命中权重 + 领域匹配 + 关注公司命中)和**重要度启发式**(发布/融资/禁令等强信号词、金额量级、时效性、数据源权重、公司影响),得到**综合分 total_score (0-100)**。
3. **LLM 深度分析**(后台异步):规则分 ≥ `llm_threshold`(默认 60)的资讯进入 `llm_analyze()`,调用 DeepSeek 输出重要度 1-10、相关度、分类、一句话结论,并与规则分融合更新。
4. **实时通知**:扫描「重要 + 已分析完成 + 未通知」的资讯,综合分 ≥ `realtime_threshold`(默认 80)→ 发 **🔥 重要AI资讯实时提醒** 邮件,标记 `notified=1`
5. **每日日报**(默认每天 10:00):汇总往前 `summary_window_hours`(默认 24h)内综合分 ≥50 的资讯,按分排序取前 `max_summary_items`(默认 15)条发 **📰 AI资讯日报**,含领域分布统计。
---
## 功能特性
- 📥 **自动定时采集**:数据源可增删改、可启停,每源带权重(影响重要度打分)
- 🧠 **两级智能分析**:规则打分秒级响应 + DeepSeek LLM 深度分析(重要度/相关度/分类/结论)
- 🔥 **实时重要资讯邮件**:综合分达到阈值自动推送,单批最多 10 条
- 📰 **每日 AI 资讯日报**:默认每天 10:00,按领域统计 + 重点资讯卡片
- 🎯 **兴趣画像管理**:关键词(带权重)、领域、关注公司,全部可在网页维护,改完一键「重新打分」
- 🔗 **数据源管理**:7 个内置数据源模板,启停/权重/类型自由配置
- 📊 **网页管理台**:仪表盘(总数/重要/待分析/趋势/领域分布)、资讯列表(筛选/搜索/分页)、详情页、通知日志
- 📧 **邮件通知**:支持 plain / starttls / ssl 三种 SMTP 模式,可测试发送
- 🛠 **手动操作台**:一键采集 / 一键 LLM 分析 / 一键发日报 / 一键造数据 / 重新打分 / 测试邮件
---
## 技术栈
- **后端**Python 3 + Flaskthreaded
- **数据库**SQLite(原生 sqlite3WAL 模式,无 ORM
- **大模型**DeepSeek `deepseek-v4-flash`OpenAI 兼容接口,`response_format=json_object`
- **前端**:原生 HTML/CSS/JS + Jinja2 模板(无前端框架)
---
## 目录结构
```
news-tracker/
├── app.py # Flask 主应用:页面路由 + API
├── config.py # 全局配置(端口/LLM/邮件/自动化默认值/默认画像/数据源模板)
├── db.py # SQLite 数据访问层(原生 sqlite3
├── scheduler.py # 后台调度器:定时采集 + 每日日报 + 实时通知扫描
├── analysis.py # 智能分析引擎:规则打分 + LLM 深度分析
├── simulate.py # 模拟数据源(真实源接入前跑通全链路)
├── notifier.py # 邮件通知(实时 / 日报,plain/starttls/ssl
├── start.sh # 启动/停止/状态脚本
├── templates/ # Jinja2 页面模板
├── static/ # 静态资源
├── data/ # news_tracker.db(运行时生成)
└── logs/ # 运行日志 + app.pid
```
---
## 快速开始
```bash
cd works/news-tracker
./start.sh # 启动(默认端口 16100
./start.sh status # 查看状态
./start.sh stop # 停止
./start.sh restart # 重启
```
访问:`http://<服务器IP>:16100/`
> ⚠️ 端口 16100 属于外网安全组白名单区间(16001-16100),可直接公网访问。
> 首次启动自动初始化:写入默认数据源/兴趣画像/设置,并 `simulate.seed_all()` 造一批模拟资讯 + 后台跑一轮 LLM 分析。
---
## 配置说明
所有默认值在 `config.py`,运行时可在网页「设置」页修改并持久化到数据库(网页优先级更高):
### 自动化参数(设置页)
| 配置项 | 默认值 | 说明 |
|--------|--------|------|
| `auto_collect` | 1 | 是否自动定时采集 |
| `scan_interval_min` | 30 | 采集扫描间隔(分钟) |
| `realtime_threshold` | 80 | 综合分 ≥ 该值 → 实时邮件通知 |
| `llm_threshold` | 60 | 规则分 ≥ 该值 → 进入 LLM 深度分析 |
| `realtime_enabled` | 1 | 是否启用实时重要资讯邮件 |
| `summary_enabled` | 1 | 是否启用每日汇总 |
| `summary_time` | 10:00 | 每日汇总时间 |
| `summary_window_hours` | 24 | 汇总窗口(往前 N 小时) |
| `max_summary_items` | 15 | 汇总邮件最多条目数 |
### 邮件配置(设置页)
`smtp_host` / `smtp_port` / `smtp_user` / `smtp_pass` / `smtp_mode`(plain|starttls|ssl) / `email_to` / `sender_name`。默认 `mail.tphai.com:587` plain,收件人 `wlq@tphai.com`
### 大模型配置(改 config.py
`LLM_BASE_URL` / `LLM_API_KEY` / `LLM_MODEL` / `LLM_TIMEOUT` / `LLM_MAX_TOKENS` / `LLM_TEMPERATURE`
---
## 网页页面
| 路由 | 说明 |
|------|------|
| `/dashboard` | 仪表盘:总资讯/重要资讯/待分析/已通知 + 近7天趋势 + 领域分布 |
| `/news` | 资讯列表:按领域/重要/关键词搜索,分页 |
| `/news/<id>` | 资讯详情:规则分/LLM分/实体/分析结论 |
| `/sources` | 数据源管理:增删改、启停、权重 |
| `/profile` | 兴趣画像:关键词/领域/公司维护 |
| `/logs` | 通知日志(实时/日报发送记录) |
| `/settings` | 设置:自动化参数 + 邮件配置 + 测试 |
---
## API
| 接口 | 方法 | 说明 |
|------|------|------|
| `/api/stats` | GET | 统计数据(总数/重要/趋势/领域分布) |
| `/api/sources` | POST | `action=add\|update\|delete\|toggle` 数据源管理 |
| `/api/profile` | POST | `action=add\|delete``kind=keyword\|domain\|company` 画像维护 |
| `/api/settings` | POST | 更新 `auto` / `mail` 设置 |
| `/api/actions` | POST | `action=collect`(采集) `llm`(LLM分析) `summary`(发日报) `seed`(造数据) `reanalyze`(重新打分) `test_mail`(测试邮件) |
请求体为 JSON,如:`{"action": "collect"}``{"action": "llm", "limit": 10}`
---
## 数据模型
- **sources**:数据源(name/type/url/weight/enabled/status/last_fetch/last_count
- **articles**:资讯(title/url/content/summary/domain/entities/importance/relevance/total_score/is_important/analysis/llm_status/notified/status/published_at/collected_at
- **keywords** / **domains** / **companies**:兴趣画像
- **notification_log**:邮件通知日志
- **settings**KV 配置(`auto` / `mail` 为 JSON
`llm_status``pending`(待分析) → `done`(完成) / `skipped`(未达标跳过) / `error`(失败)
**综合分公式**`total_score = 0.4 × 相关度 + 0.6 × 重要度`LLM 分析后按 `0.6×规则分 + 0.4×LLM分量` 融合)
---
## 接入真实数据源
当前用 `simulate.py` 模拟采集跑通全链路。接入真实源只需:
1. 新建 `sources_xxx.py`,实现 `fetch() -> list[dict]`,返回结构与模拟源一致:
```python
# 每条 dict 至少含:
# title, url, content(或summary), published_at(YYYY-MM-DD HH:MM:SS), domain, entities(list)
```
2. 在 `scheduler.collect_once()` 里把 `simulate.fetch_simulated()` 换成真实 `fetch()`(可多源合并)。
3. 其余逻辑(去重/打分/LLM/通知/网页)**无需改动**。
---
## 当前状态
- ✅ 服务运行中:端口 **16100**
- ✅ 数据库已有 **32 条**资讯(重要 12 条,LLM 已分析 12 条,已通知 12 条)
- ✅ 邮件链路已验证(`mail.tphai.com:587` plain,收件人 `wlq@tphai.com`
- 🕐 数据源为模拟数据,等待接入真实源
---
## 常见问题
- **收不到邮件?** 在设置页点「测试邮件」;确认 `smtp_mode` 与端口匹配(plain 一般不加密、starttls 用 587、ssl 用 465)。
- **想立即看效果?** 数据管理页(`/api/actions` 手动)点「立即采集 / LLM 分析 / 发送日报」。
- **改了兴趣画像想重新算分?** 点「重新打分」(reanalyze)即可全量重跑规则打分。
- **日志在哪?** `logs/app.log`(服务日志)+ 网页 `/logs`(通知日志)。
---
## Git
- 仓库:`hz4th_coder/news-tracker`
- 版本:`v1.0.0`(初版)→ `v1.0.1`(补 README