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

270 lines
6.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 服务模块详解
> 本文档描述各服务模块的职责、输入输出、失败处理和实现约束。
---
## 1. 爬虫服务
**职责**:从 HuggingFace Daily Papers 获取论文列表,写入元数据。PDF 不在抓取阶段长期保存。
### 数据源
- Daily Papers API`GET https://huggingface.co/api/daily_papers?date=YYYY-MM-DD`
- PDF`https://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=failed``summary_status.error_type=pdf_download_failed`
### 接口
```python
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`,总结成功或失败后清理。
### 调用示例
```bash
pi -p --skill daily-paper-summary \
"请深度解读以下论文,并按指定 JSON schema 输出:
@data/papers/2401.12345/meta.json
@data/tmp/2401.12345/paper.pdf"
```
### 流程
```text
取 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
```python
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. 用户数据服务
**职责**:本地个人化数据,无账号体系。
功能:
- 收藏/取消收藏。
- 阅读状态:`unread``skimmed``read_summary``read_full`
- 个人 Markdown 笔记。
- 阅读列表:按收藏、状态、标签、日期筛选。
所有用户数据跟随论文删除一起删除。
---
## 6. 清理和删除服务
**职责**:清理临时文件,并支持管理员手动删除指定日期范围内的数据。
### 临时文件清理
触发时机:
- 单篇总结成功后。
- 单篇总结失败后。
- 每日任务结束后兜底扫描 `data/tmp/`
### 手动删除
接口:
```python
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。
### 每日流程
```text
08:00
-> 按 APP_TIMEZONE 计算 today
-> crawl(date=today)
-> summarize pending papers
-> cleanup tmp files
-> write logs
```
手动触发方式:
- CLI`python -m app.cli crawl --date YYYY-MM-DD`
- API`POST /admin/crawl`
---
## 8. 管理和安全服务
**职责**:保护所有有副作用的管理操作。
### 鉴权
管理接口必须要求 `ADMIN_TOKEN`
```text
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 成本、页面复杂度和验收标准。