* feat: extract Daily Paper into a plugin * fix: satisfy clean-environment quality checks * fix: address daily paper review feedback
12 KiB
每日论文插件
每日论文从 Hugging Face Papers 的周榜和月榜中筛选三篇论文,下载 arXiv PDF,生成中文论文解读和一篇约五分钟可读完的中文简报。本目录是一个
独立 Python distribution:daily-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_KEY、LLM_MODEL_NAME、LLM_BASE_URL
每日论文使用 Application 的 default LLM 和 default AgentScope wrapper。Select 和 Analyze 调用不带工具;Digest
只使用只读的 ReMe Job 工具 memory_search 和 read。
默认 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>/*.mdfrontmatterarxiv_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 按精选顺序逐篇处理:
- 校验新版 arXiv ID 格式
YYYY.NNNN或YYYY.NNNNN; - 下载 PDF 到
resource/papers/<arxiv-id>.pdf; - 如果目标文件已存在且以
%PDF-开头,直接复用; - 用
pypdf提取分页文本,受max_pdf_pages和max_pdf_chars限制; - 将论文元数据、选择理由和 PDF 文本交给无工具 Agent;
- 将中文解读写入
daily/<date>/<中文标题>.md。
下载采用临时文件并在校验 PDF 文件头后原子替换,同时限制 max_pdf_bytes。当前没有 OCR;扫描版或无文本层 PDF 会失败。提取被截断时,笔记
frontmatter 中的 pdf_text_truncated 会记录为 true。
5. Digest
daily_paper_digest_step 以内存中的三篇解读作为本期事实来源生成中文简报,同时搜索并按需读取较早的 daily
文章来识别相关报道;历史文章只能用于建立上下文 wikilink,不能用于补充本期论文事实。输出必须包含 title、desc 和 body
。代码会:
- 去掉模型可能生成的 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_PROXY、HTTPS_PROXY 或 NO_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_cronJob 默认启用镜像;设置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:2333。daily_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