Introducción al kernel semántico

En unos pocos pasos, puede compilar su primer agente de INTELIGENCIA ARTIFICIAL con kernel semántico en Python, .NET o Java. Esta guía le mostrará cómo...

  • Instalación de los paquetes necesarios
  • Creación de una conversación de ida y vuelta con una inteligencia artificial
  • Proporcionar a un agente de IA la capacidad de ejecutar el código
  • Ver los planes de creación de inteligencia artificial sobre la marcha

Instalar el SDK

El kernel semántico tiene varios paquetes NuGet disponibles. Sin embargo, en la mayoría de los escenarios, normalmente solo necesita Microsoft.SemanticKernel.

Puede instalarlo mediante el siguiente comando:

dotnet add package Microsoft.SemanticKernel

Para obtener la lista completa de paquetes Nuget, consulte el artículo sobre los idiomas admitidos.

Las instrucciones para acceder al SemanticKernel paquete de Python están disponibles aquí. Es tan fácil como:

pip install semantic-kernel

Las instrucciones para acceder al SemanticKernel paquete de Java están disponibles aquí. Es tan fácil como:

<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>

Introducción rápida a los cuadernos

Si es desarrollador de Python o C#, puede empezar a trabajar rápidamente con nuestros cuadernos. Estos cuadernos proporcionan guías paso a paso sobre cómo usar kernel semántico para compilar agentes de IA.

Cuadernos de kernel semántico

Siga estos pasos para comenzar:

  1. Clonación del repositorio de kernel semántico
  2. Abrir el repositorio en Visual Studio Code
  3. Vaya a _/python/samples/getting_started
  4. Abra 00-getting-started.ipynb para empezar a establecer el entorno y crear su primer agente de IA.

Siga estos pasos para comenzar:

  1. Clonación del repositorio de kernel semántico
  2. Abrir el repositorio en Visual Studio Code
  3. Vaya a _/dotnet/notebooks.
  4. Abra 00-getting-started.ipynb para empezar a establecer el entorno y crear su primer agente de IA.

Escritura de la primera aplicación de consola

// 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());

El siguiente chat de ida y vuelta debe ser similar al que ve en la consola. Las llamadas de función se han agregado a continuación para demostrar cómo la inteligencia artificial aprovecha el complemento en segundo plano.

Role Mensaje
🔵User Cambie la luz.
🔴Asistente (llamada de función) LightsPlugin.GetState()
🟢Herramienta off
🔴Asistente (llamada de función) LightsPlugin.ChangeState(true)
🟢Herramienta on
🔴Asistente La luz ahora está activada

Si está interesado en comprender más sobre el código anterior, lo desglosaremos en la sección siguiente.

Descripción del código

Para facilitar la creación de aplicaciones empresariales con kernel semántico, hemos creado un paso a paso que le guía por el proceso de creación de un kernel y su uso para interactuar con los servicios de inteligencia artificial.

Asignación de Python del kernel semántico

Mapa de DotNET del kernel semántico

En las secciones siguientes, desempaquetaremos el ejemplo anterior siguiendo los pasos 1, 2, 3, 4, 6, 9 y 10. Todo lo que necesita para crear un agente sencillo con tecnología de un servicio de inteligencia artificial y puede ejecutar el código.

1) Importar paquetes

Para este ejemplo, primero empezamos importando los siguientes paquetes:

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) Incorporación de servicios de IA

Después, agregamos la parte más importante de un kernel: los servicios de inteligencia artificial que desea usar. En este ejemplo, agregamos un servicio de finalización de chat de Azure OpenAI al generador de kernels.

Nota:

En este ejemplo, usamos Azure OpenAI, pero puede usar cualquier otro servicio de finalización de chat. Para ver la lista completa de servicios admitidos, consulte el artículo idiomas admitidos. Si necesita ayuda para crear un servicio diferente, consulte el artículo servicios de INTELIGENCIA ARTIFICIAL. Allí encontrará instrucciones sobre cómo usar modelos OpenAI o Azure OpenAI como servicios.

// 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) Agregar servicios empresariales

Una de las principales ventajas de usar kernel semántico es que admite servicios de nivel empresarial. En este ejemplo, hemos agregado el servicio de registro al kernel para ayudar a depurar el agente de IA.

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) Compilación del kernel y recuperación de servicios

Una vez agregados los servicios, compilamos el kernel y recuperamos el servicio de finalización del chat para su uso posterior.

Kernel kernel = builder.Build();

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

Una vez configurado el kernel, se recupera el servicio de finalización del chat para su uso posterior.

Nota:

En Python, no es necesario compilar explícitamente el kernel. En su lugar, puede acceder a los servicios directamente desde el objeto kernel.

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) Agregar complementos

Con los complementos, puede proporcionar al agente de INTELIGENCIA ARTIFICIAL la capacidad de ejecutar el código para recuperar información de orígenes externos o realizar acciones. En el ejemplo anterior, hemos agregado un complemento que permite que el agente de IA interactúe con una bombilla. A continuación, le mostraremos cómo crear este complemento.

Creación de un complemento nativo

A continuación, puede ver que crear un complemento nativo es tan sencillo como crear una nueva clase.

En este ejemplo, hemos creado un complemento que puede manipular una bombilla. Aunque este es un ejemplo sencillo, este complemento muestra rápidamente cómo puede admitir ambos...

  1. Recuperación de generación aumentada (RAG) al proporcionar al agente de IA el estado de la bombilla
  2. Y la automatización de tareas al permitir que el agente de IA active o desactive la bombilla.

En su propio código, puede crear un complemento que interactúe con cualquier servicio externo o API para lograr resultados similares.

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);
  }
}

Adición del complemento al kernel

Una vez creado el complemento, puede agregarlo al kernel para que el agente de IA pueda acceder a él. En el ejemplo, agregamos la LightsPlugin clase al kernel.

// 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) Planificación

El kernel semántico aprovecha las llamadas a funciones,una característica nativa de la mayoría de las LLM, para proporcionar planeamiento. Con la llamada a funciones, las LLM pueden solicitar (o llamar) a una función determinada para satisfacer la solicitud de un usuario. A continuación, el kernel semántico serializa la solicitud a la función adecuada en el código base y devuelve los resultados a LLM para que el agente de IA pueda generar una respuesta final.

Para habilitar las llamadas automáticas a funciones, primero es necesario crear la configuración de ejecución adecuada para que kernel semántico sepa invocar automáticamente las funciones en el kernel cuando el agente de IA los solicite.

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) Invocar

Por último, invocamos al agente de IA con el complemento. El código de ejemplo muestra cómo generar una respuesta que no sea de streaming, pero también puede generar una respuesta de streaming mediante el GetStreamingChatMessageContentAsync método .

// 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();

Pasos siguientes

En esta guía, ha aprendido a empezar a trabajar rápidamente con el kernel semántico mediante la creación de un agente de inteligencia artificial simple que puede interactuar con un servicio de IA y ejecutar el código. Para ver más ejemplos y aprender a crear agentes de IA más complejos, consulte nuestros ejemplos detallados.