RSS
AI 트렌드

Hindsight: RAG 대신 기억을 정리하는 오픈소스 에이전트 메모리

작성자
듀오랩스 대표·7분 읽기

에이전트에게 지난주에 "우리 팀은 배포를 금요일에 하지 않는다"고 알려 줬다고 해 보겠습니다. 오늘 새 세션에서 금요일 배포 계획을 물으면 에이전트는 그 말을 기억할까요. 대화 기록을 벡터 DB에 넣어 두었다면 운이 좋을 때만 기억합니다. 질문에 "금요일"이라는 단어가 있으면 찾아지고, "주말 전에 올려도 될까?"라고 물으면 놓칠 수 있습니다.

Hindsight는 이 문제를 겨냥한 오픈소스 에이전트 메모리 시스템입니다. Vectorize가 만들었고 MIT 라이선스이며, 9월 말 기준 GitHub 스타가 4만 개를 넘었습니다. 이 글은 README와 공식 문서를 근거로 씁니다.

기억은 대화 기록을 검색하는 일이라는 오해

에이전트에 기억을 붙인다고 하면 대부분 RAG를 떠올립니다. 지난 대화를 잘게 잘라 임베딩으로 저장하고, 새 질문이 오면 비슷한 조각을 찾아 프롬프트에 붙입니다.

이 방식은 찾는 일은 하지만 정리하는 일은 하지 않습니다. 월요일에 "Alice는 주니어 엔지니어"라고 저장하고 6월에 "Alice가 시니어로 승진했다"를 저장하면, 두 조각은 서로를 모른 채 나란히 쌓입니다. 검색 결과에 둘 다 올라오면 어느 쪽이 지금 사실인지는 모델이 알아서 판단해야 합니다. 사람의 기억은 이렇게 동작하지 않습니다. 새 사실이 들어오면 예전 믿음이 고쳐집니다.

Hindsight가 README 첫머리에 적은 문장이 이 차이를 가리킵니다. 대부분의 에이전트 메모리는 대화 기록을 떠올리는 데 집중하지만, Hindsight는 기억하는 에이전트가 아니라 배우는 에이전트를 목표로 한다는 것입니다.

저장, 검색, 숙고로 나뉜 세 가지 동작

Hindsight의 API는 세 동사로 이루어집니다.

retain은 정보를 넣습니다. 이때 원문을 그대로 쌓지 않고 LLM이 핵심 사실, 시간 정보, 등장하는 대상과 관계를 뽑아 정규화합니다. 들어온 기억은 세상에 대한 사실(world facts)과 에이전트 자신의 경험(experiences) 중 한쪽으로 분류됩니다.

recall은 기억을 꺼냅니다. 네 가지 검색을 동시에 돌립니다. 임베딩 유사도, BM25 키워드 일치, 대상과 시간과 인과로 이어진 그래프, 시간 범위 필터입니다. 결과는 순위 융합과 재정렬 모델을 거쳐 토큰 한도에 맞게 잘립니다. "6월에 무슨 일이 있었지?" 같은 질문이 벡터 검색만으로는 잘 안 되는데, 시간 필터가 따로 있어서 이런 질문을 받습니다.

reflect는 기억 위에서 생각합니다. 단순 조회가 아니라 여러 기억을 엮어 새로운 결론을 냅니다. README는 프로젝트 관리 에이전트가 어떤 위험을 줄여야 하는지 되짚는 경우를 예로 듭니다.

덮어쓰지 않고 고쳐 쓰는 관찰

제가 Hindsight에서 가장 중요하다고 보는 부분은 관찰(observations)입니다. 저장된 사실은 배경에서 서로 묶여 중복이 제거된 믿음으로 정리됩니다. 각 관찰은 근거가 된 원문 인용과 근거 개수를 함께 들고 있습니다. 새 증거가 오면 관찰을 갈아엎지 않고 강화하거나, 약화하거나, 넓힙니다.

앞의 Alice 예로 돌아가면, 승진 소식은 "Alice는 주니어"라는 믿음을 조용히 지우지 않고 그 믿음을 고칩니다. 그리고 왜 고쳤는지가 근거로 남습니다. 에이전트가 틀린 말을 했을 때 어느 기억에서 나왔는지 추적할 수 있다는 뜻이기도 합니다.

