📓

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