What's up, builders? So today I want to go over advanced function calling inside of the agent node. And for those of you that are unaware, this is voice flow that came out with this agent node a couple weeks ago. So I'm going to. Showcase some of the stuff I've been testing out in here with this recent build. And this is gonna use both voice flow and N eight N for a couple of different function calls. So we're gonna just jump right in here and I wanna show you some of the things that I like inside of here as far as the dynamic capabilities.
Alright, this is a, a regular greeting message. Nothing crazy here. I hit this first. Agent node, how can I help you? And I'm just using this as an introductory router based on some intents, and maybe this is something that you've had previously in builds where you have a bunch of different intent types and it jumps around the canvas. I just threw it all in this agent node and there's no function calls in here, but I want to qualify the type of call that I'm dealing with. So if I say.
Yeah, my garage door is broken. I need someone to fix it, which sounds like a pretty normal request. Sorry to hear that. Let's get this resolved for you. Could you please provide me with your zip code so I can check if you are in our service area? All right. Handled that great.
But what actually happened here is the router. Hit a pathing here for garage door repair. I'm setting a job type to a specific value because I'm gonna use this later. And then I hit this zip code and availability. And this actually, there's a lot happening in this one node, in this interface. And that's where I wanna make kind of the main topic of the discussion today.
So if I enter my zip code here, 0 7 4 4 4. Thank you providing your zip code. Good news. Your location is within our service area.
Let me check the available appointment times for you. This will only take a moment and you'll notice that I have two separate messages here and two separate bubbles, and this is not me instructing. The agent or hard coding a message bubble to do this then that this is all based on function calls and giving the agent proper context of how I want it to handle the responses from this function. So. First one zip code.
It's in our service area. Now that I did just make this value up, no, of course I actually went and pulled information from their backend. I'll show you that here in a second. And verified that that zip code is actually within our service area. 'cause if you're building an agent for a home service franchise, guess what? They've got a lot of different locations and their owners.
Their service areas, but up against each other. And you wanna make sure that you are servicing the right zip codes for the right franchise location. So this is, this is not optional, like this has to be dialed in. The second part of this, the first available appointment is on April 5th, between 8:00 AM.
And 12:00 PM which is tomorrow morning. Will this time work for you or would you prefer a different time slot? Um, do you have anything in the afternoon? And what happens here is this gives me immediately 12 to four. Now is this just because I went into the agent and said, okay, here are available times eight to 12, 12 to four. No, this is once again pulling actual availability from the dispatch board connected to the CRM of the franchise.
This is real live availability that from a potential customer I can now interact with on a chat interface and find a time that works for me. What are all available times for Sunday? Perfect. Eight to 12, 10 to two, 12 to four, two to six. Do any of these times work for you? Yeah. Two to six is great.
So then I can route. To the next agent, which is customer information. Now, I'm gonna stop here and not enter my phone number and do all this because this is like actual customer data account lookup stuff. But I wanted to show you that you can string these things together in an agent to get some pretty cool dynamic functionality. Now let's kind of. Peek under the hood, and then we will try to mess around with some other dynamic stuff and I'll show you what's going on.
So I'm gonna go ahead and reset this chat, but let's look at this booking agent. Okay? I have two functions sitting in this agent here, and for those of you that have not looked at the agent node yet, you hit this little plus sign. Or you can actually hit community, already created functions, right? I wrote these from scratch. Zip code lookup looks up the zip code of the customer to verify our service location. It's gonna take two input variables.
One is my web hook to N eight N, and the other is the zip code. Now look at the difference here. One of these says default value, which I have a variable stored here. For my webhook, URL that I've also masked as a secret, so I don't want that viewable. Use the default value. Always perfect.
Then I have the zip code. The LLM is actually going to collect this information, which you all saw. Just work a second ago. Now let's look at all of these instructions. Giving it, you know, just a general, hey, couple of sentences, but then acknowledge the issue.
Ask the customer their zip code, call the function. But not only that, I. I'm actually gonna dictate what happens based on what the function returns. So I have an in-service area path, out of service, area path, and I want the agent to handle each of these situations in a different way.
So if I go look at this function for zip code lookup, I'm going to hit. This N eight N webhook, URL, wait for it to execute. Then I'm going to parse it in a certain way that I want it, and then output a bunch of variables. Now you'll see this alternate location, alternate phone, alternate website.
What is this? Let's look at our N eight N workflow. So I have a web hook, which is what you saw in the voice flow function. I then am going to set. A zip code and an email address, which I'm not currently using at the moment. I was for some testing with some custom launcher stuff. Then I am hitting a config, right? I'm actually going to hit a configuration for this franchise's backend to pull all of that information because the, here's what you don't want, alright? You're gonna create this.
Give me all of the zip codes. That your franchise currently services, and then you just have some manually constructed array of zip codes because what's gonna happen is. That's going to change over time, and you don't want an email that says, Hey, agent Builder, you remember that hard coded array that we made of zip codes? Yeah, I actually just added a new service area. Can you go in to your agent and modify that? No.
No, that's, that's not what you want to set up. What you want to do is dynamically pull the config. From their CRM of their actual available zip codes and then construct your own array. And once we do that, I have two set steps basically here that allow me to. Pull all of the zones, combine all the zip codes in one array. I probably could have done this with two steps, and then I'm gonna check as a very basic JavaScript function, is this zip code matching one of the values in our array? And if the answer is yes, I'm actually gonna kick out up here and respond to this web hook with nothing.
If it's in the service area, I have a blank web hook. Okay, now what is this out of service area branch here? I obviously showed you guys a successful one just a few minutes ago. This is actually gonna go and pull if it is out of the service area. I wanna find which franchise location that the customer can be serviced by and give them the appropriate contact the details. In order to help their problem because then the lead stays in the franchise, right? And everybody wins.
And you don't get this chat bot. I'm sorry I can't help you. You're not in our service area. Let us know if you need anything else, which is like the typical dumb chat bot response. So if I reset this.
I have a broken spring. Sorry to hear about that. Let's get this resolved. Can you please provide me your zip code? 2, 3, 4, 5, 5, which is in Virginia. It is not in New Jersey.
So we know this is out of service. What is this response going to look like? Takes a little bit longer because there's some more calculations going on. Unfortunately, it looks like your location is outside of our service area.
However, I can direct you to an alternate service option. Precision Virginia Beach. Here's a phone number.
Here's their website. I recommend reaching out to them. For assistance with your repair, boom, click on this link. Look at that opens right to their website. Now, it is helpful obviously that this franchise has this loca, this information available.
'cause otherwise I would have to construct it myself and then put it as part of, you know, the build. But anyways, ways, if this goes through instead of a cl instead of an empty. Webhook body.
What I will pass back is the location, phone number in the website that gets extracted from that API request, and then it feeds it back into my voice flow function, zip code look up, and then it gets handled and returned to me. That way I can then access this. Alternate location, phone and website.
You look at my pathing out of service area, in service area, some of my variables here. I can then communicate these different paths and these output variables back to my agent. Node.
Call zip code lookup. If it's in service area, boom. If it's out of service area. Save the following variables from the function output, alternate location, alternate phone, alternate website, apologize, and inform the customer they're outside their service area. Provide the information to the customer as an alternative service option, and it just works. Just gives it to 'em.
Now, let's go on to check availability, because if you remember, I had one bubble execute function, zip code lookup. Oh. If you're in our service area, congrats now because I know you're in our service area.
Let's go ahead and look up our earliest available times so we can give you our real availability because as you can imagine, a customer facing chatbot that's sitting on a website. The primary call to action for this chatbot is to book jobs, right? That's why you, that's why companies pay money for you as an agent builder to build them something valuable. What is, what is the ROI? It's, this is a self-service book jobs.
Every job booked on this chat bot is a phone call. To your customer service reps that you just saved. You don't need to pick up the phone. If you have a self-service chat bot that can just book jobs right from your website, right? So we're gonna hit as soon as zip code lookup and it's in service. You're gonna call this function.
So I have two functions sitting in this agent node that are going to get called. Pretty much in parallel. Not exactly in parallel, but if in zip code is in service, call this immediately, boom then, and you saw that with the agent one message bubble, congrats you on zip code.
Let me look up your zip code. Boom. Our first available appointment.
And that's both those function calls happening side by side from a user perspective. So if I go into check availability. I once again have my URL default value. I'm taking in a job type 'cause I actually need this job type to construct the URL path for my API call on the back end and also the zip code, which I have also just recently collected from this note, from sitting in this note.
If I go to the function check availability, same thing. I'm passing zip code. And job type and the body of this web hook. Then we're gonna do an AWAI fetch of the URL with the config body that we're passing here, and I'm gonna handle this how I want inside of this voice flow function.
Now, one of the questions that you might have is, Connor, why did you include N eight N in this particular workflow? Couldn't you have just written the both of these? In a voice flow function block. That's, that would be a good question for you to ask. Okay. Here is why I want the NA and N ran out for this particular situation. Number one, I think the debugging I. Pulling config data and messing around with schemas, it's way easier to do an NAN from a UX from a developer UX.
Number two, there's a good chance that I'm going to use these workflows in other areas outside of the voice flow environment, so I have no problem spending the time to make them an N eight N. Knowing that they have some reusability, which I would not get in an exclusive voice flow syntax function, if that makes any sense. Now, that's not a free choice, obviously, because then if this automation is going to run. Lots of times. Then I have two backend as a service platforms that I would be paying for for this particular solution. Which one is voice flow and the other is NAN.
But of course, I can always host my own NAN instance, which I will do for this particular use case. So that becomes less of a concern for me. Okay. I'm checking availability. This particular organization uses a custom scheduler connected to their CRM. And as you can imagine, they have different job types because technicians have special skill qualifications.
For example, electricians. You're not gonna send a first year apprentice to do a panel job, probably, at least not by himself. So from an ops perspective.
You need a way to dictate which of your technicians have the appropriate skills for the appropriate job types that you are booking. So you as an agent builder have to be able to handle different job types. So once again, I'm gonna pass the zip code in the job type, which you saw from my webhook and that function back into this config.
I'm gonna edit some fields here, which I believe are, this is has to do with booking buffers information, and then I'm actually going to construct the URL that I need in order to pass along this API call here. So this is just once again, just me prepping for the actual availability request. I'm not gonna pull this actual URL for you here because this is a private API that is not accessible to the public. But then here's something that you also have to take into consideration, right? This gets availability and outputs A-J-S-O-N object that has a bunch of Z times, which a user is not really going to be able to read that and understand what's going on.
So this function basically presents the information in a much more viewable way and converts it to the appropriate time zone. Right? Because we're dealing with Eastern time here for this particular build. In case you're wondering here, Nope, that's not what I wanted to say. This, oh, the dock type here. So this is basically, uh, an error that's popping up because I click through this here instead of actually having the web hook come in. But I'm just using this to showcase you what's kind of going on here.
So no worries there. Anyways, I've been saying a lot of stuff here. Let's look at the output variables, so I have a formatted output and time slots here. This is a very basic success and error path.
Nothing crazy here. Let's go back to the agent instructions. I. Call check availability using formatted output, one of our output variables. Offer the customer the first available appointment time.
Work with the customer to select an appointment time that works for them. That was showcased when I was going back and forth and saying, Hey, what about tomorrow? What are all your times available for this date? Like you have given this agent. A function output that is formatted in a certain way that has a bunch of information, a bunch of real time availability information. That is how you make it dynamic. The other thing that's nice is you'll notice this access to knowledge base is clicked on trigger the knowledge base. When a user ask a general question, instead of providing information about booking an appointment, so for example, if I go in here.
And I say, hi, how can I help you? I have a broken spring. Sorry to hear about that. Could you please provide me with your zip code so I can check if you're in our service area? Now, I'm sitting in this agent note here. If I ask a question, do you have any positive reviews on your company? Not sure I can trust you. Thank you for asking.
It's locally owned, five star average. 95.2% of our reviews are being five stars. Our technicians are professionally trained, certified, drug tested, background checked. Where, what, where is this at now? In the conversation logic, it's in the same place. It's sitting in this node.
I have not left this node at all, and I'm waiting for the customer. To provide me the information and for the appropriate functions to be executed in order to path out of this node, which allows a much more dynamic interaction set instead of, this is a fixed block. Okay, give me your first name. Okay? Give me your last name, give me your email. Let me check if this email exists.
This is Howell. We get out of that fixed form, flow build, and we inject some dynamic capabilities while using functions and providing them back to the agent in order to craft a really positive experience for customers that use your agents. On their websites to do various things.
Sure. I'll give you my zip code. It gets back on track.
Here's the answer to your general question that you just asked randomly. Let's get back on track. Could you please share your zip code so I can check if you're in our service area? Great news. Here's our first available appointment. Real time availability.
Will this time work for you? I just checked with my wife. She won't be home. Anything the next day. No problem. April 6th, eight to 12.
Uh, I think about it, it's a bit early. Anything later in the day. Immediate, immediate response, no, no thinking, and that is because you've already provided the necessary information to the agent in order to have this conversation, because the pay payload from your function call is sitting in the agent. This works great. I am now pathing out of this agent, going in the customer information where I will collect its details and do the same exact thing to get everything that I need in order to book this job direct to the technician's calendar. No human interface necessary.
This is how you build. Valuable agents. This is how you make them dynamic.
This is how you solve problems. I think this is a pretty good first crack at me incorporating some of these agent nodes and real builds and being pretty pleased overall with the process. So.
Write those functions. Give it the proper context, give it the proper pathing and guide this agent to handle all of the things it needs to 'cause. I think we're going to start building some really, really cool stuff moving forward. Got any questions, feel free to shout out. Talk to you guys soon.
Thanks.
2025-04-10 11:07