Udostępnij za pośrednictwem


Semantyczne jądro — przewodnik migracji platformy .Net w wersji 1

Uwaga

Ten dokument nie jest końcowy i będzie coraz lepiej!

Ten przewodnik ma ułatwić uaktualnienie z wersji wstępnej 1 zestawu SDK jądra semantycznego platformy .NET do wersji 1 lub nowszej. Wersja sprzed v1 używana jako odwołanie do tego dokumentu była 0.26.231009 wersją, która była ostatnią przed pierwszą wersją beta, gdy większość zmian zaczęła mieć miejsce.

Zmiany pakietu

W wyniku ponownego definiowania, usuwania i zmieniania nazw wielu pakietów, a także biorąc pod uwagę, że wykonaliśmy dobre czyszczenie oraz uproszczenie przestrzeni nazw, wiele naszych starych pakietów musiało zostać przemianowanych, uznane za przestarzałe i usunięte. W poniższej tabeli przedstawiono zmiany w naszych pakietach.

Wszystkie pakiety rozpoczynające się od Microsoft.SemanticKernel zostały obcięte prefiksem .. dla zwięzłości.

Poprzednia nazwa V1 Nazwa Wersja Przyczyna
.. Connectors.AI.HuggingFace .. Connectors.HuggingFace podgląd
..Connectors.AI.OpenAI .. Connectors.OpenAI v1
.. Connectors.AI.Oobabooga MyIA.SemanticKernel.Connectors.AI.Oobabooga alfa Łącznik oparty na społeczności
⚠️ Nie jest jeszcze gotowy na wersję 1+
.. Connectors.Memory.Kusto ..Connectors.Kusto alfa
..Connectors.Memory.DuckDB ..Connectors.DuckDB alfa
..Connectors.Memory.Pinecone .. Connectors.Pinecone alfa
..Connectors.Memory.Redis ..Connectors.Redis alfa
.. Connectors.Memory.Qdrant ..Connectors.Qdrant alfa
-- ..Connectors.Postgres alfa
.. Connectors.Memory.AzureCognitiveSearch ..Connectors.Memory.AzureAISearch alfa
.. Functions.Semantic -Usunięte- Scalono w Core
..Niezawodność.Podstawowy -Usunięte- Zastąpione przez iniekcję zależności platformy .NET
.. Reliability.Polly -Usunięte- Zastąpione przez wstrzykiwanie zależności w .NET
.. TemplateEngine.Basic -Usunięte- Scalono w rdzeniu
.. Planners.Core ..Planners.OpenAI
Planners.Handlebars
podgląd
-- .. Experimental.Agents alfa
-- .. Experimental.Orchestration.Flow v1

Pakiety niezawodnościowe — zastąpione przez wstrzykiwanie zależności w .NET

Pakiety Reliability Basic i Polly można teraz używać, korzystając z rozszerzenia kolekcji usług wstrzykiwania zależności platformy .net, aby wstrzyknąć żądane polityki odporności do wystąpień HttpClient.

// Before
var retryConfig = new BasicRetryConfig
{
    MaxRetryCount = 3,
    UseExponentialBackoff = true,
};
retryConfig.RetryableStatusCodes.Add(HttpStatusCode.Unauthorized);
var kernel = new KernelBuilder().WithRetryBasic(retryConfig).Build();
// After
builder.Services.ConfigureHttpClientDefaults(c =>
{
    // Use a standard resiliency policy, augmented to retry on 401 Unauthorized for this example
    c.AddStandardResilienceHandler().Configure(o =>
    {
        o.Retry.ShouldHandle = args => ValueTask.FromResult(args.Outcome.Result?.StatusCode is HttpStatusCode.Unauthorized);
    });
});

Usunięcie pakietu oraz wymagane zmiany

Upewnij się, że jeśli używasz dowolnego z poniższych pakietów, są zgodne z najnowszą wersją używaną przez V1.

Nazwa pakietu Wersja
Microsoft.Extensions.Configuration 8.0.0
Microsoft.Extensions.Configuration.Binder 8.0.0
Microsoft.Extensions.Configuration.EnvironmentVariables 8.0.0
Microsoft.Extensions.Configuration.Json 8.0.0
Microsoft.Extensions.Configuration.UserSecrets 8.0.0
Microsoft.Extensions.DependencyInjection 8.0.0
Microsoft.Extensions.DependencyInjection.Abstractions 8.0.0
Microsoft.Extensions.Http 8.0.0
Microsoft.Extensions.Http.Resilience 8.0.0
Microsoft.Extensions.Logging 8.0.0
Microsoft.Extensions.Logging.Abstractions 8.0.0
Microsoft.Extensions.Logging.Console 8.0.0

Zmiany nazw konwencji

Wiele z naszych wewnętrznych konwencji nazewnictwa zostało zmienionych w celu lepszego odzwierciedlenia nazw społeczności sztucznej inteligencji. Gdy OpenAI zaczęło wprowadzać ogromne zmiany i terminy takie jak Prompt, Plugins, Models, RAG zyskiwały na znaczeniu, stało się jasne, że musimy dostosować się do tych terminów, aby ułatwić społeczności zrozumienie i korzystanie z zestawu SDK.

Poprzednia nazwa Nazwa V1
Semantyczna funkcja Funkcja wywoływania
Funkcja natywna Funkcja metody
Zmienna kontekstowa Argument jądra
Ustawienia żądania Ustawienia wykonania polecenia
Uzupełnianie tekstu Generowanie tekstu
Generowanie obrazu Tekst do obrazu
Zręczność Wtyczka

Zmiany nazwy kodu

Po zmianie nazwy konwencji wiele nazw kodu zostało również zmienionych, aby lepiej odzwierciedlać nowe konwencje nazewnictwa. Skróty zostały również usunięte, aby kod był bardziej czytelny.

Poprzednia nazwa Nazwa V1
Kontekstowe zmienne ArgumentyJądra
ContextVariables.Set KernelArguments.Add
IImageGenerationService ITextToImageService
ITextCompletionService ITextGenerationService
Kernel.CreateSemanticFunction Kernel.CreateFunctionFromPrompt
Kernel.ImportFunctions Kernel.ImportPluginFrom____
ImportowanieFunkcjiSemantycznychZKataloguKernel ImportujWtyczkęZKataloguPromptówKernela
Kernel.RunAsync Kernel.InvokeAsync
NativeFunction MethodFunction
OpenAIRequestSettings UstawieniaWykonaniaPromptuOpenAI
UstawieniaŻądania UstawieniaWykonywaniaPromptów
SkException KernelException
SkFunction KernelFunction
SKFunctionMetadata KernelFunctionAttribute
SKJsonSchema KernelJsonSchema
SKParameterMetadata KernelParameterMetadata
SKPluginCollection KernelPluginCollection
SKReturnParameterMetadata KernelReturnParameterMetadata
SemanticFunction PromptFunction
SkContext FunctionResult (dane wyjściowe)

Uproszczenia przestrzeni nazw

Wcześniej stare przestrzenie nazw miały głęboką hierarchię, która odpowiadała nazwom katalogów w projektach w relacji 1:1. Jest to powszechna praktyka, ale oznaczało, że konsumenci pakietów jądra semantycznego musieli dodać wiele różnych elementów using w swoim kodzie. Postanowiliśmy zmniejszyć liczbę przestrzeni nazw w pakietach jądra semantycznego, aby większość funkcji znajduje się w głównej Microsoft.SemanticKernel przestrzeni nazw. Aby uzyskać więcej szczegółów zobacz poniższą sekcję.

Poprzednia nazwa Nazwa wersji 1
Microsoft.SemanticKernel.Orchestration Microsoft.SemanticKernel
Microsoft.SemanticKernel.Connectors.AI.* Microsoft.SemanticKernel.Connectors.*
Microsoft.SemanticKernel.SemanticFunctions Microsoft.SemanticKernel
Microsoft.SemanticKernel.Events Microsoft.SemanticKernel
Microsoft.SemanticKernel.AI.* Microsoft.SemanticKernel.*
Microsoft.SemanticKernel.Connectors.AI.OpenAI.* Microsoft.SemanticKernel.Connectors.OpenAI
Microsoft.SemanticKernel.Connectors.AI.HuggingFace.* Microsoft.SemanticKernel.Connectors.HuggingFace

Jądro

Kod do tworzenia i używania Kernel wystąpienia został uproszczony. Interfejs IKernel został wyeliminowany, ponieważ deweloperzy nie powinni tworzyć własnej Kernel implementacji. Klasa Kernel reprezentuje kolekcję usług i wtyczek. Bieżąca instancja Kernel jest dostępna wszędzie, co jest zgodne z filozofią projektowania zawartej w jądrze semantycznym.

  • IKernel interfejs został zmieniony na klasę Kernel .

  • Kernel.ImportFunctions został usunięty i zastąpiony przez Kernel.ImportPluginFrom____, gdzie ____ może być Functions, Object, PromptDirectory, Type, Grp lub OpenAIAsync, itd.

    // Before
    var textFunctions = kernel.ImportFunctions(new StaticTextPlugin(), "text");
    
    // After
    var textFunctions = kernel.ImportPluginFromObject(new StaticTextPlugin(), "text");
    
  • Kernel.RunAsync został usunięty i zastąpiony przez Kernel.InvokeAsync. Kolejność parametrów przesunięta, gdzie funkcja jest pierwszą.

    // Before
    KernelResult result = kernel.RunAsync(textFunctions["Uppercase"], "Hello World!");
    
    // After
    FunctionResult result = kernel.InvokeAsync(textFunctions["Uppercase"], new() { ["input"] = "Hello World!" });
    
  • Kernel.InvokeAsyncteraz zwraca wartość FunctionResult zamiast .KernelResult

  • Kernel.InvokeAsync dotyczy tylko jednej funkcji na wywołanie jako pierwszy parametr. Potokowanie danych nie jest obsługiwane, użyj przykładu 60, aby osiągnąć zachowanie łańcucha.

    ❌ Nieobsługiwane

    KernelResult result = await kernel.RunAsync(" Hello World! ",
        textFunctions["TrimStart"],
        textFunctions["TrimEnd"],
        textFunctions["Uppercase"]);
    

    ✔️ Jedna funkcja na wywołanie

    var trimStartResult = await kernel.InvokeAsync(textFunctions["TrimStart"], new() { ["input"] = " Hello World! " });
    var trimEndResult = await kernel.InvokeAsync(textFunctions["TrimEnd"], new() { ["input"] = trimStartResult.GetValue<string>() });
    var finalResult = await kernel.InvokeAsync(textFunctions["Uppercase"], new() { ["input"] = trimEndResult.GetValue<string>() });
    

    ✔️ Łączenie łańcuchowe przy użyciu iniekcji jądra wtyczki

    // Plugin using Kernel injection
    public class MyTextPlugin
    {
        [KernelFunction]
        public async Task<string> Chain(Kernel kernel, string input)
        {
            var trimStartResult = await kernel.InvokeAsync("textFunctions", "TrimStart", new() { ["input"] = input });
            var trimEndResult = await kernel.InvokeAsync("textFunctions", "TrimEnd", new() { ["input"] = trimStartResult.GetValue<string>() });
            var finalResult = await kernel.InvokeAsync("textFunctions", "Uppercase", new() { ["input"] = trimEndResult.GetValue<string>() });
    
            return finalResult.GetValue<string>();
        }
    }
    
    var plugin = kernel.ImportPluginFromObject(new MyTextPlugin(), "textFunctions");
    var finalResult = await kernel.InvokeAsync(plugin["Chain"], new() { ["input"] = " Hello World! "});
    
  • Kernel.InvokeAsync nie akceptuje już ciągu jako danych wejściowych, zamiast tego użyj wystąpienia KernelArguments. Funkcja jest teraz pierwszym argumentem, a argument wejściowy musi zostać podany jako instancja KernelArguments.

    // Before
    var result = await kernel.RunAsync("I missed the F1 final race", excuseFunction);
    
    // After
    var result = await kernel.InvokeAsync(excuseFunction, new() { ["input"] = "I missed the F1 final race" });
    
  • Kernel.ImportSemanticFunctionsFromDirectory został usunięty i zastąpiony przez Kernel.ImportPluginFromPromptDirectory.

  • Kernel.CreateSemanticFunction został usunięty i zastąpiony przez Kernel.CreateFunctionFromPrompt.

    • Argumenty: OpenAIRequestSettings jest teraz OpenAIPromptExecutionSettings

