跳到主要内容
Open In ColabOpen on GitHub

Ontotext GraphDB

Ontotext GraphDB 是一个图数据库和知识发现工具,符合 RDFSPARQL 标准。

本笔记本展示了如何使用 LLM 为 Ontotext GraphDB 提供自然语言查询(NLQ 到 SPARQL,也称为 text2sparql)。

GraphDB LLM 功能

GraphDB 支持一些 LLM 集成功能,如 此处 所述

gpt-queries

  • 使用来自您的知识图谱 (KG) 的数据,向 LLM 请求文本、列表或表格的魔法谓词
  • 查询解释
  • 结果解释、摘要、释义、翻译

retrieval-graphdb-connector

  • 在向量数据库中索引 KG 实体
  • 支持任何文本嵌入算法和向量数据库
  • 使用与 GraphDB 用于 Elastic、Solr、Lucene 的相同的强大连接器(索引)语言
  • RDF 数据中更改到 KG 实体索引的自动同步
  • 支持嵌套对象(GraphDB 10.5 版本中没有 UI 支持)
  • 将 KG 实体序列化为文本,如下所示(例如,对于 Wines 数据集)
Franvino:
- is a RedWine.
- made from grape Merlo.
- made from grape Cabernet Franc.
- has sugar dry.
- has year 2012.

talk-to-graph

  • 使用定义的 KG 实体索引的简单聊天机器人

在本教程中,我们不会使用 GraphDB LLM 集成,而是使用从 NLQ 生成 SPARQL。我们将使用您可以 在此处 检查的 Star Wars API (SWAPI) Ontology 和数据集。

设置

您需要一个正在运行的 GraphDB 实例。本教程展示了如何使用 GraphDB Docker 镜像 在本地运行数据库。它提供了一个 docker compose 设置,用 Star Wars 数据集填充 GraphDB。包括此笔记本在内的所有必要文件都可以从 GitHub 仓库 langchain-graphdb-qa-chain-demo 下载。

  • 安装 Docker。本教程是使用 Docker 版本 24.0.7 创建的,该版本捆绑了 Docker Compose。对于早期版本的 Docker,您可能需要单独安装 Docker Compose。
  • 在您机器的本地文件夹中克隆 GitHub 仓库 langchain-graphdb-qa-chain-demo
  • 使用从同一文件夹执行的以下脚本启动 GraphDB
docker build --tag graphdb .
docker compose up -d graphdb

您需要等待几秒钟才能在 http://localhost:7200/ 上启动数据库。Star Wars 数据集 starwars-data.trig 会自动加载到 langchain 仓库中。本地 SPARQL 端点 http://localhost:7200/repositories/langchain 可用于运行查询。您还可以从您最喜欢的 Web 浏览器 http://localhost:7200/sparql 打开 GraphDB Workbench,您可以在其中交互式地进行查询。

  • 设置工作环境

如果您使用 conda,请创建并激活一个新的 conda 环境,例如

conda create -n graph_ontotext_graphdb_qa python=3.12
conda activate graph_ontotext_graphdb_qa

安装以下库

pip install jupyter==1.1.1
pip install rdflib==7.1.1
pip install langchain-community==0.3.4
pip install langchain-openai==0.2.4

使用以下命令运行 Jupyter

jupyter notebook

指定 Ontology

为了使 LLM 能够生成 SPARQL,它需要知道知识图谱模式(Ontology)。可以使用 OntotextGraphDBGraph 类上的两个参数之一来提供它

  • query_ontology:在 SPARQL 端点上执行并返回 KG 模式语句的 CONSTRUCT 查询。我们建议您将 Ontology 存储在它自己的命名图中,这将更容易仅获取相关的语句(如下例所示)。不支持 DESCRIBE 查询,因为 DESCRIBE 返回对称简洁有界描述 (SCBD),即也返回传入的类链接。在具有数百万实例的大型图的情况下,这效率不高。查看 https://github.com/eclipse-rdf4j/rdf4j/issues/4857
  • local_file:本地 RDF Ontology 文件。支持的 RDF 格式为 TurtleRDF/XMLJSON-LDN-TriplesNotation-3TrigTrixN-Quads

在任何一种情况下,Ontology 转储都应

  • 包含关于类、属性、属性附加到类(使用 rdfs:domain, schema:domainIncludes或 OWL 限制)和分类法(重要的个体)的足够信息。
  • 不包括对于 SPARQL 构建没有帮助的过于冗长和不相关的定义和示例。
from langchain_community.graphs import OntotextGraphDBGraph

# feeding the schema using a user construct query

graph = OntotextGraphDBGraph(
query_endpoint="http://localhost:7200/repositories/langchain",
query_ontology="CONSTRUCT {?s ?p ?o} FROM <https://swapi.co/ontology/> WHERE {?s ?p ?o}",
)
# feeding the schema using a local RDF file

graph = OntotextGraphDBGraph(
query_endpoint="http://localhost:7200/repositories/langchain",
local_file="/path/to/langchain_graphdb_tutorial/starwars-ontology.nt", # change the path here
)

无论哪种方式,Ontology(模式)都以 Turtle 格式馈送到 LLM,因为带有适当前缀的 Turtle 是最紧凑且最容易让 LLM 记住的。

Star Wars Ontology 有点不寻常,因为它包含许多关于类的特定三元组,例如物种 :Aleena 生活在 <planet/38> 上,它们是 :Reptile 的子类,具有某些典型的特征(平均身高、平均寿命、肤色),并且特定个体(角色)是该类的代表

@prefix : <https://swapi.co/vocabulary/> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

:Aleena a owl:Class, :Species ;
rdfs:label "Aleena" ;
rdfs:isDefinedBy <https://swapi.co/ontology/> ;
rdfs:subClassOf :Reptile, :Sentient ;
:averageHeight 80.0 ;
:averageLifespan "79" ;
:character <https://swapi.co/resource/aleena/47> ;
:film <https://swapi.co/resource/film/4> ;
:language "Aleena" ;
:planet <https://swapi.co/resource/planet/38> ;
:skinColor "blue", "gray" .

...

为了使本教程简单易懂,我们使用未受保护的 GraphDB。如果 GraphDB 受到保护,您应该在初始化 OntotextGraphDBGraph 之前设置环境变量“GRAPHDB_USERNAME”和“GRAPHDB_PASSWORD”。

os.environ["GRAPHDB_USERNAME"] = "graphdb-user"
os.environ["GRAPHDB_PASSWORD"] = "graphdb-password"

graph = OntotextGraphDBGraph(
query_endpoint=...,
query_ontology=...
)

针对 StarWars 数据集的问题解答

我们现在可以使用 OntotextGraphDBQAChain 来提出一些问题。

import os

from langchain.chains import OntotextGraphDBQAChain
from langchain_openai import ChatOpenAI

# We'll be using an OpenAI model which requires an OpenAI API Key.
# However, other models are available as well:
# https://python.langchain.ac.cn/docs/integrations/chat/

# Set the environment variable `OPENAI_API_KEY` to your OpenAI API key
os.environ["OPENAI_API_KEY"] = "sk-***"

# Any available OpenAI model can be used here.
# We use 'gpt-4-1106-preview' because of the bigger context window.
# The 'gpt-4-1106-preview' model_name will deprecate in the future and will change to 'gpt-4-turbo' or similar,
# so be sure to consult with the OpenAI API https://platform.openai.com/docs/models for the correct naming.

chain = OntotextGraphDBQAChain.from_llm(
ChatOpenAI(temperature=0, model_name="gpt-4-1106-preview"),
graph=graph,
verbose=True,
allow_dangerous_requests=True,
)

让我们问一个简单的问题。

chain.invoke({chain.input_key: "What is the climate on Tatooine?"})[chain.output_key]


> Entering new OntotextGraphDBQAChain chain...
Generated SPARQL:
PREFIX : <https://swapi.co/vocabulary/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>

SELECT ?climate
WHERE {
?planet rdfs:label "Tatooine" ;
:climate ?climate .
}

> Finished chain.
'The climate on Tatooine is arid.'

和一个稍微复杂一点的问题。

chain.invoke({chain.input_key: "What is the climate on Luke Skywalker's home planet?"})[
chain.output_key
]


> Entering new OntotextGraphDBQAChain chain...
Generated SPARQL:
PREFIX : <https://swapi.co/vocabulary/>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>

SELECT ?climate
WHERE {
?character rdfs:label "Luke Skywalker" .
?character :homeworld ?planet .
?planet :climate ?climate .
}

