跳到主要內容
Open In ColabOpen on GitHub

Kuzu

Kùzu 是一個可嵌入、可擴展、極快速的圖形資料庫。它已獲得 MIT 許可證的許可,您可以在這裡查看其原始碼。

Kùzu 的主要特性

  • 效能和可擴展性:為圖形實現現代、最先進的連接演算法。
  • 易用性:非常容易設定和開始使用,因為沒有伺服器(嵌入式架構)。
  • 互操作性:可以方便地掃描和複製來自外部列式格式、CSV、JSON 和關聯式資料庫的資料。
  • 結構化屬性圖模型:實現屬性圖模型,並增加了結構。
  • Cypher 支援:允許使用宣告式查詢語言 Cypher 方便地查詢圖形。

造訪他們的文檔以開始使用 Kùzu。

設定

Kùzu 是一個嵌入式資料庫(它在進程內執行),因此無需管理伺服器。安裝以下依賴項以開始使用

pip install -U langchain-kuzu langchain-openai langchain-experimental

這會安裝 Kùzu 及其 LangChain 整合,以及 OpenAI Python 套件,以便我們可以使用 OpenAI 的 LLM。如果您想使用其他 LLM 提供商,您可以安裝 LangChain 隨附的各自的 Python 套件。

以下是如何在您的本機電腦上首先建立 Kùzu 資料庫並連接到它

import kuzu

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

建立 KuzuGraph

Kùzu 與 LangChain 的整合使其可以方便地從非結構化文字建立和更新圖形,也可以透過 Text2Cypher 管道查詢圖形,該管道利用了 LangChain 的 LLM 鏈的力量。首先,我們建立一個 KuzuGraph 物件,該物件使用我們上面建立的資料庫物件,並結合 KuzuGraph 建構函式。

from langchain_kuzu.graphs.kuzu_graph import KuzuGraph

graph = KuzuGraph(db, allow_dangerous_requests=True)

假設我們想要將以下文字轉換為圖形

text = "Tim Cook is the CEO of Apple. Apple has its headquarters in California."

我們將使用 LLMGraphTransformer 來使用 LLM 從文字中提取節點和關係。為了使圖形更有用,我們將定義以下架構,以便 LLM 僅提取與架構匹配的節點和關係。

# Define schema
allowed_nodes = ["Person", "Company", "Location"]
allowed_relationships = [
("Person", "IS_CEO_OF", "Company"),
("Company", "HAS_HEADQUARTERS_IN", "Location"),
]

LLMGraphTransformer 類別提供了一種將文字轉換為圖形文檔列表的便捷方法。

from langchain_core.documents import Document
from langchain_experimental.graph_transformers import LLMGraphTransformer
from langchain_openai import ChatOpenAI

# Define the LLMGraphTransformer
llm_transformer = LLMGraphTransformer(
llm=ChatOpenAI(model="gpt-4o-mini", temperature=0, api_key=OPENAI_API_KEY), # noqa: F821
allowed_nodes=allowed_nodes,
allowed_relationships=allowed_relationships,
)

documents = [Document(page_content=text)]
graph_documents = llm_transformer.convert_to_graph_documents(documents)
API 參考文檔:文檔 | LLMGraphTransformer | ChatOpenAI
graph_documents[:2]
[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.'))]

然後,我們可以呼叫上面定義的 KuzuGraph 物件的 add_graph_documents 方法,將圖形文檔攝取到 Kùzu 資料庫中。include_source 參數設定為 True,以便我們也在每個實體節點和它來自的來源文檔之間建立關係。

# Add the graph document to the graph
graph.add_graph_documents(
graph_documents,
include_source=True,
)

建立 KuzuQAChain

為了透過 Text2Cypher 管道查詢圖形,我們可以定義一個 KuzuQAChain 物件。然後,我們可以透過連接到儲存在上面定義的 test_db 目錄中的現有資料庫,使用查詢來調用鏈。

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-4o-mini", temperature=0.3, api_key=OPENAI_API_KEY), # noqa: F821
graph=graph,
verbose=True,
allow_dangerous_requests=True,
)

請注意,我們將溫度設定為略高於零,以避免 LLM 在其回應中過於簡潔。

讓我們使用 QA 鏈提出一些問題。

chain.invoke("Who is the CEO of Apple?")


> 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.
{'query': 'Who is the CEO of Apple?',
'result': 'Tim Cook is the CEO of Apple.'}
chain.invoke("Where is Apple headquartered?")


> 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.
{'query': 'Where is Apple headquartered?',
'result': 'Apple is headquartered in California.'}

刷新圖形架構

如果您變更或更新圖形,您可以檢查刷新後的架構資訊,Text2Cypher 鏈使用該資訊來產生 Cypher 語句。您不需要每次都手動呼叫 refresh_schema(),因為在您調用鏈時會自動呼叫它。

graph.refresh_schema()

print(graph.get_schema)
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)']

為 Cypher 和答案生成使用單獨的 LLM

您可以分別指定 cypher_llmqa_llm,以便為 Cypher 生成和答案生成使用不同的 LLM。

chain = KuzuQAChain.from_llm(
cypher_llm=ChatOpenAI(temperature=0, model="gpt-4o-mini"),
qa_llm=ChatOpenAI(temperature=0, model="gpt-4"),
graph=graph,
verbose=True,
allow_dangerous_requests=True,
)
chain.invoke("Who is the CEO of Apple?")


> 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.
{'query': 'Who is the CEO of Apple?',
'result': 'Tim Cook is the CEO of Apple.'}

此頁面是否對您有幫助?