Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Depois de ter vários plug-ins, você precisará de uma maneira de seu agente de IA usá-los juntos para resolver a necessidade de um usuário. É aqui que entra o planejamento.
No início, o Kernel Semântico introduziu o conceito de planejadores que usavam prompts para solicitar que a IA escolhesse quais funções invocar. Como o Kernel Semântico foi introduzido, no entanto, o OpenAI introduziu uma maneira nativa para o modelo invocar ou "chamar" uma função: chamada de função. Outros modelos de IA, como Gemini, Claude e Mistral, adotaram desde então a chamada de função como uma funcionalidade principal, tornando-o um recurso com suporte entre modelos.
Devido a esses avanços, o Kernel Semântico evoluiu para usar a chamada de função como a principal maneira de planejar e executar tarefas.
Importante
A chamada de função só está disponível em modelos da OpenAI que são da versão 0613 ou mais recente. Se você usar um modelo mais antigo (por exemplo, 0314), essa funcionalidade retornará um erro. É recomendável usar os modelos openai mais recentes para aproveitar esse recurso.
Como a chamada de uma função cria um "plano"?
Na sua mais simples, a chamada de função é apenas uma maneira de uma IA invocar uma função com os parâmetros corretos. Por exemplo, um usuário deseja ativar uma lâmpada. Supondo que a IA tenha o plug-in direito, ela pode chamar a função para ativar a luz.
| Função | Mensagem |
|---|---|
| 🔵 Usuário | Ative a luz nº 1 |
| Assistente (chamada de função) de 🔴 | Lights.change_state(1, { "isOn": true }) |
| Ferramenta 🟢 | { "id": 1, "name": "Table Lamp", "isOn": true, "brightness": 100, "hex": "FF0000" } |
| 🔴 Assistente | A lâmpada agora está ativada |
Mas e se o usuário não souber a ID da luz? Ou e se o usuário quiser ligar todas as luzes? É aqui que entra o planejamento. Os modelos LLM de hoje são capazes de chamar funções iterativamente para resolver a necessidade do usuário. Isso é feito criando um circuito de feedback em que a IA pode chamar uma função, verificar o resultado e decidir o que fazer a seguir.
Por exemplo, um usuário pode pedir à IA para "ligar/desligar" uma lâmpada. A IA primeiro precisaria verificar o estado da lâmpada antes de decidir se a ativaria ou desativaria.
| Função | Mensagem |
|---|---|
| 🔵 Usuário | Ative/desative todas as luzes |
| Assistente (chamada de função) de 🔴 | Lights.get_lights() |
| Ferramenta 🟢 | { "lights": [ { "id": 1, "name": "Table Lamp", "isOn": true, "brightness": 100, "hex": "FF0000" }, { "id": 2, "name": "Ceiling Light", "isOn": false, "brightness": 0, "hex": "FFFFFF" } ] } |
| Assistente (chamada de função) de 🔴 |
Lights.change_state(1, { "isOn": false })
Lights.change_state(2, { "isOn": true })
|
| Ferramenta 🟢 | { "id": 1, "name": "Table Lamp", "isOn": false, "brightness": 0, "hex": "FFFFFF" } |
| Ferramenta 🟢 | { "id": 2, "name": "Ceiling Light", "isOn": true, "brightness": 100, "hex": "FF0000" } |
| 🔴 Assistente | As luzes foram alternadas |
Observação
Neste exemplo, você também viu chamadas de funções em paralelo. É aí que a IA pode chamar várias funções ao mesmo tempo. Esse é um recurso poderoso que pode ajudar a IA a resolver tarefas complexas mais rapidamente. Ele foi adicionado aos modelos da OpenAI no ano de 1106.
O loop de planejamento automático
O suporte à chamada de função sem kernel semântico é relativamente complexo. Você precisaria escrever um loop que realizasse o seguinte:
- Criar esquemas JSON para cada uma de suas funções
- Forneça o LLM com o histórico de chat e os esquemas de função anteriores
- Analisar a resposta do LLM para determinar se ele deseja responder com uma mensagem ou chamar uma função
- Se o LLM quiser chamar uma função, você precisará analisar o nome da função e os parâmetros da resposta do LLM
- Invocar a função com os parâmetros corretos
- Retornar os resultados da função para que a LLM possa determinar o que ela deve fazer em seguida
- Repita as etapas 2 a 6 até que a LLM decida que concluiu a tarefa ou precisa de ajuda do usuário
No Kernel Semântico, facilitamos o uso da chamada de função automatizando esse loop para você. Isso permite que você se concentre na criação dos plug-ins necessários para resolver as necessidades do usuário.
Observação
Entender como o loop de chamada de função funciona é essencial para criar agentes de IA confiáveis e com desempenho. Para ver detalhadamente como o loop funciona, consulte o artigo de chamada de função .
Usando a chamada automática de função
Para usar a chamada automática de função no Kernel Semântico, você precisa fazer o seguinte:
- Registrar o plug-in com o kernel
- Crie um objeto de configurações de execução que instrua a IA a chamar funções automaticamente.
- Invocar o serviço de conclusão de conversas com o histórico de mensagens e o kernel
Dica
O exemplo de código a seguir usa o LightsPlugin definido aqui.
using System.ComponentModel;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;
using Microsoft.SemanticKernel.Connectors.OpenAI;
// 1. Create the kernel with the Lights plugin
var builder = Kernel.CreateBuilder().AddAzureOpenAIChatCompletion(modelId, endpoint, apiKey);
builder.Plugins.AddFromType<LightsPlugin>("Lights");
Kernel kernel = builder.Build();
var chatCompletionService = kernel.GetRequiredService<IChatCompletionService>();
// 2. Enable automatic function calling
OpenAIPromptExecutionSettings openAIPromptExecutionSettings = new()
{
FunctionChoiceBehavior = FunctionChoiceBehavior.Auto()
};
var history = new ChatHistory();
string? userInput;
do {
// Collect user input
Console.Write("User > ");
userInput = Console.ReadLine();
// Add user input
history.AddUserMessage(userInput);
// 3. Get the response from the AI with automatic function calling
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.connectors.ai import FunctionChoiceBehavior
from semantic_kernel.connectors.ai.chat_completion_client_base import ChatCompletionClientBase
from semantic_kernel.connectors.ai.open_ai import (
AzureChatCompletion,
AzureChatPromptExecutionSettings,
)
from semantic_kernel.contents import ChatHistory
from semantic_kernel.functions import kernel_function
async def main():
# 1. Create the kernel with the Lights plugin
kernel = Kernel()
kernel.add_service(AzureChatCompletion())
kernel.add_plugin(
LightsPlugin(),
plugin_name="Lights",
)
chat_completion: AzureChatCompletion = kernel.get_service(type=ChatCompletionClientBase)
# 2. Enable automatic function calling
execution_settings = AzureChatPromptExecutionSettings()
execution_settings.function_choice_behavior = FunctionChoiceBehavior.Auto()
# Create a history of the conversation
history = ChatHistory()
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)
# 3. Get the response from the AI with automatic function calling
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());
Quando você usa a chamada automática de função, todas as etapas do loop de planejamento automático são tratadas para você e adicionadas ao objeto ChatHistory. Depois que o loop de chamada de função for concluído, você poderá inspecionar o ChatHistory objeto para ver todas as chamadas de função feitas e os resultados fornecidos pelo Kernel Semântico.
O que aconteceu com os planejadores Stepwise e Handlebars?
Os planejadores Stepwise e Handlebars foram descontinuados e removidos do pacote Kernel Semântico. Esses planejadores não têm mais suporte em Python, .NET ou Java.
É recomendável usar a chamada de função, que é mais eficiente e fácil de usar para a maioria dos cenários.
Para atualizar as soluções existentes, siga nosso Guia de Migração do Planejador Stepwise.
Dica
Use a chamada de função para novos agentes de IA em vez de planejadores preteridos. Ele oferece melhor flexibilidade, suporte a ferramentas internas e uma experiência de desenvolvimento mais simples.
Próximas etapas
Agora que você entende como os planejadores funcionam no Kernel Semântico, você pode saber mais sobre como influenciar seu agente de IA para que eles planejem melhor e executem tarefas em nome de seus usuários.