채팅 메모리
원문: Koog Documentation — index 이 글은 Koog 공식 문서의 index 페이지를 한국어로 옮긴 번역본입니다. 문서 구조와 링크 의미를 유지하되, MkDocs 전용 UI 문법은 블로그에서 읽기 좋도록 정리했습니다.
채팅 메모리
ChatMemory 기능을 사용하면 AI 에이전트가 대화 기록을 저장하고 여러 실행에서 검색할 수 있습니다.
설치되면 에이전트는 각 실행 시작 시 자동으로 이전 메시지를 로드하고
실행이 완료되면 업데이트된 대화를 저장하여 자연스러운 다단계 채팅이 가능합니다.
주요 기능:
- 세션 ID별 대화 내용 자동 로딩 및 저장
ChatHistoryProvider을 통한 플러그형 스토리지 백엔드- 기록 크기를 제한하고 메시지를 필터링하는 내장 전처리기
- 임의 메시지 변환을 위한 맞춤형 전처리기 지원
종속성 추가
채팅 메모리는 기본적으로 Koog에서 사용할 수 없는 선택적인 feature입니다.
Koog 에이전트에 대한 채팅 메모리를 구현하려면 ai.koog:agents-features-memory에 대한 종속성을 추가하세요.
그레이들(코틀린)
1dependencies {2 implementation("ai.koog:agents-features-memory:$koogVersion")3}그레이들(그루비)
1dependencies {2 implementation 'ai.koog:agents-features-memory:$koogVersion'3}메이븐
1<dependency>2 <groupId>ai.koog</groupId>3 <artifactId>agents-features-memory-jvm</artifactId>4 <version>$koogVersion</version>5</dependency>참고
ChatMemory기능은 Koog 버전 0.7.0부터 사용할 수 있습니다.
채팅 메모리 활성화
에이전트를 생성할 때 install() 방법을 사용하여 ChatMemory을 설치합니다.
코틀린
1val agent = AIAgent(2 promptExecutor = simpleOpenAIExecutor(System.getenv("OPENAI_API_KEY")),3 llmModel = OpenAIModels.Chat.GPT4oMini4) {5 install(ChatMemory)6}자바
1AIAgent<String, String> agent = AIAgent.builder()2 .promptExecutor(executor)3 .llmModel(OpenAIModels.Chat.GPT4oMini)4 .install(ChatMemory.Feature)5 .build();기본적으로 preprocessors 없이 인메모리 chat history provider을 사용합니다.
사용자 정의 채팅 기록 제공자와 전처리기를 사용하도록 ChatMemory 기능을 구성합니다. 예를 들면 다음과 같습니다.
코틀린
1val agent = AIAgent(2 promptExecutor = simpleOpenAIExecutor(System.getenv("OPENAI_API_KEY")),3 llmModel = OpenAIModels.Chat.GPT4oMini4) {5 install(ChatMemory) {6 chatHistoryProvider = MyDatabaseChatHistoryProvider()7 windowSize(20)8 filterMessages { it is Message.User || it is Message.Assistant }9 }10}자바
1AIAgent<String, String> agent = AIAgent.builder()2 .promptExecutor(executor)3 .llmModel(OpenAIModels.Chat.GPT4oMini)4 .install(ChatMemory.Feature, config -> config5 .chatHistoryProvider(new MyDatabaseChatHistoryProvider())6 .windowSize(20)7 .filterMessages(msg -> msg instanceof Message.User || msg instanceof Message.Assistant))8 .build();세션 ID
agent.run()의 두 번째 인수로 세션 ID를 제공합니다.
ChatMemory은 이 ID를 사용하여 대화를 저장하고 로드합니다.
1// First run - the agent saves the chat history at the end2agent.run("What is the capital of France?", "session-1")34// Second run — the agent loads the previous exchange5agent.run("And what about Germany?", "session-1")서로 다른 세션 ID는 완전히 격리된 기록을 생성합니다.
기록 제공자
기본 InMemoryChatHistoryProvider은 스레드로부터 안전하지만 지속성이 없습니다(다시 시작하면 기록이 손실됨).
프로덕션의 경우 메시지를 지속적으로 저장하는 자체 ChatHistoryProvider을 구현하십시오.
1class MyDatabaseChatHistoryProvider(private val db: Database) : ChatHistoryProvider {2 override suspend fun store(conversationId: String, messages: List<Message>) {3 db.saveMessages(conversationId, messages)4 }56 override suspend fun load(conversationId: String): List<Message> {7 return db.loadMessages(conversationId) ?: emptyList()8 }9}전처리기
전처리기는 로드 시간(에이전트가 보기 전)과 저장 시간(저장 전)에 메시지 목록을 변환합니다.
ChatMemory 기능 구성에 추가한 순서대로 순차적으로 실행됩니다.
내장 전처리기
| 구성 방법 | 전처리기 클래스 | 행동 |
|---|---|---|
windowSize(n) |
WindowSizePreProcessor |
마지막 n 메시지만 유지합니다. |
filterMessages { ... } |
FilterMessagesPreProcessor |
메시지가 조건자와 일치하도록 유지합니다. |
전처리기 순서
전처리기는 순차적으로 실행되며 각 출력이 다음 입력이 됩니다. 즉, 순서가 중요합니다.
1// Effect: keep last 10 messages, then filter short ones from those 102windowSize(10)3filterMessages { it.content.length <= 100 }45// Effect: filter short messages first, then keep last 10 of the survivors6filterMessages { it.content.length <= 100 }7windowSize(10)맞춤형 전처리기
사용자 정의 전처리기를 생성하려면 ChatMemoryPreProcessor 인터페이스를 구현하십시오.
1class RedactEmailsPreProcessor : ChatMemoryPreProcessor {2 override fun preprocess(messages: List<Message>): List<Message> {3 return messages.map { message ->4 // Replace email addresses in message content5 Message.User(message.content.replace(Regex("[\\w.]+@[\\w.]+"), "[REDACTED]"))6 }7 }8}그런 다음 구성에 추가합니다.
1install(ChatMemory) {2 addPreProcessor(RedactEmailsPreProcessor())3 windowSize(50)4}채팅 메모리와 상담원 지속성
ChatMemory은 각 agent.run() 호출을 원자적이고 독립적인 루프로 처리합니다.
에이전트는 실행하기 전에 채팅 기록을 로드하고 성공적인 실행 후에 저장합니다.
실행 중에 에이전트가 충돌하는 경우 현재 채팅 메시지를 저장하지 않습니다.
이는 채팅 기록이 실행 전과 동일하게 유지된다는 의미입니다.
Persistence는 에이전트의 내부 실행 상태를 캡처합니다. (그래프 노드, 메시지 기록, 입력 및 출력)을 실행 중 체크포인트로 사용합니다. 에이전트가 충돌하면 마지막 체크포인트부터 다시 시작할 수 있습니다.
| 채팅메모리 | 고집 | |
|---|---|---|
| 절약되는 점 | 대화 메시지 | 실행 상태 |
| 저장할 때 | agent.run() 완료 후 |
각 그래프 노드 이후 또는 실행 중 수동으로 정의된 지점에서 |
| 충돌 동작 | 진행 중인 실행이 손실됩니다. 이전 기록이 그대로 유지됨 | 마지막 체크포인트에서 재개 가능 |
| 일반적인 사용 | 다단계 채팅 연속성 | 응급 복구 기능을 갖춘 장기 실행 에이전트 |
에이전트가 실행 중 충돌로 인해 비용이 많이 드는 장기 실행 작업을 수행하는 경우 다음을 고려하세요. 두 기능을 모두 설치:
1val agent = AIAgent(2 promptExecutor = executor,3 llmModel = OpenAIModels.Chat.GPT4oMini,4 systemPrompt = "You are a helpful assistant.",5) {6 install(ChatMemory) {7 chatHistoryProvider = MyDatabaseProvider()8 windowSize(50)9 }10 install(Persistence) {11 storage = MyPersistenceStorageProvider()12 enableAutomaticPersistence = true13 }14}모범 사례
- 항상 창 크기를 설정하여 대화가 무제한으로 늘어나는 것을 방지하세요.
- 전처리기를 신중하게 주문하세요. 윈도우화 전 필터링과 필터링 전 윈도우화는 서로 다른 결과를 생성하기 때문입니다.
- 기록 격리를 위해 의미 있는 세션 ID를 사용하세요. 사용자 ID, 채팅 스레드 ID 또는 UUID가 모두 잘 작동합니다.
- 프로덕션을 위한 영구 공급자를 구현합니다. 기본
InMemoryChatHistoryProvider은 다시 시작 시 기록을 잃기 때문입니다.