Koog 문서 한국어 번역 09: 함수형 에이전트

·8분 읽기

원문: Koog 공식 문서

함수형 에이전트

함수형 에이전트는 사용자 입력을 처리하고, LLM과 상호작용하며, 필요에 따라 도구를 호출하고, 최종 출력을 생성하는 함수로 로직을 구현합니다. 그래프 기반 에이전트와 비교했을 때, 일반적으로 프로토타입을 더 빠르게 만들 수 있지만 다음과 같은 단점이 있습니다:

  • 시각화하기 어렵습니다
  • 상태 지속성이 없습니다

참고: 사전 요구사항

이 페이지의 예제는 빠른 시작 가이드의 사전 요구사항, 의존성, API 키 설정이 완료되어 있다고 가정합니다. 또한 Ollama를 통해 Llama 3.2를 로컬에서 실행 중이라고 가정합니다.

이 페이지에서는 에이전트의 커스텀 로직을 빠르게 프로토타이핑하기 위한 함수형 전략 구현 방법을 설명합니다.

최소한의 함수형 에이전트 만들기

최소한의 함수형 에이전트를 만들려면 기본 에이전트와 동일한 AIAgent 인터페이스를 사용하고, AIAgentFunctionalStrategy 인스턴스를 전달하면 됩니다. 입력을 받아 출력을 반환하고, LLM 호출을 한 번 수행한 후 응답에서 어시스턴트 메시지 내용을 반환하는 함수형 전략을 정의할 수 있습니다.

Kotlin에서는 functionalStrategy {...} DSL 메서드를 사용하는 것이 가장 편리합니다. Java에서는 AIAgent 빌더의 functionalStrategy 메서드를 사용할 수 있습니다.

Kotlin

1val strategy = functionalStrategy<String, String> { input ->2    val response = requestLLM(input)3    response.asAssistantMessage().content4}56val mathAgent = AIAgent(7    promptExecutor = simpleOllamaAIExecutor(),8    llmModel = OllamaModels.Meta.LLAMA_3_2,9    strategy = strategy10)1112fun main() = runBlocking {13    val result = mathAgent.run("What is 12 × 9?")14    println(result)15}

Java

1AIAgent<String, String> mathAgent = AIAgent.builder()2    .promptExecutor(SimpleLLMExecutorsKt.simpleOllamaAIExecutor("http://localhost:11434"))3    .llmModel(OllamaModels.Meta.LLAMA_3_2)4    .functionalStrategy("mathStrategy", (AIAgentFunctionalContext context, String input) -> {5        Message.Response response = context.requestLLM(input);6        if (response instanceof Message.Assistant) {7            return ((Message.Assistant) response).getContent();8        }9        return "";10    })11    .build();1213String result = mathAgent.run("What is 12 × 9?");14System.out.println(result);

에이전트는 다음과 같은 출력을 생성할 수 있습니다:

1The answer to 12 × 9 is 108.

순차적 LLM 호출하기

이전 전략을 확장하여 여러 번의 순차적 LLM 호출을 수행할 수 있습니다:

Kotlin

