How to Build a Personal Assistant AI Agent in n8n (Step-by-Step, No Code)

Dr. Violet Howard builds a personal assistant AI in n8n that responds to Telegram messages and coordinates email, calendar, and research agents. It handles voice input and output, pulls contacts from Google Sheets, and creates calendar events or sends emails based on what you ask it to do.
Chapters
Hey personal assistant, can you please create a calendar event for tomorrow with Michael Scott at noon for a meeting? And then can you email him to confirm if that time works? And then finally, can you grab all of my calendar events for the rest of today? Thanks. Okay, so we just sent that off to Telegram. It's transcribing that audio. It's now hitting the personal assistant, and the assistant's going to take the contact information. It's going to create that calendar event with Michael Scott. Now it's going to hit the email agent so that it can send out that email to to confirm if that time works. And then finally, it should come back to us with a text message as well as a voice file or an audio file that's going to be telling us about what we asked for. So here's the information. The calendar event was created, the email was sent. We've got our information about the remaining events for today. And now, as you can see, that audio file is being created. So let's listen to that real quick. A calendar event has been created for a meeting with Michael Scott scheduled for tomorrow, November 29th, 2024. From 12 PM to 1 PM. An email confirming the meeting time was sent to him. Today's remaining calendar events include a meeting with Michael Scott from 12 PM to 1 PM, dinner from 5 PM to 6 PM, and dinner with Michael Scott from 7 PM to 8 PM. If further assistance is needed, please let me know. Awesome. So that's how this works. That's, uh, the agent that we just saw right here. We're going to be jumping into the build. So let's get into the video. All right, so now we are going to get into the actual step-by-step tutorial for the demo you just saw of the personal assistant. So we opened up a new workflow. As you can see, we've got personal assistant step-by-step, and we are just going to start building out this agent. So first thing we want to do, obviously, we're going to grab the actual agent. So we're going to grab an AI agent here, and we're going to leave this as a tools agent. We'll get into the prompting of this guy sort of as we start to add more tools, but that's all we got to do to start with. So As you saw in the demo, we were talking to this agent through Telegram, so we're just going to go ahead and get rid of this, um, this trigger real quick, and we're going to add a Telegram trigger. So we've got different triggers, we've got different actions, but we're going to do a trigger of on message received. So that way, anytime that we text our Telegram channel, it will basically start this workflow for a personal assistant. Just a quick reminder, as always, the workflow for this whole assistant and the other agents that we're building out today will will be in my free school community. The link for that will be down in the description. And then if you're looking to get a little more hands-on, you're looking to go further with automations with N8N, then feel free to check out my paid community. That link for that will also be down in the description. And then finally, if you're looking for some sort of assistant, if you're looking for automations, if you want me to build out some of this stuff for you or for your business, then go to my website down linked in the description and book in a call and let's chat. Anyways, back to the build. What we wanna do now is add the chat model. We have to add the brain for this assistant so that it can, you know, think about what we're asking it. It can think about what agent it needs to go to, what tool it needs to go to, and then it will ultimately give us a response. So in this case, I'm going to be using 4.0 just because, you know, it's going to have a ton of different tools connected to it, and we want these responses and, you know, the, the sending of data across workflows to be as accurate as possible. So I'm going to go with 4.0 here. Now we're going to add memory. That way, when we're talking to this assistant, it has context of previous messages. So we'll click on this plus. We're going to add window buffer memory because it's super easy. It's going to store this memory in N8N, and it's super easy to set up. But one thing that you have to do here is we have to set up the session ID, because if you leave it like this, it's not going to work. Because it's looking for— basically, this would work if you're chatting with it through a chat trigger. So if we go to a chat trigger right here and we connect this, if we chat with this agent through the trigger, we just say this. Now it will go to the window buffer memory because we have it configured to take from the previous node automatically. And in this case, it's coming through as, um, you know, JSON dot text or something. So, or chat ID. Anyways, if we're to do this with the Telegram trigger, so if I click, um, let's just get rid of this, we hit test workflow. And then I pull up my Telegram real quick and we just say hello, it's going to go through, but it's not going to actually store in the window buffer memory. So we— what we need to do is we need to see how the chat's coming through from our Telegram. We can see that it's coming through, um, right here. Let's go to schema actually, and we can see it's coming through as the chat ID. So all we need to do in here is instead of setting this from take previous note automatically, We're going to define it below. It's going to be an expression, and we're going to be pulling that chat ID from the Telegram trigger. So we'll click on Telegram trigger. What we need to do is go to.item.json.message.chat, and then we go to ID. So now we have that ID in there. As you can see, that is what's being stored as the key for our session ID. We'll hit save, test this workflow again. We'll come into here in Telegram and say hello, and we'll No prompt specified. Okay, we have to do this also. We also have to define where we're getting this from. So the text that's coming into our agent is no longer the chat input that's coming from a chat trigger. What we're wanting is the text that's coming in from Telegram. So chat.text down here, we'll drag this in here, and now we're getting the actual message. We can hit test step now, and we can see that it's being stored in the window buffer memory. So the past videos, I've had some people, um, ask questions about that. That's all you have to do. You have to define the agent where it's getting the message, and then you have to define for the window buffer memory what channel it's being stored in. So that's how that works. Another thing I'll touch on real quick is with the actual Telegram trigger. If you're having trouble connecting your credentials, once you're creating a credential in here, you basically just need to get your access token, and then you can see you have this URL. So in Telegram, all you're going to do is you're going to set up— you're going to talk to— let me pull up my Telegram real quick. If I just expand this a little bit more. If I go back here, you'll have your Botfather. And so you'll go into your Botfather, and that's how you can get your access token. You'll have to plug in some credentials. It's not super difficult at all. If you are having trouble, you can click on Open Docs right here. It'll walk you through exactly how to set up your, you know, your API, get your bot access token. You'll talk to Botfather, you'll enter this command, and it's super simple. So then once you get that set up, you'll just pretty much plug it in, and then you'll be good to go. For the rest of the time that you want to talk to Telegram in N8N. All right, we have the brain for the agent, we have the memory for the agent, and now we're going to start adding on the tools. This is where the magic really happens. So the first thing we want to do is we want to get a contact database into our agent so that it has access to different email addresses, different phone numbers in case we want to send a text, an email, calendar invite, that sort of stuff. So in this case, we're just going to be using a Google Sheet. You could do a contact database in Airtable. You could do it into Pinecone if you had a big repository of contact information. You could put that into Pinecone, a vector database. In this case, we're just going to be using Google Sheets to keep things simple. As you can see, we have information here, and this is what we're going to be giving our agent so that it can reach out to the correct people. So we're going to click on this plus for tool. We're going to grab a Google Sheets tool. You have to connect your account here. It's very simple. You can also click on Docs and you can figure out how to you know, go to Google Cloud, set up your credentials, your OAuth consent screen, all that kind of stuff. And I've also walked through that in other videos like the NNN Masterclass, other videos on my channel like that. But anyways, what we're doing here is we want to connect the right document. So we're going to grab, this one's called Contact Database, the sheet, there's only one sheet. So now that it knows it's pulling the information from here, we can leave all of this as is. We're getting rows. All that kind of stuff. So we're just going to rename this our contact database. Okay, so we've got that information into here. That's super simple to set up. And now we just want to make sure that, um, all this information is working. So let us really quickly test the workflow. We'll basically just come back into our personal assistant and we will say, um, can you get me Nate Hurk's email. And so this is actually not going to send anything back to us in Telegram because we haven't set that up yet, as you can see. But it went through the logic, and then the agent would actually be responding, Nate Hurk's email is natehurk88@gmail.com. As you can see, it sent over this query to the Google Sheet, and in here it pulled Nate Hurk and it found its email and then sent that back to us. So Real quick, what I'll do is we'll just set up the Telegram message. That way, for the rest of the time we're testing, it's actually going to come back in Telegram. So we're going to add something after the agent because typically it's going to get a query, it's going to figure out what it needs to do, it's going to hit the specific tools, and then it's going to output something over here. As you can see, one item was output, and we want this output to go to Telegram. So we're going to grab Telegram. This time we're going to do an action. So down here, We will see message actions and we will see send a text message. So at this point we have our Telegram account already connected, so we're good to go here. Now we just need to configure what this node is going to do. So we're going to be sending a message. The resource is going to be a message. As you can see, there's files, there's other stuff we can send. We're sending a message. And now we need to set up our chat ID and what the message is going to be. So because we have our trigger connected, it's really simple. We'll click on Telegram trigger over here in schema, and we're going to be looking through this information, and we're looking for chat ID. So the exact same thing that we gave our window buffer memory, we're going to give that to Telegram so it knows what, you know, channel it wants to send this message back to. So we can grab right here chat ID, we'll drag it right in there, and it's as simple as that. We are now set up. And then we just need to configure what text is actually going to be coming through through the Telegram. So text right here, All we have to do is we just want whatever the agent's saying. That's what we want. So we're going to grab the output from the AI agent, drag that into there. And now we can see we have our channel set up and we have our text set up. So if I hit test step, pull up Telegram, now we got that information. Nate Hurk's email is natehurk88@gmail.com. And then we also got this. This message was sent automatically with N8N. What we can do is go to add field, append N8N attribution, and then just flick that off. We'll test that again, open up Telegram, and now we got that message in Telegram, but we didn't get that attribution. So it's really clean. That's exactly how we want it. And we've pretty much got this guy set up. We'll just name this, um, response. And now we can see we have our Telegram trigger, and then we have our agent, and it will be actually responding to us in Telegram. So we've got this kind of foundation set up. Now let's continue to add more tools. Okay, what we're going to add now is an email agent. So what we're going to do is we're gonna go open up a new tab. We'll go back to the home screen of n8n, then we're gonna add a completely new workflow. So once this loads up, we'll click Add Workflow, and this one is going to be an email agent. So now we have an email agent that we're going to be plugging into our personal assistant. So the first thing we obviously need to do is add the trigger, which is going to be when called by another workflow. So this workflow is going to be called by our personal assistant whenever we ask, can you send an email? Can you get my emails? That sort of stuff. So this is the agent that's going to have all the actions within our Gmail. So we're going to add an AI agent once again. Um, we are going to just call this guy the email agent. It's going to be a tools agent. We'll get rid of this chat trigger because that's not how we're going to be interacting with this agent. And once again, we're going to set up our chat model. For this one, we'll use 4 on many because it's only going to have a few tools. We don't need to give this guy any memory really. And now we just have to add tools to this agent that is going to be a tool for the personal assistant. So what we want to do is grab Gmail. And this is really cool because within Gmail we have a ton of different actions we can take. And we're going to keep this, this agent very simple, just like we did in the, the personal assistant 2.0 video, but still use cool use cases of what it can do. So this first one, let's just do sending an email. So call this guy Send Email. We've got our Gmail account connected. Um, we want to be sending a message, and now we need to configure the to, the subject, the email type, and the actual message that's coming through. So what we're going to do is we're going to use this cool expression called From AI. If you want to go more in depth a little bit of how that's going to work, you can feel free to watch my video. I'll tag it right up here where I dive into this actual function. But it's just a really cool way to have AI interpret an incoming query and actually send out messages on our behalf, filling in these fields automatically. So the first one we're gonna do is the actual to field. So in here, we're going to grab from AI, and we are going to put in the key of what this from AI is looking for. And this is just gonna be, we'll just say email address. And then I want to define, actually we need to throw the quotes in there. So we've got email address, and then I actually wanna define what that means just in case. So the email address we are sending to. Okay, so we've got that set up. We need to do the same, a very similar thing with our subject. So we're going to come in here, also do from AI. And then this time we're just going to say subject and we can leave it as simple as that. We want to change the email type to text. And then in the message, we are going to do once again from AI. And we are going to say, um, email body. And so this really should work. We will test this out, of course. First thing I want to do is we want to go to append attribution. We want to turn that off. And then in this case, we can add a sender name. So, um, let's say, you know, we're always going to be sending from, from me because this is my personal assistant. So I'll put Nate in here. And this won't actually always sign off the email. This is basically just saying when it comes through in Gmail, who is it going to be sent from. So we'll see that in action. We'll save this, and then real quick, let's come in here and we'll just test out what this stuff's going to look like. So if we come in here and we put in the query, because when, um, when the personal assistant is going to be sending information to the email agent that we're building right now, it's going to send off a query. So we're just kind of putting in sample information of what a query could look like. So Let's say that we asked, can you send an email to Nate Hurk? And then also it would be giving that email because the personal assistant's grabbing the contact data and then it's forming a query to send over to the email agent. In this case, it's already gone and got my email, so it would send that over as well. And we'll just say asking what's up. So that's the query that we're going to be testing. This data will be pinned, so now we can come through and test this information. And we will pretty much just be testing the send email function so we can see how information is coming back. We'll hit run. No prompt specified. Okay, so once again, we can't just be taking it from previous node, we have to define below. And what we're grabbing is json.query. As you can see, now it's coming through. And now we'll test up. We'll see that it's going to hit the send email tool. Okay, so we're airing. Let's see what's going on here. Provided authorization. Okay, so I just need to refresh my credential. Let me just log in and do that real quick. So good learning opportunity right here. If you have your OAuth credential set as just a test app and you put in your information, I think those credentials expire every, you know, few days. So you just have to log in and do it again. But if you publish your app, then you should be good to go. So anyways, this information filled out automatically, right? So we got the query, that was, can you send Nate Hurk an email, all this kind of stuff. And so now this automatically filled that in. So it grabs the, the to, which is Nate Hurk 88. It grabbed a subject, it made a subject, what's up, and then it made an actual message, which as we can see, the message was, hey Nate, just wanted to check in, see what's up with you, hope all is well, best, your name. So the reason it signed off as your name is because we just haven't prompted it. The sender name, as you can see, we filled out down here, is going to be sort of a static sender name in our Gmail. So Let's open up the email, refresh this, and we should see the email that we just sent off. So we got, what's up? So you can see right here, this is, this is the name. That's what we put in the sender name. But if we wanted to actually sign off, we have to prompt the agent. So really quickly, what I'm going to show you is a cool GPT that you can use. If we come into here and we just say an agent who sends— or no, who takes action in Gmail, it should sign off all emails from Nate, never using placeholders. Okay, so we set that off really easy. It's a super simple prompt. Shout out to Tyler, um, who showed me this GPT. Super awesome. Great work, Tyler. But anyways, it's going to make it a super cool system prompt for you and it's going to be in Markdown. So the agent's going to understand like, you know, the headers, all this kind of stuff. So we've got that really quick. We'll copy that, go into our email agent, and we will add a system message and then we can come in here, paste that in. And so now it's going to be signing off as Nate. So let's save that. Let's try this one more time. It's going to send us another email. I'm going to pull up the email in here, refresh this. And so now at the bottom you see it's signing off, best regards, Nate. So that's sort of how that's going to work. Let's go back into Email Agent and let's add another Gmail tool. This time we are just going to be— so you can see there's— you can expand off this agent, give it tons of different actions. You can add labels, you can delete messages, you can mark stuff as unread. You have— you could basically add a tool for all these functions. In this case, let's just get many emails. Okay, so we have to set up the limit. We have to set up, um, we want to be asking like who they're coming from. So we'll say sender. And as you can see, there's different ways you could filter, you know, um, you could filter by date, you could filter by the status, all this kind of stuff. So you could, you know, configure this to say, um, if you wanted to get all emails from the past, um, you know, 5 days, you could come in here and you could set up the received after and the received before, and you could have the From AI figure out what it needs to do as far as, you know, what filters to put in here. But for now, we're going to keep it simple. We're just going to do a limit and we're going to do a sender. So in the limit, we're going to again use fromai. Okay, let's get rid of all this. We're going to be using fromai and we're basically just going to be saying limit. And I think we should be good to go with that. We'll test it out. And we don't want this to be simplified because this is going to return a simplified version of response instead of the raw data. So in our use case, in this example video, it should be fine, but basically it's going to cut off emails. So if you have long emails coming back and you don't want them to be simplified, you want to get all the content of the email to come through, then you're going to want to turn off simplify. And then sender, once again, we'll make this an expression. We will do, um, from AI, and then we're basically just going to be saying the sender to put the quotes, sender email, end it off with quotes, and we should be good to go here. And we'll just call this one Get Messages. Okay, so we've got this tool connected also. And now let's come in here and change the query. So, um, actually, first what I want to do is I need to send some emails to this inbox so that we can actually get them back. So give me a sec to do that. We now have 2 emails in the inbox. They're coming from a different email, as you can see in here. They're coming from up@digital@gmail.com, which we have associated with Michael Scott. So anyways, that's why they're signed off Michael, but they're coming through as Nate because my actual email is Nate. Anyways, we have this email stuff coming back, and now we're going to put a query in here that says, can you grab my Past emails from Michael Scott. And it would also at this point be getting that email, so up@digital@gmail.com. And this is just something that I like to do when I'm testing out different workflows. You put obviously the example query that would be coming through, and then you can go ahead and test them. So let's run this. It's now understanding that needs to get messages rather than send email. And it should be giving us basically a summary of those couple emails that we just got back. So we'll come in here and we'll see your current emails from Michael Scott. So it pulled all this information back, and there's actually a ton. So, um, because in here it's not just these two, we didn't set them as a filter to only pull back unread messages, only pull back messages from the past couple days. And also, if you remember in the query we just said past emails, we didn't say like past 2. So if I said, can you grab my past 2 emails from Michael Scott? Now we'll run this again, and it should be grabbing that limit because we put in, you know, the limit of how many emails that we were asking for right here. So now it says limit 2 from Upbit Digital, and now it's just basically making a summary of those emails. So right here we only have 2 emails. Email 1 was Project Mountain, and email 2 was want to grab lunch. So if you can see right here, we have Project Mountain and want to grab lunch. So now you see the limits working, we see, um, that it's getting it from the correct email. And then once you understand this concept, you could come in and start to add in more filters, like if you only want to get, you know, certain dates, if you want them to only be unread messages, all that kind of stuff. But this is just to give you an idea of the foundations of how these tools work within Agents. And how this agent is a tool for the overarching agent of the personal assistant. So now all we need to do here is we want this agent to respond back to the personal assistant. So if we grab a set field and we just call this field response, and all we have to do is drag in this expression, which is the information coming back from, um, the email. So we can see we have 2 emails, it's summarizing them, and then this is, this is what the, the agent's going to get. Um, so real quick, we'll just call this response. We'll hit save. And so this workflow is called Email Agent Demo. Now coming back into the Personal Assistant, we're going to add a tool and we're going to do Call N8N Workflow Tool because we're calling a different workflow. This guy's going to be called Email Agent. Just copy this into here as well. 'Call this tool to take action in email.' Sorry about the cursor right there. And so now we just need to configure which it is. So you can choose from lists, you can choose by ID, but list is really easy. We can just come in here and grab our— actually, we might need to refresh this page because— yeah, we're gonna have to refresh this page. So save this, refresh the page, because It wasn't refreshed since we made that new workflow called Email Agent Demo. So now we can come in here, grab Email Agent Demo right there, as you can see. And this is where we set up the response earlier. So the field that it's looking for, once the personal assistant sends off a query to this AI agent right here, it's going to be looking for a field called response. So that's why back in this workflow we set up the set field we called it response, and then we gave it the answer, which is the response. So now it's looking for that, and then it will actually hit it and be good to go. So if we test this guy from here, um, you know, we'll hit test workflow, we'll come into Telegram, and we'll say, can— this emoji thing is annoying— okay, can you get my past 2 emails from Michael Scott? So just like the query put in, as you can see, it has to— oh, this actually might be an issue because it didn't grab the contact data. So let's see what it said. It looks like there are no past emails from Michael Scott in your inbox. If there's anything else you need, let me know. So what happened is it didn't understand that it had to first get the contact information from Michael Scott, because then in the email agent, it was just looking for, you know, it didn't actually know who to go to. So let's go into executions of this email agent. This is the one that we just hit off, and we can see in here it doesn't have a, um, sender email. It's— it just made up the sender email, michael.scott@example.com. So that's why we need to prompt this guy to understand that it needs to look for contact database first. So let me do the same thing. I'll go into that GPT, make a prompt, and then I'll be back in a sec. Okay, I made a super quick prompt using that GPT. We outlined the role, we outlined its tasks, We gave the tool overview and usage guidelines, which is super important, outlining what each tool does, when to use it. And we basically had to tell it to use the contact database before going to try to send an email or, you know, make a calendar invite, stuff like that. And then at the bottom under reminders, you know, we gave it examples too, so showing how things should be done, which is super important, the process of it. But then at the bottom, we want to add another reminder that says here's the current date and time. So we basically just came in here and grabbed the function $now, and it would originally look like this, which, you know, the computer under— can understand it, but it looks ugly. So if you type in format, then you can grab this and you can change the way that the date comes back. So that's how that works. We're gonna hit test workflow. That's now listening for us. We're gonna ask, can you get my past 2 emails from Michael Scott? We're We'll send that off, and now it should be hitting the contact database before it actually goes to send that, to send that information to the email agent. Now it's getting those emails, it's going to respond to the personal assistant, and then it should hit us back with a message which is summarizing those two best emails. So as you can see, we now have email 1, email 2, which is exactly what we just saw. And real quick, we'll just test another one. We'll say, um, we'll have it just send an email real quick. Can you send an email to Nate Hurk, asking him how the Project Mountain is going. So same thing, it will hit contact database, it's going to grab Nate Hurk's email, and then it will pass off that query to the email agent, which should send an email. And then the personal assistant should let us know that it did that. So the email has been successfully sent inquiring about Project Mountain. And let's go to the email real quick, refresh that. So now we got in inquiry about Project Mountain. Um, hope Nestor finds you well. I wanted to check in, see how Project Mountain is progressing, all that kind of stuff. So one thing I think is super important is before you start to add more tools, you want to play with the prompting. You want to play with what's currently going on. It's going to save you a headache down the road. So now that we know that these functions are working, we can now come in and add a calendar agent. That's the next one we're going to build. So we're going to hop over to a new workflow. Um, we know that this email agent is pretty much working well. And like I said, you would start to add more tools onto here. But now we're going to add a calendar agent. So new workflow, this one is going to be the calendar agent. And first step, as always, we're going to be calling it by a, another workflow. So we've got this trigger, we're going to add an AI agent, and this one is going to be the calendar agent. So I'll move a little faster on this one because it's going to be the same principles pretty much as that past one. We've got our agent. We will once again, we saw that 4:0 mini worked fine for that, that email agent, so we'll go with 4:0 mini again. We don't need our memory. Now we can just come in here and start to add the tools. So our account's already connected. The first one we're going to do is going to be creating an event. We are going to connect our calendar, and now we just basically need to configure start time, end time, and then an additional property that we want to add is You know, we can add attendees. We can also add the summary, which I think the summary is the actual title that shows up as the, um, what's it called, as the title in Calendar. So this is what we're going to do here. And yeah, let's just start filling in that From AI stuff. So first what I want to do is add a sample query so we can play around with this data. Let's say that we ask the Calendar agent to Set up a calendar event for 5 PM for dinner. So we've got this. And so if it comes through like this, it basically means that we're just doing a personal calendar thing that we just want to block up some time. And also you can notice here that we haven't specified an end time, so all we're giving it is a start time. And so this should be interesting because in this node, which is creating an event, we have to give it a start time and an end time. So from here, we're going to do— once again, we're going to be using fromai, which is awesome. Oops, I don't know what just happened there. We're going to be grabbing fromai, and then we're just going to say in quotes start time. I'm pretty much just going to copy that and we're going to add that in here. And then we're just going to say end time. So this is something where in the prompting of the actual agent in here, this is where we want to say like if an end time isn't specified, just assume it's going to be 30 minutes after the start time or an hour after the start time. So we'll play with that. And for summary, once again, we're going to grab a from AI and we're just going to say event title. Okay, so we got this and we're pretty much gonna just gonna test it out. I'm not gonna prompt anything yet, we'll just see what happens. So we've got this, we will hit— oh, once again we didn't specify. So define below, you want to grab the query, and now we'll hit save and now we'll run this again. So now it understands what we're asking, it's going to create an event. And also I just realized Okay, this will be interesting to see. Let me pull up the calendar. I don't know where it created it because we didn't give it any sort of— yeah, so as you can see here, it came through as 2023, October 10th. So that's interesting, but we can see that it made the end time an hour after. So let me come in here and prompt this agent. We want to give it the current date and time so that it also knows when to make these events. Okay, so we want to keep this prompt shorter, straight to the point, because it's a calendar agent and right now we're only going to give it 3 tools. So we're going to give it create event, create event with an attendee, and then also to get events. So we kept everything super simple and we gave it the current date and time and we're just going to leave it as this for now. So once again, we'll try this. We will see that it's going to hit the calendar event. You can come in here and see now that it's getting it accurately. This is the correct date. This is the correct start time. Um, and then it called the event dinner. So if we go into the calendar, There it is. So 5 PM, we have dinner that was just created. Thanksgiving dinner, as you can see, today's Thanksgiving. But anyways, now that that's prompted in, we can add another tool. So if I can just copy and paste this event right here, we are going to call this tool Create Event with an Attendee. And so the reason that we're doing this in a separate workflow is because we have this option here for attendees. And so if we were to do this as just one thing and it was not to invite an attendee, it would leave this as null, and then it would probably— it would fail on the calendar creation side of things. And so there are, you know, some options to get through this. You can use specific operators, like there are some cool operators, um, which I'm planning on making a video about, like some advanced tips and this kind of stuff. But like you can use, um, two question marks, you can use two pipes, and and that sort of stuff will help you sort of almost dynamically tell if something's null, you'll go with this. But to keep things simple in this personal assistant build, we're just going to add two different tools and it's super simple. So we're going to come here and we're just going to basically say, um, attendee. And I think that that should understand it. If we are seeing that it's not working, we will come in here and prompt after the key, we'll give it a description. But this should be working great. So set a calendar event for— let's now do 7 PM for dinner, and we're going to say with Michael Scott, and it would also have included his email. And now we'll test this out. So we've got that prompted in already. We'll hit it. It should go to this one because it realizes that there's an attendee now. So that came through. Pop over the calendar. 7 PM dinner with Michael Scott. So that's working as it should. And now that we have these two tools, we will add another calendar one. And this one is going to be getting events. So right now we had it as create. We're going to do get many. Um, we're going to select the calendar once again and we'll return all. But now we want to do after and before. So when we're asking, can you get events from the past 3 days, or when you're asking, can you get events from today, tomorrow, we have to outline the parameters of, you know, it's going to go search Calendar, but which events you're going to be looking for. So that's what we need to set up here. Okay, so we're going to call this one get events. Um, and now this is going to be interesting. So let's say we were asking for Can you get my events from today? The, the filters we're looking for are events after yesterday and before tomorrow. So what we need to do in here is for after, we're going to have the AI figure out, um, we're going to call this one day before, and then we're going to outline that this is one day before the date the user requested. And so we've got that. Copy this down and see the after— or sorry, the before. And so now this is going to be one day, one day after. And then we're just going to say one day after the date the user requested. So if we think about this logically, we're asking for, can you get my events from today? And then it's going to be looking for any events that are after yesterday and any events that are before tomorrow. So we'll try this out, see what it does. In this query, we're just now going to be saying, get my events from today. So we'll save that and we'll run this, see what it does. It's going to be getting events, and hopefully it filled in these correct parameters. So we can see it did yesterday and tomorrow, so that's working correctly. And we can now see that we have our events from today. Perfect. November 28th. We've got dinner at 5, and then we have dinner with Michael Scott at 7, which, if you remember, those are the events we just created. So now that that's working, um, you know, we see that— we see the way that this is going through, and we see that it's pulling back the correct events. And, um, yeah, that's pretty much going to be it for the calendar agent, except of course we need to add a response so that it's getting back to our Agent. So we're going to add the field here, we're going to call this one response, and then we're just going to be dragging in this output once again, call this response. And then all we need to do is, um, come in here, we're going to refresh this because it won't have that workflow yet in this knowledge. Refresh the main agent, we're going to add another tool called from another workflow. This one is going to be called Calendar Agent. We'll copy that. We'll rename the tool Calendar Agent as well. Call this tool to take action in calendar. And I've had people ask me, what is the difference between the description you put here and then the description of the tool and the prompt in the system prompts up here? And really, it's not a huge difference. The tools are outlining what's going on when you would call this. But it's just best practice to also outline that in a tool section within the agent system prompt. So we've got Calendar Agent Demo, so when we just made, it's returning response. Um, and yeah, let's just test it out. We will hit test workflow and then we'll say make an event for tomorrow, um, with Michael Scott. At— okay, we'll do from 6 PM to 8 PM, and we'll just call it for a meeting. Okay, so now it's going to do that. It should grab the email, so it's— that's working well. It's going to now hit the calendar agent, and then it should respond to us with saying that that event was created. It may even provide a link to the event, which would be pretty cool. Obviously we can prompt that stuff in, but okay, so the meeting with Michael Scott's being scheduled. Um, project discussion, November 29th, 6 to 8 PM, Michael Scott with his email. And now let's hop into Calendar and we can see right here it got created. It got created twice because it did one for us and then one for the email invite with, uh, with Michael Scott. But that's great. So, um, that is working. And then real quick, we'll just test, can you get my events for tomorrow? Get my events from tomorrow. So real quick, just doing another test to make sure all our tools within our calendar agent works. Um, you know, that we tested out queries, but we want to see it working in action, the full picture. So make sure everything's working before we move on to the next tool. And now we can see we have 2 events scheduled for tomorrow. Like I said, the project discussion events got duplicated, so we would just have to go in there and fix that. But everything's working as far as it's able to create an event. It knows when to do an event by just us and when to do one with an attendee. It also knows to grab their email so that way if we wanted to do something like— yeah, actually let's do that real quick. So we're gonna test this again. We're gonna say create an event for today at noon with Michael Scott and send him an email to confirm. So we got that. It should be hitting both tools. We'll see it grab the email. Um, now it should be— as you can see, it's hitting both tools, which is awesome. It's going to send them an email, it's going to create an event, and then we'll check on both of those things. So the event should have been created. Let's just— we'll just wait because I think it's really cool to just watch this stuff happen. So we've got the event today. It's a meeting with Michael Scott. You can view and manage the event here. So it gave us a link. And then additionally, the email confirming has been sent to Michael Scott. So in the calendar, we've got the meeting right here. And then let me pull up that email. Okay, so I switched over to the other email that's associated with Michael Scott, and it said, hi Michael, just wanted to confirm that our meeting's scheduled for today at noon. Looking forward to the discussion. So that's, that's a cool way we just showed that it can use multiple tools instead of just having to use one. And then you can really, you know, start to combine tool after tool and be able to text it like, hey, I have these 5 tasks I need you to do. 'Can you please do them all?' And it will go do them all. So email agent, calendar agent. Let's look at the next tool that we're going to add. All right, next agent we're doing is a research agent. This one is just going to be able to answer questions. It can search the internet, it can search through articles, it has Wikipedia as well. And just another cool use case, it will be— this one, setting this one up is a lot easier. The, the email and the calendar ones are obviously the ones that, you know, people are thinking of a personal assistant, that's like what what comes most important to them. So let me just put in assistant prompts real quick. But, you know, obviously in this video we didn't really go super in depth with those two, what are they called, those two agents. But the idea is just to open your eyes to how you can give all your agents different tools, how you can, you know, make them more robust. And really just making it that if you build out one email agent and you have all these different functions, you can plug in this email agent to multiple different workflows and it's just gonna be really scalable, really modular. And you know, you can just basically reuse the same build and just improve on this workflow and it will just be able to plug in anywhere. So that's sort of what I wanted to show you guys with those two agents. But now we have a research agent. We're gonna set up this model real quick. 4L mini's good. And then we're gonna give it different tools. So the first one is gonna be Wikipedia. This is going to be the first thing that we wanted to go through. So as you can see, sorry, I didn't, I didn't read this prompt, but basically what I said in here is your research assistant, you have Wikipedia, Hacker News API, and SERP API, and you first want to search Wikipedia. If you can't find your answer, then you're going to search articles with Hacker News, and then if that doesn't work, you'll use SERP API. And we set it up like this so that you basically can get all the answers you need in here, but we don't always want it to be first going to SerpAPI because, um, that one has credits and it's an API call and you don't want to burn through all those. So what we're doing is pretty much giving it almost like a tier system to do. So in SerpAPI, if you make an account, you'll have a certain amount of free credits per month. You'll just connect your API key there. Um, but yeah, so this is pretty much the framework. And then what we want to do in here is give it an expression. So, um, that's what we wanted to do. So wait, anyways, we have to limit the articles that it's going to come back. So same thing, this is such a cool, a cool tool that we have is the fromai, and this is just going to say limit. So that way we can limit the amount of articles we want back. You could ask for 5, you could ask for 10, whatever that is. Okay, so the reason that the right field wasn't coming up the way I wanted it to is because now we're looking for all getting many, and now we just need to basically set this stuff up again. So I don't know why it always does that, but we're going to just do the same thing. We're typing in our, our limit here, which is going to just obviously do its thing. And then we want to add the keyword, which this is going to be another expression. It's going to be another from AI. We're basically just grabbing, um, this is how it's going to specify what type of articles to look for. So we should be able to just go through like that. So we've got Wikipedia, Hacker News, Surf API, and then we're just going to give it the response once again, which should be an expression, and I believe it's going to be json.output Okay, so now we'll just test out this thing. Um, yeah, okay, so let's actually just test this out with Telegram. So we'll make this guy pretty much active. We will come back into here, refresh this page so we can add our tool, which is going to be that research agent that we just built. And then we'll just test it out and we'll see if it goes through, you know, Hacker News or what it's coming through. So it's going to be the research agent. Um, we just do this in here. Call this tool to search the internet to answer the user's question. We're going to choose the research agent and we're good to go. So sorry, I really like to make sure it's like set up almost— I like to make them sort of symmetrical, but it's not perfect. Anyways, um, yeah, we'll test this guy out. So first, if we just say something like, what is the biggest mountain in the world? Maybe tallest would have been a better word, but anyways, okay, so we got an error already in the research agent. Um, I wonder— okay, I've done this every time. I think we need to define below, obviously, and it's going to be JSON.query. So, um, hopefully you guys— like, you probably noticed when I was setting this up, you're like, oh, it's going to fail, because I've done that every time. But anyways, We can pretty much, I think we can just run that query again. No, it's waiting. Okay. Okay, interesting. So I think what it did is that it was able to answer that just using its OpenAI model right here, which is pretty cool. I don't know why that wasn't going. Okay, it's listening for us. But it was able to answer that last time with the OpenAI chat model because it just has information. But now it's hitting the research agent. Um, and then we'll hop into the execution of the research agent. So we've got that information about Mount Everest. I'm going to assume that this one just used, um, Wikipedia. Okay. So it actually used all of them, which is interesting. So it got information here. It probably pulled back some articles. So that's not really what we want it to be doing because it grabbed 5 articles with highest mountain. Um, and obviously it could have just answered that question with using Wikipedia, so because it passed through the query of biggest mountain in the world. So let's, let's fix this up real quick to make sure that it's only using what we want to use. Okay, so in the reminder we just said you should only be calling one tool, never call all three tools if you can get an answer with just one. And then we just gave it a reminder of what the tools are. So we'll just test it in here so we can see it happen live. Um, let's ask it about like something where— something trendy. So what are the current trends with cryptocurrency? So we've got that query. We'll test this guy out and see. So now it's using SERP API and it's going to respond back to us just using that one. So It's perfect. It's going to give us the current trends in the cryptocurrency bull market emergence, AI and crypto, all that kind of stuff. That's perfect. Now let's ask something about, um, can you get me 3 articles about the, um, election? So we'll go with that, fire that off. This one I assume will go to Hacker News. It's just going to use one tool. Perfect. Just the way we want it to, and then respond back with those articles. So it's also going to give us the actual link to each article, which is cool. So let's real quick just go back into the personal assistant. We will test the workflow and we'll say, get me 3 articles about finance. So we've got that research agent, it's going to give us those articles, and then we'll just click on one of those links and see You know, that we can actually go look at them, which is gonna be cool. There we go. So we've got personal finance for engineers. So if you open this link, we've got this blog, course material. Awesome. And then of course you could click on those other links, which are right here. So that's pretty much how the research agent's gonna work. So I don't want this tutorial to go super long, but at this point you should understand how you can build agents as separate workflows, give them access to, or give the personal assistant access to these different agents. If you were to build on more, it's super simple. Once you've seen these, it's just a matter of prompting them so that it knows when to use them. You could add on vector stores, stuff like that too. But now I want to show you guys something really cool, which wasn't in the original build, which is how you can make the agent understand an audio file and also output back an audio file. So you can talk to it and listen to it rather than having to text it all the time. So what we're going to do, we're going to drag this out over here. And so as you see, when we're texting with the agent, we're getting back the actual text, which is, you know, json.chat.text, whatever. And then we're feeding it into this guy as message.text. So what we want to do now is add a switch node. So in here we have basically two paths that it's going to go down. We're going to have one for voice. Um, actually, yeah, we want to rename it down here voice, and that's not what we want to do. So we're going to have two paths, right? Like I said, one for voice and one for text. So what we want to do is if text exists, so right here is a text message, If this exists, then it's going to go down this path right here called text. And if it doesn't exist— or not if it doesn't exist, but if a voice file exists, which actually we could make it as simple as just this— but if a voice file exists, it's going to go down this path. So how do we get this voice file? We are going to have this listen for an event. We're going to come in here and just say Hello, testing. So now we've gotten back in here a voice file. And then what we can do in here is we see that we're getting this voice file rather than a text file. So what we want to do is grab that voice file, which will be file ID right here. And we're going to say, well, now if this one exists, you're going to go down this route. So we have two routes in order to talk to our agent. And so the first thing that we want to do is we need to make sure that this input right here is going to be consistent. So it needs to always be called the same thing. That way, if it's a voice file or a text file, we're going to get it no matter what. So we're just going to come in here and we're going to call this one— I hate that it does that— we're going to call this one, um, JSON.text. And now we just need to map out and make sure that each file coming through is going to be— or each output is going to be JSON.text. So how we can do that with text is we're going to add an edit field set. We're going to map this one, um, and just call it text. And we'll drag in that, that input real quick. So I'm just naming this for organization. So we're gonna have this one setting as text and coming through, and I'll show that in a sec. But now if it's a voice file, the first thing that we need to do is actually download that file. So we're gonna go to Telegram. We're going to, let's see, chat actions, file actions, get a file right there. So we're getting a file. The operation's get resources file, and then we need the file ID. So if we can test this guy, we'll see it's a voice file. It's gonna come up here. And now the file ID is just pretty much down here, which is what earlier we said, does the file ID exist? So download voice file. Now we've got the file put in here. We want to download it. We test the step and now you can see it's going to come back over here. And this is what we're looking for. So now what we need to do with this file is we want to grab an OpenAI node and we're going to grab one that is going to transcribe a recording. So we're transcribing this one. Transcribe audio. We're transcribing recording, it's coming in from here. And then we just— I think we actually should be good with that. So if we hit test, it's grabbing the input data field data, and we just said hello testing. We got that file coming back, and as you can see, it's coming back as json.txt. So we'll route this into here, and now we can see in the personal assistant it's getting our message that said hello testing. And now we just need to make sure that it's going to get this message as well. So now if we have this guy listening for us, we will just say hello. It got that file. It understands that it's a text file now because we routed it right here. And then we'll run this guy. And in here it took— it didn't do it yet, so we have to set it up. It's going to take this input, which is our text, which is currently being called json.message.text. We'll test it. Now it's coming out as JSON.txt, and now our assistant is going to be getting that message regardless whether it's a voice file or a text file. So that's super cool. And now we just need to output over here when we're getting an answer from the assistant that it's going to respond to us with a text message but also with a voice file. All right, so we've already got the text message coming through. We know that this works, so let's drag it up here. And now we need to go down another path, which is going to obviously give us the information as a text file. So first, what we want to do is I'm going to use a summarization chain because we don't exactly want, we don't want the exact text coming back. What we want is a summary of it so that we can see the details, but then visually, or sorry, audibly, we're just getting a summarization. So actually, I don't know why I was going to rename that. That's fine. So we've got this, um, it will be summarizing the actual text that we would be getting back. And then now with the summary, we want to feed this into a POST request. We're going to be sending it to ElevenLabs, which is going to be helping us make the actual audio file. So HTTP request, we're going to be doing a POST like I said, and then we need the URL, we need to set up some headers and stuff like that. So in ElevenLabs, if you haven't made an account, go go ahead and make one real quick. Um, I also want to mention that when I was testing this kind of stuff, I was on the free plan and I was getting some errors with my— it was saying my credentials were incorrect. So if you are experiencing those errors, then you may want to try the starter plan, which is only $5, and you get 40,000 credits, which lasts a decent amount of time as long as you're not getting files like 2 minutes long. But anyways, if you're getting that error, that may be why. But Once we're in here, we're looking at text-to-speech because we're going to be feeding it in text, obviously, and then it's going to be coming back with our audio file. So up here we click on curl, and you could copy this in and you could import your curl into NNN. But what we're going to do is just grab this URL. And so we're going to grab— actually, yeah, we can just grab this whole thing and we're going to paste that in here. But what follows the text-to-speech slash, as you can see right here, is the voice ID. So if you go into voices in ElevenLabs, you can listen to these different voices and you can figure out which one you want. I'm going to be using Ryan Kirk. And then you're going to click on view, you're going to click on ID, and you've copied the ID. So now all we have to do is after the text-to-speech forward slash, we just copy in that ID. So now ElevenLabs knows which voice we want to use. So we've got that set up, and now all we need to do is set up our headers and our JSON body. But headers, the first one that we have to do, if you go back to the API documentation, is our API key. So it's going to be x-i-api-key. We'll grab that. Paste that in there, and then we need the actual API key, of course. So we'll go back into, um, ElevenLabs. We will just basically create a new key. This one will be called test. We've got our value, we copy that in, and then we're going to paste that right here. Just make sure there's no trailing whitespace anywhere. And then we're going to add another header. As you can see, this header is content content-type. So we'll grab that, I can end it in, that's our header name. And then the actual value is going to be application/json. We paste that into there. And so header should be set up. Now we just need to set up the actual body, what we're sending over to, um, ElevenLabs. So first what I want to do is I'm just going to test this assistant because we want some actual data to be coming through. So I'm just going to say testing. So now it should be going through. It's probably going to respond with something like, you know, we don't actually, you know, the assistant said, if you're testing, please let me know if there's any specific. But now we have data coming through our summarization chain, which is the speaker offers assistance and invites input. So now we have that information coming back. We'll go into our send body. We're going to be using JSON expression, and we'll open this up. I want to paste that in here. Um, and what we want is to make this json. Let's see, json.response.text. And so now we have this, and I will paste this code in here as far as the replace and the stringify. I'll paste this in the FreeSchool community as well. Link for that will be in the description. Go to YouTube Resources and you can grab this little code snippet as well as the workflows that were shown in this video. But now we're just getting a nice clean string that will be sent over to ElevenLabs so it can turn this right here into audio. So let's actually just test this real quick. And that went through. Okay, it's being all weird because of the, what's it called, because of the multiple switch routes. But anyways, from here we'd have an audio file. And then once again, it's just as simple as adding Telegram. And we're going to be sending an audio file as the resource. Send audio file, chat ID. Once again, we're doing the same chat ID from earlier, which is going to be— we get that from the Telegram trigger. We want item.json.message.chat.id. There we go. And this should be the correct one. We can always just check that in here that we're getting the chat ID. You could also just copy and paste that into there. And send audio. And then we just need the actual audio. It's going to be a binary file, and so it should just be coming through as data. We should be good to go with that. So let's do a test. Let me just make this stuff a little more concise so that we can see the stuff happening. I don't like the way it does that. That's fine. That's fine. Okay, anyways, testing workflow. We'll send over an audio file. Can you send an email to Nate Hurk, um, just checking in on his day? So now we're getting that file. You can see it's being downloaded, it's being transcribed. The actual assistant is now taking place. It should be hitting the email agent. Okay, it actually didn't, so It had an information— it had an issue with my contact data, so we'll fix that in a sec. But now we just need to make sure file name is needed to send audio. Okay, right, so we have to add a file name, and that's just going to be data.mp3. Hit test again. Okay, and now we have to do that again. So anyways, This is the beauty of the almost sort of live builds. But anyways, let's see what the issue was. I found it. Nate Hurk in the database with email address natehurk@gmail.com. Ah, okay, it's because it transcribed my name as Nate Hurk with a U. So let's just try something else. Let's say, can you send an email to Michael Scott checking in on his day? So that's actually kind of ridiculous with the transcribing. Because it couldn't find Nate Hurk anyways. So it's finding Michael Scott. Now it's going to hit the email agent. We should see it get summarized. So there's the text, and then the audio file coming back should be a little different. So we've got this: The email to Michael Scott has been sent inquiring about his day. Okay, awesome. So that's pretty much how it works, the way that you can talk to it. You can see a detailed breakdown, but then you also get something else back. So if I said Let's test this workflow. Can you summarize my calendar events for today? So same thing, it's going to get that information, hit the right agent. It's going to send us a text that'll be a little more detailed, but then the summary will be, well, a summary. That's kind of the whole point of the summary anyways. So this information we got back, now it's creating that audio file for us. And it shouldn't be as detailed as we get here. So let's listen to this. We won't listen to the whole thing. Today's calendar events for November 28th, 2024 include one asterisk asterisk meeting with Michael Scott asterisk asterisk. Okay, so that was awful. It was reading off asterisks asterisk. We don't want that. I was trying to play around with the summarization chain, but what we're going to do is just We're going to grab an OpenAI message model. And basically when we're telling it to summarize, we're going to say like to make it as plain text. We don't want any of the, you know, asterisks coming through. So real quick, am I able to? Yeah. Anyways, we're just going to come in here. We can grab Floral Mini. And your goal is just to summarize this incoming information, which will be this output right here. And yeah, so we've got that. And then we're just going to say output only plain text. There should be no, um, like markdown formatting or um, or any symbols. Okay, so that should be simple enough. We'll test that out. It is going to be weird about that because, um, you know, the, the whole looping, but this should be json.message.content now, I believe. So we'll give it another run. Please summarize my calendar events for today. Okay, what is this? I don't know what, what try. I was about to say third time's a charm, but we'll see. Should now be just summarizing information. It should be a plain string. That way when the audio file is being created, it's going to be much cleaner. Let's see what we got. Okay, this looks a lot cleaner. And then we'll see what the actual file Sounds like hopefully this one's better. Your calendar events for today, November 28th, 2024 include: 1. Meeting with Michael Scott from 12 PM to 1 PM MDT. Status confirmed. Response needed from upitdigital@gmail.com. 2. Dinner from 5 PM to 6 PM. Okay, so that one comes through cleaner. We would probably want to play with the prompting so it gives you an even more high-level summary. We don't want to maybe hear that it's confirmed or if it needs a response. Or maybe we do, but anyways, that's just, you know, you'd play with the prompting within that OpenAI node right there. But yeah, I mean, that's the foundations really. We could, you know, obviously come in here and we could add something like a vector store. Let's just call this data retrieves information about company projects. So we can do that. Obviously we'd set up the other information we need for the vector store. Um, but yeah, obviously the idea is that we're just pretty much building on top of the, the agent type workflow. You can continue to come in here and add more and more tools, which is obviously the super cool part. And, um, yeah, just the whole theory of like being able to build out workflows and, and, and being able to you know, call them in multiple different workflows. They're very scalable, it's very flexible, and yeah, the whole idea is that you have all these different workflows you can sort of plug and play, which is super cool. Um, so yeah, I hope that this workflow, or I hope that the step-by-step tutorial was insightful. Um, you know, there's a lot of things that we could do to improve upon this. One thing I'll just show really quick is a cool way that you could have your agents be able to like talk to each other a little bit more. So You know, obviously we're calling email agent, we're calling calendar agent, stuff like that. Let's say we were calling the calendar agent and it errored, right? So this is the— an actual workflow that I was using for the personal assistant build, and this is not the one we just built. But anyways, you come into here and you want to go to settings, and then you want to make it continue using an error output. So if we do that, we have two different options. So if the workflow errors for some reason, rather than it just stopping, or rather than the agent responding to us on Telegram and saying we couldn't do that, it's going to go down this path and it's going to respond to that personal assistant with the response of unable to perform task, please try again. So this agent would hit this, it would get a response, and then rather than responding to us, it would be like, okay, well, that didn't work, what do we need to do differently? And you would maybe prompt that a little more specifically. But let's say for some reason it didn't grab the email, then it would try again, it would run through that whole query, And then this time it may go grab the email and then understand, okay, well, that's sort of where I messed up there. Anyways, I hope this video was insightful. Like I said, the workflows that were used in this video as well as the code snippets will be in the school community. You'll just go to YouTube resources, find this video, everything will be attached there. And, you know, I mentioned there's a lot of ways to improve on this build to make it really more production ready. And if you want to dive deeper into that, please check out the paid community. If you have any questions about that, reach out to me. The link for that will also be down in the description, but Thank you guys, really appreciate your time today, and, um, we'll see you in the next one.










