Aracılığıyla paylaş


Semantik Çekirdek Vektör Depoları nelerdir? (Önizleme)

Uyarı

Semantik Çekirdek Vektör Deposu işlevselliği, RC aşamasındadır ve sürümden önce sınırlı durumlarda, mevcut işlevselliği bozabilecek değişiklikler gerektiren iyileştirmeler yine de yapılabilir.

Uyarı

Semantik Çekirdek Vektör Deposu işlevselliği önizleme aşamasındadır ve hataya neden olan değişiklikler gerektiren iyileştirmeler, sürümden önce sınırlı koşullarda yine de gerçekleşebilir.

İpucu

Eski Bellek Deposu bağlayıcıları hakkında bilgi arıyorsanız Bellek Depoları sayfasına bakın.

Vektör veritabanlarında, doğal dil işleme (NLP), görüntü işleme (CV), öneri sistemleri (RS) ve verilerin anlamsal olarak anlaşılmasını ve eşleşmesini gerektiren diğer alanları içeren farklı etki alanları ve uygulamalar arasında birçok kullanım örneği vardır.

Bilgileri vektör veritabanında depolamak için kullanılan bir kullanım örneği, büyük dil modellerinin (LLM) daha ilgili ve tutarlı yanıtlar oluşturmasını sağlamaktır. Büyük dil modelleri genellikle yanlış veya ilgisiz bilgiler üretmek, olgusal tutarlılık veya sağduyu eksikliği göstermek, kendilerini tekrarlamak veya çelişmek, taraflı veya saldırgan olmak gibi zorluklarla karşılaşır. Bu zorlukların üstesinden gelmeye yardımcı olmak için vektör veritabanını kullanarak istediğiniz etki alanı veya tarzla ilgili farklı konular, anahtar sözcükler, olgular, görüşler ve/veya kaynaklar hakkındaki bilgileri depolayabilirsiniz. Vektör veritabanı, belirli bir soru veya konuyla ilgili bilgilerin alt kümesini verimli bir şekilde bulmanıza olanak tanır. Ardından, daha doğru ve ilgili içerik oluşturmak için bilgi isteminizle vektör veritabanından büyük dil modelinize bilgi geçirebilirsiniz.

Örneğin, yapay zekadaki en son eğilimler hakkında bir blog gönderisi yazmak istiyorsanız, bir vektör veritabanı kullanarak bu konu hakkındaki en son bilgileri depolayabilir ve en son bilgilerden yararlanan bir blog gönderisi oluşturmak için bilgileri bir LLM'ye iletebilirsiniz.

Semantik Çekirdek ve .net, Vektör Depoları ile etkileşime yönelik bir soyutlama ve çeşitli veritabanları için bu soyutlamaları uygulayan kullanıma hazır uygulamaların listesini sağlar. Özellikler arasında kayıt koleksiyonları oluşturma, listeleme ve silme, kayıtları karşıya yükleme, alma ve silme sayılabilir. Soyutlama, ücretsiz veya yerel olarak barındırılan bir Vektör Deposu ile denemeler yapmanızı ve ölçeği artırmanız gerektiğinde bir hizmete geçmeyi kolaylaştırır.

Hazır uygulamalar, Anlam Çekirdeği ile kullanılabilir, ancak çekirdek yığına bağımlı değildir ve gerekirse tamamen bağımsız olarak da kullanılabilir. Semantik Çekirdek tarafından sağlanan imlementasyonlar 'bağlayıcılar' olarak adlandırılır.

Vektör Depoları ile Artırılmış Nesil (RAG) Alma

Vektör deposu soyutlaması, vektör depolarından veri eklemeye ve almaya yönelik düşük düzeyli bir API'dir. Semantik Çekirdek, RAG için Vektör Deposu uygulamalarından herhangi birini kullanmak için yerleşik desteğe sahiptir. Bu, IVectorSearchable<TRecord>'ı sararak ve bir Metin Arama uygulaması olarak sunarak elde edilir.

İpucu

RAG için vektör depolarını kullanma hakkında daha fazla bilgi edinmek için bkz. Anlam Çekirdeği Metin Aramaile Vektör Depolarını kullanma .

