Öğretici: Azure OpenAI Hizmeti eklemelerini ve belge aramasını keşfetme

Bu öğreticide, en uygun belgeyi bulmak için bir bilgi bankası sorguladığınız belge araması gerçekleştirmek için Azure OpenAI ekleme API'sini kullanma konusunda size yol gösterilir.

Bu öğreticide aşağıdakilerin nasıl yapılacağını öğreneceksiniz:

  • Azure OpenAI'yi yükleyin.
  • Örnek veri kümesini indirin ve analize hazırlayın.
  • Kaynak uç noktanız ve API anahtarınız için ortam değişkenleri oluşturun.
  • Şu modellerden birini kullanın: text-embedding-ada-002 (Sürüm 2), text-embedding-3-large, text-embedding-3-small modelleri.
  • Arama sonuçlarını sıralamak için kosinüs benzerliğini kullanın.

Önkoşullar

Ayarlama

Python kitaplıkları

Henüz yüklemediyseniz aşağıdaki kitaplıkları yüklemeniz gerekir:

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

BillSum veri kümesini indirme

BillSum, Birleşik Devletler Kongre ve California eyalet faturalarının bir veri kümesidir. Çizim amacıyla yalnızca ABD faturalarına bakacağız. Korpus, Kongre'nin 103.-115. (1993-2018) oturumlarından gelen faturalardan oluşur. Veriler 18.949 tren faturasına ve 3.269 test faturasına ayrılmıştır. BillSum corpus 5.000 ila 20.000 karakter uzunluğunda orta uzunlukta mevzuata odaklanır. Bu veri kümesinin türetildiği proje ve özgün akademik makale hakkında daha fazla bilgi BillSum projesinin GitHub deposunda bulunabilir

Bu öğreticide bill_sum_data.csv GitHub örnek verilerimizden indirilebilen dosya kullanılır.

Yerel makinenizde aşağıdaki komutu çalıştırarak örnek verileri de indirebilirsiniz:

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

Anahtarı ve uç noktayı alma

Azure OpenAI'ye karşı başarılı bir şekilde çağrı yapmak için bir uç nokta ve anahtar gerekir.

Değişken adı Değer
ENDPOINT Hizmet uç noktası, Kaynağınızı Azure portalından incelerken Anahtarlar ve Uç Nokta bölümünde bulunabilir. Alternatif olarak, uç noktayı Azure AI Studio'daki Dağıtımlar sayfasında bulabilirsiniz. Örnek uç nokta: https://docs-test-001.openai.azure.com/.
API-KEY Bu değer, Azure portal kaynağınızı incelerken Anahtarlar ve Uç Nokta bölümünde bulunabilir. KEY1 veya KEY2 kullanabilirsiniz.

Azure portalında kaynağınıza gidin. Anahtarlar ve Uç Nokta bölümü Kaynak Yönetimi bölümünde bulunabilir. Api çağrılarınızın kimliğini doğrulamak için ihtiyacınız olacak şekilde uç noktanızı ve erişim anahtarınızı kopyalayın. KEY1 veya KEY2 kullanabilirsiniz. Her zaman iki anahtara sahip olmak, hizmet kesintisine neden olmadan anahtarları güvenli bir şekilde döndürmenize ve yeniden oluşturmanıza olanak tanır.

Azure portalında uç nokta ve erişim anahtarları konumu kırmızıyla daire içine alınmış bir Azure OpenAI kaynağının genel bakış kullanıcı arabiriminin ekran görüntüsü.

Ortam değişkenleri

Anahtarınız ve uç noktanız için kalıcı ortam değişkenleri oluşturun ve atayın.

Önemli

API anahtarı kullanıyorsanız, bunu Azure Key Vault gibi başka bir yerde güvenli bir şekilde depolayın. API anahtarını doğrudan kodunuzla eklemeyin ve hiçbir zaman herkese açık olarak göndermeyin.

Yapay zeka hizmetleri güvenliği hakkında daha fazla bilgi için bkz . Azure AI hizmetlerine yönelik isteklerin kimliğini doğrulama.

