Dialogs modeled as finite state machines ?

Giorgio Robino
Jul 14, 2016 · 7 min read

((dialogs)) — an abandoned experiment

online shopping order submission macro dialog example: conversation contains three subdialogs

Abot — a promising open source bot framework

Abot makes it easy and fun to build your own digital assistant, and we include everything you need to get started.

Why I don’t like FSM approach

func kwGetRating(in *dt.Msg) string {
biz, err := getBusiness(in)
if err != nil {
return ""
}
f := fmt.Sprintf("%.1f", biz.Rating)
return "They have a " + f + " star rating on Yelp."
}

class List < Dialog    def self.initialize_data
[]
end
#
# state: start
#
def start(text)
go :add, add_o
end
#
# state: add
#
def add(item)
case item
when yes_i
go :add, add_more_o
when no_i || exit_i
if data.empty?
reply aborted_o
return back :finish
end
# list items
reply_list
go :confirm, confirm_o
when help_i
help_add

when list_i
reply_list
go :add, add_more_o
else
#
# NLP understanding
#
interpret item
# add line to data text
data.push item
# back to the same state
go :add, add_more_o
end
end
...
# file: list_lang_it.rb
module Dialogs
class List < Dialog
private

# input methods

def yes_i
/\bsi\b|\bok\b|\bprocedi\b|\bvai\b/i
end

def del_i
/\bdel\b|\btogli\b|\brimuovi\b/i
end

# output methods

def confirm_o
"confermi lista ?"
end

def confirmed_o
"lista confermata!"
end

def del_o(max_num)
[
"quale item vuoi cancellare (1-#{max_num}) ?",
"cosa vuoi togliere (1-#{max_num}) ?"
].sample
end
// Package hello responds to "Say something" with "Hello World".
package hello

import (
"log"

"github.com/itsabot/abot/shared/datatypes"
"github.com/itsabot/abot/shared/nlp"
"github.com/itsabot/abot/shared/plugin"
)

var p *dt.Plugin

func init() {
// Create the plugin, setting it up to communicate with Abot through
// the functions we specified.
var err error
p, err = plugin.New("github.com/itsabot/plugin_hello")
if err != nil {
log.Fatalln("failed to build plugin.", err)
}

// When Abot receives a message, it'll route the message to the correct
// package. Doing that requires a trigger, which tells Abot to send the
// response to this package when Commands include "say" and Objects
// include "something", "hello", etc. Case should always be lowercase,
// and the words will be stemmed automatically, so there's no need to
// include variations like "cat" and "cats". plugin.AppendTrigger is
// optional if you set KeywordHandlers (as described in the Building a
// Plugin guide), but since we only have a state machine, we'll add
// these words as triggers.
plugin.AppendTrigger(p, &nlp.StructuredInput{
Commands: []string{"say"},
Objects: []string{"something", "hello", "hi"},
})

// Abot includes a state machine designed to have conversations. This
// is the simplest possible example, but we'll cover more advanced
// cases with branching conversations, conditional next states, memory,
// jumps and more in other guides.
//
// For more information on state machines in general, see:
// https://en.wikipedia.org/wiki/Finite-state_machine
plugin.SetStates(p, [][]dt.State{[]dt.State{
{
OnEntry: func(in *dt.Msg) string {
return "Hello world!"
},
OnInput: func(in *dt.Msg) {
},
Complete: func(in *dt.Msg) (bool, string) {
return true, ""
},
},
}})
}

Decoupling dialogs scripts from logics behind!


21 October 2016 update

23 February 2017 update


Please tap or click “︎❤” to help to promote this piece to others.

Giorgio Robino

Written by

Engineer and Researcher in Conversational AI. I work at ITD-CNR. My articles: www.convcomp.it Microblog: twitter.com/solyarisoftware

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade