Udostępnij za pośrednictwem


Korzystanie z łącznika Usługi Redis (wersja zapoznawcza)

Ostrzeżenie

Funkcja semantycznego magazynu wektorów jądra jest dostępna w wersji zapoznawczej, a ulepszenia wymagające zmian powodujących niezgodność mogą nadal występować w ograniczonych okolicznościach przed wydaniem.

Omówienie

Łącznik usługi Redis Vector Store może służyć do uzyskiwania dostępu do danych w usłudze Redis i zarządzania nimi. Łącznik obsługuje zarówno skróty, jak i tryb JSON, a wybrany tryb określa, jakie inne funkcje są obsługiwane.

Łącznik ma następujące cechy.

Obszar funkcji Pomoc techniczna
Mapowania kolekcji na Indeks redis z prefiksem ustawionym na <collectionname>:
Obsługiwane typy właściwości kluczy string
Obsługiwane typy właściwości danych W przypadku korzystania z skrótów:
  • string
  • int
  • uint
  • długi
  • ulong
  • double
  • liczba zmiennoprzecinkowa
  • bool
W przypadku korzystania z formatu JSON:
Wszelkie typy serializowalne do formatu JSON
Obsługiwane typy właściwości wektorów
  • ReadOnlyMemory<float>
  • ReadOnlyMemory<podwójnie>
Obsługiwane typy indeksów
  • Hnsw
  • Spłaszcz
Obsługiwane funkcje odległości
  • CosineSimilarity
  • DotProductSimilarity
  • EuclideanDistance
Obsługuje wiele wektorów w rekordzie Tak
Czy filtrowanie jest obsługiwane? Tak
Czy jest obsługiwany element IsFullTextSearchable? Tak
Obsługiwana nazwa_właściwości_magazynu? W przypadku korzystania z skrótów: Tak
W przypadku korzystania z formatu JSON: Nie, użyj polecenia JsonSerializerOptions i JsonPropertyNameAttribute zamiast tego. Aby uzyskać więcej informacji, zobacz tutaj.

Wprowadzenie

Dodaj pakiet nuget łącznika Redis Vector Store do projektu.

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

Magazyn wektorów można dodać do kontenera iniekcji zależności dostępnego w KernelBuilder kontenerze iniekcji zależności lub IServiceCollection przy użyciu metod rozszerzeń udostępnianych przez jądro semantyczne.

using Microsoft.SemanticKernel;

// Using Kernel Builder.
var kernelBuilder = Kernel
    .CreateBuilder()
    .AddRedisVectorStore("localhost:6379");
using Microsoft.SemanticKernel;

// Using IServiceCollection with ASP.NET Core.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRedisVectorStore("localhost:6379");

Dostępne są również metody rozszerzeń, które nie przyjmują parametrów. Wymagają one osobnego zarejestrowania wystąpienia usługi Redis IDatabase w kontenerze wstrzykiwania zależności.

using Microsoft.Extensions.DependencyInjection;
using Microsoft.SemanticKernel;
using StackExchange.Redis;

// Using Kernel Builder.
var kernelBuilder = Kernel.CreateBuilder();
kernelBuilder.Services.AddSingleton<IDatabase>(sp => ConnectionMultiplexer.Connect("localhost:6379").GetDatabase());
kernelBuilder.AddRedisVectorStore();
using Microsoft.Extensions.DependencyInjection;
using Microsoft.SemanticKernel;
using StackExchange.Redis;

// Using IServiceCollection with ASP.NET Core.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSingleton<IDatabase>(sp => ConnectionMultiplexer.Connect("localhost:6379").GetDatabase());
builder.Services.AddRedisVectorStore();

Wystąpienie usługi Redis Vector Store można skonstruować bezpośrednio.

using Microsoft.SemanticKernel.Connectors.Redis;
using StackExchange.Redis;

var vectorStore = new RedisVectorStore(ConnectionMultiplexer.Connect("localhost:6379").GetDatabase());

