📓

Difyでnote記事検索ワークフローを作ったので共有する【DSL配布あり】

に公開

「noteで気になるキーワードの記事をまとめて読みたいけど、一つずつ開くのが面倒…」

「集めた記事のタイトルとリンクだけをリストにしたいな…」

そんな情報収集のお悩みを、AIアプリ開発プラットフォームDifyで解決するツールを構築しました!

この記事では、note.comの記事を検索し、本文を整形して、JSON/TEXT形式で柔軟にデータを抽出できるワークフローをメインに紹介します。チャットフローアプリはあくまでこのワークフローの活用例として扱います。

完成したDSL/YAMLファイル(アプリファイル)を配布するので、あなたのDify環境にインポートするだけですぐに利用を開始できます!

このワークフローで出来ること

デモをご覧ください。このように、パラメータを選んでキーワードを入力するだけで…

指定した条件で、記事の本文が綺麗に整形されて返ってきます!

この記事を読めば、この便利なツールをあなたの環境で動かすための、すべての手順が分かります。

アプリを連携させるツール機能が凄い!

このシステムは、実は2つのアプリが連携して動いていますが、重要なのはワークフロー(Note Scraper API)で、チャットフロー(note.com 記事検索)はその活用例としてサンプルアプリとなっています。

  1. Note Scraper API(ワークフロー)
    note.comからデータを取得し、整形する働き者。APIとして機能します。
  2. note.com 記事検索(チャットフロー)
    ユーザーと対話する窓口。APIを呼び出して結果を表示するチャットアプリです。

なぜ分けるの?と思うかもしれませんが、このように処理を分けることで、「Note Scraper API」を他のアプリからも再利用できるようになり、非常に拡張性が高くなります。Difyの強力なワークフローをツールとして利用する機能の素晴らしさを体験してみましょう!

事前準備:2つのアプリをDifyにインポート

まずは、配布する2つのDSL(YAML)ファイルをあなたのDify環境にインポートします。

  1. Note.com Article Scraper.yml をインポートします(この記事ではNote Scraper APIと呼ぶことにします)。

https://difyshare.com/flow/68cea8bd002136ed9dab

2.Interactive Article Search.yml をインポートします(この記事ではnote.com 記事検索と呼ぶことにします)。

https://difyshare.com/flow/68cea8e70027cf9d4539

これで準備の第一段階は完了です。

バックエンドAPIをツールとして公開する

次に、チャットアプリから呼び出せるように、「Note Scraper API」をツールとして公開します。ここが一番大事なポイントです!

  1. インポートしたNote Scraper APIワークフローを開き、右上の公開ボタンを押します。
  2. アプリの概要ページに戻り、ワークフローをツールとして公開をオンにします。
  3. ツールコール名に noteapi のように好きな名前(英字・アンダースコアのみ)を設定します。
  4. ツール入力が以下のようになっていることを確認します。
パラメータ名 必須 説明
keyword string はい note.comで検索したい記事のキーワード。
size number いいえ 検索結果として取得したい記事件数。空欄の場合は3件。
start number いいえ 検索結果の何番目から取得するかを指定(0始まり)。
max_length number いいえ 記事本文の最大文字数。0または空欄で制限なし。
response select はい 最終的な出力形式を JSON または TEXT から選択。

チャットアプリとAPIを連携させる

最後に、チャットアプリnote.com 記事検索を開き、先ほど公開したAPIツールを正しく呼び出せるように設定します。

  1. ツールの再設定
    note.com 記事検索チャットフローを開きます。

【仕様上の注意点】

  1. ツールノードの入力設定
    新しく配置したNote Scraper APIツールノードの「Tool Parameters」を以下のように設定します。

パラメータ名 設定値 説明
keyword {{sys.query}} ユーザーのチャット入力をキーワードとして渡します。
response JSON 常にJSON形式でデータを受け取ります。
size 3 (任意) 取得件数を固定値で指定します。
start 0 (任意) 取得開始位置を固定値で指定します。
max_length 0 (任意) 文字数制限なしに設定します。

