Skip to content

Commit a6b26f0

Browse files
committed
Added handlebar query rewriter.
1 parent a3ea95a commit a6b26f0

6 files changed

Lines changed: 104 additions & 389 deletions

File tree

Directory.Packages.props

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,21 @@
33
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
44
</PropertyGroup>
55
<ItemGroup>
6-
<PackageVersion Include="Alkampfer.KernelMemory.ElasticSearch" Version="0.8.0" />
6+
<PackageVersion Include="Alkampfer.KernelMemory.ElasticSearch" Version="0.9.0-alpha0005" />
77
<PackageVersion Include="Azure.AI.OpenAI" Version="1.0.0-beta.17" />
88
<PackageVersion Include="CommandDotNet.Spectre" Version="3.0.2" />
99
<PackageVersion Include="Microsoft.Extensions.Http" Version="8.0.0" />
1010
<PackageVersion Include="Microsoft.Extensions.Http.Resilience" Version="8.6.0" />
1111
<PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="8.0.0" />
1212
<PackageVersion Include="Microsoft.Extensions.Logging.Debug" Version="8.0.0" />
13-
<PackageVersion Include="Microsoft.KernelMemory.Abstractions" Version="0.61.240524.1" />
14-
<PackageVersion Include="Microsoft.KernelMemory.Core" Version="0.61.240524.1" />
13+
<PackageVersion Include="Microsoft.KernelMemory.Abstractions" Version="0.65.240620.1" />
14+
<PackageVersion Include="Microsoft.KernelMemory.Core" Version="0.65.240620.1" />
1515
<PackageVersion Include="Microsoft.ML.Tokenizers" Version="0.22.0-preview.24271.1" />
16-
<PackageVersion Include="Microsoft.SemanticKernel" Version="1.13.0" />
17-
<PackageVersion Include="Microsoft.SemanticKernel.PromptTemplates.Handlebars" Version="1.13.0" />
18-
<PackageVersion Include="Microsoft.SemanticKernel.Yaml" Version="1.13.0" />
19-
<PackageVersion Include="Microsoft.SemanticKernel.Abstractions" Version="1.13.0" />
20-
<PackageVersion Include="Microsoft.SemanticKernel.Core" Version="1.13.0" />
16+
<PackageVersion Include="Microsoft.SemanticKernel" Version="1.15.1" />
17+
<PackageVersion Include="Microsoft.SemanticKernel.PromptTemplates.Handlebars" Version="1.15.1" />
18+
<PackageVersion Include="Microsoft.SemanticKernel.Yaml" Version="1.15.1" />
19+
<PackageVersion Include="Microsoft.SemanticKernel.Abstractions" Version="1.15.1" />
20+
<PackageVersion Include="Microsoft.SemanticKernel.Core" Version="1.15.1" />
2121
<PackageVersion Include="Polly.Core" Version="8.4.1" />
2222
<PackageVersion Include="TiktokenSharp" Version="1.1.4" />
2323
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="8.0.0" />

src/KernelMemory.Extensions.ConsoleTest/Samples/CustomSearchPipelineBase.cs

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
using Microsoft.KernelMemory.Prompts;
1616
using Microsoft.SemanticKernel;
1717
using Spectre.Console;
18-
using static KernelMemory.Extensions.QueryPipeline.SemanticKernelQueryRewriter;
1918

2019
namespace SemanticMemory.Samples;
2120

@@ -82,11 +81,16 @@ public async Task RunSample2()
8281
.Title("Select the query executor to use")
8382
.AddChoices(["KernelMemory Default", "Cohere CommandR+"]));
8483

84+
var queryRewriterTool = AnsiConsole.Prompt(new SelectionPrompt<string>()
85+
.Title("Select query rewriter")
86+
.AddChoices(["Semantic Kernel Base", "Semantic Kernel Handlebar"]));
87+
8588
var kernelBuider = CreateBasicKernelBuilder();
8689
var builder = CreateBasicKernelMemoryBuilder(
8790
services,
8891
storageToUse == "elasticsearch",
89-
queryExecutorToUse == "Cohere CommandR+");
92+
queryExecutorToUse == "Cohere CommandR+",
93+
queryRewriterTool == "Semantic Kernel Handlebar");
9094
var kernelMemory = builder.Build<MemoryServerless>();
9195
var kernel = kernelBuider.Build();
9296

