【AzureML プロンプトフロー】Bring Your Own Data Chat Q&A

# はじめに
今回はAzureMLのプロンプトフローを試してみます。
サンプルフローはいくつか出ていますが、その中でも「Bring Your Own Data Chat Q&A」を使います。

# Bring Your Own Data Chat Q&A
このプロンプトフローでは、GPT3.5やインデックス化したファイルを使用したQ&Aのフローです。インデックス化については、Vector Searchを使って関連性の高い情報を抽出して回答を生成できます。

まず、プロンプトフローを「作成」して、「Bring Your Own Data Chat Q&A」を選択して始めます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/8d98aaa9-6d5e-c292-11ec-b8e4c4d0516f.png)

## Azure OpenAIの接続
はじめにプロンプトフローではLLM接続が必要となってくるため、すでにデプロイしたAzure OpenAIのモデルに接続します。

「接続」タブの「作成」から下記の必要な項目を入力してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/c4b36b53-42bf-da9e-95c4-3ab23a04f3da.png)


## Runtimeの作成
続いてプロンプトフローを実行するにあたり、Runtimeの作成を行う必要があります。

「ランタイム」タブをクリックし、「作成」をすると「マネージドオンラインエンドポイントデプロイ」と「コンピューティングインスタンス」のどちらかを選択できるようになります。

今回は推奨されている「コンピューティングインスタンス」でRuntimeを作成します。

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/1a51eb0b-bf72-2018-9b1a-855965c065f5.png)

「AzureMLコンピューティングインスタンスを作成する」をクリックし、

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/6bb0623f-5384-fc02-24aa-15496258f5a1.png)

「コンピューティング名」や仮想マシンのサイズを選びます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/d1feec1e-78ec-42ed-72f8-f6021f1efebc.png)


数分待てば、コンピューティングインスタンスが作成されるので、完了したら「ランタイム名」を入力し、Runtimeを作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/b7229694-d2b1-056c-3482-70e058b9369a.png)

## 処理の流れ

サンプルを作成すると、次のような画面になり、「入力」と「出力」でユーザーの質問を記載できるようになっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/a3dc9695-f5f9-1dcc-0947-7c7dfbe265ce.png)

デフォルトでは下記のようにすでにいくつか質問がされている状態からスタートします。


```python
[
  {
    "inputs": {
      "chat_input": "Hi"
    },
    "outputs": {
      "chat_output": "Hello! How can I assist you today?"
    }
  },
  {
    "inputs": {
      "chat_input": "What is Azure compute instance?"
    },
    "outputs": {
      "chat_output": "An Azure Machine Learning compute instance is a fully managed cloud-based workstation for data scientists. It provides a pre-configured and managed development environment in the cloud for machine learning. Compute instances can also be used as a compute target for training and inferencing for development and testing purposes. They have a job queue, run jobs securely in a virtual network environment, and can run multiple small jobs in parallel. Additionally, compute instances support single-node multi-GPU distributed training jobs."
    }
  }
]
```

このようにチャット履歴がある中で、「How can I create one using azureml sdk V2?」という質問文を投げかけて出力を見てみようと思います。


一連の処理の流れはこのようになっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/893ea987-d608-c665-767a-aa98085780e7.png)


1つずつ流れや入力・出力を見ていきます。

・**embed_the_question**
ユーザーが入力した質問文を埋め込みベクトル化します。

また、LLMの接続が必要なのでAzureOpenAIですでにデプロイしたモデルを設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/1c9c7dfc-cc6f-95ee-9db1-84dacd9705ac.png)

ここでの入力は以下のようになります。

```python:入力
{
  "connection":"XXX"
  "deployment_name":"text-embedding-ada-002"
  "model":undefined
  "input":"How can I create one using azureml sdk V2?"
}
```

これで質問文がベクトル化されます。

・**search_question_from_indexed_docs**
Vector Searchを使って、ベクトル化された質問文から関連のあるドキュメント内のテキストを高速に検索します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/fdde48e8-025e-6cc8-f362-508e725bfdf8.png)

ドキュメントをインデックス化したファイルへのパスと先ほどベクトル化された質問文をクエリとして入力します。

そして下記のようにソース（ファイル名・タイトル・URL）とテキストが出力されます。

