Files
daily-paper/docs/services.md
T
Rain-Bus f1be24ab83 feat: initial project structure
- 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
2026-06-05 21:56:40 +08:00

6.9 KiB
Raw Blame History

服务模块详解

本文档描述各服务模块的职责、输入输出、失败处理和实现约束。


1. 爬虫服务

职责:从 HuggingFace Daily Papers 获取论文列表,写入元数据。PDF 不在抓取阶段长期保存。

数据源

  • Daily Papers APIGET https://huggingface.co/api/daily_papers?date=YYYY-MM-DD
  • PDFhttps://arxiv.org/pdf/{arxiv_id}.pdf(总结阶段按需下载)
  • 源码(后续增强):https://arxiv.org/e-print/{arxiv_id}

HuggingFace 官方 Hub API 文档说明 /api/daily_papers 支持 date 查询参数。

规则

  • arxiv_id 是唯一键。
  • 重复抓取同一天时,已有论文只更新 upvotes、标签等可变元数据,不重复插入。
  • 网络请求必须设置 timeout、User-Agent、重试次数。
  • API 返回空列表时记录成功日志,不视为失败。
  • 抓取阶段不下载 PDF;总结阶段 PDF 下载失败时更新 asset_status=failedsummary_status.error_type=pdf_download_failed

接口

async def fetch_daily(date: str, top_n: int) -> list[PaperMeta]: ...
async def upsert_papers(papers: list[PaperMeta]) -> list[Paper]: ...

2. AI 总结服务

职责:调用 pi CLI,把单篇论文转成结构化中文总结。

调用原则

  • 一篇论文一次 pi 调用。
  • 并发数由 SUMMARY_CONCURRENCY 控制,默认 3。
  • 单篇超时由 SUMMARY_TIMEOUT_SECONDS 控制,默认 300 秒。
  • pi 路径通过 PI_BIN 配置,当前可以先使用宿主机路径;跑通后再抽象部署方式。
  • PDF 在总结开始前按需下载到 data/tmp/{arxiv_id}/paper.pdf,总结成功或失败后清理。

调用示例

pi -p --skill daily-paper-summary \
  "请深度解读以下论文,并按指定 JSON schema 输出:
   @data/papers/2401.12345/meta.json
   @data/tmp/2401.12345/paper.pdf"

流程

取 pending 论文
  -> 下载 PDF 到 data/tmp/{arxiv_id}/paper.pdf
  -> status=processing
  -> 调 pi
  -> 提取 JSON
  -> Pydantic 校验
  -> 写 summary.json
  -> 写 paper_summaries / paper_tags / papers_fts
  -> status=done
  -> 清理 PDF/源码临时文件

失败时保存 raw output、更新 summary_status,并清理下载文件。

PDF 下载失败不调用 pi,直接记录 pdf_download_failed 并进入重试流程。


3. 搜索服务

职责:MVP 提供 FTS5 关键词搜索;后续接入 ChromaDB 语义搜索。

FTS5 搜索

索引字段:

  • 英文标题
  • 中文标题
  • 英文摘要
  • 作者
  • 标签
  • 中文总结正文

应用层负责同步 FTS

def build_fts_document(paper: Paper, summary: PaperSummary | None) -> FtsDocument:
    summary_text = ""
    if summary:
        summary_text = " ".join([
            summary.one_line or "",
            summary.motivation_problem or "",
            summary.motivation_goal or "",
            summary.method_overview or "",
            summary.method_key_idea or "",
            " ".join(summary.results_main or []),
        ])
    return FtsDocument(...)

ChromaDB 语义搜索(后续)

接入时要求:

  • CHROMA_ENABLED=true 才初始化。
  • embedding API 失败不能影响总结入库。
  • embedding 维度和配置不匹配时记录日志并跳过。
  • 使用当前 ChromaDB 官方 API 重新确认查询和过滤语法后实现。

