Dealing with newlines or multi line responses from a user with a chatbot? - chatbot

Is there a known way to deal with users writing responses over multiple lines? - is it best to handle this case on the client level? as in checking if the user is still typing and have a delay between responses, or can this be handled on Watson somehow?
An example would be:
Bot:
What's Your Name?
User:
My name is
Nour
Those are two independent messages by the user over 2 lines.

It is best to always send the full "utterance" to Assistant in one request, because the processing does not work across multiple split calls to Assistant. Otherwise you would need to do some complex logic with context variables, or ask back the user their name if they uttered "my name is" without an actual name.
Generally the client side UI would wait for the user to press Enter before sending the utterance to Assistant. So you can be sure they have entered the full utterance.
But perhaps if they do utter "my name is" you could have an intent which checks for a name and an entity that extracts the name, and a dialog node which if the intent is found has a slot which ensures the entity is also found. In that way, if they do say "my name is" and no name, the bot will ask them for their name.

DSeager's approach is potentially the right way for the example you gave. The reason being is that within your overall question you have an entity.
What about where there is on real entity? For example:
Two Intents.
Pay my speeding fine
Pay my parking fine
Here you are using the intents to understand the answer without the need of an entity. Some will argue the Intent->Entity approach, but depending on your solution it can generally not scale as well versus just an intent answer.
So now your user enters the following:
How do I pay my
parking fine
Entity solution doesn't really work here as you have no context that they want to pay.
So one approach.
1. Send "How do I pay my" to WA. Assuming you have trained the system well it should come back with a low confidence or irrelevant.
2. Before you respond to the user, see if another utterance has been cached to send. If it has, then append with some kind of marker and send. For example:
How do I pay my !! parking fine
This will return the correct answer.
But wait a second, what if they do this?
How do I pay my parking fine?
Where do I pay it?
Both are valid questions, but the second one will fail and you can't append it to the previous.
In this instance, when an answer displays have it set a $anaphora context variable. Then if you get a low confidence/irrelevant response try reasking with the $anaphora value appended.
For example:
Q: How do I pay my parking fine?
A: <Answer> $anaphora = "parking fine"
Q: Where do I pay it?
A: <Irrelevant>
Q: parking fine !! Where do I pay it?
Both of these require some work at the application layer.

Related

IBM Watson Assistant: How to ask a series of questions and store related answers?

I want to ask a series of question , taking each input and saving them in a context variable and then moving to the next question.
The problem is whenever a user responds IBM Watson starts classifying it into intents. and goes to that specific intent. What i want would look something like this:
Whats your name?
user input = xyz
xyz gets stored in username and then the bot asks the next question
whats your organ name
and so on.
My advice would be to work with slots and to define entities for what you want to capture. This allows for a more natural flow. "Henrik from xyz" could be directly stored as name "Henrik" and "yyz" as org.
If you just want to have a series of questions and store whatever was answered, take a look at special conditions. If you use true as condition and store the entire input into a context variable, you get what you asked for.

Multiple Dialogflow commands asked at same time

