LangChain integration for Apache AGE (graph) + pgvector (vector) on PostgreSQL
Project description
langchain-age
LangChain integration for Apache AGE (graph) + pgvector (vector) on PostgreSQL.
Mirrors the langchain-neo4j API so teams already familiar with the Neo4j integration can switch with minimal friction.
Features
| Component | Description |
|---|---|
AGEGraph |
GraphStore backed by PostgreSQL + Apache AGE. Executes Cypher via the cypher() SQL wrapper, introspects schema, and supports GraphDocument upserts. |
AGEVector |
VectorStore backed by pgvector. Supports cosine / L2 / inner-product similarity, HNSW & IVFFlat indexing, MMR search, and optional linkage to AGE graph nodes. |
AGEGraphCypherQAChain |
LLM chain that auto-generates Cypher for Apache AGE, executes it, and returns a natural-language answer. Drop-in replacement for GraphCypherQAChain. |
Quick Start
1. Start the database
cd docker
cp .env.example .env # edit credentials if needed
docker compose up -d
This spins up a single PostgreSQL container with both Apache AGE and pgvector pre-installed.
2. Install the library
pip install -e ".[dev]"
3. Use AGEGraph
from langchain_age import AGEGraph
graph = AGEGraph(
connection_string="host=localhost port=5432 dbname=langchain_age user=langchain password=langchain",
graph_name="my_graph",
)
# Run Cypher directly
graph.query("CREATE (:Person {name: 'Alice'})")
results = graph.query("MATCH (n:Person) RETURN n.name AS name")
print(results) # [{'name': 'Alice'}]
# Inspect the schema
print(graph.schema)
4. Use AGEVector
from langchain_age import AGEVector, DistanceStrategy
from langchain_openai import OpenAIEmbeddings
store = AGEVector(
connection_string="...",
embedding_function=OpenAIEmbeddings(),
collection_name="my_vectors",
distance_strategy=DistanceStrategy.COSINE,
)
store.add_texts(["Apache AGE adds Cypher to PostgreSQL.", "pgvector enables vector search."])
results = store.similarity_search("graph database", k=2)
for doc in results:
print(doc.page_content)
5. Use AGEGraphCypherQAChain
from langchain_age import AGEGraph, AGEGraphCypherQAChain
from langchain_openai import ChatOpenAI
graph = AGEGraph(connection_string="...", graph_name="movies")
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
chain = AGEGraphCypherQAChain.from_llm(
llm,
graph=graph,
allow_dangerous_requests=True,
verbose=True,
)
answer = chain.run("Which movies did Tom Hanks act in?")
print(answer)
AGE vs Neo4j – Key Differences
| Neo4j | Apache AGE | |
|---|---|---|
| Cypher execution | Direct Cypher protocol | Wrapped in SQL: SELECT * FROM cypher('graph', $$ ... $$) AS (col agtype) |
| Connection | Bolt protocol (neo4j://) |
PostgreSQL DSN / URI |
| Vector search | Native vector index | pgvector extension |
| APOC procedures | Available | Not available |
| Data type | Native graph types | agtype (superset of JSON) |
langchain-age handles the SQL wrapping automatically — you write plain Cypher.
Running Tests
# Unit tests (no DB required)
pytest tests/unit/
# Integration tests (requires Docker container)
export LANGCHAIN_AGE_TEST_DSN="host=localhost port=5432 dbname=langchain_age user=langchain password=langchain"
pytest tests/integration/
Project Structure
langchain-age/
├── docker/ # PostgreSQL + AGE + pgvector container
│ ├── Dockerfile
│ ├── docker-compose.yml
│ └── init/
│ └── 01_init_extensions.sql
├── langchain_age/
│ ├── __init__.py
│ ├── graphs/
│ │ └── age_graph.py # AGEGraph (GraphStore)
│ ├── vectorstores/
│ │ └── age_vector.py # AGEVector (VectorStore)
│ ├── chains/
│ │ └── graph_cypher_qa_chain.py # AGEGraphCypherQAChain
│ └── utils/
│ ├── agtype.py # agtype ↔ Python conversion
│ └── cypher.py # Cypher wrapping & validation
├── tests/
│ ├── unit/ # Pure Python, no DB
│ └── integration/ # Requires live DB
├── examples/
│ ├── 01_basic_graph_qa.py
│ ├── 02_vector_search.py
│ └── 03_graph_rag.py # Combined GraphRAG pattern
└── pyproject.toml
License
MIT
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file langchain_age-0.2.0.tar.gz.
File metadata
- Download URL: langchain_age-0.2.0.tar.gz
- Upload date:
- Size: 24.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.0 {"installer":{"name":"uv","version":"0.11.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7b877df041b09acf1ec0d8479d5a04728f2b5405da4d99407ac4a1aadffdf972
|
|
| MD5 |
206215c29492d8c545b74ef1a3ad8b63
|
|
| BLAKE2b-256 |
2bcb7d94bfc585257ae538a5b1cd56758296dd19a7e6b951a5595e4bc434e714
|
File details
Details for the file langchain_age-0.2.0-py3-none-any.whl.
File metadata
- Download URL: langchain_age-0.2.0-py3-none-any.whl
- Upload date:
- Size: 21.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.0 {"installer":{"name":"uv","version":"0.11.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
48980665d1ccb6e890d8ce0f2c0339bd3d7c56c96118db8ea4772c691523371f
|
|
| MD5 |
d2dc848dcc473ad372723340ff98f119
|
|
| BLAKE2b-256 |
0326738e4fcfb8cb5a8652d580f9895f8adbb21fba9d99071d5e9f26c0b81d24
|