mirror of
https://github.com/microsoft/semantic-kernel.git
synced 2026-10-12 02:19:06 +00:00
### Motivation and Context Following best practices for libraries outlined at https://learn.microsoft.com/en-us/dotnet/core/extensions/logging-library-authors, SK should generally be taking an ILoggerFactory rather than an ILogger. This allows individual components to each get a logger with its own category applied. ### 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 - [ ] I didn't break anyone 😄 --------- Co-authored-by: Shawn Callegari <[email protected]> Co-authored-by: Lee Miller <[email protected]>
106 lines
3.9 KiB
C#
106 lines
3.9 KiB
C#
// Copyright (c) Microsoft. All rights reserved.
|
|
|
|
using System;
|
|
using System.Net.Http;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Azure.AI.OpenAI;
|
|
using Azure.Core;
|
|
using Azure.Core.Pipeline;
|
|
using Azure.Identity;
|
|
using Microsoft.Extensions.Logging;
|
|
using Microsoft.SemanticKernel;
|
|
using Microsoft.SemanticKernel.AI.ChatCompletion;
|
|
using Microsoft.SemanticKernel.Connectors.AI.OpenAI.ChatCompletion;
|
|
using Microsoft.SemanticKernel.Diagnostics;
|
|
using RepoUtils;
|
|
|
|
// ReSharper disable once InconsistentNaming
|
|
public static class Example52_ApimAuth
|
|
{
|
|
public static async Task RunAsync()
|
|
{
|
|
// Azure API Management details
|
|
// For more information see 'Protect your Azure OpenAI API keys with Azure API Management' here: https://learn.microsoft.com/en-us/semantic-kernel/deploy/
|
|
var apimUri = new Uri(Env.Var("Apim__Endpoint"));
|
|
var subscriptionKey = Env.Var("Apim__SubscriptionKey");
|
|
|
|
// Use interactive browser login
|
|
string[] scopes = new string[] { "https://cognitiveservices.azure.com/.default" };
|
|
var credential = new InteractiveBrowserCredential();
|
|
var requestContext = new TokenRequestContext(scopes);
|
|
var accessToken = await credential.GetTokenAsync(requestContext);
|
|
|
|
// Create HttpClient and include subscription key as a default header
|
|
var httpClient = new HttpClient();
|
|
httpClient.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", subscriptionKey);
|
|
|
|
// Configure OpenAIClient to use
|
|
// - Custom HttpClient with subscription key header
|
|
// - Diagnostics to log error response headers from APIM to aid problem determination
|
|
// - Authentication using BearerTokenCredential retrieved via interactive browser login
|
|
var clientOptions = new OpenAIClientOptions
|
|
{
|
|
Transport = new HttpClientTransport(httpClient),
|
|
Diagnostics =
|
|
{
|
|
LoggedHeaderNames = { "ErrorSource", "ErrorReason", "ErrorMessage", "ErrorScope", "ErrorSection", "ErrorStatusCode" },
|
|
ApplicationId = Telemetry.HttpUserAgent,
|
|
IsTelemetryEnabled = Telemetry.IsTelemetryEnabled,
|
|
}
|
|
};
|
|
var openAIClient = new OpenAIClient(apimUri, new BearerTokenCredential(accessToken), clientOptions);
|
|
|
|
// Create logger factory with default level as warning
|
|
using ILoggerFactory loggerFactory = LoggerFactory.Create(builder =>
|
|
{
|
|
builder
|
|
.SetMinimumLevel(LogLevel.Warning)
|
|
.AddConsole();
|
|
});
|
|
|
|
var kernel = Kernel.Builder
|
|
.WithLoggerFactory(loggerFactory)
|
|
.WithAIService<IChatCompletion>(TestConfiguration.AzureOpenAI.ChatDeploymentName, (loggerFactory, config) =>
|
|
new AzureChatCompletion(TestConfiguration.AzureOpenAI.ChatDeploymentName, openAIClient, loggerFactory))
|
|
.Build();
|
|
|
|
// Load semantic skill defined with prompt templates
|
|
string folder = RepoFiles.SampleSkillsPath();
|
|
|
|
var funSkill = kernel.ImportSemanticSkillFromDirectory(
|
|
folder,
|
|
"FunSkill");
|
|
|
|
// Run
|
|
var result = await kernel.RunAsync(
|
|
"I have no homework",
|
|
funSkill["Excuses"]
|
|
);
|
|
Console.WriteLine(result);
|
|
|
|
httpClient.Dispose();
|
|
}
|
|
}
|
|
|
|
public class BearerTokenCredential : TokenCredential
|
|
{
|
|
private readonly AccessToken _accessToken;
|
|
|
|
// Constructor that takes a Bearer token string and its expiration date
|
|
public BearerTokenCredential(AccessToken accessToken)
|
|
{
|
|
this._accessToken = accessToken;
|
|
}
|
|
|
|
public override AccessToken GetToken(TokenRequestContext requestContext, CancellationToken cancellationToken)
|
|
{
|
|
return this._accessToken;
|
|
}
|
|
|
|
public override ValueTask<AccessToken> GetTokenAsync(TokenRequestContext requestContext, CancellationToken cancellationToken)
|
|
{
|
|
return new ValueTask<AccessToken>(this._accessToken);
|
|
}
|
|
}
|