그 위에 정신 모델(mental models)이 있습니다. "이 사용자의 선호는?" 같은 질문을 한 번 정해 두면 Hindsight가 답을 써서 저장하고, 기억이 쌓일 때마다 배경에서 다시 씁니다. 이 답을 읽는 것은 데이터베이스 조회라 검색도 LLM 호출도 없습니다. 에이전트가 세션을 시작할 때마다 같은 것을 다시 찾아내는 대신, 정리된 페이지 한 장을 들고 시작하게 됩니다.

파일에 적어 두는 메모리와의 차이

Claude Code의 CLAUDE.md처럼 에이전트가 읽는 파일에 규칙을 적어 두는 방식도 기억입니다. 저는 이 방식이 지금도 가장 믿을 만한 기억이라고 봅니다. 사람이 쓰고, 사람이 읽고, git으로 이력이 남습니다.

한계는 사람이 쓴다는 점 자체에 있습니다. 누군가 적어 두지 않은 것은 기억되지 않습니다. 고객 한 명 한 명의 선호처럼 파일로 관리할 수 없는 양이거나, 대화 중에 흘러간 정보를 에이전트가 스스로 쌓아야 할 때 Hindsight 같은 시스템이 필요해집니다. 둘은 경쟁하지 않습니다. 팀의 규칙은 파일에, 사용자와 작업에서 배우는 것은 메모리 시스템에 두는 구분이 자연스럽습니다.

붙이는 방법과 드는 비용

붙이는 길은 여러 가지입니다. Docker 컨테이너 하나로 서버와 관리 화면이 뜨고, 저장소는 내장 PostgreSQL을 씁니다. 서버 없이 Python 프로세스 안에 넣는 방식도 있습니다. 가장 간단한 것은 LLM 래퍼로, 기존 OpenAI나 Anthropic 클라이언트를 감싸면 호출 전에 기억을 꺼내고 호출 뒤에 대화를 저장합니다. Claude Code, Codex, Cursor 같은 코딩 에이전트와 LangGraph, CrewAI 같은 프레임워크까지 60개가 넘는 연동이 README에 올라 있습니다.

비용은 공짜가 아닙니다. retain이 사실을 뽑을 때 LLM을 부르기 때문에 기억을 넣을 때마다 모델 호출이 생깁니다. 어느 모델을 쓸지는 고를 수 있고, Ollama나 llama.cpp 같은 로컬 모델도 지원합니다. README 스스로도 n8n으로 만든 단순한 워크플로에는 과할 수 있다고 적어 두었습니다.

성능은 장기 기억 벤치마크 LongMemEval에서 90%를 넘었다고 발표했습니다. README는 이 결과를 버지니아공대 연구진과 워싱턴포스트가 독립적으로 재현했고, 비교 대상인 다른 제품들의 점수는 각 회사의 자체 보고라고 밝혀 둡니다. 저는 이 구분을 적어 둔 점을 좋게 봅니다.

기억에 비밀이 섞이는 문제

에이전트 메모리를 붙이면 한 가지 위험이 새로 생깁니다. 대화 중에 흘러간 API 키나 개인정보가 기억으로 저장되고, 나중에 전혀 다른 맥락에서 꺼내질 수 있습니다.

Hindsight에는 Memory Defense라는 선택 기능이 있습니다. 기억을 넣을 때마다 비밀값과 개인정보를 45가지 패턴으로 검사해서 가리거나 저장을 막습니다. 기본으로 켜져 있지 않고 메모리 뱅크마다 켜야 한다는 점은 알고 써야 합니다. 저라면 사용자 대화가 들어가는 뱅크에서는 첫날부터 켜 두겠습니다. 한 번 저장된 비밀을 기억 속에서 찾아 지우는 일은 넣기 전에 막는 일보다 훨씬 어렵습니다.

마지막 수정:

공유하실 때는 출처(Duolabs)와 원문 주소를 표시해 주세요.