Skip to content

Commit 87f2693

Browse files
authored
Add console RAG Ollama sample using Deepseek-R1
Merge pull request #77 from microsoft/bruno-add-rag-deepseek-r1
2 parents 1b5158f + c74f627 commit 87f2693

File tree

5 files changed

+306
-1
lines changed

5 files changed

+306
-1
lines changed

03-CoreGenerativeAITechniques/src/CoreGenerativeAITechniques.sln

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "07 Reasoning", "07 Reasonin
5757
EndProject
5858
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReasoningLabs-01-SK", "ReasoningLabs-01-SK\ReasoningLabs-01-SK.csproj", "{7274D8C3-EC9B-4D54-B472-CBE1E44C39AC}"
5959
EndProject
60+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RAGSimple-15Ollama-DeepSeekR1", "RAGSimple-15Ollama-DeepSeekR1\RAGSimple-15Ollama-DeepSeekR1.csproj", "{8DDF748E-B27D-3139-9BCE-B1276B817345}"
61+
EndProject
6062
Global
6163
GlobalSection(SolutionConfigurationPlatforms) = preSolution
6264
Debug|Any CPU = Debug|Any CPU
@@ -143,6 +145,10 @@ Global
143145
{7274D8C3-EC9B-4D54-B472-CBE1E44C39AC}.Debug|Any CPU.Build.0 = Debug|Any CPU
144146
{7274D8C3-EC9B-4D54-B472-CBE1E44C39AC}.Release|Any CPU.ActiveCfg = Release|Any CPU
145147
{7274D8C3-EC9B-4D54-B472-CBE1E44C39AC}.Release|Any CPU.Build.0 = Release|Any CPU
148+
{8DDF748E-B27D-3139-9BCE-B1276B817345}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
149+
{8DDF748E-B27D-3139-9BCE-B1276B817345}.Debug|Any CPU.Build.0 = Debug|Any CPU
150+
{8DDF748E-B27D-3139-9BCE-B1276B817345}.Release|Any CPU.ActiveCfg = Release|Any CPU
151+
{8DDF748E-B27D-3139-9BCE-B1276B817345}.Release|Any CPU.Build.0 = Release|Any CPU
146152
EndGlobalSection
147153
GlobalSection(SolutionProperties) = preSolution
148154
HideSolutionNode = FALSE
@@ -168,6 +174,7 @@ Global
168174
{33CE094D-6C79-4151-87D5-8D49A9982328} = {F5798C6F-98D6-4411-A5F0-F928CBA64095}
169175
{B0A1DF75-4625-45D5-87B0-29F7290F63E1} = {F5798C6F-98D6-4411-A5F0-F928CBA64095}
170176
{7274D8C3-EC9B-4D54-B472-CBE1E44C39AC} = {301F771F-CBE6-4D34-A24A-02F7DE5463DC}
177+
{8DDF748E-B27D-3139-9BCE-B1276B817345} = {B5980212-D3CF-4A46-94EA-3B22EFAD1257}
171178
EndGlobalSection
172179
GlobalSection(ExtensibilityGlobals) = postSolution
173180
SolutionGuid = {961EEBAB-4149-4AA4-BEE7-9DAAE4C94133}

