Udostępnij za pośrednictwem


Wprowadzenie do jądra semantycznego

W kilku krokach możesz utworzyć pierwszego agenta sztucznej inteligencji za pomocą jądra semantycznego w języku Python, .NET lub Java. W tym przewodniku pokazano, jak...

  • Instalowanie niezbędnych pakietów
  • Tworzenie konwersacji back-and-forth ze sztuczną inteligencją
  • Nadaj agentowi sztucznej inteligencji możliwość uruchamiania kodu
  • Obejrzyj plany tworzenia sztucznej inteligencji na bieżąco

Instalowanie zestawu SDK

Semantyczne jądro ma kilka dostępnych pakietów NuGet. Jednak w przypadku większości scenariuszy zwykle potrzebne Microsoft.SemanticKernelsą tylko elementy .

Można go zainstalować przy użyciu następującego polecenia:

dotnet add package Microsoft.SemanticKernel

Pełną listę pakietów Nuget można znaleźć w artykule obsługiwanych języków.

Instrukcje dotyczące uzyskiwania SemanticKernel dostępu do pakietu języka Python są dostępne tutaj. Jest to tak proste, jak:

pip install semantic-kernel

Instrukcje dotyczące uzyskiwania SemanticKernel dostępu do pakietu Java są dostępne tutaj. Jest to tak proste, jak:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.microsoft.semantic-kernel</groupId>
            <artifactId>semantickernel-bom</artifactId>
            <version>${sk.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<dependencies>
<dependency>
    <groupId>com.microsoft.semantic-kernel</groupId>
    <artifactId>semantickernel-api</artifactId>
</dependency>
<dependency>
    <groupId>com.microsoft.semantic-kernel</groupId>
    <artifactId>semantickernel-aiservices-openai</artifactId>
</dependency>
</dependencies>

Szybkie rozpoczynanie pracy z notesami

Jeśli jesteś deweloperem języka Python lub C#, możesz szybko rozpocząć pracę z naszymi notesami. Te notesy zawierają przewodniki krok po kroku dotyczące używania jądra semantycznego do tworzenia agentów sztucznej inteligencji.

Notesy jądra semantycznego

Aby rozpocząć, wykonaj następujące kroki:

  1. Klonowanie repozytorium jądra semantycznego
  2. Otwieranie repozytorium w programie Visual Studio Code
  3. Przejdź do folderu _/python/samples/getting_started
  4. Otwórz plik 00-getting-started.ipynb , aby rozpocząć ustawianie środowiska i tworzenie pierwszego agenta sztucznej inteligencji!

Aby rozpocząć, wykonaj następujące kroki:

  1. Klonowanie repozytorium jądra semantycznego
  2. Otwieranie repozytorium w programie Visual Studio Code
  3. Przejdź do folderu _/dotnet/notebooks
  4. Otwórz plik 00-getting-started.ipynb , aby rozpocząć ustawianie środowiska i tworzenie pierwszego agenta sztucznej inteligencji!

Pisanie pierwszej aplikacji konsolowej

// Import packages
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;
using Microsoft.SemanticKernel.Connectors.OpenAI;

// Create a kernel with Azure OpenAI chat completion
var builder = Kernel.CreateBuilder().AddAzureOpenAIChatCompletion(modelId, endpoint, apiKey);

// Add enterprise components
builder.Services.AddLogging(services => services.AddConsole().SetMinimumLevel(LogLevel.Trace));

// Build the kernel
Kernel kernel = builder.Build();
var chatCompletionService = kernel.GetRequiredService<IChatCompletionService>();

// Add a plugin (the LightsPlugin class is defined below)
kernel.Plugins.AddFromType<LightsPlugin>("Lights");

// Enable planning
OpenAIPromptExecutionSettings openAIPromptExecutionSettings = new() 
{
    FunctionChoiceBehavior = FunctionChoiceBehavior.Auto()
};

// Create a history store the conversation
var history = new ChatHistory();

// Initiate a back-and-forth chat
string? userInput;
do {
    // Collect user input
    Console.Write("User > ");
    userInput = Console.ReadLine();

    // Add user input
    history.AddUserMessage(userInput);

    // Get the response from the AI
    var result = await chatCompletionService.GetChatMessageContentAsync(
        history,
        executionSettings: openAIPromptExecutionSettings,
        kernel: kernel);

    // Print the results
    Console.WriteLine("Assistant > " + result);

    // Add the message from the agent to the chat history
    history.AddMessage(result.Role, result.Content ?? string.Empty);
} while (userInput is not null);
import asyncio

from semantic_kernel import Kernel
from semantic_kernel.utils.logging import setup_logging
from semantic_kernel.functions import kernel_function
from semantic_kernel.connectors.ai.open_ai import AzureChatCompletion
from semantic_kernel.connectors.ai.function_choice_behavior import FunctionChoiceBehavior
from semantic_kernel.connectors.ai.chat_completion_client_base import ChatCompletionClientBase
from semantic_kernel.contents.chat_history import ChatHistory
from semantic_kernel.functions.kernel_arguments import KernelArguments

from semantic_kernel.connectors.ai.open_ai.prompt_execution_settings.azure_chat_prompt_execution_settings import (
    AzureChatPromptExecutionSettings,
)

async def main():
    # Initialize the kernel
    kernel = Kernel()

    # Add Azure OpenAI chat completion
    chat_completion = AzureChatCompletion(
        deployment_name="your_models_deployment_name",
        api_key="your_api_key",
        base_url="your_base_url",
    )
    kernel.add_service(chat_completion)

    # Set the logging level for  semantic_kernel.kernel to DEBUG.
    setup_logging()
    logging.getLogger("kernel").setLevel(logging.DEBUG)

    # Add a plugin (the LightsPlugin class is defined below)
    kernel.add_plugin(
        LightsPlugin(),
        plugin_name="Lights",
    )

    # Enable planning
    execution_settings = AzureChatPromptExecutionSettings()
    execution_settings.function_call_behavior = FunctionChoiceBehavior.Auto()

    # Create a history of the conversation
    history = ChatHistory()

    # Initiate a back-and-forth chat
    userInput = None
    while True:
        # Collect user input
        userInput = input("User > ")

        # Terminate the loop if the user says "exit"
        if userInput == "exit":
            break

        # Add user input to the history
        history.add_user_message(userInput)

        # Get the response from the AI
        result = await chat_completion.get_chat_message_content(
            chat_history=history,
            settings=execution_settings,
            kernel=kernel,
        )

        # Print the results
        print("Assistant > " + str(result))

        # Add the message from the agent to the chat history
        history.add_message(result)

# Run the main function
if __name__ == "__main__":
    asyncio.run(main())
OpenAIAsyncClient client = new OpenAIClientBuilder()
    .credential(new AzureKeyCredential(AZURE_CLIENT_KEY))
    .endpoint(CLIENT_ENDPOINT)
    .buildAsyncClient();

// Import the LightsPlugin
KernelPlugin lightPlugin = KernelPluginFactory.createFromObject(new LightsPlugin(),
    "LightsPlugin");

// Create your AI service client
ChatCompletionService chatCompletionService = OpenAIChatCompletion.builder()
    .withModelId(MODEL_ID)
    .withOpenAIAsyncClient(client)
    .build();

// Create a kernel with Azure OpenAI chat completion and plugin
Kernel kernel = Kernel.builder()
    .withAIService(ChatCompletionService.class, chatCompletionService)
    .withPlugin(lightPlugin)
    .build();

// Add a converter to the kernel to show it how to serialise LightModel objects into a prompt
ContextVariableTypes
    .addGlobalConverter(
        ContextVariableTypeConverter.builder(LightModel.class)
            .toPromptString(new Gson()::toJson)
            .build());

// Enable planning
InvocationContext invocationContext = new InvocationContext.Builder()
    .withReturnMode(InvocationReturnMode.LAST_MESSAGE_ONLY)
    .withToolCallBehavior(ToolCallBehavior.allowAllKernelFunctions(true))
    .build();

// Create a history to store the conversation
ChatHistory history = new ChatHistory();

// Initiate a back-and-forth chat
Scanner scanner = new Scanner(System.in);
String userInput;
do {
  // Collect user input
  System.out.print("User > ");

  userInput = scanner.nextLine();
  // Add user input
  history.addUserMessage(userInput);

  // Prompt AI for response to users input
  List<ChatMessageContent<?>> results = chatCompletionService
      .getChatMessageContentsAsync(history, kernel, invocationContext)
      .block();

  for (ChatMessageContent<?> result : results) {
    // Print the results
    if (result.getAuthorRole() == AuthorRole.ASSISTANT && result.getContent() != null) {
      System.out.println("Assistant > " + result);
    }
    // Add the message from the agent to the chat history
    history.addMessage(result);
  }
} while (userInput != null && !userInput.isEmpty());

Poniższy czat z powrotem i z powrotem powinien być podobny do tego, co widzisz w konsoli. Poniższe wywołania funkcji zostały dodane, aby zademonstrować, jak sztuczna inteligencja korzysta z wtyczki w tle.

Rola Komunikat
🔵Użytkownik Przełącz światło
🔴Asystent (wywołanie funkcji) LightsPlugin.GetState()
🟢Tool (Narzędzie dostępu do centrum danych) off
🔴Asystent (wywołanie funkcji) LightsPlugin.ChangeState(true)
🟢Tool (Narzędzie dostępu do centrum danych) on
🔴Asystent Światło jest teraz włączone

Jeśli chcesz dowiedzieć się więcej o powyższym kodzie, podzielimy go w następnej sekcji.

Omówienie kodu

Aby ułatwić rozpoczęcie tworzenia aplikacji dla przedsiębiorstw za pomocą jądra semantycznego, utworzyliśmy krok po kroku, który przeprowadzi Cię przez proces tworzenia jądra i używania go do interakcji z usługami sztucznej inteligencji.

Mapa języka Python jądra semantycznego

Mapa DotNET jądra semantycznego

W poniższych sekcjach rozpakujemy powyższy przykład, przechodząc przez kroki 1, 2, 3, 4, 6, 9 i 10. Wszystko, czego potrzebujesz, aby utworzyć prostego agenta, który jest obsługiwany przez usługę sztucznej inteligencji i może uruchomić kod.

1) Importowanie pakietów