```python:出力
[
  0:{
    "system_metrics":{
      "duration":0.065792
    }
    "output":[
      0:{
        "metadata":{
          "chunk_hash":"XXX"
          "extension":".md"
          "markdown_heading":{
          "heading":"[Azure CLI](tab/cli)"
          "level":1
        }
        "mtime":1683074438
        "source":{
          "filename":"how-to-auto-train-image-models.md"
          "title":"Set up AutoML for computer vision"
          "url":"https://github.com/prakharg-msft/azureml-tutorials/blob/main//how-to-auto-train-image-models.md"
        }
        "source_doc_id":"how-to-auto-train-image-models.md59"
        "stats":{
          "chars":814
          "lines":20
          "tiktokens":281
        }
        }
        "original_entity":NULL
        "score":0.34047389030456543
        "text":"title: Set up AutoML for computer vision titleSuffix: Azure Machine Learning description: Set up Azure Machine Learning automated ML to train computer vision models with the CLI v2 and Python SDK v2. services: machine-learning author: swatig007 ms.author: swatig ms.reviewer: ssalgado ms.service: machine-learning ms.subservice: automl ms.custom: event-tier1-build-2022, ignite-2022 ms.topic: how-to ms.date: 07/13/2022 # [Azure CLI](#tab/cli) [!INCLUDE [cli v2](../../includes/machine-learning-cli-v2.md)] ```azurecli az ml model create --name od-fridge-items-mlflow-model --version 1 --path azureml://jobs/$best_run/outputs/artifacts/outputs/mlflow-model/ --type mlflow_model --workspace-name [YOUR_AZURE_WORKSPACE] --resource-group [YOUR_AZURE_RESOURCE_GROUP] --subscription [YOUR_AZURE_SUBSCRIPTION] ``` "
        "vector":NULL
      }
      1:{...}
    ]
  }
]
```

・**generate_prompt_context**
出力された検索結果を受け取り、一定の形式で返すようここで変換します。

```python:generate_prompt_context
from typing import List
from promptflow import tool
from promptflow_vectordb.core.contracts import SearchResultEntity


@tool
def generate_prompt_context(search_result: List[dict]) -> str:
    def format_doc(doc: dict):
        return f"Content: {doc['Content']}\nSource: {doc['Source']}"

    SOURCE_KEY = "source"
    URL_KEY = "url"

    retrieved_docs = []
    for item in search_result:

        entity = SearchResultEntity.from_dict(item)
        content = entity.text or ""

        source = ""
        if entity.metadata is not None:
            if SOURCE_KEY in entity.metadata:
                if URL_KEY in entity.metadata[SOURCE_KEY]:
                    source = entity.metadata[SOURCE_KEY][URL_KEY] or ""

        retrieved_docs.append({
            "Content": content,
            "Source": source
        })
    doc_string = "\n\n".join([format_doc(doc) for doc in retrieved_docs])
    return doc_string
```

ここでの出力は以下の通りになります。
```python:出力
[
  0:{
  "system_metrics":{
    "duration":0.000869
  }
  "output":"Content: title: Set up AutoML for computer vision titleSuffix: Azure Machine Learning description: Set up Azure Machine Learning automated ML to train computer vision models with the CLI v2 and Python SDK v2. services: machine-learning author: swatig007 ms.author: swatig ms.reviewer: ssalgado ms.service: machine-learning ms.subservice: automl ms.custom: event-tier1-build-2022, ignite-2022 ms.topic: how-to ms.date: 07/13/2022 # [Azure CLI](#tab/cli) [!INCLUDE [cli v2](../../includes/machine-learning-cli-v2.md)] ```azurecli az ml model create --name od-fridge-items-mlflow-model --version 1 --path azureml://jobs/$best_run/outputs/artifacts/outputs/mlflow-model/ --type mlflow_model --workspace-name [YOUR_AZURE_WORKSPACE] --resource-group [YOUR_AZURE_RESOURCE_GROUP] --subscription [YOUR_AZURE_SUBSCRIPTION] ``` Source: https://github.com/prakharg-msft/azureml-tutorials/blob/main//how-to-auto-train-image-models.md Content: title: Set up AutoML for computer vision titleSuffix: Azure Machine Learning description: Set up Azure Machine Learning automated ML to train computer vision models with the CLI v2 and Python SDK v2. services: machine-learning author: swatig007 ms.author: swatig ms.reviewer: ssalgado ms.service: machine-learning ms.subservice: automl ms.custom: event-tier1-build-2022, ignite-2022 ms.topic: how-to ms.date: 07/13/2022 ### Create the deployment Using the `MLClient` created earlier, we'll now create the deployment in the workspace. This command will start the deployment creation and return a confirmation response while the deployment creation continues. Source: https://github.com/prakharg-msft/azureml-tutorials/blob/main//how-to-auto-train-image-models.md"
  }
]
```


・**Prompt_variants**
先ほど出力されたテキストをコンテキストとして使ってプロンプトを作ります。

```python:プロンプト
system:
* You are an AI system designed to answer questions from users in a designated context. When presented with a scenario, you must reply with accuracy to inquirers' inquiries using only descriptors provided in that same context. If there is ever a situation where you are unsure of the potential answers, simply respond with "I don't know.
Please add citation after each sentence when possible in a form "(Source: citation)".
context: {{contexts}}

chat history:
{% for item in chat_history %}
user:
{{ item.inputs.chat_input }}
assistant:
{{ item.outputs.chat_output }}

