C# - Semantic Kernel의 "Basic Loading of the Kernel" 예제
아래의 예제를 보면,
Breadcrumbssemantic-kernel/samples/notebooks/dotnet/01-basic-loading-the-kernel.ipynb
; https://github.com/microsoft/semantic-kernel/blob/main/samples/notebooks/dotnet/01-basic-loading-the-kernel.ipynb
Kernel 개체를 
Generic Host처럼 초기화하는 것을 보여줍니다.
해당 코드에서는 NullLogger를 사용해서,
ILogger myLogger = NullLogger.Instance;
IKernel kernel_2 = Kernel.Builder
    .WithLogger(myLogger)
    .Build();
아무런 출력이 없지만 이것을 우리가 임의로 만든 ConsoleLogger로,
using Microsoft.Extensions.Logging;
namespace ConsoleApp1;
// https://learn.microsoft.com/en-us/dotnet/core/extensions/custom-logging-provider
public class ConsoleLogger : ILogger
{
    public IDisposable? BeginScope<TState>(TState state) where TState : notnull => default!;
    public bool IsEnabled(LogLevel logLevel)
    {
        return true;
    }
    public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter)
    {
        Console.WriteLine(formatter(state, exception));
    }
}
지난번 글의 summarize 함수와 연결해 열역학 법칙에 대해서만 테스트해 보면,
private static async Task<int> Main(string[] args)
{
    // ...[생략]...
    ILogger myLogger = new ConsoleLogger();
    var kernel = Kernel.Builder
        .WithLogger(myLogger)
        .Build();
    // ...[생략]...
    var prompt = @"{{$input}}
One line TLDR with the fewest words.";
    var summarize = kernel.CreateSemanticFunction(prompt);
    string text1 = @"
1st Law of Thermodynamics - Energy cannot be created or destroyed.
2nd Law of Thermodynamics - For a spontaneous process, the entropy of the universe increases.
3rd Law of Thermodynamics - A perfect crystal at zero Kelvin has zero entropy.";
    Console.WriteLine(await summarize.InvokeAsync(text1));
    return 0;
}
이런 결과를 얻게 됩니다.
Extracting blocks from template: {{$input}}
One line TLDR with the fewest words.
Rendering string template: {{$input}}
One line TLDR with the fewest words.
Extracting blocks from template: {{$input}}
One line TLDR with the fewest words.
Rendering list of 2 blocks
Rendered prompt:
1st Law of Thermodynamics - Energy cannot be created or destroyed.
2nd Law of Thermodynamics - For a spontaneous process, the entropy of the universe increases.
3rd Law of Thermodynamics - A perfect crystal at zero Kelvin has zero entropy.
One line TLDR with the fewest words.
Energy conserved, entropy increases, zero entropy at 0K.
자, 그다음 KernelConfig도 이렇게 바꿔서 초기화할 수 있습니다.
KernelConfig kernelConfig = new KernelConfig();
kernelConfig.AddOpenAITextCompletionService(
    "davinci-openai",
    "text-davinci-003",               // OpenAI Model name
    apiKey       // OpenAI API Key
);
ILogger myLogger = new ConsoleLogger();
var kernel = Kernel.Builder
    .WithLogger(myLogger)
    .WithConfiguration(kernelConfig)
    .Build();
kernelConfig에는 1개 이상의 서비스를 연결해 둘 수 있는데요, 예를 들어 아래는 OpenAI와 Azure OpenAI 서비스를 함께 지정하고 있습니다. (혹은 동일한 OpenAI여도 Model 이름이 다른 서비스를 추가할 수도 있습니다.)
kernelConfig.AddAzureTextCompletionService(
    "Azure_curie",                          // alias used in the prompt templates' config.json
    "my-finetuned-Curie",                   // Azure OpenAI *Deployment ID*
    "https://contoso.openai.azure.com/",    // Azure OpenAI *Endpoint*
    "...your Azure OpenAI Key..."           // Azure OpenAI *Key*
);
kernelConfig.AddOpenAITextCompletionService(
    "davinci-openai",
    "text-davinci-003",               // OpenAI Model name
    apiKey       // OpenAI API Key
);
저렇게 2개의 서비스를 추가한 경우, 기본적으로 첫 번째 서비스가 "default"로 처리된다고 합니다. 만약, 기본 서비스를 다른 걸로 지정하고 싶다면 SetDefaultTextCompletionService 메서드를 호출하면 되는데요, 아래의 코드는 위의 예제에서 두 번째 OpenAI 서비스를 default로 지정하고 있습니다.
kernelConfig.SetDefaultTextCompletionService("davinci-openai");
아하... 여기서 수수께끼가 하나 풀리는군요. ^^ 지난 글에서 AddOpenAITextCompletionService의 첫 번째 인자가 "Service ID"라고만 설명돼 있어 잘 모르겠다고 했는데 실은 임의의 문자열로 kernelConfig에 추가되는 서비스를 구분하기 위한 식별자로서만 의미가 있었던 것입니다.
따라서, 그냥 아무 문자열이나 고유하게만 붙여주면 되는 것입니다. ^^
[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]