次の方法で共有


AdventureWorks データセットを使用した Fabric データ エージェントの例 (プレビュー)

この記事では、レイクハウスをデータ ソースとして使用して、Microsoft Fabric でデータ エージェントを設定する方法について説明します。 プロセスを説明するために、まずレイクハウスを作成し、次にデータを追加します。 次に、Fabric データ エージェントを作成し、そのデータ ソースとしてレイクハウスを構成します。 Power BI セマンティック モデル (必要な読み取り/書き込みアクセス許可付き)、ウェアハウス、または KQL データベースが既にある場合は、Fabric データ エージェントを作成してデータ ソースを追加した後で同じ手順に従うことができます。 ここで示す手順はレイクハウスに焦点を当てていますが、プロセスは他のデータ ソースでも似ています。特定の選択内容に基づいて調整するだけです。

重要

この機能は プレビュー段階です

前提条件

AdventureWorksLH を使用してレイクハウスを作成する

最初にレイクハウスを作成し、必要なデータを設定します。

AdventureWorksLH のインスタンスが既にレイクハウス (または倉庫) にある場合は、この手順をスキップできます。 そうでない場合は、Fabric ノートブックの次の手順を使用して、Lakehouse にデータを設定できます。

  1. Fabric データ エージェントを作成するワークスペースに新しいノートブックを作成します。

  2. [エクスプローラー] ウィンドウの左側にある [+ データ ソース] を選択します。 このオプションを使用すると、既存のレイクハウスを追加したり、新しいレイクハウスを作成することができます。 わかりやすくするために、新しいレイクハウスを作成し、名前を割り当てます。

  3. 先頭のセルに次のコード スニペットを追加します。

    import pandas as pd
    from tqdm.auto import tqdm
    base = "https://synapseaisolutionsa.z13.web.core.windows.net/data/AdventureWorks"
    
    # load list of tables
    df_tables = pd.read_csv(f"{base}/adventureworks.csv", names=["table"])
    
    for table in (pbar := tqdm(df_tables['table'].values)):
        pbar.set_description(f"Uploading {table} to lakehouse")
    
        # download
        df = pd.read_parquet(f"{base}/{table}.parquet")
    
        # save as lakehouse table
        spark.createDataFrame(df).write.mode('overwrite').saveAsTable(table)
    
  4. [ すべて実行] を選択します

AdventureWorks アップロード コードを含むノートブックを示すスクリーンショット。

数分後に、レイクハウスに必要なデータが取り込まれます。

Fabric データ エージェントを作成する

新しい Fabric データ エージェントを作成するには、ワークスペースに移動し、次のスクリーンショットに示すように [ + 新しい項目] ボタンを選択します。

Fabric データ エージェントを作成する場所を示すスクリーンショット。

[すべての項目] タブで、 Fabric データ エージェント を検索して、適切なオプションを見つけます。 選択すると、次のスクリーンショットに示すように、Fabric データ エージェントの名前の指定を求められます。

Fabric データ エージェントの名前を指定する場所を示すスクリーンショット。

名前を入力したら、次の手順に進み、Fabric データ エージェントを特定の要件に合わせます。

データを選択する

次のスクリーンショットに示すように、前の手順で作成した lakehouse を選択し、[ 追加] を選択します。

[レイクハウスの追加] ステップを示すスクリーンショット。

Lakehouse をデータ ソースとして追加すると、Fabric データ エージェント ページの左側にある [エクスプローラー ] ウィンドウに lakehouse 名が表示されます。 使用可能なすべてのテーブルを表示するには、レイクハウスを選択します。 チェックボックスを使用して、AI で使用できるようにするテーブルを選択します。 このシナリオでは、次のテーブルを選択します。

  • dimcustomer
  • dimdate
  • dimgeography
  • dimproduct
  • dimproductcategory
  • dimpromotion
  • dimreseller
  • dimsalesterritory
  • factinternetsales
  • factresellersales

AI のテーブルを選択できる場所を示すスクリーンショット。

指示を提供する

Fabric データ エージェントの手順を追加するには、[ データ エージェントの指示 ] ボタンを選択して、右側の [Fabric データ エージェントの指示] ウィンドウを開きます。 次の手順を追加できます。

AdventureWorksLH データ ソースには、次の 3 つのテーブルからの情報が含まれています。

  • dimcustomer: 詳細な顧客の人口統計と連絡先情報
  • dimdate、日付関連のデータ (カレンダーや会計情報など)
  • dimgeography: 市区町村名や国の地域コードなどの地理的な詳細。