İpucu

Metin araması hakkında daha fazla bilgi edinmek için bkz. Anlam Çekirdeği Metin Araması nedir?

İpucu

Aracınıza HıZLA RAG ekleme hakkında daha fazla bilgi edinmek için bkz. Semantik Çekirdek Aracılarına Alma Artırılmış Nesli (RAG) Ekleme.

Vektör Deposu Soyutlaması

Vektör Deposu soyutlamaları nuget paketinde Microsoft.Extensions.VectorData.Abstractions sağlanır. Ana soyut temel sınıflar ve arabirimler aşağıdadır.

Microsoft.Extensions.VectorData.VectorStore

VectorStore , vektör deposundaki tüm koleksiyonlara yayılan işlemler içerir; örneğin, ListCollectionNames. Ayrıca VectorStoreCollection<TKey, TRecord> örneklerini alma olanağı sağlar.

Microsoft.Extensions.VectorData.VectorStoreCollection<TKey, TRecord>

VectorStoreCollection<TKey, TRecord> bir koleksiyonu temsil eder. Bu koleksiyon var olabilir veya olmayabilir ve soyut temel sınıfı koleksiyonun var olup olmadığını denetlemek, oluşturmak veya silmek için yöntemler sağlar. Soyut temel sınıfı ayrıca kayıtları eklemek, almak ve silmek için yöntemler sağlar. Son olarak, IVectorSearchable<TRecord>'den devralan soyut temel sınıf, vektör arama özellikleri sağlar.

Microsoft.Extensions.VectorData.IVectorSearchable<TRecord>

  • SearchAsync<TRecord> aşağıdakilerden birini yapmak için kullanılabilir:
    • vektör aramaları, kayıtlı bir gömme oluşturucu veya veritabanının bunu desteklediği durumlarda vektör veritabanı tarafından vektörleştirilebilen bazı girdileri alır.
    • Vektör aramaları, giriş olarak bir vektör alır.

Vektör Depoları ile Artırılmış Nesil (RAG) Alma

Vektör deposu soyutlamaları, vektör depolarından veri eklemeye ve almaya yönelik düşük düzeyli bir api'dir. Semantik Çekirdek, RAG için Vektör Deposu uygulamalarından herhangi birini kullanmak için yerleşik desteğe sahiptir. VectorSearchBase[TKey, TModel], VectorizedSearchMixin[Tmodel], VectorizableTextSearchMixin[TModel] veya VectorTextSearch[TModel] ile sarmalanıp bir Metin Arama uygulaması olarak sunulduğunda bu elde edilir.

İpucu

RAG için vektör depolarını kullanma hakkında daha fazla bilgi edinmek için bkz. Anlam Çekirdeği Metin Aramaile Vektör Depolarını kullanma .

İpucu

Metin araması hakkında daha fazla bilgi edinmek için bkz. Anlam Çekirdeği Metin Araması nedir?

Vektör Deposu Soyutlaması

Vektör Deposu soyutlamasında ana arabirimler şunlardır.

com.microsoft.semantickernel.data.vectorstorage.VectorStore

VectorStore , vektör deposundaki tüm koleksiyonlara yayılan işlemleri (ör. listCollectionNames) içerir. Ayrıca VectorStoreRecordCollection<Key, Record> örneklerini alma olanağı sağlar.

com.microsoft.semantickernel.data.vectorstorage.VectorStoreRecordCollection<Anahtar, Kayıt>

VectorStoreRecordCollection<Key, Record> bir koleksiyonu temsil eder. Bu koleksiyon var olabilir veya olmayabilir ve arabirim, koleksiyonun var olup olmadığını denetlemek, oluşturmak veya silmek için yöntemler sağlar. Arabirim ayrıca kayıtları eklemek, almak ve silmek için yöntemler sağlar. Son olarak, arabirim vektör arama özellikleri sağlamayı VectorizedSearch<Record> devralır.

com.microsoft.semantickernel.data.vectorarama.VektörleştirilmişArama<Kayıt>

