Skip to content
BAEM1N.DEV — AI, RAG, LLMOps 개발 블로그
Go back

GraphRAG를 PostgreSQL만으로 구축하기 — Neo4j 없이 Apache AGE + pgvector

Disclosure: 이 글의 저자는 langchain-age 메인테이너입니다.

TL;DR: Apache AGE(그래프) + pgvector(벡터)를 PostgreSQL 위에 올리면 Neo4j + Pinecone 조합과 동일한 GraphRAG를 DB 1개, 커넥션 1개, 백업 1개로 운영할 수 있다. langchain-age 패키지로 LangChain 생태계에 바로 연결된다.

Table of contents

Open Table of contents

시리즈

이 글은 langchain-age 시리즈의 1편이다.

  1. GraphRAG를 PostgreSQL만으로 구축하기 (현재 글)
  2. Neo4j vs Apache AGE 실측 벤치마크 — 성능 데이터
  3. 벡터 검색 완전 정복 — Hybrid, MMR, 필터링
  4. GraphRAG 파이프라인 실전 구축 — 벡터 + 그래프 통합
  5. PostgreSQL 하나로 AI Agent 전체 스택 — LangGraph 연동

이 글을 읽고 나면

문제: GraphRAG를 위해 DB를 2개 운영해야 하나?

GraphRAG는 지식 그래프와 벡터 임베딩을 함께 검색해서 LLM에 컨텍스트를 제공하는 패턴이다. 가장 많이 인용되는 접근법은 Neo4j를 사용하지만, 이는 곧:

이미 PostgreSQL을 쓰고 있다면, 같은 인스턴스에서 그래프와 벡터를 모두 처리할 수 있다.

해답: Apache AGE + pgvector

Apache AGE는 PostgreSQL에 Cypher 그래프 쿼리를 추가하는 확장이다. pgvector는 벡터 유사도 검색을 추가한다. 둘 다 같은 PostgreSQL 인스턴스 안에서 동작한다.

PostgreSQL 통합 아키텍처 — AGE + pgvector + LangGraph

하나의 데이터베이스. 하나의 커넥션 문자열.

Neo4j vs PostgreSQL+AGE 비교

항목Neo4j + PineconePostgreSQL + AGE + pgvector
데이터베이스 수2 (그래프 + 벡터)1
라이선스GPL + 상용Apache 2.0 + PostgreSQL License
HA 비용$15K+/년 + 벡터 DB 요금$0 (PG 네이티브 HA)
LangChain 연동langchain-neo4jlangchain-age
배포클러스터 2개 관리PostgreSQL 1개
백업파이프라인 2개pg_dump 1개
장기 메모리별도 DB/서비스동일 DB (LangGraph PostgresStore)

5분 만에 셋업하기

Step 1: 데이터베이스 시작

git clone https://github.com/BAEM1N/langchain-age.git
cd langchain-age/docker
docker compose up -d

컨테이너 1개에 AGE + pgvector + pg_trgm이 사전 설치되어 있다.

Step 2: 패키지 설치

pip install "langchain-age[all]" langchain-openai

Step 3: 지식 그래프 구축

from langchain_age import AGEGraph

graph = AGEGraph(
    "host=localhost port=5433 dbname=langchain_age user=langchain password=langchain",
    graph_name="company_kg",
)

# Neo4j와 동일한 Cypher 문법 — 새로 배울 것 없음
graph.query("CREATE (:Person {name: 'Alice', role: 'CTO'})")
graph.query("CREATE (:Person {name: 'Bob', role: 'Engineer'})")
graph.query("CREATE (:Product {name: 'AGE', desc: 'Graph extension for PostgreSQL'})")
graph.query(
    "MATCH (a:Person {name: 'Alice'}), (p:Product {name: 'AGE'}) "
    "CREATE (a)-[:LEADS]->(p)"
)
graph.query(
    "MATCH (a:Person {name: 'Alice'}), (b:Person {name: 'Bob'}) "
    "CREATE (a)-[:MANAGES]->(b)"
)

