mirror of
https://github.com/hwchase17/langchain.git
synced 2025-07-12 15:59:56 +00:00
Kùzu package integration docs (#29076)
## Langchain Kùzu ### Description This PR adds docs for the `langchain-kuzu` package [on PyPI](https://pypi.org/project/langchain-kuzu/) that was recently published, allowing Kùzu users to more easily use and work with LangChain QA chains. The package will also make it easier for the Kùzu team to continue supporting and updating the integration over future releases. ### Twitter Handle Please tag [@kuzudb](https://x.com/kuzudb) on Twitter once this PR is merged, so LangChain users can be notified! --------- Co-authored-by: Erick Friis <erickfriis@gmail.com>
This commit is contained in:
parent
cc0f81f40f
commit
b1dafaef9b
@ -7,12 +7,17 @@
|
|||||||
"source": [
|
"source": [
|
||||||
"# Kuzu\n",
|
"# Kuzu\n",
|
||||||
"\n",
|
"\n",
|
||||||
">[Kùzu](https://kuzudb.com) is an embeddable property graph database management system built for query speed and scalability.\n",
|
"> [Kùzu](https://kuzudb.com/) is an embeddable, scalable, extremely fast graph database.\n",
|
||||||
"> \n",
|
"> It is permissively licensed with an MIT license, and you can see its source code [here](https://github.com/kuzudb/kuzu).\n",
|
||||||
"> Kùzu has a permissive (MIT) open source license and implements [Cypher](https://en.wikipedia.org/wiki/Cypher_(query_language)), a declarative graph query language that allows for expressive and efficient data querying in a property graph.\n",
|
"\n",
|
||||||
"> It uses columnar storage and its query processor contains novel join algorithms that allow it to scale to very large graphs without sacrificing query performance.\n",
|
"> Key characteristics of Kùzu:\n",
|
||||||
"> \n",
|
">- Performance and scalability: Implements modern, state-of-the-art join algorithms for graphs.\n",
|
||||||
"> This notebook shows how to use LLMs to provide a natural language interface to [Kùzu](https://kuzudb.com) database with Cypher."
|
">- Usability: Very easy to set up and get started with, as there are no servers (embedded architecture).\n",
|
||||||
|
">- Interoperability: Can conveniently scan and copy data from external columnar formats, CSV, JSON and relational databases.\n",
|
||||||
|
">- Structured property graph model: Implements the property graph model, with added structure.\n",
|
||||||
|
">- Cypher support: Allows convenient querying of the graph in Cypher, a declarative query language.\n",
|
||||||
|
"\n",
|
||||||
|
"> Get started with Kùzu by visiting their [documentation](https://docs.kuzudb.com/)."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -22,19 +27,28 @@
|
|||||||
"source": [
|
"source": [
|
||||||
"## Setting up\n",
|
"## Setting up\n",
|
||||||
"\n",
|
"\n",
|
||||||
"Kùzu is an embedded database (it runs in-process), so there are no servers to manage.\n",
|
"Kùzu is an embedded database (it runs in-process), so there are no servers to manage. Install the\n",
|
||||||
"Simply install it via its Python package:\n",
|
"following dependencies to get started:\n",
|
||||||
"\n",
|
"\n",
|
||||||
"```bash\n",
|
"```bash\n",
|
||||||
"pip install kuzu\n",
|
"pip install -U langchain-kuzu langchain-openai langchain-experimental\n",
|
||||||
"```\n",
|
"```\n",
|
||||||
"\n",
|
"\n",
|
||||||
"Create a database on the local machine and connect to it:"
|
"This installs Kùzu along with the LangChain integration for it, as well as the OpenAI Python package\n",
|
||||||
|
"so that we can use OpenAI's LLMs. If you want to use other LLM providers, you can install their\n",
|
||||||
|
"respective Python packages that come with LangChain."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"Here's how you would first create a Kùzu database on your local machine and connect to it:"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 2,
|
"execution_count": 1,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
@ -45,80 +59,136 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"attachments": {},
|
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"First, we create the schema for a simple movie database:"
|
"## Create `KuzuGraph`"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"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\n",
|
||||||
|
"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."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 2,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"from langchain_kuzu.graphs.kuzu_graph import KuzuGraph\n",
|
||||||
|
"\n",
|
||||||
|
"graph = KuzuGraph(db, allow_dangerous_requests=True)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"Say we want to transform the following text into a graph:"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 3,
|
"execution_count": 3,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [],
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"<kuzu.query_result.QueryResult at 0x103a72290>"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 3,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
"source": [
|
||||||
"conn.execute(\"CREATE NODE TABLE Movie (name STRING, PRIMARY KEY(name))\")\n",
|
"text = \"Tim Cook is the CEO of Apple. Apple has its headquarters in California.\""
|
||||||
"conn.execute(\n",
|
|
||||||
" \"CREATE NODE TABLE Person (name STRING, birthDate STRING, PRIMARY KEY(name))\"\n",
|
|
||||||
")\n",
|
|
||||||
"conn.execute(\"CREATE REL TABLE ActedIn (FROM Person TO Movie)\")"
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"attachments": {},
|
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"Then we can insert some data."
|
"We will make use of `LLMGraphTransformer` to use an LLM to extract nodes and relationships from the text.\n",
|
||||||
|
"To make the graph more useful, we will define the following schema, such that the LLM will only\n",
|
||||||
|
"extract nodes and relationships that match the schema."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 4,
|
"execution_count": 4,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"# Define schema\n",
|
||||||
|
"allowed_nodes = [\"Person\", \"Company\", \"Location\"]\n",
|
||||||
|
"allowed_relationships = [\n",
|
||||||
|
" (\"Person\", \"IS_CEO_OF\", \"Company\"),\n",
|
||||||
|
" (\"Company\", \"HAS_HEADQUARTERS_IN\", \"Location\"),\n",
|
||||||
|
"]"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"The `LLMGraphTransformer` class provides a convenient way to convert the text into a list of graph documents."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 6,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"from langchain_core.documents import Document\n",
|
||||||
|
"from langchain_experimental.graph_transformers import LLMGraphTransformer\n",
|
||||||
|
"from langchain_openai import ChatOpenAI\n",
|
||||||
|
"\n",
|
||||||
|
"# Define the LLMGraphTransformer\n",
|
||||||
|
"llm_transformer = LLMGraphTransformer(\n",
|
||||||
|
" llm=ChatOpenAI(model=\"gpt-4o-mini\", temperature=0, api_key=OPENAI_API_KEY), # noqa: F821\n",
|
||||||
|
" allowed_nodes=allowed_nodes,\n",
|
||||||
|
" allowed_relationships=allowed_relationships,\n",
|
||||||
|
")\n",
|
||||||
|
"\n",
|
||||||
|
"documents = [Document(page_content=text)]\n",
|
||||||
|
"graph_documents = llm_transformer.convert_to_graph_documents(documents)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 7,
|
||||||
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
"data": {
|
"data": {
|
||||||
"text/plain": [
|
"text/plain": [
|
||||||
"<kuzu.query_result.QueryResult at 0x103a9e750>"
|
"[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.'))]"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"execution_count": 4,
|
"execution_count": 7,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"output_type": "execute_result"
|
"output_type": "execute_result"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"source": [
|
"source": [
|
||||||
"conn.execute(\"CREATE (:Person {name: 'Al Pacino', birthDate: '1940-04-25'})\")\n",
|
"graph_documents[:2]"
|
||||||
"conn.execute(\"CREATE (:Person {name: 'Robert De Niro', birthDate: '1943-08-17'})\")\n",
|
]
|
||||||
"conn.execute(\"CREATE (:Movie {name: 'The Godfather'})\")\n",
|
},
|
||||||
"conn.execute(\"CREATE (:Movie {name: 'The Godfather: Part II'})\")\n",
|
{
|
||||||
"conn.execute(\n",
|
"cell_type": "markdown",
|
||||||
" \"CREATE (:Movie {name: 'The Godfather Coda: The Death of Michael Corleone'})\"\n",
|
"metadata": {},
|
||||||
")\n",
|
"source": [
|
||||||
"conn.execute(\n",
|
"We can then call the above defined `KuzuGraph` object's `add_graph_documents` method to ingest the graph documents into the Kùzu database.\n",
|
||||||
" \"MATCH (p:Person), (m:Movie) WHERE p.name = 'Al Pacino' AND m.name = 'The Godfather' CREATE (p)-[:ActedIn]->(m)\"\n",
|
"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."
|
||||||
")\n",
|
]
|
||||||
"conn.execute(\n",
|
},
|
||||||
" \"MATCH (p:Person), (m:Movie) WHERE p.name = 'Al Pacino' AND m.name = 'The Godfather: Part II' CREATE (p)-[:ActedIn]->(m)\"\n",
|
{
|
||||||
")\n",
|
"cell_type": "code",
|
||||||
"conn.execute(\n",
|
"execution_count": 8,
|
||||||
" \"MATCH (p:Person), (m:Movie) WHERE p.name = 'Al Pacino' AND m.name = 'The Godfather Coda: The Death of Michael Corleone' CREATE (p)-[:ActedIn]->(m)\"\n",
|
"metadata": {},
|
||||||
")\n",
|
"outputs": [],
|
||||||
"conn.execute(\n",
|
"source": [
|
||||||
" \"MATCH (p:Person), (m:Movie) WHERE p.name = 'Robert De Niro' AND m.name = 'The Godfather: Part II' CREATE (p)-[:ActedIn]->(m)\"\n",
|
"# Add the graph document to the graph\n",
|
||||||
|
"graph.add_graph_documents(\n",
|
||||||
|
" graph_documents,\n",
|
||||||
|
" include_source=True,\n",
|
||||||
")"
|
")"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -129,51 +199,7 @@
|
|||||||
"source": [
|
"source": [
|
||||||
"## Creating `KuzuQAChain`\n",
|
"## Creating `KuzuQAChain`\n",
|
||||||
"\n",
|
"\n",
|
||||||
"We can now create the `KuzuGraph` and `KuzuQAChain`. To create the `KuzuGraph` we simply need to pass the database object to the `KuzuGraph` constructor."
|
"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."
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 5,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"from langchain.chains import KuzuQAChain\n",
|
|
||||||
"from langchain_community.graphs import KuzuGraph\n",
|
|
||||||
"from langchain_openai import ChatOpenAI"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 6,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"graph = KuzuGraph(db)"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 8,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"chain = KuzuQAChain.from_llm(\n",
|
|
||||||
" llm=ChatOpenAI(temperature=0, model=\"gpt-3.5-turbo-16k\"),\n",
|
|
||||||
" graph=graph,\n",
|
|
||||||
" verbose=True,\n",
|
|
||||||
")"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"attachments": {},
|
|
||||||
"cell_type": "markdown",
|
|
||||||
"metadata": {},
|
|
||||||
"source": [
|
|
||||||
"## Refresh graph schema information\n",
|
|
||||||
"\n",
|
|
||||||
"If the schema of database changes, you can refresh the schema information needed to generate Cypher statements.\n",
|
|
||||||
"You can also display the schema of the Kùzu graph as demonstrated below."
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -182,7 +208,30 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"# graph.refresh_schema()"
|
"from langchain_kuzu.chains.graph_qa.kuzu import KuzuQAChain\n",
|
||||||
|
"\n",
|
||||||
|
"# Create the KuzuQAChain with verbosity enabled to see the generated Cypher queries\n",
|
||||||
|
"chain = KuzuQAChain.from_llm(\n",
|
||||||
|
" llm=ChatOpenAI(model=\"gpt-4o-mini\", temperature=0.3, api_key=OPENAI_API_KEY), # noqa: F821\n",
|
||||||
|
" graph=graph,\n",
|
||||||
|
" verbose=True,\n",
|
||||||
|
" allow_dangerous_requests=True,\n",
|
||||||
|
")"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"Note that we set a temperature that's slightly higher than zero to avoid the LLM being overly concise in its response."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"attachments": {},
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"Let's ask some questions using the QA chain."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -194,25 +243,31 @@
|
|||||||
"name": "stdout",
|
"name": "stdout",
|
||||||
"output_type": "stream",
|
"output_type": "stream",
|
||||||
"text": [
|
"text": [
|
||||||
"Node properties: [{'properties': [('name', 'STRING')], 'label': 'Movie'}, {'properties': [('name', 'STRING'), ('birthDate', 'STRING')], 'label': 'Person'}]\n",
|
"\n",
|
||||||
"Relationships properties: [{'properties': [], 'label': 'ActedIn'}]\n",
|
"\n",
|
||||||
"Relationships: ['(:Person)-[:ActedIn]->(:Movie)']\n",
|
"\u001b[1m> Entering new KuzuQAChain chain...\u001b[0m\n",
|
||||||
"\n"
|
"Generated Cypher:\n",
|
||||||
|
"\u001b[32;1m\u001b[1;3mMATCH (p:Person)-[:IS_CEO_OF]->(c:Company {id: 'Apple'}) RETURN p\u001b[0m\n",
|
||||||
|
"Full Context:\n",
|
||||||
|
"\u001b[32;1m\u001b[1;3m[{'p': {'_id': {'offset': 0, 'table': 1}, '_label': 'Person', 'id': 'Tim Cook', 'type': 'entity'}}]\u001b[0m\n",
|
||||||
|
"\n",
|
||||||
|
"\u001b[1m> Finished chain.\u001b[0m\n"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"text/plain": [
|
||||||
|
"{'query': 'Who is the CEO of Apple?',\n",
|
||||||
|
" 'result': 'Tim Cook is the CEO of Apple.'}"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"execution_count": 10,
|
||||||
|
"metadata": {},
|
||||||
|
"output_type": "execute_result"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"source": [
|
"source": [
|
||||||
"print(graph.get_schema)"
|
"chain.invoke(\"Who is the CEO of Apple?\")"
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"attachments": {},
|
|
||||||
"cell_type": "markdown",
|
|
||||||
"metadata": {},
|
|
||||||
"source": [
|
|
||||||
"## Querying the graph\n",
|
|
||||||
"\n",
|
|
||||||
"We can now use the `KuzuQAChain` to ask questions of the graph."
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -228,11 +283,9 @@
|
|||||||
"\n",
|
"\n",
|
||||||
"\u001b[1m> Entering new KuzuQAChain chain...\u001b[0m\n",
|
"\u001b[1m> Entering new KuzuQAChain chain...\u001b[0m\n",
|
||||||
"Generated Cypher:\n",
|
"Generated Cypher:\n",
|
||||||
"\u001b[32;1m\u001b[1;3mMATCH (p:Person)-[:ActedIn]->(m:Movie)\n",
|
"\u001b[32;1m\u001b[1;3mMATCH (c:Company {id: 'Apple'})-[:HAS_HEADQUARTERS_IN]->(l:Location) RETURN l\u001b[0m\n",
|
||||||
"WHERE m.name = 'The Godfather: Part II'\n",
|
|
||||||
"RETURN p.name\u001b[0m\n",
|
|
||||||
"Full Context:\n",
|
"Full Context:\n",
|
||||||
"\u001b[32;1m\u001b[1;3m[{'p.name': 'Al Pacino'}, {'p.name': 'Robert De Niro'}]\u001b[0m\n",
|
"\u001b[32;1m\u001b[1;3m[{'l': {'_id': {'offset': 0, 'table': 2}, '_label': 'Location', 'id': 'California', 'type': 'entity'}}]\u001b[0m\n",
|
||||||
"\n",
|
"\n",
|
||||||
"\u001b[1m> Finished chain.\u001b[0m\n"
|
"\u001b[1m> Finished chain.\u001b[0m\n"
|
||||||
]
|
]
|
||||||
@ -240,8 +293,8 @@
|
|||||||
{
|
{
|
||||||
"data": {
|
"data": {
|
||||||
"text/plain": [
|
"text/plain": [
|
||||||
"{'query': 'Who acted in The Godfather: Part II?',\n",
|
"{'query': 'Where is Apple headquartered?',\n",
|
||||||
" 'result': 'Al Pacino, Robert De Niro acted in The Godfather: Part II.'}"
|
" 'result': 'Apple is headquartered in California.'}"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"execution_count": 11,
|
"execution_count": 11,
|
||||||
@ -250,7 +303,18 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"source": [
|
"source": [
|
||||||
"chain.invoke(\"Who acted in The Godfather: Part II?\")"
|
"chain.invoke(\"Where is Apple headquartered?\")"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"attachments": {},
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## Refresh graph schema\n",
|
||||||
|
"\n",
|
||||||
|
"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.\n",
|
||||||
|
"You don't need to manually call `refresh_schema()` each time as it's called automatically when you invoke the chain."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -262,70 +326,41 @@
|
|||||||
"name": "stdout",
|
"name": "stdout",
|
||||||
"output_type": "stream",
|
"output_type": "stream",
|
||||||
"text": [
|
"text": [
|
||||||
"\n",
|
"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'}]\n",
|
||||||
"\n",
|
"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'}]\n",
|
||||||
"\u001b[1m> Entering new KuzuQAChain chain...\u001b[0m\n",
|
"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)']\n",
|
||||||
"Generated Cypher:\n",
|
"\n"
|
||||||
"\u001b[32;1m\u001b[1;3mMATCH (p:Person)-[:ActedIn]->(m:Movie)\n",
|
|
||||||
"WHERE p.name = 'Robert De Niro'\n",
|
|
||||||
"RETURN m.name\u001b[0m\n",
|
|
||||||
"Full Context:\n",
|
|
||||||
"\u001b[32;1m\u001b[1;3m[{'m.name': 'The Godfather: Part II'}]\u001b[0m\n",
|
|
||||||
"\n",
|
|
||||||
"\u001b[1m> Finished chain.\u001b[0m\n"
|
|
||||||
]
|
]
|
||||||
},
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"{'query': 'Robert De Niro played in which movies?',\n",
|
|
||||||
" 'result': 'Robert De Niro played in The Godfather: Part II.'}"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 12,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"source": [
|
"source": [
|
||||||
"chain.invoke(\"Robert De Niro played in which movies?\")"
|
"graph.refresh_schema()\n",
|
||||||
|
"\n",
|
||||||
|
"print(graph.get_schema)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## Use separate LLMs for Cypher and answer generation\n",
|
||||||
|
"\n",
|
||||||
|
"You can specify `cypher_llm` and `qa_llm` separately to use different LLMs for Cypher generation and answer generation."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 13,
|
"execution_count": 13,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [],
|
||||||
{
|
|
||||||
"name": "stdout",
|
|
||||||
"output_type": "stream",
|
|
||||||
"text": [
|
|
||||||
"\n",
|
|
||||||
"\n",
|
|
||||||
"\u001b[1m> Entering new KuzuQAChain chain...\u001b[0m\n",
|
|
||||||
"Generated Cypher:\n",
|
|
||||||
"\u001b[32;1m\u001b[1;3mMATCH (:Person)-[:ActedIn]->(:Movie {name: 'Godfather: Part II'})\n",
|
|
||||||
"RETURN count(*)\u001b[0m\n",
|
|
||||||
"Full Context:\n",
|
|
||||||
"\u001b[32;1m\u001b[1;3m[{'COUNT_STAR()': 0}]\u001b[0m\n",
|
|
||||||
"\n",
|
|
||||||
"\u001b[1m> Finished chain.\u001b[0m\n"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"{'query': 'How many actors played in the Godfather: Part II?',\n",
|
|
||||||
" 'result': \"I don't know the answer.\"}"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 13,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
"source": [
|
||||||
"chain.invoke(\"How many actors played in the Godfather: Part II?\")"
|
"chain = KuzuQAChain.from_llm(\n",
|
||||||
|
" cypher_llm=ChatOpenAI(temperature=0, model=\"gpt-4o-mini\"),\n",
|
||||||
|
" qa_llm=ChatOpenAI(temperature=0, model=\"gpt-4\"),\n",
|
||||||
|
" graph=graph,\n",
|
||||||
|
" verbose=True,\n",
|
||||||
|
" allow_dangerous_requests=True,\n",
|
||||||
|
")"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -341,12 +376,9 @@
|
|||||||
"\n",
|
"\n",
|
||||||
"\u001b[1m> Entering new KuzuQAChain chain...\u001b[0m\n",
|
"\u001b[1m> Entering new KuzuQAChain chain...\u001b[0m\n",
|
||||||
"Generated Cypher:\n",
|
"Generated Cypher:\n",
|
||||||
"\u001b[32;1m\u001b[1;3mMATCH (p:Person)-[:ActedIn]->(m:Movie {name: 'The Godfather: Part II'})\n",
|
"\u001b[32;1m\u001b[1;3mMATCH (p:Person)-[:IS_CEO_OF]->(c:Company {id: 'Apple'}) RETURN p.id, p.type\u001b[0m\n",
|
||||||
"RETURN p.name\n",
|
|
||||||
"ORDER BY p.birthDate ASC\n",
|
|
||||||
"LIMIT 1\u001b[0m\n",
|
|
||||||
"Full Context:\n",
|
"Full Context:\n",
|
||||||
"\u001b[32;1m\u001b[1;3m[{'p.name': 'Al Pacino'}]\u001b[0m\n",
|
"\u001b[32;1m\u001b[1;3m[{'p.id': 'Tim Cook', 'p.type': 'entity'}]\u001b[0m\n",
|
||||||
"\n",
|
"\n",
|
||||||
"\u001b[1m> Finished chain.\u001b[0m\n"
|
"\u001b[1m> Finished chain.\u001b[0m\n"
|
||||||
]
|
]
|
||||||
@ -354,8 +386,8 @@
|
|||||||
{
|
{
|
||||||
"data": {
|
"data": {
|
||||||
"text/plain": [
|
"text/plain": [
|
||||||
"{'query': 'Who is the oldest actor who played in The Godfather: Part II?',\n",
|
"{'query': 'Who is the CEO of Apple?',\n",
|
||||||
" 'result': 'Al Pacino is the oldest actor who played in The Godfather: Part II.'}"
|
" 'result': 'Tim Cook is the CEO of Apple.'}"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"execution_count": 14,
|
"execution_count": 14,
|
||||||
@ -364,104 +396,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"source": [
|
"source": [
|
||||||
"chain.invoke(\"Who is the oldest actor who played in The Godfather: Part II?\")"
|
"chain.invoke(\"Who is the CEO of Apple?\")"
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "markdown",
|
|
||||||
"metadata": {},
|
|
||||||
"source": [
|
|
||||||
"## Use separate LLMs for Cypher and answer generation\n",
|
|
||||||
"\n",
|
|
||||||
"You can specify `cypher_llm` and `qa_llm` separately to use different LLMs for Cypher generation and answer generation."
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 15,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "stderr",
|
|
||||||
"output_type": "stream",
|
|
||||||
"text": [
|
|
||||||
"/Users/prrao/code/langchain/.venv/lib/python3.11/site-packages/langchain_core/_api/deprecation.py:119: LangChainDeprecationWarning: The class `LLMChain` was deprecated in LangChain 0.1.17 and will be removed in 0.3.0. Use RunnableSequence, e.g., `prompt | llm` instead.\n",
|
|
||||||
" warn_deprecated(\n"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"chain = KuzuQAChain.from_llm(\n",
|
|
||||||
" cypher_llm=ChatOpenAI(temperature=0, model=\"gpt-3.5-turbo-16k\"),\n",
|
|
||||||
" qa_llm=ChatOpenAI(temperature=0, model=\"gpt-4\"),\n",
|
|
||||||
" graph=graph,\n",
|
|
||||||
" verbose=True,\n",
|
|
||||||
")"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 16,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "stdout",
|
|
||||||
"output_type": "stream",
|
|
||||||
"text": [
|
|
||||||
"\n",
|
|
||||||
"\n",
|
|
||||||
"\u001b[1m> Entering new KuzuQAChain chain...\u001b[0m\n"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "stderr",
|
|
||||||
"output_type": "stream",
|
|
||||||
"text": [
|
|
||||||
"/Users/prrao/code/langchain/.venv/lib/python3.11/site-packages/langchain_core/_api/deprecation.py:119: LangChainDeprecationWarning: The method `Chain.run` was deprecated in langchain 0.1.0 and will be removed in 0.2.0. Use invoke instead.\n",
|
|
||||||
" warn_deprecated(\n"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "stdout",
|
|
||||||
"output_type": "stream",
|
|
||||||
"text": [
|
|
||||||
"Generated Cypher:\n",
|
|
||||||
"\u001b[32;1m\u001b[1;3mMATCH (:Person)-[:ActedIn]->(:Movie {name: 'The Godfather: Part II'})\n",
|
|
||||||
"RETURN count(*)\u001b[0m\n",
|
|
||||||
"Full Context:\n",
|
|
||||||
"\u001b[32;1m\u001b[1;3m[{'COUNT_STAR()': 2}]\u001b[0m\n"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "stderr",
|
|
||||||
"output_type": "stream",
|
|
||||||
"text": [
|
|
||||||
"/Users/prrao/code/langchain/.venv/lib/python3.11/site-packages/langchain_core/_api/deprecation.py:119: LangChainDeprecationWarning: The method `Chain.__call__` was deprecated in langchain 0.1.0 and will be removed in 0.2.0. Use invoke instead.\n",
|
|
||||||
" warn_deprecated(\n"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "stdout",
|
|
||||||
"output_type": "stream",
|
|
||||||
"text": [
|
|
||||||
"\n",
|
|
||||||
"\u001b[1m> Finished chain.\u001b[0m\n"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"{'query': 'How many actors played in The Godfather: Part II?',\n",
|
|
||||||
" 'result': 'Two actors played in The Godfather: Part II.'}"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 16,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"chain.invoke(\"How many actors played in The Godfather: Part II?\")"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@ -481,7 +416,7 @@
|
|||||||
"name": "python",
|
"name": "python",
|
||||||
"nbconvert_exporter": "python",
|
"nbconvert_exporter": "python",
|
||||||
"pygments_lexer": "ipython3",
|
"pygments_lexer": "ipython3",
|
||||||
"version": "3.11.7"
|
"version": "3.13.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nbformat": 4,
|
"nbformat": 4,
|
||||||
|
@ -1,32 +1,40 @@
|
|||||||
# Kùzu
|
# Kùzu
|
||||||
|
|
||||||
>[Kùzu](https://kuzudb.com/) is a company based in Waterloo, Ontario, Canada.
|
> [Kùzu](https://kuzudb.com/) is an embeddable, scalable, extremely fast graph database.
|
||||||
> It provides a highly scalable, extremely fast, easy-to-use [embeddable graph database](https://github.com/kuzudb/kuzu).
|
> It is permissively licensed with an MIT license, and you can see its source code [here](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/).
|
||||||
|
|
||||||
|
|
||||||
## Installation and Setup
|
## Installation and Setup
|
||||||
|
|
||||||
You need to install the `kuzu` python package.
|
Install the Python SDK as follows:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pip install kuzu
|
pip install -U langchain-kuzu
|
||||||
```
|
```
|
||||||
|
|
||||||
## Graph database
|
## Usage
|
||||||
|
|
||||||
|
## Graphs
|
||||||
|
|
||||||
See a [usage example](/docs/integrations/graphs/kuzu_db).
|
See a [usage example](/docs/integrations/graphs/kuzu_db).
|
||||||
|
|
||||||
```python
|
```python
|
||||||
from langchain_community.graphs import KuzuGraph
|
from langchain_kuzu.graphs.kuzu_graph import KuzuGraph
|
||||||
```
|
```
|
||||||
|
|
||||||
## Chain
|
## Chains
|
||||||
|
|
||||||
See a [usage example](/docs/integrations/graphs/kuzu_db/#creating-kuzuqachain).
|
See a [usage example](/docs/integrations/graphs/kuzu_db/#creating-kuzuqachain).
|
||||||
|
|
||||||
```python
|
```python
|
||||||
from langchain.chains import KuzuQAChain
|
from langchain_kuzu.chains.graph_qa.kuzu import KuzuQAChain
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
@ -324,4 +324,8 @@ packages:
|
|||||||
- name: langchain-pull-md
|
- name: langchain-pull-md
|
||||||
path: .
|
path: .
|
||||||
repo: chigwell/langchain-pull-md
|
repo: chigwell/langchain-pull-md
|
||||||
downloads: 0
|
downloads: 0
|
||||||
|
- name: langchain-kuzu
|
||||||
|
path: .
|
||||||
|
repo: kuzudb/langchain-kuzu
|
||||||
|
downloads: 0
|
||||||
|
Loading…
Reference in New Issue
Block a user