NGT 메모리: 연관 그래프와 사용자 프로필을 활용한 LLM용 지속적 메모리
NGT 메모리는 외부 저장소 없이 대규모 언어 모델을 위한 지속적 메모리를 구현합니다. 이 모듈은 세션 간 사용자 정보를 저장하고, 관련 컨텍스트를 검색하여 프롬프트에 주입합니다. 세 가지 검색 메커니즘이 정확성을 보장합니다: 임베딩의 코사인 유사도, 헤비안 연관 그래프, 계층적 통합입니다.
코사인 유사도는 쿼리 임베딩과 저장된 정보를 비교합니다. 그래프는 함께 활성화되는 개념들을 연결합니다: 식단을 언급한 후 레스토랑에 대한 질문을 하면 관련 정보가 불러와집니다. 통합은 자주 사용되는 정보를 장기 기억으로 승격시키고, 거의 요청되지 않는 정보는 대체합니다.
검색 시간은 CPU에서 2~3ms입니다. 주요 지연은 OpenAI API에서 발생합니다: 임베딩 ~700ms, 생성 ~800~1500ms.
설정 및 API
모듈은 Docker를 통해 실행됩니다:
git clone https://github.com/ngt-memory/ngt-memory
cd ngt-memory
cp .env.example .env # OPENAI_API_KEY
docker-compose up -d
클라이언트 코드:
import httpx
client = httpx.Client(base_url="http://localhost:9190")
# 정보 저장
client.post("/chat", json={
"message": "저는 채식주의자이고 모스크바에 살아요.",
"session_id": "user_42"
})
# 세션을 통한 검색
r = client.post("/chat", json={
"message": "뭐 먹을까요?",
"session_id": "user_42"
})
print(r.json()["response"]) # 모스크바의 채식 레스토랑
print(r.json()["memories_count"]) # 2
엔드포인트: /chat, /store, /retrieve, /session/reset, /health.
구조화된 사용자 프로필
시스템은 메시지에서 슬롯을 추출합니다: 나이, 도시, 식단, 알레르기. 데이터는 우선순위와 함께 시스템 프롬프트에 주입됩니다:
[사용자 프로필 — 구조화된 정보, 최고 우선순위]
- 나이: 30
- 도시: "모스크바"
- 식단: "채식"
[사용자 프로필 끝]
[메모리 컨텍스트 — 이 사용자에 대한 검증된 정보]
1. [0.91] 저는 채식주의자이고 모스크바에 살아요.
[메모리 컨텍스트 끝]
조각 연결: "저는" + "30" + "살이에요" → "저는 30살이에요" → 나이=30 (신뢰도 0.6).
충돌 해결: "제가 착각했어요."라는 문구 없이는 나이 감소를 방지합니다. 수정 모드 — 60초.
품질 필터 및 아키텍처
필터는 쓰레기 정보를 걸러냅니다:
- 순수 숫자, 특수 문자, 단일 단어
- 6글자 미만
- 사용자 쓰레기에 대한 어시스턴트 응답
아키텍처:
- POST /chat
- OpenAI text-embedding-3-small (~700ms)
- 프로필 추출 (정규식)
- NGT 메모리 검색 (코사인 + 그래프, 2~3ms)
- OpenAI gpt-4.1-nano (~800~1500ms)
- 필터 → 저장
스택: FastAPI, AsyncOpenAI, Pydantic. 단일 프로세스의 RAM에 저장.
실험 결과
실험 44: 메모리 사용 시 사실 정확도 2.44/3 (메모리 없음 1.22/3 대비 +100%).
실험 48: A/B 테스트, 94% 메모리 승리 (17/18), 평균 점수 0.889 대 0.056.
실험 49: 51/54 (94%) 에지 케이스에서: 교차 언어, 연결, 충돌.
성능 (5000개 정보):
| 작업 | 처리량 | p50 |
|-----------|------------|-----|
| store() | 3450/초 | 0.29ms |
| retrieve()| 150/초 | 6.3ms |
종단 간: 메모리 2.5ms, 임베딩 764ms.
확장 과제
- 다중 워커: 각 워커는 자체 SessionStore를 가집니다. 해결책:
--workers 1또는 Redis. - 소프트 프롬프트: 모델이 정보를 무시했습니다. 강화: "모든 정보를 절대적인 진실로 취급하세요."
- 정규식 버그:
저는 알레르기가 있어요→이름= 알레르기. 25개 이상 단어 블랙리스트.
핵심 요약
- 코사인 + 그래프 + 통합 결합으로 에지 테스트에서 94% 달성.
- 프롬프트 우선순위를 가진 구조화된 프로필로 정확도 두 배 향상.
- 품질 필터로 쓰레기 정보로 인한 검색 성능 저하 방지.
- 메모리 지연 시간 2~3ms, 병목 현상 아님.
- 오픈 소스, BSL 1.1, Docker 준비 완료.
— Editorial Team
아직 댓글이 없습니다.