
Prompt Flowが使えるようになったから、もうLangChainとか自分でホストしなくていい世界になったのかもしれない。
この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
Buildで発表され、注目されていた Model Catalogと Prompt Flowが2023年7月6日(JST)から使えるようになっていました。
※ まだ、Previewなので、今後仕様などが変更する可能性があります。
この記事ではPrompt Flowの紹介です。
Model Catalogはこちら Azure Machine LearningでModel Catalogが使えるようになりました。
どちらの機能も、Azure Machine Learning Studioから使うことができます。
Prompt Flowとは
Prompt flow is a powerful feature within Azure Machine Learning (AzureML) that streamlines the development, evaluation, and continuous integration and deployment (CI/CD) of prompt engineering projects. It empowers data scientists and LLM application developers with an interactive experience that combines natural language prompts, templating language, a list of built-in tools and Python code.
プロンプト フローは、Azure Machine Learning (AzureML) 内の強力な機能であり、プロンプト エンジニアリング プロジェクトの開発、評価、継続的インテグレーションとデプロイ (CI/CD) を合理化します。データサイエンティストとLLMアプリケーション開発者は、自然言語プロンプト、テンプレート言語、組み込みツールのリスト、およびPythonコードを組み合わせたインタラクティブなエクスペリエンスを利用できます。
簡単に言うと、 いろいろなモデルや、APIを組み合わせたりして、AI Chat botをリッチにできますよ。 ということです。
Flowを作る
Prompt FlowはFlowという単位で管理されます。

どんなTypeのFlowを作るかをまず選択していきます。
- Standard flow
 - 大規模言語モデル、カスタマイズされたPythonコード、Serp APIなどのパワーを活用して、カスタマイズされたプロンプトフローを作成できます。カスタムデータセットを使用してフローをテストし、簡単に統合できるエンドポイントとしてシームレスにデプロイします。
 - Chat flow
 - 標準のフローに加えて、このオプションはチャット履歴のサポートとオーサリング/デバッグUIのユーザーフレンドリーなチャットインターフェイスを提供します。
 - Evaluation flow
 - アウトプットが期待される基準やゴールにどれだけマッチするかを測定するための評価フローを作成します。
 
違いを見るために、全部作ってみました。

Typeごとの違い:Standard flow
まずはStandard flowから見ていきます。
画面右側には、フローが絵として表示されています。
左側には、フローの中の各モジュールの詳細が表示されるようなUIになっているようです。
今までのAzureの感じだと、左に絵があって、右に詳細を出すような形だったような気がしますが、今回は逆ですね。
Visual Studio Codeの右側にプレビューがあるような感覚で、使いやすいなぁと個人的には思いました。
Standard flowの中には、4つ(2つ?)のモジュールが見えます。
まずはinputsとoutputs
これは、入出力を定義しているように見えます。
追加もできるようになっており、入出力はJson形式でこのように出し入れするようになります。
{
    "Name": "{Value}"
    ...
    "NameN": "{ValueN}"
}
の形で、入力と出力が行われるものと思われます。
Runtimeを作る
実際に動かしてみるためにはRuntimeを作る必要があります。
Runtimeがすでに作られている場合には、選ぶだけで良さそうですが、今回は初めて動かすので新しく作ります。
画面遷移せずにここで作れるのはありがたいですね。
RuntimeにはCompute instance runtimeとManaged online deployment runtimeの2種類がありますが、
Compute instance runtimeの方はAzure Machine LearningのCompute として管理されるものになり、本番で利用する時はこちらを選ぶのが良さそうです。
名前をつけて、Virtual Machine のサイズなどを決めたら、作成できます。

runtimeの作成には、7分くらいの時間がかかりました。気長に待ちましょう。
runtimeの作成が終わると、Runtime:で選ぶことができるようになり、Runボタンを押せば実行されるはずです。
ここにつまづきポイントがあるので、後述の[つまづきポイント]も参照してください。

実行結果
実行は、4つのモジュールごとに、トレースされます。

inputsはtextという名前で、「Hello World!」が入ってきています。

次に二つ目のhello_promptを見ていきます。