4. 页面渲染服务

职责:从 SQLite 读取数据并渲染 Jinja2 模板。

kami 只作为风格参考:

  • 参考纸张质感、留白、字体层级和墨蓝强调色。
  • 不调用 kami,不依赖 kami 生成页面。
  • CSS 放在 app/static/css/style.css,按本项目页面实际结构维护。

页面必须支持降级状态:

  • 无总结:显示英文元数据和“AI 总结尚未生成”。
  • 总结失败:显示错误类型和手动重跑入口。
  • degraded/low:显示提示,但仍展示已有内容。

5. 用户数据服务

职责:本地个人化数据,无账号体系。

功能:

  • 收藏/取消收藏。
  • 阅读状态:unreadskimmedread_summaryread_full
  • 个人 Markdown 笔记。
  • 阅读列表:按收藏、状态、标签、日期筛选。

所有用户数据跟随论文删除一起删除。


6. 清理和删除服务

职责:清理临时文件,并支持管理员手动删除指定日期范围内的数据。

临时文件清理

触发时机:

  • 单篇总结成功后。
  • 单篇总结失败后。
  • 每日任务结束后兜底扫描 data/tmp/

手动删除

接口:

async def delete_papers_by_date_range(
    date_start: date,
    date_end: date,
    include_notes: bool = True,
) -> DeleteResult: ...

要求:

  • 删除前统计目标论文数量。
  • 删除 DB 记录、FTS 索引、本地文件。
  • 删除失败时记录具体 arXiv ID 和错误。
  • 日期范围必须有限制,避免误删全部数据;管理接口需要二次确认参数。

7. 调度服务

职责:自动执行每日抓取和总结。

约束

  • 应用以单 worker 运行。
  • APP_WORKERS 必须为 1,或 SCHEDULER_ENABLED=false
  • 启动时检查运行中任务,避免重复执行。
  • 同一日期同一任务使用数据库锁或日志状态防重入。
  • 推荐使用 task_locks 表;抢锁失败时,自动任务跳过,管理接口返回 409。

每日流程

08:00
  -> 按 APP_TIMEZONE 计算 today
  -> crawl(date=today)
  -> summarize pending papers
  -> cleanup tmp files
  -> write logs

手动触发方式:

  • CLIpython -m app.cli crawl --date YYYY-MM-DD
  • APIPOST /admin/crawl

8. 管理和安全服务

职责:保护所有有副作用的管理操作。

鉴权

管理接口必须要求 ADMIN_TOKEN

Authorization: Bearer <ADMIN_TOKEN>

受保护接口:

  • POST /admin/crawl
  • POST /admin/summarize/{arxiv_id}
  • POST /admin/summarize
  • POST /admin/cleanup
  • POST /admin/delete
  • GET /admin/logs

如果 ADMIN_TOKEN 为空或为默认值 change-me,应用启动时应警告;如果 APP_HOST 不是 127.0.0.1,应拒绝启动或要求显式确认。

用户数据接口默认仅面向本地使用。如果 APP_HOST=127.0.0.1,收藏、阅读状态、笔记接口不额外要求 token;如果绑定到非本地地址,应启用 same-origin 检查或要求 ADMIN_TOKEN,避免内网其他人修改本地笔记。


9. RSS 服务

职责:输出最近论文的 RSS Feed。

MVP 只做 /rss.xml

  • 默认最近 7 天。
  • 支持 ?tag=RAG
  • 有中文标题则用中文标题,否则用英文标题。
  • 详情链接指向本站 /paper/{arxiv_id}

Atom 和 JSON Feed 作为后续增强。


10. 后续增强服务

这些能力暂不进入 MVP

  • LaTeX 图片提取。
  • ChromaDB 语义搜索。
  • 相似论文推荐。
  • 趋势看板。
  • 论文对比页。

实现前需要重新评估数据量、API 成本、页面复杂度和验收标准。