Paper-Essence 论文精华推送工作流搭建教程

Paper-Essence 论文精华推送工作流搭建教程

:open_book: 项目简介

Paper-Essence 是一个基于 Dify 平台搭建的自动化论文推送工作流。该工作流能够:

  • :one_o_clock: 每天定时从 ArXiv 获取指定研究领域的最新论文
  • :robot: 使用大模型智能筛选出最有价值的论文
  • :page_facing_up: 通过 OCR 解析论文 PDF,提取关键技术细节
  • :e_mail: 生成结构化的论文日报并通过邮件自动推送

GitHub 仓库:https://github.com/LiaoYFBH/PaperFlow,您可直接导入 prj\Paper-Essence-CN.yml 或 prj\Paper-Essence-EN.yml。


:hammer_and_wrench: 前置准备

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 URL
  • NEXT_PUBLIC_SUPABASE_PUBLISHABLE_DEFAULT_KEY → 对应 Dify Supabase 插件的 Supabase Key

步骤 4:在 Dify 中配置 Supabase 插件

在 Dify 插件管理中配置 Supabase 插件,填入上述 URL 和 Key。


:bar_chart: 工作流总体架构

流程说明

阶段 节点 功能描述
触发 定时触发器 每日指定时间自动启动
配置 配置节点 读取所有环境变量并输出供后续使用
翻译 LLM翻译 将研究主题翻译为英文
搜索 Get Rows → 预处理 → HTTP请求 → 后处理 查询已推送记录,搜索 ArXiv 新论文
初审 LLM初审 使用 LLM 筛选 Top 3 论文
迭代 迭代节点 对每篇论文执行:解包→记录→OCR→分析→组装
输出 模板转换 → 邮件发送 生成格式化报告并邮件推送

本工作流完整视图:


:wrench: 详细搭建步骤

第一步:创建工作流

  1. 登录 Dify 平台
  2. 点击「工作室」→「创建应用」→ 选择「工作流」类型
  3. 输入应用名称
  4. 选择触发器类型

第二步:配置环境变量

在 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-128kernie-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:已推送记录(用于去重)

代码逻辑

  1. 计算回溯日期(cutoff_date)
  2. 解析 Supabase 返回的已推送论文 ID 列表
  3. 根据 topic 构建布尔查询字符串(支持 AND/OR 逻辑)
  4. 根据 topic 关键词添加 ArXiv 分类限制(如 cs.CV, cs.CL 等)
  5. 提取搜索关键词用于后续过滤

输出变量

  • 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: 0
    • max_results: {{fetch_limit}}
    • sortBy: submittedDate
    • sortOrder: descending

7.3 搜索论文节点后处理 (代码节点)

节点名称搜索论文节点后处理
节点类型code

解析 API 返回的 XML 数据,并进行精细过滤。

输入变量

  • http_response_body: HTTP 节点的响应体
  • 以及预处理节点的所有输出变量

代码逻辑

  1. 解析 XML 响应
  2. 去重过滤:剔除在 pushed_ids 中的论文
  3. 日期过滤:剔除早于 cutoff_date 的论文
  4. 关键词过滤:确保标题或摘要中包含至少一个搜索关键词
  5. 格式化输出为 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
  • 支持 paperstop_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 URL
  • fileType:0(PDF 文件)
  • useLayoutDetection:true(启用版面检测)
  • prettifyMarkdown:true(美化输出)

10.4 get_footnote_text(代码节点)

提取 OCR 文本中的脚注信息,用于后续的机构识别。

10.5 truncated_text(代码节点)

裁剪 OCR 文本以控制 LLM 输入长度,避免超出 token 限制。

10.6 LLM深度分析

节点名称(LLM)分析
节点类型llm

对论文进行深度分析,提取关键信息。

提取字段

  1. One_Liner:一句话痛点与解决方案
  2. Architecture:模型架构与关键创新点
  3. Dataset:数据来源与规模
  4. Metrics:核心性能指标
  5. Chinese_Abstract:中文摘要翻译
  6. Affiliation:作者机构
  7. Code_Url:代码链接

核心原则

  • 拒绝废话:直接说具体方法
  • 深挖细节:总结算法逻辑、损失函数设计
  • 数据优先:展示对比 SOTA 的提升幅度
  • 禁止 N/A:合理推断

输出格式:纯 JSON 对象

10.7 数据组装(代码节点)

节点名称数据组装
节点类型code

将所有信息组装成结构化的论文对象。

核心功能

  1. 解析发布状态(识别顶会论文)
  2. 解析 LLM 输出的 JSON
  3. 提取代码链接
  4. 组装最终论文对象

输出字段

  • 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:收件人邮箱
  • subjectPaperEssence-{{cutoff_str}}-{{today_str}}
  • content:模板转换后的内容

第十三步:输出节点

节点名称输出
节点类型end

输出最终结果,便于调试和验证。


:outbox_tray: 发布工作流并获取 API

等 workflow 调试通过后,点击右上角发布按钮。

记录以下信息:

  • API 端点:api.dify.ai/v1/workflows/run
  • API 密钥:形如 app-xxxxxxxxxxxx 的字符串

:alarm_clock: 配置每天自动运行

由于 Dify 云端平台的定时触发器在免费版可能存在限制,可以使用 Windows 任务计划程序配合脚本来实现每日定时触发工作流。

前置条件:安装 Git for Windows

本方案使用 Git Bash 执行 curl 命令,因此需要先安装 Git for Windows。

安装时注意:

  • 建议选择默认安装路径(如 C:\Program Files\Git)或自定义路径(如 D:\ProgramFiles\Git
  • 安装选项中确保勾选 “Git Bash Here”

配置 Windows 任务计划程序

  1. 按下 Win + R → 输入 taskschd.msc,回车,打开任务计划程序
  2. 点击右侧「创建任务」

常规标签:

  • 名称Paper-Essence Daily Run
  • 勾选「使用最高权限运行」

触发器标签:

  1. 点击「新建」
  2. 「开始任务」下拉框选择「按预定计划」
  3. 选择「每天」,设置触发时间(建议与 Dify 工作流中的定时器时间一致,如 20:55
  4. 点击「确定」

操作标签:

  1. 点击「新建」

  2. 操作选择「启动程序」

  3. 程序或脚本:输入你的 Git Bash 路径,例如:D:\ProgramFiles\Git\bin\bash.exe

  4. 添加参数

    curl -N -X POST "api地址" -H "Authorization: Bearer app-你的API密钥" -H "Content-Type: application/json" -d '{ "inputs": {}, "response_mode": "streaming", "user": "cron-job" }'
    
  5. 点击「确定」保存任务


:test_tube: 测试与调试

手动测试

  1. 点击工作流编辑器右上角的「运行」按钮
  2. 观察每个节点的执行状态
  3. 检查各节点的输出是否符合预期

成功运行效果

当工作流成功执行后,你将在邮箱中收到格式化的论文日报邮件,包含:

  • 论文标题、作者、机构
  • PDF 链接和代码链接
  • 中英文摘要
  • AI 分析的核心创新点、架构、数据集和性能指标

:memo: 总结

本教程涉及 YAML 节点配置与调度、环境变量与 Supabase 使用,并搭建了从 ArXiv 抓取 → PaddleOCR 解析 → LLM 分析 → Jinja2 模板化 → SMTP 投递的端到端流水线,同时加强了去重、错误处理。

致谢

感谢张晶老师、关木老师、杨有志老师的指导。

1 个赞