Redis コネクタの使用 (プレビュー)
警告
セマンティック カーネル ベクター ストア機能はプレビュー段階であり、破壊的変更を必要とする機能強化は、リリース前の限られた状況で引き続き発生する可能性があります。
概要
Redis Vector Store コネクタを使用して、Redis のデータにアクセスして管理できます。 コネクタはハッシュ モードと JSON モードの両方をサポートしており、選択したモードによって、サポートされるその他の機能が決まります。
コネクタには次の特性があります。
機能領域 | サポート |
---|---|
コレクションのマップ | プレフィックスが 〘に設定された Redis インデックス <collectionname>: |
サポートされているキー プロパティの種類 | string |
サポートされているデータ プロパティ型 | ハッシュを使用する場合:
JSON にシリアル化できる任意の型 |
サポートされているベクター プロパティ型 |
|
サポートされているインデックスの種類 |
|
サポートされている距離関数 |
|
レコード内の複数のベクターをサポートします | はい |
IsFilterable がサポートされていますか? | はい |
IsFullTextSearchable がサポートされていますか? | はい |
StoragePropertyName がサポートされていますか? | Hashes: はいを使用する場合 JSON: No を使用する場合は、代わりに JsonSerializerOptions と JsonPropertyNameAttribute を使用します。 詳細については、こちらを参照してください。 |
作業の開始
Redis Vector Store コネクタ nuget パッケージをプロジェクトに追加します。
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());
名前付きコレクションへの直接参照を構築できます。 その場合は、Redis にデータを格納する方法に応じて、JSON または Hashes インスタンスを選択する必要があります。
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
インスタンスを渡すことができます:ハッシュまたは 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 extras を使用してセマンティック カーネルをインストールします。
pip install semantic-kernel[redis]
その後、 RedisStore
クラスを使用してベクター ストア インスタンスを作成できます。これにより、Redis インスタンスに接続するために REDIS_CONNECTION_STRING
環境変数が使用されます。これらの値を直接指定することもできます。
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 用の 2 種類のコレクションがあります。
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 コレクションはどちらもアップサート時にデータ形式として dict を使用しますが、ディクテーションの構造は異なります。
JSON コレクションの例については、 redis ドキュメント を参照してください。
Hashset コレクションの場合、キー フィールドを name
として hset コマンドを使用し、データ フィールドを mapping -> metadata
として使用し、ベクトルを mapping -> [vector_field_name]
として使用します。詳細については、 こちら を参照してください。
この概念の詳細については、 erialization のドキュメントを参照してください。
作業の開始
次の依存関係を pom.xml
に追加して、Maven プロジェクトにセマンティック カーネル Redis データ コネクタの最新バージョンを含めます。
<dependency>
<groupId>com.microsoft.semantic-kernel</groupId>
<artifactId>semantickernel-data-redis</artifactId>
<version>[LATEST]</version>
</dependency>
その後、redis クライアント (JedisPooled) をパラメーターとして使用して、 RedisVectorStore
クラスを使用してベクター ストア インスタンスを作成できます。
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 では、キー プレフィックスのシステムを使用して、レコードをインデックスに関連付けます。 インデックスを作成するときに、そのインデックスで使用する 1 つ以上のプレフィックスを指定できます。 レコードをそのインデックスに関連付ける場合は、そのレコードのキーにプレフィックスを追加する必要があります。
たとえば、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 では、データを格納するための 2 つのモード (JSON とハッシュ) がサポートされています。 Redis コネクタは両方のストレージの種類をサポートしており、マッピングは選択したストレージの種類によって異なります。
JSON ストレージの種類を使用する場合のデータ マッピング
JSON ストレージの種類を使用する場合、Redis コネクタはマッピングを行うために System.Text.Json.JsonSerializer
を使用します。
Redis は個別のキーと値を持つレコードを格納するため、マッパーはキーを除くすべてのプロパティを 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 でこのデータ型を設定する方法の例を次に示します。
また、ストレージの名前付けをさらにカスタマイズするために、Description
プロパティでのJsonPropertyNameAttribute
の使用にも注意してください。
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 コネクタはマッピングを行う独自のマッパーを提供します。
このマッパーは、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>