Koog를 사용하여 숫자 추측 에이전트 구축

·3분 읽기

원문: Koog Documentation — Guesser 이 글은 Koog 공식 문서의 Guesser 페이지를 한국어로 옮긴 번역본입니다. 문서 구조와 링크 의미를 유지하되, MkDocs 전용 UI 문법은 블로그에서 읽기 좋도록 정리했습니다.

Koog를 사용하여 숫자 추측 에이전트 구축

:material-github: Open on GitHub{ .md-button .md-button--기본 } :material-download: Download .ipynb{ .md-버튼 }

당신이 생각하는 숫자를 추측하는 작지만 재미있는 에이전트를 만들어 봅시다. 우리는 Koog의 도구 호출을 활용하여 타겟 질문을 하고 고전적인 이진 검색 전략을 사용하여 수렴할 것입니다. 그 결과 문서에 바로 넣을 수 있는 관용적인 Kotlin 노트북이 탄생했습니다.

몇 가지 작은 도구, 간결한 프롬프트, 대화형 CLI 루프 등 코드를 최소화하고 흐름을 투명하게 유지하겠습니다.

설정

이 노트북은 다음을 가정합니다.

  • Koog를 사용할 수 있는 Kotlin Notebook에서 실행 중입니다.
  • 환경 변수 OPENAI_API_KEY이 설정되었습니다. 에이전트는 simpleOpenAIExecutor(System.getenv("OPENAI_API_KEY"))을 통해 이를 사용합니다.

Koog 커널을 로드합니다.

1%useLatestDescriptors2%use koog

도구: 타겟 질문하기

도구는 LLM이 호출할 수 있는 작고 잘 설명된 기능입니다. 우리는 세 가지를 제공할 것입니다:

  • lessThan(value): "귀하의 숫자가 가치보다 낮습니까?"
  • greaterThan(value): "귀하의 숫자가 가치보다 큽니까?"
  • proposeNumber(value): "귀하의 숫자가 가치와 동일합니까?" (범위가 좁을 때 사용)

각 도구는 간단한 "YES"/"NO" 문자열을 반환합니다. 도우미 ask는 최소한의 Y/n 루프를 구현하고 입력의 유효성을 검사합니다. @LLMDescription을 통한 설명은 모델이 도구를 올바르게 선택하는 데 도움이 됩니다.

1import ai.koog.agents.core.tools.annotations.Tool23class GuesserTool : ToolSet {45    @Tool6    @LLMDescription("Asks the user if his number is STRICTLY less than a given value.")7    fun lessThan(8        @LLMDescription("A value to compare the guessed number with.") value: Int9    ): String = ask("Is your number less than $value?", value)1011    @Tool12    @LLMDescription("Asks the user if his number is STRICTLY greater than a given value.")13    fun greaterThan(14        @LLMDescription("A value to compare the guessed number with.") value: Int15    ): String = ask("Is your number greater than $value?", value)1617    @Tool18    @LLMDescription("Asks the user if his number is EXACTLY equal to the given number. Only use this tool once you've narrowed down your answer.")19    fun proposeNumber(20        @LLMDescription("A value to compare the guessed number with.") value: Int21    ): String = ask("Is your number equal to $value?", value)2223    fun ask(question: String, value: Int): String {24        print("$question [Y/n]: ")25        val input = readln()26        println(input)2728        return when (input.lowercase()) {29            "", "y", "yes" -> "YES"30            "n", "no" -> "NO"31            else -> {32                println("Invalid input! Please, try again.")33                ask(question, value)34            }35        }36    }37}

도구 레지스트리

도구를 에이전트에 노출하세요. 또한 에이전트가 사용자에게 직접 메시지를 표시할 수 있도록 내장된 SayToUser 도구를 추가합니다.

1val toolRegistry = ToolRegistry {2    tool(SayToUser)3    tools(GuesserTool())4}

에이전트 구성

짧은 도구 전달 시스템 프롬프트만 있으면 됩니다. 우리는 이진 검색 전략을 제안하고 안정적이고 결정적인 동작을 위해 temperature = 0.0을 유지할 것입니다. 여기서는 명확한 계획을 위해 OpenAI의 추론 모델 GPT4oMini을 사용합니다.

1val agent = AIAgent(2    executor = simpleOpenAIExecutor(System.getenv("OPENAI_API_KEY")),3    llmModel = OpenAIModels.Chat.GPT4oMini,4    systemPrompt = """5            You are a number guessing agent. Your goal is to guess a number that the user is thinking of.6            7            Follow these steps:8            1. Start by asking the user to think of a number between 1 and 100.9            2. Use the less_than and greater_than tools to narrow down the range.10                a. If it's neither greater nor smaller, use the propose_number tool.11            3. Once you're confident about the number, use the propose_number tool to check if your guess is correct.12            4. If your guess is correct, congratulate the user. If not, continue guessing.13            14            Be efficient with your guessing strategy. A binary search approach works well.15        """.trimIndent(),16    temperature = 0.0,17    toolRegistry = toolRegistry18)

실행해 보세요

  • 1에서 100 사이의 숫자를 생각해 보세요.
  • 시작하려면 start을 입력하세요.
  • 상담원의 질문에 Y/Enter(예), n(아니오)로 답하세요. 상담원은 최대 7단계를 거쳐 귀하의 전화번호를 확인해야 합니다.
1import kotlinx.coroutines.runBlocking23println("Number Guessing Game started!")4println("Think of a number between 1 and 100, and I'll try to guess it.")5println("Type 'start' to begin the game.")67val initialMessage = readln()8runBlocking {9    agent.run(initialMessage)10}

작동 원리

  • 에이전트는 시스템 프롬프트를 읽고 이진 검색을 계획합니다.
  • 각 반복에서 lessThan, greaterThan 또는 (특정한 경우) proposeNumber 도구 중 하나를 호출합니다.
  • 도우미 ask는 Y/n 입력을 수집하고 깨끗한 "YES"/"NO" 신호를 모델에 반환합니다.
  • 확인을 받으면 SayToUser을 통해 축하합니다.

연장하다

  • 시스템 프롬프트를 조정하여 범위(예: 1..1000)를 변경합니다.
  • 호출을 더 줄이려면 between(low, high) 도구를 추가하세요.
  • 동일한 도구를 유지하면서 모델 또는 실행기를 교환합니다(예: Ollama 실행기와 로컬 모델 사용).
  • 분석을 위해 추측이나 결과를 스토어에 유지합니다.

문제 해결

  • 키 누락: 환경에 OPENAI_API_KEY이 설정되어 있는지 확인하세요.
  • 커널을 찾을 수 없음: %useLatestDescriptors%use koog이 성공적으로 실행되었는지 확인하세요.
  • 도구가 호출되지 않음: ToolRegistryGuesserTool()이 포함되어 있고 프롬프트의 이름이 도구 기능과 일치하는지 확인하세요.