Step 4: 그래프 노드 벡터화

from langchain_age import AGEVector
from langchain_openai import OpenAIEmbeddings

# 한 줄로: 그래프 노드 → 벡터 임베딩
store = AGEVector.from_existing_graph(
    embedding=OpenAIEmbeddings(model="text-embedding-3-small"),
    connection_string="host=localhost port=5433 ...",
    graph_name="company_kg",
    node_label="Person",
    text_node_properties=["name", "role"],
    collection_name="person_vectors",
)

Step 5: GraphRAG — 벡터 검색 + 그래프 컨텍스트

# 1단계: 벡터 검색으로 관련 노드 찾기
docs = store.similarity_search("engineering leadership", k=2)

# 2단계: 그래프 관계로 컨텍스트 확장
for doc in docs:
    label = doc.metadata["node_label"]
    neighbors = graph.query(
        f"MATCH (n:{label})-[r]->(m) RETURN type(r) AS rel, m.name AS name"
    )
    print(f"{doc.page_content}: {neighbors}")

Step 6: LLM 기반 Cypher QA

from langchain_age import AGEGraphCypherQAChain
from langchain_openai import ChatOpenAI

chain = AGEGraphCypherQAChain.from_llm(
    ChatOpenAI(model="gpt-4o-mini"),
    graph=graph,
    allow_dangerous_requests=True,
)

answer = chain.run("Who does Alice manage?")
# "Alice manages Bob, who is an Engineer."

Neo4j 대신 AGE를 쓰는 이유

1. 이미 PostgreSQL을 쓰고 있다

대부분의 애플리케이션은 이미 PostgreSQL을 운영 중이다. AGE 추가는 CREATE EXTENSION age; 한 줄이지, 새 DB 클러스터를 배포하는 것이 아니다.

2. 라이선스 자유

Neo4j Community는 GPL이다. 상용 제품에 포함하면 GPL이 전파된다. Enterprise는 $15K+/년 상용 라이선스가 필요하다.

Apache AGE는 Apache 2.0이다. 제약 없이 사용 가능하다.

3. 총 비용 비교

시나리오Neo4jAGE
개발/테스트무료 (Community, 단일 노드)무료
프로덕션 HA$15K+/년 (Enterprise) 또는 AuraDB ($65/GB/월)$0 (PostgreSQL Patroni/repmgr)
벡터 검색별도 벡터 DB 필요포함 (pgvector)
장기 메모리별도 서비스 필요포함 (LangGraph PostgresStore)

4. 백업 1개, 모니터링 1개, 팀 1개

PostgreSQL DBA가 이미 알고 있는 것들:

새로운 운영 전문성이 필요 없다.

5. RAG 워크로드에서 성능은 충분하다 — 실측 데이터

“AGE가 Neo4j보다 느리지 않나?”라는 의문이 있을 수 있다. 동일한 1K 노드 / 2K 엣지 그래프에서 같은 Cypher를 실행한 실측 결과:

테스트Neo4j p50AGE p50승자
포인트 룩업2.0ms0.9msAGE 2.2x
1홉 탐색1.7ms1.0msAGE 1.7x
단건 CREATE3.3ms0.9msAGE 3.7x
3홉 탐색1.7ms25.8msNeo4j 14.9x
6홉 탐색2.4ms27.7msNeo4j 11.6x

RAG에서 가장 흔한 패턴 (1~2홉 조회, CRUD)에서 AGE가 Neo4j보다 빠르다. Neo4j가 우위인 것은 3홉 이상 깊은 탐색뿐이다.

깊은 탐색도 langchain-agetraverse() (PostgreSQL WITH RECURSIVE)를 쓰면 역전된다:

깊이AGE CypherAGE traverse()Neo4j
3홉26.4ms1.3ms1.7ms
6홉28.2ms1.4ms2.4ms

traverse()를 쓰면 6홉에서도 AGE가 Neo4j보다 1.7배 빠르다. 자세한 벤치마크 결과는 Neo4j vs AGE 실측 벤치마크에서 확인할 수 있다.