03-CoreGenerativeAITechniques/src/RAGSimple-10SKOllama/Program.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@
9494
int docId = 1;
9595
foreach (var fact in facts)
9696
{
97-
SpectreConsoleOutput.WriteGreen($"Adding docId: {docId} - fact: {fact}", true);
97+
SpectreConsoleOutput.WriteYellow($"Adding docId: {docId} - fact: {fact}", true);
9898
await memory.ImportTextAsync(fact, docId.ToString());
9999
docId++;
100100
}
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
// Copyright (c) 2024
2+
// Author : Bruno Capuano
3+
// Change Log :
4+
// - Sample console application to use a local model hosted in ollama and semantic memory for search
5+
//
6+
// The MIT License (MIT)
7+
//
8+
// Permission is hereby granted, free of charge, to any person obtaining a copy
9+
// of this software and associated documentation files (the "Software"), to deal
10+
// in the Software without restriction, including without limitation the rights
11+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
// copies of the Software, and to permit persons to whom the Software is
13+
// furnished to do so, subject to the following conditions:
14+
//
15+
// The above copyright notice and this permission notice shall be included in
16+
// all copies or substantial portions of the Software.
17+
//
18+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24+
// THE SOFTWARE.
25+
26+
#pragma warning disable SKEXP0001, SKEXP0003, SKEXP0010, SKEXP0011, SKEXP0050, SKEXP0052, SKEXP0070
27+
28+
using Microsoft.KernelMemory;
29+
using Microsoft.KernelMemory.AI.Ollama;
30+
using Microsoft.SemanticKernel;
31+
32+
var ollamaEndpoint = "http://localhost:11434";
33+
//var modelIdChat = "phi";
34+
var modelIdChat = "deepseek-r1";
35+
var modelIdEmbeddings = "all-minilm";
36+
37+
// questions
38+
var questionEn = "What is Bruno's favourite super hero?";
39+
var questionEn2 = "How many people watched Venom 3?";
40+
var question = questionEn2;
41+
42+
// intro
43+
SpectreConsoleOutput.DisplayTitle(modelIdChat);
44+
SpectreConsoleOutput.DisplayTitleH2($"This program will answer the following question:");
45+
SpectreConsoleOutput.DisplayTitleH3(question);
46+
SpectreConsoleOutput.DisplayTitleH2($"Approach:");
47+
SpectreConsoleOutput.DisplayTitleH3($"1st approach will be to ask the question directly to the {modelIdChat} model.");
48+
SpectreConsoleOutput.DisplayTitleH3("2nd approach will be to add facts to a semantic memory and ask the question again");
49+
50+
SpectreConsoleOutput.DisplayTitleH2($"{modelIdChat} response (no memory).");
51+
52+
// Create a kernel with Azure OpenAI chat completion
53+
var builder = Kernel.CreateBuilder().AddOllamaChatCompletion(
54+
modelId: modelIdChat,
55+
endpoint: new Uri(ollamaEndpoint));
56+
57+
Kernel kernel = builder.Build();
58+
var response = kernel.InvokePromptStreamingAsync(question);
59+
await foreach (var result in response)
60+
{
61+
SpectreConsoleOutput.WriteGreen(result.ToString());
62+
}
63+
64+
// separator
65+
Console.WriteLine("");
66+
SpectreConsoleOutput.DisplaySeparator();
67+
68+
var configOllamaKernelMemory = new OllamaConfig
69+
{
70+
Endpoint = ollamaEndpoint,
71+
TextModel = new OllamaModelConfig(modelIdChat),
72+
EmbeddingModel = new OllamaModelConfig(modelIdEmbeddings, 2048)
73+
};
74+
var memory = new KernelMemoryBuilder()
75+
.WithOllamaTextGeneration(configOllamaKernelMemory)
76+
.WithOllamaTextEmbeddingGeneration(configOllamaKernelMemory)
77+
.Build();
78+
79+
var informationList = new List<string>
80+
{
81+
"Gisela's favourite super hero is Batman",
82+
"Gisela watched Venom 3 2 weeks ago",
83+
"Bruno's favourite super hero is Invincible",
84+
"Bruno went to the cinema to watch Venom 3",
85+
"Bruno doesn't like the super hero movie: Eternals",
86+
"ACE and Goku watched the movies Venom 3 and Eternals",
87+
};
88+
89+
SpectreConsoleOutput.DisplayTitleH2($"Information List");
90+
91+
int docId = 1;
92+
foreach (var info in informationList)
93+
{
94+
SpectreConsoleOutput.WriteYellow($"Adding docId: {docId} - information: {info}", true);
95+
await memory.ImportTextAsync(info, docId.ToString());
96+
docId++;
97+
}
98+
99+
SpectreConsoleOutput.DisplayTitleH3($"Asking question with memory: {question}");
100+
var answer = memory.AskStreamingAsync(question);
101+
await foreach (var result in answer)
102+
{
103+
SpectreConsoleOutput.WriteGreen($"{result.Result}");
104+
SpectreConsoleOutput.DisplayNewLine();
105+
SpectreConsoleOutput.DisplayNewLine();
106+
SpectreConsoleOutput.WriteYellow($"Token Usage", true);
107+
foreach (var token in result.TokenUsage)
108+
{
109+
SpectreConsoleOutput.WriteYellow($"\t>> Tokens IN: {token.TokenizerTokensIn}", true);
110+
SpectreConsoleOutput.WriteYellow($"\t>> Tokens OUT: {token.TokenizerTokensOut}", true);
111+
}
112+
113+
SpectreConsoleOutput.DisplayNewLine();
114+
SpectreConsoleOutput.WriteYellow($"Sources", true);
115+
foreach (var source in result.RelevantSources)
116+
{
117+
SpectreConsoleOutput.WriteYellow($"\t>> Content Type: {source.SourceContentType}", true);
118+
SpectreConsoleOutput.WriteYellow($"\t>> Document Id: {source.DocumentId}", true);
119+
SpectreConsoleOutput.WriteYellow($"\t>> 1st Partition Text: {source.Partitions.FirstOrDefault().Text}", true);
120+
SpectreConsoleOutput.WriteYellow($"\t>> 1st Partition Relevance: {source.Partitions.FirstOrDefault().Relevance}", true);
121+
SpectreConsoleOutput.DisplayNewLine();
122+
}
123+
124+
125+
}
126+
127+
Console.WriteLine($"");
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net9.0</TargetFramework>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<Nullable>enable</Nullable>
8+
</PropertyGroup>
9+
10+
<ItemGroup>
11+
<PackageReference Include="Microsoft.KernelMemory.Abstractions" Version="0.96.250120.1" />
12+
<PackageReference Include="Microsoft.KernelMemory.AI.Ollama" Version="0.96.250120.1" />
13+
<PackageReference Include="Microsoft.KernelMemory.Core" Version="0.96.250120.1" />
14+
<PackageReference Include="Microsoft.SemanticKernel" Version="1.34.0">
15+
<TreatAsUsed>true</TreatAsUsed>
16+
</PackageReference>
17+
<PackageReference Include="Microsoft.SemanticKernel.Connectors.Ollama" Version="1.34.0-alpha" />
18+
<PackageReference Include="Spectre.Console" Version="0.49.2-preview.0.70" />
19+
</ItemGroup>
20+
</Project>
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
// Copyright (c) 2024
2+
// Author : Bruno Capuano
3+
// Change Log :
4+
//
5+
// The MIT License (MIT)
6+
//
7+
// Permission is hereby granted, free of charge, to any person obtaining a copy
8+
// of this software and associated documentation files (the "Software"), to deal
9+
// in the Software without restriction, including without limitation the rights
10+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
// copies of the Software, and to permit persons to whom the Software is
12+
// furnished to do so, subject to the following conditions:
13+
//
14+
// The above copyright notice and this permission notice shall be included in
15+
// all copies or substantial portions of the Software.
16+
//
17+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23+
// THE SOFTWARE.
24+
25+
#pragma warning disable SKEXP0001, SKEXP0003, SKEXP0010, SKEXP0011, SKEXP0050, SKEXP0052
26+
using Spectre.Console;
27+
28+
public static class SpectreConsoleOutput
29+
{
30+
public static void DisplayTitle(string modelId = "")
31+
{
32+
var title = $"{modelId} RAG";
33+
34+
AnsiConsole.Write(new FigletText(title).Centered().Color(Color.Purple));
35+
}
36+
37+
public static void DisplayTitleH2(string subtitle)
38+
{
39+
AnsiConsole.MarkupLine($"[bold][blue]=== {subtitle} ===[/][/]");
40+
AnsiConsole.MarkupLine($"");
41+
}
42+
43+
public static void DisplayTitleH3(string subtitle)
44+
{
45+
AnsiConsole.MarkupLine($"");
46+
AnsiConsole.MarkupLine($"[bold]>> {subtitle}[/]");
47+
AnsiConsole.MarkupLine($"");
48+
}
49+
50+
public static void DisplaySeparator()
51+
{
52+
AnsiConsole.MarkupLine($"");
53+
AnsiConsole.MarkupLine($"[bold][blue]==============[/][/]");
54+
AnsiConsole.MarkupLine($"");
55+
}
56+
57+
public static void DisplayNewLine()
58+
{
59+
AnsiConsole.MarkupLine($"");
60+
}
61+
62+
public static void WriteGreen(string message, bool newLine = false)
63+
{
64+
Write(message, "green", newLine);
65+
}
66+
public static void WriteYellow(string message, bool newLine = false)
67+
{
68+
Write(message, "yellow", newLine);
69+
}
70+
public static void WriteBlue(string message, bool newLine = false)
71+
{
72+
Write(message, "blue", newLine);
73+
}
74+
75+
public static void Write(string message, string color = "yellow", bool newLine = false)
76+
{
77+
try
78+
{
79+
AnsiConsole.Markup($"[{color}]{message}[/]");
80+
}
81+
catch
82+
{
83+
AnsiConsole.Write($"{message}");
84+
}
85+
if (newLine)
86+
{
87+
AnsiConsole.MarkupLine($"");
88+
}
89+
}
90+
91+
public static void DisplayQuestion(string question)
92+
{
93+
AnsiConsole.MarkupLine($"[bold][blue]>>Q: {question}[/][/]");
94+
AnsiConsole.MarkupLine($"");
95+
}
96+
public static void DisplayAnswerStart(string answerPrefix)
97+
{
98+
AnsiConsole.Markup($"[bold][blue]>> {answerPrefix}:[/][/]");
99+
}
100+
101+
public static void DisplayFilePath(string prefix, string filePath)
102+
{
103+
var path = new TextPath(filePath);
104+
105+
AnsiConsole.Markup($"[bold][blue]>> {prefix}: [/][/]");
106+
AnsiConsole.Write(path);
107+
AnsiConsole.MarkupLine($"");
108+
}
109+
110+
public static void DisplaySubtitle(string prefix, string content)
111+
{
112+
AnsiConsole.Markup($"[bold][blue]>> {prefix}: [/][/]");
113+
AnsiConsole.WriteLine(content);
114+
AnsiConsole.MarkupLine($"");
115+
}
116+
117+
public static int AskForNumber(string question)
118+
{
119+
var number = AnsiConsole.Ask<int>(@$"[green]{question}[/]");
120+
return number;
121+
}
122+
123+
public static string AskForString(string question)
124+
{
125+
var response = AnsiConsole.Ask<string>(@$"[green]{question}[/]");
126+
return response;
127+
}
128+
129+
public static List<string> SelectScenarios()
130+
{
131+
// Ask for the user's favorite fruits
132+
var scenarios = AnsiConsole.Prompt(
133+
new MultiSelectionPrompt<string>()
134+
.Title("Select the [green]Phi 3 Vision scenarios[/] to run?")
135+
.PageSize(10)
136+
.Required(true)
137+
.MoreChoicesText("[grey](Move up and down to reveal more scenarios)[/]")
138+
.InstructionsText(
139+
"[grey](Press [blue]<space>[/] to toggle a scenario, " +
140+
"[green]<enter>[/] to accept)[/]")
141+
.AddChoiceGroup("Select an image to be analyzed", new[]
142+
{"foggyday.png","foggydaysmall.png","petsmusic.png","ultrarunningmug.png",
143+
})
144+
.AddChoices(new[] {
145+
"Type the image path to be analyzed",
146+
"Type a question"
147+
})
148+
);
149+
return scenarios;
150+
}
151+
}

0 commit comments

Comments
 (0)