-
Notifications
You must be signed in to change notification settings - Fork 25
Inject additional information to a Qanary process
Control the behavior of your Qanary system by injecting additional triples into the Qanary triplestore
In this tutorial, we will show how to control the behavior of your Qanary system by injecting additional triples into the Qanary triplestore for a specific process. This is done by using the API provided by the Qanary system v3.7.0+. Typical use cases are the following:
-
you want to implement a chatbot where information from previous interactions with the user should be provided to the process handling the next question
-
you want to test the behavior of a specific component without executing a component that would provide required information
-
your Qanary system is deployed and running
-
here we assume that the Qanary system is deployed on a local machine on port 8080 (i.e., http://localhost:8080), hence, you need to change it in the following examples while using a different URL
-
-
some components are deployed and are connected to your Qanary system
-
here, we assume that the following components are available:
-
Note: This is a reduced environment. Typically, you would have more components deployed and connected to your Qanary system. Additionally, some frontend or chatbot would be integrated (e.g., as it is done here with a Rasa Chatbot or our related General Purpose Chatbot UI project).
The intention of our question answering process is to compute the real names of superheros as it was done here. However, here we assume the Qanary system is used as a backend for a chatbot, and we want to provide the superheros DBpedia URI (like Batman) from the previous interaction with the user. Hence, the interaction could be the following (created using our related project General Purpose Chatbot UI):
It would be obvious that the user wants to know the real name of Batman. Here, there we don’t have a complete question in the last interaction turn and, hence, we cannot compute the DBpedia URI for Batman as it is only available in the previous interaction turn. However, as the dialog management of the chatbot already knows the required information, we can inject the DBpedia URI into the Qanary triplestore. This is done by using the API provided by the Qanary system.
We assume here that it was already known by the chatbot that the DBpedia URI for Batman is http://dbpedia.org/resource/Batman. Hence, we need to inject this information into the Qanary triplestore by using the API provided by the Qanary system while starting the question answering process with the question "What is the real name of this superhero?".
To do this, we need to add the following annotation to the Qanary triplestore. You can image this as we are imitating the processing results of a previous Named Entity Recognition component (like NED-DBpediaSpotlight as it was done here). The triples representing the required data for correct processing of the component QB-SimpleRealNameOfSuperHero are:
PREFIX qa: <http://www.wdaqua.eu/qa#>
PREFIX oa: <http://www.w3.org/ns/openannotation/core/>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
<urn:qanary:my_manual_annotation> a qa:AnnotationOfInstance ;
qa:score ?score ;
oa:hasTarget <urn:1> .
<urn:1> a oa:SpecificResource;
oa:hasSource <urn:qanary:currentQuestion> ;
oa:hasSelector <urn:2>.
<urn:2> a oa:TextPositionSelector ;
oa:start "25"^^xsd:nonNegativeInteger ;
oa:end "30"^^xsd:nonNegativeInteger .
<urn:qanary:my_manual_annotation> oa:hasBody <http://dbpedia.org/resource/Batman> ;
oa:annotatedBy <urn:qanary:manual:data:injection> ;
oa:annotatedAt "2023-02-01T21:32:52"^^xsd:dateTime ;
qa:score "1.0"^^xsd:decimal .
Note:
-
no blank nodes are used (instead the resources
urn:1
andurn:2
) in this triples as they might cause problems (test this with your triplestore) -
as we don’t know the question resource at the beginning, we use the resource
urn:qanary:currentQuestion
as the source of the annotation -
the property
oa:annotatedBy
is set to a fixed value -
the property
qa:score
is set to1.0
as we assume that the manually added annotation is correct
These triples are injected into the Qanary triplestore by adding it to the JSON message used for triggering the start of a Qanary processing of a question.
We use the field additionalTriples
for this purpose.
The JSON message would look like this:
{
"question": "What is the real name of this superhero?",
"componentlist": ["QB-SimpleRealNameOfSuperHero","SparqlExecuter"],
"additionalTriples": "PREFIX qa: <http://www.wdaqua.eu/qa#> \nPREFIX oa: <http://www.w3.org/ns/openannotation/core/> \nPREFIX xsd: <http://www.w3.org/2001/XMLSchema#> \n\n<urn:qanary:my_manual_annotation> a qa:AnnotationOfInstance ;\n qa:score ?score ;\n oa:hasTarget <urn:1> .\n<urn:1> a\noa:SpecificResource;\n oa:hasSource <urn:qanary:currentQuestion> ;\n oa:hasSelector <urn:2>.\n<urn:2> a oa:TextPositionSelector ;\n oa:start \"25\"^^xsd:nonNegativeInteger ;\n oa:end \"30\"^^xsd:nonNegativeInteger .\n<urn:qanary:my_manual_annotation>\noa:hasBody <http://dbpedia.org/resource/Batman> ;\n oa:annotatedBy <urn:qanary:manual:data:injection> ;\n oa:annotatedAt \"2023-02-01T21:32:52\"^^xsd:dateTime ;\n qa:score \"1.0\"^^xsd:decimal .\n "
}
This JSON message is sent to the Qanary system using the API provided by the Qanary system: http://localhost:8080/startquestionansweringwithtextquestion.
A complete curl command might look like this (obviously, you could run an equal command in the programming language of choice):
curl --location --request POST 'http://localhost:8080/startquestionansweringwithtextquestion' \
--header 'Content-Type: application/json' \
--data-raw '{
"question": "Where was Albert Einstein born?",
"componentlist": ["QB-SimpleRealNameOfSuperHero","SparqlExecuter" ],
"additionalTriples": "PREFIX qa: <http://www.wdaqua.eu/qa#> \nPREFIX oa: <http://www.w3.org/ns/openannotation/core/> \nPREFIX xsd: <http://www.w3.org/2001/XMLSchema#> \n\n<urn:qanary:my_manual_annotation> a qa:AnnotationOfInstance ;\n qa:score ?score ;\n oa:hasTarget <urn:1> .\n<urn:1> a\noa:SpecificResource;\n oa:hasSource <urn:qanary:currentQuestion> ;\n oa:hasSelector <urn:2>.\n<urn:2> a oa:TextPositionSelector ;\n oa:start \"25\"^^xsd:nonNegativeInteger ;\n oa:end \"30\"^^xsd:nonNegativeInteger .\n<urn:qanary:my_manual_annotation>\noa:hasBody <http://dbpedia.org/resource/Batman> ;\n oa:annotatedBy <urn:qanary:manual:data:injection> ;\n oa:annotatedAt \"2023-02-01T21:32:52\"^^xsd:dateTime ;\n qa:score \"1.0\"^^xsd:decimal .\n"
}'
The execution of the command would provide to you the typical Qanary process information, e.g.:
{
"endpoint": "http://localhost:8080/sparql",
"inGraph": "urn:graph:f5a12964-a3cb-468f-8ae8-4a94dec507ec",
"outGraph": "urn:graph:f5a12964-a3cb-468f-8ae8-4a94dec507ec",
"question": "http://localhost:8080/question/stored-question__text_579a8efb-5ae0-49cd-bee0-8bfec34e7199"
}
You might check the results of your Qanary process using a SPARQL query on the SPARQL endpoint of your Qanary system (here, it would be the endpoint http://localhost:8080/sparql and the graph urn:graph:f5a12964-a3cb-468f-8ae8-4a94dec507ec
):
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX oa: <http://www.w3.org/ns/openannotation/core/>
PREFIX qa: <http://www.wdaqua.eu/qa#>
SELECT *
FROM <urn:graph:f5a12964-a3cb-468f-8ae8-4a94dec507ec>
WHERE {
?annotationId rdf:type ?type .
?annotationId oa:hasTarget ?target .
?annotationId oa:annotatedBy ?annotatorBy .
?annotationId oa:annotatedAt ?annotatorAt .
?annotationId oa:hasBody ?body .
OPTIONAL { ?body ?propery ?value . }
}
Here, the component SparqlExecuter
should have created the value
:
{
"head":{
"vars":[
"resource",
"answer",
"label"
]
},
"results":{
"bindings":[
{
"resource":{
"type":"uri",
"value":"http://dbpedia.org/resource/Batman"
},
"answer":{
"type":"literal",
"xml:lang":"en",
"value":"Bruce Wayne"
},
"label":{
"type":"literal",
"xml:lang":"en",
"value":"Batman"
}
}
]
}
}
-
How to establish a Docker-based Qanary Question Answering system
-
How to implement a new Qanary component
... using Java?
... using Python (Qanary Helpers)?
... using Python (plain Flask service)?