inital
This commit is contained in:
335
DESIGN.md
Normal file
335
DESIGN.md
Normal file
@@ -0,0 +1,335 @@
|
||||
# 医药新闻聚合系统 — 设计方案
|
||||
|
||||
> 版本:v1.0 | 日期:2026-05-24
|
||||
|
||||
---
|
||||
|
||||
## 一、项目目标
|
||||
|
||||
每日自动抓取全网中英文医药新闻(约 100 条),经 AI 深度加工后精选 10 条,以网页形式展示,未来对接微信小程序。
|
||||
|
||||
---
|
||||
|
||||
## 二、整体架构
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────┐
|
||||
│ 定时调度器 │
|
||||
│ APScheduler (每日 06:00) │
|
||||
└───────────────────────┬─────────────────────────────┘
|
||||
↓
|
||||
┌─────────────────────────────────────────────────────┐
|
||||
│ 抓取层 Crawler │
|
||||
│ RSS Fetcher │ HTTP Scraper │ NewsAPI Client │
|
||||
│ (中文源) │ (备用) │ (英文源) │
|
||||
└───────────────────────┬─────────────────────────────┘
|
||||
↓ 原始新闻 (~100条/天)
|
||||
┌─────────────────────────────────────────────────────┐
|
||||
│ 数据库 PostgreSQL │
|
||||
│ raw_news │ processed_news │ llm_config │
|
||||
│ │ news_sources │ system_logs │
|
||||
└───────────────────────┬─────────────────────────────┘
|
||||
↓
|
||||
┌─────────────────────────────────────────────────────┐
|
||||
│ AI 处理流水线 │
|
||||
│ 1. 相关性过滤(去除非医药内容) │
|
||||
│ 2. 去重(相似度检测) │
|
||||
│ 3. 摘要生成(中文,150字) │
|
||||
│ 4. 观点提炼(核心结论/影响) │
|
||||
│ 5. 关键词提取(5-8个标签) │
|
||||
│ 6. 重要性评级(1-10分 + 理由) │
|
||||
│ 7. 分类标注(4个类别) │
|
||||
│ 8. 精选 TOP 10 │
|
||||
└───────────────────────┬─────────────────────────────┘
|
||||
↓
|
||||
┌─────────────────────────────────────────────────────┐
|
||||
│ FastAPI 后端 │
|
||||
│ 读者 API │ 管理员 API │
|
||||
│ GET /news │ POST /admin/llm-config │
|
||||
│ GET /news/{id} │ GET /admin/sources │
|
||||
│ GET /news/featured │ POST /admin/trigger-crawl │
|
||||
└───────────────────────┬─────────────────────────────┘
|
||||
↓
|
||||
┌───────────────┴───────────────┐
|
||||
↓ ↓
|
||||
┌──────────────┐ ┌──────────────────┐
|
||||
│ Vue 3 前端 │ │ 未来:微信小程序 │
|
||||
│ 读者页 + 管理 │ │ (复用同一 API) │
|
||||
└──────────────┘ └──────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 三、技术栈
|
||||
|
||||
| 层级 | 技术 | 版本 | 说明 |
|
||||
|------|------|------|------|
|
||||
| 任务调度 | APScheduler | 3.x | 每日定时触发,支持手动触发 |
|
||||
| 爬虫 | httpx + BeautifulSoup4 | — | 异步 HTTP,HTML 解析 |
|
||||
| RSS 解析 | feedparser | — | 解析 RSS/Atom 订阅源 |
|
||||
| AI 调用 | 统一适配层(见下) | — | 支持多 LLM 提供商切换 |
|
||||
| 后端框架 | FastAPI | 0.11x | 异步,自动生成 OpenAPI 文档 |
|
||||
| 数据库 | PostgreSQL 16 | — | 主存储,支持全文搜索 |
|
||||
| ORM | SQLAlchemy 2 + Alembic | — | 数据模型 + 迁移 |
|
||||
| 前端框架 | Vue 3 + Vite | — | 组合式 API |
|
||||
| UI 组件库 | Element Plus | — | 中文生态好,适配小程序迁移 |
|
||||
| 部署 | Docker Compose | — | 容器化,国内服务器一键启动 |
|
||||
|
||||
---
|
||||
|
||||
## 四、LLM 适配层设计
|
||||
|
||||
> 国内服务器无法直连 Claude API,需要支持可切换的 LLM 提供商。
|
||||
|
||||
```python
|
||||
# 统一接口,后端只调用这一层
|
||||
class LLMClient:
|
||||
provider: str # "openai" | "anthropic" | "qwen" | "deepseek" | "custom"
|
||||
api_key: str
|
||||
base_url: str # 支持自定义 endpoint(代理/国内镜像)
|
||||
model: str
|
||||
|
||||
async def complete(self, messages: list, response_format="json") -> str:
|
||||
# 内部适配不同 provider 的 SDK/HTTP 接口
|
||||
...
|
||||
```
|
||||
|
||||
**支持的 LLM 提供商(管理页可配置):**
|
||||
|
||||
| 提供商 | 说明 | 推荐模型 |
|
||||
|--------|------|----------|
|
||||
| DeepSeek | 国内可直连,性价比高 | deepseek-chat |
|
||||
| 通义千问 (Qwen) | 阿里云,国内服务器友好 | qwen-plus |
|
||||
| OpenAI 兼容 | 走代理或第三方中转 | gpt-4o-mini |
|
||||
| Anthropic Claude | 走代理 | claude-sonnet-4-6 |
|
||||
| 自定义 Endpoint | 私有部署模型 | 自填 |
|
||||
|
||||
---
|
||||
|
||||
## 五、数据库模型
|
||||
|
||||
```sql
|
||||
-- 新闻来源配置
|
||||
news_sources (
|
||||
id, name, url, type ENUM('rss','scrape'),
|
||||
language ENUM('zh','en'), category, is_active,
|
||||
created_at, updated_at
|
||||
)
|
||||
|
||||
-- 原始抓取数据
|
||||
raw_news (
|
||||
id, source_id, title, url, raw_content,
|
||||
published_at, crawled_at,
|
||||
status ENUM('pending','processed','skipped','error')
|
||||
)
|
||||
|
||||
-- AI 处理后数据
|
||||
processed_news (
|
||||
id, raw_news_id,
|
||||
title_zh, -- 中文标题(英文原文翻译或原标题)
|
||||
summary, -- 中文摘要(150字)
|
||||
opinion, -- 核心观点/影响(100字)
|
||||
keywords TEXT[], -- 关键词数组
|
||||
importance_score, -- 重要性 1-10
|
||||
importance_reason, -- 评分理由
|
||||
category ENUM('药品监管','临床研究','行业动态','政策法规'),
|
||||
is_featured BOOL, -- 是否入选当日 TOP 10
|
||||
featured_rank, -- TOP 10 排名
|
||||
processed_at
|
||||
)
|
||||
|
||||
-- LLM 配置(管理页维护)
|
||||
llm_config (
|
||||
id, name, provider, api_key, base_url,
|
||||
model_name, is_active, created_at
|
||||
)
|
||||
|
||||
-- 系统运行日志
|
||||
system_logs (
|
||||
id, event_type, message, details JSONB, created_at
|
||||
)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 六、AI 处理 Prompt 设计
|
||||
|
||||
每条新闻用一次 LLM 调用,返回结构化 JSON:
|
||||
|
||||
```
|
||||
你是医药行业资深分析师。请分析以下新闻,返回 JSON 格式结果。
|
||||
|
||||
新闻标题:{title}
|
||||
新闻内容:{content}
|
||||
新闻语言:{zh|en}
|
||||
|
||||
请返回:
|
||||
{
|
||||
"is_medical_related": true/false, // 是否与医药相关
|
||||
"title_zh": "中文标题",
|
||||
"summary": "中文摘要(100-150字)",
|
||||
"opinion": "核心观点或行业影响(50-100字)",
|
||||
"keywords": ["关键词1", ..., "关键词5"],
|
||||
"importance_score": 1-10,
|
||||
"importance_reason": "评分理由(30字内)",
|
||||
"category": "药品监管|临床研究|行业动态|政策法规"
|
||||
}
|
||||
|
||||
评分标准:
|
||||
9-10: 重大政策/突破性研究/重要监管决定
|
||||
7-8: 行业重要动态,影响范围广
|
||||
5-6: 常规行业新闻,有一定参考价值
|
||||
1-4: 普通资讯,信息价值有限
|
||||
```
|
||||
|
||||
**TOP 10 精选策略:**
|
||||
1. 过滤掉 `is_medical_related = false`
|
||||
2. 按 `importance_score` 降序排列
|
||||
3. 每个 category 至少保留 1 条(保证多样性)
|
||||
4. 最终取前 10 条
|
||||
|
||||
---
|
||||
|
||||
## 七、新闻数据来源(初始列表)
|
||||
|
||||
### 中文 RSS 源
|
||||
| 来源 | URL | 类别 |
|
||||
|------|-----|------|
|
||||
| 国家药监局 | https://www.nmpa.gov.cn/rss | 药品监管 |
|
||||
| 丁香园 | https://www.dxy.cn/rss | 临床研究 |
|
||||
| 医学界 | https://www.yxj.org.cn/rss | 行业动态 |
|
||||
| 健康时报 | http://www.jksb.com.cn/rss | 行业动态 |
|
||||
|
||||
### 英文 RSS 源
|
||||
| 来源 | URL | 类别 |
|
||||
|------|-----|------|
|
||||
| STAT News | https://www.statnews.com/feed | 临床研究 |
|
||||
| FiercePharma | https://www.fiercepharma.com/rss/xml | 行业动态 |
|
||||
| FDA News | https://www.fda.gov/about-fda/contact-fda/stay-informed/rss-feeds/fda-news-feed/rss.xml | 药品监管 |
|
||||
| PubMed (医药) | https://pubmed.ncbi.nlm.nih.gov/rss/... | 临床研究 |
|
||||
|
||||
> 注:以上 URL 需在开发时验证可用性,部分需要爬虫替代 RSS。
|
||||
|
||||
---
|
||||
|
||||
## 八、目录结构
|
||||
|
||||
```
|
||||
ai_news_v1/
|
||||
├── backend/
|
||||
│ ├── app/
|
||||
│ │ ├── main.py # FastAPI 入口
|
||||
│ │ ├── config.py # 环境变量配置
|
||||
│ │ ├── database.py # DB 连接
|
||||
│ │ ├── models/
|
||||
│ │ │ ├── news.py
|
||||
│ │ │ ├── source.py
|
||||
│ │ │ └── llm_config.py
|
||||
│ │ ├── api/
|
||||
│ │ │ ├── news.py # 读者 API
|
||||
│ │ │ └── admin.py # 管理 API
|
||||
│ │ ├── crawler/
|
||||
│ │ │ ├── rss_fetcher.py # RSS 抓取
|
||||
│ │ │ └── http_fetcher.py # HTTP 爬取(备用)
|
||||
│ │ ├── ai/
|
||||
│ │ │ ├── llm_client.py # 统一 LLM 适配层
|
||||
│ │ │ ├── processor.py # AI 处理流水线
|
||||
│ │ │ └── selector.py # TOP 10 精选逻辑
|
||||
│ │ └── scheduler.py # APScheduler 定时任务
|
||||
│ ├── alembic/ # 数据库迁移
|
||||
│ ├── requirements.txt
|
||||
│ └── Dockerfile
|
||||
├── frontend/
|
||||
│ ├── src/
|
||||
│ │ ├── views/
|
||||
│ │ │ ├── NewsReader.vue # 读者主页
|
||||
│ │ │ ├── NewsDetail.vue # 新闻详情
|
||||
│ │ │ └── Admin.vue # 管理后台
|
||||
│ │ ├── components/
|
||||
│ │ │ ├── NewsCard.vue
|
||||
│ │ │ └── FeaturedBadge.vue
|
||||
│ │ └── api/
|
||||
│ │ └── index.ts # API 调用封装
|
||||
│ ├── package.json
|
||||
│ └── Dockerfile
|
||||
├── docker-compose.yml
|
||||
├── docker-compose.prod.yml
|
||||
├── .env.example
|
||||
└── DESIGN.md # 本文档
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 九、API 接口设计
|
||||
|
||||
### 读者端
|
||||
|
||||
| 方法 | 路径 | 说明 |
|
||||
|------|------|------|
|
||||
| GET | `/api/news/featured` | 当日精选 TOP 10 |
|
||||
| GET | `/api/news?date=&category=&page=` | 新闻列表(分页) |
|
||||
| GET | `/api/news/{id}` | 新闻详情 |
|
||||
| GET | `/api/news/dates` | 有数据的日期列表 |
|
||||
|
||||
### 管理端(需 Bearer Token 鉴权)
|
||||
|
||||
| 方法 | 路径 | 说明 |
|
||||
|------|------|------|
|
||||
| GET/POST | `/api/admin/llm-config` | 查看/更新 LLM 配置 |
|
||||
| GET | `/api/admin/sources` | 新闻源列表 |
|
||||
| POST | `/api/admin/sources` | 添加新闻源 |
|
||||
| PUT | `/api/admin/sources/{id}` | 启用/禁用新闻源 |
|
||||
| POST | `/api/admin/crawl/trigger` | 手动触发抓取 |
|
||||
| GET | `/api/admin/logs` | 查看运行日志 |
|
||||
| GET | `/api/admin/stats` | 今日抓取统计 |
|
||||
|
||||
---
|
||||
|
||||
## 十、前端页面设计
|
||||
|
||||
### 读者主页
|
||||
- 顶部:Logo + 今日日期 + 上次更新时间
|
||||
- 主区:精选 TOP 10 卡片列表,每张卡片含:
|
||||
- 重要性评分角标(红/橙/蓝)
|
||||
- 中文标题
|
||||
- AI 摘要(折叠展开)
|
||||
- 核心观点
|
||||
- 关键词标签
|
||||
- 来源 + 原文链接
|
||||
- 侧边栏(或 Tab):按分类筛选、历史日期切换
|
||||
|
||||
### 管理后台
|
||||
- LLM 配置面板:provider 选择、API Key、Base URL、模型名、连接测试按钮
|
||||
- 新闻源管理:表格 + 启用/禁用开关 + 添加
|
||||
- 手动触发:一键触发今日抓取 + 进度显示
|
||||
- 运行日志:最近 100 条日志,带时间戳和级别
|
||||
|
||||
---
|
||||
|
||||
## 十一、部署方案
|
||||
|
||||
```yaml
|
||||
# docker-compose.yml 核心服务
|
||||
services:
|
||||
db: # PostgreSQL
|
||||
backend: # FastAPI
|
||||
frontend: # Vue (Nginx 静态托管)
|
||||
scheduler: # APScheduler (可合并入 backend)
|
||||
```
|
||||
|
||||
**国内服务器注意事项:**
|
||||
- LLM API 如需访问境外服务,在服务器配置出口代理,或选用 DeepSeek/Qwen 等国内可直连的模型
|
||||
- pip/npm 镜像切换为阿里云/清华源
|
||||
|
||||
---
|
||||
|
||||
## 十二、开发阶段划分
|
||||
|
||||
| 阶段 | 内容 | 预估工作量 |
|
||||
|------|------|-----------|
|
||||
| Phase 1 | DB 模型 + FastAPI 骨架 + LLM 适配层 | 2天 |
|
||||
| Phase 2 | RSS 抓取 + AI 处理流水线 + 定时任务 | 3天 |
|
||||
| Phase 3 | 读者前端(主页 + 详情) | 2天 |
|
||||
| Phase 4 | 管理后台前端 | 2天 |
|
||||
| Phase 5 | Docker 部署 + 联调测试 | 1天 |
|
||||
| 合计 | | **约 10 个工作日** |
|
||||
Reference in New Issue
Block a user