Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "07 Reasoning", "07 Reasonin
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReasoningLabs-01-SK", "ReasoningLabs-01-SK\ReasoningLabs-01-SK.csproj", "{7274D8C3-EC9B-4D54-B472-CBE1E44C39AC}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RAGSimple-15Ollama-DeepSeekR1", "RAGSimple-15Ollama-DeepSeekR1\RAGSimple-15Ollama-DeepSeekR1.csproj", "{8DDF748E-B27D-3139-9BCE-B1276B817345}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -143,6 +145,10 @@ Global
{7274D8C3-EC9B-4D54-B472-CBE1E44C39AC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7274D8C3-EC9B-4D54-B472-CBE1E44C39AC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7274D8C3-EC9B-4D54-B472-CBE1E44C39AC}.Release|Any CPU.Build.0 = Release|Any CPU
{8DDF748E-B27D-3139-9BCE-B1276B817345}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8DDF748E-B27D-3139-9BCE-B1276B817345}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8DDF748E-B27D-3139-9BCE-B1276B817345}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8DDF748E-B27D-3139-9BCE-B1276B817345}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -168,6 +174,7 @@ Global
{33CE094D-6C79-4151-87D5-8D49A9982328} = {F5798C6F-98D6-4411-A5F0-F928CBA64095}
{B0A1DF75-4625-45D5-87B0-29F7290F63E1} = {F5798C6F-98D6-4411-A5F0-F928CBA64095}
{7274D8C3-EC9B-4D54-B472-CBE1E44C39AC} = {301F771F-CBE6-4D34-A24A-02F7DE5463DC}
{8DDF748E-B27D-3139-9BCE-B1276B817345} = {B5980212-D3CF-4A46-94EA-3B22EFAD1257}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {961EEBAB-4149-4AA4-BEE7-9DAAE4C94133}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@
int docId = 1;
foreach (var fact in facts)
{
SpectreConsoleOutput.WriteGreen($"Adding docId: {docId} - fact: {fact}", true);
SpectreConsoleOutput.WriteYellow($"Adding docId: {docId} - fact: {fact}", true);
await memory.ImportTextAsync(fact, docId.ToString());
docId++;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
// Copyright (c) 2024
// Author : Bruno Capuano
// Change Log :
// - Sample console application to use a local model hosted in ollama and semantic memory for search
//
// The MIT License (MIT)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#pragma warning disable SKEXP0001, SKEXP0003, SKEXP0010, SKEXP0011, SKEXP0050, SKEXP0052, SKEXP0070

using Microsoft.KernelMemory;
using Microsoft.KernelMemory.AI.Ollama;
using Microsoft.SemanticKernel;

var ollamaEndpoint = "http://localhost:11434";
//var modelIdChat = "phi";
var modelIdChat = "deepseek-r1";
var modelIdEmbeddings = "all-minilm";

// questions
var questionEn = "What is Bruno's favourite super hero?";
var questionEn2 = "How many people watched Venom 3?";
var question = questionEn2;

// intro
SpectreConsoleOutput.DisplayTitle(modelIdChat);
SpectreConsoleOutput.DisplayTitleH2($"This program will answer the following question:");
SpectreConsoleOutput.DisplayTitleH3(question);
SpectreConsoleOutput.DisplayTitleH2($"Approach:");
SpectreConsoleOutput.DisplayTitleH3($"1st approach will be to ask the question directly to the {modelIdChat} model.");
SpectreConsoleOutput.DisplayTitleH3("2nd approach will be to add facts to a semantic memory and ask the question again");

SpectreConsoleOutput.DisplayTitleH2($"{modelIdChat} response (no memory).");

// Create a kernel with Azure OpenAI chat completion
var builder = Kernel.CreateBuilder().AddOllamaChatCompletion(
modelId: modelIdChat,
endpoint: new Uri(ollamaEndpoint));

Kernel kernel = builder.Build();
var response = kernel.InvokePromptStreamingAsync(question);
await foreach (var result in response)
{
SpectreConsoleOutput.WriteGreen(result.ToString());
}

// separator
Console.WriteLine("");
SpectreConsoleOutput.DisplaySeparator();

var configOllamaKernelMemory = new OllamaConfig
{
Endpoint = ollamaEndpoint,
TextModel = new OllamaModelConfig(modelIdChat),
EmbeddingModel = new OllamaModelConfig(modelIdEmbeddings, 2048)
};
var memory = new KernelMemoryBuilder()
.WithOllamaTextGeneration(configOllamaKernelMemory)
.WithOllamaTextEmbeddingGeneration(configOllamaKernelMemory)
.Build();

var informationList = new List<string>
{
"Gisela's favourite super hero is Batman",
"Gisela watched Venom 3 2 weeks ago",
"Bruno's favourite super hero is Invincible",
"Bruno went to the cinema to watch Venom 3",
"Bruno doesn't like the super hero movie: Eternals",
"ACE and Goku watched the movies Venom 3 and Eternals",
};

SpectreConsoleOutput.DisplayTitleH2($"Information List");

int docId = 1;
foreach (var info in informationList)
{
SpectreConsoleOutput.WriteYellow($"Adding docId: {docId} - information: {info}", true);
await memory.ImportTextAsync(info, docId.ToString());
docId++;
}

SpectreConsoleOutput.DisplayTitleH3($"Asking question with memory: {question}");
var answer = memory.AskStreamingAsync(question);
await foreach (var result in answer)
{
SpectreConsoleOutput.WriteGreen($"{result.Result}");
SpectreConsoleOutput.DisplayNewLine();
SpectreConsoleOutput.DisplayNewLine();
SpectreConsoleOutput.WriteYellow($"Token Usage", true);
foreach (var token in result.TokenUsage)
{
SpectreConsoleOutput.WriteYellow($"\t>> Tokens IN: {token.TokenizerTokensIn}", true);
SpectreConsoleOutput.WriteYellow($"\t>> Tokens OUT: {token.TokenizerTokensOut}", true);
}

SpectreConsoleOutput.DisplayNewLine();
SpectreConsoleOutput.WriteYellow($"Sources", true);
foreach (var source in result.RelevantSources)
{
SpectreConsoleOutput.WriteYellow($"\t>> Content Type: {source.SourceContentType}", true);
SpectreConsoleOutput.WriteYellow($"\t>> Document Id: {source.DocumentId}", true);
SpectreConsoleOutput.WriteYellow($"\t>> 1st Partition Text: {source.Partitions.FirstOrDefault().Text}", true);
SpectreConsoleOutput.WriteYellow($"\t>> 1st Partition Relevance: {source.Partitions.FirstOrDefault().Relevance}", true);
SpectreConsoleOutput.DisplayNewLine();
}


}

Console.WriteLine($"");
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.KernelMemory.Abstractions" Version="0.96.250120.1" />
<PackageReference Include="Microsoft.KernelMemory.AI.Ollama" Version="0.96.250120.1" />
<PackageReference Include="Microsoft.KernelMemory.Core" Version="0.96.250120.1" />
<PackageReference Include="Microsoft.SemanticKernel" Version="1.34.0">
<TreatAsUsed>true</TreatAsUsed>
</PackageReference>
<PackageReference Include="Microsoft.SemanticKernel.Connectors.Ollama" Version="1.34.0-alpha" />
<PackageReference Include="Spectre.Console" Version="0.49.2-preview.0.70" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
// Copyright (c) 2024
// Author : Bruno Capuano
// Change Log :
//
// The MIT License (MIT)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#pragma warning disable SKEXP0001, SKEXP0003, SKEXP0010, SKEXP0011, SKEXP0050, SKEXP0052
using Spectre.Console;

public static class SpectreConsoleOutput
{
public static void DisplayTitle(string modelId = "")
{
var title = $"{modelId} RAG";

AnsiConsole.Write(new FigletText(title).Centered().Color(Color.Purple));
}

public static void DisplayTitleH2(string subtitle)
{
AnsiConsole.MarkupLine($"[bold][blue]=== {subtitle} ===[/][/]");
AnsiConsole.MarkupLine($"");
}

public static void DisplayTitleH3(string subtitle)
{
AnsiConsole.MarkupLine($"");
AnsiConsole.MarkupLine($"[bold]>> {subtitle}[/]");
AnsiConsole.MarkupLine($"");
}

public static void DisplaySeparator()
{
AnsiConsole.MarkupLine($"");
AnsiConsole.MarkupLine($"[bold][blue]==============[/][/]");
AnsiConsole.MarkupLine($"");
}

public static void DisplayNewLine()
{
AnsiConsole.MarkupLine($"");
}

public static void WriteGreen(string message, bool newLine = false)
{
Write(message, "green", newLine);
}
public static void WriteYellow(string message, bool newLine = false)
{
Write(message, "yellow", newLine);
}
public static void WriteBlue(string message, bool newLine = false)
{
Write(message, "blue", newLine);
}

public static void Write(string message, string color = "yellow", bool newLine = false)
{
try
{
AnsiConsole.Markup($"[{color}]{message}[/]");
}
catch
{
AnsiConsole.Write($"{message}");
}
if (newLine)
{
AnsiConsole.MarkupLine($"");
}
}

public static void DisplayQuestion(string question)
{
AnsiConsole.MarkupLine($"[bold][blue]>>Q: {question}[/][/]");
AnsiConsole.MarkupLine($"");
}
public static void DisplayAnswerStart(string answerPrefix)
{
AnsiConsole.Markup($"[bold][blue]>> {answerPrefix}:[/][/]");
}

public static void DisplayFilePath(string prefix, string filePath)
{
var path = new TextPath(filePath);

AnsiConsole.Markup($"[bold][blue]>> {prefix}: [/][/]");
AnsiConsole.Write(path);
AnsiConsole.MarkupLine($"");
}

public static void DisplaySubtitle(string prefix, string content)
{
AnsiConsole.Markup($"[bold][blue]>> {prefix}: [/][/]");
AnsiConsole.WriteLine(content);
AnsiConsole.MarkupLine($"");
}

public static int AskForNumber(string question)
{
var number = AnsiConsole.Ask<int>(@$"[green]{question}[/]");
return number;
}

public static string AskForString(string question)
{
var response = AnsiConsole.Ask<string>(@$"[green]{question}[/]");
return response;
}

public static List<string> SelectScenarios()
{
// Ask for the user's favorite fruits
var scenarios = AnsiConsole.Prompt(
new MultiSelectionPrompt<string>()
.Title("Select the [green]Phi 3 Vision scenarios[/] to run?")
.PageSize(10)
.Required(true)
.MoreChoicesText("[grey](Move up and down to reveal more scenarios)[/]")
.InstructionsText(
"[grey](Press [blue]<space>[/] to toggle a scenario, " +
"[green]<enter>[/] to accept)[/]")
.AddChoiceGroup("Select an image to be analyzed", new[]
{"foggyday.png","foggydaysmall.png","petsmusic.png","ultrarunningmug.png",
})
.AddChoices(new[] {
"Type the image path to be analyzed",
"Type a question"
})
);
return scenarios;
}
}