共用方式為


教學課程: 探索 Azure OpenAI 服務內嵌和文件搜尋

本教學課程將逐步引導您使用 Azure OpenAI 內嵌API 來執行文件搜尋,您將在其中查詢知識庫以尋找最相關的文件。

在本教學課程中,您會了解如何:

  • 安裝 Azure OpenAI。
  • 下載樣本資料集並準備進行分析。
  • 為您的資源端點和 API 金鑰建立環境變數。
  • 使用 text-embedding-ada-002 (第 2 版) 模型
  • 使用 餘弦相似度 來排名搜尋結果。

必要條件

設定

Python 程式庫

如果您尚未安裝,您需要安裝下列程式庫:

pip install openai num2words matplotlib plotly scipy scikit-learn pandas tiktoken

下載 BillSum 資料集

BillSum 是美國國會和加利福尼亞州法案的資料集。 出於說明目的,我們只會查看美國的法案。 主體包含來自第 103 屆到第 115 屆 (1993-2018 年)國會議會的法案。 資料分割成 18,949 個訓練法案和 3,269 個測試法案。 BillSum 主體專注在長度從 5,000 到 20,000 個字元的中長度法規。 您可以在 BillSum 專案的 GitHub 存放庫找到此資料集衍生自的專案和原始學術檔的詳細資訊

本教學課程會使用 bill_sum_data.csv 檔案,您可以從 GitHub 範例資料下載這個檔案。

您也可以在本機電腦上執行下列命令來下載範例資料:

curl "https://raw.githubusercontent.com/Azure-Samples/Azure-OpenAI-Docs-Samples/main/Samples/Tutorials/Embeddings/data/bill_sum_data.csv" --output bill_sum_data.csv

擷取金鑰和端點

若要成功對 Azure OpenAI 進行呼叫,您需要端點金鑰

變數名稱
ENDPOINT 從 Azure 入口網站查看您的資源時,可以在 [金鑰與端點] 區段中找到此值。 或者,您可以在 [Azure OpenAI Studio]>[遊樂場]>[程式碼檢視] 中找到該值。 範例端點為:https://docs-test-001.openai.azure.com/
API-KEY 從 Azure 入口網站查看您的資源時,可以在 [金鑰與端點] 區段中找到此值。 您可以使用 KEY1KEY2

移至您在 Azure 入口網站中的資源。 您可以在 [資源管理] 區段中找到 [金鑰和端點] 區段。 複製您的端點和存取金鑰,因為您需要這兩者才能驗證 API 呼叫。 您可以使用 KEY1KEY2。 隨時持有兩個金鑰可讓您安全地輪替和重新產生金鑰,而不會造成服務中斷。

Azure 入口網站中某個 Azure OpenAI 資源,以紅色圓圈強調端點和存取金鑰位置的概觀使用者介面螢幕擷取畫面。

環境變數

setx AZURE_OPENAI_API_KEY "REPLACE_WITH_YOUR_KEY_VALUE_HERE" 
setx AZURE_OPENAI_ENDPOINT "REPLACE_WITH_YOUR_ENDPOINT_HERE" 

設定環境變數之後,您可能需要關閉並重新開啟 Jupyter 筆記本,或您使用的任何整合式開發環境 (IDE),才能存取環境變數。 雖然我們強烈建議使用 Jupyter 筆記本,但如果您因為某些原因而無法修改任何使用 print(dataframe_name) 傳回 Pandas DataFrame 的程式碼,而不是像在程式碼區塊結尾一樣,直接呼叫 dataframe_name

在慣用的 Python 整合式開發環境中執行下列程式碼:

匯入程式庫

import os
import re
import requests
import sys
from num2words import num2words
import os
import pandas as pd
import numpy as np
import tiktoken
from openai import AzureOpenAI

現在我們需要讀取 CSV 檔案,並建立 pandas 資料框架。 建立初始資料框架之後,我們可以執行 df 來檢視資料表的內容。

df=pd.read_csv(os.path.join(os.getcwd(),'bill_sum_data.csv')) # This assumes that you have placed the bill_sum_data.csv in the same directory you are running Jupyter Notebooks
df

輸出:

來自 CSV 檔案初始資料框架資料表結果的螢幕擷取畫面。

