/AI & 자동화/LLM 에이전트 메모리 시스템 설계: 단기 기억부터 장기 메모리까지
AI & 자동화LLM에이전트

LLM 에이전트 메모리 시스템 설계: 단기 기억부터 장기 메모리까지

LLM 에이전트가 장기적으로 맥락을 유지하고 학습하기 위한 메모리 아키텍처를 설계합니다. 대화 기록 관리, 요약 기반 압축, 벡터 DB를 활용한 장기 메모리까지 실전 코드와 함께 다룹니다.

LLM 에이전트 메모리 시스템 설계: 단기 기억부터 장기 메모리까지

LLM 에이전트 메모리 시스템 설계: 단기 기억부터 장기 메모리까지

에이전트의 가장 큰 한계 중 하나는 기억입니다. 컨텍스트 윈도우가 꽉 차면 초기 대화를 잊어버리고, 세션이 끊기면 모든 것이 사라집니다. 실용적인 에이전트를 만들려면 메모리를 명시적으로 설계해야 합니다.

메모리의 4가지 유형

유형특징구현 방법
단기 메모리현재 세션 내 대화 기록messages 배열
요약 메모리긴 대화를 압축 요약Summarization + LLM
의미 메모리사실·지식 저장벡터 DB
절차 메모리작업 수행 방법 기억Few-shot 예시 저장

단기 메모리: 슬라이딩 윈도우

Python
from collections import deque
from openai import OpenAI

class ShortTermMemory:
    def __init__(self, max_messages=20):
        self.messages = deque(maxlen=max_messages)
        self.system_prompt = "당신은 도움이 되는 AI 어시스턴트입니다."

    def add(self, role, content):
        self.messages.append({"role": role, "content": content})

    def get_context(self):
        return [{"role": "system", "content": self.system_prompt}] + list(self.messages)

client = OpenAI()
memory = ShortTermMemory(max_messages=10)

def chat(user_input):
    memory.add("user", user_input)
    response = client.chat.completions.create(
        model="gpt-4o", messages=memory.get_context()
    )
    reply = response.choices[0].message.content
    memory.add("assistant", reply)
    return reply

문제: 슬라이딩 윈도우는 오래된 중요 정보를 삭제합니다. 10번째 메시지에서 말한 사용자 이름을 30번째에서 잊어버립니다.

요약 메모리: 압축으로 컨텍스트 확장

대화가 길어지면 오래된 부분을 요약해서 저장합니다.

Python
import anthropic

client = anthropic.Anthropic()

class SummaryMemory:
    def __init__(self, window_size=10, summary_threshold=8):
        self.recent_messages = []
        self.summary = ""
        self.window_size = window_size
        self.summary_threshold = summary_threshold

    def _summarize(self):
        to_summarize = self.recent_messages[:self.summary_threshold]
        existing = f"기존 요약: {self.summary}

" if self.summary else ""
        conversation = "
".join(f"{m['role']}: {m['content']}" for m in to_summarize)

        response = client.messages.create(
            model="claude-haiku-4-5-20251001",
            max_tokens=300,
            messages=[{
                "role": "user",
                "content": f"{existing}다음 대화를 3-4문장으로 핵심만 요약하세요:

{conversation}"
            }]
        )
        return response.content[0].text

    def add(self, role, content):
        self.recent_messages.append({"role": role, "content": content})
        if len(self.recent_messages) > self.window_size:
            self.summary = self._summarize()
            self.recent_messages = self.recent_messages[self.summary_threshold:]

    def get_context(self):
        messages = []
        if self.summary:
            messages += [
                {"role": "user", "content": f"[이전 대화 요약]
{self.summary}"},
                {"role": "assistant", "content": "이전 대화 내용을 이해했습니다."}
            ]
        return messages + self.recent_messages

장기 메모리: 벡터 DB 기반

세션 간 정보를 유지하려면 외부 저장소가 필요합니다.

Python
from openai import OpenAI
import json
from datetime import datetime

client = OpenAI()

class LongTermMemory:
    def __init__(self, user_id, supabase_client):
        self.user_id = user_id
        self.sb = supabase_client

    def _embed(self, text):
        response = client.embeddings.create(
            model="text-embedding-3-small", input=text
        )
        return response.data[0].embedding

    def save(self, content, memory_type="fact"):
        embedding = self._embed(content)
        self.sb.table("agent_memories").insert({
            "user_id": self.user_id,
            "content": content,
            "memory_type": memory_type,
            "embedding": embedding,
            "created_at": datetime.utcnow().isoformat()
        }).execute()

    def recall(self, query, top_k=3):
        query_embedding = self._embed(query)
        result = self.sb.rpc("match_memories", {
            "query_embedding": query_embedding,
            "user_id": self.user_id,
            "match_count": top_k
        }).execute()
        return [r["content"] for r in (result.data or [])]

메모리 계층 통합

Python
class AgentWithMemory:
    def __init__(self, user_id):
        self.short_term = SummaryMemory(window_size=10)
        self.long_term = LongTermMemory(user_id=user_id)
        self.client = OpenAI()

    def chat(self, user_input):
        # 1. 장기 메모리에서 관련 기억 회상
        relevant_memories = self.long_term.recall(user_input)

        system_content = "당신은 도움이 되는 AI 어시스턴트입니다."
        if relevant_memories:
            system_content += "

[관련 기억]
" + "
".join(f"- {m}" for m in relevant_memories)

        # 2. 단기 + 장기 컨텍스트 조합
        messages = [{"role": "system", "content": system_content}]
        messages.extend(self.short_term.get_context())
        messages.append({"role": "user", "content": user_input})

        response = self.client.chat.completions.create(model="gpt-4o", messages=messages)
        reply = response.choices[0].message.content

        self.short_term.add("user", user_input)
        self.short_term.add("assistant", reply)

        # 3. 중요 정보를 장기 메모리에 저장
        self.long_term.extract_and_save(f"사용자: {user_input}
어시스턴트: {reply}")

        return reply

어떤 정보를 저장할 것인가

  • 저장 O: 사용자 선호도, 프로젝트 이름·목표, 반복 패턴, 명시적 요청("기억해줘")
  • 저장 X: 일회성 질문, 범용 사실(검색으로 대체 가능), 오류 메시지

다음 편에서는 구축한 에이전트의 평가와 디버깅 방법을 다룹니다.

✦ ✦ ✦
편집 검토 · Editorial Review

이 글은 AI 에이전트가 1차 초안을 작성한 뒤, 사람 편집자가 사실관계·출처·톤과 맥락을 검토하여 발행했습니다. 오류나 부정확한 내용이 확인되면 24시간 이내에 정정합니다.

작성 · Content Director·검토 · 사람 편집자·발행 · 2026년 5월 20일

댓글

불러오는 중...