다음을 통해 공유


Planner란?

플러그 인이 여러 개인 경우 AI 에이전트가 이를 함께 사용하여 사용자의 필요를 해결할 수 있는 방법이 필요합니다. 이것이 바로 계획이 들어오는 곳입니다.

초기에 의미 체계 커널은 프롬프트를 사용하여 AI에 호출할 함수를 선택하도록 요청하는 플래너의 개념을 소개했습니다. 그러나 의미 체계 커널이 도입된 이후 OpenAI는 모델에서 함수 호출을 호출하거나 "호출"하는 네이 티브 방법을 도입했습니다. Gemini, Claude 및 Mistral과 같은 다른 AI 모델은 이후 핵심 기능으로 함수 호출을 채택하여 모델 간 지원 기능으로 만들어 줍니다.

이러한 발전으로 인해 의미 체계 커널은 함수 호출을 작업을 계획하고 실행하는 기본 방법으로 사용하도록 발전했습니다.

Important

함수 호출은 0613 이상인 OpenAI 모델에서만 사용할 수 있습니다. 이전 모델(예: 0314)을 사용하는 경우 이 기능은 오류를 반환합니다. 이 기능을 활용하려면 최신 OpenAI 모델을 사용하는 것이 좋습니다.

함수 호출은 어떻게 "계획"을 생성하나요?

가장 간단하게 함수 호출은 AI가 올바른 매개 변수를 사용하여 함수를 호출하는 방법일 뿐입니다. 예를 들어 사용자가 전구를 켜려고 하는 경우를 예로 들어 보세요. AI에 올바른 플러그 인이 있다고 가정하면 함수를 호출하여 조명을 켤 수 있습니다.

역할 메시지
🔵사용자 조명 #1을 켜세요.
🔴도우미(함수 호출) Lights.change_state(1, { "isOn": true })
🟢도구 { "id": 1, "name": "Table Lamp", "isOn": true, "brightness": 100, "hex": "FF0000" }
🔴도우미 램프가 켜져 있습니다.

그러나 사용자가 빛의 ID를 모르는 경우 어떻게 해야 할까요? 또는 사용자가 모든 조명을 켜고 싶다면 어떻게 해야 할까요? 이것이 바로 계획이 들어오는 곳입니다. 오늘날의 LLM 모델은 사용자의 필요를 해결하기 위해 반복적으로 함수를 호출할 수 있습니다. 이 작업은 AI가 함수를 호출하고 결과를 확인한 다음 다음에 수행할 작업을 결정할 수 있는 피드백 루프를 만들어서 수행됩니다.

예를 들어 사용자는 AI에 전구를 "토글"하도록 요청할 수 있습니다. AI는 먼저 전구의 상태를 확인한 후 켜거나 끌지 결정해야 합니다.

역할 메시지
🔵사용자 모든 조명을 전환하세요.
🔴도우미(함수 호출) Lights.get_lights()
🟢도구 { "lights": [ { "id": 1, "name": "Table Lamp", "isOn": true, "brightness": 100, "hex": "FF0000" }, { "id": 2, "name": "Ceiling Light", "isOn": false, "brightness": 0, "hex": "FFFFFF" } ] }
🔴도우미(함수 호출) Lights.change_state(1, { "isOn": false }) Lights.change_state(2, { "isOn": true })
🟢도구 { "id": 1, "name": "Table Lamp", "isOn": false, "brightness": 0, "hex": "FFFFFF" }
🟢도구 { "id": 2, "name": "Ceiling Light", "isOn": true, "brightness": 100, "hex": "FF0000" }
🔴도우미 조명이 켜져 있습니다.

참고 항목

이 예제에서는 병렬 함수 호출도 보았습니다. 여기서 AI는 동시에 여러 함수를 호출할 수 있습니다. 이는 AI가 복잡한 작업을 보다 신속하게 해결하는 데 도움이 되는 강력한 기능입니다. 1106년에 OpenAI 모델에 추가되었습니다.

자동 계획 루프

의미 체계 커널 없이 함수 호출을 지원하는 것은 비교적 복잡합니다. 다음을 수행하는 루프를 작성해야 합니다.

  1. 각 함수에 대한 JSON 스키마 만들기
  2. 이전 채팅 기록 및 함수 스키마를 LLM에 제공합니다.
  3. LLM의 응답을 구문 분석하여 메시지로 회신할지 또는 함수를 호출할지 확인합니다.
  4. LLM이 함수를 호출하려는 경우 LLM의 응답에서 함수 이름 및 매개 변수를 구문 분석해야 합니다.
  5. 올바른 매개 변수를 사용하여 함수 호출
  6. LLM이 다음에 수행할 작업을 결정할 수 있도록 함수의 결과를 반환합니다.
  7. LLM이 작업을 완료했거나 사용자의 도움이 필요하다고 결정할 때까지 2-6단계를 반복합니다.

의미 체계 커널에서는 이 루프를 자동화하여 함수 호출을 쉽게 사용할 수 있습니다. 이를 통해 사용자의 요구 사항을 해결하는 데 필요한 플러그 인을 빌드하는 데 집중할 수 있습니다.

참고 항목

함수 호출 루프의 작동 방식을 이해하는 것은 성능이 뛰어나고 신뢰할 수 있는 AI 에이전트를 빌드하는 데 필수적입니다. 루프의 작동 방식에 대한 자세한 내용은 함수 호출 문서를 참조하세요.

자동 함수 호출 사용

의미 체계 커널에서 자동 함수 호출을 사용하려면 다음을 수행해야 합니다.

  1. 커널에 플러그 인 등록
  2. AI에 함수를 자동으로 호출하도록 지시하는 실행 설정 개체 만들기
  3. 채팅 기록 및 커널을 사용하여 채팅 완료 서비스 호출
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());

자동 함수 호출을 사용하는 경우 자동 계획 루프의 모든 단계가 자동으로 처리되고 개체에 ChatHistory 추가됩니다. 함수 호출 루프가 완료되면 개체를 ChatHistory 검사하여 모든 함수 호출 및 의미 체계 커널에서 제공하는 결과를 확인할 수 있습니다.

함수 호출 단계별 및 핸들바 플래너는 어떻습니까?

단계별 및 핸들바 플래너는 여전히 의미 체계 커널에서 사용할 수 있습니다. 그러나 더 강력하고 사용하기 쉽기 때문에 대부분의 태스크에 함수 호출을 사용하는 것이 좋습니다. 단계별 플래너와 핸들바 플래너는 모두 의미 체계 커널의 향후 릴리스에서 더 이상 사용되지 않습니다.

Stepwise Planner를 자동 함수 호출로 마이그레이션하는 방법을 알아봅니다.

주의

새 AI 에이전트를 빌드하는 경우 단계별 또는 핸들바 플래너를 사용하지 않는 것이 좋습니다. 대신 함수 호출은 더 강력하고 사용하기 쉽기 때문에 사용합니다.

다음 단계

이제 플래너가 의미 체계 커널에서 작동하는 방식을 이해했으므로 AI 에이전트가 사용자를 대신하여 작업을 가장 잘 계획하고 실행할 수 있도록 AI 에이전트에 미치는 영향에 대해 자세히 알아볼 수 있습니다.