VectorizedSearch<Record> vektör araması yapmak için bir yöntem içerir. VectorStoreRecordCollection<Key, Record>yalnızca aramanın gerekli olduğu ve kayıt veya koleksiyon yönetimi gerekmeyen durumlarda kendi başına kullanılmasını VectorizedSearch<Record> mümkün kılmayı VectorizedSearch<Record> devralır.

com.microsoft.semantickernel.data.vectorsearch.VectorizableTextSearch<Kaydı>

VectorizableTextSearch<Record> , vektör veritabanının otomatik olarak ekleme oluşturma özelliğine sahip olduğu vektör aramaları yapmak için bir yöntem içerir. Örneğin, bu yöntemi bir metin dizesiyle çağırabilirsiniz; veritabanı sizin için ekleme oluşturur ve bir vektör alanında arama yapabilir. Bu, tüm vektör veritabanları tarafından desteklenmez ve bu nedenle yalnızca belirli bağlayıcılar tarafından uygulanır.

Vektör Mağazalarını kullanmaya başlama

Gerekli nuget paketlerini içeri aktarma

Tüm vektör deposu arabirimleri ve soyutlamayla ilgili tüm sınıflar nuget paketinde Microsoft.Extensions.VectorData.Abstractions kullanılabilir. Her vektör deposu uygulaması kendi nuget paketinde kullanılabilir. Bilinen uygulamaların listesi için kullanıma hazır bağlayıcılar sayfasına bakın.

Soyutlama paketi aşağıdaki gibi eklenebilir.

dotnet add package Microsoft.Extensions.VectorData.Abstractions

Veri modelinizi tanımlama

Vektör Deposu soyutlamaları, veritabanlarıyla etkileşime geçmek için ilk olarak bir model yaklaşımı kullanır. Bu, ilk adımın depolama şemasına eşleyen bir veri modeli tanımlamak olduğu anlamına gelir. Uygulamaların kayıt koleksiyonları oluşturmasına ve depolama şemasına eşleştirilmesine yardımcı olmak için modele her özelliğin işlevini gösterecek şekilde açıklama eklenebilir.

using Microsoft.Extensions.VectorData;

public class Hotel
{
    [VectorStoreKey]
    public ulong HotelId { get; set; }

    [VectorStoreData(IsIndexed = true)]
    public string HotelName { get; set; }

    [VectorStoreData(IsFullTextIndexed = true)]
    public string Description { get; set; }

    [VectorStoreVector(Dimensions: 4, DistanceFunction = DistanceFunction.CosineSimilarity, IndexKind = IndexKind.Hnsw)]
    public ReadOnlyMemory<float>? DescriptionEmbedding { get; set; }

    [VectorStoreData(IsIndexed = true)]
    public string[] Tags { get; set; }
}
from dataclasses import dataclass, field
from typing import Annotated
from semantic_kernel.data.vector import (
    DistanceFunction,
    IndexKind,
    VectorStoreField,
    vectorstoremodel,
)

@vectorstoremodel
@dataclass
class Hotel:
    hotel_id: Annotated[str, VectorStoreField('key')] = field(default_factory=lambda: str(uuid4()))
    hotel_name: Annotated[str, VectorStoreField('data', is_filterable=True)]
    description: Annotated[str, VectorStoreField('data', is_full_text_searchable=True)]
    description_embedding: Annotated[list[float], VectorStoreField('vector', dimensions=4, distance_function=DistanceFunction.COSINE, index_kind=IndexKind.HNSW)]
    tags: Annotated[list[str], VectorStoreField('data', is_filterable=True)]
import com.microsoft.semantickernel.data.vectorstorage.annotations.VectorStoreRecordData;
import com.microsoft.semantickernel.data.vectorstorage.annotations.VectorStoreRecordKey;
import com.microsoft.semantickernel.data.vectorstorage.annotations.VectorStoreRecordVector;
import com.microsoft.semantickernel.data.vectorstorage.definition.DistanceFunction;
import com.microsoft.semantickernel.data.vectorstorage.definition.IndexKind;

import java.util.Collections;
import java.util.List;

