はじめに
こんにちは、SAIG/MLOpsチームでアルバイトをしている板野です。
AzureのPrompt Flowをローカル環境で動かし、作成したフローをコードで管理する方法をご紹介します。
Prompt Flowとは、Azure Machine Learning上の機能で、Azure OpenAIで提供されているLLMを利用したアプリケーション開発を円滑にするためのツールです。
実際にLLMアプリケーションを開発する場合、「プロンプトを入力して終わり」ではなく、ベクトル検索など複数の要素を組み合わせることもあります。このため、Prompt Flowでは処理のフローをDAG(有向非巡回グラフ)で可視化することで、開発効率が大きく向上します。
Prompt FlowはPythonライブラリ(2023/09/27時点ではMITライセンス)として提供されており、Azureのコンソール画面だけでなく、ローカル環境でも実行できます。
ローカルで実行できることには以下の利点があります。
- 特定のクラウドベンダーに依存しないので開発の選択肢が広がる
- フローをコードで管理できる
- よくアップデートされるGUIの変化に戸惑う必要がない
- コード編集の差分を記録できる
※本記事では、読者は「Azureのコンソール画面でのPrompt Flowの操作をしたことがある」という前提でご説明します。
事前準備
1. Pythonのインストール
Prompt Flowを動かすには、Python 3.9
あるいはPython 3.10
以上がインストールされている必要があります。
2. Prompt Flowライブラリのインストール
以下のコマンドでpromptflow
,promptflow-tools
のライブラリをインストールします
pip install promptflow promptflow-tools |
インストールが完了したら以下のコマンドでpromptflowのバージョンが出力されます
# (例) "0.1.0b5" |
3. VSCode拡張機能をインストール
Prompt FlowのVSCode拡張機能をインストールします。
VSCodeの拡張機能にて「Prompt Flow」で検索すると出てきます。

VSCode拡張機能が無くてもPrompt Flow自体は動かせますが、フローの可視化機能があるので、VSCodeが使用できる場合は入れておきましょう。
本記事ではVSCode拡張機能がインストールされている前提で説明していきます。
シンプルな標準フローを作成する
以下のコマンドで、最もシンプルな標準フローが作成できます。my-simple-flow
の部分はお好きなフロー名に変更してください。
pf flow init --flow my-simple-flow |
コマンドを実行したディレクトリの直下にmy-simple-flow
ディレクトリが自動生成されます。
中身は以下の通りです。

__pycache__
: Pythonを実行する際に生成されるキャッシュディレクトリ(削除しても特に問題はない).promptflow/flow.tools.json
: flow.dag.yamlから参照されるToolsのメタデータ(修正する必要はない)data.jsonl
: フローに入力するデータflow.dag.yaml
: 入出力・ノード・バリアント等を含むフローの全てを定義したファイル.py, .jinja2等のファイル
: フロー内のツールが参照するコードスクリプトrequirements.txt
: フローの実行に必要なPythonパッケージのリスト
flow.dag.yaml
ファイルの中身は以下の通りです。テキストベースなフロー定義データなので、直感では何をするフローか分かりにくいですね。
そこで赤枠のVisual editor
を押してみます。

すると、Azureコンソールでお馴染みのGUIベースの編集画面が出てきます。
「入力されたテキストをシステムプロンプトに含めて出力する」という、LLMを使わない簡単なフローのようです。

このVisual editorで編集した内容は、flow.dag.yaml
のテキストデータに反映されるので、GUIベース及びテキストベースのどちらからでも編集可能です。
一度、フローを動かしてみます。
上図赤枠の部分に好きなテキスト(ここではHello World!
)を入力し、my-simple-flow
の親ディレクトリから以下のコマンドを打ちます。
pf flow test --flow my-simple-flow |
すると、以下のようなコンソール出力が返ってきます。

「入力されたテキストをシステムプロンプトに含めて出力する」というシンプルな標準フローが実行できました。
LLM付きの標準フローを作成する
ここでは、入力された質問に対する応答をしてもらうフローを作っていきます。
前章で作成したフローの中にLLM(Prompt FlowではLLMツール/LLMノードと呼ぶ)を追加し、少し複雑になったフローです。
1. Connectionの設定
まずはConnection(接続)の設定を行います。
任意のディレクトリ上で、接続先を定義するYAMLファイルを作成します(ここではconnection-azure-openai.yaml
という名前で作成)
YAMLファイルの中身は公式Docsを参考に以下のように作ります。
$schema: https://azuremlschemas.azureedge.net/promptflow/latest/AzureOpenAIConnection.schema.json |
YAMLファイルが作成できたら、以下のコマンドでconnectionを追加します。
pf connection create -f <YAMLファイルのパス> |
以下のように詳細が表示されればConnection(接続)の設定は完了です。

2. LLMツールの追加
続いて、LLMツールを追加していきます。flow.dag.yaml
のVisual editorの画面から「+LLM」を押します。

上部に、LLMツールの名前入力が求められるので好きな名前を設定します(ここではllm_node
と設定)

名前入力が完了すると、「new file」を選択します(<LLMツール名>.jinja2
というファイルが新規生成されます)

LLMツールが追加されました。connectionには先程設定した接続先が選択できるようになっています。

3. フローの編集
入力された質問に対する応答をしてもらうフローを作っていきます。
Azureコンソールでは、1つの画面で全てのソースコードやプロンプトを直接編集できますが、ここではソースファイル毎に編集する必要があります。
フローの概略は以下の通りです。
Inputs
でユーザーからの質問を受け取り、system_prompt
でシステムプロンプトにユーザーの質問を埋め込み、llm_node
でLLMにプロンプトを投げ、echo_llm_output
でLLMからの回答を加工してoutput
に出力します。

flow.dag.yaml
environment: |
各ノードの詳細は以下の通りです。
Inputs&Outputs

system_prompt

system_prompt.jinja2
system: |
llm_node

llm_node.jinja2
{{input_prompt}} |
echo_llm_output

echo_llm_output.py
from promptflow import tool |
4. フローの実行
フローの編集が終わったら、先程と同様に以下のコマンドで実行します。
pf flow test --flow my-simple-flow |
Outputsの欄に出力が表示されます。

5. フローの一括実行
複数の入力を一括で実行することもできます。
まずはflow.dag.yaml
ファイルを編集し、default: 東京はどこの国の都市?
の行をコメントアウトします。
flow.dag.yaml(コメントアウト後)
environment: |
次に、フローのディレクトリ内にあったdata.jsonl
を編集し、以下のような内容を記載します。
{"question": "オーストラリアの首都は?"} |
1行が1つの入力に相当します。質問文を変えたり行を追加したりしても大丈夫です。
最後に、フローの親ディレクトリから以下のコマンドを実行します(my_run_001
の部分は任意)
pf run create --flow my-simple-flow --data ./my-simple-flow/data.jsonl --name my_run_001 |
以下のような出力が返ってくれば一括実行は成功です。

複数実行の結果はログとして記録されており、以下のコマンドでいつでも可視化できます。
pf run show-details --name my_run_001 |

作成したフローをコードで管理する
今回作成したファイル群は以下の通りです。

これらはgitで管理できます。
予め.gitignore
ファイルが含まれているため、余計なキャッシュ等を含まずプッシュできますが、connection情報が入ったYAMLファイルは後で作成したファイルなので、プッシュしてしまう恐れがあります。
該当ファイルを.gitignore
に追記するなどして、十分注意してください。
まとめ
本記事ではAzureのPrompt Flowをローカル環境で動かし、作成したフローをコードで管理する方法をご紹介しました。
LLMの開発や運用(LLMOps)に携わっている方々や、Prompt Flowを試している方々の参考となれば幸いです。