{% endfor %}

user question:
{{ chat_input }}
```

出力は以下のとおりになります。
```python:出力
[
  0:{
    "system_metrics":{
      "duration":0.003115
    }
    "output":"system: * You are an AI system designed to answer questions from users in a designated context. When presented with a scenario, you must reply with accuracy to inquirers' inquiries using only descriptors provided in that same context. If there is ever a situation where you are unsure of the potential answers, simply respond with "I don't know. Please add citation after each sentence when possible in a form "(Source: citation)". context: Content: title: Set up AutoML for computer vision titleSuffix: Azure Machine Learning description: Set up Azure Machine Learning automated ML to train computer vision models with the CLI v2 and Python SDK v2. services: machine-learning author: swatig007 ms.author: swatig ms.reviewer: ssalgado ms.service: machine-learning ms.subservice: automl ms.custom: event-tier1-build-2022, ignite-2022 ms.topic: how-to ms.date: 07/13/2022 # [Azure CLI](#tab/cli) [!INCLUDE [cli v2](../../includes/machine-learning-cli-v2.md)] ```azurecli az ml model create --name od-fridge-items-mlflow-model --version 1 --path azureml://jobs/$best_run/outputs/artifacts/outputs/mlflow-model/ --type mlflow_model --workspace-name [YOUR_AZURE_WORKSPACE] --resource-group [YOUR_AZURE_RESOURCE_GROUP] --subscription [YOUR_AZURE_SUBSCRIPTION] ``` Source: https://github.com/prakharg-msft/azureml-tutorials/blob/main//how-to-auto-train-image-models.md Content: title: Set up AutoML for computer vision titleSuffix: Azure Machine Learning description: Set up Azure Machine Learning automated ML to train computer vision models with the CLI v2 and Python SDK v2. services: machine-learning author: swatig007 ms.author: swatig ms.reviewer: ssalgado ms.service: machine-learning ms.subservice: automl ms.custom: event-tier1-build-2022, ignite-2022 ms.topic: how-to ms.date: 07/13/2022 ### Create the deployment Using the `MLClient` created earlier, we'll now create the deployment in the workspace. This command will start the deployment creation and return a confirmation response while the deployment creation continues. Source: https://github.com/prakharg-msft/azureml-tutorials/blob/main//how-to-auto-train-image-models.md chat history: user: Hi assistant: Hello! How can I assist you today? user: What is Azure compute instance? assistant: An Azure Machine Learning compute instance is a fully managed cloud-based workstation for data scientists. It provides a pre-configured and managed development environment in the cloud for machine learning. Compute instances can also be used as a compute target for training and inferencing for development and testing purposes. They have a job queue, run jobs securely in a virtual network environment, and can run multiple small jobs in parallel. Additionally, compute instances support single-node multi-GPU distributed training jobs. user question: How can I create one using azureml sdk V2?"
  }
]
```


・**chat_with_context**
先ほど出力されたプロンプトを実行します。

ここでもLLMの接続を行います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/7314e61c-9c6e-83af-f737-04bdf3107d19.png)

## 実行結果
これまでの処理を実行します。

まずは右上の「チャット」をクリックすると、すでに質問されたチャットが下記のように表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/74969ee6-1ae9-1cf6-58ca-226b702a6e28.png)

続いてチャット欄に「How can I create one using azureml sdk V2?」を入力して送信すると、回答が返ってきました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/f2945858-fb9b-5613-0ceb-3f541e00561b.png)



```python:出力
[
  0:{
  "system_metrics":{
    "completion_tokens":243
    "duration":9.18725
    "prompt_tokens":679
    "total_tokens":922
  }
  "output":"To create an Azure Machine Learning compute instance using the Azure Machine Learning SDK v2, you can use the `ComputeInstance` class. Here's an example of how to create a compute instance: ```python from azureml.core import Workspace, ComputeInstance # Load your Azure Machine Learning workspace workspace = Workspace.from_config() # Define the compute instance name and configuration compute_name = "my-compute-instance" compute_config = ComputeInstance.provisioning_configuration(vm_size="STANDARD_DS3_V2", ssh_public_access=False) # Create the compute instance compute_instance = ComputeInstance.create(workspace, compute_name, compute_config) # Wait for the compute instance to be provisioned compute_instance.wait_for_completion(show_output=True) ``` In the example above, you first load your Azure Machine Learning workspace using `Workspace.from_config()`. Then, you define the name of the compute instance (`compute_name`) and its configuration (`compute_config`). Finally, you create the compute instance using `ComputeInstance.create()` and wait for it to be provisioned using `compute_instance.wait_for_completion()`. Please note that you need to have the necessary permissions and resources in your Azure subscription to create a compute instance."
  }
]
```

これまでのチャット履歴の内容を把握しつつ、Vector Searchを使って質問文に関連ある回答を出力できました。