public class Hotel {
    @VectorStoreRecordKey
    private String hotelId;

    @VectorStoreRecordData(isFilterable = true)
    private String name;

    @VectorStoreRecordData(isFullTextSearchable = true)
    private String description;

    @VectorStoreRecordVector(dimensions = 4, indexKind = IndexKind.HNSW, distanceFunction = DistanceFunction.COSINE_DISTANCE)
    private List<Float> descriptionEmbedding;

    @VectorStoreRecordData(isFilterable = true)
    private List<String> tags;

    public Hotel() { }

    public Hotel(String hotelId, String name, String description, List<Float> descriptionEmbedding, List<String> tags) {
        this.hotelId = hotelId;
        this.name = name;
        this.description = description;
        this.descriptionEmbedding = Collections.unmodifiableList(descriptionEmbedding);
        this.tags = Collections.unmodifiableList(tags);
    }

    public String getHotelId() { return hotelId; }
    public String getName() { return name; }
    public String getDescription() { return description; }
    public List<Float> getDescriptionEmbedding() { return descriptionEmbedding; }
    public List<String> getTags() { return tags; }
}

İpucu

Veri modelinize açıklama ekleme hakkında daha fazla bilgi için veri modelinizi tanımlama bölümüne bakın.

İpucu

Veri modelinize açıklama eklemeye alternatif olarak şemanızı bir kayıt tanımıyla tanımlamaya bakın.

Veritabanınıza bağlanın ve bir koleksiyon seçin

Veri modelinizi tanımladıktan sonra, sonraki adım seçtiğiniz veritabanı için bir VectorStore örneği oluşturmak ve bir kayıt koleksiyonu seçmektir.

Bu örnekte Qdrant kullanacağız. Bu nedenle Qdrant nuget paketini içeri aktarmanız gerekir.

dotnet add package Microsoft.SemanticKernel.Connectors.Qdrant --prerelease

Qdrant'ı Docker kullanarak yerel olarak çalıştırmak istiyorsanız, Qdrant kapsayıcısını bu örnekte kullanılan ayarlarla başlatmak için aşağıdaki komutu kullanın.

docker run -d --name qdrant -p 6333:6333 -p 6334:6334 qdrant/qdrant:latest

Qdrant örneğinizin düzgün çalıştığını doğrulamak için, Qdrant docker kapsayıcısının içinde yerleşik olarak bulunan Qdrant panosunu ziyaret edin: http://localhost:6333/dashboard

Veritabanları birçok farklı türde anahtarı ve kaydı desteklediğinden, genel değerleri kullanarak koleksiyonunuz için anahtarın ve kaydın türünü belirtmenize olanak sağlarız. Bizim durumumuzda, kayıt türü, zaten tanımladığımız Hotel sınıfı olacaktır ve anahtar türü ulong olacaktır çünkü HotelId özelliği bir ulong olup, Qdrant yalnızca Guid veya ulong anahtarlarını destekler.

using Microsoft.SemanticKernel.Connectors.Qdrant;
using Qdrant.Client;

// Create a Qdrant VectorStore object
var vectorStore = new QdrantVectorStore(new QdrantClient("localhost"), ownsClient: true);

// Choose a collection from the database and specify the type of key and record stored in it via Generic parameters.
var collection = vectorStore.GetCollection<ulong, Hotel>("skhotels");

Veritabanları birçok farklı türde anahtarı ve kaydı desteklediğinden, genel değerleri kullanarak koleksiyonunuz için anahtarın ve kaydın türünü belirtmenize olanak sağlarız. Bizim durumumuzda, kayıt türü, zaten tanımladığımız Hotel sınıfı olacaktır ve anahtar türü str olacaktır çünkü HotelId özelliği bir str olup, Qdrant yalnızca str veya int anahtarlarını destekler.

from semantic_kernel.connectors.qdrant import QdrantCollection

# Create a collection specify the type of key and record stored in it via Generic parameters.
collection: QdrantCollection[str, Hotel] = QdrantCollection(
    record_type=Hotel,
    collection_name="skhotels" # this is optional, you can also specify the collection_name in the vectorstoremodel decorator.
)