このデータ ソースは、顧客の詳細、時間ベースのイベント、地理的な場所を含むクエリと分析に使用します。

AI に指示を提供できる場所を示すスクリーンショット。

例を提供する

クエリの例を追加するには、[ クエリの例 ] ボタンを選択して、右側の [サンプル クエリ] ウィンドウを開きます。 このウィンドウには、サポートされているすべてのデータ ソースのサンプル クエリを追加または編集するためのオプションが用意されています。 次のスクリーンショットに示すように、データ ソースごとに [サンプル クエリの追加] または [サンプル クエリの編集] を選択して、関連する例を入力できます。

AI に提供する例を追加できる場所を示すスクリーンショット。

ここでは、作成した lakehouse データ ソースのサンプル クエリを追加する必要があります。

Question: Calculate the average percentage increase in sales amount for repeat purchases for every zipcode. Repeat purchase is a purchase subsequent to the first purchase (the average should always be computed relative to the first purchase)

SELECT AVG((s.SalesAmount - first_purchase.SalesAmount) / first_purchase.SalesAmount * 100) AS AvgPercentageIncrease
FROM factinternetsales s
INNER JOIN dimcustomer c ON s.CustomerKey = c.CustomerKey
INNER JOIN dimgeography g ON c.GeographyKey = g.GeographyKey
INNER JOIN (
	SELECT *
	FROM (
		SELECT
			CustomerKey,
			SalesAmount,
            OrderDate,
			ROW_NUMBER() OVER (PARTITION BY CustomerKey ORDER BY OrderDate) AS RowNumber
		FROM factinternetsales
	) AS t
	WHERE RowNumber = 1
) first_purchase ON s.CustomerKey = first_purchase.CustomerKey
WHERE s.OrderDate > first_purchase.OrderDate
GROUP BY g.PostalCode;

Question: Show the monthly total and year-to-date total sales. Order by year and month.

