Difyのワークフロー用node---Templateの使い方02, 03
はじめに
今回は、前回に引き続き、Difyのワークフローの構成要素であるnodeの一つ、Templateの使い方のその2です。
Difyの新バージョンv.0.6.12登場
と、その前に、、Difyが6月28日の日本時間で深夜にバージョンアップしました。さらに、改訂が加えられ、今(7/1/2024)の最新は、v0.6.12-fix1です。
早速、cluade3.5sonnetがLLMとして選択可能となっています。
また、LangSmith とLangfuseが使えるようになり、Difyの動作を動的にトレースできるようになったようです。
これらの改訂については、上記のGitHubに記載されてますが、次のnoteの記事に比較的わかりやすく説明があります。
ただ、これをバージョンアップするに際して、これまでのPythonの標準パッケージ管理ツールであるpipから、poetryに完全に移行しています。
それに伴い、色々と設定する事項があり、初心者の私には、そもそもPoetryのインストールから、始めなければいけませんし、ちょっと、これまでのv.upよりも敷居が高そうです。
このトライは、また別途ということで、、、
まずは、今回の本題に、戻ります。
Template(node)の使い方 その2
下記の2番目となります。
テンプレートの出力変数の値を後のnodeで引用する方法
前のnodeの複数の出力変数の値をマージ(結合)して、一つの出力変数にまとめる方法
2番目の方法は、DifyのHelpのTemplateの説明にも記載されています。
今回は、ここで紹介されている例をそのまま用います。
また、説明の後、その3として、もう一つ使い方を追加します。
例えば、v0.6.9から追加されている、Iterationでは変数の型として配列を使います。この配列形式を出力時に自然言語用の文字列に変換するという使い方です。
いわばコードの世界と、LLMの世界とを繋ぐ役割としてのTemplateの使い方です。
テンプレートの使い方(続き)
2.前のnodeの複数の出力変数の値を結合して、一つの出力変数にまとめる方法
前回の使い方では、templateの入力変数を使わず、下記のような設定でした。
また、このtemplateは、引用する方のnodeの前に配置します。
今回の使い方では、入力変数を使います。前に配置したnodeからの変数を受けて、その変数を処理して結果を出力変数に出すわけです。
最も単純な変数処理は、例えば結合です。
つまり、出力変数1と出力変数2とを結合して、その結果をnode(template)の出力変数とする。
適用事例
例えば、前々回で作成したAIアプリの " 黒魔女ベラドンナ様の人生相談 " の例を強引に適用すると、こんな使い方が想定されます。
同じ質問をLLM1-1 とLLM1-2とに与え、それぞれの結果を、まとめて回答させる。
フロー
例えば、このようなフローとなります。
適用事例のフロー内の各nodeについて
1から4までは、既に説明ずみです。
なお、1.開始のnode設定では、独自に設定したLLMを選定する変数LLM01がありました。以前の使い方では、これを必須としていましたが、それをやめれば、これを使うこともできます。
必須を設定しなければ、そのままパスすれば、次の質問の入力に進むことができます。
最も、今回の使い方では、LLM01を設定しなければいいだけ、とも言えますが、ま、あえてということで。
3、4は前回の設定を用いています。
Template(node)の設定
ここで、5.結合のtemplateの設定は、次のように設定します。
ここが、今回の使い方となります。
上の赤枠が、2つのLLMの出力変数です。
これをオレンジ色で囲んだように、コードに各変数を記載すると、出力変数のoutputに、この2つの変数の内容が連続して入力されます。
このtemplate nodeは、Difyのヘルプによると、Jinja2というPythonライブラリーの一つとのことです。色々な使い方がありそうですが、現時点では、理解できていないので今回はここまでです。
Template(node)の使い方 その3 コードの世界と自然言語との橋渡し
コードと言いますか、プログラミングの変数の型の一つに配列というのがあります。たとえば、変数名のAに(数値)を入れて、A(n)というような形式で、表現します。
この型を使うことで、同じ処理を繰り返す、反復処理の記述などが簡単になります。
iteration(イテレーション)
Difyでは、v.0.6.9からIterationというnodeが追加されています。これは、このコードの世界の配列に対し、なんらかの変換処理を行い、同じ要素数の配列に変換するという機能です。
従って、Difyのワークフローでは、開始nodeの後、自然言語の世界から、コードの世界に一旦入り、Iterationで反復処理を行った後、再び、自然言語の世界に変数の内容を変換する必要があります。
この前者では、code等のnodeを用い、後者では、templateを用いることで、2つの世界の変数のいわば型変換を行います。
iterationを用いる場合のフローの例
下図に、イテレーションを使う場合のフローの例を示します。
真ん中のオレンジで囲んだ大きな四角がイテレーションnodeです。その前に、code(node)が配置されており、ここで、コードの世界の配列作成の準備をします。
また、反復処理の後には、template(node)が配置され、ここで、コード用の配列(文字列;strings)を自然言語の世界に変換します。次の黄緑の枠のLLMでは、表示形式等を設定しています。例えば、箇条書きで記載するなどです。
templateの設定
この時のテンプレートの設定の例を示します。
上から順番に、まず、赤枠で、入力変数を定義します。ここでは、反復処理(iteration)の出力を受けています。
次に、コードで、変換を定義します。ただし、{{ 入力変数名 }}と記載するだけです。
これで、出力変数の ・テンプレート:output として自然言語の世界で使える型に変換されます。
まとめ
以上、前回、今回とテンプレートの使い方の例をメモしました。
いずれも、ヘルプにさらっと書いてはあるのですが、細かい記述がなく、最初は何を言ってるかよくわかりませんでした。
各々、単純な事柄ではあるのですが、ただ、これらが使えないと、Difyをつかいこなせないように思います。
初心者は、残念ながら、こんなところで、つまづきます。
また、そもそも、iterationがよく分からず、反復処理というのでループ処理でよく出る、for~とか、whileとか、mapなど、全然出てこないので、逆にとまどいましたが、これらの機能は次?に予定されているloop(node)で実現される機能のようです。
noteのこの記事に、端的な記載がありました。
ただし、この単純な機能でも、ヘルプにあるような下記の引用例などになると、かなり立派なツールと言えます。
なお、理解不足で、誤解を与える表現となっていましたら、ご容赦ください。
引用(Difyのヘルプより)
例 1: 長い記事の反復ジェネレータ(ロングストーリージェネレーター)
開始ノードにストーリーのタイトルとアウトラインを入力します。
コード ノードを使用して、ユーザー入力から完全なコンテンツを抽出します。
パラメータ抽出ノードを使用して、完全なコンテンツを配列形式に変換します。
反復ノードを使用してLLM ノードをラップし、複数の反復を通じて各章のコンテンツを生成します。
各反復後にストリーミング出力を実現するには、反復ノード内に直接応答ノードを追加します。