에이전트 메모리가 계속 실패해서 '진술 그래프' 방식으로 처리해 봤음
Agent memory kept failing for me until I treated it like a statement graph
핵심 요약
에이전트 메모리 문제를 해결하기 위해 단순 저장 방식 대신 엔티티와 관계를 정의한 '진술 그래프' 구조를 도입한 경험 공유.
- 메모리 한계 — 컨텍스트 윈도우에 정보를 쑤셔 넣는 방식은 복잡한 관계 파악에 한계가 있음
- 진술 그래프 — 엔티티, 관계, 그리고 진술에 대한 메타 진술을 포함하는 구조로 메모리 신뢰성 확보
- 데이터 관리 — 덮어쓰기 대신 시간 순으로 진술을 추가하여 의사결정 과정의 맥락 보존
- 식별자 처리 — 이름이 아닌 URI 기반의 지문(fingerprint)을 사용하여 엔티티 중복 문제 해결
컨텍스트 윈도우에 정보를 쑤셔 넣거나 기록을 빡세게 뒤지는 방식으로 에이전트한테 "기억"을 시키려고 별짓을 다 해봤음.
근데 사람, 조직, 의사결정, 주장들이 얽히고설키기 시작하면 바로 맛이 감. 엉뚱한 "Apple"을 가져와서 확신에 차서 떠들거나, 진작에 수정됐어야 할 옛날 정보를 사실인 양 읊어대는 꼴을 보게 됨.
그래서 메모를 저장하는 대신 '스테이트먼트 그래프(statement graph)'를 짜기로 했음. 엔티티 타입이랑 관계를 정의하고, 그 위에 '주장에 대한 주장'을 얹을 공간을 만드는 방식임(이게 진짜 저평가된 설계라고 봄). 이 주장이 어디서 나왔는지(출처), 아직도 유효한지, 뭘로 수정됐는지 같은 걸 다 담는 거임. 옵시디언(Obsidian)처럼 마크다운 파일 관리하는 거랑은 차원이 다른 수준으로 해결됨.
직접 굴러보면서 뼈저리게 배운 것들:
- 프레임워크가 제공하는 메모리 기능? 실제 데이터로 스트레스 테스트 해보기 전까진 절대 믿지 마셈. 에이전트 프레임워크가 기본적인 오케스트레이션은 잘하는데, 내가 필요한 식별 규칙이나 다중 홉(multi-hop) 구조로 들어가면 바로 뻗어버림.
- 처음엔 어휘(엔티티 타입)를 존나 작게 시작하고, 충돌 날 것 같을 때만 늘리셈. 온갖 예외 상황 다 넣기 귀찮을 땐 "Concept"이라는 엔티티 타입 하나로 퉁치는 게 생각보다 개꿀임.
- 이름은 그냥 라벨이지 ID가 아님. 나는 네트워크 리소스 식별자를 지문처럼 찍어서, 같은 URI면 같은 엔티티 ID로 계산되게 만들었음(타입이랑 참조 타입까지 ID에 인코딩함). 문자열 유사도로 합치거나 AI한테 알아서 하라고 맡기면 그래프에 있는 엔티티를 도저히 믿을 수가 없음.
- 덮어쓰지 마셈. 시간 순서대로 계속 추가(append)해야 함. 전통적인 DB처럼 값을 덮어쓰는 건 기억 상실증 걸리겠다는 소리임. 특히 의사결정 과정을 추적할 땐, 새로운 결정만큼이나 그 결정에 이르게 된 옛날 사고방식을 보는 게 훨씬 중요함.
여러 ID를 하나의 실제 엔티티로 묶는 작업도 초기 반응은 괜찮음. 데이터를 넣을 때 이름을 합쳐버리는 게 아니라, "Same As"라는 문장으로 연결하는 방식을 쓰고 있음.
개인 메모나 RAG만으로는 한계가 왔을 때 다들 어떤 문제부터 터졌는지 궁금함. 식별자 꼬이는 거? 출처 관리? 아니면 또 다른 거?


