Difyワークフローでファイルの操作を試してみた

# はじめに

メリークリスマス！
NTTテクノクロスのNitabushiです。
普段はAWSの設計やLLMを用いたアプリケーションの開発に携わっています。

今回は [NTTテクノクロス Advent Calendar 2024](https://qiita.com/advent-calendar/2024/ntt-tx)シリーズ1の17日目（12/17）の記事です。
LLMアプリ開発プラットフォーム「Dify」について、ワークフロー機能における簡単なファイル操作について解説します。

# Difyとは

- OSSとして提供されているノーコードのLLMアプリケーション開発プラットフォームです
- ブラウザ上で簡単にLLM（大規模言語モデル）を活用したアプリケーションを開発することができます
![ワークフロー完成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3112326/c2156eee-68d3-ea26-9da0-4ba925597fa6.png)

- 例えば、LLMの呼び出しや、それに続く分岐処理、ファイル操作、さらにはRAGの利用もサポートしており、誰でも手軽にアプリ開発を始められる仕組みが整っているのが魅力です
- 今回の記事では基礎的な利用方法は省き、v.0.10.0から追加された**ファイルアップロード機能**について解説します

# なぜファイルアップロード機能に着目したのか？
DifyではLLMアプリケーションの動作をワークフローとして定義することができます。

:::note
ワークフローとは
- ① ユーザーが入力した情報にNGワードが含まれていないかをチェックする。
-  ② ①で問題がなければ、対象のLLMに問い合わせる。 

のように段階的な処理を指します。Difyではノードと呼ばれるブロックを組み合わせることで、様々な処理を実現することができます。
:::

以前のバージョンではワークフロー内で扱えるファイルの種類が限られており、テキストファイルを扱うことができませんでした。そのため回避策として以下のような方法がありました。

:::note
- ワークフローの入力情報にLLMで生成したい情報をベタ書きする方法
- ワークフローをバッチ処理として実行し、入力情報として利用可能なCSVファイル内にLLMで生成情報を記載する方法
:::

v0.10.0で新しくファイルアップロード機能が追加され、**テキスト、PDF、Officeなどのファイル形式がサポート**されました。
入力情報を整備する負荷が減っただけでなく、様々な資料をDifyで編集、加工することが可能になり、実現できることが増えました。

# Difyワークフローで簡単なファイル操作を実行してみる
それではDifyワークフローでファイル操作可能なフローを作成していきましょう。

## Difyワークフローの作成
- Difyスタジオ ＞ アプリを作成する ＞ 最初から作成 ＞ ワークフローを選択します
- 任意の名前を入力し、「作成する」を押下します
![Difyワークフロー画面を選択.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3112326/edd584e7-fd1d-0408-3f06-061c7ff6ee74.png)

- Difyワークフローが作成されるとブラウザ上でLLMアプリを開発可能なエディタ画面が表示されます
![Difyワークフロー_作成後画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3112326/ddb0ffc1-ae99-c8b4-f534-bb1879a5175a.png)

## 開始ノードの作成
- 開始とかかれている場所（正式には開始ノードと呼ぶ）をクリック ＞ 入力フィールドの「＋」ボタンを押下 ＞ フィールドタイプ「単一ファイル」を選択します
![Difyワークフロー_入力フィールド選択.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3112326/bf89c051-ae18-596a-dcd6-af1e6d877430.png)

- 任意の変数名、ラベル名を設定します、ここでは単一ファイルを取り扱うため「single_file」を設定します
※特にこだわりがない場合は、変数名を設定するとラベル名も同内容が入力されます
- サポートされたファイルタイプ ＞「ドキュメント」にチェックをいれます

:::note
※本記事ではテキストファイルを用いますが、他にもMarkdownやPDF、WordやPPT、Excelと幅広いドキュメントに対応しているのがわかりますね
:::

- サポートされたファイルのタイプ ＞「ローカルアップロード」を選択し、保存します
![Difyワークフロー_サポートされたファイルタイプ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3112326/7a6c0490-beda-43f0-f5d3-00ddc92dc05f.png)

- 開始タブの入力フィールドに「single_file」が追加されたことを確認してください
![Difyワークフロー_保存後の入力フィールド確認.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3112326/0a9268d6-1658-2b27-db83-74e6ab38be42.png)

## LLMノードの作成
- LLMノードを以下の内容で作成してください
    - モデル：gpt-4o-mini※今回はOpenAIの「gpt-4o-mini」を用います
    - SYSTEMプロンプト：記載内容はキャプチャを参照してください
    - USERプロンプト：記載内容はキャプチャを参照してください
    - モデルのパラメータ：編集なし、デフォルト設定を使用しています
![Difyワークフロー_LLMノード設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3112326/093d0f3a-94ec-3785-eba1-f6a946a4cb28.png)
※補足事項：各パラメータの設定については[Difyドキュメント](https://docs.dify.ai/ja-jp/guides/workflow/node/llm)を参考にしてください

## 終了ノード
- 最後に終了ノードを作成してください
- 終了ノードの出力変数には1つ前のLLMノードで定義している出力変数を定義します
![Difyワークフロー_終了ノード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3112326/a8f563d7-4c48-4b64-3b14-6276463b8132.png)

## ワークフロー完成！
- 開始ノードでファイルを受け取り、その内容を使ってLLMに質問するワークフローが完成しました
![ワークフロー完成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3112326/ecfcf5d5-5767-2381-71e9-04bfc83a54b4.png)

# ワークフローの動作確認
それでは早速ワークフローを実行してみましょう。
今回作成したワークフローはプロンプトに書店員という役割を与えておすすめの本を紹介してもらうという簡単な内容にしてみました。
ファイルの中身は以下となります。
> 「私は高校生です。夏休みの宿題で読書感想文を書く必要があります。おすすめの本を3冊教えてください。」
:::note warn
お手元で試される方は文字コードをUTF-8に修正してください。
:::

画面右上の実行ボタンを押下＞ローカルPCからファイルのアップロードが完了したら実行します
![Difyワークフロー実行.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3112326/003cdab0-f7d5-b1a1-03f2-60ee141d9b71.png)
失敗しちゃいました。。
![Difyワークフロー_失敗.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3112326/15411628-f4b6-6262-38dc-add7ee9eb482.png)
結果をみるとファイルの内容が読み取れないため、LLMノードで上手く質問を処理することができないみたいです

## 再実行
調査の結果、テキスト抽出ツールノードを使用することで解消できることがわかりました。この機能を利用することでアップロードしたファイルからテキストを抽出し、ワークフロー上で利用可能な変数の中に格納してくれます。

:::note
開始ノードで指定したファイル(single_file)をそのままDifyワークフローで使うことができないということがわかりましたね。
テキスト抽出ツールについては[こちら](https://docs.dify.ai/ja-jp/guides/workflow/node/doc-extractor)に詳しい記載があります。
:::

![Difyワークフロー_テキスト抽出ツールノード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3112326/60ec2956-1a27-c82d-22b6-8100f603c5de.png)

テキスト抽出ノードに開始ノードで定義した変数を設定します。
![Difyワークフロー_テキスト抽出ツールノード_変数ノード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3112326/d2dd3b1d-6b62-be65-812a-bea7dfa82639.png)

またLLMノードのUSERプロンプトもテキスト抽出ツールノードの変数に書き換えます
![Difyワークフロー_LLMノード修正.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3112326/59e9dc96-1113-b7ec-ffff-f07ebc920fe2.png)
それでは気を取り直して、再実行してみましょう！
![Difyワークフロー_再実行.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3112326/f4dfb9e8-1880-ff1c-bb46-dba46fb65dbc.png)
無事質問に対する結果が取得できました！

## まとめ
このようにDifyでは簡単にLLMをつかったアプリケーションを開発することが可能です。ブラウザベースで直観的に操作しやすく、アイデアを思い付いたらすぐに動くものが作れるのって楽しいですよね！

Difyはバージョンアップや新機能の発表頻度が多いので、気になる方は公式Twitterやリリースノートを定期的にチェックしてみてください。

# おわりに
ここまで読んでいただいてありがとうございました！
拙い文章ではございますが、今後も定期的に技術に関する情報を発信していければと考えております。お読みいただけましたら幸いです。
明日は[nakasho-devさん](https://qiita.com/nakasho-dev)による記事を引き続きお楽しみください。

# 【参考情報】Dify動作環境
## 環境情報
- OS：Windows11
- Dify Version：0.12.1
- Difyのデプロイ方法：ローカルデプロイ（WSL2＋Docker Engine＋Docker Compose）
    - 詳しい構築方法は本記事では解説しないため、[Difyドキュメント](https://docs.dify.ai/getting-started/install-self-hosted/docker-compose)を参考してください

## 補足事項
- DifyはSaasサービスとして利用することも可能ですが、今回はローカルPCにDifyのコンテナイメージを持ってきて、Docker Composeでデプロイしています。
- Saasサービスとしてのプランにご興味がある方は[公式サイト](https://dify.ai/pricing)を参照してください。