Chapter 6

지식과 메모리

  • 6.1 메모리 기본 사용법
  • 6.2 시맨틱 메모리와 벡터 스토어
  • 6.3 그래프RAG

모델이 아무리 똑똑해도 필요한 정보를 제때 못 꺼내면 소용없어. 메모리를 세 가지 층위로 나눠서 볼 수 있는데 — 기본적인 컨텍스트 윈도 관리부터, 시맨틱 검색과 벡터 스토어를 활용한 RAG, 그리고 지식 그래프 기반의 GraphRAG까지. 단순한 것에서 복잡한 것으로 올라가는 구조야.

에이전트의 가장 기본적인 메모리는 컨텍스트 윈도야. 모델에 넣을 수 있는 토큰 수의 한계 — Claude는 200K, GPT-4o는 128K, Gemini는 1M까지 가지만, 결국 유한하거든. 여기에 뭘 넣고 뭘 뺄지가 첫 번째 메모리 문제지.

핵심 전략들을 보면 — **슬라이딩 윈도(Sliding Window)**는 대화가 길어지면 오래된 메시지를 잘라내는 거야. 가장 단순하지만 중요한 맥락이 날아갈 수 있어. **요약 압축(Summarization)**은 오래된 대화를 LLM으로 요약해서 압축 저장하는 거지. 원본은 날리고 요약만 컨텍스트에 남겨. **계층적 메모리(Hierarchical Memory)**는 단기/중기/장기로 나눠서 관리하는 건데, 최근 대화는 원문 그대로, 좀 된 건 요약, 오래된 건 핵심 팩트만 추출하는 식이야.

여기서 중요한 건 모든 걸 컨텍스트에 때려넣는 건 답이 아니다라는 거야. 컨텍스트가 커지면 비용도 올라가고, 더 심각한 건 모델의 주의력이 분산된다는 거거든. "Lost in the Middle" 현상 — 컨텍스트 중간에 있는 정보를 모델이 무시하는 문제가 실제로 발생해. 그래서 필요한 정보를 필요한 시점에 꺼내오는 것이 진짜 메모리 관리야. 전부 넣어놓고 알아서 찾으라는 건 메모리 관리가 아니라 메모리 방치지.

컨텍스트 윈도에 다 안 들어가면? 외부에 저장하고 검색해서 가져오는 수밖에 없어. 가장 기본적인 방법이 전체 텍스트 검색이야. Elasticsearch, BM25 같은 전통적인 키워드 기반 검색이지. 정확한 키워드 매칭이 필요할 때 확실하고, 구축이 간단하고 검증된 기술이고, 고유명사나 코드, ID 같은 건 키워드 검색이 훨씬 정확해. 단점은 "환불해주세요"라고 물었을 때 "반품 정책" 문서를 못 찾는다는 거야. 같은 의미인데 단어가 다르면 끝이거든. 이게 바로 시맨틱 검색이 필요해진 이유야. 다만 전체 텍스트 검색이 쓸모없다는 게 아니야 — 실제 프로덕션에서는 키워드 검색과 시맨틱 검색을 하이브리드로 같이 쓰는 게 정석이거든.

시맨틱 검색은 키워드가 아니라 의미로 검색하는 거야. "환불해주세요"와 "반품 정책"이 비슷한 의미라는 걸 이해하는 검색이지. 이게 가능해진 건 임베딩(Embedding) 덕분이야. 텍스트를 고차원 벡터(숫자 배열)로 변환하면, 의미가 비슷한 텍스트끼리 벡터 공간에서 가까이 위치하게 돼. "강아지"와 "퍼피"는 벡터 공간에서 거의 붙어 있고, "강아지"와 "세탁기"는 한참 떨어져 있는 식이야.

임베딩 모델은 OpenAI의 text-embedding-3-small, Cohere의 embed-v4, 오픈소스로는 Sentence Transformers 같은 것들이 있어. 임베딩 모델 선택이 검색 품질을 좌우하거든 — LLM만 비싼 거 쓰고 임베딩은 대충 고르면 RAG 전체가 망가질 수 있어.

