跳到主要內容
Open In ColabOpen on GitHub

Amazon Neptune with SPARQL

Amazon Neptune 是一個高效能圖形分析和無伺服器資料庫,提供卓越的可擴展性和可用性。

此範例展示 QA 鏈,其使用 SPARQL 查詢語言查詢 Amazon Neptune 圖形資料庫中的 Resource Description Framework (RDF) 資料,並傳回人類可讀的回應。

SPARQLRDF 圖形的標準查詢語言。

此範例使用 NeptuneRdfGraph 類別,其連接 Neptune 資料庫並載入其結構描述。create_neptune_sparql_qa_chain 用於連接圖形和 LLM,以詢問自然語言問題。

此筆記本示範使用組織資料的範例。

執行此筆記本的需求

  • 可從此筆記本存取的 Neptune 1.2.x 叢集
  • 具有 Python 3.9 或更高版本的核心
  • 對於 Bedrock 存取,請確保 IAM 角色具有此政策
{
"Action": [
"bedrock:ListFoundationModels",
"bedrock:InvokeModel"
],
"Resource": "*",
"Effect": "Allow"
}
  • 用於暫存範例資料的 S3 儲存桶。儲存桶應與 Neptune 位於相同的帳戶/區域。

設定

植入 W3C 組織資料

植入 W3C 組織資料、W3C 組織本體以及一些實例。

您將需要在與 Neptune 叢集相同的區域和帳戶中建立 S3 儲存桶。將 STAGE_BUCKET 設定為該儲存桶的名稱。

STAGE_BUCKET = "<bucket-name>"
%%bash  -s "$STAGE_BUCKET"

rm -rf data
mkdir -p data
cd data
echo getting org ontology and sample org instances
wget http://www.w3.org/ns/org.ttl
wget https://raw.githubusercontent.com/aws-samples/amazon-neptune-ontology-example-blog/main/data/example_org.ttl

echo Copying org ttl to S3
aws s3 cp org.ttl s3://$1/org.ttl
aws s3 cp example_org.ttl s3://$1/example_org.ttl

我們將使用來自 graph-notebook 套件的 %load magic 命令,將 W3C 資料插入 Neptune 圖形中。在執行 %load 之前,請使用 %%graph_notebook_config 設定圖形連線參數。

!pip install --upgrade --quiet graph-notebook
%load_ext graph_notebook.magics
%%graph_notebook_config
{
"host": "<neptune-endpoint>",
"neptune_service": "neptune-db",
"port": 8182,
"auth_mode": "<[DEFAULT|IAM]>",
"load_from_s3_arn": "<neptune-cluster-load-role-arn>",
"ssl": true,
"aws_region": "<region>"
}

大量載入 org ttl - 本體和實例。

%load -s s3://{STAGE_BUCKET} -f turtle --store-to loadres --run
%load_status {loadres['payload']['loadId']} --errors --details

設定鏈

!pip install --upgrade --quiet langchain-aws

** 重新啟動核心 **

準備範例

EXAMPLES = """

<question>
Find organizations.
</question>

<sparql>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX org: <http://www.w3.org/ns/org#>

select ?org ?orgName where {{
?org rdfs:label ?orgName .
}}
</sparql>

<question>
Find sites of an organization
</question>

<sparql>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX org: <http://www.w3.org/ns/org#>

select ?org ?orgName ?siteName where {{
?org rdfs:label ?orgName .
?org org:hasSite/rdfs:label ?siteName .
}}
</sparql>

<question>
Find suborganizations of an organization
</question>

<sparql>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX org: <http://www.w3.org/ns/org#>

select ?org ?orgName ?subName where {{
?org rdfs:label ?orgName .
?org org:hasSubOrganization/rdfs:label ?subName .
}}
</sparql>

<question>
Find organizational units of an organization
</question>

<sparql>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX org: <http://www.w3.org/ns/org#>

select ?org ?orgName ?unitName where {{
?org rdfs:label ?orgName .
?org org:hasUnit/rdfs:label ?unitName .
}}
</sparql>

<question>
Find members of an organization. Also find their manager, or the member they report to.
</question>

<sparql>
PREFIX org: <http://www.w3.org/ns/org#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>

select * where {{
?person rdf:type foaf:Person .
?person org:memberOf ?org .
OPTIONAL {{ ?person foaf:firstName ?firstName . }}
OPTIONAL {{ ?person foaf:family_name ?lastName . }}
OPTIONAL {{ ?person org:reportsTo ??manager }} .
}}
</sparql>


<question>
Find change events, such as mergers and acquisitions, of an organization
</question>

<sparql>
PREFIX org: <http://www.w3.org/ns/org#>

select ?event ?prop ?obj where {{
?org rdfs:label ?orgName .
?event rdf:type org:ChangeEvent .
?event org:originalOrganization ?origOrg .
?event org:resultingOrganization ?resultingOrg .
}}
</sparql>

"""

