Skip to Content
Technical Articles
Author's profile photo Raoul Biagioni

Procedural Flow and Other Useful Techniques for Implementing a Chatbot with SAP Conversational AI

A few weeks ago I was asked to look into the SAP Conversational AI (SAP CAI) chatbot platform. My task was to get familiar with the platform by building a simple chatbot demo for a fictional telecoms customer service scenario. The chatbot allows customers to check whether they are eligible for a phone upgrade. Features of the demo bot include personalised responses based on customer profile and business rules, customer ID validation and verification, and selection of a preferred fulfillment channel. The chatbot was implemented as a Python Flask application to explore the platform’s ability to communicate with some backend data. The design of the chatbot is inspired by this excellent tutorial on chatbot memory management.

This article is intended to serve as a quick reference for techniques I found useful when building my chatbot. The areas covered include:

  • Invoking skills and skill-specific intents
  • Designing procedural flow with Quick Reply buttons
  • Dynamic skill routing using the chatbot memory
  • Regular expressions for input validation

The article assumes that the reader is already familiar with the basic concepts and workings of the SAP CAI platform. The web development aspects of the chatbot demo is beyond the scope of this article. For reference, the Flask application can be found here. The SAP CAI chatbot can be found here.

Invoking Skills and Skill-Specific Intents

Skills can be invoked in two ways, either by being triggered through intent detection, or by being redirected to from another skill. Triggered skills are typically used for either initiating the conversation flow, or for taking over when the user input is outside of the core problem domain. Skills that are being redirected to are typically part of a sequence of events of the conversation flow design. These skills can either take immediate action, or they can prompt the user to provide some input based on which the chatbot will take some action. This is particularly useful for eliciting information from the user in order to guide the conversation.

A “global” intent is an intent that is accessible to all skills. These are the intents that are setup in the Train tab of the SAP CAI platform. A skill-specific intent is an intent whose scope is limited to a given skill’s requirements. Skill-specific intents can be used to prompt for user input in order to collect information at any point in the conversation flow. Strategies for gathering user information and user preferences global and skill-specific intents are discussed next.

Designing Procedural Flow with Quick Reply Buttons

Conversation with a bot is generally focused around the task a bot is trying to achieve, which is called a procedural flow. This is where the bot asks the user a series of questions to gather all the information it needs before processing the task (source).

When building a chatbot, a common requirement is to combine into one procedural unit the tasks of asking some question of interest, capturing the response in memory and taking an action based on the response provided. One way to achieve this is to create a skill in which a skill-specific intent is used to trigger a question. Each question has two possible answers. The answers are set up as quick reply buttons and will trigger different actions. I will illustrate this process using the demo chatbot skills place_orderand delivery_options.

Working with quick reply buttons in this way requires:

  • Mapping one or more “global” intents to a skill-specific intent
  • Setting the values of the quick reply buttons to match keywords in the global intent(s).

The place_orderskill asks the user whether he/she would like to place an order and the user can respond by clicking one of the yes/no quick reply buttons. When the place_orderskill is invoked for the first time, the skill-specific @place_order intent is missing and the chatbot will trigger the prompt. The mapping of the @yes and @no intents to @place_order means that the answer of the user will be picked up by the chatbot’s NLP engine and as a result will be stored to the chatbot’s memory field _memory.place_order.slug. The values of this memory field is then used for taking the appropriate action.




Similar to the above example, the fulfillment skill @delivery_optionsasks the user whether he/she prefers home delivery or store pickup. Depending on the selected option a different type of action will ensue i.e. home address lookup in the customer database, or a search for the nearest retail store with availability of the selected item.

The differences with the previous example are:

  • In this example, a custom intent @delivery_optionsis created to detect the keywords, home and store, associated with the quick reply buttons.
  • The selected option is retrieved from memory using the field _source.






Dynamic skill routing using the chatbot memory

A typical scenario for dynamic conversation flow routing is a chatbot that first deals with a mandatory task such as eliciting a customer ID. Once this task has been completed, the chatbot is redirected to deal with the user’s query or problem e.g. answering phone upgrade queries or looking up account charges.

Dynamic skill routing can be achieved by storing user intent in memory as soon as it is detected. This is typically done by the skill that initiates a conversation which, in the the present case, is the auth-startskill. Once the intent has been saved to memory, any skill can be redirected to by simply retrieving the user intent name from memory. Note that for this technique to work, the skills we will be redirecting to dynamically, must be named after the “source” intent. For example, the name upgrade_phone is used for both the name of an intent and a skill.



Regular expressions

Regular expressions can be used to validate user input. For example, in the present chatbot demo the user is asked to provide his/her customer ID. This ID must be in the format of four digits, followed by a dash, then by five letters e.g. 1234-ABCDE. To ensure that the user enters the customer ID in this format we can use a skill requirements validator by specifying that the customer ID must match the regular expression (^[0-9]{4}-[a-zA-Z]{5}$). Note that regular expressions must follow the Ruby syntax.



In this article I described how to integrate procedural flow in to a chatbot conversation, how to dynamically route a conversation and how to validate user input using regular expressions. I included the latter because, albeit simple, I did spend some time until I got it to work. Note the enclosing brackets in the expression…

Dynamic routing can be particularly useful when a chatbot is designed to deal with more than one problem domain but must also deal with some mandatory information gathering that will be used in any of those domains. In this case, dynamic routing will facilitate the first mandatory information gathering stage while retaining flexibility as to which skills to invoke thereafter.

Triggering skills and guiding the conversation based on user input is at the core of chatbot procedural flow design. In this article I presented an overview of techniques that can be helpful in getting started when building a conversation flow that requires user input. The detection and correct classification of user intention expressed in natural language is by far the most challenging, and interesting, aspect of building a chatbot. To minimise misclassification of user intent, and therefore poor user experience, it is a safe option to design a conversational flow in a guided fashion. To this end quick reply buttons are ideal for ensuring that user information and preferences are correctly captured and that the conversation finish line will be crossed successfully.

Assigned Tags

      You must be Logged on to comment or reply to a post.
      Author's profile photo Ilia Vinogradov
      Ilia Vinogradov

      Thank you for your post and for sharing the sources!

      So, CAI forces you to use an implicit state via global flags just to deal with context-related intents and process a user’s free-input? That seems a bit old-fashioned...

      BTW, have you tried

      Author's profile photo Xavier Sanchez
      Xavier Sanchez


      I'm redirecting a skill to {{nlp.intents[0].slug}}, but it does not working. There are no errors, but nothing happens. Also when i write {{nlp.intents[0].slug}} on the redirect box, the action "strart the skill" or "wait user input" disappear.

      Do you know why it does not work?

      Thanks in advance.

      King regards