Files
dataClean/README.md
T

198 lines
7.1 KiB
Markdown
Raw Normal View History

2026-06-12 16:04:03 +08:00
# dataClean
`dataClean``rssKeeper` 的下游数据清洗与加工服务,负责:
- 为无摘要或摘要过短的 RSS 文章生成 **AI 摘要**
- 维护本地 **分类/标签/打分规则表**,初始由 AI 生成,后续按规则执行
- 对文章自动 **分类、打标签**
- 计算三维度分数:**热度、重要性、多源重复性**
- 基于 URL 和 **内容相似度去重**
- 生成每日简报(**Markdown 文件 + 结构化 JSON/API**
- 提供 **Web UI** 可视化展示结果并管理配置
## 技术栈
- 后端:Python 3.12 + FastAPI + SQLAlchemy 2.0 + SQLite + APScheduler
- 前端:Vue 3.4 + Element Plus 2.6 + Vite 5 + Axios
- AIOpenAI API 兼容客户端
- 去重:scikit-learnTF-IDF 相似度)
## 快速开始
### 1. 环境配置
复制示例配置并修改:
```bash
cp .env.example .env
```
编辑 `.env`,至少配置:
```bash
RSSKEEPER_BASE_URL=http://localhost:7329
OPENAI_API_KEY=sk-xxx
OPENAI_BASE_URL=https://api.openai.com/v1
OPENAI_MODEL=gpt-4o-mini
# 生产环境务必设置 API TokenWeb UI 右上角可输入该 Token 后调用受保护接口
API_TOKEN=your-strong-token-here
# CORS 允许来源,逗号分隔;生产环境请填写具体域名
CORS_ALLOWED_ORIGINS=https://dataclean.example.com
```
### 2. Docker 运行(推荐)
```bash
docker-compose up -d --build
```
服务将运行在 `http://localhost:7331`Web UI 直接通过该地址访问。
### 3. 本地开发
启动后端:
```bash
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
uvicorn main:app --reload --port 7331
```
启动前端(新终端):
```bash
cd frontend
npm install
npm run dev
```
前端开发服务器运行在 `http://localhost:7332`,代理到后端 `http://localhost:7331`
## 核心流程
服务启动后:
1. 自动初始化 SQLite 数据库。
2.`app_settings` 表为空,使用 `.env` 中的值初始化默认配置。
3.`taxonomy` 表为空,调用 LLM 生成分类/标签/打分规则(仅一次)。
4. 启动定时任务:
- **摘要任务**:每 `SUMMARIZE_INTERVAL_MINUTES` 分钟(默认 60)拉取最近文章并补充 AI 摘要。
- **分类/打分/去重任务**:每 `TAG_SCORE_INTERVAL_MINUTES` 分钟(默认 1440,即 24 小时)执行。
- **每日简报**:每天 `08:00` 生成昨日/当日简报。
## Web UI 功能
| 页面 | 功能 |
|------|------|
| 仪表盘 | 统计卡片、分类分布、最近简报、定时任务下次执行时间 |
| 文章列表 | 搜索、分类/标签筛选、代表文章过滤、分页、综合分排序 |
| 文章详情 | AI 摘要、标签分类、热度/重要性/重复度/综合分、原文链接 |
| 每日简报 | 简报列表、按分类聚合展示、重新生成 |
| 分类体系 | 分类/标签/打分规则查看、手动触发 AI 重新生成 |
| 任务管理 | 手动触发摘要/分类/去重/简报任务 |
| 系统配置 | 查看和修改所有配置项,保存到数据库,重启后生效 |
## API 接口
| 接口 | 说明 |
|------|------|
| `GET /health` | 健康检查 |
| `GET /api/articles` | 查询加工后文章(返回 `{items, total}` |
| `GET /api/articles/{id}` | 单篇详情 |
| `GET /api/briefs` | 简报列表 |
| `GET /api/briefs/{date}` | 指定日期简报(YYYY-MM-DD |
| `POST /api/briefs/{date}/regenerate` | 手动重新生成简报(需 Token) |
| `GET /api/taxonomy` | 分类/标签/规则列表 |
| `POST /api/taxonomy/bootstrap?force=true` | 手动触发/重置分类体系(需 Token) |
| `POST /api/tasks/summarize` | 手动触发摘要任务(需 Token,互斥锁) |
| `POST /api/tasks/tag-score-dedup` | 手动触发分类/去重/打分任务(需 Token,互斥锁) |
| `POST /api/tasks/brief` | 手动触发简报生成任务(需 Token,互斥锁) |
| `GET /api/settings` | 获取所有可编辑配置(需 Token) |
| `PUT /api/settings/{key}` | 更新单个配置(需 Token) |
| `PUT /api/settings` | 批量更新配置(需 Token) |
| `POST /api/settings/reset` | 重置为 `.env` 默认值(需 Token |
| `GET /api/stats` | 仪表盘统计数据 |
## 目录结构
```
dataClean/
├── main.py # FastAPI 入口
├── config.py # 环境变量配置
├── database.py # SQLite 连接
├── models.py # SQLAlchemy 模型
├── scheduler.py # APScheduler 定时任务
├── Dockerfile # 多阶段构建(含前端)
├── docker-compose.yml
├── requirements.txt
├── .env.example
├── README.md
├── app/ # 后端业务模块
│ ├── rss_client.py
│ ├── ai_client.py
│ ├── taxonomy.py
│ ├── summarizer.py
│ ├── tagger.py
│ ├── scorer.py
│ ├── deduplicator.py
│ ├── brief.py
│ └── settings_manager.py
├── tests/ # 后端测试
└── frontend/ # Vue 3 Web UI
├── package.json
├── vite.config.js
├── index.html
└── src/
├── main.js
├── App.vue
├── router/
├── api/
├── style.css
└── views/
```
## 安全说明
- **API Token**:生产环境请务必设置 `API_TOKEN`。所有写入类接口(修改配置、触发任务、重新生成分类/简报)都需要在请求头携带 `Authorization: Bearer <token>`。Web UI 右上角提供 Token 输入框。
- **CORS**:默认不启用跨域 credentials。生产环境请通过 `CORS_ALLOWED_ORIGINS` 设置具体域名,避免 `*` + `allow_credentials=True` 的安全风险。
- **容器权限**Dockerfile 已使用非 root 用户 `app`uid=1000)运行服务。
## 与 rssKeeper 的关系
- dataClean **只读调用** rssKeeper 的外部 API`/api/v1/external/*`)。
- 所有加工结果(AI 摘要、标签、分数、去重组、简报)存储在 dataClean 本地 SQLite 中。
- 不回写 rssKeeper,避免耦合。
## 配置说明
配置分两层:
1. **环境变量(`.env`**:首次启动时的默认值,Docker 运行时使用。
2. **数据库配置(`app_settings` 表)**:通过 Web UI 修改后保存到这里,重启服务后生效。
详见 `.env.example`。关键配置:
| 变量 | 默认值 | 说明 |
|------|--------|------|
| `RSSKEEPER_BASE_URL` | `http://localhost:7329` | rssKeeper 服务地址 |
| `OPENAI_API_KEY` | - | LLM API Key |
| `OPENAI_MODEL` | `gpt-4o-mini` | 模型名 |
| `SUMMARIZE_INTERVAL_MINUTES` | 60 | 摘要任务间隔 |
| `TAG_SCORE_INTERVAL_MINUTES` | 1440 | 分类/打分/去重任务间隔 |
| `DAILY_BRIEF_HOUR` / `MINUTE` | 8 / 0 | 简报生成时间 |
| `TITLE_SIMILARITY_THRESHOLD` | 0.85 | 标题相似度阈值 |
| `CONTENT_SIMILARITY_THRESHOLD` | 0.80 | 内容相似度阈值 |
| `API_TOKEN` | - | API 鉴权 Token(为空不启用鉴权) |
| `CORS_ALLOWED_ORIGINS` | - | CORS 允许来源,逗号分隔 |
## 后续扩展
- 接入 rssKeeper 前端展示 enriched 数据
- 支持多语言摘要
- 接入向量数据库做语义检索
- 根据用户反馈调整 taxonomy 规则
- 引入 Alembic 数据库迁移
- Web UI 迁移到 TypeScript