初始資料表的資料行數目超過我們需要的資料行,我們會建立名為 df_bills 的新小型資料框架,其只會包含 textsummarytitle 資料行。

df_bills = df[['text', 'summary', 'title']]
df_bills

輸出:

只有顯示文字、摘要和標題資料行的小型資料框架資料表結果的螢幕擷取畫面。

接下來,我們將藉由移除備援空白字元並清除標點符號來準備資料以進行 Token 化,以執行一些簡單的資料清除。

pd.options.mode.chained_assignment = None #https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#evaluation-order-matters

# s is input text
def normalize_text(s, sep_token = " \n "):
    s = re.sub(r'\s+',  ' ', s).strip()
    s = re.sub(r". ,","",s)
    # remove all instances of multiple spaces
    s = s.replace("..",".")
    s = s.replace(". .",".")
    s = s.replace("\n", "")
    s = s.strip()
    
    return s

df_bills['text']= df_bills["text"].apply(lambda x : normalize_text(x))

現在,我們需要移除超過語彙基元限制 (8192 個語彙基元) 的任何法案。

tokenizer = tiktoken.get_encoding("cl100k_base")
df_bills['n_tokens'] = df_bills["text"].apply(lambda x: len(tokenizer.encode(x)))
df_bills = df_bills[df_bills.n_tokens<8192]
len(df_bills)
20

注意

在此情況下,所有法案都在內嵌模型輸入語彙基元限制下,但您可以使用上述技術來移除會導致內嵌失敗的專案。 當面臨超過內嵌限制的內容時,您也可以將內容區塊化成較小的片段,然後一次內嵌一個。

我們會再次檢查 df_bills

df_bills

輸出:

有名叫 n_tokens 新資料行的資料框架的螢幕擷取畫面。

若要深入瞭解 n_tokens 資料行,以及文字最終如何Token 化,執行下列程式碼會很有幫助:

sample_encode = tokenizer.encode(df_bills.text[0]) 
decode = tokenizer.decode_tokens_bytes(sample_encode)
decode

針對我們的文件,我們會刻意截斷輸出,但在您的環境中執行此命令,將會從索引零 Token 化為區塊傳回全文檢索。 在某些情況下,整個字組會以單一語彙基元來表示,而字組的其他部分則會被分割成多個語彙基元。

[b'SECTION',
 b' ',
 b'1',
 b'.',
 b' SHORT',
 b' TITLE',
 b'.',
 b' This',
 b' Act',
 b' may',
 b' be',
 b' cited',
 b' as',
 b' the',
 b' ``',
 b'National',
 b' Science',
 b' Education',
 b' Tax',
 b' In',
 b'cent',
 b'ive',
 b' for',
 b' Businesses',
 b' Act',
 b' of',
 b' ',
 b'200',
 b'7',
 b"''.",
 b' SEC',
 b'.',
 b' ',
 b'2',
 b'.',
 b' C',
 b'RED',
 b'ITS',
 b' FOR',
 b' CERT',
 b'AIN',
 b' CONTRIBUT',
 b'IONS',
 b' BEN',
 b'EF',
 b'IT',
 b'ING',
 b' SC',

如果您接著檢查 decode 變數的長度,您會發現它符合n_tokens 資料行中的第一個數字。

len(decode)
1466

既然我們已深入了解 Token 化的運作方式,我們可以繼續進行內嵌。 請務必注意,我們尚未實際將文件權杖化。 n_tokens 資料行只是一種確保我們傳遞至模型以進行 Token 化和內嵌的資料超出了輸入語彙基元限制 8,192 的方法。 當我們將文件傳遞至內嵌模型時,它會將文件分成類似上述範例的語彙基元 (但不一定完全相同),然後將語彙基元轉換成可透過向量搜尋存取的一系列浮點數。 這些內嵌可以儲存在本機或 Azure 資料庫,以支援向量搜尋。 因此,每個法案在 DataFrame 右側的新 ada_v2 資料行中都會有自己的對應內嵌向量。

在下列範例,我們會根據想要內嵌的每個項目呼叫一次內嵌模型。 處理大型內嵌專案時,您也可以向模型傳遞一個陣列要內嵌的輸入內容,而不是一次內嵌一個。 向模型傳遞一個陣列的輸入內容時,每次呼叫至內嵌端點的輸入項目數目上限為 2048。

client = AzureOpenAI(
  api_key = os.getenv("AZURE_OPENAI_API_KEY"),  
  api_version = "2024-02-01",
  azure_endpoint = os.getenv("AZURE_OPENAI_ENDPOINT")
)

def generate_embeddings(text, model="text-embedding-ada-002"): # model = "deployment_name"
    return client.embeddings.create(input = [text], model=model).data[0].embedding

df_bills['ada_v2'] = df_bills["text"].apply(lambda x : generate_embeddings (x, model = 'text-embedding-ada-002')) # model should be set to the deployment name you chose when you deployed the text-embedding-ada-002 (Version 2) model
df_bills

輸出:

來自 df_bills 命令的格式化結果的螢幕擷取畫面。

當我們執行下方的搜尋程式碼區塊時,我們將內嵌搜尋查詢 「我是否可以取得有線電視公司稅收收入的相關資訊?」 並使用相同的 text-embedding-ada-002 (第 2 版) 模型。 接下來,我們會在依餘弦相似度排名的查詢中找到最接近新內嵌文字的法案內嵌。

def cosine_similarity(a, b):
    return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))

