프로젝트 기억을 Neo4j 그래프 + GraphRAG로 넓힌다
- 상태: 제안됨
- 작성일: 2026-08-13
- 관련 문서: ADR-0013
맥락
두 문서가 서로 반대 방향으로 서 있다.
기술 쪽에서는 ADR-0013이 전용 벡터 DB와 GraphRAG를 함께 검토했다. "운영 컴포넌트가 하나 늘고 추출 파이프라인까지 붙는" 비용 대비 "노트 수백 개 규모에서 값이 안 보인다"로 그래프를 배제했다. 지금 벡터는 heymoa-ai의 pgvector에 있다.
제품 쪽에서는 정본이 프로젝트 기억을 관계망으로 정의한다. 평면 목록이 아니다. 사람, 발화, 회의, 안건, 자료, 질문·답, 결정, 인사이트, 할 일과 외부 결과를 근거·맥락·대체·관련·담당·이월·실행 관계로 잇는다. 제품 한 줄도 "이전 결정과의 충돌을 감지"이고, "출시일은 왜 바뀌었어?"·"이 결정과 관련된 할 일은?"이 답해야 할 질문으로 명시돼 있다.
벡터 유사도가 답하는 모양이 아닌 질문들이다. "왜 바뀌었나"는 결정 A를 결정 B가 대체했다는 간선을 따라가야 나온다. 유사한 문장 top-k로는 안 나온다.
결정
프로젝트 기억의 관계를 Neo4j에 두고 검색을 GraphRAG로 한다.
⚠️ 아래가 채워지기 전에는 상태를 채택됨으로 올리지 않는다. 지금 기록된 것은 제품 요구와 선택지
이름뿐이다.
- pgvector를 대체하나 병행하나. 병행이면 어느 질문이 어디로 가는지 라우팅 규칙을 정해야 한다. 대체면 전사 청크 검색을 그래프가 어떻게 받는지가 남는다.
- 관계 추출을 누가 언제 하는가. 정본은 사람이 회의 요약을 승인하기 전에는 지식 그래프의 확정 관계로 저장하지 않는다고 정했다. 추출은 후보로만 쌓이고 승인이 커밋 경계라는 뜻인데, 이 경계가 그래프 쓰기 경로에 어떻게 들어가는지.
- 운영 컴포넌트 하나 추가를 지금은 감당하는 이유. 그것이 ADR-0013의 배제 근거 그 자체였다. 노트 수백 개 규모가 바뀐 것인지, 질문 유형이 달라진 것인지.
- heymoa-ai DB 규칙과의 관계. "AI DB에는 파생 데이터만 두고 cross-database 쿼리를 금지한다"에서 그래프가 파생인가 정본인가. 정본이면 그 규칙의 예외를 명시해야 한다.
대안
대안 1 — Postgres 안에서 관계 테이블 + pgvector. 운영 DB를 늘리지 않고 간선을 행으로 둔다. 기각한 이유: 가변 깊이 탐색과 경로 질의가 재귀 CTE가 된다. 관계 종류가 늘수록 쿼리도 커진다. 다만 지금 규모에서는 이쪽이 ADR-0013의 결론과 일관되므로 재검토 여지가 있다.
대안 2 — 요약 인덱스 agentic 검색. 저장소를 안 늘리고 LLM이 요약을 훑어 관계를 조립한다. 기각한 이유: 이미 한 번 "임베딩의 대체 관계가 아니다"로 판정된 안이다. 근거 링크의 정확성이 매 호출의 운에 걸린다.
대안 3 — 현행 유지(pgvector 단독). 아무 비용이 없다. 기각한 이유: 관계 질문을 제품에서 빼야 하는데, 그것이 정본이 정의한 기억과 어긋난다.
결과
- 관계 질문("왜 바뀌었나", "이 사람이 맡은 것은")이 간선 탐색으로 답해진다. 제품 정본이 정의한 기억의 모양과 저장소 모양이 일치한다.
- 운영 DB가 둘이 된다. 백업·마이그레이션·접근 제어·모니터링이 두 벌이다. EC2 두 대 + RDS 하나로 버티던 인프라 형상도 깨진다. Neo4j는 메모리를 많이 써서 현재 인스턴스 등급에 얹을 수 없다.
- 추출 파이프라인 품질이 곧 답 품질이 된다. 관계가 틀리면 근거 링크가 틀린다. "근거와 함께 축적"이라는 제품 한 줄을 정면으로 배신하는 실패 모양이고, 벡터 검색의 실패(관련 없는 청크)보다 나쁘다.
- 두 저장소 사이의 정합성을 우리가 진다. 노트 삭제·재분석은 그래프에도 전파돼야 한다. 파괴적 마이그레이션 규칙은 Postgres에만 있다.
- Cypher와 GraphRAG 스택이 새 학습 비용이다. 3인 팀에서 이 층을 아는 사람이 한 명이면 버스 팩터 1이 된다.