こんにちは、技術イベントに参加してきてアウトプット欲が高まっているハヤトです。
この記事は Dify Advent Calendar 2024 のシリーズ2、24日目の投稿です。
最近も精力的にアップデートが重ねられているDifyですが、
その中心的な機能であるワークフローとノードについて改めて基本的な内容を確認していきたいと思います。
実際に動作するワークフローを構築しながら説明するので、
Dify初心者の方も是非ご一読ください。
※本記事はDifyバージョン0.13.1時点のものです。
Difyについて
DifyはオープンソースのLLMアプリ開発プラットフォームです。
dify.ai
Difyの環境構築と基本的な使い方については以下の記事を参考にしてみてください。
acro-engineer.hatenablog.com
Difyの「ワークフロー」とは
Difyの「ワークフロー」は、小さな処理のステップ(ノード)を組み合わせることで一連のタスクを自動化することができる機能です。
以下のイメージのように、視覚的にノードを配置してつなぎ合わせることでワークフローを構築することができます。
非常に柔軟な機能なので様々なユースケースに適用できますが、例えば以下のようなことが実現できます。
- カスタマーサービス:よくある質問への自動応答を作成し、サポートチームの負担を軽減する。
- コンテンツ生成:与えられたアウトラインやテーマをもとに、ブログ記事や製品説明、マーケティング資料などを作成する。
- データ分析とレポート:大規模なデータセットを分析し、レポートや要約を生成する。
Difyワークフローの種類と使い分け
Difyアプリを最初から作成する際に、タイプ選択の中に「チャットフロー(Chatflow)」と「ワークフロー」があります。
これらがDifyで利用可能なワークフローで、それぞれの差分は以下のようになっています。
チャットフロー | ワークフロー | |
---|---|---|
適用シナリオ | カスタマーサービス、セマンティック検索、その他の対話型アプリケーションの構築において、複数のステップを含む論理を必要とする対話型シナリオに適している。 | 自動化とバッチ処理のシナリオに対応し、高品質な翻訳、データ分析、コンテンツ生成、メール自動化などのアプリケーションに適している。 |
固有のノード | プロセス終了時にのみ選択可能な終了ノードがある。 | プロセス中間ステップでも使用できる回答ノードがあり、テキストのストリーミング出力が可能。 |
使用する変数 | 開始時に実行変数を定義し、プロセス中で複雑な処理ロジックを実現するために使用する。 | sys.query、sys.files、sys.conversation_id、sys.user_idなどの内蔵変数が使用され、ユーザーとの対話履歴を保持するメモリ機能も使用可能。 |
まとめると、チャットフローは対話型のシナリオ向け、ワークフローは自動化やバッチ処理のシナリオ向けで、
利用可能なノードもそれに応じたものになっているという形ですね。
ノードについて
ワークフローで利用可能な全ノードの概要は以下の通りです。
Icon | ノード名 | 英名 | 説明 |
---|---|---|---|
開始 | Start | ワークフローの初期パラメータを定義する。 | |
終了 | End | ワークフローの最終出力内容を定義する。 | |
返信 | Answer | チャットフロー内の回答内容を定義する。 | |
大規模言語モデル | LLM | 大規模言語モデルを呼び出して質問に答えたり、自然言語を処理したりする。 | |
ナレッジ検索 | Knowledge Retrieval | 質問に関連するテキストをナレッジベースから検索し、後続のLLMノードで使用する。 | |
質問分類器 | Question Classifier | 分類の説明を定義することで、LLMがユーザーの入力に基づいて適切な分類を選択できるようにする。 | |
条件分岐 | IF/ELSE | if/elseの条件に基づいてワークフローを分岐する。 | |
コード実行 | Code | Python / NodeJSコードを実行してワークフロー内でデータ変換などのカスタムロジックを実行する。 | |
テンプレート | Template | Jinja2のPythonテンプレート言語を利用して、データ変換やテキスト処理を柔軟に行う。 | |
変数集約 | Variable Aggregator | 複数の分岐の変数を1つの変数に集約して、下流ノードで参照およびアクセスできるようにする。 | |
パラメーター抽出器 | Parameter Extractor | LLMにより構造化パラメーターを推論し、後続のツール呼び出しやHTTPリクエストに使用する。 | |
イテレーション | Iteration | リストオブジェクトに対して複数回のステップを実行し、すべての結果を出力する。 | |
HTTPリクエスト | HTTP Request | HTTPプロトコルを介してサーバーリクエストを送信し、外部サービスとの連携を実現する。 | |
- |
ツール | Tools | Dify内蔵ツール、カスタムツール、サブワークフローなどをワークフロー内で呼び出す。 |
変数代入 | Variable Assigner | 変数(会話変数など)に指定した値を代入する。 | |
リスト操作 | List Operator | 配列変数からフィルタやソート条件に基づいて要素を抽出する。 | |
テキスト抽出ツール | Document Extractor | アップロードした文書ファイルの情報を解析して読み取り、テキストに変換してLLMで使用する。 |
ここでは、LLMを活用するノードについて実際に動作するワークフローを構築しながら詳細を確認していきます。
ナレッジ検索
ナレッジベースからユーザーの質問に関連する内容を検索し、それを後続のLLMノードのコンテキストとして使用することができます。
一般的なシナリオとして、外部データ/ナレッジに基づくAI質問応答システム(RAG)を構築するために使用します。
ナレッジ検索を使用したシンプルなアプリケーションの例を示します。
※翻訳が揺れていますが、ナレッジ検索のブロック名は「知識取得」になっています。
このアプリでは、IPAが公開しているデジタルスキル標準のPDFをナレッジとして使用し、それに基づいて回答を行います。
作成の手順を見ていきましょう。
ナレッジの作成
ナレッジ検索を使用するには、まずナレッジを作成する必要があります。
Difyの「ナレッジ」ページで「ナレッジ作成」を選択し、データソースの選択から「テキストファイルからインポート」でPDFをアップロードします。
今回は簡易的にナレッジ検索を試すため、インデックスモードは「経済的」を選択し、他は変更せずに「保存して処理」を実行します。
※ナレッジベースの詳細を知りたい方は以下を参照してみてください。
docs.dify.ai
作成したナレッジが使用可能になったら、ワークフローを構成していきましょう。
ナレッジ検索を使用するワークフローの構成
アプリの「最初から作成」でチャットフローを作成します。
LLMノードの手前にナレッジ検索(知識取得)のブロックを追加し、先ほど作成したナレッジを使用するように設定します。
次に、後続のLLMノードで、取得したナレッジをコンテキストとして使用するように設定します。
SYSTEMプロンプトとして以下のような内容を与えることで、ナレッジに基づいた回答のみを行うアプリを構築できます。
{{#context#}} --- ユーザーからの質問に上記のコンテキストに基づいて回答してください。 コンテキストに含まれない情報については回答しないでください。。
プレビューから質問をしてみると、期待通りナレッジに基づいた回答をしてくれました。
質問分類器
LLMを使用して、与えられた分類の定義に対してユーザーの入力がどれに属するものかを判定し、処理を分岐することができます。
例えばカスタマーサービスのアプリを構築することを考えると、
ユーザーの質問が「製品について」なのか「アフターサービスについて」なのかを分類し、
それぞれに適したナレッジ検索を行うことで回答の精度を上げることができます。
先ほど作成したナレッジ検索の例を拡張して、以下のようなアプリを構築してみます。
- デジタルスキル標準に関する質問にはナレッジに基づいて回答する。
- それ以外のITに関する質問にはLLMを使って回答する。
- IT関連以外の質問には「IT以外の質問についてはお答え出来ません。」と回答する。
質問分類器の設定
開始ブロックの直接的に質問分類器を追加して、以下のようにクラスを設定します。
クラス1:「デジタルスキル標準に関する質問」には先ほど作成したナレッジ検索のワークフローを接続します。
クラス2:「IT全般に関する質問」には新しくLLMブロックを追加して接続します。
クラス3:「その他の質問」には固定の回答を返す回答ブロックを接続します。
これで、質問の分類に応じた回答が得られるようになりました。
パラメーター抽出器
Difyで用意されているツールやサードパーティのAPIを実行する際には、適切な入力パラメータが必要となります。
パラメーター抽出器では、ユーザーが入力した自然言語から構造化パラメーターを推論し、それらの呼び出しに使うことが出来ます。
先ほどのワークフローを更に拡張してみましょう。
論文に関する質問から著者名を抽出し、Dify組み込みのArxiv論文検索ツールを使って該当する論文を回答するようにしてみます。
パラメーター抽出器の設定
質問分類器のクラスに「論文に関する質問」を追加し、そこにパラメーター抽出器のブロックを作成して接続します。
ブロックの設定で「パラメータを抽出」から変数名"author"として論文の著者名を抽出するように設定します。
まとめ
今回はDifyのワークフローとノードの基本について、実際にワークフローを作成しながら確認していきました。
特に、LLMを使用して処理を行うノードはうまく活用することでより回答の精度を上げたり、
外部サービスと連携して機能を拡張することが可能になります。ぜひ皆さんも活用してみてください。
Acroquest Technologyでは、キャリア採用を行っています。
- Azure OpenAI/Amazon Bedrock等を使った生成AIソリューションの開発
- ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
- マイクロサービス、DevOps、最新のOSSやクラウドサービスを利用する開発プロジェクト
- 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長
少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。