詳細の下部にOutputsという欄があり、出力を見てみると、
[
  0:{
    "system_metrics":{
      "duration":0.004247
    }
    "output":"Write a simple Hello World! program that displays the greeting message when executed."
  }
]
このようなOutputがされていることがわかります。 これはPromptの内容
{# Please replace the template with your own prompt. #}
Write a simple {{text}} program that displays the greeting message when executed.
の{{text}}の部分が、
このモジュールへのインプットで置き換えられていることがわかります。
インプットは、textという名前で、${inputs.text}を参照しています。

次に、3つ目のecho_my_promptです。 ここでは、Pythonのコードが実行されるようになっています。
from promptflow import tool
# The inputs section will change based on the arguments of the tool function, after you save the code
# Adding type to arguments and return value will help the system show the types properly
# Please update the function name/signature per need
@tool
def my_python_tool(input1: str) -> str:
    return "Prompt: " + input1
このモジュールへの入力は input1という名前で、hello_promptのoutputを参照していますので、
hello_promptのoutput :「Write a simple {{text}} program that displays the greeting message when executed.」に「Prompt: 」を頭につけて返しているというのがわかります。

このフローの実行結果から、Prompt Flowは複数の処理をデータを受け渡しながら実行していくことがわかりました。
つまづきポイント
Runを押したところ、UserAuthenticationErrorが発生しました。
![]()
Azure Machine Learning Workspaceのアクセス制御で、今回のエンドポイントのマネージドIDに対してAzure ML Data Sceientistのロールを割り当てる必要がありました。 ということで、Azure Portal(Machine Learning Studioではない)からロールの割り当ての追加をしていきます。

Runtimeは機械学習エンドポイントリソースとしてAzure Portalでは見えます。 マネージドIDがついているので、このIDに対してロールを割り当てます。
他にも、Storage Accountにもロールを割り当てる必要があります。 自動で、ストレージBLOBデータ閲覧者がつきますが、
'Storage Table Data Contributor' and 'Storage Blob Data Contributor'
も欲しいそうです。欲張りさん。

あとは、ロールの追加の反映を待って問題は解決します。 このあたりのロール設定も自動でやってくれるようになると良いですね。今後に期待です。
Typeごとの違い:Chat flow
次に、Chat flowを見ていきます。
右側のフローチャートを見てみると、すごくシンプルです。
しかし、inputsが先ほど違うことに気づきます。
chat_historyというのが、List形式で入ってきています。

次のchatモジュールを見ていきます。
Connectionという項目があります。
そこには、Default_AzureOpenAI 、 APIには、chat, completion, embeddingと用意されています。(最近出た、拡張Chat Completionがないですが、これはそのうち出てくると思うので、待ちませう。)

ここで、ん? Default_AzureOpenAI? と不思議に思ったので、Azure PortalでAzure OpenAIを見てみると、新しく、Azure OpenAIのリソースが作成されていました。

おそらく、このモジュールで使うために、モデルをデプロイしなくてはいけないと思うので、gpt-35-turbo (0613)をデプロイしておきます。

モデルをデプロイしたら、deployment_nameが選択できるようになったので、モデルのデプロイは大事な作業でした。
次に、Promptを見てみると、気になる一文があります。
{% for item in chat_history %}
過去のChat でのやり取りがPromptに追加されるようになっています。
このやり取りを自分で実装すると、APIをただコールするだけのところから急激に実装の手間が増えますが、Prompt flowだと、特に意識することなく会話の内容を記憶してくれるようです。(Prompt のToken上限の話は置いておいて)

それでは、確認したところで、実行してみます。
Standard flowでは、Runだった実行ボタンが、Chatボタンに変わっています。
Chatボタンを押してみると、チャットウィンドウが開き、チャットできるようになっています。
ちゃんと、お返事も帰ってきています。

何ターンか会話してみます。
その後、inputsのchat_historyがどうなっているのかみてみます。
!!!!

inputsには、きちんと、やり取りが保存されているのが確認できます。 これは実装が楽になりますね。
実態は、Table StorageのFlow Recordsというテーブルに保存されていそうです。

このテンプレから作ったフローはシンプルなものでしたが、LLM以外にも、Serp APIであったり、Vector DBからの検索であったりと、さまざまなAPIを組み合わせて一つのフローが実装できます。
Bing Chatのように、会話に応じて検索し、その結果を要約し返答すると言ったようなChatBotが簡単に作れそうです。

Typeごとの違い:Evaluation flow
ここまでで、だいぶ記事が長くなってしまったので、Evaluation flowはまた別の記事にする予定です。
アプリに組み込むには?
ここまでで、フローを作るのが非常に簡単にできると言うことがわかりました。 しかし、画面上で動かせるだけでは検証には良いかもしれませんが、アプリケーションとして使う場合には物足りません。
このフローをAPIで呼び出せるようになるとすごく嬉しいです。 ということで、Deployをして、エンドポイントを作っていきます。

Deployはウィザードに従って作っていきますが、ウィザードの中で気になったところをいくつか。 まずは、responseに含めるOutputを選べるというところです。 検証段階では必要だけれど、本番では必要のない、Outputはウィザードの中で省くことができます。

LLMのモデルを検証用と、本番用で切り替えることもできます。

無事にEndpointが作成されたら、早速cURLで呼び出してみます。 CunsumptionタブからKeyを取得して、cURLで呼び出してみます。
% curl -XPOST \
     -H 'Content-Type: application/json' \
     -H 'Authorization: Bearer XXXXXXXXXXXXXXXXXXXXXXXXXXXX' \
     -d '{ "inputs":{ "question": ["こんにちは"]}}' \
     "https://promptflow-mglmc.eastus.inference.ml.azure.com/score"
{
  "answer": "こんにちは!お手伝いできることはありますか?"
}
無事に会話が返ってくることが確認できました。
さいごに
今までだとLang chain やSemantic Kernelなどで実装していたようなことが、 Prompt flowを使うことで、コーディングを一切せずに作ることができたのはとても大きい進化だと思います。
複雑な処理を挟む(社内DocumentをCognitive Searchから読み込むなど)こともできそうなので、 今後企業内でChatbotを導入していきましょうという時には非常に強力なツールとなりそうです。