def get_embedding(text, model="text-embedding-ada-002"): # model = "deployment_name"
    return client.embeddings.create(input = [text], model=model).data[0].embedding

def search_docs(df, user_query, top_n=4, to_print=True):
    embedding = get_embedding(
        user_query,
        model="text-embedding-ada-002" # model should be set to the deployment name you chose when you deployed the text-embedding-ada-002 (Version 2) model
    )
    df["similarities"] = df.ada_v2.apply(lambda x: cosine_similarity(x, embedding))

    res = (
        df.sort_values("similarities", ascending=False)
        .head(top_n)
    )
    if to_print:
        display(res)
    return res


res = search_docs(df_bills, "Can I get information on cable company tax revenue?", top_n=4)

輸出:

執行搜尋查詢之後,res 格式化結果的螢幕擷取畫面。

最後,我們會根據針對整個知識庫的使用者查詢,顯示文件搜尋的首選結果。 這會傳回「1993 年納稅人檢視權法案」的首選結果。 本文件在查詢與文件之間具有 0.76 的餘弦相似度分數:

res["summary"][9]
"Taxpayer's Right to View Act of 1993 - Amends the Communications Act of 1934 to prohibit a cable operator from assessing separate charges for any video programming of a sporting, theatrical, or other entertainment event if that event is performed at a facility constructed, renovated, or maintained with tax revenues or by an organization that receives public financial support. Authorizes the Federal Communications Commission and local franchising authorities to make determinations concerning the applicability of such prohibition. Sets forth conditions under which a facility is considered to have been constructed, maintained, or renovated with tax revenues. Considers events performed by nonprofit or public organizations that receive tax subsidies to be subject to this Act if the event is sponsored by, or includes the participation of a team that is part of, a tax exempt organization."

必要條件

注意

本教學課程很多範例會在不同步驟重複使用變數。 讓同一個終端機工作階段全程保持開啟。 如果在上一個步驟設定的變數因關閉終端機而遺失,您必須從頭開始。

擷取金鑰和端點

若要成功對 Azure OpenAI 進行呼叫,您需要端點金鑰

變數名稱
ENDPOINT 從 Azure 入口網站查看您的資源時,可以在 [金鑰與端點] 區段中找到此值。 或者,您可以在 [Azure OpenAI Studio]>[遊樂場]>[程式碼檢視] 中找到該值。 範例端點為:https://docs-test-001.openai.azure.com/
API-KEY 從 Azure 入口網站查看您的資源時,可以在 [金鑰與端點] 區段中找到此值。 您可以使用 KEY1KEY2

移至您在 Azure 入口網站中的資源。 您可以在 [資源管理] 區段中找到 [金鑰和端點] 區段。 複製您的端點和存取金鑰,因為您需要這兩者才能驗證 API 呼叫。 您可以使用 KEY1KEY2。 隨時持有兩個金鑰可讓您安全地輪替和重新產生金鑰,而不會造成服務中斷。

Azure 入口網站中某個 Azure OpenAI 資源,以紅色圓圈強調端點和存取金鑰位置的概觀使用者介面螢幕擷取畫面。

為您的金鑰和端點建立及指派永續性環境變數。

環境變數