SELECT
    Year,
	Month,
	MonthlySales,
	SUM(MonthlySales) OVER (PARTITION BY Year ORDER BY Year, Month ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS CumulativeTotal
FROM (
	SELECT
	   YEAR(OrderDate) AS Year,
	   MONTH(OrderDate) AS Month,
	   SUM(SalesAmount) AS MonthlySales
	FROM factinternetsales
	GROUP BY YEAR(OrderDate), MONTH(OrderDate)
) AS t

SQL の例の追加を示すスクリーンショット。

Power BI セマンティック モデルのデータ ソースでは、サンプル クエリと質問のペアの追加は現在サポートされていません。

Fabric データ エージェントをテストして修正する

Fabric データ エージェントの構成、Fabric データ エージェント命令の追加、レイクハウスのサンプル クエリの提供を行ったところで、データ エージェントに質問して回答を受け取るという対話ができるようになります。 テストを続ける際に、例を追加したり、命令を改善したりすることで、Fabric データ エージェントのパフォーマンスをさらに向上させられます。 同僚と共同作業してフィードバックを収集し、入力に基づいて、提供されているクエリと指示の例が、質問の種類と一致していることを確認します。

Fabric データ エージェントを発行する

Fabric データ エージェントのパフォーマンスを検証した後、データについての Q&A を実行することを希望する仕事仲間と共有するためにそれを公開すると決めることができます。 この場合は、次のスクリーンショットに示すように [ 発行] を選択します。

[発行] オプションの選択を示すスクリーンショット。

次のスクリーンショットに示すように、[ データ エージェントの発行 ] ボックスが開きます。

データ エージェントの発行機能を示すスクリーンショット。

このボックスで、[ 発行 ] を選択して Fabric データ エージェントを発行します。 次のスクリーンショットで示すように、Fabric データ エージェントの公開済みの URL が表示されます。

発行された URL を示すスクリーンショット。

Power BI で Copilot で Fabric データ エージェントを使用する

Power BI の Copilot を使用して、発行後に Fabric データ エージェントを操作できます。 Power BI の Copilot を使用すると、データ エージェントやその他の項目 (レポート、セマンティック モデルなど) を切り替えることなく直接使用できます。

左側のナビゲーション ウィンドウで [Copilot ] ボタンを選択して、Power BI で Copilot を開きます。 次に、下部のテキスト ボックスで [ 項目の追加 ] を選択して、データ エージェントを追加します。 開いたウィンドウで [ データ エージェント ] を選択します。 アクセス許可を持っているデータ エージェントのみを表示できます。 目的のデータ エージェントを選択し、[ 確認] を選択します。 この例では、1 つのデータ エージェントを操作する方法を示しますが、他のデータ エージェント、レポート、セマンティック モデルなど、さらに項目を追加できます。 次のスクリーンショットは、1 つのデータ エージェントの手順を示しています。

データ エージェントなどの項目を追加する [Copilot] ボタンとボタンを示すスクリーンショット。

Power BI の Copilot にデータ エージェントを追加したら、次のスクリーンショットに示すように、Fabric データ エージェントに関連する質問をすることができます。

質問に答える Copilot を示すスクリーンショット。

Fabric データ エージェントをプログラムで使用する

Fabric ノートブック内のプログラムで Fabric データ エージェントを使用できます。 次のスクリーンショットに示すように、Fabric データ エージェントに発行された URL 値があるかどうかを判断するには、[ 設定] を選択します。

Fabric データ エージェント設定の選択を示すスクリーンショット。

次のスクリーンショットに示すように、Fabric データ エージェントを発行する前に、発行された URL 値はありません。

発行前に Fabric データ エージェントに発行された URL 値がないことを示すスクリーンショット。

以前に Fabric データ エージェントを発行したことがない場合は、前の手順の手順に従って発行できます。 発行済み URL をコピーし、Fabric ノートブックで使用できます。 このように、Fabric ノートブックで Fabric データ エージェント API を呼び出して、Fabric データ エージェントのクエリを実行できます。 コピーした URL をこのコード スニペットに貼り付けます。 次に、質問を Fabric データ エージェントに関連するクエリに置き換えます。 この例では、\<generic published URL value\> という URL を使用しています。

%pip install "openai==1.70.0"
%pip install httpx==0.27.2
import requests
import json
import pprint
import typing as t
import time
import uuid

from openai import OpenAI
from openai._exceptions import APIStatusError
from openai._models import FinalRequestOptions
from openai._types import Omit
from openai._utils import is_given
from synapse.ml.mlflow import get_mlflow_env_config
from sempy.fabric._token_provider import SynapseTokenProvider
 
base_url = "https://<generic published base URL value>"
question = "What datasources do you have access to?"

configs = get_mlflow_env_config()

# Create OpenAI Client
class FabricOpenAI(OpenAI):
    def __init__(
        self,
        api_version: str ="2024-05-01-preview",
        **kwargs: t.Any,
    ) -> None:
        self.api_version = api_version
        default_query = kwargs.pop("default_query", {})
        default_query["api-version"] = self.api_version
        super().__init__(
            api_key="",
            base_url=base_url,
            default_query=default_query,
            **kwargs,
        )
    
    def _prepare_options(self, options: FinalRequestOptions) -> None:
        headers: dict[str, str | Omit] = (
            {**options.headers} if is_given(options.headers) else {}
        )
        options.headers = headers
        headers["Authorization"] = f"Bearer {configs.driver_aad_token}"
        if "Accept" not in headers:
            headers["Accept"] = "application/json"
        if "ActivityId" not in headers:
            correlation_id = str(uuid.uuid4())
            headers["ActivityId"] = correlation_id

        return super()._prepare_options(options)

# Pretty printing helper
def pretty_print(messages):
    print("---Conversation---")
    for m in messages:
        print(f"{m.role}: {m.content[0].text.value}")
    print()

fabric_client = FabricOpenAI()
# Create assistant
assistant = fabric_client.beta.assistants.create(model="not used")
# Create thread
thread = fabric_client.beta.threads.create()
# Create message on thread
message = fabric_client.beta.threads.messages.create(thread_id=thread.id, role="user", content=question)
# Create run
run = fabric_client.beta.threads.runs.create(thread_id=thread.id, assistant_id=assistant.id)

# Wait for run to complete
while run.status == "queued" or run.status == "in_progress":
    run = fabric_client.beta.threads.runs.retrieve(
        thread_id=thread.id,
        run_id=run.id,
    )
    print(run.status)
    time.sleep(2)

# Print messages
response = fabric_client.beta.threads.messages.list(thread_id=thread.id, order="asc")
pretty_print(response)

# Delete thread
fabric_client.beta.threads.delete(thread_id=thread.id)