W tym przykładzie najpierw rozpoczęliśmy od zaimportowania następujących pakietów:

using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;
using Microsoft.SemanticKernel.Connectors.OpenAI;
import asyncio

from semantic_kernel import Kernel
from semantic_kernel.connectors.ai.open_ai import AzureChatCompletion
from semantic_kernel.connectors.ai.function_choice_behavior import FunctionChoiceBehavior
from semantic_kernel.connectors.ai.chat_completion_client_base import ChatCompletionClientBase
from semantic_kernel.contents.chat_history import ChatHistory
from semantic_kernel.functions.kernel_arguments import KernelArguments

from semantic_kernel.connectors.ai.open_ai.prompt_execution_settings.azure_chat_prompt_execution_settings import (
    AzureChatPromptExecutionSettings,
)
import com.microsoft.semantickernel.Kernel;
import com.microsoft.semantickernel.aiservices.openai.chatcompletion.OpenAIChatCompletion;
import com.microsoft.semantickernel.contextvariables.ContextVariableTypeConverter;
import com.microsoft.semantickernel.contextvariables.ContextVariableTypes;
import com.microsoft.semantickernel.orchestration.InvocationContext;
import com.microsoft.semantickernel.orchestration.InvocationReturnMode;
import com.microsoft.semantickernel.orchestration.ToolCallBehavior;
import com.microsoft.semantickernel.plugin.KernelPlugin;
import com.microsoft.semantickernel.plugin.KernelPluginFactory;
import com.microsoft.semantickernel.services.chatcompletion.AuthorRole;
import com.microsoft.semantickernel.services.chatcompletion.ChatCompletionService;
import com.microsoft.semantickernel.services.chatcompletion.ChatHistory;
import com.microsoft.semantickernel.services.chatcompletion.ChatMessageContent;