Veritabanları birçok farklı türde anahtarı ve kaydı desteklediğinden, genel değerleri kullanarak koleksiyonunuz için anahtarın ve kaydın türünü belirtmenize olanak sağlarız. Bizim örneğimizde, kayıt türü zaten tanımladığımız Hotel sınıf olacak ve anahtar türü String olacak, çünkü hotelId özelliği bir String ve JDBC deposu yalnızca String anahtarları destekler.

import com.microsoft.semantickernel.data.jdbc.JDBCVectorStore;
import com.microsoft.semantickernel.data.jdbc.JDBCVectorStoreOptions;
import com.microsoft.semantickernel.data.jdbc.JDBCVectorStoreRecordCollectionOptions;
import com.microsoft.semantickernel.data.jdbc.mysql.MySQLVectorStoreQueryProvider;
import com.mysql.cj.jdbc.MysqlDataSource;

import java.util.List;

public class Main {
    public static void main(String[] args) {
        // Create a MySQL data source
        var dataSource = new MysqlDataSource();
        dataSource.setUrl("jdbc:mysql://localhost:3306/sk");
        dataSource.setPassword("root");
        dataSource.setUser("root");

        // Create a JDBC vector store
        var vectorStore = JDBCVectorStore.builder()
            .withDataSource(dataSource)
            .withOptions(
                JDBCVectorStoreOptions.builder()
                    .withQueryProvider(MySQLVectorStoreQueryProvider.builder()
                        .withDataSource(dataSource)
                        .build())
                    .build()
            )
            .build();

        // Get a collection from the vector store
        var collection = vectorStore.getCollection("skhotels",
            JDBCVectorStoreRecordCollectionOptions.<Hotel>builder()
                .withRecordClass(Hotel.class)
                .build()
        );
    }
}

İpucu

Her Vektör Deposu uygulamasının desteklediği anahtar ve alan türleri hakkında daha fazla bilgi için, her uygulamanın belgelerine bakın.

Koleksiyonu oluşturma ve kayıt ekleme

// Placeholder embedding generation method.
async Task<ReadOnlyMemory<float>> GenerateEmbeddingAsync(string textToVectorize)
{
    // your logic here
}

// Create the collection if it doesn't exist yet.
await collection.EnsureCollectionExistsAsync();

// Upsert a record.
string descriptionText = "A place where everyone can be happy.";
ulong hotelId = 1;

// Create a record and generate a vector for the description using your chosen embedding generation implementation.
await collection.UpsertAsync(new Hotel
{
    HotelId = hotelId,
    HotelName = "Hotel Happy",
    Description = descriptionText,
    DescriptionEmbedding = await GenerateEmbeddingAsync(descriptionText),
    Tags = new[] { "luxury", "pool" }
});

// Retrieve the upserted record.
Hotel? retrievedHotel = await collection.GetAsync(hotelId);

Koleksiyonu oluşturma ve kayıt ekleme

# Create the collection if it doesn't exist yet.
await collection.ensure_collection_exists()

# Upsert a record.
description = "A place where everyone can be happy."
hotel_id = "1"

await collection.upsert(Hotel(
    hotel_id = hotel_id,
    hotel_name = "Hotel Happy",
    description = description,
    description_embedding = await GenerateEmbeddingAsync(description),
    tags = ["luxury", "pool"]
))

# Retrieve the upserted record.
retrieved_hotel = await collection.get(hotel_id)
// Create the collection if it doesn't exist yet.
collection.createCollectionAsync().block();

// Upsert a record.
var description = "A place where everyone can be happy";
var hotelId = "1";
var hotel = new Hotel(
    hotelId, 
    "Hotel Happy", 
    description, 
    generateEmbeddingsAsync(description).block(), 
    List.of("luxury", "pool")
);

collection.upsertAsync(hotel, null).block();

// Retrieve the upserted record.
var retrievedHotel = collection.getAsync(hotelId, null).block();

İpucu

Gömme oluşturma hakkında daha fazla bilgi için bkz gömme oluşturma.