建立 Neptune 資料庫 RDF 圖形

from langchain_aws.graphs import NeptuneRdfGraph

host = "<your host>"
port = 8182 # change if different
region = "us-east-1" # change if different
graph = NeptuneRdfGraph(host=host, port=port, use_iam_auth=True, region_name=region)

# Optionally, change the schema
# elems = graph.get_schema_elements
# change elems ...
# graph.load_schema(elems)
API 參考文檔:NeptuneRdfGraph

使用 Neptune SPARQL QA 鏈

此 QA 鏈使用 SPARQL 查詢 Neptune 圖形資料庫,並傳回人類可讀的回應。

from langchain_aws import ChatBedrockConverse
from langchain_aws.chains import create_neptune_sparql_qa_chain

MODEL_ID = "anthropic.claude-3-5-sonnet-20241022-v2:0"
llm = ChatBedrockConverse(
model_id=MODEL_ID,
temperature=0,
)

chain = create_neptune_sparql_qa_chain(
llm=llm,
graph=graph,
examples=EXAMPLES,
)

result = chain.invoke("How many organizations are in the graph?")
print(result["result"].content)

以下是一些更多提示,可在已擷取的圖形資料上嘗試。

result = chain.invoke("Are there any mergers or acquisitions?")
print(result["result"].content)
result = chain.invoke("Find organizations.")
print(result["result"].content)
result = chain.invoke("Find sites of MegaSystems or MegaFinancial.")
print(result["result"].content)
result = chain.invoke("Find a member who is a manager of one or more members.")
print(result["result"].content)
result = chain.invoke("Find five members and their managers.")
print(result["result"].content)
result = chain.invoke(
"Find org units or suborganizations of The Mega Group. What are the sites of those units?"
)
print(result["result"].content)

新增訊息歷史記錄

Neptune SPARQL QA 鏈能夠由 RunnableWithMessageHistory 包裝。這將訊息歷史記錄新增至鏈,讓我們能夠建立一個聊天機器人,在多次調用之間保留對話狀態。

首先,我們需要一種儲存和載入訊息歷史記錄的方法。為此,每個執行緒都將建立為 InMemoryChatMessageHistory 的實例,並儲存到字典中以供重複存取。

(另請參閱:https://langchain-python.dev.org.tw/docs/versions/migrating_memory/chat_history/#chatmessagehistory)

from langchain_core.chat_history import InMemoryChatMessageHistory

chats_by_session_id = {}


def get_chat_history(session_id: str) -> InMemoryChatMessageHistory:
chat_history = chats_by_session_id.get(session_id)
if chat_history is None:
chat_history = InMemoryChatMessageHistory()
chats_by_session_id[session_id] = chat_history
return chat_history
API 參考文檔:InMemoryChatMessageHistory

現在,QA 鏈和訊息歷史記錄儲存可用於建立新的 RunnableWithMessageHistory。請注意,我們必須將 query 設定為輸入金鑰,以符合基礎鏈預期的格式。

from langchain_core.runnables.history import RunnableWithMessageHistory

runnable_with_history = RunnableWithMessageHistory(
chain,
get_chat_history,
input_messages_key="query",
)
API 參考文檔:RunnableWithMessageHistory

在調用鏈之前,需要為新的 InMemoryChatMessageHistory 將記住的對話產生唯一的 session_id

import uuid

session_id = uuid.uuid4()

最後,使用 session_id 調用啟用訊息歷史記錄的鏈。

result = runnable_with_history.invoke(
{"query": "How many org units or suborganizations does the The Mega Group have?"},
config={"configurable": {"session_id": session_id}},
)
print(result["result"].content)

當繼續使用相同的 session_id 調用鏈時,回應將在對話中先前查詢的上下文中傳回。

result = runnable_with_history.invoke(
{"query": "List the sites for each of the units."},
config={"configurable": {"session_id": session_id}},
)
print(result["result"].content)

此頁面是否對您有幫助?