Co je Planner?
Jakmile budete mít více modulů plug-in, budete potřebovat způsob, jak ho agent umělé inteligence používat společně k řešení potřeby uživatele. Tady přichází plánování.
V rané fázi představilo sémantické jádro koncept plánovačů, které použily výzvy k vyžádání umělé inteligence, aby zvolilo, které funkce se mají vyvolat. Vzhledem k tomu, že bylo zavedeno sémantické jádro, OpenAI však zavedl nativní způsob, jak model vyvolat nebo "volat" funkci: volání funkce. Jiné modely umělé inteligence, jako je Gemini, Claude a Mistral, od té doby přijaly volání funkcí jako základní funkce, což z něj dělá podporovanou funkci napříč modely.
Z těchto pokroků se sémantické jádro vyvinulo tak, aby jako primární způsob plánování a provádění úkolů používalo volání funkcí.
Důležité
Volání funkcí je dostupné jenom v modelech OpenAI, které jsou 0613 nebo novější. Pokud používáte starší model (např. 0314), vrátí tato funkce chybu. K využití této funkce doporučujeme používat nejnovější modely OpenAI.
Jak volání funkce vytvoří "plán"?
V nejjednodušším volání funkce je jen způsob, jak AI vyvolat funkci se správnými parametry. Představte si například, že uživatel chce zapnout žárovku. Za předpokladu, že AI má správný modul plug-in, může volat funkci, která zapne světlo.
Role | Zpráva |
---|---|
🔵Uživatel | Zapněte světlo č. 1. |
🔴Asistent (volání funkce) | Lights.change_state(1, { "isOn": true }) |
🟢Nástroj | { "id": 1, "name": "Table Lamp", "isOn": true, "brightness": 100, "hex": "FF0000" } |
🔴Asistent | Lampa je teď zapnutá. |
Ale co když uživatel nezná ID světla? Nebo co když chce uživatel zapnout všechna světla? Tady přichází plánování. Dnešní modely LLM jsou schopné iterativním voláním funkcí vyřešit potřeby uživatele. Toho dosáhnete tak, že vytvoříte smyčku zpětné vazby, ve které může AI volat funkci, zkontrolovat výsledek a pak rozhodnout, co dělat dál.
Uživatel může například požádat AI, aby "přepnul" žárovku. AI by nejprve potřebovala zkontrolovat stav žárovky, než se rozhodnete, jestli ji chcete zapnout nebo vypnout.
Role | Zpráva |
---|---|
🔵Uživatel | Přepněte všechna světla. |
🔴Asistent (volání funkce) | Lights.get_lights() |
🟢Nástroj | { "lights": [ { "id": 1, "name": "Table Lamp", "isOn": true, "brightness": 100, "hex": "FF0000" }, { "id": 2, "name": "Ceiling Light", "isOn": false, "brightness": 0, "hex": "FFFFFF" } ] } |
🔴Asistent (volání funkce) | Lights.change_state(1, { "isOn": false }) Lights.change_state(2, { "isOn": true }) |
🟢Nástroj | { "id": 1, "name": "Table Lamp", "isOn": false, "brightness": 0, "hex": "FFFFFF" } |
🟢Nástroj | { "id": 2, "name": "Ceiling Light", "isOn": true, "brightness": 100, "hex": "FF0000" } |
🔴Asistent | Světla byla přepínována. |
Poznámka:
V tomto příkladu jste také viděli paralelní volání funkcí. V tomto případě může AI současně volat více funkcí. Jedná se o výkonnou funkci, která pomáhá AI rychleji řešit složité úlohy. Byla přidána do modelů OpenAI v roce 1106.
Smyčka automatického plánování
Podpora volání funkcí bez sémantického jádra je poměrně složitá. Museli byste napsat smyčku, která by dosáhla následujících kroků:
- Vytvoření schémat JSON pro každou z vašich funkcí
- Poskytnutí LLM s předchozí historií chatu a schématy funkcí
- Parsujte odpověď LLM a zjistěte, jestli chce odpovědět zprávou nebo volat funkci.
- Pokud LLM chce volat funkci, budete muset analyzovat název a parametry funkce z odpovědi LLM.
- Vyvolání funkce se správnými parametry
- Vrátí výsledky funkce, aby LLM mohl určit, co by měl udělat dál.
- Opakujte kroky 2 až 6, dokud se LLM nerozhodne, že dokončil úkol nebo potřebuje pomoc od uživatele.
V sémantickém jádru usnadňujeme volání funkcí automatizací této smyčky za vás. Díky tomu se můžete zaměřit na vytváření modulů plug-in potřebných k řešení potřeb uživatele.
Poznámka:
Pochopení fungování volající smyčky funkce je nezbytné pro vytváření výkonných a spolehlivých agentů AI. Podrobné informace o tom, jak smyčka funguje, najdete v článku volání funkce.
Použití automatického volání funkce
Pokud chcete použít automatické volání funkce v sémantickém jádru, musíte udělat toto:
- Registrace modulu plug-in v jádru
- Vytvoření objektu nastavení spuštění, který dává umělé inteligenci pokyn, aby automaticky volal funkce
- Vyvolání služby pro dokončování chatu s historií chatu a jádrem
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.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():
# 1. Create the kernel with the Lights plugin
kernel = Kernel()
kernel.add_service(AzureChatCompletion(
deployment_name="your_models_deployment_name",
api_key="your_api_key",
base_url="your_base_url",
))
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_call_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_contents(
chat_history=history,
settings=execution_settings,
kernel=kernel,
arguments=KernelArguments(),
))[0]
# 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());
Když použijete automatické volání funkce, všechny kroky ve smyčce automatického plánování se za vás zpracují a přidají do objektu ChatHistory
. Po dokončení volající smyčky funkce můžete zkontrolovat ChatHistory
objekt a zobrazit všechna volání funkce a výsledky poskytované sémantickým jádrem.
A co plánovače funkcí volání krokových ručiček a úchytů?
Plánovače krokových a obslužných panelů jsou stále k dispozici v sémantickém jádru. Doporučujeme ale používat volání funkcí pro většinu úloh, protože je výkonnější a jednodušší. Plánovače krokových i obslužných panelů budou v budoucí verzi sémantického jádra zastaralé.
Zjistěte, jak migrovat Krokwise Planner do automatického volání funkcí.
Upozornění
Pokud vytváříte nového agenta AI, doporučujeme nepoužívat plánovače krokových ručiček ani úchytů. Místo toho používejte volání funkcí, protože je výkonnější a jednodušší.
Další kroky
Teď, když rozumíte tomu, jak plannery fungují v sémantickém jádru, můžete se dozvědět více o tom, jak ovlivňují agenta AI, aby mohli nejlépe plánovat a spouštět úkoly jménem uživatelů.