# HF Daily Papers — 中文论文导览站 > 每日自动抓取 HuggingFace Daily Papers,调用 AI 生成结构化中文解读,提供本地 Web 应用用于浏览、搜索、收藏与管理。 --- ## 功能特性 - **每日抓取**:按日期拉取 HuggingFace Daily Papers,提取元数据并入库,自动去重与重试。 - **AI 中文总结**:下载 PDF,通过 `pi` 或 `claude` 后端为每篇论文生成结构化中文解读(动机、方法、结果、局限性等),完成后清理临时文件。 - **浏览与详情**:首页按日期导航、论文详情页展示元数据与总结,提供未总结论文的英文原文回退。 - **搜索**:基于 SQLite FTS5 的关键词搜索(BM25 排序、片段高亮),覆盖标题、摘要、作者、标签与总结正文。 - **语义搜索**(可选):ChromaDB 向量数据库实现相似度搜索,优雅降级至 FTS5。 - **论文对比**:并排对比最多 5 篇论文的 12 个结构化字段。 - **趋势看板**:Chart.js 驱动的可视化统计(日论文量、Top 标签、投票分布、总结完成率)。 - **个人化**:收藏、阅读状态、个人笔记与阅读列表。 - **RSS 订阅**:最近 7 天论文的 RSS 2.0 输出,支持标签过滤。 - **管理后台**:Session 认证的 Web 管理界面(仪表盘、论文管理、日志查看、手动操作)。 - **定时调度**:APScheduler 内嵌调度,默认每日自动抓取与总结(TaskLock 防重)。 - **LaTeX 图片提取**:下载 arXiv 源码,扫描 `.tex` 文件提取论文图片用于详情页展示。 - **布局检测**(可选):ONNX 模型识别 PDF 页面布局,提升图片提取精度。 - **HTMX 局部更新**:收藏切换等操作无需整页刷新。 - **键盘快捷键**:`Ctrl+K` 或 `/` 聚焦搜索框。 --- ## 技术栈 | 层级 | 技术 | |------|------| | 后端 | Python 3.12+ · FastAPI · Uvicorn | | 模板 | Jinja2(服务端渲染) | | 前端 | HTMX · 原生 JS · Chart.js · 自定义 CSS("kami" 纸质风格) | | 数据库 | SQLite + SQLAlchemy · SQLite FTS5(全文搜索) | | AI 总结 | `pi` CLI 或 `claude` CLI(可配置后端) | | 语义搜索 | ChromaDB(可选) | | 调度 | APScheduler(内嵌单进程) | | CLI | Typer | | 测试 | pytest · pytest-asyncio | | 构建 | Hatchling(PEP 517) | --- ## 项目结构 ``` paper/ ├── README.md ├── .env.example ├── pyproject.toml │ ├── app/ │ ├── __init__.py │ ├── main.py # FastAPI 入口(lifespan 管理) │ ├── config.py # pydantic-settings 配置加载 │ ├── database.py # SQLAlchemy 引擎、会话与 FTS5 │ ├── models.py # 11 个 ORM 模型 + 1 枚举 │ ├── utils.py # 共享工具函数 │ ├── exceptions.py # 统一业务异常体系 │ ├── cli.py # Typer CLI(crawl / summarize / init-db) │ │ │ ├── routes/ # 页面与 API 路由 │ │ ├── pages.py # 首页、日期页、论文详情、相似推荐 │ │ ├── admin.py # Session 认证管理后台 │ │ ├── search.py # 搜索、阅读列表、RSS │ │ ├── user.py # 收藏、阅读状态、笔记 API │ │ ├── trends.py # 趋势看板 │ │ └── compare.py # 论文对比页 │ │ │ ├── services/ # 业务逻辑层 │ │ ├── crawler.py # HuggingFace API 爬虫 │ │ ├── summarizer.py # AI 总结编排(调度层) │ │ ├── summary_generator.py # 总结生成与重试 │ │ ├── summary_persister.py # 总结持久化与文件管理 │ │ ├── summary_utils.py # 总结工具(prompt 构建、PDF 提取) │ │ ├── pi_client.py # pi CLI 封装 + JSON 提取 │ │ ├── claude_backend.py # claude CLI 后端 │ │ ├── searcher.py # FTS5 + 语义搜索 │ │ ├── schemas.py # Pydantic 总结校验 │ │ ├── cleaner.py # 临时文件清理 + 日期范围删除 │ │ ├── scheduler.py # APScheduler 每日管线 │ │ ├── pipeline.py # 抓取 + 总结流水线编排 │ │ ├── admin.py # 管理后台查询与统计 │ │ ├── user_data.py # 收藏、阅读状态、笔记 │ │ ├── embedder.py # ChromaDB 向量索引 │ │ ├── trends.py # 趋势统计聚合 │ │ ├── pdf_downloader.py # PDF + LaTeX 源码下载 │ │ ├── pdf_image_extractor.py # LaTeX 图片提取 + 图表关联 │ │ └── layout_detector.py # ONNX 布局检测(可选) │ │ │ ├── templates/ # Jinja2 模板 │ │ ├── base.html │ │ ├── index.html │ │ ├── detail.html │ │ ├── search.html │ │ ├── reading_list.html │ │ ├── compare.html │ │ ├── trends.html │ │ ├── login.html │ │ ├── admin_dashboard.html │ │ ├── admin_papers.html │ │ ├── admin_logs.html │ │ └── partials/ │ │ ├── admin_subnav.html │ │ ├── paper_card.html │ │ └── summary_list.html │ │ │ └── static/ │ ├── css/ │ │ ├── style.css # 自定义 CSS(kami 风格) │ │ └── admin.css # 管理后台样式 │ ├── js/ │ │ ├── app.js # 键盘快捷键 │ │ ├── date-picker.js # 日期导航 │ │ └── lightbox.js # 图片灯箱 │ └── favicon.svg │ ├── data/ # 运行时数据(已 gitignore) │ ├── db/papers.db # SQLite 数据库 │ ├── papers/{arxiv_id}/ # 长期资产(meta.json / summary.json / 图片) │ ├── tmp/{arxiv_id}/ # 临时下载(流程完成后清理) │ ├── chroma/ # ChromaDB 向量库(可选) │ └── models/ # ONNX 模型(布局检测) │ ├── scripts/ │ ├── init_db.py # 数据库初始化 │ ├── manual_crawl.py # 手动抓取脚本 │ ├── export_doclayout_yolo_onnx.py # 导出布局检测 ONNX 模型 │ ├── reextract_images.py # 批量重新提取图片 │ └── validate_summary.py # 校验总结 JSON 结构 │ ├── tests/ # 13 个测试模块 │ ├── conftest.py # 测试夹具(内存 DB、样本数据) │ └── test_*.py # 各模块测试 │ └── logs/ # 运行日志 ``` --- ## 快速开始 ### 1. 准备环境 - Python **3.12+** - [uv](https://docs.astral.sh/uv/) 包管理器 - 可选:[`pi`](https://www.npmjs.com/package/@mariozechner/pi-coding-agent) CLI 或 [`claude`](https://claude.ai/code) CLI(用于 AI 总结) ### 2. 安装依赖 ```bash cp .env.example .env uv sync ``` ### 3. 配置环境变量 ```bash # 编辑 .env,至少修改以下三项 ADMIN_USERNAME=admin ADMIN_PASSWORD=your_secure_password SECRET_KEY=your_random_secret_key ``` 关键配置项: | 变量 | 默认值 | 说明 | |------|--------|------| | `APP_HOST` / `APP_PORT` | `127.0.0.1` / `8000` | 服务监听地址 | | `APP_DEBUG` | `false` | 调试模式(开启 uvicorn reload) | | `BASE_URL` | `http://127.0.0.1:8000` | 站点根 URL(用于 RSS 生成) | | `APP_TIMEZONE` | `Asia/Shanghai` | 时区 | | `ADMIN_USERNAME` | `admin` | 管理后台用户名 | | `ADMIN_PASSWORD` | — | 管理后台密码 | | `SECRET_KEY` | `change-me` | Session 签名密钥 | | `HF_API_BASE` | `https://huggingface.co/api` | HuggingFace API 地址 | | `HF_PROXY` | — | HTTP 代理 | | `TOP_N` | `20` | 每日抓取 Top N 论文 | | `HTTP_TIMEOUT_SECONDS` | `30` | HTTP 请求超时 | | `HTTP_MAX_RETRIES` | `3` | HTTP 最大重试次数 | | `SUMMARY_BACKEND` | `pi` | 总结后端:`pi` 或 `claude` | | `PI_BIN` | — | `pi` CLI 路径 | | `CLAUDE_BIN` | `claude` | `claude` CLI 路径 | | `SUMMARY_SKILL` | `daily-paper-summary` | pi 总结技能名 | | `SUMMARY_CONCURRENCY` | `3` | 最大并行总结数 | | `SUMMARY_TIMEOUT_SECONDS` | `1200` | 单篇总结超时 | | `SUMMARY_MAX_RETRIES` | `2` | 总结最大重试次数 | | `SUMMARY_PDF_MODE` | `auto` | PDF 传递方式:`auto` / `inject` / `search` | | `UPVOTE_REFRESH_DAYS` | `7` | 自动刷新最近 N 天论文的 upvotes | | `PDF_DOWNLOAD_TIMEOUT` | `120` | PDF 下载超时(秒) | | `SCHEDULER_ENABLED` | `false` | 启用每日自动抓取 | | `SCHEDULE_HOUR` / `SCHEDULE_MINUTE` | `4` / `0` | 定时任务时间(APP_TIMEZONE) | | `APP_WORKERS` | `1` | Uvicorn worker 数(必须为 1) | | `DATABASE_URL` | `sqlite:///data/db/papers.db` | 数据库路径 | | `CHROMA_ENABLED` | `false` | 启用语义搜索 | | `CHROMA_DIR` | `data/chroma` | ChromaDB 数据目录 | | `EMBED_API_BASE` | — | Embedding API 地址 | | `EMBED_API_KEY` | — | Embedding API Key | | `EMBED_MODEL` | — | Embedding 模型名 | | `EMBED_DIMENSIONS` | `0` | 向量维度 | | `LAYOUT_MODEL_PATH` | `data/models/doclayout_yolo_docstructbench_imgsz1024.onnx` | DocLayout-YOLO ONNX 模型路径(可选) | | `LAYOUT_IMGSZ` | `1024` | 模型输入尺寸 | | `LAYOUT_THRESHOLD` | `0.2` | 布局检测置信度阈值(可选) | | `LAYOUT_DEVICE` | `auto` | 推理设备:auto/cpu/cuda/directml/openvino/...(可选) | ### 4. 初始化数据库 ```bash uv run python -m app.cli init-db ``` ### 5. 启动服务 ```bash uv run python -m app.main ``` > 调度器依赖单 worker:不可使用 `--workers > 1`,否则每日任务会被重复触发。 打开浏览器访问 `http://127.0.0.1:8000` 即可。 --- ## 常用命令 ### 手动抓取 ```bash # 自动探测今天/昨天 uv run python -m app.cli crawl # 指定日期 uv run python -m app.cli crawl 2025-01-15 --top 20 # 强制重抓(即使已有数据) uv run python -m app.cli crawl --force ``` ### 手动触发总结 ```bash # 单篇 uv run python -m app.cli summarize 2401.01234 # 批量(所有待总结论文) uv run python -m app.cli summarize # 指定后端和 PDF 模式 uv run python -m app.cli summarize --backend claude --pdf-mode inject ``` ### 管理后台 打开浏览器访问 `http://127.0.0.1:8000/admin/login`,使用 `.env` 中配置的用户名密码登录。 管理后台包含: - **仪表盘**:统计卡、调度器控制、存储信息、最近活动 - **论文管理**:搜索、筛选、单篇/批量删除 - **日志**:运行日志、总结状态、失败重试 ### 运行测试 ```bash uv run pytest ``` ### 代码检查 ```bash uv run ruff format # 格式化代码 uv run ruff check --fix # 自动修复 lint 问题 ``` --- ## 安全提示 - 管理后台使用 Session 认证,请务必在 `.env` 中设置强密码和随机 `SECRET_KEY`。 - 默认仅监听 `127.0.0.1`,如需内网访问请配合反向代理与 HTTPS。 - 项目面向本地 / 内网部署,不包含多用户账号体系与公网防护。 --- ## 许可证 本项目仅供学习与个人使用,请遵守 HuggingFace、arXiv 与上游论文作者的相关条款。