Paper-Essence 论文精华推送工作流搭建教程
项目简介
Paper-Essence 是一个基于 Dify 平台搭建的自动化论文推送工作流。该工作流能够:
每天定时从 ArXiv 获取指定研究领域的最新论文
使用大模型智能筛选出最有价值的论文
通过 OCR 解析论文 PDF,提取关键技术细节
生成结构化的论文日报并通过邮件自动推送
GitHub 仓库:https://github.com/LiaoYFBH/PaperFlow,您可直接导入 prj\Paper-Essence-CN.yml 或 prj\Paper-Essence-EN.yml。
前置准备
1. 平台与账号准备
- Dify 平台账号:确保已注册并登录 Dify 平台(也可采用docker部署)
- 邮箱账号:需要一个支持 SMTP 的邮箱(本教程使用 163 邮箱)
- 大模型 API:需要配置文心飞桨星河社区的 API
2. 安装必要的插件
在 Dify 插件市场中安装以下插件:
| 插件名称 | 用途 |
|---|---|
| PaddleOCR | PDF/图片 OCR 解析 |
| 163SMTP邮件发送 | 163 邮箱 SMTP 发送 |
| Supabase | 数据库存储(记录已推送论文) |
| 文心飞桨星河社区 | 星河社区 API 调用百度文心大模型调用 |
3. 准备 Supabase 数据库
为了实现对已经给用户推送过的论文过滤的功能,这里使用云端数据库supabase。
步骤 1:登录并创建项目
访问 supabase.com,点击右上角登录,然后点击 Start your project
步骤 2:创建数据表
在 SQL Editor 中执行以下 SQL 语句:
在数据库中新建一张用于记录论文推送信息的表,表名定义为pushed_papers,同时为表设置了两个核心字段并添加了数据完整性约束,确保论文推送记录的唯一性和有效性。
create table pushed_papers (
arxiv_id text not null,
pushed_at timestamp default now(),
primary key (arxiv_id)
);
步骤 3:获取 API 密钥
在 Project Settings → API 中记录以下信息:
NEXT_PUBLIC_SUPABASE_URL→ 对应 Dify Supabase 插件的 Supabase URLNEXT_PUBLIC_SUPABASE_PUBLISHABLE_DEFAULT_KEY→ 对应 Dify Supabase 插件的 Supabase Key
步骤 4:在 Dify 中配置 Supabase 插件
在 Dify 插件管理中配置 Supabase 插件,填入上述 URL 和 Key。
工作流总体架构
流程说明
| 阶段 | 节点 | 功能描述 |
|---|---|---|
| 触发 | 定时触发器 | 每日指定时间自动启动 |
| 配置 | 配置节点 | 读取所有环境变量并输出供后续使用 |
| 翻译 | LLM翻译 | 将研究主题翻译为英文 |
| 搜索 | Get Rows → 预处理 → HTTP请求 → 后处理 | 查询已推送记录,搜索 ArXiv 新论文 |
| 初审 | LLM初审 | 使用 LLM 筛选 Top 3 论文 |
| 迭代 | 迭代节点 | 对每篇论文执行:解包→记录→OCR→分析→组装 |
| 输出 | 模板转换 → 邮件发送 | 生成格式化报告并邮件推送 |
本工作流完整视图:
详细搭建步骤
第一步:创建工作流
- 登录 Dify 平台
- 点击「工作室」→「创建应用」→ 选择「工作流」类型
- 输入应用名称
- 选择触发器类型
第二步:配置环境变量
在 UI 界面右上角点击设置按钮,添加环境变量:
| 变量名 | 类型 | 说明 | 示例值 |
|---|---|---|---|
table_name |
string | Supabase 表名 | pushed_papers |
SMTP_PORT |
string | 邮箱 SMTP 端口 | 465 |
SMTP_SERVER |
string | SMTP 服务器 | smtp.163.com |
SMTP_PASSWORD |
secret | 邮箱授权码 | (你的授权码) |
SMTP_USER |
secret | 邮箱账号 | your_email@163.com |
MY_RAW_TOPIC |
string | 研究主题 | agent记忆 |
获取邮箱授权码:登录163邮箱 → 设置 → POP3/SMTP/IMAP → 开启服务并获取授权码
第三步:定时触发器节点
节点名称:定时触发器
配置项:
- 触发频率:每日(daily)
- 触发时间:
8:59 AM(或根据需求调整)
第四步:配置节点(代码节点)
节点名称:配置
节点类型:code
该节点负责读取所有环境变量并输出供后续节点使用。
输入变量:
- 从环境变量读取:
SMTP_PORT,SMTP_SERVER,SMTP_USER,SMTP_PASSWORD,MY_RAW_TOPIC,table_name
输出变量:
raw_topic:研究主题user_email:接收邮箱fetch_count:搜索论文数量(默认 50)push_limit:推送数量限制(默认 3)days_lookback:回溯天数(默认 30)- 以及 SMTP 相关配置
代码:
import os
def main(
SMTP_USER: str,
MY_RAW_TOPIC: str,
SMTP_PORT: str,
SMTP_SERVER: str,
SMTP_PASSWORD: str,
table_name: str
) -> dict:
user_email = SMTP_USER
raw_topic = MY_RAW_TOPIC
smtp_port = SMTP_PORT
smtp_server = SMTP_SERVER
smtp_password = SMTP_PASSWORD
table_name = table_name
return {
"raw_topic": raw_topic,
"user_email": user_email,
"smtp_port": smtp_port,
"smtp_server": smtp_server,
"smtp_password": smtp_password,
"fetch_count": 50,
"push_limit": 3,
"days_lookback": 30,
"table_name": table_name
}
第五步:研究领域翻译(LLM节点)
节点名称:研究领域LLM翻译
节点类型:llm
将中文研究主题翻译为 ArXiv API 可识别的英文布尔查询字符串。
模型配置:
- 模型:
ernie-4.5-turbo-128k或ernie-5.0-thinking-preview - 温度:
0.7
系统提示词:
你是一个专业的学术翻译助手。请将用户输入的中文研究主题翻译为英文,并转换为适合 ArXiv API 的布尔查询字符串格式。
要求:
1. 识别核心关键词并翻译为英文
2. 使用 AND/OR 连接多个关键词
3. 输出纯文本,不要有额外解释
4. 示例:输入"多模态大模型" → 输出"multimodal AND large language model"
第六步:查询已推送记录(Supabase节点)
节点名称:Get Rows
节点类型:tool (Supabase)
从 Supabase 数据库查询已推送的论文记录,避免重复推送。
配置:
- 表名:
{{table_name}}(从配置节点获取)
第七步:搜索论文(拆分为3个节点)
为了提高工作流的稳定性和可维护性,将搜索功能拆分为 “预处理” → “HTTP请求” → “后处理” 三个连续的节点。
7.1 搜索论文节点预处理 (代码节点)
节点名称:搜索论文节点预处理
节点类型:code
该节点负责准备搜索参数,计算日期范围,并构建 ArXiv API 查询字符串。
输入变量:
topic:翻译后的英文搜索词days_lookback:回溯天数count:搜索数量supabase_output:已推送记录(用于去重)
代码逻辑:
- 计算回溯日期(cutoff_date)
- 解析 Supabase 返回的已推送论文 ID 列表
- 根据 topic 构建布尔查询字符串(支持 AND/OR 逻辑)
- 根据 topic 关键词添加 ArXiv 分类限制(如 cs.CV, cs.CL 等)
- 提取搜索关键词用于后续过滤
输出变量:
base_query:构建好的查询字符串pushed_ids:已推送 ID 列表cutoff_str:截止日期字符串search_keywords:搜索关键词列表fetch_limit:API 获取数量上限
7.2 HTTP 请求 (HTTP 节点)
节点名称:HTTP 请求
节点类型:http-request
直接调用 ArXiv API 获取原始 XML 数据。
配置:
- API URL:
export.arxiv.org/api/query - Method:
GET - Query Parameters:
search_query:{{base_query}}start:0max_results:{{fetch_limit}}sortBy:submittedDatesortOrder:descending
7.3 搜索论文节点后处理 (代码节点)
节点名称:搜索论文节点后处理
节点类型:code
解析 API 返回的 XML 数据,并进行精细过滤。
输入变量:
http_response_body: HTTP 节点的响应体- 以及预处理节点的所有输出变量
代码逻辑:
- 解析 XML 响应
- 去重过滤:剔除在
pushed_ids中的论文 - 日期过滤:剔除早于
cutoff_date的论文 - 关键词过滤:确保标题或摘要中包含至少一个搜索关键词
- 格式化输出为 JSON 对象列表
输出变量:
result:最终筛选出的论文列表(JSON 字符串)count:最终论文数量debug:调试信息(包含过滤统计)
第八步:LLM初审筛选(LLM节点)
节点名称:LLM初审
节点类型:llm
使用 LLM 对论文进行初步评审,筛选出最有价值的论文。
系统提示词:
你是一位资深的学术研究员,擅长快速评估论文价值。
任务:从给定的论文列表中筛选出最有价值的 Top 3 论文。
评估标准:
1. 创新性:方法是否新颖
2. 实用性:是否有实际应用价值
3. 影响力:作者机构、发表状态
4. 技术深度:是否有技术突破
输出要求:
- 纯净 JSON 数组格式
- 保留所有原始字段
- 输出 Top 3 论文
第九步:JSON解析(代码节点)
节点名称:JSON 解析
节点类型:code
解析 LLM 输出的 JSON 字符串,处理各种可能的格式。
核心逻辑:
- 处理嵌套 JSON
- 支持
papers或top_papers字段 - 容错处理
第十步:迭代节点
节点名称:迭代
节点类型:iteration
对筛选后的每篇论文进行迭代处理。
配置:
- 输入:
top_papers(论文数组) - 输出:
merged_paper(处理后的论文对象) - 并行模式:关闭(顺序执行)
- 错误处理:遇错终止
迭代内部详细流程
| 序号 | 节点名称 | 类型 | 功能 |
|---|---|---|---|
| 1 | DataUnpack | code | 将迭代项拆解为独立变量 |
| 2 | Create a Row | tool | 将 arxiv_id 记录到 Supabase 防重复 |
| 3 | 大模型文档解析 | tool | PaddleOCR 解析 PDF 提取正文 |
| 4 | get_footnote_text | code | 提取脚注信息(用于机构识别) |
| 5 | truncated_text | code | 裁剪 OCR 文本(控制 LLM 输入长度) |
| 6 | (LLM)分析 | llm | 深度分析论文提取关键信息 |
| 7 | 数据组装 | code | 组装最终的论文对象 |
10.1 DataUnpack(代码节点)
将迭代项拆解为独立变量。
输出:
title_str:论文标题pdf_url:PDF 链接summary_str:摘要published:发布日期authors:作者arxiv_id:ArXiv ID
10.2 Create a Row(Supabase节点)
将论文 ArXiv ID 记录到数据库,防止重复推送。
配置:
- 表名:从配置节点获取
- 数据:
{"arxiv_id": "{{arxiv_id}}"}
10.3 大模型文档解析(PaddleOCR节点)
节点名称:大模型文档解析
节点类型:tool (PaddleOCR)
使用 PaddleOCR 解析论文 PDF,提取正文内容。
配置:
file:PDF URLfileType:0(PDF 文件)useLayoutDetection:true(启用版面检测)prettifyMarkdown:true(美化输出)
10.4 get_footnote_text(代码节点)
提取 OCR 文本中的脚注信息,用于后续的机构识别。
10.5 truncated_text(代码节点)
裁剪 OCR 文本以控制 LLM 输入长度,避免超出 token 限制。
10.6 LLM深度分析
节点名称:(LLM)分析
节点类型:llm
对论文进行深度分析,提取关键信息。
提取字段:
- One_Liner:一句话痛点与解决方案
- Architecture:模型架构与关键创新点
- Dataset:数据来源与规模
- Metrics:核心性能指标
- Chinese_Abstract:中文摘要翻译
- Affiliation:作者机构
- Code_Url:代码链接
核心原则:
- 拒绝废话:直接说具体方法
- 深挖细节:总结算法逻辑、损失函数设计
- 数据优先:展示对比 SOTA 的提升幅度
- 禁止 N/A:合理推断
输出格式:纯 JSON 对象
10.7 数据组装(代码节点)
节点名称:数据组装
节点类型:code
将所有信息组装成结构化的论文对象。
核心功能:
- 解析发布状态(识别顶会论文)
- 解析 LLM 输出的 JSON
- 提取代码链接
- 组装最终论文对象
输出字段:
title:标题authors:作者affiliation:机构pdf_url:PDF 链接summary:英文摘要published:发布状态github_stats:代码状态code_url:代码链接ai_evaluation:AI 分析结果
第十一步:模板转换
节点名称:模板转换
节点类型:template-transform
使用 Jinja2 模板将论文数据转换为格式化的邮件内容。
模板结构:
📅 PaperEssence 科研日报
根据您指定的研究内容"{{ raw_topic }}",每天推送 arxiv 近 30 天更新论文中挑选的 3 篇论文。
--------------------------------------------------
<small><i>⚠️ 注:内容由 AI 生成,仅供学术参考。请在引用或深入研究前,务必点击 PDF 链接查阅原始论文进行核实。</i></small>
生成日期: {{ items.target_date | default('Today') }}
==================================================
{% set final_list = items.paper | default(items) %}
{% for item in final_list %}
📄 [{{ loop.index }}] {{ item.title }}
--------------------------------------------------
👤 作者: {{ item.authors }}
🏢 机构: {{ item.affiliation }}
🔗 PDF: {{ item.pdf_url }}
📅 状态: {{ item.published }}
{% if item.code_url and item.code_url != 'N/A' %}
📦 Code: {{ item.github_stats }}
🔗 {{ item.code_url }}
{% else %}
📦 Code: {{ item.github_stats }}
{% endif %}
English Abstract:
{{ item.summary | replace('\n', ' ') }}
中文摘要:
{{ item.ai_evaluation.Chinese_Abstract }}
🚀 核心创新:
{{ item.ai_evaluation.One_Liner }}
📊 总结:
--------------------------------------------------
🏗️ 架构:
{{ item.ai_evaluation.Architecture | replace('\n- ', '\n\n 🔹 ') | replace('- ', ' 🔹 ') }}
💾 数据:
{{ item.ai_evaluation.Dataset | replace('\n- ', '\n\n 🔹 ') | replace('- ', ' 🔹 ') }}
📈 指标:
{{ item.ai_evaluation.Metrics | replace('\n- ', '\n\n 🔹 ') | replace('- ', ' 🔹 ') }}
==================================================
{% else %}
⚠️ 今日无新论文更新。
{% endfor %}
第十二步:邮件发送
节点名称:163SMTP邮件发送
节点类型:tool (163-smtp-send-mail)
配置:
username_send:发件人邮箱(从环境变量读取)authorization_code:邮箱授权码(从环境变量读取)username_recv:收件人邮箱subject:PaperEssence-{{cutoff_str}}-{{today_str}}content:模板转换后的内容
第十三步:输出节点
节点名称:输出
节点类型:end
输出最终结果,便于调试和验证。
发布工作流并获取 API
等 workflow 调试通过后,点击右上角发布按钮。
记录以下信息:
- API 端点:api.dify.ai/v1/workflows/run
- API 密钥:形如
app-xxxxxxxxxxxx的字符串
配置每天自动运行
由于 Dify 云端平台的定时触发器在免费版可能存在限制,可以使用 Windows 任务计划程序配合脚本来实现每日定时触发工作流。
前置条件:安装 Git for Windows
本方案使用 Git Bash 执行 curl 命令,因此需要先安装 Git for Windows。
安装时注意:
- 建议选择默认安装路径(如
C:\Program Files\Git)或自定义路径(如D:\ProgramFiles\Git) - 安装选项中确保勾选 “Git Bash Here”
配置 Windows 任务计划程序
- 按下
Win + R→ 输入taskschd.msc,回车,打开任务计划程序 - 点击右侧「创建任务」
常规标签:
- 名称:
Paper-Essence Daily Run - 勾选「使用最高权限运行」
触发器标签:
- 点击「新建」
- 「开始任务」下拉框选择「按预定计划」
- 选择「每天」,设置触发时间(建议与 Dify 工作流中的定时器时间一致,如
20:55) - 点击「确定」
操作标签:
-
点击「新建」
-
操作选择「启动程序」
-
程序或脚本:输入你的 Git Bash 路径,例如:
D:\ProgramFiles\Git\bin\bash.exe -
添加参数:
curl -N -X POST "api地址" -H "Authorization: Bearer app-你的API密钥" -H "Content-Type: application/json" -d '{ "inputs": {}, "response_mode": "streaming", "user": "cron-job" }' -
点击「确定」保存任务
测试与调试
手动测试
- 点击工作流编辑器右上角的「运行」按钮
- 观察每个节点的执行状态
- 检查各节点的输出是否符合预期
成功运行效果
当工作流成功执行后,你将在邮箱中收到格式化的论文日报邮件,包含:
- 论文标题、作者、机构
- PDF 链接和代码链接
- 中英文摘要
- AI 分析的核心创新点、架构、数据集和性能指标
总结
本教程涉及 YAML 节点配置与调度、环境变量与 Supabase 使用,并搭建了从 ArXiv 抓取 → PaddleOCR 解析 → LLM 分析 → Jinja2 模板化 → SMTP 投递的端到端流水线,同时加强了去重、错误处理。
致谢
感谢张晶老师、关木老师、杨有志老师的指导。