Compartilhar via


Entendendo o kernel

O kernel é o componente central do Kernel Semântico. Em sua forma mais simples, o kernel é um contêiner de injeção de dependência que gerencia todos os serviços e plug-ins necessários para executar seu aplicativo de IA. Se você fornecer todos os seus serviços e plug-ins ao kernel, eles serão usados perfeitamente pela IA conforme necessário.

O kernel está no centro

Como o kernel tem todos os serviços e plug-ins necessários para executar o código nativo e os serviços de IA, ele é usado por quase todos os componentes do SDK do Kernel Semântico para alimentar seus agentes. Isso significa que, se você executar qualquer prompt ou código no Kernel Semântico, o kernel estará sempre disponível para recuperar os serviços e plug-ins necessários.

O kernel está no centro de tudo no Semantic Kernel

Isso é extremamente poderoso, porque significa que você, como desenvolvedor, tem um único local onde pode configurar e, o mais importante, monitorar seus agentes de IA. Tomemos, por exemplo, quando você invoca um prompt do kernel. Quando você fizer isso, o kernel irá...

  1. Selecione o melhor serviço de IA para executar o prompt.
  2. Crie o prompt usando o modelo de prompt fornecido.
  3. Envie o prompt para o serviço de IA.
  4. Receba e analise a resposta.
  5. E finalmente, retorne a resposta do LLM para seu aplicativo.

Ao longo de todo esse processo, você pode criar eventos e middleware que são acionados em cada uma dessas etapas. Isso significa que você pode executar ações como registro, fornecer atualizações de status aos usuários e, o mais importante, IA responsável. Tudo em um único lugar.

Construa um kernel com serviços e plugins

Antes de construir um kernel, você deve primeiro entender os dois tipos de componentes que existem:

Componente Descrição
Serviços Eles consistem em serviços de IA (por exemplo, conclusão de bate-papo) e outros serviços (por exemplo, registro em log e clientes HTTP) necessários para executar seu aplicativo. Isso foi modelado após o padrão provedor de serviços no .NET para que pudéssemos dar suporte à injeção de dependência em todos os idiomas.
Plugins Esses são os componentes usados pelos serviços de IA e pelos modelos de solicitação para executar o trabalho. Os serviços de IA, por exemplo, podem usar plug-ins para recuperar dados de um banco de dados ou chamar uma API externa para executar ações.

Para começar a criar um kernel, importe os pacotes necessários na parte superior do seu arquivo:

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Plugins.Core;

Em seguida, você pode adicionar serviços e plugins. Abaixo está um exemplo de como você pode adicionar uma conclusão de chat do Azure OpenAI, um registrador e um plug-in de tempo.

// Create a kernel with a logger and Azure OpenAI chat completion service
var builder = Kernel.CreateBuilder();
builder.AddAzureOpenAIChatCompletion(modelId, endpoint, apiKey);
builder.Services.AddLogging(c => c.AddDebug().SetMinimumLevel(LogLevel.Trace));
builder.Plugins.AddFromType<TimePlugin>();
Kernel kernel = builder.Build();

Importe os pacotes necessários:

from semantic_kernel import Kernel
from semantic_kernel.connectors.ai.open_ai import AzureChatCompletion
from semantic_kernel.core_plugins.time_plugin import TimePlugin

Em seguida, você pode criar um kernel.

# Initialize the kernel
kernel = Kernel()

Finalmente, você pode adicionar os serviços e plugins necessários. Abaixo está um exemplo de como você pode adicionar uma conclusão de chat do Azure OpenAI, um logger e um plug-in de tempo.

# Add the Azure OpenAI chat completion service
kernel.add_service(AzureChatCompletion(model_id, endpoint, api_key))

# Add a plugin
kernel.add_plugin(
    TimePlugin(),
    plugin_name="TimePlugin",
)

Criando um servidor MCP a partir do seu kernel

Agora damos suporte à criação de um servidor MCP com base na função que você registrou na instância do Kernel Semântico.

Para fazer isso, você cria o kernel como faria normalmente e, em seguida, pode criar um servidor MCP com base nele.

from semantic_kernel import Kernel
from semantic_kernel.connectors.ai.open_ai import OpenAIChatCompletion
from semantic_kernel.functions import kernel_function
from semantic_kernel.prompt_template import InputVariable, PromptTemplateConfig

kernel = Kernel()

@kernel_function()
def echo_function(message: str, extra: str = "") -> str:
    """Echo a message as a function"""
    return f"Function echo: {message} {extra}"

