次の方法で共有


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

この記事では、データ ソースの例として lakehouse を使用して Microsoft Fabric でデータ エージェントを設定する方法について説明します。 最初に、Lakehouse を作成して設定し、次に Fabric データ エージェントを作成し、それに lakehouse を追加します。 Power BI セマンティック モデル (必要な読み取り/書き込みアクセス許可を持つ)、ウェアハウス、KQL データベース、またはオントロジが既にある場合は、同じ手順に従って、代わりにそのソースを選択します。 このチュートリアルでは lakehouse を使用しますが、パターンは他のソースでも同じです。データ ソースの選択のみが異なります。

Von Bedeutung

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

[前提条件]

Von Bedeutung

Power BI 管理ポータルでスタンドアロンの Copilot エクスペリエンスが有効になっていることを確認します (テナント設定 > Copilot > スタンドアロン Copilot エクスペリエンス)。 有効になっていない場合、他の Copilot テナント スイッチがオンになっている場合でも、Copilot シナリオ内でデータ エージェントを使用することはできません。 詳細については、 Power BI テナント設定の Copilot に関するページを参照してください。

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 データ エージェントを特定の要件に合わせます。

データを選択する

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

レイクハウスを追加する手順を示すスクリーンショット。

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

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

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

指示を提供する

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

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 を使用しています。

Von Bedeutung

データ エージェントをプログラムで呼び出す場合は、次を実装します。

  1. 不定ループを回避するためのポーリング タイムアウト (下記の例を参照)。
  2. 最小ポーリング頻度 (2 ~ 5 秒から開始し、必要な場合にのみ増加します)。
  3. 完了後に作成されたスレッドまたはリソースのクリーンアップ。
  4. Fabric 容量の解放が完了したら、ノートブック セッションをシャットダウンします。

これらの正確なバージョンが古くなった場合は、バージョン ピン (openaisynapsemlpandastqdm) を Fabric ランタイムの最新の検証済みバージョンに調整します。

%pip install "openai==1.70.0"
%pip install "synapseml==1.0.5"  # Required for synapse.ml.mlflow (update version as needed)
%pip install pandas tqdm  # Skip if already available in the Fabric runtime
import typing as t
import time
import uuid

# OpenAI SDK internals
from openai import OpenAI
from openai._models import FinalRequestOptions
from openai._types import Omit
from openai._utils import is_given

# SynapseML helper for env config
from synapse.ml.mlflow import get_mlflow_env_config

# Removed unused imports: requests, json, pprint, APIStatusError, SynapseTokenProvider
 
base_url = "https://<generic published base URL value>"
question = "What data sources 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 (avoid indefinite loop)
terminal_states = {"completed", "failed", "cancelled", "requires_action"}
poll_interval = 2
timeout_seconds = 300  # Adjust based on expected workload
start_time = time.time()

while run.status not in terminal_states:
    if time.time() - start_time > timeout_seconds:
        raise TimeoutError(f"Run polling exceeded {timeout_seconds} seconds (last status={run.status})")
    run = fabric_client.beta.threads.runs.retrieve(
        thread_id=thread.id,
        run_id=run.id,
    )
    print(run.status)
    time.sleep(poll_interval)

if run.status != "completed":
    print(f"Run finished with status: {run.status}")

# 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)