Använda Redis-anslutningsappen (förhandsversion)
Varning
Funktionen Semantic Kernel Vector Store är i förhandsversion, och förbättringar som kräver icke-bakåtkompatibla ändringar kan fortfarande ske under begränsade omständigheter före lanseringen.
Översikt
Redis Vector Store-anslutningsappen kan användas för att komma åt och hantera data i Redis. Anslutningsappen stöder både Hashes- och JSON-lägen och vilket läge du väljer avgör vilka andra funktioner som stöds.
Anslutningsappen har följande egenskaper.
Funktionsområde | Support |
---|---|
Samlingskartor till | Redis-index med prefix inställt på <collectionname>: |
Nyckelegenskapstyper som stöds | sträng |
Dataegenskapstyper som stöds | När du använder hashar:
Alla typer som kan serialiseras till JSON |
Egenskapstyper för vektorer som stöds |
|
Indextyper som stöds |
|
Avståndsfunktioner som stöds |
|
Stöder flera vektorer i en post | Ja |
Stöds IsFilterable? | Ja |
Stöds IsFullTextSearchable? | Ja |
Stöds StoragePropertyName? | När du använder hashar: Ja När du använder JSON: Nej, använd JsonSerializerOptions och JsonPropertyNameAttribute i stället. Mer information finns här. |
Komma igång
Lägg till nuget-paketet för Redis Vector Store-anslutningsappen i projektet.
dotnet add package Microsoft.SemanticKernel.Connectors.Redis --prerelease
Du kan lägga till vektorlagret i den beroendeinmatningscontainer som är tillgänglig i containern KernelBuilder
eller till containern för IServiceCollection
beroendeinmatning med hjälp av tilläggsmetoder som tillhandahålls av semantisk kernel.
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");
Tilläggsmetoder som inte har några parametrar tillhandahålls också. Dessa kräver att en instans av Redis IDatabase
registreras separat med containern för beroendeinmatning.
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();
Du kan skapa en Redis Vector Store-instans direkt.
using Microsoft.SemanticKernel.Connectors.Redis;
using StackExchange.Redis;
var vectorStore = new RedisVectorStore(ConnectionMultiplexer.Connect("localhost:6379").GetDatabase());
Det går att skapa en direktreferens till en namngiven samling. När du gör det måste du välja mellan JSON- eller Hashes-instansen beroende på hur du vill lagra data i 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");
När du skapar en RedisVectorStore
eller registrerar den med containern för beroendeinmatning är det möjligt att skicka en RedisVectorStoreOptions
instans som konfigurerar önskad lagringstyp/-läge som används: Hashar eller JSON. Om det inte anges är standardvärdet JSON.
using Microsoft.SemanticKernel.Connectors.Redis;
using StackExchange.Redis;
var vectorStore = new RedisVectorStore(
ConnectionMultiplexer.Connect("localhost:6379").GetDatabase(),
new() { StorageType = RedisStorageType.HashSet });
Komma igång
Installera semantisk kernel med redis-extrafunktionerna, som innehåller redis-klienten.
pip install semantic-kernel[redis]
Du kan sedan skapa en vektorlagerinstans med hjälp av RedisStore
klassen. Då används miljövariablerna REDIS_CONNECTION_STRING
för att ansluta till en Redis-instans. Dessa värden kan också anges direkt.
from semantic_kernel.connectors.memory.redis import RedisStore
vector_store = RedisStore()
Du kan också skapa vektorarkivet med din egen instans av Redis-databasklienten.
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)
Du kan också skapa en samling direkt, men det finns två typer av samlingar, en för Hashes och en för 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)
När du skapar en samling från vektorarkivet kan du skicka in samlingstypen som en uppräkning: RedisCollectionTypes
, standardvärdet är en hash-samling.
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,
)
Serialisering
Redis-samlingarna använder båda en diktering som dataformat vid upphettning, men strukturen för diktaten skiljer sig åt mellan dem.
För JSON-samlingar, se redis-dokument för ett exempel.
För Hashset-samlingar använder den kommandot hset med nyckelfältet som name
, datafält som mapping -> metadata
och vektorer som mapping -> [vector_field_name]
, se här för mer information.
Mer information om det här konceptet finns i serialiseringsdokumentationen.
Komma igång
Inkludera den senaste versionen av Semantic Kernel Redis-dataanslutningen i ditt Maven-projekt genom att lägga till följande beroende i :pom.xml
<dependency>
<groupId>com.microsoft.semantic-kernel</groupId>
<artifactId>semantickernel-data-redis</artifactId>
<version>[LATEST]</version>
</dependency>
Du kan sedan skapa en vektorlagringsinstans med hjälp av RedisVectorStore
klassen med Redis-klienten (JedisPooled) som en parameter.
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();
}
}
Du kan också hämta en samling direkt.
var collection = vectorStore.getCollection("skhotels",
RedisJsonVectorStoreRecordCollectionOptions.<Hotel>builder()
.withRecordClass(Hotel.class)
.build());
Indexprefix
Redis använder ett system med nyckelprefix för att associera en post med ett index. När du skapar ett index kan du ange ett eller flera prefix som ska användas med indexet. Om du vill associera en post med det indexet måste du lägga till prefixet i postens nyckel.
T.ex. Om du skapar ett index med namnet skhotelsjson
med prefixet skhotelsjson:
, när du anger en post med nyckeln h1
, måste postnyckeln prefixas så här skhotelsjson:h1
för att läggas till i indexet.
När du skapar en ny samling med Hjälp av Redis-anslutningsappen skapar anslutningsappen ett index i Redis med ett prefix som består av samlingsnamnet och ett kolon, som det här <collectionname>:
.
Som standard prefixar anslutningsappen även alla nycklar med det här prefixet när du utför poståtgärder som Get, Upsert och Delete.
Om du inte vill använda ett prefix som består av samlingsnamnet och ett kolon är det möjligt att stänga av prefixbeteendet och skicka in den helt prefixerade nyckeln till poståtgärderna.
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();
Mappning av data
Redis stöder två lägen för lagring av data: JSON och Hashes. Redis-anslutningsappen stöder båda lagringstyperna och mappningen skiljer sig beroende på vilken lagringstyp som valts.
Datamappning när du använder JSON-lagringstypen
När du använder JSON-lagringstypen används System.Text.Json.JsonSerializer
Redis-anslutningsappen för att mappa.
Eftersom Redis lagrar poster med en separat nyckel och ett separat värde serialiserar mapparen alla egenskaper förutom nyckeln till ett JSON-objekt och använder det som värde.
Användning av JsonPropertyNameAttribute
stöds om ett annat lagringsnamn än datamodellens egenskapsnamn krävs. Du kan också använda en anpassad JsonSerializerOptions
instans med en anpassad namngivningsprincip för egenskaper. För att aktivera detta JsonSerializerOptions
måste skickas till bygget RedisJsonVectorStoreRecordCollection
.
var jsonSerializerOptions = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseUpper };
var collection = new RedisJsonVectorStoreRecordCollection<Hotel>(
ConnectionMultiplexer.Connect("localhost:6379").GetDatabase(),
"skhotelsjson",
new() { JsonSerializerOptions = jsonSerializerOptions });
Eftersom en namngivningsprincip för ormfallsöverkant valdes, här är ett exempel på hur den här datatypen kommer att anges i Redis.
Observera också användningen av JsonPropertyNameAttribute
på Description
egenskapen för att ytterligare anpassa lagringsnamngivningen.
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] }'
Datamappning när du använder Hashes-lagringstypen
När du använder Hashes-lagringstypen tillhandahåller Redis-anslutningsappen en egen mappningsapp för mappning.
Den här mapparen mappar varje egenskap till ett fältvärdepar som stöds av Redis-kommandot HSET
.
För dataegenskaper och vektoregenskaper kan du ange åsidosättningsfältnamn som ska användas i lagring som skiljer sig från egenskapsnamnen i datamodellen. Detta stöds inte för nycklar eftersom nycklar inte kan namnges i Redis.
Egenskapsnamn åsidosättas genom att ange StoragePropertyName
alternativet via datamodellattributen eller postdefinitionen.
Här är ett exempel på en datamodell med StoragePropertyName
angivna attribut och hur dessa anges i 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>