The Qanary Framework is dedicated to creating Question Answering systems. Question Answering (QA) is a task requiring different fields leading to expensive/time-consuming engineering tasks that might block research as it is too expensive. Typical problems/use cases that might occur while developing a Question Answering system are:
-
an algorithm requires analyzing textual questions and annotating the found entities, relations, classes, etc.
-
it is time-consuming as many services/algorithms/tools need to be compared
-
your QA process needs to be improved
-
following traditional development approaches requires additional efforts for testing and debugging of code to uncover possible flaws
-
the quality of components dedicated to a particular task needs to be analyzed
-
it is expensive to integrate all of the particular components due to a missing generalized interface
In this repository, the components of the Qanary framework are stored. All components are implemented in Java or Python, and provide a Docker container for lightweight maintenance.
- Status: migration to the current Qanary framework (4.0.0)
- Build and run a minimal set of components
- Big Picture
- How to Cite
- Qanary Components
- Automatic Speech Recognition (ASR)
- Language Detection (LD)
- Machine Translation (MT)
- Named Entity Recognition (NER)
- Named Entity Disambiguation / Entity Linking (NED)
- Named Entity Recognition and Disambiguation (NERD)
- Class Linking / Classification (CLS)
- Relation Linking (REL)
- Relation Detection (RD)
- Question Classification (QC)
- Expected Answer Type (EAT)
- Query Building (QB)
- Query Building and Execution (QBE)
- Query Execution (QE)
- Knowledge-graph translation (KG2KG)
- Textual Question Answering (TQA)
- Utility
- Question classification (legacy)
- Tooling and non-components
All Java Question Answering components in this repository have been migrated to
the current Qanary framework 4.0.0 (Spring Boot 3, Java 21, Apache Jena 5).
(They previously targeted the legacy Spring Boot 2 / Qanary 3.x framework — parent
qa.qanarycomponent-parent [0.1.0,1.0.0), qanary.version [3.x,4.0.0).) The only
non-migrated module is the standalone dev tool qanary_docker-compose-writer,
which is not a Spring Boot Qanary component.
Most components build + pass their tests on a clean offline build. The
following wrap keyed/remote services or load NLP models, so they are verified
to build + package but their *LiveTest / cache / full-context @SpringBootTest
tests require API keys, network access or model files (as was already the case on
3.x) — run those with credentials, or mvn … -DskipTests offline:
NED-Aylien, NED-Babelfy, NED-Dandelion, NED-MeaningCloud, NED-OpenAI-GPT,
NER-Dandelion, NER-MeaningCloud, NER-Stanford, NER-Tagme, NER-TextRazor,
REL-RelationLinker1, REL-RelationLinker2, TQA-ChatGPTWrapper.
The framework artifacts (qa.component, qa.commons) are a local build of the
Qanary repository (mvn install), not published
to Maven Central — so build the migrated components with JDK 21.
All 59 components were verified stepwise on eclipse-temurin:21-jre: build the jar
→ build the image → run the container → check startup → remove the container + image.
Result: every component’s image builds and the Spring Boot fat jar loads. 44
containers start cleanly (the Spring Boot Admin "connection refused" to a
non-running pipeline is logged but non-fatal). The 13 keyed/remote/model components
listed above fail to finish startup only because they validate an API key or
remote endpoint, or load model files, in a bean constructor at boot — expected
without those resources; they start normally once the service/key is reachable.
-
Replace the parent
eu.wdaqua.qanary:qa.qanarycomponent-parent [0.1.0,1.0.0)(Spring Boot 2) withorg.springframework.boot:spring-boot-starter-parent:3.5.15and depend oneu.wdaqua.qanary:qa.component:4.0.0(mirrors the 4.0.0 component template). Set<java.version>21</java.version>. -
Where the component exposes OpenAPI/Swagger, replace
springdoc-openapi-ui/springdoc-openapi-webmvc-core(1.x) withspringdoc-openapi-starter-webmvc-ui2.x (it providesio.swagger.v3.oas.*and the@Operationannotations). -
Fold the explicit JUnit 4/5, Hamcrest, Mockito,
spring-testandjson-pathtest dependencies into a singlespring-boot-starter-test(test scope); drop leftover JUnit 4 imports (org.junit.Ignore→ JUnit 5@Disabled). -
Drop the unmaintained
com.spotify:dockerfile-maven-plugin; set a stable<finalName>and build the image via theDockerfile(eclipse-temurin:21-jre). -
Fix Spring Boot 2→3 / Jena 4→5 fallout, e.g.
QueryExecutionFactory.sparqlService(endpoint, query)→QueryExecutionHTTP.service(endpoint).query(query).build(). Most credential-free components need no further code changes. -
Build clean (
mvn clean …): an earlier Spring Boot 2 build of a module weaves framework classes (the explainability aspect) intotarget/classesvia the old parent’s AspectJ plugin; stalejavax.servletclasses there would otherwise shadow the 4.0.0 (jakarta) ones at test time.
To show the Qanary methodology and its functionality a tiny template-based Question Answering system was designed. It is capable of answering questions for the real name of a superhero like "What is the real name of Captain America?". For this purpose, just two components were used:
a) Qanary DBpedia Spotlight component: The component is capable of finding superhero names and linking it to the DBpedia knowledge base (such a process is called Named Entity Recognition and Disambiguation).
b) Qanary Query Builder for Superhero Names: The component is capable of creating SPARQL SELECT queries to be executed on DBpedia (such a component is typically called Query Builder) if the given question is following the template What is the real name of <superheroname>.
Hence, given a question following the described pattern the result will be a SPARQL query that might be executed, s.t., the real name of a superhero is retrieved from DBpedia.
-
Clone the current repository:
git clone https://github.com/WDAqua/Qanary-question-answering-components.git
-
Switch to the folder
Qanary-question-answering-components:
cd Qanary-question-answering-components
-
Build the minimal set of components using the Maven profile "tinytutorial" (here we skip creating the corresponding Docker images by adding the parameter
-Ddockerfile.skip=trueto the Maven command):
mvn clean package -Ddockerfile.skip=true -P tinytutorial
-
The output should look like the following indicating that the component
qa.NED-DBpedia-Spotlight``and `qanary_component-QB-SimpleRealNameOfSuperHerowas created:
[INFO] ------------------------------------------------------------------------ [INFO] Reactor Summary: [INFO] [INFO] qa.NED-DBpedia-Spotlight 2.1.0 ..................... SUCCESS [ 3.717 s] [INFO] qanary_component-QB-SimpleRealNameOfSuperHero 2.0.0 SUCCESS [ 1.083 s] [INFO] mvn.reactor 0.1.1-SNAPSHOT ......................... SUCCESS [ 0.073 s] [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------
-
Now, both components might be started using the JAR files:
java -jar qanary_component-NED-DBpedia-Spotlight/target/qa.NED-DBpedia-Spotlight-X.Y.Z.jar java -jar qanary_component-QB-SimpleRealNameOfSuperHero/target/qanary_component-QB-SimpleRealNameOfSuperHero-X.Y.Z.jar
-
While having installed the Qanary components and Qanary pipeline using the standard configuration you can access a trivial Question Answering frontend via http://localhost:8080/startquestionansweringwithtextquestion
-
Use the question "What is the real name of Captain America?".
-
The question can be answered using the given two components.
-
Thereafter, the triplestore will hold a SPARQL query that was created by the QueryBuilder component
SimpleRealNameOfSuperHero(for DBpedia). It could be used to retrieve the actual answer from DBpedia. The UI shows the graph ID where the computed information was stored. -
Retrieve the SPARQL query from your Qanary triplestore using:
-
PREFIX oa: <http://www.w3.org/ns/openannotation/core/>
PREFIX qa: <http://www.wdaqua.eu/qa#>
SELECT *
FROM <ADD-YOUR-GRAPH-ID-HERE>
WHERE {
?s a qa:AnnotationOfAnswerSPARQL.
?s oa:hasBody ?sparqlQueryOnDBpedia .
?s oa:annotatedBy ?annotatingService .
}
-
Qanary provides the methodology for a knowledge-driven, vocabulary-based approach. Our long-term agenda is to create a knowledge-driven ecosystem for the field of Question Answering. It is part of the WDAqua project where Question Answering systems are researched and developed.
-
Qanary Framework provides the core framework for creating Question Answering systems following the Qanary methodology. You might consider the Qanary Framework as a reference implementation of the Qanary framework as a microservice-based component architecture.
-
Qanary components is covering the QA components compatible with the Qanary framework.
-
Frankenstein is a supporting framework to establish a toolset for rapid orchestration and benchmarking of Qanary components. For example, it provides the tools to create from 29 components 380 QA systems.
Regarding questions, ideas, or any feedback related to Qanary please do not hesitate to contact the core developers. However, if you would like to see a QA system originally built using the Qanary framework, one of our core developers has built a complete end-to-end QA system that allows you to query several RDF data stores: http://wdaqua.eu/qa.
Please go to the GitHub Wiki page of the Qanary repository to get more insights on how to use this framework, how to add new components etc.
Kuldeep Singh, Andreas Both, Dennis Diefenbach, Saeedeh Shekarpour: Towards a Message-Driven Vocabulary for Promoting the Interoperability of Question Answering Systems. ICSC 2016: 386-389 DOI 10.1109/ICSC.2016.59
Andreas Both, Dennis Diefenbach, Kuldeep Singh, Saeedeh Shekarpour, Didier Cherix, Christoph Lange: Qanary - A Methodology for Vocabulary-Driven Open Question Answering Systems. ESWC 2016: 625-641 DOI 10.1007/978-3-319-34129-3_38
Dennis Diefenbach, Kuldeep Singh, Andreas Both, Didier Cherix, Christoph Lange, Sören Auer: The Qanary Ecosystem: Getting New Insights by Composing Question Answering Pipelines. ICWE 2017: 171-189 DOI 10.1007/978-3-319-60131-1_10
For further publications please see the following wiki page.
All Question Answering components in this repository, grouped by task. Each links to the component’s own README.adoc (intention, behavior, characteristics and implementation details).
| Component | Language | Intention |
|---|---|---|
Java |
The component get the voice signal and transforms it to the textual representation which is saved in a standardized way to the Qanary triplestore. |
| Component | Language | Intention |
|---|---|---|
Java |
The component is classifying the queston of the current process (already stored in the Qanary triplestore) using the Shuyo language model. |
| Component | Language | Intention |
|---|---|---|
Python |
MT tool that uses pre-trained models by Helsinki NLP implemented in transformers library. |
|
Python |
MT tool that uses LibreTranslate to translate questions into English. |
|
Python |
MT tool that uses pre-trained MBart and Mbart-50 models by implemented in transformers library. |
|
Python |
MT tool that uses pre-trained "No Language Left Behind" (NLLB) models by Meta in transformers library. |
| Component | Language | Intention |
|---|---|---|
Java |
Receives a textual question recognizes named entities and stores them. |
|
Java |
Receives a textual question recognizes and disambiguates named entities and stores them. |
|
Java |
Receives a textual question recognizes and disambiguates named entities and stores them. |
|
Java |
Receives a textual question recognizes and disambiguates named entities and stores them. |
|
Java |
Receives a textual question recognizes and disambiguates named entities and stores them. |
|
Java |
Receives a textual question, forwards it to DBpedia Spotlight API and writes result in JSON format. |
|
Java |
This is a dummy component. |
|
Java |
Receives a textual question, forwards it to https://ner.vse.cz API and saves resulting named entities. |
|
Java |
Receives a textual question, forwards it to http://fox-demo.aksw.org/api API and saves resulting named entities. |
|
Java |
Receives a textual question, forwards it to the Meaning Cloud’s API and saves resulting named entities. |
|
Java |
Receives a textual question, forwards it to the OntoText’s API and saves resulting named entities. |
|
Java |
Receives a textual question, and uses Stanford NLP library to for NER task. |
|
Java |
Receives a textual question forwards it to the API of TagMe, gets back recognized entities and stores them. |
|
Java |
Receives a textual question forwards it to the API of Text Razor, gets back recognized entities and stores them. |
| Component | Language | Intention |
|---|---|---|
Java |
Receives a textual question and the spots from an NER component, disambiguates the spots and stores the corresponding named entities. |
|
Java |
Receives a textual question recognizes and disambiguates named entities and stores them. |
|
Java |
Receives a textual question recognizes and disambiguates named entities and stores them. |
|
Java |
Receives a textual question recognizes and disambiguates named entities and stores them. |
|
Java |
Receives a textual question recognizes and disambiguates named entities and stores them. |
|
Java |
Receives a textual question, forwards it to DBpedia Spotlight API and writes result in JSON format. |
|
Java |
Disambiguate recognised entity mentions and link them to a knowledge base. |
|
Java |
Receives a textual question recognizes and disambiguates named entities and stores them. |
|
Java |
Receives a textual question recognizes and disambiguates named entities and stores them. |
|
Java |
Receives a textual question, forwards it to OpenAI API and links them to the DBpedia knowledge graph. |
|
Java |
Receives a textual question recognizes and disambiguates named entities and stores them. |
|
Java |
Receives a textual question recognizes and disambiguates named entities and stores them. |
|
Java |
* API documentation: http://cloud.ibm.com/apidocs/natural-language-understanding * request own API key: http://cloud.ibm.com/catalog/services/natural-language-understanding. |
| Component | Language | Intention |
|---|---|---|
Java |
Receives a textual question recognizes and links named entities with the Alchemy API and stores them. |
|
Java |
Receives a textual question, tokenizes it with Lucene, links named entities given a static textual file and stores them. |
|
Java |
In order to use this component you need to install the smaph-erd fork and run smaph system first. |
| Component | Language | Intention |
|---|---|---|
Java |
The component fetches the textual question and annotates a recognized and disambiguated class and save it to the triplestore. |
| Component | Language | Intention |
|---|---|---|
Python |
The component wraps the Falcon relation extraction service. |
|
Java |
Receives a textual question forwards it to some local API, gets back recognized DBpedia relations and stores them. |
|
Java |
Receives a textual question forwards it to some local API, gets back recognized DBpedia relations and stores them. |
|
Java |
Receives a textual question forwards it to some local API, gets back recognized DBpedia relations and stores them. |
| Component | Language | Intention |
|---|---|---|
Java |
The component fetches the textual question and annotates a recognized and disambiguated class and save it to the triplestore. |
|
Java |
<<<<<<< HEAD:qanary-component-RD-DiambiguationProperty-OKBQA/README.md component source: https://www.okbqa.org/architecture/disambiguation =======. |
| Component | Language | Intention |
|---|---|---|
Java |
Classify the question (e.g. its expected answer type). |
| Component | Language | Intention |
|---|---|---|
Python |
The component classifies the DBpedia answer type of a textual question. |
| Component | Language | Intention |
|---|---|---|
Java |
Component source: https://www.okbqa.org/architecture/template-generation The component fetches the textual question and annotates a recognized and disambiguated class and save it to the triplestore. |
|
Java |
Receives a disambiguated entity and builds a SPARQL query over Wikidata about all the data related to birth of an entity. |
|
Java |
Receives a disambiguated entity and builds a SPARQL query over Wikidata about all the data related to birth of an entity. |
|
Java |
This component is intended to create and store a SPARQL query which can be executed on dbpedia to receive the date of death for a given person. |
|
Java |
see the Qanary wiki for a tutorial on how to use this Apache Maven archetype for creating a Qanary component. |
|
Java |
The main task of this component is to manage the communication between the Qanary pipeline and the gAnswer API and to prepare the data. |
|
Java |
A dummy component for monolithic systems that produce SPARQL queries. |
|
Java |
The main task of this component is to manage the communication between the Qanary pipeline and the Platypus API and to prepare the data. |
|
Python |
QA Interface component is a customizable wrapper for black-box KGQA systems. |
|
Java |
The component is fetching (typically 60) SPARQL queries from the QAnswer API which are considered to be possible solutons for the given question (aka SPARQL Query Candidates). |
|
Java |
The main task of this component is to manage the communication between the Qanary pipeline and the RuBQ API and to prepare the data. |
|
Java |
This rule-based Qanary component is intended to create a SPARQL query that can be executed on DBpedia for the limited knowledge domain of superhero names. |
|
Java |
Receives 3 data structures: |
|
Java |
The main task of this component is to manage the communication between the Qanary pipeline and the TeBaQA API and to prepare the data. |
| Component | Language | Intention |
|---|---|---|
Java |
The component is fetching results from the QAnswer API. |
|
Java |
Receives 3 optional data structures: |
| Component | Language | Intention |
|---|---|---|
Python |
A simple component that executes a SPARQL query on a given endpoint and returns the results. |
|
Java |
Receives a SPARQL query over DBpedia or Wikidata, executes it and writes result in JSON format. |
|
Java |
Receives a SPARQL query over Wikidata, executes it and writes result in JSON format. |
| Component | Language | Intention |
|---|---|---|
Java |
:toc: :toclevels: 5 :toc-placement!: :source-highlighter: highlight.js ifdef::env-github[] :tip-caption: 💡 :note-caption: ℹ️ :important-caption: ❗ :caution-caption: 🔥 :warning-caption: |
| Component | Language | Intention |
|---|---|---|
Java |
This component is a wrapper for the OpenAI API. |
| Component | Language | Intention |
|---|---|---|
Java |
A Qanary component that copies the annotations of a prior process graph into the current graph. |
| Component | Language | Intention |
|---|---|---|
Legacy |
This repository contain all the reusable resources present in Frankenstein Architecture, and detailed description of how to use the resources within Frankenstein. |
-
qanary_docker-compose-writer— a development build tool (generates a docker-compose file), not a QA component. -
Qanary-component-QB-Python-KGQAnWrapper— an (uninitialized) git submodule; no sources are present in this checkout.
