f1be24ab83
- Add FastAPI app with paper browsing UI and REST API - Add crawler service and database models - Add scripts for DB init and manual crawl - Add docs (api-and-ui, data-model, services) - Add requirements and project config
6.9 KiB
6.9 KiB
HF Daily Papers — 中文论文导览站
每日从 HuggingFace Daily Papers 获取热门论文,生成中文结构化解读,提供浏览、搜索、收藏和管理的本地 Web 应用。
文档索引
| 文档 | 内容 |
|---|---|
| services.md | 服务模块:爬虫、AI 总结、搜索、清理、调度、安全等 |
| data-model.md | SQLite 表结构、summary.json schema、索引和校验策略 |
| api-and-ui.md | 路由、页面、用户流程、验收标准 |
1. 产品边界
当前目标
构建一个本地运行的论文导览站:
- 按日期抓取 HuggingFace Daily Papers。
- 提取必要元数据,写入 SQLite。
- 总结阶段按需下载 PDF,调用 pi CLI 为论文生成中文结构化总结,完成后清理下载文件。
- 展示首页、日期列表、论文详情、搜索结果、阅读列表。
- 支持收藏、阅读状态、个人笔记。
- 提供安全的管理接口,用于手动抓取、总结、清理和查看日志。
暂不做
- 不做 Docker / Docker Compose。
- 不做自动归档。
- 不保留下载文件作为长期资产:PDF/源码只用于解析和总结,流程完成后清理。
- 不做 PDF 图片兜底提取。
- 不做多用户账号体系。
- 不做公网服务设计,默认本地或内网部署。
2. 技术选型
| 层 | 选型 | 说明 |
|---|---|---|
| 后端框架 | FastAPI | 页面路由、JSON API、管理接口 |
| 模板 | Jinja2 | 服务端渲染 HTML |
| 前端交互 | HTMX + 少量原生 JS | 收藏、状态、搜索、局部刷新 |
| 样式 | 自定义 CSS,参考 kami 风格 | kami 只作为视觉和排版参考,不调用 kami 构建管线 |
| 数据库 | SQLite + SQLAlchemy | 单文件、本地低运维 |
| 全文搜索 | SQLite FTS5 | 标题、摘要、总结、作者、标签关键词搜索 |
| 语义搜索 | ChromaDB(可选增强) | MVP 后接入,用在线嵌入服务生成向量 |
| AI 总结 | pi CLI | 一篇论文一次 pi 调用 |
| 调度 | APScheduler | 单进程内嵌调度,禁止多 worker 重复运行 |
3. 项目结构
paper/
├── README.md
├── REQUIREMENTS.md
├── docs/
│ ├── services.md
│ ├── data-model.md
│ └── api-and-ui.md
├── .env
├── .env.example
├── pyproject.toml
│
├── app/
│ ├── main.py
│ ├── config.py
│ ├── database.py
│ ├── models.py
│ ├── security.py
│ ├── cli.py
│ │
│ ├── routes/
│ │ ├── pages.py
│ │ ├── api.py
│ │ ├── search.py
│ │ ├── user.py
│ │ └── admin.py
│ │
│ ├── services/
│ │ ├── crawler.py
│ │ ├── summarizer.py
│ │ ├── searcher.py
│ │ ├── cleaner.py
│ │ ├── user_data.py
│ │ └── scheduler.py
│ │
│ ├── templates/
│ │ ├── base.html
│ │ ├── index.html
│ │ ├── detail.html
│ │ ├── search.html
│ │ ├── reading_list.html
│ │ ├── admin_logs.html
│ │ └── partials/
│ │ ├── paper_card.html
│ │ ├── date_nav.html
│ │ └── search_bar.html
│ │
│ └── static/
│ ├── css/style.css
│ └── js/app.js
│
├── data/
│ ├── db/papers.db
│ ├── papers/{arxiv_id}/
│ │ ├── meta.json
│ │ ├── summary.json
│ │ └── raw_output.txt
│ ├── tmp/{arxiv_id}/
│ │ ├── paper.pdf
│ │ └── source/
│ └── chroma/
│
├── logs/
├── tests/
└── scripts/
├── init_db.py
└── manual_crawl.py
data/tmp/ 是临时文件目录。PDF、LaTeX 源码等下载文件只在总结阶段按需下载,解析和总结完成后删除;数据库、meta.json、summary.json 和 raw_output.txt 可长期保留。
4. 配置项
# 应用
APP_HOST=127.0.0.1
APP_PORT=8000
APP_DEBUG=false
BASE_URL=http://127.0.0.1:8000
APP_TIMEZONE=Asia/Shanghai
# 安全
ADMIN_TOKEN=change-me
# HuggingFace / arXiv
HF_API_BASE=https://huggingface.co/api
HF_PROXY=
TOP_N=20
HTTP_TIMEOUT_SECONDS=30
HTTP_MAX_RETRIES=3
HTTP_USER_AGENT=hf-daily-papers-local/0.1
# AI 总结
PI_BIN=/home/rainbus/.local/share/mise/installs/pi/latest/pi
SUMMARY_SKILL=daily-paper-summary
SUMMARY_CONCURRENCY=3
SUMMARY_TIMEOUT_SECONDS=300
SUMMARY_MAX_RETRIES=1
# 调度
SCHEDULER_ENABLED=true
SCHEDULE_HOUR=8
SCHEDULE_MINUTE=0
APP_WORKERS=1
# 数据库
DATABASE_URL=sqlite:///data/db/papers.db
# 语义搜索(后续增强,可为空)
CHROMA_ENABLED=false
CHROMA_DIR=data/chroma
EMBED_API_BASE=
EMBED_API_KEY=
EMBED_MODEL=
EMBED_DIMENSIONS=
5. 里程碑
Phase 1 — MVP:抓取、入库、浏览
- FastAPI + SQLite + SQLAlchemy 项目骨架。
- 数据表、FTS5 表、基础迁移或初始化脚本。
- HF Daily Papers 抓取:支持日期、TOP_N、去重、重试、空日期。
- 抓取阶段只入库元数据,不长期保存 PDF。
- 首页
/day/{date}和论文详情页/paper/{arxiv_id}。 - CLI:手动抓取指定日期。
Phase 2 — AI 总结
- pi CLI 集成:一篇论文一次调用。
- 总结阶段按需下载 PDF,成功或失败后清理临时文件。
- summary.json schema 校验、降级展示、失败重试。
- 总结状态追踪。
- raw_output.txt 保存和管理后台复跑。
- 总结完成后更新
papers、paper_summaries、FTS5。
Phase 3 — 搜索和个人化
- FTS5 关键词搜索。
- 收藏、阅读状态、个人笔记。
- 阅读列表页。
- RSS Feed。
Phase 4 — 管理和自动化
- APScheduler 每日自动抓取和总结。
- 管理接口 token 鉴权。
- 管理后台日志。
- 手动删除指定时间段内的数据。
- 临时文件清理任务。
Phase 5 — 后续增强
- ChromaDB 语义搜索。
- 相似论文推荐。
- 趋势看板。
- 论文对比。
- LaTeX 图片提取。
6. 核心验收标准
- 重复抓取同一天不会重复入库。
- HuggingFace 或 arXiv 请求失败时有超时、重试和日志。
- 某篇论文总结失败不会阻塞其他论文。
- 首页能展示四种状态:未总结、总结中、总结失败、总结完成。
- 详情页在无总结时展示英文标题、摘要、作者、链接和手动总结入口。
- 搜索至少能匹配标题、摘要、作者、标签和中文总结正文。
- 管理接口没有 token 时不能触发抓取、总结、删除等写操作。
- PDF/源码临时文件在流程完成后被清理。
- 手动删除指定日期范围后,页面、搜索索引、用户数据和本地文件保持一致。
- 调度器在单 worker 下只触发一次每日任务。