Taste of Tech Topics

Acroquest Technology株式会社のエンジニアが書く技術ブログ

Dify v1.0.0 で新登場したエージェントノードで Function Calling を実行

1. はじめに

こんにちは、りょうたです。

先週、ついに待望のDify v1.0.0が正式リリースされて、生成AIを利用したサービスや基盤開発に関わる身として大変ワクワクしております!

github.com

本バージョン注目の機能として、エージェントノード と プラグインシステム が導入されています。

エージェントノードとは、予め定義されている「エージェント戦略」を用いて、質問に応じたツールの呼び出しや複数ステップにわたる推論を自動的に実行する、新しいノードです。

今回は、Dify公式が出しているエージェンティック戦略を用いて、チャットフローを作成してみます。

2. エージェントノードとは

2.1. 基本的な機能

エージェントノードとは、事前に定義されている複数ステップにわたる推論と、ツール実行を行うノードです​。

チャットフローにこのノードを組み込むことで、ユーザーの質問に応じて、動的にツールを選択・呼び出し、推論を行い、複雑なタスクを実行することが可能になります。

Dify公式が用意している「Dify Agent Strategies」というプラグインには、2つのエージェンティック戦略が用意されています。

戦略 概要
Function Calling ユーザーからの質問に応じて、あらかじめ定義した外部関数の中から、どのツールを呼び出すかをAIが判断し、使用する関数名と引数を返してくれる仕組みのこと。別名 Tool Use とも呼ばれている。
ReAct AIが推論(Reasoning)と行動(Action)を交互に実行する手法のこと。思考結果とツール呼び出しの結果を反映して回答を更新していくことで、複雑な問題の解決やタスク自動化を実現する仕組み。

今回は、Function Callingを用いて、ツールの呼び出しを行います。

今回用いるFunction Callingについて、詳細はこちらをご参照ください。

acro-engineer.hatenablog.com

2.2. 従来のワークフローで実現しようとした際との違い

以前は実現したいチャットフローの構成ごとに、全体の設計を行い、ツール選択の実現方法などを検討する必要がありました。

例えば、Function Callingをチャットフローで実現しようとした際は

  1. どうやって適切なツールを選択させるか
  2. どういった条件で、使用するツールを分岐させるか
  3. 分岐した先の処理を考慮して、呼び出し元でどのような情報を渡しておかなければいけないか

などを検討する必要があり、設計や開発、改修などにコストがかかる状態でした。

エージェントノードを用いることで、これらのコストを削減することが出来そうです。

従来のチャットフローでのFunction Calling実現例

2.3. Difyアプリの「エージェント」との違い

従来のエージェントは単一のアプリとして動作し、事前に定義された特定のタスクを単体で実行するアプリでした。

簡潔に言うと、単純なチャットボットに近いものです。

一方で、エージェントノードは、ワークフローの一部として統合され、他の様々なツールと連携して、複雑な処理を実現することが出来ます。

エージェントアプリ

3. エージェントノードを使ってみた

3.1. フローの概要

今回は、食事に関する相談を受け付けるチャットフローを作成していきます。

こちらに今回作成するフローを示します。

今回作成したチャットフロー

主となるチャットフローを作成し、こちらのエージェントノードのFunction Calling戦略を用いて、ツールの振り分け処理を定義します。

質問に応じて、このエージェントノードから、ツールの呼び出しを行う構成です。

今回は、以下の3つのツールを用意しています。

  1. メニュー考案
  2. 栄養士
  3. 一般質問

3.2. Function Callingを用いたフローの構築

ツールの準備

エージェントノードの前に、呼び出し先のツールについて定義しておきます。

エージェントノードから呼び出し可能なツールは、以下の3つです。

  1. プラグイン
  2. カスタムツール
  3. ワークフロー

今回はワークフローを用います。

スタジオの新規作成からワークフローを選択し、以下のようなフローを構築します。

質問文を受け取り、LLMに問い合わせを行うシンプルな構成です。

メニュー考案ワークフロー

メニュー考案のLLMのシステムプロンプトは次のように定義しました。

あなたは、料理の献立を考案し提案する専門のチャットボットです。ユーザーからの質問や希望を受け取り、その内容に応じた最適な料理の献立を提供してください。
ただし、提案する献立は1食分のみです。

役割と目的:
ユーザーの質問や条件に沿った料理の献立を、具体的な料理名、調理方法を提案する。
栄養バランスや調理の手間、季節感、テーマ(和食、洋食、中華など)にも配慮し、利用者のニーズに合わせた献立を考案する。

ユーザーの具体的な条件(食材の制限、アレルギー、予算、調理時間など)が提示された場合は、それらに適合する献立を提案する。

最後に、終了ノードの出力変数に、LLMの回答を設定すれば、ワークフローの構築は完了です。

ツールとして用いるために、公開ボタンを押して、ワークフローを公開状態にします。

ワークフロー公開

作成したワークフローを、エージェントノードで用いるツールとして用いるため、名前などの設定を行います。

