Files
semantic-kernel/dotnet/samples/TelemetryExample/Program.cs
T
Gina TrioloandChris 3a7d3bdc5c .Net: Planner options improvements (#4793)
### Motivation and Context

<!-- Thank you for your contribution to the semantic-kernel repo!
Please help reviewers and future users, providing the following
information:
  1. Why is this change required?
  2. What problem does it solve?
  3. What scenario does it contribute to?
  4. If it fixes an open issue, please link to the issue here.
-->
Changes to improve consistency across the .NET planners. Addresses the
following:
- #4727 
- #4728 
- #4729 
- #4731 
- #4775 

### Description

<!-- Describe your changes, the overall approach, the underlying design.
These notes will help understanding how your code works. Thanks! -->
- Clean up planner options. Shared options live in parent class
(`PlannerOptions`). Other options reside in the planner-specific options
class (`HandlebarsPlannerOptions` or
`FunctionCallingStepwisePlannerOptions`).
- Change default name delimiter to dash (was underscore for function
calling stepwise planner). Update all tests accordingly. (Will explore
making this configurable in a separate issue/PR)
- Change how we get the list of available functions for Handlebars
planner, to reduce code duplication and get overridable options for
free.
- Make `MaxTokens` setting optional for function calling stepwise
planner (not yet supported for Handlebars planner)

### Contribution Checklist

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

- [x] The code builds clean without any errors or warnings
- [x] 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
- [x] All unit tests pass, and I have added new tests where possible
- [x] I didn't break anyone 😄

---------

Co-authored-by: Chris <[email protected]>
2024-02-06 21:32:21 +00:00

123 lines
4.4 KiB
C#

// Copyright (c) Microsoft. All rights reserved.
using System;
using System.Diagnostics;
using System.IO;
using System.Threading.Tasks;
using Azure.Monitor.OpenTelemetry.Exporter;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Planning.Handlebars;
using OpenTelemetry;
using OpenTelemetry.Metrics;
using OpenTelemetry.Trace;
/// <summary>
/// Example of telemetry in Semantic Kernel using Application Insights within console application.
/// </summary>
public sealed class Program
{
/// <summary>
/// Log level to be used by <see cref="ILogger"/>.
/// </summary>
/// <remarks>
/// <see cref="LogLevel.Information"/> is set by default. <para />
/// <see cref="LogLevel.Trace"/> will enable logging with more detailed information, including sensitive data. Should not be used in production. <para />
/// </remarks>
private const LogLevel MinLogLevel = LogLevel.Information;
/// <summary>
/// Instance of <see cref="ActivitySource"/> for the application activities.
/// </summary>
private static readonly ActivitySource s_activitySource = new("Telemetry.Example");
/// <summary>
/// The main entry point for the application.
/// </summary>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
public static async Task Main()
{
// Load configuration from environment variables or user secrets.
LoadUserSecrets();
var connectionString = TestConfiguration.ApplicationInsights.ConnectionString;
using var traceProvider = Sdk.CreateTracerProviderBuilder()
.AddSource("Microsoft.SemanticKernel*")
.AddSource("Telemetry.Example")
.AddAzureMonitorTraceExporter(options => options.ConnectionString = connectionString)
.Build();
using var meterProvider = Sdk.CreateMeterProviderBuilder()
.AddMeter("Microsoft.SemanticKernel*")
.AddAzureMonitorMetricExporter(options => options.ConnectionString = connectionString)
.Build();
using var loggerFactory = LoggerFactory.Create(builder =>
{
// Add OpenTelemetry as a logging provider
builder.AddOpenTelemetry(options =>
{
options.AddAzureMonitorLogExporter(options => options.ConnectionString = connectionString);
// Format log messages. This is default to false.
options.IncludeFormattedMessage = true;
});
builder.SetMinimumLevel(MinLogLevel);
});
var kernel = GetKernel(loggerFactory);
var planner = CreatePlanner();
using var activity = s_activitySource.StartActivity("Main");
Console.WriteLine("Operation/Trace ID:");
Console.WriteLine(Activity.Current?.TraceId);
var plan = await planner.CreatePlanAsync(kernel, "Write a poem about John Doe, then translate it into Italian.");
Console.WriteLine("Original plan:");
Console.WriteLine(plan.ToString());
var result = await plan.InvokeAsync(kernel).ConfigureAwait(false);
Console.WriteLine("Result:");
Console.WriteLine(result);
}
private static Kernel GetKernel(ILoggerFactory loggerFactory)
{
var folder = RepoFiles.SamplePluginsPath();
IKernelBuilder builder = Kernel.CreateBuilder();
builder.Services.AddSingleton(loggerFactory);
builder.AddAzureOpenAIChatCompletion(
deploymentName: TestConfiguration.AzureOpenAI.ChatDeploymentName,
modelId: TestConfiguration.AzureOpenAI.ChatModelId,
endpoint: TestConfiguration.AzureOpenAI.Endpoint,
apiKey: TestConfiguration.AzureOpenAI.ApiKey
).Build();
builder.Plugins.AddFromPromptDirectory(Path.Combine(folder, "WriterPlugin"));
return builder.Build();
}
private static HandlebarsPlanner CreatePlanner()
{
var plannerOptions = new HandlebarsPlannerOptions();
return new HandlebarsPlanner(plannerOptions);
}
private static void LoadUserSecrets()
{
IConfigurationRoot configRoot = new ConfigurationBuilder()
.AddEnvironmentVariables()
.AddUserSecrets<Program>()
.Build();
TestConfiguration.Initialize(configRoot);
}
}