LLM 클라이언트

·3분 읽기

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

LLM 클라이언트

LLM 클라이언트는 LLM 제공자와 직접 상호 작용하도록 설계되었습니다. 각 클라이언트는 프롬프트 실행 및 응답 스트리밍을 위한 메서드를 제공하는 LLMClient 인터페이스를 구현합니다.

단일 LLM 공급자와 작업하고 고급 수명 주기 관리가 필요하지 않은 경우 LLM 클라이언트를 사용할 수 있습니다. 여러 LLM 제공업체를 관리해야 하는 경우 prompt executor을 사용하세요.

아래 표에는 사용 가능한 LLM 클라이언트와 해당 기능이 나와 있습니다.

LLM 제공업체 LLM클라이언트 도구
호출
스트리밍 다중
선택
임베딩 모더레이션 모델
목록
참고
OpenAI OpenAILLMClient ✓[^1]
Anthropic AnthropicLLMClient - - - - -
Google GoogleLLMClient - -
DeepSeek DeepSeekLLMClient - - OpenAI 호환 채팅 클라이언트.
OpenRouter OpenRouterLLMClient - - OpenAI 호환 라우터 클라이언트.
Amazon Bedrock BedrockLLMClient - ✓[^2] - 여러 모델 계열을 지원하는 JVM 전용 AWS SDK 클라이언트입니다.
Mistral MistralAILLMClient ✓[^3] OpenAI 호환 클라이언트.
Alibaba DashScopeLLMClient - - 공급자별 매개변수(enableSearch, parallelToolCalls, enableThinking)를 노출하는 OpenAI 호환 클라이언트입니다.
Ollama OllamaClient - - 모델 관리 API를 갖춘 로컬 서버 클라이언트.

프롬프트 실행

LLM 클라이언트를 사용하여 프롬프트를 실행하려면 다음을 수행하십시오.

  1. 애플리케이션과 LLM 공급자 간의 연결을 처리하는 LLM 클라이언트를 만듭니다.
  2. 프롬프트와 LLM을 인수로 사용하여 execute() 메서드를 호출합니다.

다음은 OpenAILLMClient을 사용하여 프롬프트를 실행하는 예입니다.

코틀린

