チュートリアル: パート 3 - プロンプト フロー SDK を使用したカスタム チャット アプリケーションを評価してデプロイする
このチュートリアルでは、プロンプト フロー SDK (およびその他のライブラリ) を使用して、チュートリアル シリーズのパート 2 で構築したチャット アプリを評価してデプロイします。 このパート 3 では、次の方法について説明します。
- チャット アプリの応答の品質を評価する
- チャット アプリを Azure にデプロイする
- デプロイを検証する
このチュートリアルは、3 部構成のチュートリアルのパート 3 です。
前提条件
チャット アプリケーションを構築するには、チュートリアル シリーズのパート 2 を完了します。
Azure サブスクリプションでロールの割り当てを追加するために必要なアクセス許可も必要です。 ロールの割り当てによるアクセス許可の付与は、特定の Azure リソースの所有者によってのみ許可されます。 チュートリアルの後半で、エンドポイント アクセスについて、Azure サブスクリプション所有者 (IT 管理者の場合もあります) に問い合わせる必要がある場合があります。
チャット アプリの応答の品質を評価する
チャット履歴など、チャット アプリがクエリに適切に応答することがわかったので、いくつかの異なるメトリックとより多くのデータでコパイロットのパフォーマンスを評価しましょう。
評価データセットと get_chat_response()
の対象の関数でプロンプト フロー エバリュエータを使用し、評価結果を評価します。
評価を実行したら、システム プロンプトの改善などによってロジックを向上させ、チャット アプリの応答がどのように変化し、改善されるかを観察できます。
評価モデルを設定する
使用する評価モデルを選択します。 アプリの構築に使用したチャット モデルと同じにすることができます。 評価のために別のモデルが必要な場合は、それをデプロイするか、既に存在する場合はそれを指定する必要があります。 たとえば、チャットの完了には gpt-35-turbo
を使用していますが、評価には gpt-4
を使用したいと考えています。
.env ファイルに評価モデル名を追加します。
AZURE_OPENAI_EVALUATION_DEPLOYMENT=<your evaluation model deployment name>
評価データセットを作成する
次の評価データセットを使用します。このデータセットには、質問の例と想定される回答 (真理) が含まれています。
rag-tutorial フォルダーに eval_dataset.jsonl というファイルを作成します。 アプリケーション コード構造を参照してください。
このデータセットをファイルに貼り付けます。
{"chat_input": "Which tent is the most waterproof?", "truth": "The Alpine Explorer Tent has the highest rainfly waterproof rating at 3000m"} {"chat_input": "Which camping table holds the most weight?", "truth": "The Adventure Dining Table has a higher weight capacity than all of the other camping tables mentioned"} {"chat_input": "How much do the TrailWalker Hiking Shoes cost? ", "truth": "The Trailewalker Hiking Shoes are priced at $110"} {"chat_input": "What is the proper care for trailwalker hiking shoes? ", "truth": "After each use, remove any dirt or debris by brushing or wiping the shoes with a damp cloth."} {"chat_input": "What brand is for TrailMaster tent? ", "truth": "OutdoorLiving"} {"chat_input": "How do I carry the TrailMaster tent around? ", "truth": " Carry bag included for convenient storage and transportation"} {"chat_input": "What is the floor area for Floor Area? ", "truth": "80 square feet"} {"chat_input": "What is the material for TrailBlaze Hiking Pants?", "truth": "Made of high-quality nylon fabric"} {"chat_input": "What color does TrailBlaze Hiking Pants come in?", "truth": "Khaki"} {"chat_input": "Can the warrenty for TrailBlaze pants be transfered? ", "truth": "The warranty is non-transferable and applies only to the original purchaser of the TrailBlaze Hiking Pants. It is valid only when the product is purchased from an authorized retailer."} {"chat_input": "How long are the TrailBlaze pants under warrenty for? ", "truth": " The TrailBlaze Hiking Pants are backed by a 1-year limited warranty from the date of purchase."} {"chat_input": "What is the material for PowerBurner Camping Stove? ", "truth": "Stainless Steel"} {"chat_input": "Is France in Europe?", "truth": "Sorry, I can only queries related to outdoor/camping gear and equipment"}
プロンプト フロー エバリュエータを使用して評価する
次に、次のような評価スクリプトを定義します。
- プロンプト フロー
evals
パッケージからevaluate
関数とエバリュエータをインポートします。 - サンプル
.jsonl
データセットを読み込みます。 - チャット アプリ ロジックの対象の関数ラッパーを生成します。
- 対象の関数を受け取り、評価データセットとチャット アプリからの応答をマージして、評価を実行します。
- GPT 支援メトリック (関連性、根拠性、一貫性) を生成し、チャット アプリの回答の質を評価します。
- 結果をローカルに出力し、クラウド プロジェクトにログを記録します。
このスクリプトでは、結果をコマンド ラインや JSON ファイルに出力することで、ローカルで結果を確認できます。
また、スクリプトは評価結果をクラウド プロジェクトにログ記録するため、UI で評価の実行を比較できます。
rag-tutorial フォルダーに evaluate.py というファイルを作成します。
次のコードを追加します。
dataset_path
とevaluation_name
をユース ケースに合うように更新します。import json import os # set environment variables before importing any other code from dotenv import load_dotenv load_dotenv() import pandas as pd from promptflow.core import AzureOpenAIModelConfiguration from promptflow.evals.evaluate import evaluate from promptflow.evals.evaluators import ( RelevanceEvaluator, GroundednessEvaluator, CoherenceEvaluator, ) # Helper methods def load_jsonl(path): with open(path, "r") as f: return [json.loads(line) for line in f.readlines()] def copilot_wrapper(*, chat_input, **kwargs): from copilot_flow.copilot import get_chat_response result = get_chat_response(chat_input) parsedResult = {"answer": str(result["reply"]), "context": str(result["context"])} return parsedResult def run_evaluation(eval_name, dataset_path): model_config = AzureOpenAIModelConfiguration( azure_deployment=os.getenv("AZURE_OPENAI_EVALUATION_DEPLOYMENT"), api_version=os.getenv("AZURE_OPENAI_API_VERSION"), azure_endpoint=os.getenv("AZURE_OPENAI_ENDPOINT"), ) # Initializing Evaluators relevance_eval = RelevanceEvaluator(model_config) groundedness_eval = GroundednessEvaluator(model_config) coherence_eval = CoherenceEvaluator(model_config) output_path = "./eval_results.jsonl" result = evaluate( target=copilot_wrapper, evaluation_name=eval_name, data=dataset_path, evaluators={ "relevance": relevance_eval, "groundedness": groundedness_eval, "coherence": coherence_eval, }, evaluator_config={ "relevance": {"question": "${data.chat_input}"}, "coherence": {"question": "${data.chat_input}"}, }, # to log evaluation to the cloud AI Studio project azure_ai_project={ "subscription_id": os.getenv("AZURE_SUBSCRIPTION_ID"), "resource_group_name": os.getenv("AZURE_RESOURCE_GROUP"), "project_name": os.getenv("AZUREAI_PROJECT_NAME"), }, ) tabular_result = pd.DataFrame(result.get("rows")) tabular_result.to_json(output_path, orient="records", lines=True) return result, tabular_result if __name__ == "__main__": eval_name = "tutorial-eval" dataset_path = "./eval_dataset.jsonl" result, tabular_result = run_evaluation( eval_name=eval_name, dataset_path=dataset_path ) from pprint import pprint pprint("-----Summarized Metrics-----") pprint(result["metrics"]) pprint("-----Tabular Result-----") pprint(tabular_result) pprint(f"View evaluation results in AI Studio: {result['studio_url']}")
最後の main 機能では、評価結果をローカルで表示したり、AI Studio の評価結果へのリンクを表示したりすることができます。
評価スクリプトを実行する
コンソールから、Azure CLI を使用して Azure アカウントにサインインします。
az login
必要なパッケージをインストールします。
pip install promptflow-evals pip install promptflow-azure
次に、評価スクリプトを実行します。
python evaluate.py
評価用のプロンプト フロー SDK の使用に関する詳細については、「プロンプト フロー SDK を使用して評価する」を参照してください。
評価結果の解釈
コンソールの出力では、各質問に対する答えと、要約されたメトリックがこのすばらしい表形式で表示されます。 (出力には異なる列が表示される場合があります。)
'-----Summarized Metrics-----'
{'coherence.gpt_coherence': 4.3076923076923075,
'groundedness.gpt_groundedness': 4.384615384615385,
'relevance.gpt_relevance': 4.384615384615385}
'-----Tabular Result-----'
question ... gpt_coherence
0 Which tent is the most waterproof? ... 5
1 Which camping table holds the most weight? ... 5
2 How much does TrailWalker Hiking Shoes cost? ... 5
3 What is the proper care for trailwalker hiking... ... 5
4 What brand is the TrailMaster tent? ... 1
5 How do I carry the TrailMaster tent around? ... 5
6 What is the floor area for Floor Area? ... 3
7 What is the material for TrailBlaze Hiking Pants ... 5
8 What color do the TrailBlaze Hiking Pants come ... 5
9 Can the warranty for TrailBlaze pants be trans... ... 3
10 How long are the TrailBlaze pants under warren... ... 5
11 What is the material for PowerBurner Camping S... ... 5
12 Is France in Europe? ... 1
スクリプトは ./eval_results.jsonl
に評価結果をすべて書き込みます。
コンソールには、Azure AI Studio プロジェクトで評価結果を表示するためのリンクがあります。
Note
ERROR:asyncio:Unclosed client session
が表示される場合があります。これは無視しても問題なく、評価結果には影響しません。
AI Studio で評価結果を表示する
評価の実行が完了したら、リンクに従って Azure AI Studio の [評価] ページで評価結果を表示します。
また、個別の行を見て、行ごとのメトリック スコアを見たり、検索されたすべてのコンテキストやドキュメントを表示したりすることもできます。 これらのメトリックは、評価結果の解釈やデバッグに役立ちます。
AI Studio での評価結果の詳細については、「AI Studio で評価結果を表示する方法」を参照してください。
チャット アプリが期待どおりに動作することを確認できたので、アプリケーションをデプロイする準備ができました。
チャット アプリを Azure にデプロイする
次に、このチャット アプリをマネージド エンドポイントに展開して、外部アプリケーションまたは Web サイトで使用できるようにしましょう。
デプロイ スクリプトは次のようになります。
- マネージド オンライン エンドポイントを作成する
- フローをモデルとして定義する
- 環境変数を含むそのエンドポイント上のマネージド環境にフローをデプロイします。
- すべてのトラフィックをそのデプロイにルーティングする
- Azure AI Studio でデプロイを表示およびテストするためのリンクを出力する
デプロイは、フロー フォルダーで指定した requirement.txt
に依存するビルド コンテキスト (Dockerfile) を定義し、環境変数もデプロイされた環境に設定します。それにより、ローカルと同様に運用環境でも自信を持ってチャット アプリを実行できます。
デプロイ用のビルド コンテキスト (Dockerfile)
デプロイ環境にはビルド コンテキストが必要なので、デプロイ環境用の Dockerfile を定義しましょう。 デプロイ スクリプトは、この Docker ファイルに基づいて環境を作成します。 この Dockerfile を copilot_flow フォルダーに作成します。
FROM mcr.microsoft.com/azureml/promptflow/promptflow-runtime:latest
COPY ./requirements.txt .
RUN pip install -r requirements.txt
チャット アプリをマネージド エンドポイントにデプロイする
Azure のマネージド エンドポイントにアプリケーションをデプロイするには、オンライン エンドポイントを作成し、そのエンドポイントにデプロイを作成し、すべてのトラフィックをそのデプロイにルーティングします。
デプロイ作成の一環として、copilot_flow フォルダーがモデルとしてパッケージ化され、クラウド環境がビルドされます。 エンドポイントは Microsoft Entra ID 認証で設定されています。 コード内で、または Azure AI Studio のエンドポイントの詳細ページで、必要な認証モードを更新できます。
重要
Azure のマネージド エンドポイントにアプリケーションをデプロイすると、選択したインスタンスの種類に基づいて、関連するコンピューティング コストが発生します。 関連コストを認識し、指定したインスタンスの種類のクォータがあることを確認してください。 オンライン エンドポイントの詳細について説明します。
rag-tutorial フォルダーに deploy.py ファイルを作成します。 次のコードを追加します。
import os
from dotenv import load_dotenv
load_dotenv()
from azure.ai.ml import MLClient
from azure.identity import DefaultAzureCredential
from azure.ai.ml.entities import (
ManagedOnlineEndpoint,
ManagedOnlineDeployment,
Model,
Environment,
BuildContext,
)
client = MLClient(
DefaultAzureCredential(),
os.getenv("AZURE_SUBSCRIPTION_ID"),
os.getenv("AZURE_RESOURCE_GROUP"),
os.getenv("AZUREAI_PROJECT_NAME"),
)
endpoint_name = "tutorial-endpoint"
deployment_name = "tutorial-deployment"
endpoint = ManagedOnlineEndpoint(
name=endpoint_name,
properties={
"enforce_access_to_default_secret_stores": "enabled" # for secret injection support
},
auth_mode="aad_token", # using aad auth instead of key-based auth
)
# Get the directory of the current script
script_dir = os.path.dirname(os.path.abspath(__file__))
# Define the path to the directory, appending the script directory to the relative path
copilot_path = os.path.join(script_dir, "copilot_flow")
deployment = ManagedOnlineDeployment(
name=deployment_name,
endpoint_name=endpoint_name,
model=Model(
name="copilot_flow_model",
path=copilot_path, # path to promptflow folder
properties=[ # this enables the chat interface in the endpoint test tab
["azureml.promptflow.source_flow_id", "basic-chat"],
["azureml.promptflow.mode", "chat"],
["azureml.promptflow.chat_input", "chat_input"],
["azureml.promptflow.chat_output", "reply"],
],
),
environment=Environment(
build=BuildContext(
path=copilot_path,
),
inference_config={
"liveness_route": {
"path": "/health",
"port": 8080,
},
"readiness_route": {
"path": "/health",
"port": 8080,
},
"scoring_route": {
"path": "/score",
"port": 8080,
},
},
),
instance_type="Standard_DS3_v2",
instance_count=1,
environment_variables={
"PRT_CONFIG_OVERRIDE": f"deployment.subscription_id={client.subscription_id},deployment.resource_group={client.resource_group_name},deployment.workspace_name={client.workspace_name},deployment.endpoint_name={endpoint_name},deployment.deployment_name={deployment_name}",
"AZURE_OPENAI_ENDPOINT": os.getenv("AZURE_OPENAI_ENDPOINT"),
"AZURE_SEARCH_ENDPOINT": os.getenv("AZURE_SEARCH_ENDPOINT"),
"AZURE_OPENAI_API_VERSION": os.getenv("AZURE_OPENAI_API_VERSION"),
"AZURE_OPENAI_CHAT_DEPLOYMENT": os.getenv("AZURE_OPENAI_CHAT_DEPLOYMENT"),
"AZURE_OPENAI_EVALUATION_DEPLOYMENT": os.getenv(
"AZURE_OPENAI_EVALUATION_DEPLOYMENT"
),
"AZURE_OPENAI_EMBEDDING_DEPLOYMENT": os.getenv(
"AZURE_OPENAI_EMBEDDING_DEPLOYMENT"
),
"AZUREAI_SEARCH_INDEX_NAME": os.getenv("AZUREAI_SEARCH_INDEX_NAME"),
},
)
# 1. create endpoint
created_endpoint = client.begin_create_or_update(
endpoint
).result() # result() means we wait on this to complete
# 2. create deployment
created_deployment = client.begin_create_or_update(deployment).result()
# 3. update endpoint traffic for the deployment
endpoint.traffic = {deployment_name: 100} # 100% of traffic
client.begin_create_or_update(endpoint).result()
重要
エンドポイント名とデプロイ名は、Azure リージョン内で一意である必要があります。 エンドポイント名またはデプロイ名が既に存在するというエラーが発生した場合は、別の名前を試してください。
出力デプロイの詳細
デプロイ スクリプトの最後に次の行を追加して、評価結果をローカルに表示し、スタジオへのリンクを取得します。
def get_ai_studio_url_for_deploy(
client: MLClient, endpoint_name: str, deployment_name
) -> str:
studio_base_url = "https://ai.azure.com"
deployment_url = f"{studio_base_url}/projectdeployments/realtime/{endpoint_name}/{deployment_name}/detail?wsid=/subscriptions/{client.subscription_id}/resourceGroups/{client.resource_group_name}/providers/Microsoft.MachineLearningServices/workspaces/{client.workspace_name}&deploymentName={deployment_name}"
return deployment_url
print("\n ~~~Deployment details~~~")
print(f"Your online endpoint name is: {endpoint_name}")
print(f"Your deployment name is: {deployment_name}")
print("\n ~~~Test in the Azure AI Studio~~~")
print("\n Follow this link to your deployment in the Azure AI Studio:")
print(
get_ai_studio_url_for_deploy(
client=client, endpoint_name=endpoint_name, deployment_name=deployment_name
)
)
次に、スクリプトを実行します。
python deploy.py
Note
デプロイが完了するまで 10 分以上かかる場合があります。 次の手順に従って、待機中にエンドポイントへのアクセスを割り当てることをお勧めします。
デプロイが完了すると、Azure AI Studio のデプロイ ページへのリンクが表示され、デプロイをテストできます。
デプロイを検証する
Azure AI Studio でアプリケーションをテストすることをお勧めします。 デプロイしたエンドポイントをローカルでテストする場合は、カスタム コードを使用して呼び出すことができます。
エンドポイント名をメモしておきます。これは次の手順で必要です。
Azure OpenAI リソースのエンドポイント アクセス
このセクションについては、Azure サブスクリプション所有者 (IT 管理者の場合もあります) に問い合わせる必要がある場合があります。
アプリケーションのデプロイを待つ間に、ユーザーまたは管理者はエンドポイントにロールベースのアクセスを割り当てることができます。 これらのロールは、デプロイされた環境において、ローカルと同じようにキーなしでアプリケーションを実行できるようにします。
以前は、Microsoft Entra ID 認証を使用してリソースにアクセスできるように、アカウントに特定のロールを設定していました。 ここで、エンドポイントに同じ Cognitive Services OpenAI ユーザー ロールを割り当てます。
Note
これらの手順は、クイックスタートで Azure OpenAI Service を使用するためにユーザー ID にロールを割り当てた方法と似ています。
使用している Azure AI サービス リソースへのアクセス権を自分自身に付与するには:
AI Studio で、プロジェクトに移動し、左側のペインから [設定] を選択します。
[接続されたリソース] セクションで、[AIServices] という種類の接続名を選択します。
Note
[AIServices] という接続が表示されない場合は、代わりに [Azure OpenAI] という接続を使用します。
[リソースの詳細] ページで、[リソース] 見出しの下にあるリンクを選択して、Azure portal で AI サービス リソースを開きます。
Azure portal の左側のページから、[アクセス制御 (IAM)]>[+ 追加]>[ロールの割り当ての追加] の順に選択します。
Cognitive Services OpenAI ユーザー ロールを検索し、それを選択します。 [次へ] を選択します。
[マネージド ID] を選択します。 次に、[メンバーの選択] を選択します。
開いた [メンバーを選択する] ペインで、マネージド ID に [機械学習オンライン エンドポイント] を選択し、エンドポイント名を検索します。 エンドポイントを選択して [選択] を選択します。
ウィザードを続行し、[確認と割り当て] を選択してロールの割り当てを追加します。
Note
アクセスが反映されるまで数分かかることがあります。 次の手順でテストする場合に承認されていないエラーが表示された場合は、数分後にもう一度試してください。
Azure AI Search リソースのエンドポイント アクセス
このセクションについては、Azure サブスクリプション所有者 (IT 管理者の場合もあります) に問い合わせる必要がある場合があります。
検索インデックス データ共同作成者 Azure AI Search Service へのロールに割り当てた方法と同様に、エンドポイントにも同じロールを割り当てる必要があります。
Azure AI Studio で、[設定] を選択し、接続されている Azure AI Search サービスに移動します。
リンクを選択すると、リソースの概要が開きます。 概要ページのリンクを選択すると、Azure portal でリソースが開きます。
Azure portal の左側のページから、[アクセス制御 (IAM)]>[+ 追加]>[ロールの割り当ての追加] の順に選択します。
[検索インデックス データ共同作成者] ロールを検索し、選択します。 [次へ] を選択します。
[マネージド ID] を選択します。 次に、[メンバーの選択] を選択します。
開いた [メンバーを選択する] ペインで、マネージド ID に [機械学習オンライン エンドポイント] を選択し、エンドポイント名を検索します。 エンドポイントを選択して [選択] を選択します。
ウィザードを続行し、[確認と割り当て] を選択してロールの割り当てを追加します。
Note
アクセスが反映されるまで数分かかることがあります。 次の手順でテストする場合に承認されていないエラーが表示された場合は、数分後にもう一度試してください。
AI Studio でデプロイをテストする
デプロイが完了すると、デプロイへの便利なリンクが表示されます。 リンクを使用しない場合は、プロジェクトの [デプロイ] タブに移動し、新しいデプロイを選択します。
[テスト] タブを選択し、チャット インターフェイスで質問してみます。
たとえば、"トレイルウォーカーのハイキング シューズは防水ですか?" と入力して Enter キーを押します。
応答が返ってくるのを確認すると、デプロイを確認できます。
エラーが発生した場合は、[ログ] タブを選択して詳細を確認してください。
Note
未承認のエラーが表示された場合は、エンドポイント アクセスがまだ適用されていない可能性があります。 数分たってから、もう一度試してください。
デプロイされたチャット アプリをローカルで呼び出す
デプロイをローカルで確認する場合は、Python スクリプトを介して呼び出すことができます。
次のようなスクリプトを定義します。
- スコアリング URL への整形式要求を作成します。
- 要求を投稿し、応答を処理します。
次のコードを含む rag-tutorial フォルダーに invoke-local.py ファイルを作成します。 query
と endpoint_name
(および必要に応じて他のパラメーター) は、ユース ケースに合わせて変更してください。
import os
from dotenv import load_dotenv
load_dotenv()
import requests
from azure.ai.ml import MLClient
from azure.identity import DefaultAzureCredential
query = "Are the trailwalker shoes waterproof?"
endpoint_name = "tutorial-endpoint"
client = MLClient(
DefaultAzureCredential(),
os.getenv("AZURE_SUBSCRIPTION_ID"),
os.getenv("AZURE_RESOURCE_GROUP"),
os.getenv("AZUREAI_PROJECT_NAME"),
)
scoring_url = client.online_endpoints.get(endpoint_name).scoring_uri
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {client._credential.get_token('https://ml.azure.com').token}",
"Accept": "application/json",
}
response = requests.post(
scoring_url,
headers=headers,
json={"chat_input": query},
)
(print(response.json()["reply"]))
クエリに対するチャット アプリの返信がコンソールに表示されます。
Note
未承認のエラーが表示された場合は、エンドポイント アクセスがまだ適用されていない可能性があります。 数分たってから、もう一度試してください。
リソースをクリーンアップする
不要な Azure コストが発生しないように、このチュートリアルで作成したリソースが不要になったら削除してください。 リソースを管理するために、Azure portal を使用できます。
関連するコンテンツ
- プロンプト フローに関する詳細情報
- RAG を実装するサンプル チャット アプリ アプリケーションについては、Azure-Samples/rag-data-openai-python-promptflow を参照してください