Workflow-Driven NLP Bots

Introduction

Command-based bots and hard-coded decision trees are easy to implement and a good first step toward automation. Symphony bots present themselves as users of the platform, so the end goal for the "user experience" is to make the bots interact as seamlessly as possible. Natural language processing (NLP) helps create this seamless interaction.

Natural Language Processing

NLP allows a computer to better understand human language. Using NLP has helped us move away from #command and into bots that understand orders, questions, or queries expressed in a natural way by humans.

Business Process Model and Notation

BPMN helps us model business processes using a graphical representation that can then be ingested by a workflow platform. For the example use case below, we use Camunda. This tool keeps track of state in a long-lived conversation, replacing hard-coded decision trees and the need to store state in a persistent store.

A Simple Human-Bot Use Case

To demonstrate NLP and BPMN, we will use a simple use case. This use case presents the first step of an "intelligent" conversation between a human and a bot. An end user makes a request, which triggers a specific workflow process. The bot gathers information for the user and asks for a confirmation. When the human replies, the bot needs to understand the answer as a specific action in the workflow.

Message > NLP > Action

Each message the bot receives is processed in the following three steps. The NLP service:

  1. Splits the message into sentences.
  2. Maps each word in each sentence to a part of speech (POS).
  3. Tries to match the list of words and their parts of speech to one of the patterns provided in a json configuration file.
[
  {"action":"buyShares",
    "posrequirementList":[
      {"options":["buy","purchase"],"parameter":null,"pos":"V"},
      {"options":null,"parameter":"quantity","pos":"CD"},
      {"options":["shares","stock"],"parameter":null,"pos":"NN"},
      {"options":null,"parameter":null,"pos":"IN"},
      {"options":null,"parameter":"product","pos":"NN"}]
  },
  {"action":"buyShares",
    "posrequirementList":[
      {"options":["buy","purchase"],"parameter":null,"pos":"V"},
      {"options":null,"parameter":"product","pos":"NN"},
      {"options":null,"parameter":"quantity","pos":"CD"}]
  },
  {"action":"buyShares",
    "posrequirementList":[
      {"options":["buy","purchase"],"parameter":null,"pos":"V"},
      {"options":null,"parameter":"product","pos":"*"},
      {"options":null,"parameter":"quantity","pos":"CD"}]
  },
  {"action":"buyShares",
    "posrequirementList":[
      {"options":["buy","purchase"],"parameter":null,"pos":"V"},
      {"options":null,"parameter":"quantity","pos":"CD"},
      {"options":null,"parameter":"product","pos":"NN"}]
  },
  {"action": "decision",
  "posrequirementList":[{"pos":"UH","options":["yes","yeah","sure","yep","confirm","y"],"parameter":"decisionBool", "value": "true"}]
  },
  {"action": "decision",
    "posrequirementList":[{"pos":"UH","options":["no","nope","reject","n"],"parameter":"decisionBool", "value": "false"}]
  },
  {"action":"headlines",
    "posrequirementList":[
      {"options":["headlines","news","articles"],"parameter":null,"pos":"NN"},
      {"options":null,"parameter":null,"pos":"*"},
      {"options":null,"parameter":"product","pos":"NN"}]
  },
  {"action":"headlines",
    "posrequirementList":[
      {"options":null,"parameter":"product","pos":"NN"},
      {"options":["headlines","news","articles"],"parameter":null,"pos":"NN"}
      ]
  }
]

An diagram of POS mapping is shown below:

Conversation

The streamId of the one-on-one with the bot becomes the unique identifier for processes on the engine. (Your workflow is the basis for this design decision. For purposes of this use case, we use the variable streamid. The Camunda engine can be queried for process instances that match any variable.)

  • If no existing process is assigned to the message's streamId, and the action extracted from the message sent by the user matches the name of a process deployed to the engine, an instance of that process is started.
  • If a process instance matches the streamId, a user task is fetched to be completed with the action extracted from the message.

The diagram below shows the process flow:

Service tasks

In this simple use case, service tasks are tasks completed by the bot. In a broader workflow, a micro-service can be assigned to each type of task so that any system can complete it.

User tasks

These are actions expected from a user.

Getting Started

This section provides the steps to generate a Java-based bot that uses the Camunda engine for NLP.

Dependencies
This project uses three Maven libraries provided by the Symphony #platformsolutions team:

  1. symphony-api-client-java: Refer to Get Started with Java for more information.
  2. symphony-camunda-client: A helper library to access the Camunda REST APIs and tie them into the Symphony use case.
  3. symphony-opennlp-java: An OpenNLP-based library to make POS and pattern matching to actions easier.

Steps to Generate a Project

  1. Use the Symphony Bot Generator and follow the prompts to create a Java bot that uses the 'NLP Based Trade Workflow' template.
  2. Download and install the Camunda engine.
  3. Upload the provided BPMN files to the Camunda engine using the Camunda REST API.
  4. Set up the Java project in your IDE and run the BotExample main class as shown in Get Started with Java.
  5. Compile, run, and then modify based on your business needs.

Workflow-Driven NLP Bots


Suggested Edits are limited on API Reference Pages

You can only suggest edits to Markdown body content, but not to the API spec.