1fun main() = runBlocking {2    // Create an OpenAI client3    val apiKey = System.getenv("OPENAI_API_KEY")4    val client = OpenAILLMClient(apiKey)56    // Create a prompt7    val prompt = prompt("prompt_name", LLMParams()) {8        // Add a system message to set the context9        system("You are a helpful assistant.")1011        // Add a user message12        user("Tell me about Kotlin")1314        // You can also add assistant messages for few-shot examples15        assistant("Kotlin is a modern programming language...")1617        // Add another user message18        user("What are its key features?")19    }2021    // Run the prompt22    val response = client.execute(prompt, OpenAIModels.Chat.GPT4o)23    // Print the response24    println(response)25}

자바

1// Create an OpenAI client2String apiKey = System.getenv("OPENAI_API_KEY");3OpenAILLMClient client = new OpenAILLMClient(apiKey);45// Create a prompt6Prompt prompt = Prompt.builder("prompt_name")7    // Add a system message to set the context8    .system("You are a helpful assistant.")9    10    // Add a user message11    .user("Tell me about Kotlin")1213    // You can also add assistant messages for few-shot examples14    .assistant("Kotlin is a modern programming language...")1516    // Add another user message17    .user("What are its key features?")18    .build();1920// Run the prompt21List<Message.Response> response = client.execute(prompt, OpenAIModels.Chat.GPT4o, Collections.emptyList());22// Print the response23System.out.println(response);2425client.close();

스트리밍 응답

참고 모든 LLM 고객이 사용할 수 있습니다.

생성된 응답을 처리해야 하는 경우 Kotlin의 executeStreaming() 메서드를 사용하거나 모델 출력을 스트리밍하기 위한 Java의 executeStreamingWithPublisher().

스트리밍 API는 다양한 프레임 유형을 제공합니다.

  • 델타 프레임 (TextDelta, ReasoningDelta, ToolCallDelta) — 청크로 도착하는 증분 콘텐츠
  • 전체 프레임(TextComplete, ReasoningComplete, ToolCallComplete) — 모든 델타가 수신된 후 전체 콘텐츠
  • 끝 프레임 (End) — 종료 이유와 함께 스트림 완료 신호를 보냅니다.

추론을 지원하는 모델(예: Claude Sonnet 4.5 또는 GPT-o1)의 경우 추론 프레임은 스트리밍. 프레임 작업에 대한 자세한 내용은 Streaming API documentation을 참조하세요.

코틀린

1// Set up the OpenAI client with your API key2val token = System.getenv("OPENAI_API_KEY")3val client = OpenAILLMClient(token)45val response = client.executeStreaming(6    prompt = prompt("stream_demo") { user("Stream this response in short chunks.") },7    model = OpenAIModels.Chat.GPT4_18)910response.collect { frame ->11    when (frame) {12        is StreamFrame.TextDelta -> print(frame.text)13        is StreamFrame.ReasoningDelta -> print("[Reasoning] ${frame.text}")14        is StreamFrame.ToolCallComplete -> println("\nTool call: ${frame.name}")15        is StreamFrame.End -> println("\n[done] Reason: ${frame.finishReason}")16        else -> {} // Handle other frame types if needed17    }18}

자바

1// Set up the OpenAI client with your API key2String token = System.getenv("OPENAI_API_KEY");3OpenAILLMClient client = new OpenAILLMClient(token);45Prompt prompt = Prompt.builder("stream_demo")6            .user("Stream this response in short chunks.")7            .build();89Publisher<StreamFrame> response = client.executeStreamingWithPublisher(prompt, OpenAIModels.Chat.GPT4_1);1011// Subscribe to the Publisher to consume frames12response.subscribe(new Subscriber<StreamFrame>() {13    private Subscription subscription;1415    @Override16    public void onSubscribe(Subscription s) {17        this.subscription = s;18        s.request(Long.MAX_VALUE);19    }2021    @Override22    public void onNext(StreamFrame frame) {23        switch (frame) {24            case StreamFrame.TextDelta delta ->25                    System.out.print(delta.getText());26            case StreamFrame.ReasoningDelta reasoning ->27                    System.out.print("[Reasoning] " + reasoning.getText());28            case StreamFrame.ToolCallComplete toolCall ->29                    System.out.println("\nTool call: " + toolCall.getName());30            case StreamFrame.End end ->31                    System.out.println("\n[done] Reason: " + end.getFinishReason());32            default -> {} // Handle other frame types33        }34    }3536    @Override37    public void onError(Throwable t) {38        t.printStackTrace();39    }4041    @Override42    public void onComplete() { }43});

객관식

참고 GoogleLLMClient, BedrockLLMClientOllamaClient를 제외한 모든 LLM 클라이언트에 사용 가능

executeMultipleChoices() 메서드를 사용하면 단일 호출로 모델에서 여러 대체 응답을 요청할 수 있습니다. 프롬프트에서 numberOfChoices LLM 매개변수를 추가로 지정해야 합니다. 처형되고 있습니다.

코틀린

1fun main() = runBlocking {2    val apiKey = System.getenv("OPENAI_API_KEY")3    val client = OpenAILLMClient(apiKey)45    val choices = client.executeMultipleChoices(6        prompt = prompt("n_best", params = LLMParams(numberOfChoices = 3)) {7            system("You are a creative assistant.")8            user("Give me three different opening lines for a story.")9        },10        model = OpenAIModels.Chat.GPT4o11    )1213    choices.forEachIndexed { i, choice ->14        val text = choice.joinToString(" ") { it.content }15        println("Line #${i + 1}: $text")16    }17}

자바

1String apiKey = System.getenv("OPENAI_API_KEY");2OpenAILLMClient client = new OpenAILLMClient(apiKey);34// Configure parameters (LLMParams constructor requires all 8 arguments in Java)5LLMParams params = new LLMParams(6    null, // temperature7    null, // maxTokens8    3,    // numberOfChoices9    null, // speculation10    null, // schema11    null, // toolChoice12    null, // user13    null  // additionalProperties14);1516Prompt prompt = Prompt.builder("n_best")17    .system("You are a creative assistant.")18    .user("Give me three different opening lines for a story.")19    .build()20    .withParams(params);2122// LLMChoice is a type alias for List<Message.Response>23List<List<Message.Response>> choices = client.executeMultipleChoices(24    prompt, 25    OpenAIModels.Chat.GPT4o26);2728for (int i = 0; i < choices.size(); i++) {29    List<Message.Response> choice = choices.get(i);30    StringBuilder text = new StringBuilder();31    for (Message.Response msg : choice) {32        text.append(msg.getContent()).append(" ");33    }34    System.out.println("Line #" + (i + 1) + ": " + text.toString().trim());35}

사용 가능한 모델 나열

참고 AnthropicLLMClient, BedrockLLMClientOllamaClient를 제외한 모든 LLM 클라이언트에 사용할 수 있습니다.

LLM 클라이언트가 지원하는 사용 가능한 모델 ID 목록을 얻으려면 models() 메서드를 사용하세요.

코틀린

1fun main() = runBlocking {2    val apiKey = System.getenv("OPENAI_API_KEY")3    val client = OpenAILLMClient(apiKey)45    val models: List<LLModel> = client.models()6    models.forEach { println(it.id) }7}

자바

1String apiKey = System.getenv("OPENAI_API_KEY");2OpenAILLMClient client = new OpenAILLMClient(apiKey);34List<LLModel> models = client.models();5for (LLModel model : models) {6    System.out.println(model.getId());7}

임베딩

참고 OpenAILLMClient, GoogleLLMClient, BedrockLLMClient, MistralAILLMClientOllamaClient에 사용할 수 있습니다.

embed() 메서드를 사용하여 텍스트를 임베딩 벡터로 변환합니다. 임베딩 모델을 선택하고 텍스트를 이 메서드에 전달합니다.

1fun main() = runBlocking {2    val apiKey = System.getenv("OPENAI_API_KEY")3    val client = OpenAILLMClient(apiKey)45    val embedding = client.embed(6        text = "This is a sample text for embedding",7        model = OpenAIModels.Embeddings.TextEmbedding3Large8    )910    println("Embedding size: ${embedding.size}")11}

절도

참고 다음 LLM 클라이언트에 사용할 수 있습니다: OpenAILLMClient, BedrockLLMClient, MistralAILLMClient, OllamaClient.

중재 모델과 함께 moderate() 방법을 사용하여 프롬프트에 부적절한 콘텐츠가 포함되어 있는지 확인할 수 있습니다.

코틀린

1fun main() = runBlocking {2    val apiKey = System.getenv("OPENAI_API_KEY")3    val client = OpenAILLMClient(apiKey)45    val result = client.moderate(6        prompt = prompt("moderation") {7            user("This is a test message that may contain offensive content.")8        },9        model = OpenAIModels.Moderation.Omni10    )1112    println(result)13}

자바

1String apiKey = System.getenv("OPENAI_API_KEY");2OpenAILLMClient client = new OpenAILLMClient(apiKey);34Prompt prompt = Prompt.builder("moderation")5    .user("This is a test message that may contain offensive content.")6    .build();78ModerationResult result = client.moderate(prompt, OpenAIModels.Moderation.Omni);9System.out.println(result);

프롬프트 실행자와 통합

Prompt executors은 LLM 클라이언트를 래핑하고 라우팅, 폴백, 공급자 전체의 통합 사용과 같은 추가 기능을 제공합니다. 여러 공급자와 작업할 때 유연성을 제공하므로 프로덕션 용도로 권장됩니다.

[^1]: OpenAI Moderation API를 통해 조정을 지원합니다. [^2]: 중재에는 Guardrails 구성이 필요합니다. [^3]: Mistral v1/moderations 엔드포인트를 통한 중재를 지원합니다.