Bagikan melalui


Apa itu Perencana?

Setelah Anda memiliki beberapa plugin, Anda kemudian memerlukan cara bagi agen AI Anda untuk menggunakannya bersama-sama untuk menyelesaikan kebutuhan pengguna. Di sinilah perencanaan datang.

Awalnya, Semantic Kernel memperkenalkan konsep perencana yang menggunakan perintah untuk meminta AI untuk memilih fungsi mana yang akan dipanggil. Karena Semantic Kernel diperkenalkan, Namun, OpenAI memperkenalkan cara asli bagi model untuk memanggil atau "memanggil" fungsi: panggilan fungsi. Model AI lainnya seperti Gemini, Claude, dan Mistral sejak itu mengadopsi pemanggilan fungsi sebagai kemampuan inti, menjadikannya fitur yang didukung lintas model.

Karena kemajuan ini, Semantic Kernel telah berevolusi untuk menggunakan panggilan fungsi sebagai cara utama untuk merencanakan dan menjalankan tugas.

Penting

Panggilan fungsi hanya tersedia dalam model OpenAI yang 0613 atau yang lebih baru. Jika Anda menggunakan model yang lebih lama (misalnya, 0314), fungsionalitas ini akan mengembalikan kesalahan. Sebaiknya gunakan model OpenAI terbaru untuk memanfaatkan fitur ini.

Bagaimana pemanggilan fungsi membuat "paket"?

Paling sederhana, panggilan fungsi hanyalah cara bagi AI untuk memanggil fungsi dengan parameter yang tepat. Ambil contoh pengguna ingin menyalakan bola lampu. Dengan asumsi AI memiliki plugin yang tepat, AI dapat memanggil fungsi untuk menyalakan lampu.

Peran Pesan
🔵Pengguna Nyalakan lampu #1
🔴Asisten (panggilan fungsi) Lights.change_state(1, { "isOn": true })
🟢Alat { "id": 1, "name": "Table Lamp", "isOn": true, "brightness": 100, "hex": "FF0000" }
🔴Asisten Lampu sekarang menyala

Tetapi bagaimana jika pengguna tidak tahu ID cahaya? Atau bagaimana jika pengguna ingin menyalakan semua lampu? Di sinilah perencanaan datang. Model LLM saat ini mampu memanggil fungsi secara berulang untuk menyelesaikan kebutuhan pengguna. Ini dicapai dengan membuat perulangan umpan balik di mana AI dapat memanggil fungsi, memeriksa hasilnya, lalu memutuskan apa yang harus dilakukan selanjutnya.

Misalnya, pengguna dapat meminta AI untuk "mengalihkan" bola lampu. AI pertama-tama perlu memeriksa status bola lampu sebelum memutuskan apakah akan menyalakan atau mematikannya.

Peran Pesan
🔵Pengguna Silakan alihkan semua lampu
🔴Asisten (panggilan fungsi) Lights.get_lights()
🟢Alat { "lights": [ { "id": 1, "name": "Table Lamp", "isOn": true, "brightness": 100, "hex": "FF0000" }, { "id": 2, "name": "Ceiling Light", "isOn": false, "brightness": 0, "hex": "FFFFFF" } ] }
🔴Asisten (panggilan fungsi) Lights.change_state(1, { "isOn": false }) Lights.change_state(2, { "isOn": true })
🟢Alat { "id": 1, "name": "Table Lamp", "isOn": false, "brightness": 0, "hex": "FFFFFF" }
🟢Alat { "id": 2, "name": "Ceiling Light", "isOn": true, "brightness": 100, "hex": "FF0000" }
🔴Asisten Lampu telah dialihkan

Catatan

Dalam contoh ini, Anda juga melihat panggilan fungsi paralel. Di sinilah AI dapat memanggil beberapa fungsi secara bersamaan. Ini adalah fitur canggih yang dapat membantu AI menyelesaikan tugas kompleks dengan lebih cepat. Ini ditambahkan ke model OpenAI pada tahun 1106.

Perulangan perencanaan otomatis

Mendukung panggilan fungsi tanpa Semantic Kernel relatif kompleks. Anda perlu menulis perulangan yang akan mencapai hal berikut:

  1. Membuat skema JSON untuk setiap fungsi Anda
  2. Berikan LLM dengan riwayat obrolan dan skema fungsi sebelumnya
  3. Mengurai respons LLM untuk menentukan apakah ia ingin membalas dengan pesan atau memanggil fungsi
  4. Jika LLM ingin memanggil fungsi, Anda harus mengurai nama fungsi dan parameter dari respons LLM
  5. Memanggil fungsi dengan parameter yang tepat
  6. Mengembalikan hasil fungsi sehingga LLM dapat menentukan apa yang harus dilakukan selanjutnya
  7. Ulangi langkah 2-6 hingga LLM memutuskan telah menyelesaikan tugas atau memerlukan bantuan dari pengguna

Di Semantic Kernel, kami memudahkan penggunaan panggilan fungsi dengan mengotomatiskan perulangan ini untuk Anda. Ini memungkinkan Anda untuk fokus membangun plugin yang diperlukan untuk menyelesaikan kebutuhan pengguna Anda.

Catatan

Memahami cara kerja perulangan panggilan fungsi sangat penting untuk membangun agen AI yang berkinerja dan andal. Untuk melihat secara mendalam cara kerja perulangan, lihat artikel panggilan fungsi.

Menggunakan panggilan fungsi otomatis

Untuk menggunakan panggilan fungsi otomatis di Semantic Kernel, Anda perlu melakukan hal berikut:

  1. Daftarkan plugin dengan kernel
  2. Membuat objek pengaturan eksekusi yang memberi tahu AI untuk memanggil fungsi secara otomatis
  3. Panggil layanan penyelesaian obrolan dengan riwayat obrolan dan kernel
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());

Saat Anda menggunakan panggilan fungsi otomatis, semua langkah dalam perulangan perencanaan otomatis ditangani untuk Anda dan ditambahkan ke ChatHistory objek. Setelah perulangan panggilan fungsi selesai, Anda dapat memeriksa ChatHistory objek untuk melihat semua panggilan fungsi yang dilakukan dan hasil yang disediakan oleh Kernel Semantik.

Bagaimana dengan perencana Function Calling Stepwise dan Handlebars?

Perencana Stepwise dan Handlebars masih tersedia di Semantic Kernel. Namun, sebaiknya gunakan pemanggilan fungsi untuk sebagian besar tugas karena lebih kuat dan lebih mudah digunakan. Perencana Stepwise dan Handlebars tidak akan digunakan lagi dalam rilis Kernel Semantik di masa mendatang.

Pelajari cara memigrasikan Stepwise Planner ke Panggilan Fungsi Otomatis.

Perhatian

Jika Anda membangun agen AI baru, kami sarankan Anda tidak menggunakan perencana Stepwise atau Handlebars. Sebagai gantinya, gunakan pemanggilan fungsi karena lebih kuat dan lebih mudah digunakan.

Langkah berikutnya

Sekarang setelah Anda memahami cara kerja perencana di Kernel Semantik, Anda dapat mempelajari lebih lanjut tentang bagaimana memengaruhi agen AI Anda sehingga mereka paling baik merencanakan dan menjalankan tugas atas nama pengguna Anda.