LLM 세션 및 수동 이력 관리
원문: Koog Documentation — sessions 이 글은 Koog 공식 문서의 sessions 페이지를 한국어로 옮긴 번역본입니다. 문서 구조와 링크 의미를 유지하되, MkDocs 전용 UI 문법은 블로그에서 읽기 좋도록 정리했습니다.
LLM 세션 및 수동 이력 관리
이 페이지는 읽기 작업 방법을 포함하여 LLM 세션에 대한 자세한 정보를 제공합니다. 세션을 작성하고, 대화 기록을 관리하고, 언어 모델에 요청합니다.
소개
LLM 세션은 언어 모델(LLM)과 상호 작용하는 구조화된 방법을 제공하는 기본 개념입니다. 대화 기록을 관리하고, LLM에 대한 요청을 처리하며, 일관된 도구를 실행하고 응답을 처리하기 위한 인터페이스입니다.
LLM 세션 이해
LLM 세션은 언어 모델과 상호 작용하기 위한 컨텍스트를 나타냅니다. 이는 다음을 캡슐화합니다:
- 대화 내역(프롬프트)
- 사용 가능한 도구
- LLM에 요청하는 방법
- 대화 기록 업데이트 방법
- 도구 실행 방법
세션은 읽기 및 쓰기 세션을 생성하는 방법을 제공하는 AIAgentLLMContext 클래스에 의해 관리됩니다.
세션 유형
Koog 프레임워크는 두 가지 유형의 세션을 제공합니다.
쓰기 세션(
AIAgentLLMWriteSession): 프롬프트 및 도구 수정, LLM 요청 및 실행 도구. 쓰기 세션에서 변경된 내용은 LLM 컨텍스트에 다시 유지됩니다.세션 읽기(
AIAgentLLMReadSession): 프롬프트 및 도구에 대한 읽기 전용 액세스를 제공합니다. 그들은 유용합니다 변경하지 않고 현재 상태를 검사합니다.
주요 차이점은 쓰기 세션은 대화 기록을 수정할 수 있지만 읽기 세션은 수정할 수 없다는 것입니다.
세션 수명주기
세션에는 정의된 수명 주기가 있습니다.
- 생성:
llm.writeSession { ... }또는llm.readSession { ... }을 사용하여 세션이 생성됩니다. - 활성 단계: 람다 블록이 실행되는 동안 세션이 활성화됩니다.
- 종료: 람다 블록이 완료되면 세션이 자동으로 닫힙니다.
세션은 AutoCloseable 인터페이스를 구현하여 예외가 발생하더라도 적절하게 정리되도록 합니다.
LLM 세션 작업
세션 생성
세션은 AIAgentLLMContext 클래스의 메서드를 사용하여 생성됩니다.
코틀린
1// Creating a write session2llm.writeSession {3 // Session code here4}56// Creating a read session7llm.readSession {8 // Session code here9}자바
1// Creating a write session2ctx.getLlm().writeSession(session -> {3 // Session code here4 return null;5});67// Creating a read session8ctx.getLlm().readSession(session -> {9 // Session code here10 return null;11});이러한 함수는 세션 컨텍스트 내에서 실행되는 람다 블록을 사용합니다. 세션이 자동으로 닫힙니다. 블록이 완료되면.
세션 범위 및 스레드 안전성
세션은 스레드 안전을 보장하기 위해 읽기-쓰기 잠금을 사용합니다.
- 여러 읽기 세션이 동시에 활성화될 수 있습니다.
- 한 번에 하나의 쓰기 세션만 활성화될 수 있습니다.
- 쓰기 세션은 다른 모든 세션(읽기 및 쓰기 모두)을 차단합니다.
이렇게 하면 동시 수정으로 인해 대화 기록이 손상되지 않습니다.
세션 속성에 액세스
세션 내에서 프롬프트와 도구에 액세스할 수 있습니다.
코틀린
1llm.readSession {2 val messageCount = prompt.messages.size3 val availableTools = tools.map { it.name }4}자바
1ctx.getLlm().readSession(session -> {2 int messageCount = session.getPrompt().getMessages().size();3 var availableTools = session.getTools().stream().map(tool -> tool.getName()).toList();4 return null;5});쓰기 세션에서는 다음 속성을 수정할 수도 있습니다.
코틀린
1llm.writeSession {2 // Modify the prompt3 appendPrompt {4 user("New user message")5 }67 // Modify the tools8 tools = newTools9}자바
1ctx.getLlm().writeSession(session -> {2 // Modify the prompt3 session.appendPrompt(promptBuilder -> {4 promptBuilder.user("New user message");5 return null;6 });78 // Modify the tools9 session.setTools(newTools);10 return null;11});자세한 내용은 AIAgentLLMReadSession 및 AIAgentLLMWriteSession에 대한 자세한 API 참조를 참조하세요.
LLM 요청하기
기본 요청 방법
LLM 요청을 하는 가장 일반적인 방법은 다음과 같습니다.
requestLLM(): 현재 프롬프트와 도구를 사용하여 LLM에 요청하고 단일 응답을 반환합니다.requestLLMMultiple(): 현재 프롬프트와 도구를 사용하여 LLM에 요청하고 여러 개를 반환합니다. 응답.requestLLMWithoutTools(): 도구 없이 현재 프롬프트를 사용하여 LLM에 요청하고 단일 응답.requestLLMForceOneTool(): 현재 프롬프트와 도구를 사용하여 LLM에 요청하여 하나의 도구를 사용하도록 합니다.requestLLMOnlyCallingTools(): 도구를 사용해서만 처리해야 하는 LLM에 요청합니다.
예:
코틀린
1llm.writeSession {2 // Make a request with tools enabled3 val response = requestLLM()45 // Make a request without tools6 val responseWithoutTools = requestLLMWithoutTools()78 // Make a request that returns multiple responses9 val responses = requestLLMMultiple()10}자바
1ctx.getLlm().writeSession(session -> {2 // Make a request with tools enabled3 var response = session.requestLLM();45 // Make a request without tools6 var responseWithoutTools = session.requestLLMWithoutTools();78 // Make a request that returns multiple responses9 var responses = session.requestLLMMultiple();10 return null;11});요청 작동 방식
요청 메서드 중 하나를 명시적으로 호출하면 LLM 요청이 이루어집니다. 이해해야 할 핵심 사항은 다음과 같습니다.
- 명시적 호출: 요청은
requestLLM(),requestLLMWithoutTools()등과 같은 메서드를 호출할 때만 발생합니다. - 즉시 실행: 요청 메서드를 호출하면 즉시 요청이 이루어지고 메서드가 차단됩니다. 응답을 받을 때까지.
- 자동 기록 업데이트: 쓰기 세션에서 응답이 자동으로 대화 기록에 추가됩니다.
도구를 사용한 요청 방법
도구가 활성화된 상태에서 요청할 때 LLM은 텍스트 응답 대신 도구 호출로 응답할 수 있습니다. 요청 메소드는 이를 투명하게 처리합니다.
코틀린
1llm.writeSession {2 val response = requestLLM()34 // The response might be a tool call or a text response5 if (response is Message.Tool.Call) {6 // Handle tool call7 } else {8 // Handle text response9 }10}자바
1ctx.getLlm().writeSession(session -> {2 var response = session.requestLLM();34 // The response might be a tool call or a text response5 if (response instanceof Message.Tool.Call) {6 // Handle tool call7 } else {8 // Handle text response9 }10 return null;11});실제로는 에이전트 그래프가 이 라우팅을 처리하므로 일반적으로 응답 유형을 수동으로 확인할 필요가 없습니다. 자동으로.
구조화된 요청과 스트리밍 요청
고급 사용 사례의 경우 구조화된 요청과 스트리밍 요청 방법이 제공됩니다.
requestLLMStructured(): LLM에 특정 구조화된 형식으로 응답을 제공하도록 요청합니다.requestLLMStructuredOneShot():requestLLMStructured()과 유사하지만 재시도나 수정이 없습니다.requestLLMStreaming(): LLM에 스트리밍 요청을 하고 응답 청크의 흐름을 반환합니다. Streaming API 페이지에서 스트리밍에 대해 자세히 알아볼 수 있습니다.
예:
코틀린
1llm.writeSession {2 // Make a structured request3 val structuredResponse = requestLLMStructured<JokeRating>()45 // Make a streaming request6 val responseStream = requestLLMStreaming()7 responseStream.collect { chunk ->8 // Process each chunk as it arrives9 }10}자바
1ctx.getLlm().writeSession(session -> {2 // Make a non-tool request3 var responseWithoutTools = session.requestLLMWithoutTools();45 // Make a streaming request6 var responseStream = session.requestLLMStreaming();7 // Process chunks from Flow.Publisher<StreamFrame>8 return null;9});대화 기록 관리
프롬프트 업데이트 중
쓰기 세션에서 appendPrompt 메서드를 사용하여 프롬프트(대화 기록)에 메시지를 추가할 수 있습니다.
코틀린
1llm.writeSession {2 appendPrompt {3 // Add a system message4 system("You are a helpful assistant.")56 // Add a user message7 user("Hello, can you help me with a coding question?")89 // Add an assistant message10 assistant("Of course! What's your question?")1112 // Add a tool result13 tool {14 result(myToolResult)15 }16 }17}자바
1ctx.getLlm().writeSession(session -> {2 session.appendPrompt(promptBuilder -> {3 // Add a system message4 promptBuilder.system("You are a helpful assistant.");56 // Add a user message7 promptBuilder.user("Hello, can you help me with a coding question?");89 // Add an assistant message10 promptBuilder.assistant("Of course! What's your question?");1112 // Add follow-up context after tool execution13 promptBuilder.assistant("Tool execution completed successfully.");14 return null;15 });16 return null;17});prompt 속성에 새 Prompt 개체를 할당하여 프롬프트를 완전히 다시 작성할 수도 있습니다.
코틀린
1llm.writeSession {2 // Create a new prompt based on the old one3 prompt = prompt.copy(messages = filteredMessages)4}자바
1ctx.getLlm().writeSession(session -> {2 var oldPrompt = session.getPrompt();3 // Rebuild and replace the prompt (manual rewrite approach in Java)4 session.setPrompt(5 Prompt.builder(oldPrompt.getId())6 .user("Retained summary of previous conversation")7 .build()8 );9 return null;10});응답 시 자동 기록 업데이트
쓰기 세션에서 LLM 요청을 하면 응답이 자동으로 대화 기록에 추가됩니다.
코틀린
1llm.writeSession {2 // Add a user message3 appendPrompt {4 user("What's the capital of France?")5 }67 // Make a request - the response is automatically added to the history8 val response = requestLLM()910 // The prompt now includes both the user message and the model's response11}자바
1ctx.getLlm().writeSession(session -> {2 // Add a user message3 session.appendPrompt(promptBuilder -> {4 promptBuilder.user("What's the capital of France?");5 return null;6 });78 // Make a request - the response is automatically added to the history9 var response = session.requestLLM();1011 // The prompt now includes both the user message and the model's response12 return null;13});이 자동 기록 업데이트는 대화가 자연스럽게 흐르도록 보장하는 쓰기 세션의 핵심 기능입니다.
기록 압축
장기간 실행되는 대화의 경우 기록이 커지고 많은 토큰을 소비할 수 있습니다. 플랫폼은 방법을 제공합니다 기록을 압축하려면 다음을 수행하세요.
코틀린
1llm.writeSession {2 // Compress the history using a TLDR approach3 replaceHistoryWithTLDR(HistoryCompressionStrategy.WholeHistory, preserveMemory = true)4}자바
1// Use the dedicated Java node for history compression.2var compressHistory = AIAgentNode.llmCompressHistory("compressHistory");전략 그래프에서 nodeLLMCompressHistory 노드를 사용하여 특정 지점의 기록을 압축할 수도 있습니다.
기록 압축 및 압축 전략에 대한 자세한 내용은 History compression을 참조하세요.
세션에서 도구 실행
호출 도구
쓰기 세션은 도구 호출을 위한 여러 가지 방법을 제공합니다.
callTool(tool, args): 참조로 도구를 호출합니다.callTool(toolName, args): 이름으로 도구를 호출합니다.callTool(toolClass, args): 클래스별로 도구를 호출합니다.callToolRaw(toolName, args): 이름으로 도구를 호출하고 원시 문자열 결과를 반환합니다.
예:
코틀린
1llm.writeSession {2 // Call a tool by reference3 val result = callTool(myTool, myArgs)45 // Call a tool by name6 val result2 = callTool("myToolName", myArgs)78 // Call a tool by class9 val result3 = callTool(MyTool::class, myArgs)1011 // Call a tool and get the raw result12 val rawResult = callToolRaw("myToolName", myArgs)13}자바
1// Java uses dedicated tool-execution nodes in graph strategies.2var executeTool = AIAgentNode.executeTool("executeTool");3var sendToolResult = AIAgentNode.llmSendToolResult("sendToolResult");병렬 도구 실행
여러 도구를 병렬로 실행하려면 쓰기 세션이 Flow에 확장 기능을 제공합니다.
코틀린
1llm.writeSession {2 // Run tools in parallel3 parseDataToArgs(data).toParallelToolCalls(MyTool::class).collect { result ->4 // Process each result5 }67 // Run tools in parallel and get raw results8 parseDataToArgs(data).toParallelToolCallsRaw(MyTool::class).collect { rawResult ->9 // Process each raw result10 }11}자바
1// Java equivalent for multi-tool execution in parallel: use executeMultipleTools node.2var executeMultipleTools = AIAgentNode.executeMultipleTools(true, "executeMultipleTools");이는 많은 양의 데이터를 효율적으로 처리하는 데 유용합니다.
모범 사례
LLM 세션으로 작업할 때 다음 모범 사례를 따르십시오.
올바른 세션 유형 사용: 대화 기록을 수정하고 읽어야 하는 경우 쓰기 세션을 사용하세요. 읽기만 하면 되는 세션입니다.
세션을 짧게 유지: 세션은 특정 작업에 중점을 두고 릴리스하려면 최대한 빨리 종료해야 합니다. 자원.
예외 처리: 리소스 누출을 방지하려면 세션 내에서 예외를 처리해야 합니다.
기록 크기 관리: 장기간 실행되는 대화의 경우 기록 압축을 사용하여 토큰 사용량을 줄입니다.
고수준 추상화 선호: 가능하면 노드 기반 API를 사용하세요. 예를 들어 세션에서 직접 작업하는 대신
nodeLLMRequest을 사용합니다.스레드 안전에 유의하세요: 쓰기 세션이 다른 세션을 차단하므로 쓰기 작업을 짧게 유지하세요. 가능한 한.
복잡한 데이터에 구조화된 요청 사용: 구조화된 데이터를 반환하기 위해 LLM이 필요한 경우 다음을 사용하세요.
requestLLMStructured자유 형식 텍스트를 구문 분석하는 대신.긴 응답에는 스트리밍 사용: 긴 응답의 경우
requestLLMStreaming을 사용하여 응답을 그대로 처리합니다. 도착합니다.
문제 해결
세션이 이미 종료되었습니다.
Cannot use session after it was closed과 같은 오류가 표시되면 람다 이후에 세션을 사용하려고 하는 것입니다.
블록이 완료되었습니다. 모든 세션 작업이 세션 블록 내에서 수행되는지 확인하세요.
기록이 너무 큼
기록이 너무 커지고 너무 많은 토큰을 소비하는 경우 기록 압축 기술을 사용하십시오.
코틀린
1llm.writeSession {2 replaceHistoryWithTLDR(HistoryCompressionStrategy.FromLastNMessages(10), preserveMemory = true)3}자바
1// Compress recent history with the Java compression node.2var compressHistory = AIAgentNode.llmCompressHistory("compressHistory");자세한 내용은 History compression을 참조하세요.
도구를 찾을 수 없습니다
도구를 찾을 수 없다는 오류가 표시되면 다음을 확인하세요.
- 도구가 도구 레지스트리에 올바르게 등록되었습니다.
- 올바른 도구 이름이나 클래스를 사용하고 있습니다.
API 문서
자세한 내용은 전체 AIAgentLLMSession 및 AIAgentLLMContext 참조를 확인하세요.