Sdílet prostřednictvím


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

  1. Vytvoření schémat JSON pro každou z vašich funkcí
  2. Poskytnutí LLM s předchozí historií chatu a schématy funkcí
  3. Parsujte odpověď LLM a zjistěte, jestli chce odpovědět zprávou nebo volat funkci.
  4. Pokud LLM chce volat funkci, budete muset analyzovat název a parametry funkce z odpovědi LLM.
  5. Vyvolání funkce se správnými parametry
  6. Vrátí výsledky funkce, aby LLM mohl určit, co by měl udělat dál.
  7. 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:

  1. Registrace modulu plug-in v jádru
  2. Vytvoření objektu nastavení spuštění, který dává umělé inteligenci pokyn, aby automaticky volal funkce
  3. 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ů.