setx AZURE_OPENAI_API_KEY "REPLACE_WITH_YOUR_KEY_VALUE_HERE" 
setx AZURE_OPENAI_ENDPOINT "REPLACE_WITH_YOUR_ENDPOINT_HERE" 

在本教學課程,我們使用 PowerShell 7.4 參考文件,作為熟悉且安全的樣本資料集。 或者,您可以選擇探索 Microsoft Research 工具樣本資料集。

建立您要儲存專案的資料夾。 將位置設定為專案資料夾。 使用 Invoke-WebRequest 命令將資料集下載至本機電腦,然後展開封存。 最後,將位置設定為包含 PowerShell 7.4 版參考資訊的子資料夾。

New-Item '<FILE-PATH-TO-YOUR-PROJECT>' -Type Directory
Set-Location '<FILE-PATH-TO-YOUR-PROJECT>'

$DocsUri = 'https://github.com/MicrosoftDocs/PowerShell-Docs/archive/refs/heads/main.zip'
Invoke-WebRequest $DocsUri -OutFile './PSDocs.zip'

Expand-Archive './PSDocs.zip'
Set-Location './PSDocs/PowerShell-Docs-main/reference/7.4/'

在本教學課程我們處理了大量資料,因此會使用 .NET 運算列表物件實現高效的效能。 運算列表有資料行標題內容準備uri檔案,以及向量標題資料行是主索引鍵

在下一個步驟,我們會將每個 Markdown 檔案的內容載入運算列表。 我們也使用 PowerShell -match 運算子擷取已知的文字行 title:online version:,並將其儲存在不同的資料行。 有些檔案不包含文字的中繼資料行,但由於它們是概觀頁面,而不是詳細的參考文件,因此我們會將它們從運算列表排除。

# make sure your location is the project subfolder

$DataTable = New-Object System.Data.DataTable

'title', 'content', 'prep', 'uri', 'file', 'vectors' | ForEach-Object {
    $DataTable.Columns.Add($_)
} | Out-Null
$DataTable.PrimaryKey = $DataTable.Columns['title']

$md = Get-ChildItem -Path . -Include *.md -Recurse

$md | ForEach-Object {
    $file       = $_.FullName
    $content    = Get-Content $file
    $title      = $content | Where-Object { $_ -match 'title: ' }
    $uri        = $content | Where-Object { $_ -match 'online version: ' }
    if ($title -and $uri) {
        $row                = $DataTable.NewRow()
        $row.title          = $title.ToString().Replace('title: ', '')
        $row.content        = $content | Out-String
        $row.prep           = '' # use later in the tutorial
        $row.uri            = $uri.ToString().Replace('online version: ', '')
        $row.file           = $file
        $row.vectors        = '' # use later in the tutorial
        $Datatable.rows.add($row)
    }
}

使用 out-gridview 命令檢視資料 (在 Cloud Shell 無法使用)。

$Datatable | out-gridview

輸出:

初始 DataTable 結果的螢幕擷取畫面。

接下來,移除額外的字元、空格和其他文件表示法,準備要權杖化的資料。 範例函數 Invoke-DocPrep 示範,如何使用 PowerShell -replace 運算子逐一查看您想從內容移除的字元清單。

# sample demonstrates how to use `-replace` to remove characters from text content
function Invoke-DocPrep {
param(
    [Parameter(Mandatory = $true, ValueFromPipeline = $true)]
    [string]$content
)
    # tab, line breaks, empty space
    $replace = @('\t','\r\n','\n','\r')
    # non-UTF8 characters
    $replace += @('[^\x00-\x7F]')
    # html
    $replace += @('<table>','</table>','<tr>','</tr>','<td>','</td>')
    $replace += @('<ul>','</ul>','<li>','</li>')
    $replace += @('<p>','</p>','<br>')
    # docs
    $replace += @('\*\*IMPORTANT:\*\*','\*\*NOTE:\*\*')
    $replace += @('<!','no-loc ','text=')
    $replace += @('<--','-->','---','--',':::')
    # markdown
    $replace += @('###','##','#','```')
    $replace | ForEach-Object {
        $content = $content -replace $_, ' ' -replace '  ',' '
    }
    return $content
}

