How To Avoid
Pyramid Of Doom
When Designing
Bot Workflows
Alex Bunardzic
October 14, 2016
Vienna, Austria
me
26 years of software development
50% engineering, 50% process
50% business analysis
fan of
purity in programming
(no side effects)
intensely dislike self-serve (will be explained later)
Two Families of Bots
1. Concierge
2. Butler
Concierge
Loyal to the Corporation
Butler
Loyal to the Individual
Butler
Focused on learning about its owner's habits
Focused on detecting recurring behavioural patterns
Trained to respect the owner's preferences
Butler Bot
Stars in many Hollywood movies
Needs heavy duty AI
Concierge
Focused on learning about the corporate goals
Focused on consistent customer service
Trained to detect business opportunities (i.e. up-sell/cross-sell)
Sets the tone of the conversation
Concierge Bot
Establishes the conversational protocol
Concierge Bot
Doesn't need beefy AI
Conversation with a
narrow focus
Example: Medical Receptionist
Typical experience with a Medical Receptionist (Concierge)
Receptionist sets the tone of the conversation
Establishes the
conversational protocol
Asks for pertinent information (name, insurance, phone, date of birth)
Impervious to any attempts to spark up irrelevant conversation
If a visitor refuses to comply, receptionist may ask them to leave
Concierge Bot model requires
rudimentary NLP
Self-serve
Technological advancements have ushered the era of
self-serve
High tech self-servitude => instead of human cashiers,
self-serve checkouts
Consumers are duped into doing all the legwork while still paying the full price
Only businesses benefit from the self-serve model
Concierge bots are the next step in the evolution of high tech self-serve paradigm
What's the difference between self-serve and full-serve bots?
Using a self-serve bot is similar to explaining your problem to a toddler
Using a full-serve bot is similar to explaining your problem to a mathematician
Self-serve/full-serve
dichotomy is similar to the
imperative/functional programming
dichotomy
Challenges
Challenges
Even rudimentary NLP is a huge challenge!
Google Assistant
Challenges
Even rudimentary NLP is a huge challenge!
Luckily, there are commodities and neural networks to help
Challenges
Even rudimentary NLP is a huge challenge!
Luckily, there are commodities and neural networks to help
One challenge remains largely unaddressed
Workflow
Workflow
Bot workflow
is an uncharted territory
Why?
Bots are
Stateless
Stateless Bots are Useless Bots
How to Endow Bots with State?
Implement Workflow!
Bot Workflow persists the state of conversation
Workflow can get
very complex!
Is there a prescribed solution?
Yes, there is. It's called REST
How does REST implement workflow?
HATEOAS:
H
ypermedia
A
s
T
he
E
ngine
O
f
A
pplication
S
tate
Work flows through
piecemeal discovery
All the information necessary to decide what's the next step is
in band
There is no need to establish the purpose of the conversation
beforehand
There is no need to reach out for any additional information that's
out of band
Nice. Why don't we use REST for bot workflow then?
Unlike apps, bots have
no routes
In REST, business logic is compartmentalized in
routes
In bots, business logic is piled up in a big
bowl of spaghetti
Also known as the
Pyramid of Doom!
So what's wrong with the
Pyramid of Doom
?
Difficult to read
Difficult to reason about
Very hard to modify
Extremely hard to troubleshoot
Extremely hard to debug
Almost impossible to document
Is there a solution to this?
I wasn't able to find ready made solution for bot workflows, so I rolled up my sleeves
Fight the Pyramid of Doom!
Divide and Conquer!
Bot Architecture
Two Layers
Commodity layer
Core competence layer
Commodity Layer
Messaging channels (SMS, Messenger, WhatsApp, Slack, etc.)
Natural Language Processing/Understanding (NLP/NLU)
Computing infrastructure (servers, clients, message queues...)
Core Competence Layer
Business application domain-specific code
Business entities
Business operation
Business Operation
Dispatching
Authentication/authorization
Validation
Business rules/processing logic
Persistence
Response
Business Entities
User
Conversation
Context
Conversation
Belongs to User
Remembers messages received from the User
Remembers replies to the User
Declares the
next step
Drives the workflow
Next step?
Determined by the business logic
How is
next step
implemented?
If using
imperative
approach, results in
Pyramid of Doom!
More desirable to implement next step using
declarative
approach
How to implement
declarative
approach?
Compartmentalize processing logic into
isolated
components
Similar to
REST
and
HATEOAS
In
REST
isolated components are implemented as
resources
HATEOAS
provides the
next step
Example (simplified)
User asks the bot to see the menu
The bot messages back with the menu
User is supposed to pick an item and send it to the bot as a message
Bot checks if the user chose an existing menu item, or if the user said something unrelated
Implementation
(gory details)
Create a component
ProcessMenuSelection
Declare
next step
to be "TakeItemSelection"
Create a component
TakeItemSelection
Declare
next step
to be "TakeItemQuantity"
And so on...
How to execute this Workflow?
Create a main diver component:
Entry
with a single method:
dispatch
The main engine runs on
two lines
of code:
clas =
next_step
.constantize
clas.new(params)
OK, but where is the
next step
coming from?
next_step = user.conversations.last.next_step
Wrap up
Bots for Business
https://medium.com/bots-for-business
Welcome to Web 3.0!
Questions?
Parting is a sweet sorrow
https://twitter.com/alexbunardzic
https://medium.com/@alexbunardzic
Made with Slides.com