setx AZURE_OPENAI_API_KEY "REPLACE_WITH_YOUR_KEY_VALUE_HERE" 
setx AZURE_OPENAI_ENDPOINT "REPLACE_WITH_YOUR_ENDPOINT_HERE" 

Ortam değişkenlerini ayarladıktan sonra, ortam değişkenlerinin erişilebilir olması için Jupyter not defterlerini veya kullandığınız IDE'yi kapatıp yeniden açmanız gerekebilir. Jupyter Not Defterlerini kullanmanızı kesinlikle öneririz, ancak herhangi bir nedenle yapamazsanız, bir kod bloğunun sonunda genellikle olduğu gibi doğrudan çağırmak dataframe_name yerine kullanarak print(dataframe_name) pandas veri çerçevesi döndüren kodları değiştirmeniz gerekir.

Tercih ettiğiniz Python IDE'de aşağıdaki kodu çalıştırın:

Kitaplıkları içeri aktarma

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

Şimdi csv dosyamızı okumamız ve bir pandas DataFrame oluşturmamız gerekiyor. İlk DataFrame oluşturulduktan sonra komutunu çalıştırarak dftablonun içeriğini görüntüleyebiliriz.

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

Çıktı:

Csv dosyasındaki ilk DataFrame tablosu sonuçlarının ekran görüntüsü.

İlk tabloda ihtiyacımız olandan daha fazla sütun var, adlıdf_bills, yalnızca , summaryve titlesütunlarını textiçerecek yeni bir daha küçük DataFrame oluşturacağız.

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

Çıktı:

Yalnızca metin, özet ve başlık sütunlarının görüntülendiği daha küçük DataFrame tablosu sonuçlarının ekran görüntüsü.

Şimdi gereksiz boşlukları kaldırarak ve verileri belirteçleştirmeye hazırlamak için noktalama işaretlerini temizleyerek bazı hafif veri temizleme işlemleri gerçekleştireceğiz.

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

Şimdi belirteç sınırı (8192 belirteçleri) için çok uzun olan faturaları kaldırmamız gerekiyor.

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

Not

Bu durumda tüm faturalar ekleme modeli giriş belirteci sınırı altındadır, ancak ekleme işleminin başarısız olmasına neden olacak girişleri kaldırmak için yukarıdaki tekniği kullanabilirsiniz. Ekleme sınırını aşan içerikle karşılaştığınızda, içeriği daha küçük parçalara ayırabilir ve sonra bunları tek tek ekleyebilirsiniz.

Bir kez daha df_bills inceleyeceğiz.

df_bills

Çıktı:

dataframe'in n_tokens adlı yeni bir sütunla ekran görüntüsü.

n_tokens sütununu biraz daha anlamak ve metnin nasıl belirteç haline getirildiği hakkında bilgi edinmek için aşağıdaki kodu çalıştırmak yararlı olabilir:

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

Belgelerimiz için kasıtlı olarak çıkışı kesiyoruz, ancak bu komutu ortamınızda çalıştırmak sıfır dizinindeki tam metni öbekler halinde belirteçli olarak döndürür. Bazı durumlarda bir sözcüğün tamamının tek bir belirteçle temsil edilirken, diğer durumlarda sözcüklerin bazı bölümlerinin birden çok belirteç arasında bölündüğünü görebilirsiniz.