Istnieje możliwość utworzenia bezpośredniego odwołania do nazwanej kolekcji. W tym celu musisz wybrać wystąpienie JSON lub Hashes w zależności od sposobu przechowywania danych w usłudze Redis.

using Microsoft.SemanticKernel.Connectors.Redis;
using StackExchange.Redis;

// Using Hashes.
var hashesCollection = new RedisHashSetVectorStoreRecordCollection<Hotel>(
    ConnectionMultiplexer.Connect("localhost:6379").GetDatabase(),
    "skhotelshashes");
using Microsoft.SemanticKernel.Connectors.Redis;
using StackExchange.Redis;

// Using JSON.
var jsonCollection = new RedisJsonVectorStoreRecordCollection<Hotel>(
    ConnectionMultiplexer.Connect("localhost:6379").GetDatabase(),
    "skhotelsjson");

Podczas konstruowania RedisVectorStore lub rejestrowania go w kontenerze wstrzykiwania zależności można przekazać RedisVectorStoreOptions wystąpienie, które konfiguruje preferowany typ/tryb przechowywania używany: skróty lub dane JSON. Jeśli nie zostanie określony, wartość domyślna to JSON.

using Microsoft.SemanticKernel.Connectors.Redis;
using StackExchange.Redis;

var vectorStore = new RedisVectorStore(
    ConnectionMultiplexer.Connect("localhost:6379").GetDatabase(),
    new() { StorageType = RedisStorageType.HashSet });

Wprowadzenie

Zainstaluj jądro semantyczne przy użyciu dodatków redis, które obejmują klienta redis.

pip install semantic-kernel[redis]

Następnie można utworzyć wystąpienie magazynu wektorów przy użyciu RedisStore klasy. Spowoduje to użycie zmiennych REDIS_CONNECTION_STRING środowiskowych w celu nawiązania połączenia z wystąpieniem usługi Redis. Te wartości można również podać bezpośrednio.


from semantic_kernel.connectors.memory.redis import RedisStore

vector_store = RedisStore()

Możesz również utworzyć magazyn wektorów przy użyciu własnego wystąpienia klienta bazy danych Redis.

from redis.asyncio.client import Redis
from semantic_kernel.connectors.memory.redis import RedisStore

redis_database = Redis.from_url(url="https://<your-redis-service-name>")
vector_store = RedisStore(redis_database=redis_database)

Możesz również utworzyć kolekcję bezpośrednio, ale istnieją dwa typy kolekcji, po jednym dla skrótów i jeden dla formatu JSON.

from semantic_kernel.connectors.memory.redis import RedisHashsetCollection, RedisJsonCollection

hash_collection = RedisHashsetCollection(collection_name="skhotels", data_model_type=Hotel)
json_collection = RedisJsonCollection(collection_name="skhotels", data_model_type=Hotel)

Podczas tworzenia kolekcji z magazynu wektorów można przekazać typ kolekcji jako wyliczenie: RedisCollectionTypes, wartość domyślna to kolekcja skrótów.

from semantic_kernel.connectors.memory.redis import RedisStore, RedisCollectionTypes

vector_store = RedisStore()
collection = vector_store.get_collection(
    collection_name="skhotels", 
    data_model_type=Hotel, 
    collection_type=RedisCollectionTypes.JSON,
)

Serializacja

Kolekcje redis używają dykt jako formatu danych podczas upserting, jednak struktura dyktowania różni się między nimi.

W przypadku kolekcji JSON zobacz dokumentację usługi Redis na przykład.

W przypadku kolekcji hashset używa polecenia hset z polem klucza jako name, pola danych jako mapping -> metadata i wektory jako mapping -> [vector_field_name] , zobacz tutaj , aby uzyskać więcej informacji.

Aby uzyskać więcej informacji na temat tej koncepcji, zobacz dokumentację serializacji.

Wprowadzenie

Dołącz najnowszą wersję łącznika danych Semantic Kernel Redis w projekcie maven, dodając następującą zależność do elementu pom.xml:

