Linear conversations

Hi
I've posted about this on the previous forum (https://buddyscript.colloquis.com/forums/showthread.php?s=9b7f429d59865822e5f78c1958603b30&threadid=1376&highlight=topic)

but did not get any responses.

Is there any chance we can get a decent example of a conversation flow, even if with SetTopic? What I'm after is the ability to get a follow-up question / comment done by the Agent based on the current topic...

Thanks
Riaan

[449 byte] By [Riaanvs] at [2008-2-20]
# 1

Hi, Riaan -

Good question! For the sake of context, I'm going to copy some snippets from your post on the old forum.

First, you provided a generalized example illustrating a common scenario where an agent fails to "stay on topic" the way a human would:

Ideally I'm trying to get the bot to continue with a conversation.

Example:

1. Routine produces a result
2. User puts in unhappy face e.g. Sad
3. Bot asks what's wrong
4. User says something in relation to the routine at 1.
5. Bot does not tie it up..i.e. comments but not in context of the routine.

Later, you pointed out a case where agents do manage to stay on topic...

...could you explain how the bot can do this:

Me: Call me Riaan
Bot: You asked me to call you X, now ... Riaan?
Me: No
Bot: What would you like me to call you?

...and then gave an example of something similar (but not exactly the same) that you wanted to acheive:

...I would for instance like to do this:

Me: I like cars.
Bot: That's cool.
Me: I would like to buy one.
Bot: Let me see where I can help you buy a car
[procedure for cars here]

So, with that for context, let's discuss. In a nutshell, there's no single, universal approach to enabling your agent to have multi-turn conversations. Rather, the BuddyScript language and libraries provide a set of features (dialogs, domains & contexts, custom-scripted logic, etc.) that you can utilize to implement "conversational smarts" on a case-by-case basis. Over time, the BuddyScript libraries will provide more tools to help in this area (in fact, we're working on some now), but for the foreseeable future those will just be additions to your bag of tricks, not a centralized solution for conversation-management.

Let's take a look at your specific examples:

  • The first example, I'm afraid, is a bit too vague to suggest a specific approach. We would need to have a more concrete idea of what the agent said in Turn 1 and what the user said in Turn 4 to make any recommendations.
  • The second example is easily handled using dialog syntax. For example:

Code Snippet

? Call me NAME=AnythingStrong.

NAME = StringUppercaseInitials(NAME)

if NAME eq G_NAME

- I already call you G_NAME, silly!

else

- You asked me to call you G_NAME. Want me to call you NAME instead?

? Yes

G_NAME = NAME

- OK, I'll call you NAME from now on.

? No

- Fine. I'll just keep calling you G_NAME unless you tell me otherwise.

  • In the third example, it seems like you might be hoping for a mechanism to automatically resolve anaphora (figure out references to previous subjects -- in this case, to figure out that "one" refers to a car). We are in fact working on a rudimentary mechanism like this for a future version of the libraries, but it's only semi-automatic, and it won't work in all cases...it's actually a very difficult problem to solve across the board.

With that said, I think you stand a pretty good chance of achieving what you want if you try to tackle smaller problems individually. For example, if you want your agent to jump on opportunities to promote additional services/content/funcionality that it offers, I would actually recommend taking a more active approach and aiming to avoid the scenario in your example.

To do so, I would special-case my responses to statements like "I like X," so that the generic response only occurs if I don't have anything further I'd like to say on the topic. In response to "I like cars," the agent might instead say something like "Cool! Would you like me to help you buy one?", or "Cool! I know a lot about cars. I can give you detailed model info, price quotes, or help you buy one. Just ask!" In the context of this customized response, you could script a dialog where a reference to "one" is explicitly understood to mean "a car," thereby avoiding the need to have the agent figure this out automatically.

Hope this helped! We'd be happy to answer additional specific questions on this topic, so feel free to ask.

- Gray

GrayNorton-MSFT at 2007-10-3 > top of Msdn Tech,Windows Live Developer Forums,Windows Live Agents Development...
# 2

I also have a need like this...In my case I'd like to have the user essentially select a conversation when they first connect and then follow a linear progression with yes or no questions and possibly more feedback. (I'm thinking this would mean a separate domain for each "conversation"). I would have some kind of keyword they could use to break out of the conversation and redirect. Essentially my bot is a troubleshooter. So I need the user to tell me the problem they are having and then from there I control the conversation having them perform the troubleshooting steps and informing me when they are done so we can move to the next step. I also plan to incorporate the activity pane to include screenshots or link to kb articles. Any advice is appreciated.

T

TreySmith at 2007-10-3 > top of Msdn Tech,Windows Live Developer Forums,Windows Live Agents Development...
# 3

One thing you might consider is allowing users to break in and out of the troubleshooting dialog freely, by storing what steps they have done and adding matching to let them back in.

Code Snippet

procedure CheckGas()
if !G_TROUBLESHOOTING_STATE["Check Gas"]
- Are you out of gas?
? Yes
G_TROUBLESHOOTING_STATE["Check Gas"]++
- You'll have to fill up the tank.
call DidThatFixIt()
? No
G_TROUBLESHOOTING_STATE["Check Gas"]++
- Okay. \c

procedure CheckBattery()
if !G_TROUBLESHOOTING_STATE["Check Battery"]
- Did your battery die?
? Yes
G_TROUBLESHOOTING_STATE["Check Battery"]++
- You need to get a jumpstart.
call DidThatFixIt()
? No
G_TROUBLESHOOTING_STATE["Check Battery"]++
- All right, then. \c

procedure CheckRadiator()
if !G_TROUBLESHOOTING_STATE["Check Radiator"]
- Is there steam coming out of the radiator?
? Yes
G_TROUBLESHOOTING_STATE["Check Radiator"]++
- Wait for the car to cool down, then fill the radiator slowly.
call DidThatFixIt()
? No
G_TROUBLESHOOTING_STATE["Check Radiator"]++
- Okay. \c

procedure Mechanic()
- You probably need to call a mechanic.

procedure DidThatFixIt()
- Did that fix your problem?
? Yes
- Great!

exit all
? No
- Hmm... \c
call CarDied()

procedure CarDied()
call CheckGas()
call CheckBattery()
call CheckRadiator()
call Mechanic()

? my car died
? my car is still dead
call CarDied()

Hope this helps!

TomRagle at 2007-10-3 > top of Msdn Tech,Windows Live Developer Forums,Windows Live Agents Development...
# 4
Thanks for the excellent example...in my mind that is pretty much the approach I was going to take...glad to see I'm not alone.
TreySmith at 2007-10-3 > top of Msdn Tech,Windows Live Developer Forums,Windows Live Agents Development...

Windows Live Developer Forums

Site Classified