[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',

Ardından değişkenin uzunluğunu decode denetlerseniz, değişkenin n_tokens sütunundaki ilk sayıyla eşleşdiğini görürsünüz.

len(decode)
1466

Artık belirteç oluşturmanın nasıl çalıştığı hakkında daha fazla bilgi edindiğimize göre ekleme işlemine geçebiliriz. Belgeleri henüz belirteci oluşturmadığımıza dikkat etmek önemlidir. Sütun n_tokens yalnızca belirteç oluşturma ve ekleme için modele aktardığımız verilerin 8.192 giriş belirteci sınırını aşmamasını sağlamanın bir yoludur. Belgeleri ekleme modeline geçirdiğimizde, belgeler yukarıdaki örneklere benzer belirteçlere (aynı olmasa da) bölünür ve ardından belirteçleri vektör araması yoluyla erişilebilecek bir dizi kayan nokta numarasına dönüştürür. Bu eklemeler, Vektör Arama'yı desteklemek için yerel olarak veya Azure Veritabanı'nda depolanabilir. Sonuç olarak, her faturanın DataFrame'in sağ tarafındaki yeni ada_v2 sütuna kendi karşılık gelen ekleme vektörleri olur.

Aşağıdaki örnekte, eklemek istediğimiz her öğe için ekleme modelini bir kez çağırıyoruz. Büyük ekleme projeleriyle çalışırken, modele aynı anda bir giriş yerine eklemeye bir giriş dizisi geçirebilirsiniz. Modeli geçirdiğinizde, ekleme uç noktasına çağrı başına en fazla giriş öğesi sayısı 2048'dir.

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

Çıktı:

df_bills komutundan biçimlendirilmiş sonuçların ekran görüntüsü.

Aşağıdaki arama kodu bloğunu çalıştırdığımız için "Kablo şirketi vergi geliri hakkında bilgi alabilir miyim?" arama sorgusunu ekleyeceğiz. aynı text-embedding-ada-002 (Sürüm 2) modeliyle. Daha sonra sorgumuzdan yeni eklenen metne kosinüs benzerliğine göre derecelendirilen en yakın faturayı ekleyeceğiz.

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)

Çıktı:

Arama sorgusu çalıştırıldıktan sonra biçimlendirilmiş res sonuçlarının ekran görüntüsü.

Son olarak, tüm bilgi bankası kullanıcı sorgusunu temel alan belge aramasının en iyi sonucunu göstereceğiz. Bu, "Vergi mükellefinin 1993'ün Görüntüleme Hakkı Yasası"nın en üst sonucunu döndürür. Bu belgede sorgu ile belge arasında kosinüs benzerlik puanı 0,76'dır:

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."

Önkoşullar

  • Azure aboneliği - Ücretsiz bir abonelik oluşturun

  • Text-embedding-ada-002 (Sürüm 2) modelinin dağıtıldığı bir Azure OpenAI kaynağı.

    Bu model şu anda yalnızca belirli bölgelerde kullanılabilir. Kaynağınız yoksa, kaynak dağıtım kılavuzumuzda kaynak oluşturma işlemi belgelenmiştir.

  • PowerShell 7.4

Not

Bu öğreticideki birçok örnek, değişkenleri adım adım yeniden kullanır. Tüm oturum boyunca aynı terminal oturumunu açık tutun. Önceki adımda ayarladığınız değişkenler terminal kapatıldığında kaybolursa, baştan yeniden başlamanız gerekir.

Anahtarı ve uç noktayı alma

Azure OpenAI'ye karşı başarılı bir şekilde çağrı yapmak için bir uç nokta ve anahtar gerekir.

Değişken adı Değer
ENDPOINT Hizmet uç noktası, Kaynağınızı Azure portalından incelerken Anahtarlar ve Uç Nokta bölümünde bulunabilir. Alternatif olarak, uç noktayı Azure AI Studio'daki Dağıtımlar sayfasında bulabilirsiniz. Örnek uç nokta: https://docs-test-001.openai.azure.com/.
API-KEY Bu değer, Azure portal kaynağınızı incelerken Anahtarlar ve Uç Nokta bölümünde bulunabilir. KEY1 veya KEY2 kullanabilirsiniz.

Azure portalında kaynağınıza gidin. Anahtarlar ve Uç Nokta bölümü Kaynak Yönetimi bölümünde bulunabilir. Api çağrılarınızın kimliğini doğrulamak için ihtiyacınız olacak şekilde uç noktanızı ve erişim anahtarınızı kopyalayın. KEY1 veya KEY2 kullanabilirsiniz. Her zaman iki anahtara sahip olmak, hizmet kesintisine neden olmadan anahtarları güvenli bir şekilde döndürmenize ve yeniden oluşturmanıza olanak tanır.

