From 30308f8bb69039aed484cadff5aea903286e6168 Mon Sep 17 00:00:00 2001 From: xbotter Date: Thu, 4 Jan 2024 10:04:29 +0800 Subject: [PATCH] Add support for filtering memories by tags in SK Plugin (#226) ## Motivation and Context (Why the change? What's the scenario?) Add support for filtering memories by tags in memory.search and memory.ask methods. --- .../SemanticKernelPlugin/MemoryPlugin.cs | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/clients/dotnet/SemanticKernelPlugin/MemoryPlugin.cs b/clients/dotnet/SemanticKernelPlugin/MemoryPlugin.cs index 11386c9d0..96a6f01ba 100644 --- a/clients/dotnet/SemanticKernelPlugin/MemoryPlugin.cs +++ b/clients/dotnet/SemanticKernelPlugin/MemoryPlugin.cs @@ -26,7 +26,6 @@ namespace Microsoft.KernelMemory; /// * memory.search /// * memory.delete /// -/// TODO / not supported: filters on tags /// public class MemoryPlugin { @@ -338,12 +337,15 @@ public async Task SearchAsync( double minRelevance = 0, [ /*SKName(LimitParam),*/ Description("Maximum number of memories to return"), DefaultValue(1)] int limit = 1, + [ /*SKName(TagsParam),*/ Description("Memories tags to search for information"), DefaultValue(null)] + TagCollectionWrapper? tags = null, CancellationToken cancellationToken = default) { SearchResult result = await this._memory .SearchAsync( query: query, index: index ?? this._defaultIndex, + filter: TagsToMemoryFilter(tags ?? this._defaultRetrievalTags), minRelevance: minRelevance, limit: limit, cancellationToken: cancellationToken).ConfigureAwait(false); @@ -373,12 +375,15 @@ public async Task AskAsync( string? index = null, [ /*SKName(MinRelevanceParam),*/ Description("Minimum relevance of the sources to consider"), DefaultValue(0d)] double minRelevance = 0, + [ /*SKName(TagsParam),*/ Description("Memories tags to search for information"), DefaultValue(null)] + TagCollectionWrapper? tags = null, ILoggerFactory? loggerFactory = null, CancellationToken cancellationToken = default) { MemoryAnswer answer = await this._memory.AskAsync( question: question, index: index ?? this._defaultIndex, + filter: TagsToMemoryFilter(tags ?? this._defaultRetrievalTags), minRelevance: minRelevance, cancellationToken: cancellationToken).ConfigureAwait(false); return answer.Result; @@ -425,4 +430,21 @@ private async Task WaitForDocumentReadinessAsync(string documentId, Cancellation // Nothing to do } } + + private static MemoryFilter? TagsToMemoryFilter(TagCollection? tags) + { + if (tags == null) + { + return null; + } + + var filters = new MemoryFilter(); + + foreach (var tag in tags) + { + filters.Add(tag.Key, tag.Value); + } + + return filters; + } }