建立 Invoke-DocPrep 函數之後,請使用 ForEach-Object 命令,針對資料表中所有資料列,將備妥的內容儲存於準備資料行。 我們使用的是新的資料行,因此,如果稍後想要擷取,可以使用原始格式設定。

$Datatable.rows | ForEach-Object { $_.prep = Invoke-DocPrep $_.content }

再次檢視資料表,查看變更。

$Datatable | out-gridview

將文件傳遞至內嵌模型時,它會將文件編碼成權杖,然後傳回一系列的浮點數,用於餘弦相似性搜尋。 這些內嵌可以儲存在本機或服務,例如 Azure AI 搜尋中的向量搜尋。 每個文件在新的向量資料行,都有自己的對應內嵌向量。

下一個範例會輪流查看資料表中的每一個資料列、擷取前置處理內容的向量,並將其儲存至向量資料行。 OpenAI 服務會節流頻繁的要求,因此此範例包含指數輪詢,如文件所建議。

指令碼完成之後,每個資料列都應該有每個文件之 1536 個向量的逗號分隔清單。 如果發生錯誤,且狀態代碼為 400,則會將檔案路徑、標題和錯誤碼新增至名為 $errorDocs 的變數進行疑難排解。 權杖計數超過模型的提示限制時,會發生最常見的錯誤。

# Azure OpenAI metadata variables
$openai = @{
    api_key     = $Env:AZURE_OPENAI_API_KEY 
    api_base    = $Env:AZURE_OPENAI_ENDPOINT # should look like 'https://<YOUR_RESOURCE_NAME>.openai.azure.com/'
    api_version = '2024-02-01' # may change in the future
    name        = $Env:AZURE_OPENAI_EMBEDDINGS_DEPLOYMENT # custom name you chose for your deployment
}

$headers = [ordered]@{
    'api-key' = $openai.api_key
}

$url = "$($openai.api_base)/openai/deployments/$($openai.name)/embeddings?api-version=$($openai.api_version)"

$Datatable | ForEach-Object {
    $doc = $_

    $body = [ordered]@{
        input = $doc.prep
    } | ConvertTo-Json

    $retryCount = 0
    $maxRetries = 10
    $delay      = 1
    $docErrors = @()

    do {
        try {
            $params = @{
                Uri         = $url
                Headers     = $headers
                Body        = $body
                Method      = 'Post'
                ContentType = 'application/json'
            }
            $response = Invoke-RestMethod @params
            $Datatable.rows.find($doc.title).vectors = $response.data.embedding -join ','
            break
        } catch {
            if ($_.Exception.Response.StatusCode -eq 429) {
                $retryCount++
                [int]$retryAfter = $_.Exception.Response.Headers |
                    Where-Object key -eq 'Retry-After' |
                    Select-Object -ExpandProperty Value

                # Use delay from error header
                if ($delay -lt $retryAfter) { $delay = $retryAfter++ }
                Start-Sleep -Seconds $delay
                # Exponential back-off
                $delay = [math]::min($delay * 1.5, 300)
            } elseif ($_.Exception.Response.StatusCode -eq 400) {
                if ($docErrors.file -notcontains $doc.file) {
                    $docErrors += [ordered]@{
                        error   = $_.exception.ErrorDetails.Message | ForEach-Object error | ForEach-Object message
                        file    = $doc.file
                        title   = $doc.title
                    }
                }
            } else {
                throw
            }
        }
    } while ($retryCount -lt $maxRetries)
}
if (0 -lt $docErrors.count) {
    Write-Host "$($docErrors.count) documents encountered known errors such as too many tokens.`nReview the `$docErrors variable for details."
}

您現在有 PowerShell 7.4 參考文件的本機記憶體內部資料庫資料表了。

根據搜尋字串,我們必須計算另一組向量,PowerShell 才能依相似度排名每份文件。

下一個範例會擷取搜尋字串 get a list of running processes 的向量。

$searchText = "get a list of running processes"

$body = [ordered]@{
    input = $searchText
} | ConvertTo-Json

$url = "$($openai.api_base)/openai/deployments/$($openai.name)/embeddings?api-version=$($openai.api_version)"

$params = @{
    Uri         = $url
    Headers     = $headers
    Body        = $body
    Method      = 'Post'
    ContentType = 'application/json'
}
$response = Invoke-RestMethod @params
$searchVectors = $response.data.embedding -join ','