Azure portalında uç nokta ve erişim anahtarları konumu kırmızıyla daire içine alınmış bir Azure OpenAI kaynağının genel bakış kullanıcı arabiriminin ekran görüntüsü.

Ortam değişkenleri

Anahtarınız ve uç noktanız için kalıcı ortam değişkenleri oluşturun ve atayın.

Önemli

API anahtarı kullanıyorsanız, bunu Azure Key Vault gibi başka bir yerde güvenli bir şekilde depolayın. API anahtarını doğrudan kodunuzla eklemeyin ve hiçbir zaman herkese açık olarak göndermeyin.

Yapay zeka hizmetleri güvenliği hakkında daha fazla bilgi için bkz . Azure AI hizmetlerine yönelik isteklerin kimliğini doğrulama.

setx AZURE_OPENAI_API_KEY "REPLACE_WITH_YOUR_KEY_VALUE_HERE" 
setx AZURE_OPENAI_ENDPOINT "REPLACE_WITH_YOUR_ENDPOINT_HERE" 

Bu öğreticide, iyi bilinen ve güvenli bir örnek veri kümesi olarak PowerShell 7.4 başvuru belgelerini kullanırız. Alternatif olarak, Microsoft Research araçları örnek veri kümelerini keşfetmeyi seçebilirsiniz.

Projenizi depolamak istediğiniz bir klasör oluşturun. Konumunuzu proje klasörüne ayarlayın. komutunu kullanarak Invoke-WebRequest veri kümesini yerel makinenize indirin ve ardından arşivi genişletin. Son olarak, powershell sürüm 7.4 için başvuru bilgilerini içeren alt klasöre konumunuzu ayarlayın.

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/'

Bu öğreticide büyük miktarda veriyle çalışıyoruz, bu nedenle verimli performans için bir .NET veri tablosu nesnesi kullanıyoruz. Veri tablosunun sütun başlığı, içeriği, hazırlığı, uri'sini, dosyasını ve vektörlerini vardır. Başlık sütunu birincil anahtardır.

Sonraki adımda, her markdown dosyasının içeriğini veri tablosuna yükleyeceğiz. Ayrıca powershell -match işlecini kullanarak bilinen metin title: satırlarını ve online version:değerlerini yakalayıp bunları ayrı sütunlarda depolarız. Bazı dosyalar metin meta veri satırlarını içermez, ancak bunlar genel bakış sayfaları olduğundan ve ayrıntılı başvuru belgeleri olmadığından, bunları veri tablosundan dışlarız.

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

komutunu kullanarak out-gridview verileri görüntüleyin (Cloud Shell'de kullanılamaz).

$Datatable | out-gridview

Çıktı:

İlk DataTable sonuçlarının ekran görüntüsü.

Daha sonra, verileri belirteçleştirmeye hazırlamak için fazladan karakter, boş alan ve diğer belge gösterimini kaldırarak bazı basit veri temizleme işlemleri gerçekleştirin. Örnek işlev Invoke-DocPrep , powershell -replace işlecini kullanarak içerikten kaldırmak istediğiniz karakterlerin listesini yinelemeyi gösterir.

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

İşlevi Invoke-DocPrep oluşturduktan sonra, hazır içeriği veri tablosundaki tüm satırlar için hazırlık sütununda depolamak için komutunu kullanınForEach-Object. Daha sonra almak istersek özgün biçimlendirmenin kullanılabilir olması için yeni bir sütun kullanıyoruz.

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

Değişikliği görmek için veri tablolarını yeniden görüntüleyin.

$Datatable | out-gridview

Belgeleri ekleme modeline geçirdiğimizde, belgeleri belirteçlere kodlar ve sonra kosinüs benzerliği aramasında kullanmak üzere bir dizi kayan nokta numarası döndürür. Bu eklemeler yerel olarak veya Azure AI Search'te Vektör Arama gibi bir hizmette depolanabilir. Her belgenin yeni vektörler sütununda kendi ekleme vektörleri vardır .

Sonraki örnek, veri tablosundaki her satırda döngü oluşturur, önceden işlenmiş içeriğin vektörlerini alır ve bunları vectors sütununa depolar . OpenAI hizmeti sık istekleri kısıtlar, bu nedenle örnekte belgelerde önerilen üstel bir geri alma bulunur.

Betik tamamlandıktan sonra, her satırda her belge için 1536 vektörden oluşan virgülle ayrılmış bir liste olmalıdır. Bir hata oluşursa ve durum kodu ise 400, dosya yolu, başlık ve hata kodu sorun giderme için adlı $errorDocs bir değişkene eklenir. En yaygın hata, belirteç sayısı model için istem sınırından fazla olduğunda oluşur.

# 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."
}