1val strategy = functionalStrategy<String, String> { input ->2    // The first LLM call produces an initial draft based on the user input3    val draft = requestLLM("Draft: $input").asAssistantMessage().content4    // The second LLM call improves the initial draft5    val improved = requestLLM("Improve and clarify.").asAssistantMessage().content6    // The final LLM call formats the improved text and returns the result7    requestLLM("Format the result as bold.").asAssistantMessage().content8}

Java

1AIAgent<String, String> mathAgent = AIAgent.builder()2    .promptExecutor(simpleOllamaAIExecutor("http://localhost:11434"))3    .systemPrompt("You are a precise math assistant.")4    .llmModel(OllamaModels.Meta.LLAMA_3_2)5    .functionalStrategy((AIAgentFunctionalContext context, String input) -> {6        // The first LLM call produces an initial draft based on the user input7        Message.Response draftResponse = context.requestLLM("Draft: " + input);8        String draft = "";9        if (draftResponse instanceof Message.Assistant) {10            draft = ((Message.Assistant) draftResponse).getContent();11        }1213        // The second LLM call improves the initial draft14        Message.Response improvedResponse = context.requestLLM("Improve and clarify.");15        String improved = "";16        if (improvedResponse instanceof Message.Assistant) {17            improved = ((Message.Assistant) improvedResponse).getContent();18        }1920        // The final LLM call formats the improved text and returns the result21        Message.Response finalResponse = context.requestLLM("Format the result as bold.");22        if (finalResponse instanceof Message.Assistant) {23            return ((Message.Assistant) finalResponse).getContent();24        }25        return "";26    })27    .build();

에이전트는 다음과 같은 출력을 생성할 수 있습니다:

1To calculate the product of 12 and 9, we multiply these two numbers together.2312 × 9 = **108**

도구 추가하기

많은 경우, 함수형 에이전트는 데이터 읽기 및 쓰기, API 호출, 또는 기타 결정론적 작업과 같은 특정 태스크를 수행해야 합니다. Koog에서는 이러한 기능을 도구로 노출하여 LLM이 언제 호출할지 결정하도록 합니다.

필요한 작업은 다음과 같습니다:

  1. 어노테이션 기반 도구를 만듭니다.
  2. 도구 레지스트리에 추가하고 레지스트리를 에이전트에 전달합니다.
  3. 에이전트 전략이 LLM 응답에서 도구 호출을 식별하고, 요청된 도구를 실행하고, 결과를 LLM에 다시 전송하며, 도구 호출이 없을 때까지 이 과정을 반복할 수 있도록 합니다.

Kotlin

1@LLMDescription("Tools for performing math operations")2class MathTools : ToolSet {3    @Tool4    @LLMDescription("Multiplies two numbers and returns the result")5    fun multiply(a: Int, b: Int): Int {6        // This is not necessary, but it helps to see the tool call in the console output7        println("Multiplying $a and $b...")8        return a * b9    }10}1112val toolRegistry = ToolRegistry {13    tool(MathTools()::multiply)14}1516val strategy = functionalStrategy<String, String> { input ->17    // Send the user input to the LLM18    var responses = requestLLMMultiple(input)1920    // Only loop while the LLM requests tools21    while (responses.containsToolCalls()) {22        // Extract tool calls from the response23        val pendingCalls = extractToolCalls(responses)24        // Execute the tools and return the results25        val results = executeMultipleTools(pendingCalls)26        // Send the tool results back to the LLM. The LLM may call more tools or return a final output27        responses = sendMultipleToolResults(results)28    }2930    // When no tool calls remain, extract and return the assistant message content from the response31    responses.single().asAssistantMessage().content32}3334val mathAgentWithTools = AIAgent(35    promptExecutor = simpleOllamaAIExecutor(),36    llmModel = OllamaModels.Meta.LLAMA_3_2,37    toolRegistry = toolRegistry,38    strategy = strategy39)4041fun main() = runBlocking {42    val result = mathAgentWithTools.run("Multiply 3 by 4, then multiply the result by 5.")43    println(result)44}

Java

1@LLMDescription(description = "Tools for performing math operations")2public static class MathTools implements ToolSet {3    @Tool4    @LLMDescription(description = "Multiplies two numbers and returns the result")5    public int multiply(int a, int b) {6        // This is not necessary, but it helps to see the tool call in the console output7        System.out.println("Multiplying " + a + " and " + b + "...");8        return a * b;9    }10}1112public static void main(String[] args) {13    MathTools mathTools = new MathTools();14    ToolRegistry toolRegistry = ToolRegistry.builder()15        .tools(mathTools)16        .build();1718    AIAgent<String, String> mathAgentWithTools = AIAgent.builder()19        .promptExecutor(SimpleLLMExecutorsKt.simpleOllamaAIExecutor("http://localhost:11434"))20        .llmModel(OllamaModels.Meta.LLAMA_3_2)21        .toolRegistry(toolRegistry)22        .functionalStrategy("mathWithTools", (AIAgentFunctionalContext context, String input) -> {23            // Send the user input to the LLM24            List<Message.Response> responses = context.requestLLMMultiple(input);2526            // Only loop while the LLM requests tools27            while (context.containsToolCalls(responses)) {28                // Extract tool calls from the response29                List<Message.Tool.Call> pendingCalls = context.extractToolCalls(responses);30                // Execute the tools and return the results31                List<ReceivedToolResult> results = context.executeMultipleTools(pendingCalls, false);32                // Send the tool results back to the LLM33                responses = context.sendMultipleToolResults(results);34            }3536            // Extract and return the assistant message content from the response37            Message.Response finalResponse = responses.get(0);38            if (finalResponse instanceof Message.Assistant) {39                return ((Message.Assistant) finalResponse).getContent();40            }41            return "";42        })43        .build();4445    String result = mathAgentWithTools.run("Multiply 3 by 4, then multiply the result by 5.");46    System.out.println(result);47}

에이전트는 다음과 같은 출력을 생성할 수 있습니다:

1Multiplying 3 and 4...2Multiplying 12 and 5...3The result of multiplying 3 by 4 is 12. Multiplying 12 by 5 gives us a final answer of 60.

다음 단계