2) Dodawanie usług sztucznej inteligencji

Następnie dodamy najważniejszą część jądra: usługi sztucznej inteligencji, których chcesz użyć. W tym przykładzie dodaliśmy do konstruktora jądra usługę uzupełniania czatów usługi Azure OpenAI.

Uwaga

W tym przykładzie użyliśmy usługi Azure OpenAI, ale możesz użyć dowolnej innej usługi uzupełniania czatów. Aby zapoznać się z pełną listą obsługiwanych usług, zapoznaj się z artykułem obsługiwanych języków. Jeśli potrzebujesz pomocy przy tworzeniu innej usługi, zapoznaj się z artykułem dotyczącym usług sztucznej inteligencji. W tym miejscu znajdziesz wskazówki dotyczące używania modeli OpenAI lub Azure OpenAI jako usług.

// Create kernel
var builder = Kernel.CreateBuilder()
builder.AddAzureOpenAIChatCompletion(modelId, endpoint, apiKey);
# Initialize the kernel
kernel = Kernel()

# Add Azure OpenAI chat completion
kernel.add_service(AzureChatCompletion(
    deployment_name="your_models_deployment_name",
    api_key="your_api_key",
    base_url="your_base_url",
))
// Create your AI service client
ChatCompletionService chatCompletionService = OpenAIChatCompletion.builder()
    .withModelId(MODEL_ID)
    .withOpenAIAsyncClient(client)
    .build();