<dependency>
    <groupId>com.microsoft.semantic-kernel</groupId>
    <artifactId>semantickernel-data-redis</artifactId>
    <version>[LATEST]</version>
</dependency>

Następnie można utworzyć wystąpienie magazynu wektorów przy użyciu RedisVectorStore klasy , używając klienta Redis (JedisPooled) jako parametru.

import com.microsoft.semantickernel.data.redis.RedisJsonVectorStoreRecordCollectionOptions;
import com.microsoft.semantickernel.data.redis.RedisStorageType;
import com.microsoft.semantickernel.data.redis.RedisVectorStore;
import com.microsoft.semantickernel.data.redis.RedisVectorStoreOptions;
import redis.clients.jedis.JedisPooled;

public class Main {
    public static void main(String[] args) {
        JedisPooled jedis = new JedisPooled("<your-redis-url>");

        // Build a Redis Vector Store
        // Available storage types are JSON and HASHSET. Default is JSON.
        var vectorStore = RedisVectorStore.builder()
            .withClient(jedis)
            .withOptions(
                RedisVectorStoreOptions.builder()
                    .withStorageType(RedisStorageType.HASH_SET).build())
            .build();
    }
}

Możesz również pobrać kolekcję bezpośrednio.

var collection = vectorStore.getCollection("skhotels",
    RedisJsonVectorStoreRecordCollectionOptions.<Hotel>builder()
        .withRecordClass(Hotel.class)
        .build());

Prefiksy indeksów

Usługa Redis używa systemu prefiksowania kluczy do skojarzenia rekordu z indeksem. Podczas tworzenia indeksu można określić jeden lub więcej prefiksów do użycia z tym indeksem. Jeśli chcesz skojarzyć rekord z tym indeksem, musisz dodać prefiks do klucza tego rekordu.

Na przykład jeśli utworzysz indeks o nazwie skhotelsjson z prefiksem skhotelsjson:, podczas ustawiania rekordu z kluczem h1, klucz rekordu musi być poprzedzony skhotelsjson:h1 prefiksem, tak aby został dodany do indeksu.

Podczas tworzenia nowej kolekcji przy użyciu łącznika usługi Redis łącznik utworzy indeks w usłudze Redis z prefiksem składającym się z nazwy kolekcji i dwukropka, na przykład w tym <collectionname>:. Domyślnie łącznik będzie również prefiksować wszystkie klucze z tym prefiksem podczas wykonywania operacji rekordów, takich jak Get, Upsert i Delete.

Jeśli nie chcesz używać prefiksu składającego się z nazwy kolekcji i dwukropka, można wyłączyć zachowanie prefiksowania i przekazać w pełni prefiksowany klucz do operacji rekordu.

using Microsoft.SemanticKernel.Connectors.Redis;
using StackExchange.Redis;

var collection = new RedisJsonVectorStoreRecordCollection<Hotel>(
    ConnectionMultiplexer.Connect("localhost:6379").GetDatabase(),
    "skhotelsjson",
    new() { PrefixCollectionNameToKeyNames = false });

await collection.GetAsync("myprefix_h1");
from semantic_kernel.connectors.memory.redis import RedisJsonCollection

collection = RedisJsonCollection(collection_name="skhotels", data_model_type=hotel, prefix_collection_name_to_key_names=False)

await collection.get("myprefix_h1")
var collection = vectorStore.getCollection("skhotels",
    RedisJsonVectorStoreRecordCollectionOptions.<Hotel>builder()
        .withRecordClass(Hotel.class)
        .withPrefixCollectionName(false)
        .build());

collection.getAsync("myprefix_h1", null).block();

Mapowanie danych

Usługa Redis obsługuje dwa tryby przechowywania danych: JSON i Skróty. Łącznik usługi Redis obsługuje oba typy magazynów, a mapowanie różni się w zależności od wybranego typu magazynu.

