Back to Index

Variables and Flows for Chatbots | NeMo Guardrails #2


Chapters

0:0 NeMo Guardrails
0:47 Variables and Flows in Colang
2:50 Setting Variables with the Context Role
5:6 Setting Variables from User Input
7:25 How the Greeting Flow Works

Transcript

In this video, we're going to be exploring Kolang of Guardrails a little more and specifically focusing on the variables and flows within the Kolang modeling language. Now, Kolang is the modeling language that has been built specifically for building conversational flows for chatbots by NVIDIA and is used by the NVIDIA Nemo Guardrails library.

Kolang is pretty simple and it's relatively easy to read, particularly if you know Python as well. But there are a few concepts and items that we need to figure out before we begin using Guardrails more. That being said, whilst we're figuring this out, we will be using Guardrails on top of these anyway.

So we're kind of learning as we go. Now, we're going to be going through this notebook. There'll be a link to this notebook at the top of the video right now. And what we're going to do is just take a look at these variables, how we set them, and also the flows.

So we have the definition of a flow that I've already shown you in a previous video, but we also want to take a look at the if/else within the flow and how we can use that. And that fits quite nicely with variables. So what I first want to do is we'll initialize our OpenAI API key, and we're going to initialize our Colang file and our config file, right?

So let's just take a quick look at what we have here. We have a user greeting. This is our user message, canonical form. And these are some utterances that can define what that should look like. Then we have our bot message, canonical form here. And when this is called, we're going to return this, which is "Hey, name," right?

And just note here that the name is preceded by this dollar symbol. That means that this is a context variable, so a variable within the context of our Colang file. And then we define a flow. So this flow is initialized if we see a user greeting, and we can see that we have an if/else statement in here.

So if name, basically this is saying if the name exists, if that variable has been set, then the bot is going to use this greeting here. So it's going to use a name. Otherwise, the bot's just going to do a greeting, right? We haven't defined this canonical form here, but the way that Colang and Guardrails works is actually the bot can just read this and build its own sort of message from that.

So it will basically create a greeting. So let's try this, right? So we're going to initialize our Rails using those configs. And now here we're doing something slightly different to what we were doing before. So before we were doing like this, we had instead of messages, we were just passing in a single prompt.

And that's a completely valid way of doing this. But by passing in messages, we can also pass in conversational history, which one is very useful by itself, but also we can pass in this context role. And this context role, I haven't defined anything here yet, but it will allow us to pass in variables or set variables at the beginning of the conversation.

So within the messages that we're using here, we're allowed to use three different roles. We have that context, we have the user and we have the assistant. I've commented this out because I want you to see an example of what that assistant role would look like, but we're not actually going to be using it, at least not yet.

So we'll initialize those messages and we'll pass them into our Rails. And we get this response from the assistant role saying, "Hey there, how can I help you?" Very similar to the prompt approach. It just, we have that history in there and we have the content. So with this, the bot is just saying, "Hey there, how can I help you?" We kind of wanted to trigger this.

So right now it's gone to else because there is no name defined. It's just created a bot greeting, right? It's generated the greeting by itself. So if we'd like it to trigger the name here and trigger the bot name greeting, we need to pass in a name. And we can do within the content.

So within content, we're going to pass a dictionary. And that dictionary can contain our context variables and their values. So I'm going to pass in my name through this. And actually, I'm going to remove this middle message from the assistant. And now this is exactly the same as what we had up here.

But now we just have the context variable and name for James. So let's run this. And we see now that it triggers the, "Hey, James." So that is the form that we specified here. Okay. So that's now working. Now let's try adding these context variables from within the conversation rather than just at the start of it because we can do that too.

Okay. So what I'm going to do here is I'm going to define a few things. So I'm going to define the user giving a name. And there's a few examples here of what that would look like. We still have these. So these are from before. The user greeting and the bot name greeting.

But then we define a new flow. This flow is when the user is giving a name. Okay. So initialize by this. And so this is kind of an interesting way of doing things. We can take the name from the input. And when we're using this syntax here, an LLM is actually going to extract the name.

Okay. The way that I've written it here is very clear. I'm saying extract the name from the user's response. So an LLM will actually do that. And it will pass the name that it extracts into this name variable here. And then after that, we can actually call the bot name greeting.

Right. Okay. So here we're just saying if the name does not already exist, which it won't do, just ask for the name. Okay. So let's see how that will work. Run this. We're going to have to remove the name parameter from the context. So let me move that as well.

We reinitialize our Rails. And now we're going to generate. Okay. We see here that the assistant is saying, "Hi there. What's your name?" Okay. Why is it doing that? Let's take a look. We have our user greeting. This is being initialized because we say, "Hey there." If not name, so no name is defined, the bot will ask for the name.

Okay. Which is what it does. "Hi there. What is your name?" Then we're going to respond. Okay. So first we want to add this response from the assistant to our messages. So we add that here. And then we also add our response. Okay. I'm going to say, "I'm James." Okay.

We run that. And now, because we have the name, because that has been added, it will respond with, "Hey, James." Okay. So we come up to here. Our input is us giving the name. I said, "I'm James." So we trigger this flow, user give name. We extract the name from the user giving it using the LLM, and then the bot responds with this bot name greeting, which is, "Hey, name," which is exactly what we get down here.

Okay. So that's just a quick introduction to how variables and flows work within Colang and Nemo guardrails. I just wanted that to be a very quick introduction to those. In the next video, what we're going to be looking at is something called actions. So the execution of actual code from within our guardrails, which will be pretty interesting.

So for now, that's it for this video. I hope this has been useful and interesting. So thank you very much for watching, and I will see you again in the next one. Bye.