다음을 통해 공유


AdventureWorks 데이터 세트를 사용하는 AI 기술 예제(미리 보기)

이 문서에서는 레이크하우스를 데이터 원본으로 사용하여 AI 기술을 설정하는 방법을 설명합니다. 프로세스를 설명하기 위해 먼저 Lakehouse를 만든 다음, 여기에 데이터를 추가합니다. 그런 다음 AI 기술을 만들고 레이크하우스를 데이터 원본으로 구성합니다. Power BI 의미 체계 모델(필요한 읽기/쓰기 권한), 웨어하우스 또는 KQL 데이터베이스가 이미 있는 경우 AI 기술을 만들어 데이터 원본을 추가한 후 동일한 단계를 수행할 수 있습니다. 여기에 표시된 단계는 Lakehouse에 초점을 맞추고 있지만 프로세스는 다른 데이터 원본과 유사합니다. 특정 선택에 따라 조정만 하면 됩니다.

Important

이 기능은 프리뷰로 제공됩니다.

필수 조건

AdventureWorksLH를 사용하여 레이크하우스 만들기

먼저 레이크하우스를 만들고 필요한 데이터로 채웁니다.

레이크하우스(또는 창고)에 AdventureWorksLH 인스턴스가 이미 있는 경우, 이 단계를 건너뛸 수 있습니다. 그렇지 않은 경우 Fabric Notebook의 다음 지침을 사용하여 레이크하우스를 데이터로 채울 수 있습니다.

  1. AI 기술을 만들려는 작업 영역에서 새 Notebook을 만듭니다.

  2. Explorer 창의 왼쪽에서 + 데이터 원본을 선택합니다. 이 옵션을 사용하면 기존 레이크하우스를 추가하거나 새 레이크하우스를 만들 수 있습니다. 명확성을 위해 새 레이크하우스를 만들고 이름을 할당합니다.

  3. 맨 위의 셀에서 클래스에 다음 코드 조각을 추가합니다.

    import pandas as pd
    from tqdm.auto import tqdm
    base = "https://synapseaisolutionsa.blob.core.windows.net/public/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 업로드 코드가 있는 Notebook을 보여 주는 스크린샷

몇 분 후, 레이크 하우스는 필요한 데이터로 채웁니다.

AI 기술 만들기

새 AI 기술을 만들려면 작업 영역으로 이동하여 다음 스크린샷과 같이 + 새 항목 단추를 선택합니다.

AI 기술을 만들 위치를 보여 주는 스크린샷

모든 항목 탭에서 AI 기술 검색하여 적절한 옵션을 찾습니다. 선택하면 다음 스크린샷에 표시된 것처럼 AI 기술의 이름을 입력하라는 메시지가 표시됩니다.

AI 기술의 이름을 제공할 위치를 보여 주는 스크린샷

이름을 입력한 후 다음 단계를 진행하여 AI 기술을 특정 요구 사항에 맞춥니다.

데이터 선택

이전 단계에서 생성한 lakehouse를 선택한 후, 를 선택하고을 추가합니다. 레이크하우스가 데이터 원본으로 추가되면 AI 기술 페이지의 왼쪽에 있는 탐색기 창에 레이크하우스 이름이 표시됩니다. 레이크하우스를 선택하여 사용 가능한 모든 테이블을 봅니다. 확인란을 사용하여 AI에서 사용할 테이블을 선택합니다. 이 시나리오에서는 다음 테이블을 선택합니다.

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

AI용 테이블을 선택할 수 있는 위치를 보여 주는 스크린샷

지침 제공

AI 지침을 추가하려면 AI 지침 단추를 선택하여 오른쪽에 있는 AI 지침 창을 엽니다. 다음 지침을 추가할 수 있습니다.

AdventureWorksLH 데이터 원본에는 다음 세 테이블의 정보가 포함됩니다.

  • 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 의미 체계 모델 데이터 원본에 대해 지원되지 않습니다.

AI 기술 테스트 및 수정

이제 AI 기술을 구성하고, AI 지침을 추가하고, 레이크하우스에 대한 예제 쿼리를 제공했으므로 질문을 하고 답변을 받아 상호 작용할 수 있습니다. 테스트를 계속하면 더 많은 예제를 추가하고 지침을 구체화하여 AI 기술의 성능을 더욱 향상시킬 수 있습니다. 동료와 협업하여 피드백을 수집하고 입력에 따라 제공된 예제 쿼리 및 지침이 질문할 질문 유형과 일치하는지 확인합니다.

프로그래밍 방식으로 AI 기술 사용

Fabric Notebook 내에서 프로그래밍 방식으로 AI 기술을 사용할 수 있습니다. AI 기술에 게시된 URL 값이 있는지 여부를 확인하려면 다음 스크린샷에서 보듯이 설정을 선택합니다.

AI 기술 설정 선택 영역을 보여 주는 스크린샷

다음 스크린샷에서 보듯이 AI 기술을 게시하기 전에는 게시된 URL 값이 없습니다.

AI 기술에 게시하기 전에 게시된 URL 값이 없음을 보여 주는 스크린샷

AI 기술의 성능에 대한 유효성을 검사한 후 데이터를 통해 Q&A를 수행하려는 동료와 공유할 수 있도록 게시하기로 결정할 수 있습니다. 이 경우 다음 스크린샷에 나와 있듯이 게시를 선택합니다.

게시 옵션의 선택 영역을 보여 주는 스크린샷

이 스크린샷에 나와 있듯이 AI 기술에 대한 게시된 URL이 표시됩니다.

게시된 URL을 보여 주는 스크린샷

그러면 게시된 URL을 복사하여 Fabric Notebook에서 사용할 수 있습니다. 이러한 방식으로 Fabric Notebook에서 AI 기술 API를 호출하여 AI 기술을 쿼리할 수 있습니다. 복사한 URL을 이 코드 조각에 붙여 넣습니다. 그런 다음, 질문을 AI 기술과 관련된 쿼리로 바꿉다. 이 예제에서는 \<generic published URL value\>을(를) URL로 사용합니다.

%pip install "openai==1.14.1"
%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)