PostgreSQL 하나로 관계형·벡터 검색 모두 처리하기
엔터프라이즈 환경에서 AI 기능을 서비스에 붙이다 보면, 어느 순간 "벡터 검색을 위한 전용 DB를 따로 띄워야 하나?"라는 고민에 부딪히게 된다. Pinecone이나 Weaviate 같은 전용 벡터 DB를 도입하면 운영 복잡도가 급격히 올라가고, 기존 관계형 데이터와의 조인이나 트랜잭션 정합성 보장도 어려워진다. 이 문제에 대한 현실적인 대안이 바로 PostgreSQL의 멀티모달 기능을 적극 활용하는 전략이다.
PostgreSQL은 JSONB를 통한 문서형 데이터 처리와 pgvector 확장을 통한 벡터 인덱싱을 모두 지원한다. JSONB는 단순 저장에 그치지 않고 GIN 인덱스와 결합하면 중첩 JSON 필드에 대한 빠른 조회가 가능하다. 여기에 HNSW(Hierarchical Navigable Small World) 벡터 인덱스를 더하면, 고차원 임베딩에 대해 높은 재현율(high-recall)을 유지하면서도 근사 최근접 이웃 검색을 수행할 수 있다. 결국 하나의 DB 위에서 정형 데이터 필터링, 문서 파싱, 시맨틱 벡터 검색을 모두 처리하는 구조가 가능해진다.
HNSW 인덱스와 벡터 양자화로 쿼리 성능 끌어올리기
HNSW 인덱스는 IVFFlat 방식 대비 인덱스 빌드 비용은 높지만, 검색 재현율과 쿼리 응답 속도 면에서 프로덕션 워크로드에 더 적합하다. pgvector 0.7 이후부터는 벡터 양자화(Vector Quantization)도 지원되는데, 이를 적용하면 메모리 사용량을 줄이면서 쿼리 속도를 최대 4배까지 향상시킬 수 있다.
-- HNSW 인덱스 생성 예시
CREATE INDEX ON documents
USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 64);
-- 벡터 양자화(halfvec) 적용
CREATE INDEX ON documents
USING hnsw (embedding::halfvec(1536) vector_cosine_ops);
halfvec 타입으로 캐스팅해 인덱스를 구성하면 float32 대신 float16 정밀도로 저장되므로, 메모리 풋프린트가 절반으로 줄어든다. 실제 검색 쿼리에서 WHERE 절로 관계형 필터를 함께 적용하면 벡터 스캔 범위 자체가 줄어들어 성능 이점이 더욱 커진다. 단, ef_search 파라미터 튜닝을 통해 재현율과 속도 간의 트레이드오프를 상황에 맞게 조정하는 것이 중요하다.
에이전트 메모리 관리 전략
AI 에이전트를 서비스에 통합할 때 간과하기 쉬운 부분이 메모리 관리다. 에이전트가 다중 세션이나 긴 대화 흐름을 처리하려면 단기 컨텍스트와 장기 기억을 구분해서 저장·조회하는 전략이 필요하다. PostgreSQL을 활용하면 이 두 가지를 하나의 스토리지 레이어에서 일관성 있게 관리할 수 있다.
구체적으로는 다음과 같은 패턴이 실무에서 유효하다.
- 단기 메모리(세션 컨텍스트): 대화 이력을 JSONB 컬럼에 저장하고, 세션 TTL 기반으로 파티셔닝하거나 주기적으로 아카이빙
- 장기 메모리(사실·선호 정보): 핵심 정보를 임베딩 벡터로 변환해 HNSW 인덱스가 붙은 테이블에 저장하고, 관련 컨텍스트 조회 시 시맨틱 검색으로 리트리브
- 결정론적 컨텍스트: 사용자 권한, 계정 상태 등 구조화된 정보는 일반 관계형 테이블에 유지하고 JOIN으로 결합
이 패턴은 별도의 외부 메모리 스토어 없이도 에이전트가 필요로 하는 결정론적(deterministic) 컨텍스트와 시맨틱 컨텍스트를 동시에 제공할 수 있다는 점에서, 운영 복잡도를 낮추는 데 실질적인 효과가 있다.
정리
- PostgreSQL의 JSONB + HNSW 조합으로 벡터 전용 DB 없이 관계형·시맨틱 검색을 단일 DB에서 처리할 수 있다.
halfvec기반 벡터 양자화를 적용하면 메모리 절감과 함께 쿼리 속도를 최대 4배 향상시킬 수 있다.- 에이전트 메모리는 단기/장기/결정론적 컨텍스트로 분리해 PostgreSQL 단일 레이어에서 관리하는 전략이 운영 효율을 높인다.