「ツール入力」のqueryは、ワークフローの開始ノードで設定している入力フィールドになります。

こちらで設定できるメソッドの項目については、LLMが自動で入力してくれる「LLM入力」と、予め入力する値を自分で定義しておく必要がある「設定」の2つが設定可能です。

今回は、ユーザーからの質問文を受け取るqueryという項目について、Function Callingからの結果を受け取るために、メソッドはLLM入力を設定します。

ツールとしてのワークフロー設定

同様に、「栄養士」「一般質問」についても、以下のシステムプロンプトでワークフローを作成します。

■栄養士

あなたはプロの栄養士として、利用者から送られてくる献立や食事に関する質問に対して、健康や栄養バランスの視点からコメントし、適切なアドバイスを提供する役割を担います。以下の指針に従って回答してください。

# 専門的な視点でアドバイス
献立に含まれる栄養素や食材の特徴、調理方法に基づいた具体的なコメントを行う。
利用者の質問内容や状況に応じたアドバイスを心がけること。
​
# 指針
食材や調理法、栄養バランスについて利用者が理解しやすい言葉で表現する。
献立の改善点や、補完すべき栄養素があれば具体的な提案を行う。
健康維持やダイエット、エネルギー補給など、利用者の目的に沿ったアドバイスを行う。

■一般質問

あなたは優秀なチャットボットとして、ユーザからの様々な質問に回答してください

エージェントノードを設定

チャットフローを選択してアプリを新規作成し、こちらのようにエージェントノードを設定します。

エージェントノード

エージェンティック戦略はFunction Callingを選択します。

モデルはAWS (Bedrock) の「Claude 3 Haiku」を用います。 Function Callingに公式に対応している、OpenAI以外のモデルであっても実行することが可能です。

Tools Listには、先ほど定義した3つのワークフローを定義します。

最後にシステムプロンプトと、ユーザプロンプトを設定します。

システムプロンプト

あなたは、食事に関する質問を受け付けるエージェントシステムのスーパーバイザーエージェントです。
以下のルールと方針に従い、適切なツールの選択を行ってください。

# システム全体の概要
- ユーザーからの食事関連の質問に対して、以下の3種類の専門エージェントを活用する。 
1. **献立考案**:新たなメニューのアイデアや料理の提案を行う。 
2. **栄養士**:栄養バランス、健康面、食材の組み合わせ等の観点からアドバイスを提供する。 
3. **その他の一般質問エージェント**:料理以外の雑多な質問や、料理の豆知識や調理法、食材の選び方など、専門分野に分類されない質問に対応する。

# 注意点
選択できるツールは1つのみです。
呼び出したツールからの応答を基に、情報を全て使って回答を行ってください。
必要に応じて箇条書きにするなど、読みやすく出力してください

# 最終目標
あなたの役割は、ユーザーからの食事に関する質問に対し、各エージェントがその専門分野で最適な回答を提供できる環境を維持し、システム全体として一貫性のある、質の高い情報提供を実現することです。

4. Function Callingを実行してみる

実行結果

フロー全体が完成したので、プレビューで実際に実行してみます。

まずは、メニュー考案に関する質問を行ってみます。

■質問1

肉料理の献立を考えて

結果は以下のようになりました。

ログも確認すると、tool_nameのところに、ツールとしてのワークフロー設定で設定したthink_nameというツールが呼ばれています。

メニュー考案のワークフローを呼んでくれているようです。

さらに、queryの部分を見ると、「肉料理の献立」というテキストが入力されています。

質問文から、ツールに渡す適切なテキストを抽出して、ツールに渡してくれているようです。

メニュー考案

料理以外のことについても質問してみました。

■質問2

富士山の標高を教えて

こちらも、一般質問を呼び出してくれているようです。

一般質問

対応するツールが存在しない場合はどうなる?

質問に対応する適切なツールが存在しない場合は、どのように動作するのでしょうか。

エージェントノードの「一般質問」を無効化した上で、もう一度富士山の標高に関する質問を行いました。

まず、エージェントノードの設定画面で、「一般質問」を無効化します。

一般質問無効化

この状態で、以下の質問を行います。

■質問

富士山の標高を教えて

結果は、全く関係ないはずの「メニュー考案」を選択しました。

どのような質問が来ても、いずれかのツールが選択されるのかもしれません。

このことを考慮して、用意するツールを検討する必要がありそうです。

対応するツールが存在しない場合の検証

5. まとめ

今回は、エージェントノードを使って、Function Callingを使ってみました。

エージェンティック戦略が増えれば、Difyの活用方法が一気に広がりそうですね!

引き続き、Difyのアップデートを追っていこうと思います。

Acroquest Technologyでは、キャリア採用を行っています。
  • Azure OpenAI/Amazon Bedrock等を使った生成AIソリューションの開発
  • ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
  • マイクロサービス、DevOps、最新のOSSクラウドサービスを利用する開発プロジェクト
  • 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長
少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。 www.wantedly.com