I have an Action where the user can set values of different parameters. Currently this is implemented something like this, and it works well:
Now I want to make the conversation less robot-like and more flexible, so I would like to allow users to set or change more than one value at a time. They should be able to say things like
Change the Interest Rate to 4% and the Term to 15 years.
or
Change the Interest Rate to 4%, the Term to 15 years, and the Years to Average Principal to 3.
There are a couple of ways to do this, but none of them are great, and all of them have issues of some sort when you try to scale them. (So they might work well for two or three parameters entered, but they probably won't work well for more than that.)
(It is worth noting, just for reference, that the Assistant itself has only recently started accepting more than one instruction at a time. But it only handles two, and this doesn't work for all commands.)
Add phrases with additional parameters
With this solution, you would supplement the phrases you have that collect one parameter with a similar set of phrases that collect two parameters. And then another set that also collect three parameters. You should be able to do these all as a single Intent and, in your fulfillment, determine which ones have been set.
It might look something like this:
That looks like it starts getting complicated, doesn't it? You need to list each combination of absolute values and percentages. If you have other types, you need to include each of those combinations as well. That starts getting unwieldy for 3 possible parameters, and certainly is above that. You also run the risk that it might get confused about which parameter should be set with which value (I haven't tested this - it is a theoretical concern).
Add an optional continuation phrase and handle that recursively
You can also treat this as the user saying "set a value, and then do something else" and treat the "do something else" part as another statement made to Dialogflow. The Intent might look something like this:
You can implement the "another statement made to Dialogflow" using the Dialogflow API. With Dialogflow V1, you'd use the Query endpoint. With Dialogflow V2, you'd use the detectIntent endpoint. In either case, you'd send the additional part of the query (if the user said something) and would get back the results from that. You'd add the resulting message from the call to the message from setting the current set of values and send the whole thing back.
As a recursive call, however, this does take up time. Since the initial call to Dialogflow really needs to be answered within 5 seconds, every additional call to Dialogflow (and then to your fulfillment) needs to be handled as quickly as possible. But even so, you probably won't be able to handle more than 2 or 3 of these before things time out on the front end.
It also runs the risk (or benefit) that other intents besides the edit.attribute Intent might be called in the "additional" portion. If you want to limit the risk of this, you could set a context to make sure that only Intents that have that incoming context would be called.
Summary
This really isn't an easy problem to solve. On one hand, you have the problem of having to list out every combination. On the other hand, recursion takes time, and you don't have a lot of time to process everything. In both cases, there is a real possibility of the phrase being understood incorrectly and you'll need to figure out error handling in the case where some values have been changed and others haven't.
You may need to experiment a lot, and the results may still not be satisfactory.
You can implement the "another statement made to Dialogflow" using the
Dialogflow API. With Dialogflow V1, you'd use the Query endpoint.
With Dialogflow V2, you'd use the detectIntent endpoint. In either
case, you'd send the additional part of the query (if the user said
something) and would get back the results from that. You'd add the
resulting message from the call to the message from setting the
current set of values and send the whole thing back.
As a recursive call, however, this does take up time. Since the
initial call to Dialogflow really needs to be answered within 5
seconds, every additional call to Dialogflow (and then to your
fulfillment) needs to be handled as quickly as possible. But even so,
you probably won't be able to handle more than 2 or 3 of these before
things time out on the front end.
The first thing that came to mind after reading those two paragraphs was batch requests.
A batch request allows a client application to pack multiple API calls into a single HTTP request (this batching technique is also known as a multi-part request).
Many Google APIs support a batch endpoint and I was able to verify that DialogFlow has a batch endpoint by checking its API Discovery document. This batch endpoint is not formerly documented in DialogFlow's API reference but you can leverage the documentation of other APIs (like this one) to get a feel for how it works. This link should also be instructive now that the global batch endpoint is no longer supported.
Assuming your queries are independent (ie. they don't rely on the results of other queries) you should be able to use a batch request to fetch more data.

CQRS events do not contain details needed for updating read model

There is one thing about CQRS I do not get: How to update the read model when the raised event does not contain the details needed for updating the read model.
Unfortunately, this is a quite common scenario.
Example: I add a user to a group, so I send a addUserToGroup(userId, groupId) command. This is received, handled by the command handler, the userAddedToGroup event is created, stored and published.
Now, an event handler receives this event and the both IDs. Now there shall be a view that lists all users with the names of the groups they're in. To update the read model for that view, we do need the user id (which we have) and the group name (which we don't have, we only have its id).
So the question is: How do I handle this scenario?
Currently, four options come to my mind, all with their specific disadvantages:
The read model asks the domain. => Forbidden, and not even possible, as the domain only has behavior, no (public) state.
The read model reads the group name from another table in the read model. => Works, but what if there is no matching table?
Add the neccessary data to the event. => Does not work, as this means that I had to update all previous events as well, and I cannot foresee which data I may need one day.
Do not handle the event via a "usual" event handler, but start an ETL process in the background that deals with the event store, creates the neccessary data and writes the read model. => Works, but to me this seems a little bit of way too much overhead for such a simple scenario.
So, the question is: How do I deal with this scenario correctly?
There are two common solutions.
1) "Event Enrichment" is where you indeed put information on the event that reflects the information you are mentioning, e.g. the group name. Doing this is somewhere between modeling your domain properly and cheating. If you know, for instance, that group names change, emitting the name at the moment of the change is not a bad idea. Imagine when you create a line item on a quote or invoice, you want to emit the price of the good sold on the invoice created event. This is because you must honor that price, even if it changes later.
2) Project several streams at once. Write a projector which watches information from the various streams and joins them together. You might watch user and group events as well as your user added to group event. Depending on the ordering of events in your system, you may know that a user is in a group before you know the name of the group, but you should know the general properties of your event store before you get going.
Events don't necessarily represent a one-to-one mapping of the commands that have initiated the process in the first place. For instance, if you have a command:
SubmitPurchaseOrder
Shopping Cart Id
Shipping Address
Billing Address
The resulting event might look like the following:
PurchaseOrderSubmitted
Items (Id, Name, Amount, Price)
Shipping Address
Shipping Provider
Our Shipping Cost
Shipping Cost billed to Customer
Billing Address
VAT %
VAT Amount
First Time Customer
...
Usually the information is available to the domain model (either by being provided by the command or as being known internal state of the concerned aggregate or by being calculated as part of processing.)
Additionally the event can be enriched by querying the read model or even a different BC (e.g. to retrieve the actual VAT % depending on state) during processing.
You're correctly assuming that events can (and probably will) change over time. This basically doesn't matter at all if you employ versioning: Add the new event (e.g. SubmitPurchaseOrderV2) and add an appropriate event handler to all the classes that are supposed to consume it. No need to change the old event, it can still be consumed since you don't modify the interface, you extend it. This basically comes down to a very good example of the Open/Closed Principle in practice.
Option 2 would be fine, your question about "what about the mismatching in the groups' name read-model table" wouldn´t apply. no data should be deleted, should invalidated when a previous event (say delete group) was emmited. In the end the row in the groups table is there effectively and you can read the group name without problem at all. The only apparent problem could be speed inconsistency, but thats another issue, events should be orderly processed no matter speed they are being processed.

