ReMe/plugins/daily_paper/README_ZH.md
jinliyl 513fb5b7f4
feat: extract Daily Paper into an independently packaged plugin (#491)
* feat: extract Daily Paper into a plugin

* fix: satisfy clean-environment quality checks

* fix: address daily paper review feedback
2026-08-26 17:32:46 +08:00

12 KiB
Raw Blame History

每日论文插件

English

每日论文从 Hugging Face Papers 的周榜和月榜中筛选三篇论文,下载 arXiv PDF生成中文论文解读和一篇约五分钟可读完的中文简报。本目录是一个 独立 Python distributiondaily-paper entry point 通过 package 内的 plugin.yaml 暴露五个 Step backend 和完整 Job 默认配置;安装后使用 plugins=["daily-paper"] 显式启用。

快速开始

要求 Python 3.11 或更高版本、可用的 AgentScope LLM以及能访问 Hugging Face Papers 和 arXiv 的网络。

python -m pip install "reme-ai[core]>=0.4.1.8"
reme plugins install reme-daily-paper
export LLM_API_KEY="your-api-key"
export LLM_MODEL_NAME="qwen3.7-plus"
export LLM_BASE_URL="https://your-provider.example/v1"
reme start plugins='["daily-paper"]' job=daily_paper

内置 LLM 组件默认配置为:

  • 模型:qwen3.7-plus
  • endpoint无内置 LLM_BASE_URL;请设置服务商要求的 OpenAI 兼容 endpoint
  • 环境变量:LLM_API_KEYLLM_MODEL_NAMELLM_BASE_URL

每日论文使用 Application 的 default LLM 和 default AgentScope wrapper。Select 和 Analyze 调用不带工具Digest 只使用只读的 ReMe Job 工具 memory_searchread

默认 workspace 是启动目录下的 .reme/;可通过 workspace_dir=... 或与插件组合使用的 Application 配置覆盖。

从内置 Cookbook 迁移

Daily Paper 不再由核心 reme-ai distribution 导入或配置。需要安装本 package 并显式启用 daily-paper,而不是通过 config=daily_cookbook 获取 Daily Paper Job

# 旧方式
reme start config=daily_cookbook job=daily_paper

# 新方式
reme plugins install reme-daily-paper
reme start plugins='["daily-paper"]' job=daily_paper

工作流 schema 已从 reme.schema.daily_paper 移至 reme_daily_paper.schema。原先位于 reme.utils 的 arXiv 和 Hugging Face client 现在是 reme_daily_paper 下的插件实现细节;直接使用这些模块的应用需要安装本 package 并更新 import。已有 workspace 笔记、下载的 PDF 和索引不会被迁移或改写;将 Application 指向原 workspace_dir 即可继续使用。

工作流

Hugging Face 周榜/月榜
          │
          ▼
Collect ──► Rank ──► Select 3 篇 ──► Analyze PDF ──► Digest ──► DingTalk可选
                                       │                │
                                       ├─ PDF           ├─ 每日简报
                                       └─ 论文解读      └─ 当日索引

1. Collect

daily_paper_collect_step 根据运行日期并发读取:

  • 该日期所在 ISO week 的 Hugging Face 周榜;
  • 该日期所在自然月的 Hugging Face 月榜;
  • 严格前一个自然日的 Hugging Face Daily Papers。

周榜和月榜按 arXiv ID 合并,并保留各自排名。随后排除:

  • 昨日 Daily Papers 中的论文;
  • history_days 窗口内,已出现在 daily/<date>/*.md frontmatter arxiv_id 中的论文。

如果当天已经存在 kind: daily-paper-brief 的 Markdown 且 force=false整个生成流程会跳过已有简报仍可进入钉钉发送步骤。没有剩余候选论文时Job 直接失败。

2. Rank

daily_paper_rank_step 使用 reciprocal-rank fusion

score = 1 / (rrf_k + monthly_rank)
      + weekly_weight / (rrf_k + weekly_rank)

缺失的榜单排名贡献为零。论文按融合分、upvotes、arXiv ID 排序,候选池最多保留 candidate_limit 篇。Rank 阶段不应用任何主题倾向。

3. Select

daily_paper_select_step 将候选元数据交给无工具的 AgentScope Agent并要求返回恰好三项

{"papers": [{"arxiv_id": "2601.01234", "reasoning": "具体且可核验的选择理由"}]}

三个 ID 必须唯一且都属于候选池,理由不能为空。校验失败后,错误信息会反馈给 Agent 并重试一次。只有非空 topics 会向精选提示注入个性化主题,且不会改变固定的三篇数量。

4. Analyze

daily_paper_analyze_step 按精选顺序逐篇处理:

  1. 校验新版 arXiv ID 格式 YYYY.NNNNYYYY.NNNNN
  2. 下载 PDF 到 resource/papers/<arxiv-id>.pdf
  3. 如果目标文件已存在且以 %PDF- 开头,直接复用;
  4. pypdf 提取分页文本,受 max_pdf_pagesmax_pdf_chars 限制;
  5. 将论文元数据、选择理由和 PDF 文本交给无工具 Agent
  6. 将中文解读写入 daily/<date>/<中文标题>.md

下载采用临时文件并在校验 PDF 文件头后原子替换,同时限制 max_pdf_bytes。当前没有 OCR扫描版或无文本层 PDF 会失败。提取被截断时,笔记 frontmatter 中的 pdf_text_truncated 会记录为 true

5. Digest

daily_paper_digest_step 以内存中的三篇解读作为本期事实来源生成中文简报,同时搜索并按需读取较早的 daily 文章来识别相关报道;历史文章只能用于建立上下文 wikilink不能用于补充本期论文事实。输出必须包含 titledescbody 。代码会:

  • 去掉模型可能生成的 YAML frontmatter
  • 规范化中文标题并用作文件名;
  • 只保留指向真实存在、日期早于运行日期的 daily/ Markdown 文件的模型生成 wikilink
  • 确定性追加三篇源笔记的 wikilink
  • 写入 daily/<date>/<中文简报标题>.md
  • 重建 daily/<date>.md 当日索引。

最终响应 metadata 包含日期、周/月范围、入选 arXiv ID、选择理由、笔记/PDF/简报路径、源榜单数量和排重数量。

6. DingTalk

最后的 dingtalk_markdown_send_step 是可选步骤。未设置群会话 ID 时无副作用跳过;配置后会去掉 frontmatter并把简报正文依次发送给所有群

DINGTALK_APP_KEY=your-app-key
DINGTALK_APP_SECRET=your-app-secret
DINGTALK_ROBOT_CODE=your-robot-code
DINGTALK_CONVERSATION_IDS=cid-group-one,cid-group-two

任一群发送失败不会阻止继续尝试后续群,全部尝试结束后统一报告失败。

产物

.reme/
├── daily/
│   ├── YYYY-MM-DD.md
│   └── YYYY-MM-DD/
│       ├── <中文论文标题>.md       # 三篇kind: daily-paper-analysis
│       └── <中文简报标题>.md       # 一篇kind: daily-paper-brief
└── resource/
    └── papers/
        └── <arxiv-id>.pdf

每次成功生成会写入三篇论文解读和一篇简报。强制重跑后当日目录中可能保留其他内容或此前入选论文的解读ReMe 不会把它们作为清理对象删除。文件名来自 Agent 返回的中文标题。代码会清理路径不安全字符并处理同名文件。Markdown 和 PDF 都通过同目录临时文件写入后原子替换。

参数与默认值

可在调用时传入的 Job 参数:

参数 默认值 作用
date "" 运行日期;空值使用应用时区当天,非空值必须为 YYYY-MM-DD
force false 已有当日简报时仍重新生成
use_hf_mirror false 是否使用 Hugging Face 镜像站;优先读取 HF_MIRROR_URL,未配置时使用 https://hf-mirror.com
topics "" 精选论文时优先考虑的主题
weekly_weight 0.7 RRF 中周榜权重
history_days 30 历史推荐排重窗口

daily_paper Job 的步骤级配置:

配置 默认值 作用
candidate_limit 20 送入 Select 的最大候选数
rrf_k 60 RRF 常数
hf_timeout 600 Hugging Face 单次请求超时
hf_max_retries 3 Hugging Face 最大尝试次数
pdf_timeout 600 arXiv PDF 下载超时
max_pdf_bytes 52428800 PDF 上限50 MiB
max_pdf_pages 35 最多提取页数
max_pdf_chars 300000 最多送入 Agent 的 PDF 字符数

镜像站

数据客户端使用 httpx 默认的环境处理,因此存在 HTTP_PROXYHTTPS_PROXYNO_PROXY 时会自动生效。两个数据源启用镜像的方式不同Hugging Face 由 use_hf_mirror 任务参数控制arXiv 仅由环境变量驱动。

# 插件提供的 daily_paper_cron Job 默认启用镜像站;设为 false 可改用官方服务
DAILY_PAPER_USE_HF_MIRROR=false

# 仅在手动任务或定时任务启用镜像时读取;未配置时使用 https://hf-mirror.com
HF_MIRROR_URL=https://hf-mirror.com

# 可选覆盖;未设置时代码使用 https://arxiv.org
ARXIV_MIRROR_URL=https://export.arxiv.org

# 也支持带路径前缀的中转地址
# HF_MIRROR_URL=http://relay-host:18080/hf
# ARXIV_MIRROR_URL=http://relay-host:18080/arxiv

HF_MIRROR_URL 必须提供当前代码使用的 /papers/.../api/daily_papers/api/papers/... 路径。ARXIV_MIRROR_URL 必须支持 /pdf/<arxiv-id>。两种 base URL 都会保留路径前缀,末尾 / 可有可无。不存在备用地址回退:客户端选定哪个 base URL就只访问该地址。

行为变更: 以往只要设置 HF_MIRROR_URL 就会改变 Hugging Face 的访问地址;现在该变量仅在任务启用镜像时才会读取,否则直接访问官方站点,并输出一条“已忽略该变量”的告警日志。手动调用需传入 use_hf_mirror=true。插件提供的 daily_paper_cron Job 默认启用镜像;设置 DAILY_PAPER_USE_HF_MIRROR=false 可让该定时任务改用官方服务。

运行方式

生成指定日期的简报:

reme start \
  plugins='["daily-paper"]' \
  job=daily_paper \
  date=2026-08-06 \
  topics="Agent memory" \
  history_days=30

强制重跑;有效的本地 PDF 仍会复用:

reme start plugins='["daily-paper"]' job=daily_paper date=2026-08-06 force=true

启动 HTTP 服务和定时任务:

reme start plugins='["daily-paper"]'

使用 ReMe 默认配置时HTTP 服务监听 127.0.0.1:2333daily_paper_cron 按 Application 时区每天 08:00 运行, 默认优先关注 大模型长期记忆,并使用 Hugging Face 镜像站。设置 DAILY_PAPER_USE_HF_MIRROR=false 可改用官方服务; 可通过常规 ReMe 配置或启动参数覆盖监听地址和端口。

curl -s http://127.0.0.1:2333/daily_paper \
  -H 'Content-Type: application/json' \
  -d '{"date":"2026-08-06","force":false,"topics":"Agent memory"}'

失败与重跑

  • Hugging Face HTTP 请求失败会指数退避重试,最多尝试 hf_max_retries 次;响应数据格式无效时立即失败。
  • 候选少于三篇、Agent 精选不合法、PDF 无效/过大/无文本或 Agent 输出为空都会终止 Job。
  • 三篇论文按顺序处理;中途失败时,之前已完成的 PDF 和笔记会保留。
  • force=true 会重新生成本次入选论文的解读和简报,并复用有效 PDF不会删除当日目录中已有的其他笔记。
  • 多文件流程不是事务,也没有同一日期的全局运行锁。

测试

单元测试会 mock Hugging Face、arXiv、AgentScope 和 DingTalk 边界,不访问真实服务:

python -m pip install -e packages/reme_ai_studio -e ".[dev,core]" -e plugins/daily_paper
python -m pytest plugins/daily_paper -v