
RAG에서 메모리 시스템으로: 상태 유지 AI 아키텍처 구축하기
요약
RAG의 한계를 넘어 AI 에이전트의 연속성을 보장하기 위한 메모리 시스템 구축 방법을 다룹니다. 단순 검색을 넘어 사실, 선호도, 정책 등을 관리하는 상태 유지(Stateful) 아키텍처 설계의 중요성을 강조합니다.
핵심 포인트
- RAG는 정보 검색 도구일 뿐, 사용자의 선호도나 맥락을 기억하는 메모리가 아님
- 메모리 시스템은 사실, 선호도, 정책 등을 저장하여 대화의 연속성을 제공함
- 효율적인 메모리 관리를 위해 무엇을 저장하고 검색할지 제어하는 메모리 관리자가 필수적임
- 단순한 프롬프트 팽창이 아닌 재사용 가능한 메모리 계층 구축이 목표임
이 기사는 blogs.oracle.com의 원문 게시물에서 제공되었습니다. 최신 업데이트를 확인하려면 해당 사이트의 정식 버전을 읽어보세요.
검색(Retrieval)이 메모리가 아닌 이유, 그리고 조회를 위한 설계가 아닌 연속성을 위해 구축할 때 무엇이 변하는가.
핵심 요약 (Key Takeaways)
- RAG는 검색(Retrieval)이지 메모리가 아닙니다. RAG는 AI가 정보를 찾는 것을 도와주지만, 사용자의 선호도, 과거 작업 또는 진행 중인 대화를 안정적으로 기억할 수는 없습니다.
- 메모리 시스템은 연속성(Continuity)을 더합니다. 메모리 시스템은 사실(Facts), 선호도(Preferences), 정책(Policies), 요약(Summaries)을 저장하고 재사용하여 AI가 세션과 상호작용 전반에 걸쳐 지속될 수 있도록 합니다.
- 서로 다른 메모리에는 서로 다른 처리가 필요합니다. 정책, 선호도, 사실, 에피소드(Episodes), 흔적(Traces)은 각각 고유한 저장 규칙, 검색 방법 및 생명주기(Lifecycles)를 가져야 합니다.
- 메모리 관리자(Memory Manager)가 핵심 구성 요소입니다. 메모리 관리자는 거버넌스, 개인정보 보호 및 효율성을 유지하면서 무엇을 저장할지, 무엇을 검색할지, 그리고 매 턴마다 프롬프트(Prompts)를 어떻게 재구성할지를 제어합니다.
대부분의 팀이 RAG로 배포하는 패턴은 대략 네 줄의 코드와 같습니다: 문서를 임베딩(Embed)하고, 각 사용자 쿼리(Query)를 임베딩한 다음, 상위 k개의 근접 이웃(Top-k nearest neighbors)을 가져와 프롬프트에 집어넣는 방식입니다. 이 방식은 작동합니다. 지난 2년 동안 배포된 거의 모든 내부 지식 어시스턴트의 기본값으로 사용될 만큼 충분히 잘 작동합니다. 하지만 이 방식은 왜 그러한 어시스턴트들이 첫 번째 흥미로운 대화 이후에 모두 똑같이 느껴지는지를 설명해 주기도 합니다. 그들은 잊어버리고 같은 말을 반복합니다. 방금 들은 내용으로부터 학습할 수 없으며, 의미 있는 일련의 대화를 이어 나갈 수 없습니다.
RAG는 모델이 정보를 찾아볼 수 있도록 돕습니다. 메모리 시스템 (Memory system)은 애플리케이션이 여러 턴 (turns)에 걸쳐 내용을 기억하고 지속할 수 있도록 돕습니다. 목표는 프롬프트 (prompts)에 더 많은 토큰 (tokens)을 계속해서 채워 넣는 것이 아닙니다. 목표는 한 번 입력받고, 유용한 것을 추출하며, 필요할 때 적절한 조각을 검색하는 재사용 가능한 메모리 계층 (memory layer)을 구축하는 것입니다. 대부분의 팀은 에이전트 메모리 (agent memory)를 갖춘 것이 아니라, 검색 (retrieval)과 프롬프트 팽창 (prompt inflation)을 가지고 있을 뿐입니다.
함께 제공되는 데모를 시도해 보세요: Oracle AI Developer Hub 리포지토리에서 작동하는 RAG-to-memory 구현, 스키마 (schemas), 그리고 실행 가능한 코드를 탐색할 수 있습니다.
AI 에이전트를 실제로 상태 유지 (stateful)가 가능하게 만들기 위해 검색 주변에 무엇이 배치되어야 하는지 보여주는 가이드 영상을 확인해 보세요: 타입 지정 메모리 (typed memory), 범위 지정 레코드 (scoped records), 승격 게이트 (promotion gates), 폴백 검색 (fallback retrieval), 프롬프트 조립 (prompt assembly), 그리고 트레이스 (traces)가 포함되어 있습니다.
RAG를 메모리 시스템으로 진화시키는 방법
요약하자면: 검색 파이프라인 (retrieval pipeline)을 더 큰 루프 (loop)의 하나의 입력으로 유지하고, 그 주변에 다음 다섯 가지를 추가하십시오.
- 메모리에 타입을 지정하십시오. 정책 (policy), 선호도 (preference), 사실 (fact), 에피소드 (episodic), 그리고 트레이스 (trace) 메모리를 서로 다른 생명주기를 가진 별도의 스키마 (schemas)로 분리하십시오.
- 모든 레코드에 범위를 지정하십시오. tenant_id, user_id, agent_id를 추가하고, 랭킹 (ranking) 이후가 아니라 랭킹 이전에 범위를 엄격한 술어 (predicate)로 강제하십시오.
- 관찰 (observations)과 영구 저장 (durable writes) 사이에 승격 게이트 (promotion gate)를 두십시오. 이는 모델이 말한 모든 내용으로 인해 저장소가 오염되는 것을 방지합니다.
- 매 턴마다 프롬프트를 재조립하십시오. 여러 턴에 걸쳐 컨텍스트 (context)를 누적하기보다 타입 지정 메모리 (typed memory)를 사용하십시오.
- 루프를 계측 (instrument)하십시오. 다시 재생(replay), 감사(audit), 그리고 개선할 수 있도록 트레이스 엔벨로프 (trace envelope)를 추가하십시오.
RAG vs 메모리 비교
이 가이드의 나머지 부분에서는 각 단계, 그 이면에 있는 스키마 (schemas), 쿼리 (queries), 구축해야 할 순서, 그리고 프로덕션 (production) 환경에서 생존할 수 있을지를 결정하는 트레이드오프 (tradeoffs)를 살펴봅니다.
왜 기본적인 RAG는 상태 유지 (stateful) AI에 미치지 못하는가
순수 검색 (retrieval) 아키텍처는 보통 다음과 같은 다섯 가지 지점에서 실패하며, 대개 동일한 순서로 문제가 발생합니다.
멀티턴 연속성 (Multi-turn continuity). 매 턴마다 대화 기록 (transcript)을 다시 채워 넣지 않는 한, 시스템은 방금 무엇이 말해졌는지에 대한 기억이 없습니다. 기록을 채워 넣으면 토큰 (tokens) 비용이 발생하고 컨텍스트 부패 (context rot)로 인해 모델 품질이 저하됩니다. 기록을 생략하면 에이전트 (agent)는 사용자가 세 메시지 전에 무엇을 물었는지 잊어버립니다. 검색 (retrieval)만으로는 이 문제를 해결할 수 없습니다.
재개 가능성 (Resumability). 사용자가 금요일에 탭을 닫고 월요일에 다시 엽니다. 에이전트는 사용자가 멈췄던 지점부터 다시 시작해야 합니다. RAG만 사용하면 살아남는 것은 문서 코퍼스 (document corpus)뿐입니다. 사용자가 표현한 모든 선호도와 진행 중이던 모든 부분적인 워크플로우 (workflow)는 사라집니다.
긴 대화 (Long conversations). 수백 번의 턴이 지나면 더 이상 대화 기록을 모두 담을 수 없습니다. 요약 (summarization)과 구조화된 추출 (structured extraction)이 필요합니다. 이 중 어느 것도 검색 (retrieval)이 아닙니다.
사용자 선호도 및 정책 회상 (User preferences and policy recall). "이 사용자는 JSON을 원함." "이 테넌트 (tenant)는 날짜 형식을 DD/MM/YYYY로 사용함." "500달러 이상의 환불은 승인이 필요함." 이러한 정보는 사용자의 마지막 메시지와 의미적 유사성 (semantic similarity)을 비교한다고 해서 얻을 수 있는 것이 아닙니다. 이는 적절한 사용자 또는 테넌트 범위 내에서 매 턴마다 안정적인 가시성을 가지고 정확한 조회 (lookup)가 필요한 지속적인 규칙이자 파라미터 (parameters)입니다.
프롬프트 증가 (Prompt growth). 위 모든 문제에 대한 기본 대응은 프롬프트 (prompt)에 더 많은 것을 집어넣는 것입니다. 더 많은 검색 (retrieval), 더 많은 히스토리 (history), 더 많은 컨텍스트 (context). 토큰 비용은 복리로 증가하고, 모델은 중간 부분에서 길을 잃으며 (lost-in-the-middle), 시스템은 더 유능해져야 할 바로 그 순간에 오히려 더 느리게 느껴집니다.
문서에 대한 의미적 조회 (semantic lookup)만 필요하다면 기본적인 RAG로 충분합니다. 하지만 연속성과 관리된 회상 (governed recall)이 필요하다면, 이제 당신은 메모리 시스템 (memory system) 설계 문제에 직면한 것입니다.
검색이 메모리가 될 때 무엇이 변하는가
여기서의 변화는 벡터 스토어(vector store) 옆에 데이터베이스를 단순히 덧붙이는 것이 아닙니다. 변화하는 핵심은 저장 계층(storage layer)의 용도와 에이전트(agent)가 저장 계층과 상호작용하는 방식입니다.
검색(Retrieval)은 한 번 주입(ingest)된 코퍼스(corpus)에 대한 질의(query)입니다. 코퍼스는 상류(upstream)에 있고 질의는 하류(downstream)에 있습니다. 모델이 말하거나 수행하는 그 어떤 것도 코퍼스로 다시 흘러 들어가지 않습니다.
메모리는 '쓰기(write)' 경로입니다. 시스템이 실행 중에 관찰한 모든 것이나 사용자가 명시적으로 확인한 모든 것은 영구 저장소(durable store)로 승격(promote)될 수 있습니다. 승격된 각 레코드(record)는 고유한 범위(scope), 이를 생성한 실행(run)으로 거슬러 올라가는 출처(provenance), 그리고 보존 규칙(retention rule)을 가집니다. 동일한 레코드는 나중에 다른 턴(turn), 다른 세션(session), 또는 동일한 액세스 경계(access boundary) 내에서 작동하는 다른 에이전트에 의해 읽힐 수 있습니다.
이 가이드의 나머지 부분을 위한 유용한 프레임워크는 다음과 같습니다:
- 지식이 필요할 때는 검색(Retrieve)하십시오
- 연속성(continuity)이 필요할 때는 저장(Store)하십시오
- 정밀도(precision)가 필요할 때는 구조화(Structure)하십시오
- 압축(compression)이 필요할 때는 요약(Summarize)하십시오
- 운영 환경의 신뢰(production trust)가 필요할 때는 거버넌스(Govern)하십시오
이러한 종류의 시스템을 설명하는 대중적인 비유가 있습니다: 바로 '제2의 뇌(the second brain)'입니다. 이러한 프레임워크가 중요한 이유는 대부분의 제2의 뇌 구현 방식이 한 단계 부족하기 때문입니다. 대부분은 검색 가능한 노트(notes)를 제공하는데, 이는 실제 메모리라기보다는 더 나은 서류 보관함(filing cabinet)에 가깝습니다. 진정한 제2의 뇌는 축적되고 재사용 가능한 메모리입니다. 노트는 그것이 설명하는 엔티티(entity)에 부착되는 사실(fact)로 증류(distill)되며, 완료된 작업은 재사용 가능한 에피소드(episode)로 요약됩니다. 그러면 동일한 저장소가 한 사용자의 채팅 세션, 사용자를 대신해 실행되는 자율 에이전트(autonomous agent), 그리고 나중에 자신의 작업을 검색하는 사람에게 각각 별도의 복사본을 가질 필요 없이 서비스를 제공합니다. 아키텍처의 도약은 파일 검색(file retrieval)에서 메모리 형성(memory formation)으로의 전환입니다. 최적화는 컨텍스트 채워넣기(context stuffing)에서 컨텍스트 재사용(context reuse)으로의 전환입니다.
벡터 스토어는 메모리 시스템이 아닙니다. 이 가이드의 나머지 내용은 그 차이점 이면에 있는 내용들을 다룹니다.
AI 시스템에는 어떤 종류의 메모리가 필요한가
AI 시스템을 위한 메모리 유형
"메모리 추가(Add memory)"는 단일 기능처럼 들릴 수 있지만, 실제로는 여러 개의 서로 다른 시스템을 의미합니다. 이들을 분리하지 않으면 모든 질문을 형편없이 처리하는 하나의 만능 저장소(catch-all store)를 갖게 될 뿐입니다.
안티 패턴(Anti-pattern): 모든 종류의 메모리를 위한 단일 메모리 저장소. 모든 것이 들어가는 단일 벡터 인덱스(vector index)를 사용하는 경우입니다. 가공되지 않은 대화 로그(Raw conversation logs)가 추출된 사실(extracted facts) 옆에 놓입니다. 사용자의 선호도(user preference)는 3주 전의 스쳐 지나가는 발언처럼 보입니다. 테넌트 정책(tenant policy)은 단지 순위가 매겨져야 할 또 다른 행(row)일 뿐입니다. 검색(Retrieval) 단계에서 이를 구분할 수 없으며, 결과가 프롬프트(prompt)에 전달될 때 모델 또한 이를 구분할 수 없습니다.
구분할 가치가 있는 다섯 가지 유형이 있습니다. 각 유형은 고유한 스키마(schema)와 생명주기(lifecycle)를 가지며, 각기 다른 검색 전략(retrieval strategy)을 요구합니다. 이 중 어느 두 가지라도 혼동하면 특정한 예측 가능한 실패 모드(failure modes)가 발생합니다.
정책 메모리 (Policy memory)
절차적 규칙 및 제약 조건입니다. 테넌트 범위(Tenant-scoped) 또는 전역(global)이며, 버전 관리(versioned)가 되고 엄격하게 제어됩니다. 유사도(similarity)가 아닌 정확한 일치(exact match)를 통해 검색됩니다.
존재 이유: 에이전트(agent)는 규칙을 따라야 합니다. 컴플라이언스 제약(Compliance constraints), 브랜드 가드레일(brand guardrails), 승인 임계값(approval thresholds), 보안 경계(security boundaries) 등이 이에 해당합니다. 이러한 규칙들은 드물게, 그리고 의도적으로 변경됩니다. 이는 제안 사항이 아니며 검색 대상도 아닙니다.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "policy_memory",
...
예시 레코드:
{ "policy_key": "refund_threshold", "policy_value": { "max_auto_approve_usd": 500 } }
{ "policy_key": "data_residency", "policy_value": { "allowed_regions": ["us-east-1"] } }
{ "policy_key": "tone_guardrail", "policy_value": { "forbidden_phrases": ["risk-free"] } }
조회(Retrieval)는 tenant_id = ? AND policy_key = ?인 지점에서 이루어집니다. 벡터(Vector)는 관여하지 않습니다. 유사도(Similarity)를 사용하는 정책 조회(Policy retrieval)는 버그입니다. 왜냐하면 실제로 적용되고 있는 규칙으로부터 소리 없이 벗어나게 되기 때문입니다.
선호도 메모리 (Preference memory)
안정적인 개인화 파라미터(Personalization parameters)입니다. 사용자 범위(User-scoped)이며, 때로는 테넌트 범위(Tenant-scoped)이기도 합니다. 예측 가능한 조회(Lookup)가 이루어지며, 랭킹(Ranking)은 없습니다.
존재 이유: 이것이 바로 사용자가 매 세션마다 같은 말을 반복하지 않아도 시스템이 맞춤화된 것처럼 느끼게 만드는 요소입니다. "JSON 형식을 원해.", "날짜는 DD/MM/YYYY로 써줘.", "간결하게 말해줘."와 같은 것들입니다. 선호도 조회(Preference retrieval)를 한 번이라도 건너뛰면 시스템은 일반적인(Generic) 느낌을 주게 됩니다.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "preference_memory",
...
예시 레코드:
{ "pref_key": "response_format", "pref_value": "json", "source": "user_stated" }
{ "pref_key": "date_format", "pref_value": "DD/MM/YYYY", "source": "inferred", "confidence": 0.85 }
{ "pref_key": "verbosity", "pref_value": "terse", "source": "user_stated" }
조회는 매 턴(Turn)마다 실행되는 단일 키 기반 조회(Keyed lookup)입니다. 선호도는 프롬프트(Prompt)의 정적 접두사(Static prefix), 즉 캐시(Cache)에 적중하고 안정적으로 유지되어야 하는 부분에 공급됩니다.
사실 메모리 (Fact memory)
Durable assertion(내구성이 있는 단언)이며, 출처(Provenance)를 포함하여 에이전트가 재사용할 수 있습니다. 복리 효과(Compounding advantage)가 발생하는 지점이자, 설계 문제가 가장 까다로워지는 지점입니다. 왜냐하면 당신이 기록하는 모든 사실은 미래에 대한 베팅이기 때문입니다.
존재 이유: 이것은 세상에 대한 에이전트의 작업 지식(Working knowledge)입니다. "고객의 운영 데이터베이스는 us-east-1에 있다.", "그들의 회계 연도는 4월 1일에 시작한다."와 같은 정보들입니다. 사실(Fact)은 에이전트가 여러 세션에 걸쳐 동일한 확인 질문을 반복하는 것을 멈추게 해줍니다. 또한, 부주의하게 승격(Promoted)될 경우 시스템을 오염시키는 원인이 되기도 합니다.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "fact_memory",
...
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기