最後,下一個範例函數會借用範例指令碼的範例,Lee Holmes 撰寫的 Measure-VectorSimilarity,執行餘弦相似度計算,然後對資料表中的每一個資料列進行排名。

# Sample function to calculate cosine similarity
function Get-CosineSimilarity ([float[]]$vector1, [float[]]$vector2) {
    $dot = 0
    $mag1 = 0
    $mag2 = 0

    $allkeys = 0..($vector1.Length-1)

    foreach ($key in $allkeys) {
        $dot  += $vector1[$key]  * $vector2[$key]
        $mag1 += ($vector1[$key] * $vector1[$key])
        $mag2 += ($vector2[$key] * $vector2[$key])
    }

    $mag1 = [Math]::Sqrt($mag1)
    $mag2 = [Math]::Sqrt($mag2)

    return [Math]::Round($dot / ($mag1 * $mag2), 3)
}

下一個範例的命令會輪流查看 $Datatable 中的所有資料列,並計算搜尋字串的餘弦相似度。 結果會排序,前三筆結果會儲存於名為 $topThree 的變數。 此範例不會傳回輸出。

# Calculate cosine similarity for each row and select the top 3
$topThree = $Datatable | ForEach-Object {
    [PSCustomObject]@{
        title = $_.title
        similarity = Get-CosineSimilarity $_.vectors.split(',') $searchVectors.split(',')
    }
} | Sort-Object -property similarity -descending | Select-Object -First 3 | ForEach-Object {
    $title = $_.title
    $Datatable | Where-Object { $_.title -eq $title }
}

在 gridview 中,檢閱 $topThree 變數的輸出,內容只有標題url 屬性。

$topThree | Select "title", "uri" | Out-GridView

輸出:

搜尋查詢完成後格式化結果的螢幕擷取畫面。

$topThree 變數包含資料表中資料列的所有資訊。 例如,內容屬性包含原始文件格式。 使用 [0] 索引至陣列中第一個項目。

$topThree[0].content

檢視完整文件 (在本頁面的輸出程式碼片段遭到截斷)。

---
external help file: Microsoft.PowerShell.Commands.Management.dll-Help.xml
Locale: en-US
Module Name: Microsoft.PowerShell.Management
ms.date: 07/03/2023
online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.management/get-process?view=powershell-7.4&WT.mc_id=ps-gethelp
schema: 2.0.0
title: Get-Process
---

# Get-Process

## SYNOPSIS
Gets the processes that are running on the local computer.

## SYNTAX

### Name (Default)

Get-Process [[-Name] <String[]>] [-Module] [-FileVersionInfo] [<CommonParameters>]
# truncated example

最後,您不必每次查詢資料集時都重新產生內嵌,大可將資料儲存至磁碟,以便未來重新叫用。 下一個範例中,DataTable 物件類型的 WriteXML()ReadXML() 方法會簡化此流程。 XML 檔案的結構描述需要資料表有 TableName

以您想要寫入和讀取 XML 檔案的完整路徑取代 <YOUR-FULL-FILE-PATH>。 路徑結尾應為 .xml

# Set DataTable name
$Datatable.TableName = "MyDataTable"

# Writing DataTable to XML
$Datatable.WriteXml("<YOUR-FULL-FILE-PATH>", [System.Data.XmlWriteMode]::WriteSchema)

# Reading XML back to DataTable
$newDatatable = New-Object System.Data.DataTable
$newDatatable.ReadXml("<YOUR-FULL-FILE-PATH>")

重複使用資料時,必須取得每個新搜尋字串的向量 (但不是整份資料表)。 學習時,不妨練習嘗試建立 PowerShell 指令碼,使用搜尋字串做為參數,將 Invoke-RestMethod 命令自動化。

使用這種方法,您可以使用內嵌作為知識庫中文件之間的搜尋機制。 然後,使用者可以取得首選的搜尋結果,並將其用於自己的下游工作,以提示其初始查詢。

清除資源

如果建立 Azure OpenAI 資源單純是為了完成本教學課程,而且想清除並移除 Azure OpenAI 資源,您必須刪除已部署的模型,然後在測試資源專用時刪除資源或相關聯的資源群組。 刪除資源群組也會刪除與其相關聯的任何其他資源。

下一步

深入了解 Azure OpenAI 模型: