tree: 80631ff7dfc11ab295e8ae1ac82331eff01c599c [path history] [tgz]
  1. .github/
  2. bin/
  3. bindist/
  4. docker/
  5. external/
  6. idea/
  7. javadoc/
  8. nlpcraft/
  9. nlpcraft-stanford/
  10. openapi/
  11. sql/
  12. .asf.yaml
  13. .gitignore
  14. assembly.xml
  15. DISCLAIMER
  16. LICENSE
  17. NOTICE
  18. pom.xml
  19. README.md
README.md

License Build Documentation Status Gitter

What is Apache NLPCraft?

Apache NLPCraft is an open source library for adding a natural language interface for modern applications:

Why Natural Language?

Natural Language Interface (NLI) enables users to explore any type of data sources using natural language augmenting existing UI/UX with fidelity and simplicity of a familiar spoken language. There is no learning curve, no special rules or UI to master, no cumbersome syntax or terms to remember - just a natural language that your users already speak.

Key Features

Programmable Intents

Fully programmable, advanced intent DSL with deterministic matching provides easy to use and expressive mechanism for a complex intent logic.

Short-Term-Memory

Advanced out-of-the-box support for maintaining and managing conversational context that is fully integrated with intent matching.

English Focused

NLPCraft focuses on processing English language delivering the ease of use and unparalleled comprehension for the language spoken by more than a billion people.

By Devs - For Devs

Built with a singular focus - provide developers with unprecedented productivity and efficiency when building modern NLI applications.

Composable Named Entities

Compose new reusable Named Entities out of existing internal or external ones, build new ones and mix and match using comprehensive DSL.

Java-First

REST API and Java-based implementation natively supports the world's largest ecosystem of development tools, multiple programming languages, frameworks and services.

Model-As-A-Code

Model-as-a-code convention natively supports any system development life cycle tools and frameworks in the Java ecosystem.

Out-Of-The-Box Integration

NLPCraft natively integrates with 3rd party libraries for base NLP processing and named entity recognition:

Learn more >

How It Works

When using NLPCraft you will be dealing with three main components:

Data model specifies how to interpret user input, how to query a data source, and how to format the result back. Developers use model-as-a-code approach to build models using any JVM language like Java, Scala, Groovy or Kotlin.

Data probe is a DMZ-deployed application designed to securely deploy and manage data models. Each probe can manage multiple models, and you can have many probes.

REST server provides REST endpoint for user applications to securely query data sources using NLI via data models deployed in data probes.

Learn more >

Example

As a quick example let's consider a very simple implementation for NLI-powered light switch. Our app should understand something like Turn the lights off in the entire house or Switch on the illumination in the master bedroom closet. You can easily modify intent callbacks in the model implementation below to perform the actual light switching using HomeKit or Arduino-based controllers.

Add NLPCraft

Add NLPCraft dependency to your project:

<dependencies>
    <dependency>
        <groupId>org.apache.nlpcraft</groupId>
        <artifactId>nlpcraft</artifactId>
        <version>0.7.4</version>
    </dependency>
</dependencies>

NOTE: 0.7.4 should be the latest NLPCraft version.

Define Data Model

Declare the static part of the data model using YAML which we will later load in our model implementation. You can declare entire model in the code - but doing it with JSON or YAML is more productive:

id: "nlpcraft.lightswitch.ex"
name: "Light Switch Example Model"
version: "1.0"
description: "NLI-powered light switch example model."
macros:
  - name: "<ACTION>"
    macro: "{turn|switch|dial|control|let|set|get|put}"
  - name: "<ENTIRE_OPT>"
    macro: "{entire|full|whole|total|*}"
  - name: "<LIGHT>"
    macro: "{all|*} {it|them|light|illumination|lamp|lamplight}"
enabledBuiltInTokens: [] # This example doesn't use any built-in tokens.
elements:
  - id: "ls:loc"
    description: "Location of lights."
    synonyms:
      - "<ENTIRE_OPT> {upstairs|downstairs|*} {kitchen|library|closet|garage|office|playroom|{dinning|laundry|play} room}"
      - "<ENTIRE_OPT> {upstairs|downstairs|*} {master|kid|children|child|guest|*} {bedroom|bathroom|washroom|storage} {closet|*}"
      - "<ENTIRE_OPT> {house|home|building|{1st|first} floor|{2nd|second} floor}"
 
  - id: "ls:on"
    groups:
      - "act"
    description: "Light switch ON action."
    synonyms:
      - "<ACTION> <LIGHT>"
      - "<ACTION> on <LIGHT>"
 
  - id: "ls:off"
    groups:
      - "act"
    description: "Light switch OFF action."
    synonyms:
      - "<ACTION> <LIGHT> {off|out}"
      - "{<ACTION>|shut|kill|stop|eliminate} {off|out} <LIGHT>"
      - "no <LIGHT>"
intents:
  - "intent=ls term(act)~{groups @@ 'act'} term(loc)~{id == 'ls:loc'}*"

Model Implementation

Once we have model declaration we can provide implementation for intent callbacks. We'll use Scala to implement the data model, but you can use any JVM-based language like Java, Groovy, or Kotlin:

package org.apache.nlpcraft.examples.lightswitch
 
import org.apache.nlpcraft.model.{NCIntentTerm, _}
 
class LightSwitchModel extends NCModelFileAdapter("org/apache/nlpcraft/examples/lightswitch/lightswitch_model.yaml") {
    @NCIntentRef("ls")
    @NCIntentSample(Array(
        "Turn the lights off in the entire house.",
        "Switch on the illumination in the master bedroom closet.",
        "Get the lights on.",
        "Please, put the light out in the upstairs bedroom.",
        "Set the lights on in the entire house.",
        "Turn the lights off in the guest bedroom.",
        "Could you please switch off all the lights?",
        "Dial off illumination on the 2nd floor.",
        "Please, no lights!",
        "Kill off all the lights now!",
        "No lights in the bedroom, please."
    ))
    def onMatch(
        @NCIntentTerm("act") actTok: NCToken,
        @NCIntentTerm("loc") locToks: List[NCToken]
    ): NCResult = {
        val status = if (actTok.getId == "ls:on") "on" else "off"
        val locations =
            if (locToks.isEmpty)
                "entire house"
            else
                locToks.map(_.meta[String]("nlpcraft:nlp:origtext")).mkString(", ")
 
        // Add HomeKit, Arduino or other integration here.
 
        // By default - just return a descriptive action string.
        NCResult.text(s"Lights '$status' in '${locations.toLowerCase}'.")
    }
}

NOTES:

  • We are loading our static model declaration that we've defined above using NCModelFileAdapter base class.
  • Annotation @NCIntentRef references the intent defined in our YAML model definition.
  • We use @NCIntentSample to provide sample sentences that should satisfy this intent. These samples are used for model auto-testing and synonyms analysis.

Done! 👌

Learn more about this example >

Copyright

Copyright (C) 2021 Apache Software Foundation