how to create a use case diagram for the forum system

there would be users with different privilages and as a consequence there would be a lot of conditions, so how can i model the conditions in the use case diagrams? for example, the forum manager may create a post or update a post or even delete a post, create a threads or update avialable threads, delete threads, etc.
1- should i have different "use case" elements for each task? i mean add an oval/circle element for each task?? like creating an oval for "create a post", an oval for "updating the post",.....
2- is it correct to have one actor for each privilage?? like one for anonymuse user, one for logged in user, .....
thanks.
You shouldn't get into conditions and ifs and buts in use cases diagrams. A set of use cases is intended to provide an overview of the system's functionality, and each use case describes an interaction between the system and one or more actors. You want to keep that description simple and succinct.
Each use case should in some way make sense to the actor. To a person using a forum, it does make sense that creating a post is a separate activity from updating one (or responding to one), so that seems like a sensible start to me. You should not be overly concerned with the number of use cases at this stage. The number of use cases does not translate directly into system complexity, and a large number of clearly defined use cases is better than a small number of large, ambiguous ones.
The next step is to elaborate your use cases, and that's where you can start talking about conditions. Elaboration is typically done using an activity diagram which describes how the interaction between the actor and the system proceeds, eg Poster initiates post; System checks poster's privileges; System rejects post if privileges are insufficient; etc.
There is of course no right or wrong, but generally speaking it's a bad idea to use actors such as "logged in user" etc, and in fact you should avoid employing a "user" actor at all. Why? Because the interaction is actually between the system and a person, whereas a user (account) is an in-system representation of a person's privileges.
In other words, if you find yourself using actors which are in fact concepts from within the system, you've taken a wrong turn somewhere. Every use case must involve a system-external actor, otherwise you're not describing the system from the outside.
A better set of actors for a forum system would probably be Poster, Reader and Manager (and possibly a System Administrator as well).

Three Step Buyonline The RESTful way

We are re-developing our buyonline functionality and we are doing it the RESTful way.
The process is a three step one and the customer is asked to enter data at each step.
Let's say the three URL's are;
/step1.aspx
/step2.aspx
/step3.aspx
Each step is pretty autonomous and don't require data from any of the other steps.
The question is how do I stop customers directly navigating to step2 w/out first completing the details in step1 given each step knows nothing about the previous step?
I know I can add a property to my object model telling me which step was the last one etc but doesn't that kinda break the whole REST principle?
I also don't want to check my model as to whether details in a previous step have been fileld in because again that violates REST principles.
I think I'm slowly resigning myself to a concept that I need (something) to tell me where I have been but I don't want that.
Should/Can the controller perhaps detect that the history doesn't contain the previous step placing control back to where I think it should be?
REST URLs are supposed to represent entities. e.g. books / orders / photos etc.
I think the confusion above is that you're trying to represent a booking sequence in REST terms as entities, and (of course) they're not. So the objects that your customers can select, their orders etc. may be usefully represented in this fashion. Other elements of the process shouldn't be.
You may argue that step 1 represents an address (for the sake of argument). But POSTing an address object is distinct from entering that data in a form and permitting navigation to/from related pages. That operation has a sequence or flow to it, and is conceptually richer than simply POSTing/GETing/DELETEing an address. You've illustrated this by arguing you want to prevent someone completing step 2 without completing step 1 etc.
When going from step1.asx to step2.asx, pass a query parameter that contains some key that tells the server that step1 was visited. For example, step1.asx has a href to step2.asx?whatever=a92jv29.
The "a92jv29" can be, for example, encrypted timestamp from the server. You can easily verify that it is valid (not expired and not from the future) in the server side. No need to store the state.
Your URL's could have better names, should as "terms.aspx", "registration.aspx" or whatever but that is strictly not necessary.