기본 AI 에이전트에 메모리 추가하기
요약
본 글은 AI 에이전트에 장기 메모리(long-term memory)를 추가하는 방법을 설명합니다. 단기 메모리가 세션 종료 시 사라지는 한계를 극복하고, 프로젝트 및 사용자별 영구적인 지식을 저장하여 다음 세션에서도 활용할 수 있게 합니다.
핵심 포인트
- 장기 메모리는 세션 간에 생존하며 필요할 때만 검색됩니다.
- 프로젝트 메모리는 환경 규칙과 교훈을 저장합니다.
- 사용자 메모리는 사용자의 선호도와 기대치를 기록합니다.
- 메모리 기능 추가는 개인 정보 보호 및 안전 문제(Security)를 야기하므로 주의해야 합니다.
Build a Basic AI Agent From Scratch:
지난 글들:
이 코드는 본 블로그 시리즈의 Github repo에서 찾고 클론할 수 있습니다.
이전 글들을 통해 우리는 에이전트를 유능하고, 자율적이며, 훨씬 더 안전하게 만들었습니다. 이 에이전트는 Docker 샌드박스 내에서 도구를 사용하고, 장기 작업을 계획하며, 도움을 요청하고, 도구 정책을 준수하며, 리소스 한계에 도달하면 중지할 수 있습니다. 하지만 프로그램을 종료할 때마다 모든 것을 잊어버립니다.
이것은 큰 한계입니다. 에이전트는 사용자가 간결한 답변을 선호하거나, 프로젝트가 uv를 사용하거나, 어제 마이그레이션 작업이 부분적으로 완료되었다는 것을 배울 수 있습니다. 다음 세션에서는 이 모든 것을 다시 발견해야 합니다.
이번 글에서는 **장기 메모리(long-term memory)**를 추가할 것입니다. 우리의 에이전트는 프로젝트와 사용자에 대한 지속적인 노트를 저장하고, 이를 향후 세션에서 사용할 수 있게 될 것입니다.
단기 메모리 vs 장기 메모리
우리의 에이전트 루프에 있는 messages 리스트는 이미 일종의 메모리입니다. 여기에는 시스템 프롬프트(system prompt), 사용자 메시지, 모델 답변, 도구 결과가 포함됩니다. 이것이 **단기 메모리(short-term memory)**입니다. 프로세스가 실행되는 동안 유지되며 컨텍스트로 모델에 전송됩니다.
이는 두 가지 중요한 한계가 있습니다:
- 프로세스가 종료되면 사라집니다.
- 모델의 컨텍스트 창은 유한하고 추가 토큰마다 시간과 비용이 들기 때문에 영원히 성장할 수 없습니다.
장기 메모리는 다릅니다. 세션 간에 생존하며, 필요할 때만 검색됩니다. 우리는 이를 두 가지 다른 용도로 사용할 것입니다:
- 프로젝트 메모리(Project memory): "Python 명령에
uv사용"과 같은 프로젝트 환경 및 규칙에 대한 영구적인 교훈. - 사용자 메모리(User memory): "간결한 답변을 선호함"과 같은 안정적인 사용자 선호도 및 기대치.
메모리를 위한 보안 (Security for Memory)
메모리는 에이전트를 더 유용하게 만들지만, 동시에 새로운 개인 정보 보호 및 안전 문제를 야기합니다. 바로 메모리가 영구적인 데이터이기 때문입니다. 잘못되거나 너무 광범위한 메모는 원래의 컨텍스트가 사라진 후에도 나중 작업에 영향을 미칠 수 있습니다.
첫 번째 구현을 위해 시스템 프롬프트는 모델에게 엄격한 규칙을 부여합니다:
"- 장기 메모리 (read_memory / append_memory): 세션 시작 시, "
"프로젝트 및 사용자 메모리를 모두 읽어옵니다. 프로젝트 메모리는 영구적인 교훈, 환경 "
"사실 및 관습을 위한 것이며; 사용자 메모리는 안정적인 선호도와 기대치를 위한 것입니다. "
...
이는 몇 가지 이유로 중요합니다:
- API 키, 비밀번호 및 토큰은 모델 컨텍스트나 영구 파일에 절대 저장되어서는 안 됩니다.
- "이 문서에서 파란색 제목을 사용하세요"와 같은 일회성 지침은 장기 메모리로 유용하지 않습니다.
- 웹 페이지나 파일에서 프롬프트 주입된 콘텐츠는 절대로 메모리로 승격되어서는 안 됩니다.
- 메모리는 사람이 검토하고 수정할 수 있도록 간결해야 합니다.
기본적으로, 메모리 디렉터리는 Docker 프로젝트 마운트 외부에 위치합니다. 에이전트는 파일 시스템 도구를 통해서가 아니라 MemoryStore를 통해 이 메모리에 접근합니다.
파일 기반 메모리 저장소 (File-Backed Memory Store)
시작하기 위해 데이터베이스나 벡터 스토어가 필요하지 않습니다. 몇 개의 파일만으로 충분하며, 검사하기도 쉽고 백업하기도 쉽습니다. 기본 디렉터리는 ~/.agent-harness/memory입니다:
~/.agent-harness/memory/
project.md
user.md
project.md와 user.md에는 추가 전용(append-only) 메모가 포함됩니다. 이 설계를 염두에 두고, 메모리 저장소를 구현해 보겠습니다:
class MemoryStore:
"""에이전트 메모, 사용자 선호도 및 전체 세션 기록을 영구적으로 저장합니다."""
...
_notes_path 헬퍼는 project와 user만 허용하며, 모델이 임의의 파일 이름을 선택하도록 허용하지 않습니다:
메모리 도구 (Memory Tools)
에이전트가 이 저장소(store)에 접근하려면 도구가 필요합니다. 모든 도구는 스크래치패드 및 할 일 목록과 함께 인-프로세스(in-process)로 실행됩니다. 이는 해당 도구들이 프로젝트 파일에 직접 작용하기보다는 하네스 상태(harness state)를 보유하기 때문입니다:
def read_memory(scope: str) -> str:
return _get_store().read_notes(scope)
...
장기 메모리 노트와 작업하려면 에이전트는 두 가지 도구를 얻습니다:
read_memory:project또는user노트를 읽습니다.append_memory: 간결하고 영구적인(durable) 노트를 추가합니다.
이러한 도구들은 PLANNING_TOOLS에 포함되어 있으므로 호출할 때마다 권한을 요청하지 않습니다. 이는 이들이 설정된 메모리 디렉터리에만 접근하기 때문에 합리적인 기본값입니다. 또한, 메모리 디렉터리는 민감한 사용자 데이터로 취급되어 일반 운영체제(operating-system) 권한 및 백업으로 보호되어야 함을 의미합니다.
테스트해 봅시다 (Let's Test It)
먼저, 에이전트에게 안정적인 선호도(preference)를 기억하도록 요청할 수 있습니다:
$ uv run agent.py
Session: z7Pq3hM4kA
Memory directory: /home/xxxxx/.agent-harness/memory
...
다음 번에 에이전트는 답변하기 전에 해당 노트를 읽을 수 있습니다:
You: 이 프로젝트를 이해하는 데 도움을 주세요.
[tool] read_memory({'scope': 'project'})
[tool result] Python 명령어에는 uv를 사용하세요.
...
구축한 것 (What You've Built)
이제 우리 에이전트는 전체 히스토리(history)를 모든 모델 요청으로 변환하지 않고도 영구적인 메모리를 갖게 되었습니다:
- 스코프별 노트(Scoped notes): 안정적인 환경 사실과 사용자 선호도를 사람이 읽을 수 있는 Markdown 파일에 저장합니다.
- 메모리 안전 규칙(Memory safety rules): 저장되는 정보가 간결하고 영구적인 사실로 제한되며, 비밀 정보나 일시적 데이터는 명시적으로 제외됩니다.
이제 에이전트는 실행 간에도 유용한 사실을 유지할 수 있으므로, 매번 같은 선호도와 프로젝트 관습을 재발견할 필요가 없습니다.
다음은 무엇인가요 (What's next)
본 기사에서는 세션의 기초를 소개했습니다. 다음 기사에서는 이를 확장하여 이전 세션 목록을 확인하고, 미완성된 세션을 재개하며, 긴 세션을 모델의 컨텍스트 창 내에서 지속할 수 있도록 압축하는 방법을 다룰 것입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기