Zmienne kontekstowe

ContextVariables został ponownie zdefiniowany jakoKernelArguments i jest teraz słownikiem, gdzie klucz jest nazwą argumentu, a wartość jest wartością argumentu. Metody takie jak Set i Get zostały usunięte, a wspólny słownik Dodaj lub indeksator [] do ustawiania i pobierania wartości należy użyć zamiast tego.

// Before
var variables = new ContextVariables("Today is: ");
variables.Set("day", DateTimeOffset.Now.ToString("dddd", CultureInfo.CurrentCulture));

// After
var arguments = new KernelArguments() {
  ["input"] = "Today is: ",
  ["day"] = DateTimeOffset.Now.ToString("dddd", CultureInfo.CurrentCulture)
};

// Initialize directly or use the dictionary indexer below
arguments["day"] = DateTimeOffset.Now.ToString("dddd", CultureInfo.CurrentCulture);

Konstruktor jądra

Wiele zmian zostało wprowadzonych do naszego KernelBuilder, aby uczynić go bardziej intuicyjnym i łatwiejszym w użyciu, a także bardziej zgodnym z podejściem budowniczych .NET oraz uproszczonym.

  • Tworzenie KernelBuilder można teraz zrealizować tylko przy użyciu metody Kernel.CreateBuilder().

    Ta zmiana upraszcza i ułatwia korzystanie z narzędzia KernelBuilder w dowolnej bazie kodu, zapewniając jeden główny sposób korzystania z konstruktora zamiast wielu sposobów, które zapewniają złożoność i nakład pracy konserwacyjnych.

    // Before
    IKernel kernel = new KernelBuilder().Build();
    
    // After
    var builder = Kernel.CreateBuilder().Build();
    
  • Nazwę KernelBuilder.With... zmieniono na KernelBuilder.Add...

    • Nazwę polecenia WithOpenAIChatCompletionService zmieniono na AddOpenAIChatCompletionService
    • WithAIService<ITextCompletion>
  • KernelBuilder.WithLoggerFactory nie jest bardziej używany, zamiast tego należy użyć metody wstrzykiwania zależności w celu dodania fabryki rejestratora.

    IKernelBuilder builder = Kernel.CreateBuilder();
    builder.Services.AddLogging(c => c.AddConsole().SetMinimumLevel(LogLevel.Information));
    
  • WithAIService<T> Wstrzykiwanie zależności

    Wcześniej KernelBuilder zawierał metodę WithAIService<T>, która została usunięta, a nowa właściwość ServiceCollection Services została udostępniona, aby umożliwić deweloperowi dodawanie usług do kontenera do wstrzykiwania zależności. tj.

    builder.Services.AddSingleton<ITextGenerationService>()
    

Wynik jądra systemu

Ponieważ jądro stało się tylko kontenerem dla wtyczek, a teraz wykonuje tylko jedną funkcję, nie było już potrzeby posiadania jednostki KernelResult i wszystkie wywołania funkcji z jądra teraz zwracają FunctionResult.

SkContext

Po wielu dyskusjach i opiniach wewnętrznie i od społeczności, aby uprościć interfejs API i uczynić go bardziej intuicyjnym, koncepcja SKContext została rozcieńczona w różnych jednostkach: KernelArguments dla danych wejściowych funkcji i FunctionResult dla danych wyjściowych funkcji.

Ze względu na ważną decyzję, aby Kernel stał się wymaganym argumentem wywołania funkcji, SKContext został usunięty, a KernelArguments oraz FunctionResult zostały wprowadzone.

KernelArguments to słownik, który przechowuje argumenty wejściowe dla wywołania funkcji, które wcześniej znajdowały się we SKContext.Variables właściwości .

FunctionResult jest wynikiem metody Kernel.InvokeAsync i przechowuje rezultat wywołania funkcji, które wcześniej było przechowywane we właściwości SKContext.Result.

