표준 메모리 모듈을 버리고 DB를 진실의 원천으로: 제로 디케이 시뮬레이션 루프 구축기 (LangGraph 스타일)
Ditching standard memory modules for strict DB-as-truth: How we built a zero-decay sim loop (LangGraph-style)
핵심 요약
표준 메모리 모듈 대신 PostgreSQL을 데이터의 원천으로 사용하여 AI 에이전트의 기억 소실 문제를 해결한 사례.
- 기억 소실 해결 — 표준 메모리 모듈 대신 DB를 사용하여 장기 기억 유지함
- 상태 기반 아키텍처 — LangGraph와 PostgreSQL을 결합해 상태를 원자적으로 관리함
- 구조화된 상태 변경 — LLM이 텍스트가 아닌 JSON 상태 변경값만 출력하게 함
- 원자적 트랜잭션 — 상태 변경을 DB에 직접 커밋하여 데이터 일관성을 보장함
표준 ConversationBufferMemory나 벡터 기반 검색기가 결국 무너진다는 건 긴 실행 시간의 에이전트나 시뮬레이션을 만들어 본 사람이라면 다 알 겁니다. 슬라이딩 윈도우로 인한 기억 상실을 겪거나, 50턴 전의 상태를 검색해 와서 에이전트가 어제 판 물건을 아직 가지고 있다고 착각하는 상황이 발생하죠.
저는 https://altworld.io (AI 보조 라이프 시뮬레이션) 백엔드를 만들면서 정확히 이 벽에 부딪혔습니다. 우리에겐 절대적인 연속성이 필요했죠. 5턴에 상자에 칼을 넣었다면, 500턴에도 그 칼이 있어야 합니다.
우리의 해결책은 기존의 대화 메모리 모듈을 완전히 뜯어내는 것이었습니다. 대신 아키텍처를 PostgreSQL이 절대적인 진실의 원천인 LangGraph 상태 머신처럼 다루기로 했습니다.
"표준 실행 상태는 구조화된 테이블과 JSON 블록에 저장됨"
슬라이딩 컨텍스트를 원자적 트랜잭션으로 대체한 방법은 다음과 같습니다:
상태 하이드레이션 노드: LLM을 호출하기 전에 Postgres에서 정확한 현재 상태(인벤토리, 위치, NPC 관계)를 가져옵니다.
결정론적 노드: AI가 아닌 시스템이 먼저 실행됩니다. 날씨 업데이트, 경제 변화, 기본적인 NPC 스케줄 등이 포함됩니다.
LLM 판정 노드: 사용자의 입력은 엄격하게 JSON 규칙 엔진으로 프롬프트된 LLM에 전달됩니다. LLM은 하이드레이션된 상태와 사용자의 행동을 평가한 뒤, JSON 변경 페이로드(예: {"inventory": {"remove": "gold_coin"}})를 반환합니다.
트랜잭션 커밋: 해당 JSON을 Postgres DB에 적용합니다. 이는 원자적으로 처리됩니다.
내러티브 렌더링 노드: "내러티브 텍스트는 상태 변경 전이 아니라 후에 생성됨", 마지막 LLM이 새로 업데이트된 상태를 가져와 사용자에게 보여줄 맛깔나는 텍스트를 생성합니다.
LLM이 메모리를 위해 원시 산문이 아닌 구조화된 상태 변경만 출력하도록 강제함으로써, 컨텍스트 소실을 완전히 제거할 수 있습니다. "세상이 데이터로 존재하기 때문에 앱은 복구, 복원, 분기, 지속이 가능함"
혹시 표준 LangChain 메모리 모듈에서 벗어나 LangGraph 설정에 엄격한 DB 변경 패턴을 도입해 본 분 계신가요? 벡터 검색에 의존하지 않고 복잡한 상태 지속성을 어떻게 처리하는지 궁금합니다.