Neo4j가 더 나은 경우

솔직하게 말하면:

“100억 엣지 소셜 네트워크에서 실시간 커뮤니티 탐지”가 워크로드라면 Neo4j를 쓰고 라이선스비를 내라. 그만한 가치가 있다.

“벡터 검색과 함께 그래프 컨텍스트가 필요한 RAG 애플리케이션”이 워크로드라면, PostgreSQL 위의 AGE가 더 단순하고, 저렴하고, 유지보수하기 쉬운 선택이다.

자주 묻는 질문

Apache AGE와 Neo4j의 Cypher 호환성은 어느 정도인가?

AGE는 openCypher 스펙을 구현하며 CREATE, MATCH, MERGE, DELETE 등 핵심 문법을 지원한다. Neo4j 전용 APOC 프로시저는 사용할 수 없지만, 일반적인 CRUD와 패턴 매칭 쿼리는 그대로 동작한다.

pgvector와 Pinecone 중 어떤 벡터 DB가 RAG에 적합한가?

1,000만 벡터 이하의 워크로드에서는 pgvector가 충분하다. 별도 인프라 비용이 없고 PostgreSQL 트랜잭션과 함께 동작한다. 수억 벡터 + 초저지연이 필요하면 Pinecone 같은 전용 벡터 DB를 고려하라.

langchain-age는 LangGraph와 호환되나?

호환된다. 같은 PostgreSQL 인스턴스에서 LangGraph의 PostgresStore와 Checkpoint를 함께 사용할 수 있어, 그래프·벡터·에이전트 상태를 DB 하나로 관리 가능하다.

기존 Neo4j 그래프를 AGE로 마이그레이션할 수 있나?

Cypher EXPORT로 노드와 관계를 내보낸 후 AGE에서 동일한 CREATE 문으로 적재할 수 있다. 대량 데이터는 AGE의 CSV 로더를 사용하면 효율적이다.

langchain-age와 langchain-neo4j의 API는 얼마나 호환되나?

langchain-age는 langchain-neo4j의 API를 미러링한다. AGEGraphNeo4jGraph, AGEVectorNeo4jVector, AGEGraphCypherQAChainGraphCypherQAChain에 대응한다. 대부분의 경우 import 경로와 커넥션 문자열을 변경하면 기존 코드가 그대로 동작한다. 단, Neo4j 전용 APOC 프로시저를 사용하는 코드는 수정이 필요하다.

이미 Neo4j를 쓰고 있다면 AGE로 마이그레이션해야 하나?

반드시 그런 것은 아니다. Neo4j가 이미 잘 동작하고, 라이선스 비용이 문제가 아니라면 굳이 마이그레이션할 이유가 없다. AGE가 유리한 경우는: (1) PostgreSQL을 이미 운영 중이고 별도 DB를 추가하고 싶지 않을 때, (2) GPL 라이선스가 상용 제품에 문제가 될 때, (3) HA 비용을 줄이고 싶을 때다.

Apache AGE를 프로덕션에서 사용해도 안정적인가?

Apache AGE는 Apache Software Foundation의 Top-Level Project이며 PostgreSQL 확장으로 동작하므로, PostgreSQL의 MVCC·WAL·크래시 복구를 그대로 상속한다. 프로덕션 HA는 Patroni나 repmgr 같은 기존 PG HA 솔루션을 그대로 적용할 수 있다.

시작하기

pip install "langchain-age[all]"

핵심 정리

관련 포스트


langchain-age는 MIT 라이선스. Apache AGE는 Apache 2.0. pgvector는 PostgreSQL License. 라이선스 비용 없음, 벤더 종속 없음.


AI-assisted content
Share this post on:

Previous Post
PostgreSQL 하나로 AI Agent 전체 스택 — LangGraph + langchain-age
Next Post
Neo4j vs Apache AGE 실측 벤치마크 — 같은 Cypher, 같은 데이터, 다른 결과