Mapowanie danych podczas korzystania z typu magazynu JSON

W przypadku używania typu magazynu JSON łącznik usługi Redis będzie używany System.Text.Json.JsonSerializer do mapowania. Ponieważ usługa Redis przechowuje rekordy z oddzielnym kluczem i wartością, maper będzie serializować wszystkie właściwości z wyjątkiem klucza do obiektu JSON i używać go jako wartości.

Użycie elementu JsonPropertyNameAttribute jest obsługiwane, jeśli wymagana jest inna nazwa magazynu dla nazwy właściwości modelu danych. Istnieje również możliwość użycia wystąpienia niestandardowego JsonSerializerOptions z dostosowanymi zasadami nazewnictwa właściwości. Aby to umożliwić, należy przekazać je JsonSerializerOptions do RedisJsonVectorStoreRecordCollection konstrukcji.

var jsonSerializerOptions = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseUpper };
var collection = new RedisJsonVectorStoreRecordCollection<Hotel>(
    ConnectionMultiplexer.Connect("localhost:6379").GetDatabase(),
    "skhotelsjson",
    new() { JsonSerializerOptions = jsonSerializerOptions });

Ponieważ wybrano zasady nazewnictwa górnej litery węża, oto przykład sposobu ustawienia tego typu danych w usłudze Redis. Zwróć również uwagę na użycie JsonPropertyNameAttribute właściwości w Description celu dalszego dostosowywania nazewnictwa magazynu.

using System.Text.Json.Serialization;
using Microsoft.Extensions.VectorData;

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

    [VectorStoreRecordData(IsFilterable = true)]
    public string HotelName { get; set; }

    [JsonPropertyName("HOTEL_DESCRIPTION")]
    [VectorStoreRecordData(IsFullTextSearchable = true)]
    public string Description { get; set; }

    [VectorStoreRecordVector(Dimensions: 4, DistanceFunction.CosineDistance, IndexKind.Hnsw)]
    public ReadOnlyMemory<float>? DescriptionEmbedding { get; set; }
}
JSON.SET skhotelsjson:h1 $ '{ "HOTEL_NAME": "Hotel Happy", "HOTEL_DESCRIPTION": "A place where everyone can be happy.", "DESCRIPTION_EMBEDDING": [0.9, 0.1, 0.1, 0.1] }'

Mapowanie danych podczas korzystania z typu magazynu skrótów

W przypadku korzystania z typu magazynu skrótów łącznik Redis udostępnia własny maper do mapowania. Ten maper mapuje każdą właściwość na parę pól-wartość, która jest obsługiwana przez polecenie Redis HSET .

W przypadku właściwości danych i właściwości wektorów można podać nazwy pól przesłonięć do użycia w magazynie, który różni się od nazw właściwości w modelu danych. Nie jest to obsługiwane w przypadku kluczy, ponieważ klucze nie mogą być nazwane w usłudze Redis.

Zastępowanie nazwy właściwości odbywa się przez ustawienie StoragePropertyName opcji za pomocą atrybutów modelu danych lub definicji rekordu.

Oto przykład modelu danych z StoragePropertyName ustawionymi atrybutami i sposobem ich ustawiania w usłudze Redis.

using Microsoft.Extensions.VectorData;

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

    [VectorStoreRecordData(IsFilterable = true, StoragePropertyName = "hotel_name")]
    public string HotelName { get; set; }

    [VectorStoreRecordData(IsFullTextSearchable = true, StoragePropertyName = "hotel_description")]
    public string Description { get; set; }

    [VectorStoreRecordVector(Dimensions: 4, DistanceFunction.CosineDistance, IndexKind.Hnsw, StoragePropertyName = "hotel_description_embedding")]
    public ReadOnlyMemory<float>? DescriptionEmbedding { get; set; }
}
HSET skhotelshashes:h1 hotel_name "Hotel Happy" hotel_description 'A place where everyone can be happy.' hotel_description_embedding <vector_bytes>