@@ -221,7 +225,8 @@ private static async Task IndexDocument(MemoryServerless kernelMemory, string do
221225
private static IKernelMemoryBuilder CreateBasicKernelMemoryBuilder(
222226
ServiceCollection services,
223227
bool useElasticSearch,
224-
bool useCohereCommandRPlusForQueryExecutor)
228+
bool useCohereCommandRPlusForQueryExecutor,
229+
bool useHandlebarQueryRewriter)
225230
{
226231
// we need a series of services to use Kernel Memory, the first one is
227232
// an embedding service that will be used to create dense vector for
@@ -283,6 +288,7 @@ private static IKernelMemoryBuilder CreateBasicKernelMemoryBuilder(
283288

284289
services.AddSingleton<IKernelMemoryBuilder>(kernelMemoryBuilder);
285290
services.AddSingleton<CohereReRanker>();
291+
services.AddSingleton<HandlebarSemanticKernelQueryRewriter>();
286292
services.AddSingleton<SemanticKernelQueryRewriter>();
287293
services.AddSingleton<StandardVectorSearchQueryHandler>();
288294
services.AddSingleton<KeywordSearchQueryHandler>();
@@ -315,7 +321,15 @@ private static IKernelMemoryBuilder CreateBasicKernelMemoryBuilder(
315321
}
316322

317323
config.SetReRanker<CohereReRanker>();
318-
config.SetQueryRewriter<SemanticKernelQueryRewriter>();
324+
325+
if (useHandlebarQueryRewriter)
326+
{
327+
config.SetQueryRewriter<HandlebarSemanticKernelQueryRewriter>();
328+
}
329+
else
330+
{
331+
config.SetQueryRewriter<SemanticKernelQueryRewriter>();
332+
}
319333
});
320334
return kernelMemoryBuilder;
321335
}

src/KernelMemory.Extensions/KernelMemory.Extensions.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,4 +67,8 @@
6767
<ProjectReference Include="..\KernelMemory.Extensions.Interfaces\KernelMemory.Extensions.Interfaces.csproj" />
6868
</ItemGroup>
6969

70+
<ItemGroup>
71+
<Folder Include="QueryPipeline\data\" />
72+
</ItemGroup>
73+
7074
</Project>

src/KernelMemory.Extensions/QueryPipeline/IConversationQueryRewriter.cs

Lines changed: 74 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
using Microsoft.SemanticKernel;
22
using Microsoft.SemanticKernel.ChatCompletion;
3+
using Microsoft.SemanticKernel.Connectors.OpenAI;
4+
using Microsoft.SemanticKernel.PromptTemplates.Handlebars;
35
using System.Threading.Tasks;
46

57
namespace KernelMemory.Extensions.QueryPipeline;
@@ -66,14 +68,80 @@ be a standalone question that contains also the previous context. If there is no
6668

6769
return result?.ToString() ?? question;
6870
}
71+
}
72+
73+
/// <summary>
74+
/// Allows some parametrization of the rewriter.
75+
/// </summary>
76+
public class SemanticKernelQueryRewriterOptions
77+
{
78+
public string? ModelId { get; set; }
79+
80+
public float Temperature { get; set; } = 0.0f;
81+
}
6982

70-
/// <summary>
71-
/// Allows some parametrization of the rewriter.
72-
/// </summary>
73-
public class SemanticKernelQueryRewriterOptions
83+
public class HandlebarSemanticKernelQueryRewriter : IConversationQueryRewriter
84+
{
85+
private readonly SemanticKernelQueryRewriterOptions _semanticKernelQueryRewriterOptions;
86+
private readonly Kernel _kernel;
87+
private readonly KernelFunction _chatFunction;
88+
89+
public HandlebarSemanticKernelQueryRewriter(
90+
SemanticKernelQueryRewriterOptions semanticKernelQueryRewriterOptions,
91+
Kernel kernel)
7492
{
75-
public string? ModelId { get; set; }
93+
_semanticKernelQueryRewriterOptions = semanticKernelQueryRewriterOptions;
94+
_kernel = kernel;
95+
96+
// Create a template for chat with settings
97+
_chatFunction = kernel.CreateFunctionFromPrompt(new PromptTemplateConfig()
98+
{
99+
Name = "TestRewrite",
100+
Description = "Rewrite a query for kernel memory.",
101+
Template = @"system:
102+
* Given the following conversation history and the users next question,rephrase the question to be a stand alone question.
103+
If the conversation is irrelevant or empty, just restate the original question.
104+
Do not add more details than necessary to the question.
105+
106+
chat history:
107+
{{#each history}}
108+
question:
109+
{{question}}
110+
answer:
111+
{{answer}}
112+
{{/each}}
113+
114+
Follow up Input: {{ chat_input }}
115+
Standalone Question:",
116+
TemplateFormat = "handlebars",
117+
InputVariables =
118+
[
119+
new() { Name = "chat_input", Description = "New question of the user", IsRequired = false, Default = "" },
120+
new() { Name = "history", Description = "The history of the RAG CHAT.", IsRequired = true }
121+
],
122+
ExecutionSettings =
123+
{
124+
{ "default", new OpenAIPromptExecutionSettings()
125+
{
126+
MaxTokens = 1000,
127+
Temperature = 0,
128+
ModelId = "gpt35",
129+
}
130+
},
131+
}
132+
},
133+
promptTemplateFactory: new HandlebarsPromptTemplateFactory());
134+
}
76135

77-
public float Temperature { get; set; } = 0.0f;
136+
public async Task<string> RewriteAsync(Conversation conversation, string question)
137+
{
138+
KernelArguments ka = new();
139+
ka["chat_input"] = question;
140+
141+
ka["history"] = conversation.GetQuestions();
142+
143+
var result = await _kernel.InvokeAsync(_chatFunction, ka);
144+
145+
return result?.ToString() ?? question;
78146
}
79147
}

0 commit comments

Comments
 (0)