**벡터 스토어(Vector Store)**는 임베딩 벡터를 저장하고 유사도 검색을 해주는 데이터베이스야. 전용 벡터 DB(Pinecone, Weaviate, Qdrant, Chroma), 기존 DB의 벡터 확장(PostgreSQL + pgvector, MongoDB Atlas Vector Search), 검색 엔진 통합(Elasticsearch의 벡터 검색 지원) 같은 옵션들이 있지. 이미 PostgreSQL 쓰고 있으면 pgvector부터 시도하고, 벡터 검색이 핵심이고 스케일이 크면 전용 벡터 DB, 키워드 + 시맨틱 하이브리드가 필요하면 Elasticsearch 계열 — 이렇게 실용적으로 고르면 돼. 검색할 때는 **코사인 유사도(Cosine Similarity)**를 주로 써. 두 벡터의 방향이 얼마나 비슷한지 측정하는 건데, 1에 가까우면 의미가 비슷하고 0에 가까우면 관련 없는 거야.

**RAG(Retrieval-Augmented Generation)**는 검색해서 가져온 정보를 LLM에 넣어주고 답변을 생성하는 패턴이야. 2020년 Meta가 처음 제안한 개념인데, 지금은 사실상 프로덕션 AI 에이전트의 표준 아키텍처가 됐지. 기본 흐름은 사용자 질문 → 임베딩 변환 → 벡터 스토어에서 관련 문서 검색 → 검색된 문서를 컨텍스트에 넣어서 LLM에 전달 → 답변 생성이야. 모델의 학습 데이터는 특정 시점에 끊기니까, RAG는 이 지식의 시차 문제를 해결하는 거지.

RAG 구현에서 핵심 포인트들을 보면 — **청킹(Chunking)**은 문서를 적절한 크기로 잘라야 하는 건데, 너무 크면 관련 없는 내용이 같이 딸려오고, 너무 작으면 맥락이 끊겨. 의미 단위로 자르되 앞뒤 문맥이 겹치도록 오버랩을 주는 게 좋아. **하이브리드 검색(Hybrid Search)**은 시맨틱 검색만 쓰면 고유명사를 놓치고, 키워드 검색만 쓰면 유의어를 놓치니까 둘 다 돌리고 결과를 합치는 거야. 보통 벡터 가중치 0.7 + BM25 가중치 0.3 정도로 퓨전하지. **리랭킹(Re-ranking)**은 초벌 검색으로 후보를 넓게 가져온 다음, 크로스 인코더 같은 더 정교한 모델로 관련성을 재평가하는 건데, 이 한 단계가 체감 품질을 크게 올려. 메타데이터 필터링은 벡터 유사도만 믿지 말고, 문서의 생성 날짜, 카테고리, 소스 같은 메타데이터로 필터링을 거는 거야.

2025년 들어서 RAG가 진화한 형태가 **에이전틱 RAG(Agentic RAG)**야. 기본 RAG는 "검색 → 생성" 한 번으로 끝나는데, 에이전틱 RAG는 에이전트가 검색 전략 자체를 판단해. 질문을 분석해서 어떤 데이터소스를 검색할지 결정하고, 첫 검색 결과가 부족하면 쿼리를 바꿔서 재검색하고, 여러 소스의 결과를 종합해서 답변을 생성하지. 기본 RAG가 "도서관에서 책 찾아오기"라면, 에이전틱 RAG는 "도서관 사서가 알아서 관련 자료를 찾아주고, 부족하면 다른 도서관까지 뒤지는 것"에 가까워.

검색할 외부 문서만이 메모리가 아니야. 에이전트가 이전 상호작용에서 경험을 축적하는 것도 메모리거든. 시맨틱 경험 메모리는 사용자와의 대화에서 중요한 사실, 선호도, 결정사항을 추출해서 임베딩한 뒤 벡터 스토어에 저장하고, 다음 대화 시 관련 경험을 시맨틱 검색으로 불러오는 거야. **시맨틱 캐싱(Semantic Caching)**도 연결되는데, 비슷한 질문이 이전에 들어왔으면 그때의 검색 결과와 응답을 재활용하는 거지. 비용 절감 + 응답 속도 개선 효과가 커.

