Skip to content

Commit

Permalink
.Net: Add new getting started samples (microsoft#4191)
Browse files Browse the repository at this point in the history
### Motivation and Context

Closes microsoft#4019 

### Description

<!-- Describe your changes, the overall approach, the underlying design.
These notes will help understanding how your code works. Thanks! -->

### Contribution Checklist

<!-- Before submitting this PR, please make sure: -->

- [ ] The code builds clean without any errors or warnings
- [ ] The PR follows the [SK Contribution
Guidelines](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md)
and the [pre-submission formatting
script](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md#development-scripts)
raises no violations
- [ ] All unit tests pass, and I have added new tests where possible
- [ ] I didn't break anyone 😄
  • Loading branch information
markwallace-microsoft committed Dec 12, 2023
1 parent cb73546 commit 4487ca3
Show file tree
Hide file tree
Showing 8 changed files with 247 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
* This example shows how to use GPT Vision model with different content types (text and image).
*/
// ReSharper disable once InconsistentNaming
public static class Example75_GPTVision
public static class Example74_GPTVision
{
public static async Task RunAsync()
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright (c) Microsoft. All rights reserved.

using System;
using System.Threading.Tasks;
using Microsoft.SemanticKernel;

/**
* This example shows how to create and use a <see cref="Kernel"/>.
*/
public static class Step1_Create_Kernel
{
/// <summary>
/// Show how to create a <see cref="Kernel"/> and use it to execute prompts.
/// </summary>
public static async Task RunAsync()
{
// Create a kernel with OpenAI chat completion
Kernel kernel = Kernel.CreateBuilder()
.AddOpenAIChatCompletion(
modelId: TestConfiguration.OpenAI.ChatModelId,
apiKey: TestConfiguration.OpenAI.ApiKey)
.Build();

// Example 1. Invoke the kernel with a prompt and display the result
Console.WriteLine(await kernel.InvokePromptAsync("What color is the sky?"));

// Example 2. Invoke the kernel with a templated prompt and display the result
KernelArguments arguments = new() { { "topic", "sea" } };
Console.WriteLine(await kernel.InvokePromptAsync("What color is the {{$topic}}?", arguments));

// Example 3. Invoke the kernel with a templated prompt and stream the results to the display
await foreach (var update in kernel.InvokePromptStreamingAsync("What color is the {{$topic}}? Provide a detailed explanation.", arguments))
{
Console.Write(update);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright (c) Microsoft. All rights reserved.

// ReSharper disable once InconsistentNaming
using System;
using System.Threading.Tasks;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Connectors.OpenAI;
/**
* This example shows how to load a <see cref="KernelPlugin"/> instances.
*/
public static class Step2_Add_Plugins
{
/// <summary>
/// Shows different ways to load a <see cref="KernelPlugin"/> instances.
/// </summary>
public static async Task RunAsync()
{
// Create a kernel with OpenAI chat completion
IKernelBuilder kernelBuilder = Kernel.CreateBuilder();
kernelBuilder.AddOpenAIChatCompletion(
modelId: TestConfiguration.OpenAI.ChatModelId,
apiKey: TestConfiguration.OpenAI.ApiKey);
kernelBuilder.Plugins.AddFromType<TimeInformation>();
Kernel kernel = kernelBuilder.Build();

// Example 1. Invoke the kernel with a prompt that asks the AI for inromation it cannot provide and may hallucinate
Console.WriteLine(await kernel.InvokePromptAsync("How many days until Christmas?"));

// Example 2. Invoke the kernel with a templated prompt that invokes a plugin and display the result
Console.WriteLine(await kernel.InvokePromptAsync("The current time is {{TimeInformation.GetCurrentUtcTime}}. How many days until Christmas?"));

// Example 3. Invoke the kernel with a prompt and allow the AI to automatically invoke functions
OpenAIPromptExecutionSettings settings = new() { ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions };
Console.WriteLine(await kernel.InvokePromptAsync("How many days until Christmas? Explain your thinking.", new(settings)));
}

/// <summary>
/// A plugin that returns the current time.
/// </summary>
public class TimeInformation
{
[KernelFunction]
public string GetCurrentUtcTime() => DateTime.UtcNow.ToString("R");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// Copyright (c) Microsoft. All rights reserved.

using System;
using System.Threading.Tasks;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.PromptTemplate.Handlebars;

/**
* This example shows how to create a prompt <see cref="KernelFunction"/> from a YAML resource.
*/
public static class Step3_Yaml_Prompt
{
/// <summary>
/// Show how to create a prompt <see cref="KernelFunction"/> from a YAML resource.
/// </summary>
public static async Task RunAsync()
{
// Create a kernel with OpenAI chat completion
Kernel kernel = Kernel.CreateBuilder()
.AddOpenAIChatCompletion(
modelId: TestConfiguration.OpenAI.ChatModelId,
apiKey: TestConfiguration.OpenAI.ApiKey)
.Build();

// Load prompt from resource
var function = kernel.CreateFunctionFromPromptYaml(GenerateStoryYaml);

// Invoke the prompt function and display the result
Console.WriteLine(await kernel.InvokeAsync(function, arguments: new()
{
{ "topic", "Dog" },
{ "length", "3" },
}));

// Load prompt from resource
function = kernel.CreateFunctionFromPromptYaml(GenerateStoryHandlebarsYaml, new HandlebarsPromptTemplateFactory());

// Invoke the prompt function and display the result
Console.WriteLine(await kernel.InvokeAsync(function, arguments: new()
{
{ "topic", "Cat" },
{ "length", "3" },
}));
}

private const string GenerateStoryYaml = @"
name: GenerateStory
template: |
Tell a story about {{$topic}} that is {{$length}} sentences long.
template_format: semantic-kernel
description: A function that generates a story about a topic.
input_variables:
- name: topic
description: The topic of the story.
is_required: true
- name: length
description: The number of sentences in the story.
is_required: true
output_variable:
description: The generated story.
execution_settings:
- temperature: 0.6
";

private const string GenerateStoryHandlebarsYaml = @"
name: GenerateStory
template: |
Tell a story about {{topic}} that is {{length}} sentences long.
template_format: handlebars
description: A function that generates a story about a topic.
input_variables:
- name: topic
description: The topic of the story.
is_required: true
- name: length
description: The number of sentences in the story.
is_required: true
output_variable:
description: The generated story.
execution_settings:
- model_id: gpt-4
temperature: 0.6
- model_id: gpt-3.5-turbo
temperature: 0.4
- temperature: 0.5
";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// Copyright (c) Microsoft. All rights reserved.

// ReSharper disable once InconsistentNaming
// ReSharper disable once InconsistentNaming
using System;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.SemanticKernel;
using RepoUtils;

// ReSharper disable once InconsistentNaming
/**
* This example shows how to using Dependency Injection with the Semantic Kernel
*/
public static class Step4_Dependency_Injection
{
/// <summary>
/// Show how to create a <see cref="Kernel"/> that participates in Dependency Injection.
/// </summary>
public static async Task RunAsync()
{
// If an application follows DI guidelines, the following line is unnecessary because DI will inject an instance of the KernelClient class to a class that references it.
// DI container guidelines - https://learn.microsoft.com/en-us/dotnet/core/extensions/dependency-injection-guidelines#recommendations
var serviceProvider = BuildServiceProvider();
var kernel = serviceProvider.GetRequiredService<Kernel>();

// Invoke the kernel with a templated prompt and stream the results to the display
KernelArguments arguments = new() { { "topic", "earth when viewed from space" } };
await foreach (var update in kernel.InvokePromptStreamingAsync("What color is the {{$topic}}? Provide a detailed explanation.", arguments))
{
Console.Write(update);
}
}

/// <summary>
/// Build a ServiceProvdier that can be used to resolve services.
/// </summary>
private static ServiceProvider BuildServiceProvider()
{
var collection = new ServiceCollection();
collection.AddSingleton<ILoggerFactory>(ConsoleLogger.LoggerFactory);

var kernelBuilder = collection.AddKernel();
kernelBuilder.Services.AddOpenAITextGeneration(TestConfiguration.OpenAI.ModelId, TestConfiguration.OpenAI.ApiKey);
kernelBuilder.Plugins.AddFromType<TimeInformation>();

return collection.BuildServiceProvider();
}

/// <summary>
/// A plugin that returns the current time.
/// </summary>
public class TimeInformation
{
private readonly ILogger _logger;

public TimeInformation(ILoggerFactory loggerFactory)
{
this._logger = loggerFactory.CreateLogger(typeof(TimeInformation));
}

[KernelFunction]
public string GetCurrentUtcTime()
{
var utcNow = DateTime.UtcNow.ToString("R");
this._logger.LogInformation("Returning current time {0}", utcNow);
return utcNow;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,7 @@
using Microsoft.Extensions.Logging;
using Microsoft.SemanticKernel;

#pragma warning disable RCS1110 // Declare type inside namespace.
#pragma warning disable CA5394

public static class Example74_Pipelining
public static class Step5_Pipelining
{
/// <summary>
/// Provides an example of combining multiple functions into a single function that invokes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<OutputType>Exe</OutputType>
<IsPackable>false</IsPackable>
<!-- Suppress: "Declare types in namespaces", "Require ConfigureAwait", "Experimental" -->
<NoWarn>CA1050,CA1707,CA2007,VSTHRD111,CS1591,SKEXP0001,SKEXP0002,SKEXP0003,SKEXP0004,SKEXP0010,SKEXP0011,,SKEXP0012,SKEXP0020,SKEXP0021,SKEXP0022,SKEXP0023,SKEXP0024,SKEXP0025,SKEXP0026,SKEXP0027,SKEXP0028,SKEXP0029,SKEXP0030,SKEXP0031,SKEXP0032,SKEXP0040,SKEXP0041,SKEXP0050,SKEXP0051,SKEXP0052,SKEXP0053,SKEXP0054,SKEXP0055,SKEXP0060,SKEXP0061,SKEXP0101,SKEXP0102</NoWarn>
<NoWarn>CA1050,CA1707,CA2007,VSTHRD111,CS1591,RCS1110,CA5394,SKEXP0001,SKEXP0002,SKEXP0003,SKEXP0004,SKEXP0010,SKEXP0011,,SKEXP0012,SKEXP0020,SKEXP0021,SKEXP0022,SKEXP0023,SKEXP0024,SKEXP0025,SKEXP0026,SKEXP0027,SKEXP0028,SKEXP0029,SKEXP0030,SKEXP0031,SKEXP0032,SKEXP0040,SKEXP0041,SKEXP0050,SKEXP0051,SKEXP0052,SKEXP0053,SKEXP0054,SKEXP0055,SKEXP0060,SKEXP0061,SKEXP0101,SKEXP0102</NoWarn>
</PropertyGroup>
<ItemGroup>
<Compile Remove="Example12_SequentialPlanner.cs" />
Expand Down
8 changes: 4 additions & 4 deletions dotnet/samples/KernelSyntaxExamples/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ public static async Task Main(string[] args)
private static async Task RunExamplesAsync(string? filter, CancellationToken cancellationToken)
{
var examples = (Assembly.GetExecutingAssembly().GetTypes())
.Where(type => type.Name.StartsWith("Example", StringComparison.OrdinalIgnoreCase))
.Select(type => type.Name).ToList();

// Filter and run examples
Expand All @@ -43,15 +42,15 @@ private static async Task RunExamplesAsync(string? filter, CancellationToken can
{
try
{
Console.WriteLine($"Running {example}...");

var method = Assembly.GetExecutingAssembly().GetType(example)?.GetMethod("RunAsync");
if (method == null)
{
Console.WriteLine($"Example {example} not found");
// Skip if the type does not have a RunAsync method
continue;
}

Console.WriteLine($"Running {example}...");

bool hasCancellationToken = method.GetParameters().Any(param => param.ParameterType == typeof(CancellationToken));

var taskParameters = hasCancellationToken ? new object[] { cancellationToken } : null;
Expand Down Expand Up @@ -99,6 +98,7 @@ private static async Task SafeWaitAsync(this Task task,
try
{
await task.WaitAsync(cancellationToken);
Console.WriteLine();
Console.WriteLine("== DONE ==");
}
catch (ConfigurationNotFoundException ex)
Expand Down

0 comments on commit 4487ca3

Please sign in to comment.