Being able to utilize SPARQL Query Templates to fine-tune ChatGPT (3.5 or 4.0) is a remarkably powerful and delightful surprise. In this post, I provide live examples of using this functionality to enhance the discovery of data across knowledge graphs associated with SPARQL Query Service endpoints.
It’s important to note that live SPARQL Query Service endpoints across the LOD Cloud Knowledge Graph have been in place since 2007. As part of the Linked Data effort to reorient the notion of a Semantic Web back to the Web, courtesy of Linked Data principles, they have been growing in size, quality, and uptime stealthily. Today, they offer vital infrastructure that reinforces the symbiotic relationship between Large Language Model (LLM)-based Natural Language processors and the idea of a Semantic Web, usable publicly or privately.
Here’s a generic SPARQL Query that enables the discovery of an aggregate of entity types associated with a sample of entities existing in a Knowledge Graph accessible via a SPARQL Query Services endpoint:
SELECT (SAMPLE(?s) AS ?EntityID)
(COUNT(*) AS ?count)
(?o AS ?EntityTypeID)
FROM <urn:schemaorg:data:abox>
WHERE { ?s a ?o . FILTER (CONTAINS(STR(?o),'schema'))} GROUP BY ?o ORDER BY DESC (?count)
I will use this query as the foundation of the templates used in this post.
Transcript
Q: Load the following templates.
Provide a starting point for exploring knowledge graph <G> using schema.org terms;SELECT (SAMPLE(?s) AS ?EntityID) (COUNT(*) AS ?count) (?o AS ?EntityTypeID) FROM <G> WHERE { ?s a ?o . FILTER (CONTAINS(STR(?o),'schema.org'))} GROUP BY ?o ORDER BY DESC (?count) ; Provide a starting point for exploring schema:offers associated with knowledge graph <G> using schema.org terms;SELECT (SAMPLE(?s) AS ?EntityID) (COUNT(*) AS ?count) (?o AS ?EntityTypeID) FROM <G> WHERE { ?s a ?o . FILTER (CONTAINS(STR(?o),'schema.org/Offer'))} GROUP BY ?o ORDER BY DESC (?count) ; Provide a starting point for exploring across all knowledge graphs using schema.org terms;SELECT (SAMPLE(?s) AS ?EntityID) (COUNT(*) AS ?count) (?o AS ?EntityTypeID) WHERE { ?s a ?o . FILTER (CONTAINS(STR(?o),'schema.org'))} GROUP BY ?o ORDER BY DESC (?count) ; Provide a starting point for exploring knowledge graph <G>;SELECT (SAMPLE(?s) AS ?EntityID) (COUNT(*) AS ?count) (?o AS ?EntityTypeID) FROM <G> WHERE { ?s a ?o . } GROUP BY ?o ORDER BY DESC (?count) ; Provide a starting point for exploring across all knowledge graphs;SELECT (SAMPLE(?s) AS ?EntityID) (COUNT(*) AS ?count) (?o AS ?EntityTypeID) WHERE { ?s a ?o . } GROUP BY ?o ORDER BY DESC (?count) ; -- Problematic -- Provide a starting point for exploring across all knowledge graphs, with sponging enabled;DEFINE get:soft "soft" SELECT (SAMPLE(?s) AS ?EntityID) (COUNT(*) AS ?count) (?o AS ?EntityTypeID) WHERE { ?s a ?o . } GROUP BY ?o ORDER BY DESC (?count) ; # Introspection Query with Built-in rdfs:subClassOf Inference DEFINE input:inference "urn:rdfs:subclass:subproperty:inference:rules" SELECT (SAMPLE(?s) AS ?EntityID) (COUNT(*) AS ?count) (?o AS ?EntityTypeID) FROM <urn:schemaorg:data:abox> WHERE { ?s a ?o . FILTER (CONTAINS(STR(?o),'schema'))} GROUP BY ?o ORDER BY DESC (?count) ## Derived Templates -- Built-in Reasoning & Inference ### Across all Vocabularies Provide a starting point for exploring knowledge graph <G> with subClassOf reasoning enabled;DEFINE input:inference "urn:rdfs:subclass:subproperty:inference:rules" SELECT (SAMPLE(?s) AS ?EntityID) (COUNT(*) AS ?count) (?o AS ?EntityTypeID) FROM <G> WHERE { ?s a ?o.} GROUP BY ?o ORDER BY DESC (?count) ; ### Scoped to Schema.org Provide a starting point for exploring knowledge graph <G> using schema.org terms with subClassOf reasoning enabled;DEFINE input:inference "urn:rdfs:subclass:subproperty:inference:rules" SELECT (SAMPLE(?s) AS ?EntityID) (COUNT(*) AS ?count) (?o AS ?EntityTypeID) FROM <G> WHERE { ?s a ?o . FILTER (CONTAINS(STR(?o),'schema.org'))} GROUP BY ?o ORDER BY DESC (?count) ; # Organization oriented queries SELECT (SAMPLE(?s) AS ?EntityID) (COUNT(*) AS ?count) (?o AS ?EntityTypeID) FROM <urn:schemaorg:data:abox> WHERE { ?s a ?o . FILTER (CONTAINS(STR(?s),'apple.com')) FILTER (CONTAINS(STR(?o),'schema'))} GROUP BY ?o ORDER BY DESC (?count) ## Derived Templates Provide a starting point for exploring an <Org> centric <Org> knowledge graph <G> using schema.org terms;SELECT (SAMPLE(?s) AS ?EntityID) (COUNT(*) AS ?count) (?o AS ?EntityTypeID) FROM <G> WHERE { ?s a ?o . FILTER (CONTAINS(STR(?s),'<Org>')) FILTER (CONTAINS(STR(?o),'schema.org'))} GROUP BY ?o ORDER BY DESC (?count) ; # Item Listing Queries ## Offers List offers and prices associated with knowledge graph <G>, using terms from schema.org;SELECT ?offer ?price FROM <G> WHERE { ?offer a schema:Offer; schema:price ?price .} ORDER BY ASC (?price) ; List offers and prices from <Org> associated with knowledge graph <G>, using terms from schema.org;SELECT ?offer ?price FROM <G> WHERE { ?offer a schema:Offer; schema:price ?price . FILTER (CONTAINS(STR(?offer),'<Org>'))} ORDER BY ASC (?price) ; ## Products & Offers List products associated with knowledge graph <G>, using terms from schema.org;SELECT ?product ?name ?offer ?price FROM <G> WHERE { ?product a schema:Product; schema:name ?name; (schema:offers | schema:itemOffered) ?offer. ?offer a schema:Offer; schema:price ?price .} ORDER BY ASC (?price) ; List products from <Org> associated with knowledge graph <G>, using terms from schema.org;SELECT ?product ?name ?offer ?price FROM <G> WHERE { ?product a schema:Product; schema:name ?name; (schema:offers | schema:itemOffered) ?offer. ?offer a schema:Offer; schema:price ?price . FILTER (CONTAINS(STR(?offer),'<Org>'))} ORDER BY ASC (?price) ; ## Products List products associated with knowledge graph <G>, using terms from schema.org;SELECT ?product ?name FROM <G> WHERE { ?product a schema:Product; schema:name ?name.} ORDER BY ASC (?name) ; List products from <Org> associated with knowledge graph <G>, using terms from schema.org;SELECT ?product ?name ?offer ?price FROM <G> WHERE { ?product a schema:Product; schema:name ?name. FILTER (CONTAINS(STR(?product),'<Org>'))} ORDER BY ASC (?price) ; ## FAQ Page List FAQs associated with knowledge graph <G>, using terms from schema.org;SELECT ?page ?question ?name ?answerText FROM <G> WHERE { ?page a schema:FAQPage; schema:mainEntity ?question. ?question (schema:name|schema:title) ?name; (schema:acceptedAnswer|schema:suggestedAnswer) ?answer. ?answer schema:text ?answerText.} ORDER BY ASC (?name) ; List FAQs from <Org> associated with knowledge graph <G>, using terms from schema.org;SELECT ?page ?question ?name ?answerText FROM <G> WHERE { ?page a schema:FAQPage; schema:mainEntity ?question. ?question (schema:name|schema:title) ?name; (schema:acceptedAnswer|schema:suggestedAnswer) ?answer. ?answer schema:text ?answerText. FILTER (CONTAINS(STR(?page),'<Org>'))} ORDER BY ASC (?name) ; ## Jobs List Job Postings associated with knowledge graph <G>, using terms from schema.org;SELECT DISTINCT ?job ?name FROM <G> WHERE { ?job a schema:JobPosting; (schema:name|schema:title) ?name. } ; List Job Postings from <Org> associated with knowledge graph <G>, using terms from schema.org;SELECT DISTINCT ?job ?name ?org FROM <G> WHERE { ?job a schema:JobPosting; (schema:name|schema:title) ?name; schema:hiringOrganization ?org . FILTER (CONTAINS(STR(?org),'<Org>'))} ;
GPT Generated Template additions
Q: Based on my current template collection, can you create an addition for schema:SearchAction class instances based on my the Products template?
A (GPT 4.0):
List SearchActions associated with knowledge graph , using terms from schema.org;SELECT ?action ?query ?target FROM WHERE { ?action a schema:SearchAction; schema:query ?query; schema:target ?target .} ORDER BY ASC (?query) ;
List SearchActions from associated with knowledge graph , using terms from schema.org;SELECT ?action ?query ?target FROM WHERE { ?action a schema:SearchAction; schema:query ?query; schema:target ?target. FILTER (CONTAINS(STR(?action),‘’))} ORDER BY ASC (?query) ;
Q: Using the recent FAQ related templates as guidelines, generate template variants for schema:HowTo instance that include HowToStep instance associations.
A:
Here are the templates for schema:HowTo instances that include schema:HowToStep instance associations:
List HowTo guides associated with knowledge graph , using terms from schema.org;
SELECT ?guide ?step ?name ?text FROM <G> WHERE {
?guide a schema:HowTo;
schema:step ?step.
?step (schema:name|schema:text) ?text.
?guide (schema:name|schema:title) ?name.
}
ORDER BY ASC(?name)
List HowTo guides from associated with knowledge graph , using terms from schema.org;
SELECT ?guide ?step ?name ?text FROM <G> WHERE {
?guide a schema:HowTo;
schema:step ?step.
?step (schema:name|schema:text) ?text.
?guide (schema:name|schema:title) ?name.
FILTER (CONTAINS(STR(?guide),'<Org>'))
}
ORDER BY ASC(?name)
Q: Generate an Ontology for my templates that includes an Template instance for schema:Recipe
A:
Sure, I can help generate an ontology that includes a Template instance for the schema:Recipe
class. Here is an example:
@prefix ont: <http://example.org/ontology/> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix schema: <http://schema.org/> .
ont: ont:Template rdf:type rdfs:Class .
ont:Prompt rdf:type rdfs:Class ; rdfs:subClassOf ont:Template .
ont:Response rdf:type rdfs:Class ; rdfs:subClassOf ont:Template .
ont:PromptRecipe rdf:type ont:Prompt ;
ont:hasUser ont:UserA ;
ont:hasInput "List recipes associated with knowledge graph <G>, using terms from schema.org;SELECT DISTINCT ?recipe ?name FROM <G> WHERE {?recipe a schema:Recipe; schema:name ?name.} ORDER BY ASC (?name);" ;
ont:hasResponse ont:Response4 .
ont:Response4 rdf:type ont:Response .
ont:PromptRecipeByOrg rdf:type ont:Prompt ;
ont:hasUser ont:UserA ;
ont:hasInput "List recipes from <Org> associated with knowledge graph <G>, using terms from schema.org;SELECT DISTINCT ?recipe ?name FROM <G> WHERE {?recipe a schema:Recipe; schema:name ?name. FILTER (CONTAINS(STR(?recipe),'<Org>'))} ORDER BY ASC (?recipe);" ;
ont:hasResponse ont:Response5 .
ont:Response5 rdf:type ont:Response .
This ontology defines two templates:
-
ont:PromptRecipe
for listing recipes from a knowledge graph -
ont:PromptRecipeByOrg
for listing recipes from a specific organization within a knowledge graph.
Please replace <G>
and <Org>
with the IRI of your knowledge graph and your organization respectively when using these templates. The FILTER
function in the second template is used to filter the results by the specified organization.
Q: Redo, but replace example.com with a relative hyperlinks using <#> .
A:
Sure, I can modify the ontology to use relative hyperlinks. Here’s the revised ontology:
## Turtle Start ##
@prefix : <#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix schema: <http://schema.org/> .
:Template rdf:type rdfs:Class .
:Prompt rdf:type rdfs:Class ; rdfs:subClassOf :Template .
:Response rdf:type rdfs:Class ; rdfs:subClassOf :Template .
:PromptRecipe rdf:type :Prompt ;
:hasUser :UserA ;
:hasInput "List recipes associated with knowledge graph <G>, using terms from schema.org;SELECT DISTINCT ?recipe ?name FROM <G> WHERE {?recipe a schema:Recipe; schema:name ?name.} ORDER BY ASC (?name);" ;
:hasResponse :Response4 .
:Response4 rdf:type :Response .
:PromptRecipeByOrg rdf:type :Prompt ;
:hasUser :UserA ;
:hasInput "List recipes from <Org> associated with knowledge graph <G>, using terms from schema.org;SELECT DISTINCT ?recipe ?name FROM <G> WHERE {?recipe a schema:Recipe; schema:name ?name. FILTER (CONTAINS(STR(?recipe),'<Org>'))} ORDER BY ASC (?recipe);" ;
:hasResponse :Response5 .
:Response5 rdf:type :Response .
## Turtle End ##
This version uses relative hyperlinks (i.e., <#>
) to define resources within the ontology. This is a common practice in RDF and is used when the base URL of the ontology is not known or can vary. In this case, the base URL will be the URL where the ontology is hosted.
GPT Generated SPARQL Template Ontology Screenshot 1
GPT Generate SPARQL Template Ontology Screenshot 2
Testing Natural Language Query using GPT Generated Templates
-
Using the newly added template, explore recipes using the knowledge graph urn:schemaorg:data:abox via the query service endpoint Protected SPARQL Query Service. Explore recipes
-
Redo, for recipes from epicurious.com. Recipes from epicurious.com
-
Ditto, for HowTos in general. Explore HowTos
-
Ditto, for HowTos from google.com. HowTos from google.com
Additional Sample Natural Language Queries Collection
These queries work with both GPT 3.5 and 4.0.
-
Explore web pages in the knowledge graph denoted by https://linkeddataorchestration.com/2023/05/11/foursquare-moves-to-the-future-with-a-geospatial-knowledge-graph/ using a clickable sparql query link with Protected SPARQL Query Service ans the endpoint. Explore Web Pag
-
Repeat, but for Books using the Knowledge Graph denoted by urn:schemaorg:data:abox. Explore Books
-
Ditto, but for Courses. Explore Courses
-
Ditto, Offers. Explore Offers
-
Ditto Products & Offers. Explore Products & Offers
-
Ditto Products only. Explore Products
-
Ditto Products from apple.com only. Products from apple.com
-
Using a clickable SPARQL link, explore Job Postings associated with Knowledge Graph urn:schemaorg:data:abox using endpoint Protected SPARQL Query Service. Explore Job Postings
-
Ditto Job Postings from microsoft.com. Explore Job Postings at microsoft.com
-
Generate a clickable SPARQL link for exploring FAQs associated with the Knowledge Graph denoted by
urn:schemaorg:data:abox
using query service endpoint athttps://linkeddata.uriburner.com/sparql
. Explore FAQs -
Ditto, for FAQs from
apple.com
. Explore FAQs from apple.com
Note:
You can also incorporate the following into your prompts to control the behavior of your hyperlink lookups, if you are targeting a Virtuoso-based endpoint with the Faceted Search & Browsing module installed:
Redo, setting the value of the &format
to text/x-html+tr
.
Tools Used
Combined Multi-Model Database & HTTP Server Technology
OpenLink Structured Data Sniffer – Multi-Browser Extension
- Google Chrome Store for Chromium-based Browsers
- Mozilla Store for Firefox
- Mac App Store for Safari
- Github Open Source Repository
Related
- LOD Cloud SPARQL Endpoints Spreadsheet
- Recent LinkedIn Post about LOD Cloud SPARQL Endpoints
- Generating a Prompt Ontology using ChatGPT
- Generating an Ontology and instance data, using RDF, that starts from a Mermaid Entity Relationship Model
- Executing Queries over the Web using ChatGPT via SPARQL Query Links
- Reasoning over RDF based Entity Relationships using ChatGPT
- OpenLink Community Forum Search Results for ChatGPT related HowTos