Artık PowerShell 7.4 başvuru belgelerini içeren yerel bir bellek içi veritabanı tablonuz var.

Bir arama dizesini temel alarak PowerShell'in her belgeyi benzerliğe göre derecelemesi için başka bir vektör kümesi hesaplamamız gerekir.

Sonraki örnekte, arama dizesi get a list of running processesiçin vektörler alınır.

$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 ','

Son olarak, Lee Holmes tarafından yazılan Measure-VectorSimilarity örnek betiğinden bir örnek alan sonraki örnek işlev, kosinüs benzerlik hesaplaması yapar ve ardından veri tablosundaki her satırı dereceler.

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

Sonraki örnekteki komutlar içindeki tüm satırlar $Datatable arasında döngü oluşturur ve arama dizesine kosinüs benzerliğini hesaplar. Sonuçlar sıralanır ve ilk üç sonuç adlı $topThreebir değişkende depolanır. Örnek çıkış döndürmez.

# 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'da yalnızca başlık ve url özellikleriyle değişkenin $topThree çıkışını gözden geçirin.

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

Çıktı:

Arama sorgusu tamamlandıktan sonra biçimlendirilmiş sonuçların ekran görüntüsü.

değişkeni, $topThree veri tablosundaki satırlardaki tüm bilgileri içerir. Örneğin, içerik özelliği özgün belge biçimini içerir. Dizideki ilk öğeye dizin oluşturmak için kullanın [0] .

$topThree[0].content

Belgenin tamamını görüntüleyin (bu sayfanın çıkış parçacığında kesilmiş).

---
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://video2.skills-academy.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

Son olarak, veri kümesini her sorgulamanız gerektiğinde eklemeleri yeniden oluşturmak yerine, verileri diske depolayabilir ve gelecekte geri çağırabilirsiniz. WriteXML() Sonraki örnekteki DataTable nesne türlerinin ve ReadXML() yöntemleri işlemi basitleştirir. XML dosyasının şeması, veri tablosunun TableName'e sahip olmasını gerektirir.

değerini, XML dosyasını yazmak ve okumak istediğiniz tam yolla değiştirin <YOUR-FULL-FILE-PATH> . Yol ile .xmlbitmelidir.

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

Verileri yeniden kullandığınızda, her yeni arama dizesinin vektörlerini almanız gerekir (ancak veri tablolarının tamamını almalısınız). Öğrenme alıştırması olarak, arama dizesini parametre olarak kullanarak komutu otomatikleştirmek Invoke-RestMethod için bir PowerShell betiği oluşturmayı deneyin.

Bu yaklaşımı kullanarak, bilgi bankası belgeler arasında arama mekanizması olarak eklemeleri kullanabilirsiniz. Kullanıcı daha sonra en üstteki arama sonucunu alabilir ve ilk sorgusunu soran aşağı akış görevi için kullanabilir.

Kaynakları temizleme

Yalnızca bu öğreticiyi tamamlamak için bir Azure OpenAI kaynağı oluşturduysanız ve bir Azure OpenAI kaynağını temizlemek ve kaldırmak istiyorsanız, dağıtılan modellerinizi silmeniz ve ardından test kaynağınıza ayrılmışsa kaynağı veya ilişkili kaynak grubunu silmeniz gerekir. Kaynak grubunun silinmesi, kaynak grubuyla ilişkili diğer tüm kaynakları da siler.

Sonraki adımlar

Azure OpenAI modelleri hakkında daha fazla bilgi edinin: