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/PaperFlowprj\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によるBaidu Wenxin大規模モデル呼び出し

3. Supabaseデータベースの準備

ユーザーにすでに配信した論文をフィルタリングする機能を実現するために、ここではクラウドデータベースSupabaseを使用します。

ステップ 1:ログインしてプロジェクトを作成

supabase.comにアクセスし、右上のログインをクリックし、次に「Start your project」をクリックします。

ステップ 2:データテーブルを作成

SQL Editorで以下のSQLステートメントを実行します。

論文配信情報を記録するための新しいテーブルをデータベースに作成します。テーブル名はpushed_papersと定義し、同時にテーブルに2つの主要なフィールドを設定し、データ整合性制約を追加して、論文配信記録の一意性と有効性を確保します。

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を使用して上位3論文を選別
イテレーション イテレーションノード 各論文に対して:アンパック→記録→OCR→分析→アセンブル を実行
出力 テンプレート変換 → メール送信 フォーマットされたレポートを生成し、メールで配信

このワークフローの完全なビュー:


:wrench: 詳細な構築手順

ステップ 1:ワークフローを作成

  1. Difyプラットフォームにログイン
  2. 「スタジオ」→「アプリケーションを作成」→「ワークフロー」タイプを選択
  3. アプリケーション名を入力
  4. トリガータイプを選択

ステップ 2:環境変数を設定

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 → サービスを有効にして認証コードを取得


ステップ 3:タイマートリガーノード

ノード名タイマートリガー

設定項目:

  • トリガー頻度:毎日(daily)
  • トリガー時間8:59 AM(または必要に応じて調整)

ステップ 4:設定ノード(コードノード)

ノード名設定
ノードタイプ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
    }

ステップ 5:研究分野翻訳(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」

ステップ 6:配信済み記録の照会(Supabaseノード)

ノード名Get Rows
ノードタイプtool (Supabase)

Supabaseデータベースから配信済みの論文記録を照会し、重複配信を回避します。

設定

  • テーブル名:{{table_name}}(設定ノードから取得)

ステップ 7:論文の検索(3つのノードに分割)

ワークフローの安定性と保守性を向上させるため、検索機能を「前処理」→「HTTPリクエスト」→「後処理」の3つの連続したノードに分割します。

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. キーワードフィルタリング:タイトルまたは要約に少なくとも1つの検索キーワードが含まれていることを確認
  5. JSONオブジェクトリストとして出力をフォーマット

出力変数

  • result:最終的に選別された論文リスト(JSON文字列)
  • count:最終論文数
  • debug:デバッグ情報(フィルタリング統計を含む)

ステップ 8:LLM一次審査選別(LLMノード)

ノード名LLM一次審査
ノードタイプllm

LLMを使用して論文を一次審査し、最も価値のある論文を選別します。

システムプロンプト

あなたは経験豊富な学術研究者であり、論文の価値を迅速に評価することに長けています。

タスク:与えられた論文リストから、最も価値のある上位3論文を選別してください。

評価基準:
1. 革新性:手法が新しいか
2. 実用性:実用的な応用価値があるか
3. 影響力:著者機関、発表状況
4. 技術的深さ:技術的なブレークスルーがあるか

出力要件:
- 純粋なJSON配列形式
- すべての元のフィールドを保持する
- 上位3論文を出力する

ステップ 9:JSON解析(コードノード)

ノード名JSON解析
ノードタイプcode

LLMが出力したJSON文字列を解析し、さまざまな可能性のある形式を処理します。

コアロジック

  • ネストされたJSONの処理
  • papersまたはtop_papersフィールドをサポート
  • 許容範囲内のエラー処理

ステップ 10:イテレーションノード

ノード名イテレーション
ノードタイプ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(コードノード)

LLM入力長を制御するためにOCRテキストをトリミングし、トークン制限を超えないようにします。

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分析結果

ステップ11:テンプレート変換

ノード名テンプレート変換
ノードタイプ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' %}
📦 コード: {{ item.github_stats }}
   🔗 {{ item.code_url }}
{% else %}
📦 コード: {{ item.github_stats }}
{% endif %}

英語要約:
{{ 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 %}

ステップ12:メール送信

ノード名163SMTP邮件发送
ノードタイプtool (163-smtp-send-mail)

設定

  • username_send:送信者メールアドレス(環境変数から読み込み)
  • authorization_code:メール認証コード(環境変数から読み込み)
  • username_recv:受信者メールアドレス
  • subjectPaperEssence-{{cutoff_str}}-{{today_str}}
  • content:テンプレート変換後のコンテンツ

ステップ13:出力ノード

ノード名出力
ノードタイプend

最終結果を出力し、デバッグと検証を容易にします。


:outbox_tray: ワークフローを公開してAPIを取得

ワークフローのデバッグが完了したら、右上の公開ボタンをクリックします。

以下の情報を記録します:

  • 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と入力し、Enterキーを押してタスクスケジューラを開きます
  2. 右側の「タスクの作成」をクリックします

全般タブ:

  • 名前Paper-Essence Daily Run
  • 「最上位の特権で実行する」にチェックを入れます

トリガータブ:

  1. 「新規」をクリックします
  2. 「タスクの開始」ドロップダウンリストで「スケジュールに従って」を選択します
  3. 「毎日」を選択し、トリガー時間を設定します(Difyワークフローのタイマー時間と一致させることをお推奨します。例:20:55
  4. 「OK」をクリックします

操作タブ:

  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. 「OK」をクリックしてタスクを保存します


:test_tube: テストとデバッグ

手動テスト

  1. ワークフローエディタの右上にある「実行」ボタンをクリックします
  2. 各ノードの実行ステータスを観察します
  3. 各ノードの出力が期待通りか確認します

実行成功時の効果

ワークフローが正常に実行されると、以下の内容を含むフォーマットされた論文日報メールが届きます:

  • 論文タイトル、著者、所属機関
  • PDFリンクとコードリンク
  • 中国語と英語の要約
  • AI分析による主要なイノベーションポイント、アーキテクチャ、データセット、性能指標

:memo: まとめ

このチュートリアルでは、YAMLノードの設定とスケジューリング、環境変数とSupabaseの使用について説明し、ArXivからの取得 → PaddleOCRによる解析 → LLMによる分析 → Jinja2によるテンプレート化 → SMTPによる配信というエンドツーエンドのパイプラインを構築し、重複排除とエラー処理も強化しました。

謝辞

張晶先生、関木先生、楊有志先生のご指導に感謝いたします。

「いいね!」 1