> ## Documentation Index
> Fetch the complete documentation index at: https://docs.langchain.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Kuzu integration

> Integrate with the Kuzu graph using LangChain Python.

> [Kùzu](https://kuzudb.com/) is an embeddable, scalable, extremely fast graph database.
> It is permissively licensed with an MIT license, and you can see its source code [on GitHub](https://github.com/kuzudb/kuzu).

> Key characteristics of Kùzu:
>
> * Performance and scalability: Implements modern, state-of-the-art join algorithms for graphs.
> * Usability: Very easy to set up and get started with, as there are no servers (embedded architecture).
> * Interoperability: Can conveniently scan and copy data from external columnar formats, CSV, JSON and relational databases.
> * Structured property graph model: Implements the property graph model, with added structure.
> * Cypher support: Allows convenient querying of the graph in Cypher, a declarative query language.

> Get started with Kùzu by visiting their [documentation](https://docs.kuzudb.com/).

## Setting up

Kùzu is an embedded database (it runs in-process), so there are no servers to manage. Install the
following dependencies to get started:

<Warning>
  The `langchain-experimental` package is no longer maintained. Examples that import from `langchain_experimental` may be outdated or broken. Use with caution.
</Warning>

```bash theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
pip install -U langchain-kuzu langchain-openai langchain-experimental langchain-neo4j
```

This installs Kùzu along with the LangChain integration for it, as well as the OpenAI Python package
so that we can use OpenAI's LLMs. If you want to use other LLM providers, you can install their
respective Python packages that come with LangChain.

Here's how you would first create a Kùzu database on your local machine and connect to it:

```python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
import kuzu

db = kuzu.Database("test_db")
conn = kuzu.Connection(db)
```

## Create `KuzuGraph`

Kùzu's integration with LangChain makes it convenient to create and update graphs from unstructured text, and also to query graphs via a Text2Cypher pipeline that utilizes the
power of LangChain's LLM chains. To begin, we create a `KuzuGraph` object that uses the database object we created above in combination with the `KuzuGraph` constructor.

```python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
from langchain_kuzu.graphs.kuzu_graph import KuzuGraph

graph = KuzuGraph(db, allow_dangerous_requests=True)
```

Say we want to transform the following text into a graph:

```python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
text = "Tim Cook is the CEO of Apple. Apple has its headquarters in California."
```

We will make use of `LLMGraphTransformer` to use an LLM to extract nodes and relationships from the text.
To make the graph more useful, we will define the following schema, such that the LLM will only
extract nodes and relationships that match the schema.

```python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
# Define schema
allowed_nodes = ["Person", "Company", "Location"]
allowed_relationships = [
    ("Person", "IS_CEO_OF", "Company"),
    ("Company", "HAS_HEADQUARTERS_IN", "Location"),
]
```

The `LLMGraphTransformer` class provides a convenient way to convert the text into a list of graph documents.

```python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
from langchain_core.documents import Document
from langchain_neo4j import LLMGraphTransformer
from langchain_openai import ChatOpenAI

# Define the LLMGraphTransformer
llm_transformer = LLMGraphTransformer(
    llm=ChatOpenAI(model="gpt-5.4-mini", temperature=0, api_key=OPENAI_API_KEY),
    allowed_nodes=allowed_nodes,
    allowed_relationships=allowed_relationships,
)

documents = [Document(page_content=text)]
graph_documents = llm_transformer.convert_to_graph_documents(documents)
```

```python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
graph_documents[:2]
```

```text theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
[GraphDocument(nodes=[Node(id='Tim Cook', type='Person', properties={}), Node(id='Apple', type='Company', properties={}), Node(id='California', type='Location', properties={})], relationships=[Relationship(source=Node(id='Tim Cook', type='Person', properties={}), target=Node(id='Apple', type='Company', properties={}), type='IS_CEO_OF', properties={}), Relationship(source=Node(id='Apple', type='Company', properties={}), target=Node(id='California', type='Location', properties={}), type='HAS_HEADQUARTERS_IN', properties={})], source=Document(metadata={}, page_content='Tim Cook is the CEO of Apple. Apple has its headquarters in California.'))]
```

We can then call the above defined `KuzuGraph` object's `add_graph_documents` method to ingest the graph documents into the Kùzu database.
The `include_source` argument is set to `True` so that we also create relationships between each entity node and the source document that it came from.

```python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
# Add the graph document to the graph
graph.add_graph_documents(
    graph_documents,
    include_source=True,
)
```

## Creating `KuzuQAChain`

To query the graph via a Text2Cypher pipeline, we can define a `KuzuQAChain` object. Then, we can invoke the chain with a query by connecting to the existing database that's stored in the `test_db` directory defined above.

```python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
from langchain_kuzu.chains.graph_qa.kuzu import KuzuQAChain

# Create the KuzuQAChain with verbosity enabled to see the generated Cypher queries
chain = KuzuQAChain.from_llm(
    llm=ChatOpenAI(model="gpt-5.4-mini", temperature=0.3, api_key=OPENAI_API_KEY),
    graph=graph,
    verbose=True,
    allow_dangerous_requests=True,
)
```

Note that we set a temperature that's slightly higher than zero to avoid the LLM being overly concise in its response.

Let's ask some questions using the QA chain.

```python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
chain.invoke("Who is the CEO of Apple?")
```

```text theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
> Entering new KuzuQAChain chain...
Generated Cypher:
MATCH (p:Person)-[:IS_CEO_OF]->(c:Company {id: 'Apple'}) RETURN p
Full Context:
[{'p': {'_id': {'offset': 0, 'table': 1}, '_label': 'Person', 'id': 'Tim Cook', 'type': 'entity'}}]

> Finished chain.
```

```text theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
{'query': 'Who is the CEO of Apple?',
 'result': 'Tim Cook is the CEO of Apple.'}
```

```python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
chain.invoke("Where is Apple headquartered?")
```

```text theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
> Entering new KuzuQAChain chain...
Generated Cypher:
MATCH (c:Company {id: 'Apple'})-[:HAS_HEADQUARTERS_IN]->(l:Location) RETURN l
Full Context:
[{'l': {'_id': {'offset': 0, 'table': 2}, '_label': 'Location', 'id': 'California', 'type': 'entity'}}]

> Finished chain.
```

```text theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
{'query': 'Where is Apple headquartered?',
 'result': 'Apple is headquartered in California.'}
```

## Refresh graph schema

If you mutate or update the graph, you can inspect the refreshed schema information that's used by the Text2Cypher chain to generate Cypher statements.
You don't need to manually call `refresh_schema()` each time as it's called automatically when you invoke the chain.

```python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
graph.refresh_schema()

print(graph.get_schema)
```

```text theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
Node properties: [{'properties': [('id', 'STRING'), ('type', 'STRING')], 'label': 'Person'}, {'properties': [('id', 'STRING'), ('type', 'STRING')], 'label': 'Location'}, {'properties': [('id', 'STRING'), ('text', 'STRING'), ('type', 'STRING')], 'label': 'Chunk'}, {'properties': [('id', 'STRING'), ('type', 'STRING')], 'label': 'Company'}]
Relationships properties: [{'properties': [], 'label': 'HAS_HEADQUARTERS_IN'}, {'properties': [('label', 'STRING'), ('triplet_source_id', 'STRING')], 'label': 'MENTIONS_Chunk_Person'}, {'properties': [('label', 'STRING'), ('triplet_source_id', 'STRING')], 'label': 'MENTIONS_Chunk_Location'}, {'properties': [], 'label': 'IS_CEO_OF'}, {'properties': [('label', 'STRING'), ('triplet_source_id', 'STRING')], 'label': 'MENTIONS_Chunk_Company'}]
Relationships: ['(:Company)-[:HAS_HEADQUARTERS_IN]->(:Location)', '(:Chunk)-[:MENTIONS_Chunk_Person]->(:Person)', '(:Chunk)-[:MENTIONS_Chunk_Location]->(:Location)', '(:Person)-[:IS_CEO_OF]->(:Company)', '(:Chunk)-[:MENTIONS_Chunk_Company]->(:Company)']
```

## Use separate LLMs for cypher and answer generation

You can specify `cypher_llm` and `qa_llm` separately to use different LLMs for Cypher generation and answer generation.

```python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
chain = KuzuQAChain.from_llm(
    cypher_llm=ChatOpenAI(temperature=0, model="gpt-5.4-mini"),
    qa_llm=ChatOpenAI(temperature=0, model="gpt-4"),
    graph=graph,
    verbose=True,
    allow_dangerous_requests=True,
)
```

```python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
chain.invoke("Who is the CEO of Apple?")
```

```text theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
> Entering new KuzuQAChain chain...
Generated Cypher:
MATCH (p:Person)-[:IS_CEO_OF]->(c:Company {id: 'Apple'}) RETURN p.id, p.type
Full Context:
[{'p.id': 'Tim Cook', 'p.type': 'entity'}]

> Finished chain.
```

```text theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
{'query': 'Who is the CEO of Apple?',
 'result': 'Tim Cook is the CEO of Apple.'}
```

***

<div className="source-links">
  <Callout icon="terminal-2">
    [Connect these docs](/use-these-docs) to Claude, VSCode, and more via MCP for real-time answers.
  </Callout>

  <Callout icon="edit">
    [Edit this page on GitHub](https://github.com/langchain-ai/docs/edit/main/src/oss/python/integrations/graphs/kuzu_db.mdx) or [file an issue](https://github.com/langchain-ai/docs/issues/new/choose).
  </Callout>
</div>