Nowe abstrakcje wtyczki

  • KernelPlugin Entity: Przed wersją V1 nie było pojęcia jednostki skoncentrowanej na wtyczkach. Zmiany te weszły w wersji 1, a dla każdej funkcji dodanej do jądra otrzymasz wtyczkę, do której ona należy.

Niezmienność wtyczek

Wtyczki są domyślnie tworzone jako niezmienne przez naszą gotową do użycia implementację DefaultKernelPlugin, co oznacza, że nie można ich modyfikować ani zmieniać po utworzeniu.

Próba zaimportowania wtyczek, które mają taką samą nazwę w jądrze, spowoduje wyjątek naruszenia klucza.

Dodanie abstrakcji KernelPlugin umożliwia dynamiczne implementacje, które mogą obsługiwać modyfikowalność, a my przedstawiliśmy przykład, jak zaimplementować modyfikowalną wtyczkę w Przykładzie 69.

Łączenie wielu wtyczek w jeden

Próba utworzenia wtyczki z katalogu i późniejsze dodanie funkcji Method do tej samej wtyczki nie zadziała, chyba że użyjesz innego podejścia, takiego jak oddzielne utworzenie pierwotnej i dodatkowej wtyczki, a następnie połączenie ich w jedną, iterując po ich funkcjach w celu zebrania do końcowej wtyczki przy użyciu rozszerzenia kernel.ImportPluginFromFunctions("myAggregatePlugin", myAggregatedFunctions).

Użycie funkcji atrybutu eksperymentalnego.

Te funkcje zostały wprowadzone w celu oznaczenia niektórych funkcji w wersji 1, które możemy ewentualnie zmienić lub całkowicie usunąć.

Aby uzyskać szczegółowe informacje o trybie, zobacz tutaj listę bieżących wydanych funkcji eksperymentalnych.

Monituj pliki konfiguracji

Wprowadzono poważne zmiany w plikach konfiguracji podpowiedzi, obejmujące domyślne oraz różnorodne konfiguracje usługi i modelu.

Inne zmiany nazewnictwa, które należy zwrócić uwagę:

  • Nazwa completion została zmieniona na execution_settings
  • Nazwa input została zmieniona na input_variables
  • Nazwę defaultValue zmieniono na default
  • Nazwa parameters została zmieniona na input_variables
  • Każda nazwa właściwości w execution_settings, gdy zostanie dopasowana do service_id, będzie użyta do konfiguracji ustawień wykonywania usługi/modelu. tj.
    // The "service1" execution settings will be used to configure the OpenAIChatCompletion service
    Kernel kernel = Kernel.CreateBuilder()
        .AddOpenAIChatCompletion(serviceId: "service1", modelId: "gpt-4")
    

Przed

{
  "schema": 1,
  "description": "Given a text input, continue it with additional text.",
  "type": "completion",
  "completion": {
    "max_tokens": 4000,
    "temperature": 0.3,
    "top_p": 0.5,
    "presence_penalty": 0.0,
    "frequency_penalty": 0.0
  },
  "input": {
    "parameters": [
      {
        "name": "input",
        "description": "The text to continue.",
        "defaultValue": ""
      }
    ]
  }
}

Po

{
  "schema": 1,
  "description": "Given a text input, continue it with additional text.",
  "execution_settings": {
    "default": {
      "max_tokens": 4000,
      "temperature": 0.3,
      "top_p": 0.5,
      "presence_penalty": 0.0,
      "frequency_penalty": 0.0
    },
    "service1": {
      "model_id": "gpt-4",
      "max_tokens": 200,
      "temperature": 0.2,
      "top_p": 0.0,
      "presence_penalty": 0.0,
      "frequency_penalty": 0.0,
      "stop_sequences": ["Human", "AI"]
    },
    "service2": {
      "model_id": "gpt-3.5_turbo",
      "max_tokens": 256,
      "temperature": 0.3,
      "top_p": 0.0,
      "presence_penalty": 0.0,
      "frequency_penalty": 0.0,
      "stop_sequences": ["Human", "AI"]
    }
  },
  "input_variables": [
    {
      "name": "input",
      "description": "The text to continue.",
      "default": ""
    }
  ]
}