무엇인가
Graphiti는 Zep이 만든 시간 인식 지식 그래프 엔진입니다. 대화·문서 같은 '에피소드'를 넣으면 언어 모델이 사람·대상(노드)과 그 사이의 사실(간선)을 뽑아 그래프에 쌓습니다. 다른 그래프 RAG와 다른 점은 사실마다 유효기간이 붙는다는 것입니다.
"판교에 산다"는 사실이 있고 두 달 뒤 "서초로 이사했다"는 말이 들어오면, Graphiti는 앞 사실을 지우지 않고 닫습니다(invalid_at). 그래서 "지금 어디 사나"와 "4월에는 어디 살았나"에 모두 답할 수 있습니다.
어떻게 동작하나
valid_at·invalid_at)과 시스템이 알게 된·폐기한 시각(created_at·expired_at)을 따로 적는다 — 이중 시간(bitemporal) 모델.저장소는 Neo4j가 기본이고 FalkorDB·Amazon Neptune도 지원합니다(Kuzu 드라이버는 2026-10 README 기준 폐기 예정). MCP 서버가 함께 들어 있어 Claude·Cursor 같은 에이전트에 바로 붙일 수 있습니다.
빠른 시작
pip install graphiti-core
# Neo4j를 로컬에 띄운다
docker run -d -p 7474:7474 -p 7687:7687 -e NEO4J_AUTH=neo4j/password neo4j:5.26
import asyncio
from datetime import datetime, timezone
from graphiti_core import Graphiti
from graphiti_core.nodes import EpisodeType
async def main():
g = Graphiti("bolt://localhost:7687", "neo4j", "password")
await g.build_indices_and_constraints()
await g.add_episode(
name="상담-0302",
episode_body="고객: 저 이번에 판교로 이사했어요.",
source=EpisodeType.message,
source_description="상담 로그",
reference_time=datetime(2026, 3, 2, tzinfo=timezone.utc),
)
await g.add_episode(
name="상담-0510",
episode_body="고객: 회사가 강남으로 옮겨서 서초로 다시 이사했습니다.",
source=EpisodeType.message,
source_description="상담 로그",
reference_time=datetime(2026, 5, 10, tzinfo=timezone.utc),
)
for edge in await g.search("고객은 어디에 사나?"):
print(edge.fact, edge.valid_at, edge.invalid_at)
asyncio.run(main())
기본 설정은 OpenAI 키(OPENAI_API_KEY)를 씁니다. 구조화 출력을 지원하는 모델을 쓰라고 README가 강조합니다 — 작은 모델은 출력 형식이 틀려 수집이 실패하는 일이 잦습니다.
코어닷투데이 실측
graphiti-core 0.30.2에 한국어 상담 로그 240건을 넣고 옛 사실이 제대로 닫히는지 쟀습니다(Neo4j 5.26, 임베딩 bge-m3).
| 측정 | 기본 설정 | 바꾼 설정 |
|---|---|---|
| 잘못 닫힌 사실 (판정 모델) | 15~28% (gpt-4.1-nano) | 0% (gpt-4.1-mini) |
| 바뀐 사실을 못 닫음 | 37~42% | 모델을 바꿔도 남음 |
| 한국어 키워드 검색 적중 | 23.7% (기본 BM25 분석기) | 58.8% (cjk 분석기) |
| 한국어로 저장된 사실 | 30% 미만 (gpt-4.1-mini) | 100% (gpt-5.5, 비용 12배) |
모순·날짜 판정은 기본으로 작은 모델(small_model)이 맡습니다. 한국어 데이터라면 판정 모델과 전문 검색 분석기부터 바꾸는 것이 가장 효과가 큽니다. 실험 전 과정은 아래 관련 글에 있습니다.
언제 쓰고, 언제 피하나
- 잘 맞는다: 사용자 정보가 시간에 따라 바뀌는 상담·CRM 에이전트, "그때는 무엇이 참이었나"를 물어야 하는 감사·규정 업무, 여러 출처의 사실을 엮어야 하는 기억.
- 다른 방법을 먼저 본다: 기억이 짧고 대화가 단순하다면 원문을 파일로 쌓고 검색하는 편이 더 정확했다(코어닷투데이 실측에서 원문 파일 95% 대 그래프 81%). 수집 한 건마다 LLM 호출이 여러 번 들어가 비용·지연이 크다.
한계와 주의
- 미래형 표현을 거르는 정규식이 영어 전용이다. 한국어 "다음 달에 이사할 거예요"가 현재 사실로 들어갈 수 있다.
- 무효화 후보를 찾을 때 그룹 전체를 뒤진다(이슈 #1728). 관련 수정 PR은 2026-10 기준 병합되지 않았다.
- 날짜 하나만 바꿔 넣어도 기억이 바뀐다 — 출처를 확인하지 않는 수집은 기억 오염에 취약하다.
- Zep 논문은 arXiv 2501.13956이다. 2504.03182는 이름이 비슷한 다른 논문(Cypher↔SQL 동치 검증)이니 혼동하지 않는다.




