루프 메모리: 스크래치패드에서 NOTES.md까지
LLM에게 “기억”이란 무엇인가
섹션 제목: “LLM에게 “기억”이란 무엇인가”사람은 하루 동안 배운 것을 잠자리에 들며 장기 기억으로 굳힌다. LLM에게는 그런 생물학적 메커니즘이 없다. 모델 가중치는 추론 중에 바뀌지 않는다. 그렇다면 에이전틱 루프에서 “이전 이터레이션에서 알아낸 것”은 어디에 저장되는가? 컨텍스트 창이 유일한 작업 기억이고, 그 창이 꽉 차거나 재시작되면 정보를 잃는다. 이 근본적 제약을 극복하기 위해 루프 메모리 계층을 설계해야 한다.
Lilian Weng의 LLM 에이전트 프레임워크는 에이전트 메모리를 감각 기억, 단기 기억, 장기 기억으로 구분했다. 루프 엔지니어링 관점에서는 이를 더 실용적으로 세 계층으로 나눌 수 있다.
┌────────────────────────────────────────────────────────────┐│ 루프 메모리 계층 구조 │├────────────────┬───────────────────────────────────────────┤│ 계층 │ 특성 및 예시 │├────────────────┼───────────────────────────────────────────┤│ 단기 메모리 │ 컨텍스트 창 내 작업 기억 ││ (Working) │ • 현재 이터레이션의 추론 과정 ││ │ • 스크래치패드(Scratchpad) / 내부 독백 ││ │ • 이번 루프 내 도구 결과 │├────────────────┼───────────────────────────────────────────┤│ 장기 메모리 │ 루프 재시작 후에도 지속 ││ (Persistent) │ • 파일: CLAUDE.md, NOTES.md, fix_plan.md ││ │ • 체크포인트 상태 ││ │ • 코드베이스 자체 (수정된 파일) │├────────────────┼───────────────────────────────────────────┤│ 외부 메모리 │ 전용 저장소에서 검색 ││ (External) │ • 벡터 데이터베이스 (시맨틱 검색) ││ │ • 관계형 DB / KV 스토어 ││ │ • 이전 실행 로그 / 트레이스 │└────────────────┴───────────────────────────────────────────┘단기 메모리: 스크래치패드
섹션 제목: “단기 메모리: 스크래치패드”스크래치패드(scratchpad)는 모델이 응답을 생성하기 전 내부 추론을 기록하는 공간이다. 추론 모델(reasoning model)에서 <thinking> 태그로 구분되는 내부 독백이 대표적 예다. 일반 에이전트에서는 “내가 알아낸 것”, “다음에 해야 할 것” 같은 메모를 도구 호출 전에 텍스트로 작성하게 유도하는 방식이 이에 해당한다.
단기 메모리의 특성은 다음과 같다.
- 빠르다. 모델이 직접 쓰고 읽으므로 별도 도구 호출이 없다.
- 휘발적이다. 컨텍스트가 재초기화되거나 compaction이 일어나면 사라진다.
- 용량이 제한적이다. 컨텍스트 창의 일부를 차지한다.
단기 메모리만으로는 장기 에이전트를 지원하기 어렵다. 여러 이터레이션에 걸쳐 축적된 발견 사항, 완료된 작업 목록, 아직 해결되지 않은 문제를 compaction 이후에도 유지하려면 장기 메모리가 필요하다.
장기 메모리: 파일 기반 노트테이킹
섹션 제목: “장기 메모리: 파일 기반 노트테이킹”가장 단순하고 강력한 장기 메모리 구현은 파일 시스템이다. Claude Code의 CLAUDE.md, Geoffrey Huntley의 Ralph 패턴에서 쓰는 PROMPT.md, 그리고 에이전트가 직접 작성하는 NOTES.md가 이 범주에 속한다.
# 개념 이해용 의사 코드이며 실제 API와 다를 수 있습니다.
NOTES_FILE = "NOTES.md"
def save_finding(key: str, value: str) -> None: """에이전트가 중요한 발견을 장기 메모리에 저장.""" entry = f"\n## {key}\n{value}\n" append_to_file(NOTES_FILE, entry)
def load_relevant_notes(query: str) -> str: """루프 재시작 시 또는 compaction 후 관련 노트를 복원.""" notes = read_file(NOTES_FILE) # 단순 버전: 전체 노트 반환 # 고급 버전: 쿼리와 관련된 섹션만 추출 (JIT 검색과 결합) return notes
# 루프에서 사용 예시def run_loop_with_memory(task: str): # 이전 진행 상황 복원 prior_notes = load_relevant_notes(task) messages = [ {"role": "system", "content": SYSTEM_PROMPT}, {"role": "user", "content": task}, ] if prior_notes: messages.append({"role": "assistant", "content": f"[이전 노트]\n{prior_notes}"})
while True: response = model.generate(messages) if response.stop_reason == "end_turn": break # ... 도구 실행 ... # 중요 발견 즉시 파일에 저장 if response.has_finding(): save_finding(response.finding_key, response.finding_value)구조적 노트테이킹의 핵심은 에이전트가 스스로 메모를 작성하도록 유도하는 것이다. 단순히 “발견한 것을 기록하라”는 지시보다, 체계적인 스키마(“완료된 작업”, “미완료 작업”, “발견된 이슈”, “결정 사항”)를 제공하면 훨씬 활용 가능한 노트가 만들어진다.
| 노트 카테고리 | 내용 예시 | 저장 시점 |
|---|---|---|
| 완료된 행동 | “auth.py 수정 완료 — JWT 검증 추가” | 각 하위 작업 완료 후 즉시 |
| 발견된 사실 | “DB 스키마에 users.role 컬럼 없음” | 도구 결과에서 핵심 발견 시 |
| 결정 사항 | “파이썬 3.11 이상만 지원” | 설계 선택 확정 시 |
| 미완료 항목 | “rate limiting 미구현” | 다음 이터레이션 인계 시 |
외부 메모리: 벡터 DB와 검색
섹션 제목: “외부 메모리: 벡터 DB와 검색”장기 에이전트가 수천 개의 파일이나 이전 실행 로그를 다뤄야 할 때, 파일 기반 노트만으로는 부족하다. 벡터 데이터베이스에 임베딩으로 저장하고 시맨틱 검색으로 필요한 것만 꺼내 쓰는 방식이 이 한계를 넘어선다.
다만 외부 메모리는 구현 복잡도가 높고, 검색 지연이 발생하며, 잘못된 검색 결과가 오히려 오답을 유도할 수 있다. 단순한 태스크라면 파일 기반 장기 메모리가 훨씬 실용적이다.
서브에이전트 컨텍스트 격리
섹션 제목: “서브에이전트 컨텍스트 격리”멀티에이전트 시스템에서 중요한 설계 원칙이 있다. 각 서브에이전트는 자신만의 격리된 컨텍스트를 가져야 한다. Anthropic 멀티에이전트 리서치 시스템에서 서브에이전트들은 각각 별도의 컨텍스트 창에서 동작하며, 오케스트레이터의 컨텍스트가 서브에이전트 실행 내용으로 오염되지 않는다. 서브에이전트가 작업을 완료하면 요약만 오케스트레이터에게 반환된다.
이 격리는 두 가지 문제를 동시에 해결한다. 첫째, 오케스트레이터의 주의 예산을 절약한다. 둘째, 한 서브에이전트의 오류가 다른 에이전트 컨텍스트를 오염시키지 않는다.
메모리 계층 선택 가이드
섹션 제목: “메모리 계층 선택 가이드”어떤 메모리 계층을 언제 써야 할까?
- 단기 루프 (< 10 이터레이션, 단일 태스크): 단기 메모리(컨텍스트)만으로 충분.
- 중기 루프 (10~50 이터레이션, 복잡한 태스크): 파일 기반 장기 메모리 + compaction 조합.
- 장기 루프 (50+ 이터레이션, 코드베이스 전체 작업): 파일 메모리 + JIT 검색 + 서브에이전트 격리.
- 다중 세션 에이전트: 외부 DB 기반 메모리 + 구조화된 상태 직렬화.
루프 메모리 설계는 “지금 당장 필요한 정보”와 “나중에 필요할 수도 있는 정보”를 어디에, 어떤 형태로 저장할지 결정하는 아키텍처 선택이다. 다음 챕터에서는 이 메모리 계층과 맞물려 동작하는 JIT 검색 전략을 살펴본다.
참고 자료
- Anthropic — Effective context engineering for AI agents — 접속 2026-06-30
- Anthropic — How we built our multi-agent research system — 접속 2026-06-30
- Lilian Weng — LLM Powered Autonomous Agents — 접속 2026-06-30