// Create a kernel with Azure OpenAI chat completion and plugin
Kernel kernel = Kernel.builder()
    .withAIService(ChatCompletionService.class, chatCompletionService)
    .withPlugin(lightPlugin)
    .build();

3) Dodawanie usług przedsiębiorstwa

Jedną z głównych zalet korzystania z jądra semantycznego jest obsługa usług klasy korporacyjnej. W tym przykładzie dodaliśmy usługę rejestrowania do jądra, aby ułatwić debugowanie agenta sztucznej inteligencji.

builder.Services.AddLogging(services => services.AddConsole().SetMinimumLevel(LogLevel.Trace));
import logging

# Set the logging level for  semantic_kernel.kernel to DEBUG.
logging.basicConfig(
    format="[%(asctime)s - %(name)s:%(lineno)d - %(levelname)s] %(message)s",
    datefmt="%Y-%m-%d %H:%M:%S",
)
logging.getLogger("kernel").setLevel(logging.DEBUG)

4) Tworzenie jądra i pobieranie usług

Po dodaniu usług skompilujemy jądro i pobierzemy usługę uzupełniania czatu do późniejszego użycia.

Kernel kernel = builder.Build();

// Retrieve the chat completion service
var chatCompletionService = kernel.Services.GetRequiredService<IChatCompletionService>();

Po skonfigurowaniu jądra pobieramy usługę uzupełniania czatu do późniejszego użycia.

Uwaga

W języku Python nie trzeba jawnie kompilować jądra. Zamiast tego można uzyskać dostęp do usług bezpośrednio z obiektu jądra.

chat_completion : AzureChatCompletion = kernel.get_service(type=ChatCompletionClientBase)
// Create a kernel with Azure OpenAI chat completion and plugin
Kernel kernel = Kernel.builder()
    .withAIService(ChatCompletionService.class, chatCompletionService)
    .withPlugin(lightPlugin)
    .build();

6) Dodawanie wtyczek