後続ノードのエラー修正

各ノードを開き、input_data変数の参照先を、新しく配置したNote Scraper APIノードの出力変数jsonに設定し直してください。

内部処理とコード

このチャットアプリが、どのようにしてユーザーの選択に応じてデータを絞り込んでいるか、内部のコードを紹介します。カスタマイズの参考にしてください。

ユーザーインターフェース

開始ノードで、ユーザーが操作するパラメータを定義しています。

項目名 変数名 タイプ 説明
取得モード mode Select すべて取得 か 番号で指定して取得 を選びます。
抽出する項目 filter_key Select タイトル, 著者, リンク, コンテンツから選びます。
取得する記事の番号 item_index Number 「番号で指定」の時に、何番目の記事を取得するかを指定します。

「すべて取得」が選ばれた場合の処理 (全件抽出ノード)

JSONデータの中から指定された項目をすべて抜き出します。
【入力変数】

変数名 参照元
input_data Array(Object) {{Note_Scraper_API.json}}
filter_key String {{キー名を英語に変換.filter_key}}

【出力変数】

変数名
result Array(String)

【コード】

python3
`def main(**kwargs) -> dict:`  
  `input_data = kwargs.get('input_data', [])`  
  `filter_key = kwargs.get('filter_key', 'title')`  
    
  `extracted_values = []`  
    
  `try:`  
    `article_list = input_data[0]['json']`  
      
    `if isinstance(article_list, list):`  
      `for article in article_list:`  
        `if isinstance(article, dict) and filter_key in article:`  
          `extracted_values.append(article[filter_key])`  
        
  `except (IndexError, TypeError, KeyError, AttributeError):`  
    `pass`  
      
  `return {`  
    `'result': extracted_values`  
  `}`

「番号で指定して取得」が選ばれた場合の処理 (個別抽出ノード)

指定された番号の記事から、1つの項目だけを抜き出します。
【入力変数】

変数名 参照元
input_data Array(Object) {{Note_Scraper_API.json}}
filter_key String {{キー名を英語に変換.filter_key}}
item_index Number {{開始.item_index}}

【出力変数】

変数名
result String

【コード】

python3
`def main(**kwargs) -> dict:`  
  `input_data = kwargs.get('input_data', [])`  
  `filter_key = kwargs.get('filter_key', 'title')`  
  `item_index = kwargs.get('item_index', 0)`

  `result_string = "指定された項目が見つかりませんでした。"`

  `try:`  
    `article_list = input_data[0]['json']`

    `if isinstance(article_list, list) and 0 <= item_index < len(article_list):`  
      `target_article = article_list[item_index]`  
        
      `if isinstance(target_article, dict) and filter_key in target_article:`  
        `result_string = str(target_article[filter_key])`

  `except (IndexError, TypeError, KeyError, AttributeError):`  
    `pass`

  `return {`  
    `'result': result_string`  
  `}`

上記のコードはすべてGeminiによって生成されています。あるプロンプトをリクエストするだけでDify上で動くPythonコードがつくれます。こちらの記事で解説しているのでご活用ください!👇

https://zenn.dev/lnkiai/articles/3290e1cb2fc7b1

おわりに

お疲れ様でした!これで、note.com記事検索チャットアプリの準備が整いました。

今回は基本的な使い方を紹介しましたが、ここからさらにAI要約機能を追加したり、特定のキーワードの出現回数をカウントしたりと、アイデア次第でどんどん機能を拡張できます。

ぜひこのワークフローをベースに、あなただけのオリジナルツールを作ってみてくださいね!

ダウンロードはこちら👇
Note Scraper APIワークフローのDSLファイル

https://difyshare.com/flow/68cea8bd002136ed9dab

note.com 記事検索チャットフロー活用DSLファイル

https://difyshare.com/flow/68cea8e70027cf9d4539

Discussion