> Finished chain.
"The climate on Luke Skywalker's home planet is arid."

我们还可以提出更复杂的问题,例如

chain.invoke(
{
chain.input_key: "What is the average box office revenue for all the Star Wars movies?"
}
)[chain.output_key]


> Entering new OntotextGraphDBQAChain chain...
Generated SPARQL:
PREFIX : <https://swapi.co/vocabulary/>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>

SELECT (AVG(?boxOffice) AS ?averageBoxOfficeRevenue)
WHERE {
?film a :Film .
?film :boxOffice ?boxOfficeValue .
BIND(xsd:decimal(?boxOfficeValue) AS ?boxOffice)
}


> Finished chain.
'The average box office revenue for all the Star Wars movies is approximately 754.1 million dollars.'

链修改器

Ontotext GraphDB QA 链允许提示改进,以进一步改进您的 QA 链并增强您的应用程序的整体用户体验。

“SPARQL 生成”提示

该提示用于基于用户问题和 KG 模式生成 SPARQL 查询。

  • sparql_generation_prompt

    默认值

      GRAPHDB_SPARQL_GENERATION_TEMPLATE = """
    Write a SPARQL SELECT query for querying a graph database.
    The ontology schema delimited by triple backticks in Turtle format is:
    ```
    {schema}
    ```
    Use only the classes and properties provided in the schema to construct the SPARQL query.
    Do not use any classes or properties that are not explicitly provided in the SPARQL query.
    Include all necessary prefixes.
    Do not include any explanations or apologies in your responses.
    Do not wrap the query in backticks.
    Do not include any text except the SPARQL query generated.
    The question delimited by triple backticks is:
    ```
    {prompt}
    ```
    """
    GRAPHDB_SPARQL_GENERATION_PROMPT = PromptTemplate(
    input_variables=["schema", "prompt"],
    template=GRAPHDB_SPARQL_GENERATION_TEMPLATE,
    )

“SPARQL 修复”提示

有时,LLM 可能会生成带有语法错误或缺少前缀等的 SPARQL 查询。链将尝试通过提示 LLM 在一定次数内进行纠正来修改此问题。

  • sparql_fix_prompt

    默认值

      GRAPHDB_SPARQL_FIX_TEMPLATE = """
    This following SPARQL query delimited by triple backticks
    ```
    {generated_sparql}
    ```
    is not valid.
    The error delimited by triple backticks is
    ```
    {error_message}
    ```
    Give me a correct version of the SPARQL query.
    Do not change the logic of the query.
    Do not include any explanations or apologies in your responses.
    Do not wrap the query in backticks.
    Do not include any text except the SPARQL query generated.
    The ontology schema delimited by triple backticks in Turtle format is:
    ```
    {schema}
    ```
    """

    GRAPHDB_SPARQL_FIX_PROMPT = PromptTemplate(
    input_variables=["error_message", "generated_sparql", "schema"],
    template=GRAPHDB_SPARQL_FIX_TEMPLATE,
    )
  • max_fix_retries

    默认值:5

“回答”提示

该提示用于基于从数据库返回的结果和初始用户问题来回答问题。默认情况下,指示 LLM 仅使用来自返回结果的信息。如果结果集为空,则 LLM 应告知它无法回答问题。

  • qa_prompt

    默认值

      GRAPHDB_QA_TEMPLATE = """Task: Generate a natural language response from the results of a SPARQL query.
    You are an assistant that creates well-written and human understandable answers.
    The information part contains the information provided, which you can use to construct an answer.
    The information provided is authoritative, you must never doubt it or try to use your internal knowledge to correct it.
    Make your response sound like the information is coming from an AI assistant, but don't add any information.
    Don't use internal knowledge to answer the question, just say you don't know if no information is available.
    Information:
    {context}

    Question: {prompt}
    Helpful Answer:"""
    GRAPHDB_QA_PROMPT = PromptTemplate(
    input_variables=["context", "prompt"], template=GRAPHDB_QA_TEMPLATE
    )

一旦您完成使用 GraphDB 进行 QA,您可以通过从带有 Docker compose 文件的目录运行 docker compose down -v --remove-orphans 来关闭 Docker 环境。


此页是否对您有帮助?