Dzięki wtyczkom można nadać agentowi sztucznej inteligencji możliwość uruchamiania kodu w celu pobierania informacji ze źródeł zewnętrznych lub wykonywania akcji. W powyższym przykładzie dodaliśmy wtyczkę, która umożliwia agentowi sztucznej inteligencji interakcję z żarówką. Poniżej pokażemy, jak utworzyć tę wtyczkę.

Tworzenie wtyczki natywnej

Poniżej widać, że tworzenie wtyczki natywnej jest tak proste, jak utworzenie nowej klasy.

W tym przykładzie utworzyliśmy wtyczkę, która może manipulować żarówką. Chociaż jest to prosty przykład, ta wtyczka szybko pokazuje, jak można obsługiwać oba...

  1. Pobieranie rozszerzonej generacji (RAG) przez dostarczenie agenta sztucznej inteligencji ze stanem żarówki
  2. Automatyzacja zadań umożliwia agentowi sztucznej inteligencji włączenie lub wyłączenie żarówki.

We własnym kodzie możesz utworzyć wtyczkę, która współdziała z dowolną usługą zewnętrzną lub interfejsem API, aby uzyskać podobne wyniki.

using System.ComponentModel;
using Microsoft.SemanticKernel;

public class LightsPlugin
{
   // Mock data for the lights
   private readonly List<LightModel> lights = new()
   {
      new LightModel { Id = 1, Name = "Table Lamp", IsOn = false },
      new LightModel { Id = 2, Name = "Porch light", IsOn = false },
      new LightModel { Id = 3, Name = "Chandelier", IsOn = true }
   };

   [KernelFunction("get_lights")]
   [Description("Gets a list of lights and their current state")]
   [return: Description("An array of lights")]
   public async Task<List<LightModel>> GetLightsAsync()
   {
      return lights;
   }

   [KernelFunction("change_state")]
   [Description("Changes the state of the light")]
   [return: Description("The updated state of the light; will return null if the light does not exist")]
   public async Task<LightModel?> ChangeStateAsync(int id, bool isOn)
   {
      var light = lights.FirstOrDefault(light => light.Id == id);

      if (light == null)
      {
         return null;
      }

      // Update the light with the new state
      light.IsOn = isOn;

      return light;
   }
}

public class LightModel
{
   [JsonPropertyName("id")]
   public int Id { get; set; }

   [JsonPropertyName("name")]
   public string Name { get; set; }

   [JsonPropertyName("is_on")]
   public bool? IsOn { get; set; }
}
from typing import Annotated
from semantic_kernel.functions import kernel_function

class LightsPlugin:
    lights = [
        {"id": 1, "name": "Table Lamp", "is_on": False},
        {"id": 2, "name": "Porch light", "is_on": False},
        {"id": 3, "name": "Chandelier", "is_on": True},
    ]

    @kernel_function(
        name="get_lights",
        description="Gets a list of lights and their current state",
    )
    def get_state(
        self,
    ) -> Annotated[str, "the output is a string"]:
        """Gets a list of lights and their current state."""
        return self.lights

    @kernel_function(
        name="change_state",
        description="Changes the state of the light",
    )
    def change_state(
        self,
        id: int,
        is_on: bool,
    ) -> Annotated[str, "the output is a string"]:
        """Changes the state of the light."""
        for light in self.lights:
            if light["id"] == id:
                light["is_on"] = is_on
                return light
        return None
public class LightsPlugin {

  // Mock data for the lights
  private final Map<Integer, LightModel> lights = new HashMap<>();

  public LightsPlugin() {
    lights.put(1, new LightModel(1, "Table Lamp", false));
    lights.put(2, new LightModel(2, "Porch light", false));
    lights.put(3, new LightModel(3, "Chandelier", true));
  }

  @DefineKernelFunction(name = "get_lights", description = "Gets a list of lights and their current state")
  public List<LightModel> getLights() {
    System.out.println("Getting lights");
    return new ArrayList<>(lights.values());
  }

  @DefineKernelFunction(name = "change_state", description = "Changes the state of the light")
  public LightModel changeState(
      @KernelFunctionParameter(name = "id", description = "The ID of the light to change") int id,
      @KernelFunctionParameter(name = "isOn", description = "The new state of the light") boolean isOn) {
    System.out.println("Changing light " + id + " " + isOn);
    if (!lights.containsKey(id)) {
      throw new IllegalArgumentException("Light not found");
    }

    lights.get(id).setIsOn(isOn);

    return lights.get(id);
  }
}

Dodawanie wtyczki do jądra

Po utworzeniu wtyczki możesz dodać ją do jądra, aby agent sztucznej inteligencji mógł uzyskać do niego dostęp. W przykładzie dodaliśmy klasę LightsPlugin do jądra.

// Add the plugin to the kernel
kernel.Plugins.AddFromType<LightsPlugin>("Lights");
# Add the plugin to the kernel
kernel.add_plugin(
    LightsPlugin(),
    plugin_name="Lights",
)
// Import the LightsPlugin
KernelPlugin lightPlugin = KernelPluginFactory.createFromObject(new LightsPlugin(),
    "LightsPlugin");

9) Planowanie

Semantyczne jądro wykorzystuje funkcję wywołującą — natywną funkcję większości llMs — w celu zapewnienia planowania. W przypadku wywoływania funkcji maszyny LLM mogą żądać (lub wywołać) określonej funkcji w celu spełnienia żądania użytkownika. Semantyczne jądro następnie marshaluje żądanie do odpowiedniej funkcji w bazie kodu i zwraca wyniki z powrotem do usługi LLM, aby agent sztucznej inteligencji mógł wygenerować ostateczną odpowiedź.

Aby włączyć automatyczne wywoływanie funkcji, najpierw musimy utworzyć odpowiednie ustawienia wykonywania, aby jądro semantyczne wiedziało, aby automatycznie wywoływać funkcje w jądrze, gdy agent sztucznej inteligencji żąda ich.

OpenAIPromptExecutionSettings openAIPromptExecutionSettings = new()
{
    FunctionChoiceBehavior = FunctionChoiceBehavior.Auto()
};
execution_settings = AzureChatPromptExecutionSettings()
execution_settings.function_call_behavior = FunctionChoiceBehavior.Auto()
// Enable planning
InvocationContext invocationContext = new InvocationContext.Builder()
    .withReturnMode(InvocationReturnMode.LAST_MESSAGE_ONLY)
    .withToolCallBehavior(ToolCallBehavior.allowAllKernelFunctions(true))
    .build();

10) Wywołaj

Na koniec wywołujemy agenta sztucznej inteligencji za pomocą wtyczki. Przykładowy kod demonstruje sposób generowania odpowiedzi nieprzesyłania strumieniowego, ale można również wygenerować odpowiedź strumieniową przy użyciu GetStreamingChatMessageContentAsync metody .

// Create chat history
var history = new ChatHistory();

// Get the response from the AI
var result = await chatCompletionService.GetChatMessageContentAsync(
    history,
    executionSettings: openAIPromptExecutionSettings,
    kernel: kernel
);
# Create a history of the conversation
history = ChatHistory()

# Get the response from the AI
result = (await chat_completion.get_chat_message_contents(
    chat_history=history,
    settings=execution_settings,
    kernel=kernel,
    arguments=KernelArguments(),
))[0]
userInput = scanner.nextLine();
// Add user input
history.addUserMessage(userInput);

// Prompt AI for response to users input
List<ChatMessageContent<?>> results = chatCompletionService
    .getChatMessageContentsAsync(history, kernel, invocationContext)
    .block();

Następne kroki

W tym przewodniku pokazano, jak szybko rozpocząć pracę z jądrem semantycznym, tworząc prostego agenta sztucznej inteligencji, który może wchodzić w interakcje z usługą sztucznej inteligencji i uruchamiać kod. Aby zobaczyć więcej przykładów i dowiedzieć się, jak tworzyć bardziej złożonych agentów sztucznej inteligencji, zapoznaj się z naszymi szczegółowymi przykładami.