kernel.add_service(OpenAIChatCompletion(service_id="default"))
kernel.add_function("echo", echo_function, "echo_function")
kernel.add_function(
    plugin_name="prompt",
    function_name="prompt",
    prompt_template_config=PromptTemplateConfig(
        name="prompt",
        description="This is a prompt",
        template="Please repeat this: {{$message}} and this: {{$extra}}",
        input_variables=[
            InputVariable(
                name="message",
                description="This is the message.",
                is_required=True,
                json_schema='{ "type": "string", "description": "This is the message."}',
            ),
            InputVariable(
                name="extra",
                description="This is extra.",
                default="default",
                is_required=False,
                json_schema='{ "type": "string", "description": "This is the message."}',
            ),
        ],
    ),
)
server = kernel.as_mcp_server(server_name="sk")

O server objeto criado acima vem do pacote mcp, você pode estendê-lo ainda mais, por exemplo, adicionando recursos ou outros recursos a ele. E, em seguida, você pode colocá-lo online, por exemplo, para ser usado com Stdio:

import anyio
from mcp.server.stdio import stdio_server

async def handle_stdin(stdin: Any | None = None, stdout: Any | None = None) -> None:
    async with stdio_server() as (read_stream, write_stream):
        await server.run(read_stream, write_stream, server.create_initialization_options())

anyio.run(handle_stdin)

Ou com SSE:

import uvicorn
from mcp.server.sse import SseServerTransport
from starlette.applications import Starlette
from starlette.routing import Mount, Route

sse = SseServerTransport("/messages/")

async def handle_sse(request):
    async with sse.connect_sse(request.scope, request.receive, request._send) as (read_stream, write_stream):
        await server.run(read_stream, write_stream, server.create_initialization_options())

starlette_app = Starlette(
    debug=True,
    routes=[
        Route("/sse", endpoint=handle_sse),
        Mount("/messages/", app=sse.handle_post_message),
    ],
)

uvicorn.run(starlette_app, host="0.0.0.0", port=8000)

Expondo modelos de prompt como prompt do MCP

Você também pode utilizar os diferentes modelos de prompts do Kernel Semântico expondo-os como prompts do MCP, desta forma:

from semantic_kernel.prompt_template import InputVariable, KernelPromptTemplate, PromptTemplateConfig

prompt = KernelPromptTemplate(
    prompt_template_config=PromptTemplateConfig(
        name="release_notes_prompt",
        description="This creates the prompts for a full set of release notes based on the PR messages given.",
        template=template,
        input_variables=[
            InputVariable(
                name="messages",
                description="These are the PR messages, they are a single string with new lines.",
                is_required=True,
                json_schema='{"type": "string"}',
            )
        ],
    )
)

server = kernel.as_mcp_server(server_name="sk_release_notes", prompts=[prompt])

Construir um kernel

Os kernels podem ser construídos usando um Kernel.builder(). Sobre isso, você pode adicionar serviços e plug-ins de IA necessários.

Kernel kernel = Kernel.builder()
    .withAIService(ChatCompletionService.class, chatCompletionService)
    .withPlugin(lightPlugin)
    .build();

Usando injeção de dependência

Em C#, você pode usar a Injeção de Dependência para criar um kernel. Isso é feito criando um ServiceCollection e adicionando serviços e plugins a ele. Abaixo está um exemplo de como você pode criar um kernel usando a Injeção de Dependência.

Dica

Recomendamos que você crie um kernel como um serviço transitório para que ele seja descartado após cada uso, pois a coleção de plug-ins é mutável. O kernel é extremamente leve (já que é apenas um contêiner para serviços e plugins), portanto, criar um novo kernel para cada uso não é uma preocupação de desempenho.

using Microsoft.SemanticKernel;

var builder = Host.CreateApplicationBuilder(args);

// Add the OpenAI chat completion service as a singleton
builder.Services.AddOpenAIChatCompletion(
    modelId: "gpt-4",
    apiKey: "YOUR_API_KEY",
    orgId: "YOUR_ORG_ID", // Optional; for OpenAI deployment
    serviceId: "YOUR_SERVICE_ID" // Optional; for targeting specific services within Semantic Kernel
);

// Create singletons of your plugins
builder.Services.AddSingleton(() => new LightsPlugin());
builder.Services.AddSingleton(() => new SpeakerPlugin());

// Create the plugin collection (using the KernelPluginFactory to create plugins from objects)
builder.Services.AddSingleton<KernelPluginCollection>((serviceProvider) => 
    [
        KernelPluginFactory.CreateFromObject(serviceProvider.GetRequiredService<LightsPlugin>()),
        KernelPluginFactory.CreateFromObject(serviceProvider.GetRequiredService<SpeakerPlugin>())
    ]
);

// Finally, create the Kernel service with the service provider and plugin collection
builder.Services.AddTransient((serviceProvider)=> {
    KernelPluginCollection pluginCollection = serviceProvider.GetRequiredService<KernelPluginCollection>();

    return new Kernel(serviceProvider, pluginCollection);
});

Dica

Para obter mais exemplos sobre como usar a injeção de dependência em C#, consulte os exemplos de conceito.

Próximas etapas

Agora que você entende o kernel, pode aprender sobre todos os diferentes serviços de IA que você pode adicionar a ele.