// Placeholder embedding generation method.
async Task<ReadOnlyMemory<float>> GenerateEmbeddingAsync(string textToVectorize)
{
    // your logic here
}

// Generate a vector for your search text, using your chosen embedding generation implementation.
ReadOnlyMemory<float> searchVector = await GenerateEmbeddingAsync("I'm looking for a hotel where customer happiness is the priority.");

// Do the search.
var searchResult = collection.SearchAsync(searchVector, top: 1);

// Inspect the returned hotel.
await foreach (var record in searchResult)
{
    Console.WriteLine("Found hotel description: " + record.Record.Description);
    Console.WriteLine("Found record score: " + record.Score);
}

Vektör araması yapma

Arama yöntemi, koleksiyondaki kayıtları aramak için kullanılabilir. Daha sonra model veya koleksiyondaki ekleme oluşturma kurulumu kullanılarak vektörleştirilen bir dize veya önceden oluşturulmuş bir vektör alır.

# Do a search.
search_result = await collection.search("I'm looking for a hotel where customer happiness is the priority.", vector_property_name="description_embedding", top=3)

# Inspect the returned hotels.
async for result in search_result.results:
    print(f"Found hotel description: {result.record.description}")

Arama işlevi oluşturma

Otel aramak için kullanılabilecek basit bir arama işlevi oluşturmak için koleksiyonda create_search_function yöntemini kullanabilirsiniz.

Ad ve açıklamanın yanı sıra parametrelerin adları ve açıklamaları, işlev çağrısı kullanıldığında LLM'ye gönderilen bir işlev imzası oluşturmak için kullanılır. Bu ayarların değiştirilmesi, LLM'nin doğru işlev çağrısını oluşturmasını sağlamak için yararlı olabilir.

collection.create_search_function(
    function_name="hotel_search",
    description="A hotel search engine, allows searching for hotels in specific cities, "
    "you do not have to specify that you are searching for hotels, for all, use `*`."
)

Başka birçok parametre vardır, örneğin daha karmaşık bir sürümün nasıl göründüğüdür, parametrelerin özelleştirildiğini ve string_mapper kaydı dizeye dönüştürmek için kullanılan işlevi not edin.

from semantic_kernel.function import KernelParameterMetadata

collection.create_search_function(
    function_name="hotel_search",
    description="A hotel search engine, allows searching for hotels in specific cities, "
    "you do not have to specify that you are searching for hotels, for all, use `*`.",
    search_type="keyword_hybrid", # default is "vector"
    parameters=[
        KernelParameterMetadata(
            name="query",
            description="The terms you want to search for in the hotel database.",
            type="str",
            is_required=True,
            type_object=str,
        ),
        KernelParameterMetadata(
            name="tags",
            description="The tags you want to search for in the hotel database, use `*` to match all.",
            type="str",
            type_object=str,
            default_value="*",
        ),
        KernelParameterMetadata(
            name="top",
            description="Number of results to return.",
            type="int",
            default_value=5,
            type_object=int,
        ),
    ],
    # finally, we specify the `string_mapper` function that is used to convert the record to a string.
    # This is used to make sure the relevant information from the record is passed to the LLM.
    string_mapper=lambda x: f"Hotel {x.record.hotel_name}: {x.record.description}. Tags: {x.record.tags} (hotel_id: {x.record.hotel_id}) ", 
)

İpucu

Uçtan uca örnekler de dahil olmak üzere daha fazla örnek için bkz. AnlamSal Çekirdek Örnekleri deposu.

// Generate a vector for your search text, using your chosen embedding generation implementation.
// Just showing a placeholder method here for brevity.
var searchVector = generateEmbeddingsAsync("I'm looking for a hotel where customer happiness is the priority.").block();

// Do the search.
var searchResult = collection.searchAsync(searchVector, VectorSearchOptions.builder()
    .withTop(1).build()
).block();

Hotel record = searchResult.getResults().get(0).getRecord();
System.out.printf("Found hotel description: %s\n", record.getDescription());

İpucu

Gömme oluşturma hakkında daha fazla bilgi için bkz gömme oluşturma.

Sonraki adımlar