Использование соединителя Redis (предварительная версия)
Предупреждение
Функции хранилища векторов семантического ядра доступны в предварительной версии и улучшения, требующие критических изменений, могут по-прежнему возникать в ограниченных обстоятельствах перед выпуском.
Обзор
Соединитель Redis Vector Store можно использовать для доступа к данным и управления ими в Redis. Соединитель поддерживает режимы хэшей и JSON, а также выбранный режим определяет, какие другие функции поддерживаются.
Соединитель имеет следующие характеристики.
Область функций | Поддержка |
---|---|
Коллекция сопоставляется с | Индекс Redis с префиксом, равным <collectionname>: |
Поддерживаемые типы свойств ключей | строка |
Поддерживаемые типы свойств данных | При использовании хэшей:
Все типы, сериализуемые в JSON |
Поддерживаемые типы свойств вектора |
|
Поддерживаемые типы индексов |
|
Поддерживаемые функции расстояния |
|
Поддержка нескольких векторов в записи | Да |
Поддерживается IsFilterable? | Да |
Поддерживается ЛиFullTextSearchable? | Да |
Поддерживается StoragePropertyName? | При использовании хэшей: Да При использовании JSON: нет, используйте JsonSerializerOptions и JsonPropertyNameAttribute вместо этого. Дополнительные сведения см. здесь. |
Начало работы
Добавьте в проект пакет nuget соединителя Redis Vector Store.
dotnet add package Microsoft.SemanticKernel.Connectors.Redis --prerelease
Хранилище векторов можно добавить в контейнер внедрения зависимостей, доступный в KernelBuilder
контейнере внедрения зависимостей или в IServiceCollection
контейнер внедрения зависимостей, используя методы расширения, предоставляемые семантического ядра.
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");
Методы расширения, которые не принимают параметров, также предоставляются. Для них требуется, чтобы экземпляр Redis IDatabase
был отдельно зарегистрирован в контейнере внедрения зависимостей.
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();
Экземпляр Redis Vector Store можно создать напрямую.
using Microsoft.SemanticKernel.Connectors.Redis;
using StackExchange.Redis;
var vectorStore = new RedisVectorStore(ConnectionMultiplexer.Connect("localhost:6379").GetDatabase());
Можно создать прямую ссылку на именованную коллекцию. При этом необходимо выбрать экземпляр JSON или Hashes в зависимости от способа хранения данных в 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");
При создании RedisVectorStore
или регистрации в контейнере внедрения зависимостей можно передать RedisVectorStoreOptions
экземпляр, который настраивает предпочтительный тип хранилища или используемый режим: Hashes или JSON. Если значение не указано, значение по умолчанию — JSON.
using Microsoft.SemanticKernel.Connectors.Redis;
using StackExchange.Redis;
var vectorStore = new RedisVectorStore(
ConnectionMultiplexer.Connect("localhost:6379").GetDatabase(),
new() { StorageType = RedisStorageType.HashSet });
Начало работы
Установите семантические ядра с дополнительными компонентами Redis, включая клиент Redis.
pip install semantic-kernel[redis]
Затем можно создать экземпляр векторного хранилища с помощью RedisStore
класса, используйте переменные REDIS_CONNECTION_STRING
среды для подключения к экземпляру Redis, эти значения также можно предоставить напрямую.
from semantic_kernel.connectors.memory.redis import RedisStore
vector_store = RedisStore()
Вы также можете создать хранилище векторов с собственным экземпляром клиента базы данных 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)
Вы также можете создать коллекцию напрямую, но существует два типа коллекций, один для хэшей и один для 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)
При создании коллекции из векторного хранилища можно передать тип коллекции в виде перечисления: RedisCollectionTypes
по умолчанию используется хэш-коллекция.
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,
)
Сериализация
Коллекции Redis используют дикт в качестве формата данных при переверхе, однако структура диктовок отличается между ними.
Пример для коллекций JSON см . в документации redis.
Для коллекций Hashset используется команда hset с ключевым полем как name
поля данных как mapping -> metadata
и векторы, как mapping -> [vector_field_name]
, см . здесь дополнительные сведения.
Дополнительные сведения об этой концепции см. в документации по сериализации.
Начало работы
Включите последнюю версию соединителя данных Redis семантического ядра в проект Maven, добавив в проект pom.xml
Maven следующую зависимость:
<dependency>
<groupId>com.microsoft.semantic-kernel</groupId>
<artifactId>semantickernel-data-redis</artifactId>
<version>[LATEST]</version>
</dependency>
Затем можно создать экземпляр векторного хранилища с помощью RedisVectorStore
класса, имея клиент Redis (JedisPooled) в качестве параметра.
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();
}
}
Вы также можете получить коллекцию напрямую.
var collection = vectorStore.getCollection("skhotels",
RedisJsonVectorStoreRecordCollectionOptions.<Hotel>builder()
.withRecordClass(Hotel.class)
.build());
Префиксы индекса
Redis использует систему префикса ключа для связывания записи с индексом. При создании индекса можно указать один или несколько префиксов, используемых с этим индексом. Если вы хотите связать запись с этим индексом, необходимо добавить префикс в ключ этой записи.
Например, если вы создаете индекс, вызываемый skhotelsjson
префиксом skhotelsjson:
, при настройке записи с ключом h1
, ключ записи должен быть префиксирован так, как это skhotelsjson:h1
будет добавлено в индекс.
При создании новой коллекции с помощью соединителя Redis соединитель создаст индекс в Redis с префиксом, состоящим из имени коллекции и двоеточия, как показано ниже <collectionname>:
.
По умолчанию соединитель также будет префиксировать все ключи с этим префиксом при выполнении операций записи, таких как Get, Upsert и Delete.
Если вы не хотите использовать префикс, состоящий из имени коллекции и двоеточия, можно отключить поведение префикса и передать в операции записи полностью префиксированные ключи.
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();
Сопоставление данных
Redis поддерживает два режима хранения данных: JSON и Hashes. Соединитель Redis поддерживает как типы хранилища, так и сопоставление отличается в зависимости от выбранного типа хранилища.
Сопоставление данных при использовании типа хранилища JSON
При использовании типа хранилища JSON соединитель Redis будет использовать System.Text.Json.JsonSerializer
для сопоставления.
Так как Redis хранит записи с отдельным ключом и значением, приложение mapper сериализует все свойства, кроме ключа в объект JSON, и использует его в качестве значения.
JsonPropertyNameAttribute
Использование поддерживается, если требуется другое имя хранилища для имени свойства модели данных. Также можно использовать пользовательский JsonSerializerOptions
экземпляр с настраиваемой политикой именования свойств. Чтобы включить это, JsonSerializerOptions
необходимо передать в RedisJsonVectorStoreRecordCollection
строительство.
var jsonSerializerOptions = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseUpper };
var collection = new RedisJsonVectorStoreRecordCollection<Hotel>(
ConnectionMultiplexer.Connect("localhost:6379").GetDatabase(),
"skhotelsjson",
new() { JsonSerializerOptions = jsonSerializerOptions });
Так как выбрана политика именования верхнего регистра змеи, вот пример того, как этот тип данных будет установлен в Redis.
Кроме того, обратите внимание на использование JsonPropertyNameAttribute
Description
свойства для дальнейшей настройки именования хранилища.
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] }'
Сопоставление данных при использовании типа хранилища Hashes
При использовании типа хранилища Hashes соединитель Redis предоставляет собственную схему для сопоставления.
Это приложение mapper сопоставляет каждое свойство с парой "поле-значение", как поддерживается командой Redis HSET
.
Для свойств данных и векторных свойств можно указать переопределение имен полей для использования в хранилище, которое отличается от имен свойств в модели данных. Это не поддерживается для ключей, так как ключи не могут быть названы в Redis.
Переопределение имени свойства выполняется путем задания StoragePropertyName
параметра с помощью атрибутов модели данных или определения записи.
Ниже приведен пример модели данных с StoragePropertyName
набором атрибутов и их настройке в 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>