네이티브 함수 이해

완료됨

네이티브 함수는 애플리케이션에서 의미 체계 커널 SDK에서 호출할 수 있는 네이티브 코드로 작성된 함수입니다. LLM(대규모 언어 모델) 자체에서 수행할 수 없는 작업을 수행하는 데 유용합니다. 네이티브 함수는 애플리케이션이 수행할 수 있는 기술과 같다고 생각할 수 있습니다.

이후 모듈에서는 의미 체계 커널을 사용하여 사용자가 만든 네이티브 함수를 자동으로 호출하고 논리를 LLM에 프롬프트와 결합하는 방법을 알아봅니다. 채팅 완료 서비스와 기능 기술을 결합하여 다양한 작업을 수행할 수 있는 AI 에이전트를 만들 수 있습니다. 하지만 지금은 네이티브 함수를 디자인하는 데 집중해 보겠습니다.

네이티브 함수는 커널에서 사용할 특정 형식과 권장되는 파일 구조를 갖습니다. 네이티브 함수는 정의에 KernelFunction 데코레이터를 사용해야 합니다. 또한 매개 변수에 Description 필드를 사용합니다. 예시:

[KernelFunction, Description("Convert an amount of currency to USD")]
public static string ConvertCurrency(
  [Description("The currency")] string currency, 
  [Description("The amount")] double amount)
{
  // Code to convert currency
}

네이티브 함수를 플러그 인으로 커널로 가져올 수 있습니다. 네이티브 함수를 포함하는 클래스는 "플러그 인" 디렉터리에 배치되어야 합니다. 코드를 구성하려면 관련 함수를 동일한 파일에 배치해야 합니다. "플러그 인" 디렉터리 내에서 하위 디렉터리를 활용하여 코드를 추가로 구성할 수도 있습니다.

예를 들어 할 일 목록 애플리케이션이 있다고 가정해 보겠습니다. 사용자가 할 일 목록에 있는 항목을 완료하려고 합니다. 대규모 언어 모델(LLM)은 사용자의 할 일 목록에 직접 액세스할 수 없지만 네이티브 함수를 작성하여 목록에 액세스하고 항목을 완료로 표시할 수 있습니다. 예를 들어 할 일 목록 파일에는 다음이 포함될 수 있습니다.

{
  "todoList": [
    {
      "task": "Complete coding exercise",
      "completed": false
    },
    {
      "task": "Practice Mandarin",
      "completed": false
    },
    {
      "task": "Buy groceries",
      "completed": false
    }
  ]
}

'Plugins' 디렉토리에 작업 완료를 표시하는 코드를 사용하여 TodoListPlugin.cs 파일을 만들 수 있습니다.

using System.ComponentModel;
using System.Text.Json;
using System.Text.Json.Nodes;
using Microsoft.SemanticKernel;

public class TodoListPlugin
{
    [KernelFunction, Description("Mark a todo list item as complete")]
    public static string CompleteTask([Description("The task to complete")] string task)
    {
        // Read the JSON file
        string jsonFilePath = $"{Directory.GetCurrentDirectory()}/todo.txt";
        string jsonContent = File.ReadAllText(jsonFilePath);

        // Parse the JSON content
        JsonNode todoData = JsonNode.Parse(jsonContent);

        // Find the task and mark it as complete
        JsonArray todoList = (JsonArray) todoData["todoList"];
        foreach (JsonNode taskNode in todoList)
        {
            if (taskNode["task"].ToString() == task)
            {
                taskNode["completed"] = true;
                break;
            }
        }

        // Save the modified JSON back to the file
        File.WriteAllText(jsonFilePath, JsonSerializer.Serialize(todoData));
        return $"Task '{task}' marked as complete.";
    }
}

KernelFunction 함수의 CompleteTask 데코레이터를 확인합니다. 이 데코레이터는 커널에 이 함수에 액세스할 수 있음을 알려줍니다. Description 데코레이터는 함수가 수행하는 작업을 커널에 알려줍니다. 함수는 task(을)를 문자열로 허용합니다. 커널 함수의 변수에는 변수가 무엇인지 설명하는 설명이 포함되어야 합니다. 또한 이 함수는 작업이 완료된 것으로 표시되었음을 사용자에게 알리는 문자열을 반환합니다.

Program.cs 파일에서 기본 제공 플러그 인 중 하나를 호출하는 방법과 유사하게 이 네이티브 함수를 가져오고 호출할 수 있습니다. 예시:

using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Plugins.Core;

var builder = Kernel.CreateBuilder();
builder.AddAzureOpenAIChatCompletion(
  "your-deployment-name",
  "your-endpoint",
  "your-api-key",
  "deployment-model");
var kernel = builder.Build();
kernel.ImportPluginFromType<TodoListPlugin>();

var result = await kernel.InvokeAsync<string>(
  "TodoListPlugin", 
  "CompleteTask", 
  new() {{ "task", "Buy groceries" }}
);
Console.WriteLine(result);

이 예제에서 kernel.InvokeAsync은(는) 플러그인 이름, 함수 이름 및 인수와 함께 호출됩니다. task 인수는 "식료품 구입"으로 설정됩니다. 함수는 할 일 목록 파일에서 작업을 완료로 표시하고 사용자에게 메시지를 반환합니다.

이제 AI 에이전트는 사용자가 할 일 목록에 대한 작업을 완료하는 데 도움을 줄 수 있습니다. 필요에 따라 InvokeAsync 호출에서 함수의 반환 형식을 나타내도록 선택할 수 있습니다. 그러지 않으면 FunctionResult 개체가 반환됩니다.

다음 연습에서는 네이티브 함수를 사용하여 고유한 플러그 인을 만드는 방법을 연습합니다.