벡터 기반 RAG가 잘 작동하는 건 맞지만 한계가 있어. 관계성 부재 — "A회사가 B회사를 인수했고, B회사 CEO가 C였다"에서 A-B-C의 관계를 벡터 유사도만으로는 파악하기 어려워. 전역적 질문 — "이 데이터셋의 주요 테마는 뭐야?" 같은 요약형 질문에 개별 청크를 검색하는 걸론 전체 그림을 못 봐. 멀티홉 추론 — 답을 얻으려면 여러 문서를 거쳐야 하는 질문도 벡터 RAG론 힘들지.

이걸 해결하려고 나온 게 **그래프RAG(GraphRAG)**야. 2024년 마이크로소프트 리서치에서 본격적으로 제안한 접근법이지. 문서에서 **엔티티(Entity)**와 **관계(Relation)**를 추출해서 지식 그래프를 만드는 거야. 구축 과정은 — 엔티티 추출(사람, 조직, 장소, 개념 등을 LLM으로 뽑아냄) → 관계 추출(엔티티 간의 "소속", "인수", "경쟁" 같은 관계 파악) → 커뮤니티 탐지(밀접하게 연결된 엔티티 그룹을 묶어서 주제별 클러스터 생성) → 계층적 요약(각 커뮤니티에 대한 요약 생성). 검색할 때는 벡터 유사도 대신(또는 함께) **그래프 순회(Graph Traversal)**를 사용해. 질문에서 엔티티를 찾고, 그 엔티티와 연결된 관계를 따라가면서 필요한 정보를 수집하지. 전역적 질문에서는 기존 RAG 대비 평균 5배까지 쿼리 속도가 빠를 수 있어. 다만 지역적(특정 팩트 검색) 질문에서는 기존 벡터 RAG가 더 효율적일 수 있어.

정적 지식 그래프는 한 번 구축하면 끝인데, 현실 세계의 정보는 계속 바뀌잖아. 동적 지식 그래프의 가능성은 — 에이전트가 대화하면서 새로운 사실을 발견하면 그래프에 추가하고, 시간에 따라 변하는 정보를 추적할 수 있다는 거야. Graphiti 같은 프레임워크가 시간적 맥락을 추적하면서 사실의 변화 이력을 관리하지. 위험은 — 에이전트가 잘못된 정보를 그래프에 추가하면 환각이 지식으로 고착되고, 모순되는 정보가 들어왔을 때 어떤 걸 믿을 건지의 문제가 생기고, 그래프가 커질수록 유지보수 비용이 기하급수적으로 증가해. 동적 지식 그래프를 쓸 거면 반드시 출처 추적충돌 해결 정책을 먼저 설계해야 해. 그냥 에이전트한테 "알아서 업데이트해"라고 하면 쓰레기 지식이 쌓여서 시스템 전체가 오염되거든.

마지막으로 좀 의외인 주제가 노트 작성이야. 에이전트가 작업하면서 중간 결과나 발견한 사실을 메모하는 거지. 에이전트가 복잡한 리서치를 할 때 중간 발견을 "화이트보드"에 적어놓고 나중에 참조하고, 컨텍스트 윈도에 전부 넣기엔 너무 많은 중간 결과를 구조화해서 저장하는 거야. 사람이 복잡한 프로젝트 할 때 머리로만 기억하는 사람 없잖아. 메모하고, 정리하고, 필요할 때 찾아보는 거. 에이전트도 마찬가지야.


정리

6장에서 기억할 것 세 가지:

  1. 메모리는 층위가 있어. 컨텍스트 윈도 관리(단기) → 벡터 검색 RAG(중기) → 지식 그래프(장기). 하나만 쓰는 게 아니라 조합해서 써야 하거든
  2. 검색 품질이 생성 품질을 결정해. RAG에서 R(Retrieval)이 망하면 G(Generation)도 망하지. 청킹, 하이브리드 검색, 리랭킹에 투자해야 해
  3. 동적 메모리는 양날의 검이야. 에이전트가 스스로 지식을 축적하는 건 강력하지만, 잘못된 지식이 쌓이면 시스템 전체를 오염시켜. 출처 추적과 검증 메커니즘이 필수거든