Build & Sell n8n AI Agents (8+ Hour Course, No Code)

1.4M views May 23, 2025

Full courses + unlimited support: https://www.skool.com/ai-automation-society-plus/about
All my FREE resources: https://www.skool.com/ai-automation-society/about
Work with me: https://uppitai.com/

My Tools💻
14 day FREE n8n trial: https://n8n.partnerlinks.io/22crlu8afq5r
Code NATEHERK to Self-Host n8n for 10% off (annual plan): http://hostinger.com/nateherk



Welcome to the most comprehensive free course on AI automation and AI agents for beginners using n8n.

In this 8+ hour deep-dive, I’ll walk you step-by-step through what you need to go from complete beginner to building and selling real AI-powered automations, no coding required.

We’ll cover what AI agents are, why they’re a smart investment right now, and how to use n8n to build powerful workflows with a free two-week trial.

You’ll learn n8n foundations, how to set up APIs and HTTP requests, and how to use tools like agent memory, multi-agent systems, and prompting to create scalable systems.

We’ll also explore essential concepts like webhooks, MCP servers, and self-hosting, plus a ton of advanced strategies packed into easy-to-follow lessons.

By the end of this course, you’ll have built over 15 working AI automations that you can use or sell. This video is insanely value-packed, so make sure to save it and come back to it whenever you hit a roadblock.

If you’re serious about mastering AI agents and automation, this course is the only one you’ll need.

Sponsorship Inquiries:
📧 sponsorships@nateherk.com

WATCH NEXT:
https://youtu.be/QhujcQk8pyU?si=kpGWo0cF4aiAaT68

TIMESTAMPS
00:00 Course Agenda (8+ Hours)
01:43 AI Agents Simplified
09:02 The Industry Opportunity
12:05 n8n Foundations (workflows, variables, JSON)
40:45 n8n Data Types
48:25 23 Workflow Templates FREE
49:09 Step by Step AI Workflows
51:25 1) RAG Pipeline & Chatbot
01:11:02 2) Customer Support Workflow
01:22:06 3) LinkedIn Content Creator Workflow
01:32:58 Bonus Workflow: Invoice Processing
02:09:54 APIs Explained Simply
02:34:21 Perplexity API Setup
02:40:36 Firecrawl API Setup
02:54:48 Apify API Setup
03:02:50 Image Generation API Setup
03:21:11 Video Generation API Setup
03:47:15 Don't Use AI Agents Wrong
04:00:26 Build Your First Agent!
04:24:06 Postgres & Supabase Setup
04:34:46 Multi Agent System Architecture
04:55:22 4 Agent Architectures
05:12:52 Prompting AI Agents
05:39:58 Output Parsing
05:46:25 Human in the Loop
06:02:16 Error Workflows
06:11:47 Dynamic Brain
06:25:03 Webhooks
06:31:24 Voice Email Agent
06:47:31 Front End w/ Lovable
07:06:59 What is MCP?
07:19:49 MCP & Self Host n8n Setup
07:45:05 Lessons from 6 Months of Building Agents
08:25:36 If You Made it Here, You Rock


Gear I Used:
Camera: Razer Kiyo Pro
Microphone: Blue Yeti USB

0:00 In this course, I'm going to take you
0:01 from a complete beginner to building
0:03 powerful noode AI agents. I don't have
0:05 any coding experience, and you don't
0:07 need any either. In the past eight
0:08 months, I've made over half a million
0:10 dollars in revenue by building and
0:12 teaching people how to build AI agents.
0:14 In this video together, we're going to
0:15 set up your 2e free and end trial. We're
0:17 going to set up credentials together and
0:18 walk through step-by-step builds. And by
0:20 the end, you'll have over 15 AI
0:22 automations ready to take advantage of
0:24 this opportunity. All right, so here is
0:25 a quick look at the highle course
0:27 agenda. Keep in mind everything will be
0:29 timestamped below so you can jump around
0:31 to where you need. But I definitely
0:32 recommend saving this for later. As you
0:34 can see, this is extremely
0:35 comprehensive, packed with a ton of
0:37 value, so you can come back to this
0:38 later when you want to explore different
0:40 chapters. But what we're going to do is
0:42 start off with talking about AI agents
0:43 and the opportunity that we are all
0:45 living in right now. Then we'll move
0:47 into Foundations. I'll set up a free
0:49 twoe trial with you guys. I will talk
0:51 about the UI. We'll get familiar with it
0:53 and go over some foundational knowledge
0:54 you'll need. From there, we'll move into
0:56 step-by-step workflows where we're
0:58 actually using that knowledge and
0:59 connecting to different integrations and
1:01 setting up some pretty cool automations
1:03 right away. Then, we'll talk about APIs
1:05 and HTTP request. We'll set up a few
1:07 common examples together, and you'll see
1:08 it's not that difficult. Then, moving
1:10 into the back half of the course, we'll
1:11 talk about AI agent tools and memory. We
1:14 will discuss multi-agent architectures.
1:16 I'll talk about prompting, do a live
1:18 example, and some other cool tips that I
1:19 want to share with you guys that could
1:20 be helpful. We will look at web hooks,
1:23 what those really mean. And then we'll
1:24 look at a few example workflows where
1:26 we've triggered them with web hooks.
1:28 I'll talk about MCP servers, what that
1:30 really is, and we'll do a step-by-step
1:32 self-hosted setup of Naden and connect
1:33 to some MCP servers. And finally, we'll
1:36 close off with lessons from my first 6
1:38 months of building AI agents. So, if
1:40 that all sounds good to you guys, let's
1:42 go ahead and get
1:46 started. All right, so AI agents,
1:48 artificial intelligence, whatever it is,
1:50 there is definitely a lot of hype.
1:51 There's no denying that. And so the
1:53 purpose of this section is just to make
1:55 sure we can cut through all of that and
1:56 actually understand what is an AI agent
1:58 at its core. What can they do and why do
2:01 we need them? You probably heard you
2:03 know digital employee or virtual
2:05 assistant all this kind of stuff. But we
2:07 need to understand what that actually
2:08 means and what powers them. So at this
2:11 point I'm sure we are all familiar with
2:12 something like chatbt which is a large
2:15 language model at its core. And so we're
2:16 looking at right here is a very simple
2:18 visualization of how a large language
2:20 model works. Meaning right here in green
2:22 we have a large language model. Let's
2:23 say it's chatbt and we the user give it
2:26 some sort of input. So maybe that's like
2:28 hey help me write an email to John. The
2:30 LLM would then take our input process
2:33 this. It would basically just create an
2:35 email for us and then it would spit that
2:36 out as an output and that's it. This LLM
2:39 at its core cannot take any action. It's
2:41 really not that practical. It just kind
2:43 of helps you be more productive because
2:45 at the end of the process, we'd have to
2:47 take this output and copy and paste it
2:49 into something that actually can take
2:50 action like Gmail. And so the power of
2:52 these large language models really comes
2:54 into play when we start to expose them
2:56 to different tools. And tools just means
2:58 any of these integrations that we use
3:00 every single day within our work that
3:02 let us actually do something. So whether
3:03 that's send an email or update a row in
3:06 our CRM or look at a database or Air
3:09 Table, whatever it is, even Outlook,
3:11 that's a tool. It just means connecting
3:13 to an actual platform that we use to do
3:16 something. So now instead of having the
3:18 LLM help us write an email that we would
3:19 copy and paste or us exporting a Google
3:22 sheet and giving it to an LLM to
3:24 analyze, it can basically just interact
3:25 with any of its tools that we give it
3:27 access to. So when we add an LLM to
3:30 tools, we basically can get two
3:33 different things and that is either an
3:34 AI workflow or an AI agent. So right
3:38 away you can already tell what the
3:39 difference is, but you can also see some
3:40 similarities. So, let's break it down.
3:42 Starting with an AI workflow, we can see
3:44 that we have an input similar to like we
3:46 did up top with our LLM. But now,
3:48 instead of just going input, LLM,
3:51 output, we can work in those tools right
3:54 into the actual AI workflow itself. So,
3:56 here is an example of what an AI
3:58 workflow could practically look like.
3:59 First of all, we have a tool which is
4:01 HubSpot, and that's going to be the
4:02 input for this workflow. This will
4:04 basically pass over a new lead that has
4:06 been inserted into our CRM. Then we're
4:08 hitting another tool which is Perplexity
4:10 which helps us do research. So we're
4:11 going to do research on that lead. From
4:13 there, after we get that research, we're
4:15 going to hit an LLM, which is where this
4:17 whole AI powered workflow terminology
4:18 comes in, because we're using that LLM
4:21 to then take the research, draft a
4:23 personalized email, and then it can use
4:25 another tool to actually send that
4:26 email. And the reason that we do this as
4:28 a workflow is because this is going to
4:30 happen in the same four steps in that
4:32 order every time. new lead comes in,
4:35 research, write the personalized email,
4:37 send the email. And so whenever we know
4:39 a process is linear or sequential or
4:41 it's going to follow that order every
4:43 time, it's much much better to do an
4:45 actual workflow rather than send that
4:47 off to an AI agent where we have an
4:49 input, we have the LLM, which is the AI
4:51 agent. This is the brain of the whole
4:52 operation and it has access to all of
4:54 the different tools it can use and then
4:56 it has an output. So yes, it is true
4:59 that this AI agent down here could do
5:00 the exact same job as this AI workflow.
5:02 We could also over here with an AI agent
5:04 get a new form and have a new row in our
5:07 CRM. The agent could then think about it
5:09 and decide, okay, I'm going to use
5:10 perplexity to do research and then after
5:12 that I'm going to send an email with my
5:13 email tool. But it's not the most
5:15 effective way to do it because it's
5:16 going to be more expensive. It's going
5:18 to be slower and it's going to be more
5:20 errorprone. So basically the whole idea
5:22 is AI agents can make decisions and act
5:25 autonomously based on different inputs.
5:27 AI workflows follow the guardrails that
5:29 we put in place. there's no way they can
5:31 deviate off the path that we chose for
5:32 them. So, a big part of building
5:34 effective systems is understanding,
5:36 okay, do I need to build an AI workflow
5:37 or am I going to build an AI agent? Is
5:39 this process deterministic or
5:41 nondeterministic? Or in other words, is
5:43 it predictable or is it unpredictable?
5:45 If something's unpredictable, that's
5:46 when we're going to use an AI agent with
5:48 a brain and with different tools to
5:50 actually do the job. And that's where
5:51 the whole autonomy comes into play. And
5:53 I don't want to dive too deep into the
5:54 weeds of this right now. We'll cover
5:56 this later in a different section. But
5:58 real quick, four main pros of AI
6:00 workflows over AI agents. Reliability
6:02 and consistency, cost efficiency, easier
6:05 debugging and maintenance, and
6:06 scalability. Once again, we have a whole
6:08 section dedicated to this idea and we're
6:10 going to dive into it after we've built
6:12 out a few AI workflows, but I wanted you
6:14 guys to understand this because
6:15 obviously the whole purpose you probably
6:16 came here was to learn how to build AI
6:18 agents. But before we build AI agents,
6:20 we're going to learn how to build AI
6:22 workflows. It's the whole concept of
6:24 crawl, walk, run. you wouldn't just
6:26 start running right away. And trust me,
6:28 after you've built out a few AI
6:29 workflows, it's going to make a lot more
6:30 sense when you hop into building some
6:32 more complex agentic systems. But just
6:34 to give you that quick fix of AI agent
6:36 knowledge, and we'll revisit this later
6:37 when we actually build our first agent
6:39 together. What is the anatomy of an AI
6:41 agent? What are the different parts that
6:43 make one up? So, here's a simple diagram
6:44 that I think illustrates AI agents as
6:47 simple as possible. We have an input, we
6:49 have our LLM, and we have our output
6:51 like we talked about earlier. But then
6:53 inside the AI agent you can see two main
6:55 things. We have a brain and we have
6:57 instructions. So the first thing is a
6:59 brain. This comes in the form of a large
7:00 language model and also memory. So first
7:03 off the large language model this is an
7:05 AI chat model that we'll choose whether
7:07 that's an open AI model or an anthropic
7:09 model or a Google model. This is going
7:11 to be what powers the AI agent to make
7:13 decisions to reason to generate outputs
7:16 that sort of stuff. And then we also
7:17 have the memory. So this can come in the
7:19 form of long-term memory as well as
7:21 short-term memory. But basically, we
7:22 want to make sure that if we're
7:23 conversating with our agent, it's not
7:25 going to forget what we're talking about
7:28 after every single sentence. It's going
7:29 to retain that context window, and it
7:31 can also remember things that we talked
7:33 about a while back. And then the other
7:35 piece is the instructions for the AI
7:37 agent, which is also kind of referred to
7:38 as a system prompt. And this is really
7:40 important because this is telling this
7:42 AI agent, you know, here's your role,
7:45 here's what you do, here are the tools
7:47 you have. This is basically like your
7:49 job description. So, the same way you
7:51 wouldn't expect a new hire to hop into
7:53 the company and just start using its
7:54 different tools and knowing what to do,
7:56 you would have to give it basically some
7:58 pretty specific training on this is
8:01 basically your end goal. Here are the
8:02 tools you have and here's when you use
8:03 each one to get the job done. And the
8:06 system prompt is different than the
8:07 input, which is kind of referred to as a
8:09 user prompt. And think of it like this.
8:11 when you're talking to chatbt in your
8:13 browser and every single message that
8:15 you're typing and sending off to it is a
8:17 user message because that input changes
8:19 every time. It's dynamic, but the system
8:22 prompt is typically going to say the
8:23 same over the course of this agent's
8:25 life unless its role or actual
8:27 instructions are going to change. But
8:29 anyways, let's say the input is, hey,
8:30 can you help me send an email to John?
8:32 What's going to happen is the agent's
8:34 going to use its brain to understand the
8:35 input. It's going to check its memory to
8:37 see if there's any other interactions
8:38 that would help with this current input.
8:40 Then it will look at its instructions
8:42 and see, okay, how do I actually send an
8:44 email to John? And then it will call on
8:46 its tool to actually send an email. So
8:48 at a high level, that is the anatomy of
8:50 an AI agent. And I hope that that helps
8:52 paint a clear picture in your mind.
8:54 Cool. So now that we've talked about
8:55 what an AI agent is and what a workflow
8:57 is and why we want to walk before we
8:59 run, let's actually get into Naden and
9:01 start building some
9:03 stuff. All right. Right. So, before we
9:05 dive into actually building AI agents, I
9:07 want to share some eyeopening research
9:08 that underscores exactly why you're
9:10 making such a valuable investment in
9:11 yourself today. This research report
9:13 that I'm going to be walking through
9:14 real quick will be available for free in
9:16 my school community if you want to go
9:17 ahead and take a look at it. It's got a
9:19 total of 48 sources that are all from
9:21 within the past year. So, you know it's
9:22 real, you know it's relevant, and it was
9:24 completely generated for me using
9:25 Perplexity, which is an awesome AI tool.
9:27 So, just a year ago, AI was still
9:29 considered experimental technology for
9:31 most businesses. Now, it's become the
9:33 core driver of competitive advantage
9:35 across every industry and business size.
9:37 What we're witnessing isn't just another
9:39 tech trend. It's a fundamental business
9:42 transformation. Let me start with
9:44 something that might surprise you. 75%
9:46 of small businesses now use AI tools.
9:48 That's right. This isn't just enterprise
9:50 technology anymore. In fact, the
9:52 adoption rates are climbing fastest
9:53 among companies generating just over a
9:55 million dollars in revenue at 86%.
9:58 What's truly remarkable is the
9:59 investment threshold. The median annual
10:01 AI investment for small businesses is
10:03 just 1,800. That's less than 150 bucks
10:06 per month to access technology that was
10:08 science fiction just a few years
10:10 ago. Now, I know some of you might be
10:13 skeptical about AI's practical value.
10:15 Let's look at concrete outcomes
10:16 businesses are achieving. Marketing
10:18 teams are seeing a 22% increase in ROI
10:20 for AIdriven campaigns. Customer service
10:23 AI agents have reduced response time by
10:25 60% while resolving 80% of inquiries
10:28 without human intervention. Supply
10:29 chains optimized with AI have cut
10:31 transportation costs by 5 to 10% through
10:34 better routing and demand forecasting.
10:35 These are actual measured results from
10:37 implementations over the past year. Now,
10:39 for those of you from small
10:40 organizations, consider these examples.
10:42 Henry's House of Coffee used AIdriven
10:44 SEO tools to improve their product
10:46 descriptions, resulting in a 200%
10:48 improvement in search rankings and 25%
10:51 revenue increase. Vanisec insurance
10:53 implemented custom chat bots that cut
10:55 client query resolution time from 48
10:57 hours to just 15 minutes. Small
10:59 businesses using Zapier automations
11:01 saved 10 to 15 hours weekly on routine
11:04 data entry and CRM updates. What's
11:06 revolutionary here is that none of these
11:08 companies needed to hire AI specialists
11:09 or data scientists to achieve these
11:12 results. The economic case for AI skills
11:15 is compelling. 54% of small and medium
11:17 businesses plan to increase AI spending
11:19 this year. 83% of enterprises now
11:21 prioritize AI literacy in their hiring
11:23 decisions. Organizations with AI trained
11:25 teams are seeing 5 to 8% higher
11:27 profitability than their peers. But
11:29 perhaps most telling is this. Small
11:31 businesses using AI report 91% higher
11:34 revenue growth than nonAI adopters. That
11:37 gap is only widening. So the opportunity
11:39 ahead. The truth is mastering AI is no
11:42 longer optional. It's becoming the price
11:43 of entry for modern business
11:45 competitiveness. those who delay risk
11:46 irrelevance while early adopters are
11:48 already reaping the benefits of
11:49 efficiency, innovation, and market share
11:52 gains. Now, the good news is that we're
11:54 still in the early stages. By developing
11:56 these skills now, you're positioning
11:57 yourself at the forefront of this
11:59 transformation and going to be in
12:00 extremely high demand over the next
12:02 decade. So, let's get started building
12:04 your first AI
12:08 agent. All right, so here we are on
12:10 Naden's website. You can get here using
12:12 the link in the description. And what
12:14 I'm going to do is go ahead and sign up
12:15 for a free trial with you guys. And this
12:17 is exactly the process you're going to
12:18 take. And you're going to get two weeks
12:19 of free playing around. And like I said,
12:22 by the end of those two weeks, you're
12:23 already going to have automations up and
12:24 running and tons of templates imported
12:26 into your workflows. And I'm not going
12:28 to spend too much time here, but
12:29 basically Nitn just lets you automate
12:31 anything. Any business process that you
12:33 have, you can automate it visually with
12:35 no code, which is why I love it. So here
12:37 you can see NIDN lets you automate
12:39 business processes without limits on
12:40 your logic. It's a very visual builder.
12:42 We have a ton of different integrations.
12:44 We have the ability to use code if you
12:46 want to. Lots of native nodes to do data
12:48 transformation. And we have tons of
12:50 different triggers, tons of different AI
12:52 nodes. And we're going to dive into this
12:53 so you can understand what's all going
12:55 on. But there's also hundreds of
12:56 templates to get you started. Not only
12:58 on the end website itself, but also in
13:00 my free school community. I have almost
13:02 100 templates in there that you can plug
13:03 in right away. Anyways, let's scroll
13:05 back up to the top and let's get started
13:06 here with a new account. All right. All
13:08 right. So, I put in my name, my email,
13:09 password, and I give my account a name,
13:11 which will basically be up in the top
13:13 search bar. It'll be like nate
13:16 herkdemo.app.n.cloud. So, that's what
13:17 your account name means. And you can see
13:19 I'm going to go ahead and start our
13:20 14-day free trial. Just have to do some
13:22 quick little onboarding. So, it asks us
13:24 what type of team are we on. I'm just
13:26 going to put product and design. It asks
13:27 us the size of our company. It's going
13:29 to ask us which of these things do we
13:30 feel most comfortable doing. These are
13:32 all pretty technical. I just want to put
13:33 none of them, and that's fine. And how
13:35 did you hear about any? Let's go ahead
13:36 with YouTube and submit that off. And
13:39 now you have the option to invite other
13:40 members to your workspace if you want to
13:42 collaborate and share some credentials.
13:43 For now, I'm just going to go ahead and
13:44 skip that option. So from here, our
13:46 workspace is already ready. There's a
13:48 little quick start guide you could watch
13:49 from Eniden's YouTube channel, but I'm
13:50 just going to go ahead and click on
13:52 start automating. All right, so here we
13:53 are. This is what Eniden looks like. And
13:55 let's just familiarize with this
13:57 dashboard a little bit real quick. So up
13:58 in the top left, we can see we have 14
14:00 days left in our free trial and we've
14:02 used zero out of a,000 executions. An
14:05 execution just basically means when you
14:07 run a workflow from end to end that's
14:09 going to be an execution. So we can see
14:10 on the lefth hand side we have overview.
14:12 We have like a personal set of projects.
14:14 We have things that have been shared
14:15 with us. We have the ability to add a
14:17 project. We have the ability to go to
14:19 our admin panel where we can upgrade our
14:20 instance of nodn. We can turn it off.
14:23 That sort of stuff. So here's my admin
14:24 panel. You can see how many executions I
14:26 have, how many active workflows I have,
14:28 which I'll explain what that means
14:29 later. We have the ability to go ahead
14:30 and manage our nen versions. And this is
14:33 where you could kind of upgrade your
14:34 plan and change your billing
14:36 information, stuff like that. But you'll
14:37 notice that I didn't even have to put
14:39 any billing details to get started with
14:41 my twoe free trial. But then if I want
14:43 to get back into my workspace, I'm just
14:44 going to click on open right here. And
14:45 that will send us right back into this
14:47 dashboard that we were just on. Cool. So
14:49 right here we can see we can either
14:51 start from scratch, a new workflow, or
14:53 we can test a simple AI agent example.
14:54 So let's just click into here real quick
14:56 and break down what is actually going on
14:58 here. So, in order for us to actually
15:00 access this demo where we're going to
15:01 just talk to this AI agent, it says that
15:03 we have to start by saying hi. So,
15:05 there's an open chat button down here.
15:06 I'm going to click on open chat and I'm
15:08 just going to type in here, hi. And what
15:11 happens is our AI agent fails because
15:13 this is basically the brain that it
15:15 needs to use in order to think about our
15:16 message and respond to us. And what
15:18 happens is we can see there's an error
15:19 message. So, because these things are
15:21 red, I can click into it and I can see
15:23 what is the error. It says error in
15:25 subnode OpenAI model. So that would be
15:28 this node down here which is called
15:29 OpenAI model. I would click into this
15:31 node and we can basically see that the
15:33 error is there is no credentials. So
15:35 when you're in NADN what happens is in
15:38 order to access any sort of API which
15:40 we'll talk about later but in order to
15:41 access something like your Gmail or
15:43 OpenAI or your CRM you always need to
15:47 import some sort of credential which is
15:48 just a fancy word for a password in
15:50 order to actually like get into that
15:52 information. So right here we can see
15:54 there's 100 free credits from OpenAI.
15:56 I'm going to click on claim credits. And
15:58 now we just are using our NEN free
15:59 OpenAI API credits and we're fine on
16:02 this front. But don't worry, later in
16:03 this video I'm going to cover how we can
16:05 actually go to OpenAI and get an API key
16:07 and create our own password in here. But
16:10 for now, we've claimed 100 free credits,
16:11 which is great. And what I'm going to do
16:13 is just go ahead and resend this message
16:14 that says hi. So I can actually go to
16:16 this hi text and I can just click on
16:18 this button which says repost message.
16:20 And that's just going to send it off
16:21 again. And now our agent's going to
16:23 actually be able to use its brain and
16:24 respond to us. So what it says here is
16:27 welcome to NINDN. Let's start with the
16:28 first step to give me memory. Click the
16:30 plus button on the agent that says
16:32 memory and choose simple memory. Just
16:34 tell me once you've done that. So sure,
16:36 why not? Let's click on the plus button
16:37 under memory. And we'll click on simple
16:39 memory real quick. And we're already set
16:41 up. Good to go. So now I'm just going to
16:43 come down here and say done. Now we can
16:46 see that our agent was able to use its
16:47 memory and its brain in order to respond
16:49 to us. So now it can prompt us to add
16:52 tools. It can do this other stuff, but
16:54 we're going to break that down later in
16:55 this video. Just wanted to show you real
16:57 quick demo of how this works. So, what I
17:00 would do is up in the top right, I can
17:01 click on save just to make sure that the
17:03 what we've done is actually going to be
17:05 saved. And then to get back out to the
17:07 main screen, I'm going to click on
17:08 either overview or personal. But if I
17:10 click on overview, that just takes us
17:11 back to that home screen. But now, let's
17:13 talk about some other stuff that happens
17:15 in a workflow. So, up in the top right,
17:17 I'm going to click on create workflow.
17:19 You can see now this opens up a new
17:20 blank page. And then you have the option
17:22 up here in the top left to name it. So
17:24 I'm just going to call this one demo.
17:26 Now we have this new workflow that's
17:28 saved in our N environment called demo.
17:31 So a couple things before we actually
17:32 drag in any nodes is up here. You can
17:34 see where is this saved. If you have
17:36 different projects, you can save
17:37 workflows in those projects. If you want
17:39 to tag them, you can tag different
17:40 things like if you have one for customer
17:42 support or you have stuff for marketing,
17:45 you can give your workflows different
17:46 tags just to keep everything organized.
17:48 But anyways, every single workflow has
17:51 to start off with some sort of trigger.
17:53 So when I click on add first step, it
17:54 opens up this panel on the right that
17:56 says what triggers this workflow. So we
17:58 can have a manual trigger. We can have a
18:00 certain event like a new message in
18:01 Telegram or a new row in our CRM. We can
18:04 have a schedule, meaning we can set this
18:05 to run at 6 a.m. every single day. We
18:08 can have a web hook call, form
18:09 submission, chat message like we saw
18:11 earlier. There's tons of ways to
18:13 actually trigger a workflow. So for this
18:15 example, let's just say I'm going to
18:16 click on trigger manually, which
18:18 literally just gives us this button
18:19 where if we click test workflow, it goes
18:21 ahead and executes. Cool. So this is a
18:24 workflow and this is a node, but this is
18:26 a trigger node. What happens after a
18:28 trigger node is different types of
18:29 nodes, whether that's like an action
18:31 node or a data transformation node or an
18:34 AI node, some sort of node. So what I
18:37 would do is if I want to link up a node
18:39 to this trigger, I would click on the
18:41 plus button right here. And this pulls
18:42 up a little panel on the right that says
18:44 what happens next. Do you want to take
18:46 action with AI? Do you want to take
18:47 action within a certain app? Do you want
18:48 to do data transformation? There's all
18:50 these other different types of nodes.
18:52 And what's cool is let's say we wanted
18:53 to take action within an app. If I
18:55 clicked on this, we can see all of the
18:57 different native integrations that Nin
18:58 has. And once again, in order to connect
19:00 to any of these tons of different tools
19:02 that we have here, you always need to
19:04 get some sort of password. So let's say
19:06 Google Drive. Now that I've clicked into
19:07 Google Drive, there's tons of different
19:09 actions that we can take and they're all
19:10 very intuitive. you know would you want
19:12 to copy a file would you want to share a
19:14 file do you want to create a shared
19:16 drive it's all very natural language and
19:18 let's say for example I want to copy a
19:19 file in order for nitn to tell Google
19:22 drive which file do we want to copy we
19:24 first of all have to provide a
19:26 credential so every app you'll have to
19:27 provide some sort of credential and then
19:29 you have basically like a configuration
19:31 panel right here in the middle which
19:32 would be saying what is the resource you
19:34 want what do you want to do what is the
19:36 file all this kind of stuff so whenever
19:38 you're in a node in nen what you're
19:40 going to have is on the left you have an
19:42 input panel which is basically any data
19:44 that's going to be feeding into this
19:45 current node. In the middle you'll have
19:47 your configuration which is like the
19:49 different settings and the different
19:50 little levers you can tweak in order to
19:52 do different things. And then on the
19:54 right is going to be the output panel of
19:56 what actually comes out of this node
19:58 based on the way that you configured it.
20:00 So every time you're looking at a node
20:01 you're going to have three main places
20:03 input configuration and output. So,
20:06 let's just do a quick example where I'm
20:07 going to delete this Google Drive node
20:09 by clicking on the delete button. I'm
20:10 going to add an AI node because there's
20:12 a ton of different AI actions we can
20:14 take as well. And all I'm going to do is
20:15 I'm just going to talk to OpenAI's kind
20:17 of like chatbt. So, I'll click on that
20:20 and I'm just going to click on message a
20:21 model. So, once that pulls up, we're
20:23 going to be using our NEN free OpenAI
20:25 credits that we got earlier. And as you
20:27 can see, we have to configure this node.
20:30 What do we want to do? The resource is
20:32 going to be text. It could be image,
20:34 audio, assistant, whatever we want. The
20:36 operation we're taking is we want to
20:38 just message a model. And then of
20:41 course, because we're messaging a model,
20:42 we have to choose from this list of
20:44 OpenAI models that we have access to.
20:47 And actually, it looks like this N free
20:49 credits only actually give us access to
20:51 a chat model. And this is a bit
20:53 different. Not exactly sure why.
20:54 Probably just because they're free
20:55 credits. So, what we're going to do real
20:57 quick is head over to OpenAI and get a
20:59 credential so I can just show you guys
21:01 how this works with input configuration
21:03 and output. So, basically, you'd go to
21:05 openai.com. You'd come in here and you'd
21:08 create an account if you don't already
21:09 have one. If you have a chat GBT account
21:11 and you're on like maybe the 20 bucks a
21:12 month plan, that is different than
21:14 creating an OpenAI API account. So,
21:16 you'd come in here and create an OpenAI
21:18 account. As you see up here, we have the
21:20 option for Chatbt login or API platform
21:23 login, which is what we're looking for
21:25 here. So, now that you've created an
21:26 account with OpenAI's API, what you're
21:29 going to do is come up to your dashboard
21:31 and you're going to go to your API keys.
21:34 And then all you'd have to do is click
21:35 on create new key. Name this one
21:38 whatever you want. And then you have a
21:39 new secret key. But keep in mind, in
21:42 order for this key to work, you have to
21:43 have put in some billing information in
21:45 your OpenAI account. So, throw in a few
21:47 bucks. They'll go a lot longer than you
21:49 may think. And then you're going to take
21:50 that key that we just copied, come back
21:52 into Nitn, and under the credential
21:54 section, we're going to click on create
21:56 new credential. All I had to do now was
21:58 paste in that API key right there. And
22:00 then you have the option to name this
22:01 credential if you have a ton of
22:02 different ones. So I can just say, you
22:03 know, like demo on May 21st. And now I
22:07 have my credential saved and named
22:10 because now we can tell the difference
22:11 between our demo credential and our NAN
22:13 free OpenAI credits credential. And now
22:15 hopefully we have the ability to
22:16 actually choose a model from the list.
22:18 So, as you can see, we can access chat
22:21 GBT for latest, 3.5 Turbo, 4, 4.1 mini,
22:25 all this kind of stuff. I'm going to
22:26 choose 4.1 mini, but as you can see, you
22:28 can come back and change this whenever
22:30 you want. And I'm going to keep this
22:31 really simple. In the prompt, I'm just
22:33 going to type in, tell me a joke. So
22:35 now, when this node executes, it's
22:38 basically just going to be sending this
22:39 message to OpenAI's model, which is
22:42 GBT4.1 Mini, and it's just going to say,
22:44 "Tell me a joke." And then what we're
22:46 going to get on the output panel is the
22:48 actual joke. So what I can do is come up
22:50 right here and click on test step. This
22:52 is going to run this node and then we
22:54 get an output over here. And as you can
22:56 see both with the input and the output
22:59 we have three options of how we want to
23:00 view our data. We can click on schema,
23:03 we can click on table or we can click on
23:05 JSON. And this is all the exact same
23:07 data. It's just like a different way to
23:09 actually look at it. I typically like to
23:11 look at schema. I think it just looks
23:13 the most simple and natural language.
23:15 But what you can see here is the message
23:17 that we got back from this open AAI
23:19 model was sure here's a joke for you.
23:21 Why don't scientists trust atoms?
23:23 Because they make up everything. And
23:25 what's cool about schemas is that this
23:27 is all drag and drop. So now once we
23:29 have this output, we could basically
23:30 just use it however we want. So if I
23:32 click out of here and I open up another
23:34 node after this, and for now I'm just
23:36 going to grab a set node just to show
23:37 you guys how we can drag and drop. What
23:39 I would do is let's say we wanted to add
23:41 a new field and I'm just going to call
23:43 this open AI's response. So we're
23:47 creating a field called open AI's
23:48 response. And as you can see it says
23:50 drag an input field from the left to use
23:52 it here. So as we know every node we
23:54 have input configuration output on the
23:57 input we can basically choose which one
23:59 of these things do we want to use. I
24:00 just want to reference this content
24:02 which is the actual thing that OpenAI
24:04 said to us. So I would drag this from
24:06 here right into the value. And now we
24:08 can see that we have what's called a
24:10 variable. So anything that's going to be
24:12 wrapped in these two curly braces and
24:14 it's going to be green is a variable.
24:16 And it's coming through as JSON
24:18 message.content which is basically just
24:20 something that represents whatever is
24:22 coming from the previous node in the
24:24 field called content. So we can see
24:26 right here JSON message.content we have
24:29 message. Within message we have
24:30 basically a subfolder called content and
24:33 that's where we access this actual
24:35 result this real text. And you can see
24:37 if I click into this variable, if I make
24:39 it full screen, we have an expression
24:41 which is our JSON variable. And then we
24:43 have our result, which is the actual
24:45 text that we want back. So now if I go
24:48 ahead and test this step, we can see
24:49 that we only get output to us OpenAI's
24:52 response, which is the text we want.
24:54 Okay, so this would basically be a
24:56 workflow because we have a trigger and
24:58 then we have our nodes that are going to
25:00 execute when we hit test workflow. So if
25:02 I hit test workflow, it's going to run
25:03 the whole thing. And as you can see,
25:05 super visual. We saw that OpenAI was
25:07 thinking and then we come over here and
25:09 we get our final output which was the
25:11 actual joke. And now let me show you one
25:12 more example of how we can map our
25:14 different variables without using a
25:16 manual trigger. So let's say we don't
25:18 want a manual trigger. I'm just going to
25:19 delete that. But now we have no way to
25:21 run this workflow because there's no
25:22 sort of trigger. So I'm just going to
25:24 come back in here and grab a chat
25:25 trigger just so we can talk to this
25:27 workflow in Naden. I'm going to hook it
25:29 up right here. I would just basically
25:31 drag this plus into the node that I
25:33 want. So I just drag it into OpenAI. And
25:35 now these two things are connected. So
25:37 if I went into the chat and I said
25:39 hello, it's going to run the whole
25:41 workflow, but it's not really going to
25:43 make sense because I said hello and now
25:44 it's telling me a joke about why don't
25:46 scientists trust atoms. So what I would
25:48 want to do is I'd want to come into this
25:50 OpenAI node right here. And I'm just
25:52 going to change the actual prompt. So
25:54 rather than asking it to tell me a joke,
25:56 what I would do is I'd just delete this.
25:58 And what I want to do is I want OpenAI
26:00 to go ahead and process whatever I type
26:02 in this chat. same way it would work if
26:05 we were in chatbt in our browser and
26:07 whatever we type OpenAI responds to. So
26:10 all I would have to do to do that is I
26:12 would grab the chat input variable right
26:14 here. I would drag that into the prompt
26:16 section. And now if I open this up, it's
26:20 looking at the expression called
26:21 JSON.input because this field right here
26:23 is called chat input. And then the
26:25 result is going to be whatever we type
26:27 anytime. even if it's different 100
26:29 times in a row, it's always going to
26:30 come back as a result that's different,
26:32 but it's always going to be referenced
26:34 as the same exact expression. So, just
26:36 to actually show you guys this, let's
26:38 save this workflow. And I'm going to
26:40 say, "My name is
26:42 Nate. I like to eat ice
26:46 cream. Make up a funny story about me."
26:51 Okay, so we'll send this off and the
26:53 response that we should get will be one
26:55 that is actually about me and it's going
26:57 to have some sort of element of a story
26:59 with ice cream. So let's take a look. So
27:00 it said, "Sure, Nate, here's a funny
27:02 story for you." And actually, because
27:03 we're setting it, it's coming through a
27:05 little weird. So let's actually click
27:06 into here to look at it. Okay, so here
27:08 is the story. Let me just make this a
27:09 little bigger. I can go ahead and drag
27:10 the configuration panel around by doing
27:12 this. I can also make it larger or
27:14 smaller if I do this. So let's just make
27:16 it small. We'll move it all the way to
27:17 the left and let's read the story. So,
27:20 it said, "Sure, Nate. Here's a funny
27:22 story just for you. Once upon a time,
27:24 there was a guy named Nate who loved ice
27:25 cream more than anything else in the
27:26 world. One day, Nate decided to invent
27:28 the ultimate ice cream. A flavor so
27:31 amazing that it would make the entire
27:32 town go crazy." So, let's skip ahead to
27:34 the bottom. Basically, what happens is
27:36 from that day on, Nate's stand became
27:38 the funniest spot in town. A place where
27:40 you never knew if you'd get a sweet,
27:41 savory, or plain silly ice cream. And
27:43 Nate, he became the legendary ice cream
27:45 wizard. That sounds awesome. So that's
27:47 exactly how you guys can see what
27:49 happened was in this OpenAI node. We
27:52 have a dynamic input which was us
27:54 talking to this thing in a chat trigger.
27:56 We drag in that variable that represents
27:58 what we type into the user prompt. And
28:01 this is going to get sent to OpenAI's
28:03 model of GPT 4.1 Mini because we
28:06 configured this node to do so. And the
28:08 reason we were able to actually
28:09 successfully do that is because we put
28:11 in our API key or our password for
28:15 OpenAI. And then on the right we get
28:17 this output which we can look at either
28:18 in schema view, table view or JSON view.
28:22 But they all represent the same data. As
28:24 you can see, this is the exact story we
28:26 just read. Something I wanted to talk
28:28 about real quick that is going to be
28:29 super helpful for the rest of this
28:30 course is just understanding what is
28:32 JSON. And JSON stands for JavaScript
28:35 object notation. And it's just a way to
28:37 identify things. And the reason why it's
28:39 so important to talk about is because
28:40 over here, right, we all kind of know
28:42 what schema is. It's just kind of like
28:43 the way something's broken down. And as
28:45 you can see, we have different drill
28:47 downs over here. And we have different
28:48 things to reference. Then we all
28:50 understand what a table is. It's kind of
28:51 like a table view of different objects
28:53 with different things within them. Kind
28:55 of like the subfolders. And once again,
28:56 you can also drag and drop from table
28:58 view as well. And then we have JSON,
29:00 which also you can drag and drop. Don't
29:02 worry, you can drag and drop pretty much
29:04 this whole platform, which is why it's
29:05 awesome. But this may look a little more
29:08 cody or intimidating, but I want to talk
29:10 about why it is not. So, first of all,
29:13 JSON is so so important because
29:15 everything that we do is pretty much
29:17 going to be built on top of JSON. Even
29:19 the workflows that you're going to
29:20 download later when you'll see like,
29:22 hey, you can download this template for
29:24 free. When you download that, it's going
29:26 to be a JSON file, which means the whole
29:28 workflow in NN is basically represented
29:30 as JSON. And so, hopefully that doesn't
29:32 confuse you guys, but what it is is it's
29:35 literally just key value pairs. So what
29:38 I mean by that is like over here the key
29:41 is index and index equals zero and then
29:44 we have like the role of the openi
29:46 assistant and that's the key and the
29:48 value of the role is assistant. So it's
29:51 very very natural language if you really
29:52 break it down. What is the content that
29:54 we're looking at? The content that we're
29:55 looking at is this actual content over
29:58 here. But like I said the great thing
29:59 about that is that pretty much every
30:01 single large language model or like chat
30:03 gbt cloud 3.5 they're all trained on
30:06 JSON and they all understand it. So,
30:08 well, because it's universal. So, right
30:10 here on the left, we're looking at JSON.
30:11 If I was to just copy this entire JSON,
30:13 go into ChatgBT and say, "Hey, help me
30:17 understand this JSON." And then I just
30:19 basically pasted that in there, it's
30:21 going to be able to tell us exactly like
30:22 which keys are in here and what those
30:24 values are. So, it says this JSON
30:26 represents the response from an AI model
30:28 like chatbt in a structured format. Let
30:30 me break it down for you. So, basically,
30:32 it's going to explain what each part of
30:34 this JSON means. We can see the index is
30:36 zero. That means it's the first
30:37 response. We can see the role equals
30:39 assistant. We can see that the content
30:41 is the funny story about Nate. We can
30:44 see all this stuff and it basically is
30:45 able to not only break it down for us,
30:48 but let's say we need to make JSON. We
30:50 could say, "Hey, I have this natural
30:52 language. Can you make that into JSON
30:54 for me?" Hey, can you help me make a
30:55 JSON body where my name is Nate? I'm 23
31:00 years old. I went to the University of
31:02 Iowa. I like to play pickle ball. We'll
31:06 send that off and basically it will be
31:08 able to turn that into JSON for us. So
31:10 here you go. We can see name Nate, age
31:13 23, education, University of Iowa,
31:16 interest pickle ball. And so don't let
31:18 it overwhelm you. If you ever need help
31:20 either making JSON or understanding
31:22 JSON, throw it into chat and it will do
31:24 a phenomenal job for you. And actually,
31:26 just to show you guys that I'm not
31:27 lying, let's just copy this JSON that
31:29 chat gave us. Go back into our workflow
31:32 and I'm just going to add a set field
31:33 just to show you guys. And instead of
31:35 manual mapping, I'm just going to set
31:36 some data using JSON. So I'm going to
31:38 delete this, paste in exactly what chat
31:41 gave me. Hit test step. And what do we
31:43 see over here? We see the name of
31:44 someone named Nate. We see their age. We
31:46 see their education. And we see their
31:47 interest in either schema table or JSON
31:51 view. So hopefully that gives you guys
31:53 some reassurance. And just once again,
31:55 JSON's super important. And it's not
31:57 even code. That is just a really quick
32:00 foundational understanding of a trigger,
32:02 different nodes, action nodes, AI nodes.
32:05 You have a ton to play with. And that's
32:08 kind of like the whole most overwhelming
32:09 part about NIN is you know what you need
32:12 to do in your brain, but you don't know
32:14 maybe which is the best nen node to
32:16 actually get that job done. So that's
32:18 kind of the tough part is it's a lot of
32:19 just getting the reps in, understanding
32:21 what node is best for what. But I assure
32:24 you by the time your twoe trial is up,
32:25 you'll have mastered pretty much all
32:27 that. All right, but something else I
32:29 want to show you guys is now what we're
32:30 looking at is called the editor. So if
32:32 you look at the top middle right here,
32:34 we have an editor. And this is where we
32:35 can, you know, zoom out, we can move
32:37 around, we can basically edit our
32:39 workflow right here. And it moves from
32:41 left to right, as you guys saw, the same
32:42 way we we read from left to right. And
32:46 now, because we've done a few runs and
32:48 we've tested out these different nodes,
32:49 what we'll click into is executions. And
32:52 this will basically show us the
32:53 different times we've ran this workflow.
32:55 And what's cool about this is it will
32:57 show us the data that has moved through.
32:59 So let's say you set up a workflow that
33:01 every time you get an email, it's going
33:02 to send some sort of automated response.
33:04 You could come into this workflow, you
33:06 could click on executions, and you could
33:07 go look at what time they happened, what
33:09 actually came through, what email was
33:11 sent, all that kind of stuff. So if I go
33:13 all the way down to this third
33:15 execution, we can remember that what I
33:17 did earlier was I asked this node to
33:19 tell us a joke. We also had a manual
33:21 trigger rather than a chat trigger. And
33:23 we can see this version of the workflow.
33:26 I could now click into this node and I
33:28 could see this is when we had it
33:30 configured to tell us a joke. And we
33:32 could see the actual joke it told us
33:33 which was about scientists not trusting
33:35 atoms. And obviously we can still
33:37 manipulate this stuff, look at schema,
33:39 look at table and do the same thing on
33:40 that left-hand side as well. So I wanted
33:42 to talk about how you can import
33:44 templates into your own NN environment
33:46 because it's super cool and like I said
33:48 they're all kind of built on top of
33:49 JSON. So, I'm going to go to NN's
33:51 website and we're going to go to product
33:52 and we're going to scroll down here to
33:54 templates. And you can see there's over
33:56 2100 workflow automation templates. So,
33:58 let's scroll down. Let's say we want to
34:00 do this one with cloning viral Tik Toks
34:02 with AI avatars. And we can use this one
34:04 for free. So, I'll click on use for
34:05 free. And what's cool is we can either
34:07 copy the template to clipboard or since
34:09 we're in the cloud workspace, we could
34:10 just import it right away. And so, this
34:12 is logged into my other kind of my main
34:14 cloud instance, but I'll still show you
34:15 guys how this works. I would click on
34:16 this button. it would pull up this
34:18 screen where I just get to set up a few
34:19 things. So, there's going to be
34:20 different things we'd have to connect
34:22 to. So, you would basically just select
34:23 your different credentials if you
34:24 already had them set up. If not, you
34:26 could create them right here. And then
34:27 you would just basically be able to hit
34:30 continue. And as this loads up, you see
34:32 we have the exact template right there
34:34 to play with. Or let's say you're
34:36 scrolling on YouTube and you see just a
34:38 phenomenal Nate Herk YouTube video that
34:39 you want to play around with. All you
34:41 have to do is go to my free school
34:42 community and you will come into YouTube
34:44 resources or search for the title of the
34:46 video. And let's say you wanted to play
34:47 with this shorts automation that I
34:48 built. What you'll see right here is a
34:50 JSON file that you'll have to download.
34:52 Once you download that, you'll go back
34:53 into Nitn, create a new workflow, and
34:56 then when you import that from file if
34:57 you click on this button right here, you
34:59 can see the entire workflow comes in.
35:01 And then all you're going to have to do
35:02 is follow the setup guide in order to
35:03 connect your own credentials to these
35:05 different nodes. All right. And then the
35:06 final thing I wanted to talk about is
35:08 inactive versus active workflows. So you
35:10 may have noticed that none of our
35:11 executions actually counted up from
35:13 zero. And the reason is because this is
35:16 counting active workflow executions. And
35:18 if we come up here to the top right, we
35:20 can see that we have the ability to make
35:21 a workflow active, but it has to have a
35:24 trigger node that requires activation.
35:26 So real quick, let's say that we come in
35:27 here and we want a workflow to start
35:29 when we have a schedule trigger. So I
35:32 would go to schedule and I would
35:33 basically say, okay, I want this to go
35:35 off every single day at midnight as we
35:36 have here. And what would happen is
35:38 while this workflow is inactive, it's
35:41 only actually going to run if we hit
35:42 test workflow and then it runs. But if
35:45 we were to flick this on as active now,
35:47 it says your schedule trigger will now
35:49 trigger executions on the schedule you
35:51 have defined. These executions will not
35:53 show up immediately in the editor, but
35:55 you can see them in the execution list.
35:57 So this is basically saying two things.
35:59 It's saying now that we have the
36:00 schedule trigger set up to run at
36:01 midnight, it's actually going to run at
36:03 midnight because it's active. If we left
36:05 this inactive, it would not actually
36:07 run. And all it meant by the second part
36:09 is if we were sitting in this workflow
36:11 at midnight, we wouldn't see it execute
36:13 and go spinning and green and red in
36:16 live real time, but it would still show
36:18 up as an execution. But if it's an
36:20 active workflow, you just don't get to
36:22 see them live visually running and
36:24 spinning anymore. So that's the
36:26 difference between an active workflow
36:27 and an inactive workflow. Let's say you
36:29 have a trigger that's like um let's say
36:31 you have a HubSpot trigger where you
36:33 want this basically to fire off the
36:35 workflow whenever a new contact is
36:37 created. So you'd connect to HubSpot and
36:40 you would make this workflow active so
36:42 that it actually runs if a new contact's
36:44 created. If you left this inactive, even
36:46 though it says it's going to trigger on
36:48 new contact, it would not actually do so
36:50 unless this workflow was active. So
36:52 that's a super important thing to
36:53 remember. All right. And then one last
36:55 thing I want to talk about which we were
36:57 not going to dive into because we'll see
36:58 examples later is there is one more way
37:01 that we can see data rather than schema
37:03 table or JSON and it's something called
37:05 binary. So binary basically just means
37:08 an image or maybe a big PDF or a word
37:11 doc or a PowerPoint file. It's basically
37:14 something that's not explicitly
37:15 textbased. So let me show you exactly
37:17 what that might look like. What I'm
37:19 going to do is I'm going to add another
37:20 trigger under this workflow and I'm
37:22 going to click on tab. And even though
37:23 it doesn't say like what triggers this
37:25 workflow, we can still access different
37:26 triggers. So I'm just going to type in
37:28 form. And this is going to give us a
37:30 form submission that basically is an
37:32 NAND native form. And you can see
37:34 there's an option at the bottom for
37:35 triggers. So I'm going to click on this
37:36 trigger. Now basically what this pulls
37:38 up is another configuration panel, but
37:40 obviously we don't have an input because
37:42 it's a trigger, but we are going to get
37:43 an output. So anyways, let me just set
37:46 up a quick example form. I'm just going
37:47 to say the title of this form is demo.
37:50 The description is binary data. And now
37:53 what happens if I click on test step,
37:55 it's going to pull up this form. And as
37:57 you can see, we haven't set up like any
37:58 fields for people to actually submit
38:00 stuff. So the only option is to submit.
38:02 But when I hit submit, you can see that
38:04 the node has been executed. And now
38:06 there's actually data in here. Submitted
38:07 at with a timestamp. And then we have
38:09 different information right here. So let
38:11 me just show you guys. We can add a form
38:13 element. And when I'm adding a form
38:15 element, we can basically have this be,
38:16 you know, date, it can be a drop down,
38:18 it can be an email, it can be a file, it
38:20 can be text. So, real quick, I'm just
38:22 going to show you an example where,
38:23 let's say we have a form where someone
38:24 has to submit their name. We have the
38:27 option to add a placeholder or make it
38:29 required. And this isn't really the bulk
38:30 of what I'm trying to show you guys. I
38:32 just want to show you binary data. But
38:34 anyways, let's say we're adding another
38:35 field that's going to be a file. I'm
38:37 just going to say file. And this will
38:39 also be required. And now if I go ahead
38:41 and hit test step, it's going to pull up
38:43 a new form for us with a name parameter
38:45 and a file parameter. So what I did is I
38:47 put my name and I put in just a YouTube
38:49 short that I had published. And you can
38:51 see it's an MP4 file. So if I hit
38:53 submit, we're going to get this data
38:54 pulled into N as you can see in the
38:56 background. Just go ahead and watch. The
38:58 form is going to actually capture this
39:00 data. There you go. Form submitted. And
39:03 now what we see right here is binary
39:05 data. So this is interesting, right? We
39:07 still have our schema. We still have our
39:09 table. We still have our JSON, but what
39:11 this is showing us is basically, okay,
39:13 the name that the person submitted was
39:15 Nate. The file, here are some
39:16 information about it as far as the name
39:19 of it, the mime type, and the size, but
39:21 we don't actually access the file
39:23 through table or JSON or schema view.
39:25 The only way we can access a video file
39:27 is through binary. And as you can see,
39:29 if I clicked on view, it's my actual
39:31 video file right here. And so that's all
39:33 I really wanted to show you guys was
39:34 when you're working with PDFs or images
39:36 or videos, a lot of times they're going
39:38 to come through as binary, which is a
39:39 little confusing at first, but it's not
39:41 too bad. And we will cover an example
39:42 later in this tutorial where we look at
39:44 a binary file and we process it. But as
39:47 you can see now, if we were doing a next
39:49 node, we would have schema, table, JSON,
39:52 and binary. So we're still able to work
39:54 with the binary. We're still able to
39:55 reference it. But I just wanted to throw
39:57 out there, when you see binary, don't
39:58 get scared. It just basically means it's
40:00 a different file type. It's not just
40:02 textbased. Okay, so that's going to do
40:04 it for just kind of setting up the
40:05 foundational knowledge and getting
40:07 familiar with the dashboard and the UI a
40:08 little bit. And as you move into these
40:11 next tutorials, which are going to be
40:12 some step by steps, I'm going to walk
40:14 through every single thing with you guys
40:15 setting up different accounts with
40:17 Google and something called Pine Cone.
40:19 And we'll talk about all this stuff step
40:20 by step. But hopefully now it's going to
40:22 be a lot better moving into those
40:24 sections because you've seen, you know,
40:25 some of the input stuff and how you
40:27 configure nodes and just like all this
40:29 terminology that you may not have been
40:30 familiar with like JSON, JavaScript
40:33 variables, workflows, executions, that
40:36 sort of stuff. So, like I said, let's
40:38 move into those actual step-by-step
40:39 builds. And I can assure you guys,
40:41 you're going to feel a lot more
40:42 comfortable after you have built a
40:43 workflow end to end. All right, we're
40:46 going to talk about data types in Nadn
40:48 and what those look like. It's really
40:49 important to get familiar with this
40:50 before we actually start automating
40:52 things and building agents and stuff
40:53 like that. So, what I'm going to do is
40:55 just pull in a set node. As you guys
40:56 know, this just lets us modify, add, or
40:59 remove fields. And it's very, very
41:01 simple. We basically would just click on
41:02 this to add fields. We can add the name
41:05 of the field. We choose the data type,
41:07 and then we set the value, whether
41:08 that's a fixed value, which we'll be
41:10 looking at here, or if we're dragging in
41:13 some sort of variable from the lefth
41:14 hand side. But clearly, right now, we
41:15 have no data incoming. We just have a
41:17 manual trigger. So, what I'm going to do
41:20 is zoom in on the actual browser so we
41:22 can examine this data on the output a
41:24 bit bigger and I don't have to just keep
41:26 cutting back and forth with the editing.
41:27 So, as you can see, there's five main
41:29 data types that we have access to and
41:31 end it in. We have a string, which is
41:33 basically just a fancy name for a word.
41:35 Um, as you can see, it's represented by
41:36 a little a, a letter a. Then we have a
41:40 number, which is represented by a pound
41:42 sign or a hashtag, whatever you want to
41:43 call it. Um, it's pretty
41:44 self-explanatory. Then we have a boolean
41:47 which is basically just going to be true
41:48 or false. That's basically the only
41:50 thing it can be represented by a little
41:52 checkbox. We have an array which is just
41:54 a fancy word for list. And we'll see
41:56 exactly what this looks like. And then
41:58 we have an object which is probably the
42:00 most confusing one which basically means
42:01 it's just this big block which can have
42:03 strings in them, numbers in them. It can
42:05 have booleans in them. It can have
42:07 arrays in them. And it can also have
42:09 nested objects within objects. So we'll
42:11 take a look at that. Let's just start
42:12 off real quick with the string. So let's
42:14 say a string would be a name and that
42:17 would be my name. So if I hit test step
42:18 on the right hand side in the JSON, it
42:21 comes through as key value pair like we
42:23 talked about. Name equals Nate. Super
42:26 simple. You can tell it's a string
42:28 because right here we have two quotes
42:30 around the word Nate. So that represents
42:32 a string. Or you could go to the schema
42:34 and you can see that with name equals
42:36 Nate, there's the little letter A and
42:38 that basically says, okay, this is a
42:39 string. As you see, it matches up right
42:41 here. Cool. So that's a string. Let's
42:44 switch over to a number. Now we'll just
42:46 say we're looking at age and we'll throw
42:48 in the number 50. Hit test step. And now
42:51 we see age equals 50 with the pound sign
42:54 right here as the symbol in the schema
42:55 view. Or if we go to JSON view, we have
42:58 the key value pair age equals 50. But
43:01 now there are no double quotes around
43:03 the actual number. It's green. So that's
43:05 how we know it's not a string. This is a
43:07 number. And um that's where you may run
43:10 into some issues where if you had like
43:11 age coming through as a string, you
43:13 wouldn't be able to like do any
43:15 summarizations or filters, you know,
43:17 like if age is greater than 50, send it
43:19 off this way. If it's less than 50, send
43:21 it that way. In order to do that type of
43:23 filtering and routing, you would need to
43:24 make sure that age is actually a number
43:26 variable type or data type. Cool. So
43:30 there's age. Let's go to a boolean. So
43:32 we're going to basically just say adult.
43:35 And that can only be true or false. You
43:36 see, I don't have the option to type
43:39 anything here. It's only going to be
43:40 false or it's only going to be true. And
43:42 as you can see, it'll come through.
43:44 It'll look like a string, but there's no
43:45 quotes around it. It's green. And that's
43:47 how we know it's a boolean. Or we could
43:49 go to schema, and we can see that
43:50 there's a checkbox rather than the
43:53 letter A
43:54 symbol. Now, we're going to move on to
43:56 an array. And this one's interesting,
43:58 right? So, let's just say we we want to
43:59 have a list of names. So, if I have a
44:01 list of names and I was typing in my
44:03 name and I tried to hit test step, this
44:05 is where you would run into an error
44:07 because it's basically saying, okay, the
44:09 field called names, which we set right
44:10 here, it's expecting to get an array,
44:13 but all we got was Nate, which is
44:15 basically a string. So, to fix this
44:17 error, change the type for the field
44:19 names or you can ignore type
44:21 conversions, whatever. Um, so if we were
44:24 to come down to the option and ignore
44:25 type conversions. So when we hit ignore
44:27 type conversions and tested the step, it
44:29 basically just converted the field
44:30 called names to a string because it just
44:32 could understand that this was a string
44:34 rather than an array. So let's turn that
44:35 back off and let's actually see how we
44:37 could get this to work if we wanted to
44:39 make an array. So like we know an array
44:42 just is a fancy word for a list. And in
44:44 order for us to actually send through an
44:45 end and say, okay, this is a list, we
44:48 have to wrap it in square brackets like
44:50 this. But we also have to wrap each item
44:53 in the list in quotes. So I have to go
44:55 like this and go like that. And now this
44:58 would pass through as a list of a of
45:00 different strings. And those are names.
45:02 And so if I wanted to add another one
45:04 after the first item, I would put a
45:06 comma. I put two quotes. And then inside
45:08 that I could put another name. Hit test
45:10 step. And now you can see we're getting
45:12 this array that's made up of different
45:14 strings and they're all going to be
45:15 different names. So I could expand that.
45:17 I could close it out. Um we could drag
45:19 in different names. And in JSON, what
45:21 that looks like is we have our key and
45:23 then we have two closed brackets, which
45:25 is basically exactly what like right
45:27 here. This is exactly what we typed
45:29 right here. So that's how it's being
45:30 represented within these square brackets
45:32 right here. Okay, cool. So the final one
45:34 we have to talk about is an object. And
45:36 this one's a little more complex. So if
45:38 I was to hit test step here, it's going
45:40 to tell us names expects an object, but
45:42 we got an array. So once again, you
45:44 could come in here, ignore type
45:45 conversions, and then it would just
45:46 basically come through as a string, but
45:49 it's not coming through as an array. So
45:50 that's not how we want to do it. And I
45:52 don't want to mess with the actual like
45:55 schema of typing in an object. So what
45:57 I'm going to do is go to chat. I
45:58 literally just said, give me an example
45:59 JSON object to put into naden. It gives
46:02 me this example JSON object. I'm going
46:03 to copy that. Come into the set node,
46:06 and instead of manual mapping, I'm just
46:07 going to customize it with JSON. Paste
46:09 the one that chat just gave us. And when
46:12 I hit test step, what we now see first
46:14 of all in the schema view is we have one
46:16 item
46:18 with you know this is an object and all
46:21 this different stuff makes it up. So we
46:22 have a string which is name herk. We
46:24 have a string which is email nate
46:26 example.com. We have a string which is
46:27 company true horizon. Then we have an
46:30 array of interests within this object.
46:33 So I could close this out. I could open
46:34 it up. And we have three interests. AI
46:36 automation nadn and YouTube content. And
46:38 this is, you know, chat GBT's long-term
46:40 memory about me making this. And then we
46:43 also have an object within our object
46:45 which is called
46:46 project. And the interesting difference
46:48 here with an object or an array is that
46:51 when you have an array of interests,
46:53 every single item in that array is going
46:54 to be called interest zero, interest
46:56 one, interest two. And by the way, this
46:58 is three interests, but computers start
47:00 counting from zero. So that's why it
47:01 says 0, one, two. But with an object, it
47:04 doesn't all have to be the same thing.
47:06 So you can see in this project object
47:08 project object we have one string called
47:11 title we have one string called called
47:13 called status and we have one string
47:15 called deadline and this all makes up
47:17 its own object. As you can see if we
47:18 went to table view this is literally
47:20 just one item that's really easy to
47:22 read. And you can tell that this is an
47:24 array because it goes 012. And you can
47:26 tell that this is an object because it
47:27 has different fields in it. This is a
47:29 one item. It's one object. It's got
47:31 strings up top. It has no numbers
47:33 actually. So the date right here, this
47:35 is coming through as a string variable
47:37 type. We can tell because it's not
47:38 green. We can tell because it has double
47:40 quotes around it. And we can also tell
47:42 because in schema it comes through with
47:43 the letter A. But this is just how you
47:46 can see there's these different things
47:47 that make up um this object. And you can
47:50 even close them down in JSON view. We
47:52 can see interest is an array that has
47:53 three items. We could open that up. We
47:55 can see project is an object because
47:57 it's wrapped in in um curly braces, not
47:59 not um the closed square brackets as you
48:02 can see. So, there's a difference. And I
48:05 know this wasn't super detailed and it's
48:08 just something really really important
48:09 to know heading into when you actually
48:11 start to build stuff out because you're
48:12 probably going to get some of those
48:13 errors where you're like, you know,
48:15 blank expects an object but got this or
48:17 expects an array and got this. So, just
48:19 wanted to make sure I came in here and
48:21 threw that module at you guys and
48:22 hopefully it'll save you some headaches
48:24 down the road. Real quick, guys, if you
48:26 want to be able to download all the
48:27 resources from this video, they'll be
48:29 available for free in my free school
48:31 community, which will be the link in the
48:32 pinned comment. There'll be a zip file
48:34 in there that has all 23 of these
48:36 workflows, as you can see, and also two
48:38 PDFs at the bottom, which are covered in
48:40 the video. So, like I said, join the
48:41 Free School community. Not only does it
48:43 have all of my YouTube resources, but
48:45 it's also a really quick growing
48:46 community of people who are obsessed
48:47 with AI automation and using ND every
48:49 day. All you'll have to do is search for
48:51 the title of this video using the search
48:53 bar or you can click on YouTube
48:54 resources and find the post associated
48:56 with this video. And then you'll have
48:57 the zip file right here to download
48:59 which once again is going to have all 23
49:01 of these JSON N workflows and two PDFs.
49:04 And there may even be some bonus files
49:06 in here. You'll just have to join the
49:07 free school community to find out. Okay,
49:09 so we talked about AI agents. We talked
49:11 about AI workflows. We've gotten into
49:12 NADN and set up our account. We
49:14 understand workflows, nodes, triggers,
49:16 JSON, stuff like that, and data types.
49:19 Now, it's time to use all that stuff
49:20 that we've talked about and start
49:21 applying it. So, we're going to head
49:22 into this next portion of this course,
49:24 which is going to be about step-by-step
49:25 builds, where I'm going to walk you
49:26 through every single step live, and
49:29 we'll have some pretty cool workflows
49:30 set up by the end. So, let's get into
49:32 it. Today, we're going to be looking at
49:34 three simple AI workflows that you can
49:36 build right now to get started learning
49:37 NAND. We're going to walk through
49:39 everything step by step, including all
49:40 of the credentials and the setups. So,
49:42 let's take a look at the three workflows
49:43 we're going to be building today. All
49:45 right, the first one is going to be a
49:46 rag pipeline and chatbot. And if you
49:48 don't know what rag means, don't worry.
49:50 We're going to explain it all. But at a
49:51 high level, what we're doing is we're
49:52 going to be using Pine Cone as a vector
49:54 database. If you don't know what a
49:55 vector database is, we'll break it down.
49:57 We're going to be using Google Drive.
49:58 We're going to be using Google Docs. And
50:00 then something called Open Router, which
50:01 lets us connect to a bunch of different
50:02 AI models like OpenAI's models or
50:05 Anthropics models. The second workflow
50:07 we're going to look at is a customer
50:08 support workflow that's kind of going to
50:09 be building off of the first one we just
50:11 built. Because in the first workflow,
50:13 we're going to be putting data into a
50:14 Pine Cone vector database. And in this
50:16 one, we're going to use that data in
50:17 there in order to respond to customer
50:19 support related emails. So, we'll
50:21 already have had Pine Cone set up, but
50:23 we're going to set up our credentials
50:24 for Gmail. And then we're also going to
50:25 be using an NAN AI agent as well as Open
50:28 Router once again. And then finally,
50:30 we're going to be doing LinkedIn content
50:31 creation. And in this one, we'll be
50:33 using an NAN AI agent and open router
50:35 once again, but we'll have two new
50:36 credentials to set up. The first one
50:38 being Tavi, which is going to let us
50:39 search the web. And then the second one
50:41 will be Google Sheets where we're going
50:42 to store our content ideas, pull them
50:44 in, and then have the content written
50:47 back to that Google sheet. So by the end
50:49 of this video, you're going to have
50:50 three workflows set up and you're going
50:51 to have a really good foundation to
50:52 continue to learn more about NADN.
50:55 You'll already have gotten a lot of
50:56 credentials set up and understand what
50:57 goes into connecting to different
50:58 services. One of the trickiest being
51:00 Google. So we'll walk through that step
51:02 by step and then you'll have it
51:03 configured and you'll be good. And then
51:04 from there, you'll be able to
51:05 continuously build on top of these three
51:07 workflows that we're going to walk
51:08 through together because there's really
51:10 no such thing as a finished product in
51:11 the space. Different AI models keep
51:13 getting released and keep getting
51:14 better. There's always ways to improve
51:15 your templates. And the cool thing about
51:17 building workflows in NAN is that you
51:19 can make them super customized for
51:20 exactly what you're looking for. So, if
51:22 this sounds good to you, let's hop into
51:24 that first workflow. Okay, so for this
51:26 first workflow, we're building a rag
51:27 pipeline and chatbot. And so if that
51:29 sounds like a bunch of gibberish to you,
51:31 let's quickly understand what rag is and
51:33 what a vector database is. So rag stands
51:36 for retrieval augmented generation. And
51:38 in the simplest terms, let's say you ask
51:40 me a question and I don't actually know
51:41 the answer. I would just kind of Google
51:43 it and then I would get the answer from
51:45 my phone and then I would tell you the
51:47 answer. So in this case, when we're
51:48 building a rag chatbot, we're going to
51:50 be asking the chatbot questions and it's
51:52 not going to know the answer. So it's
51:53 going to look inside our vector
51:54 database, find the answer, and then it's
51:56 going to respond to us. And so when
51:58 we're combining the elements of rag with
52:00 a vector database, here's how it works.
52:02 So the first thing we want to talk about
52:03 is actually what is a vector database.
52:06 So essentially this is what a vector
52:07 database would look like. We're all
52:09 familiar with like an x and yaxis graph
52:11 where you can plot points on there on a
52:12 two dimensional plane. But a vector
52:14 database is a multi-dimensional graph of
52:17 points. So in this case, you can see
52:19 this multi-dimensional space with all
52:20 these different points or vectors. And
52:23 each vector is placed based on the
52:25 actual meaning of the word or words in
52:27 the vector. So over here you can see we
52:29 have wolf, dog and cat. And they're
52:31 placed similarly because the meaning of
52:33 these words are all like animals.
52:35 Whereas over here we have apple and
52:36 banana which the meaning of the words
52:38 are food more likely fruits. And that's
52:40 why they're placed over here together.
52:42 So when we're searching through the
52:44 database, we basically vectorize a
52:46 question the same way we would vectorize
52:48 any of these other points. And in this
52:50 case, we were asking for a kitten. And
52:51 then that query gets placed over here
52:53 near the other animals and then we're
52:54 able to say okay well we have all these
52:56 results now. So what that looks like and
52:58 what we'll see when we get into NAND is
53:00 we have a document that we want to
53:01 vectorize. We have to split the document
53:03 up into chunks because we can't put like
53:05 a 50page PDF as one chunk. So it gets
53:07 split up and then we're going to run it
53:09 through something called an embeddings
53:10 model which basically just turns text
53:12 into numbers. Just as simple as that.
53:14 And as you can see in this case let's
53:16 say we had a document about a company.
53:18 We have company data, finance data, and
53:20 marketing data. And they all get placed
53:22 differently because they mean different
53:24 things. And the the context of those
53:26 chunks are different. And then this
53:28 visual down here is just kind of how an
53:30 LLM or in this case, this agent takes
53:32 our question, turns it into its own
53:34 question. We vectorize that using the
53:36 same embeddings model that we used up
53:38 here to vectorize the original data. And
53:40 then because it gets placed here, it
53:42 just grabs back any vectors that are
53:44 nearest, maybe like the nearest four or
53:46 five, and then it brings it back in
53:48 order to respond to us. So don't want to
53:49 dive too much into this. Don't want to
53:51 over complicate it, but hopefully this
53:53 all makes sense. Cool. So now that we
53:55 understand that, let's actually start
53:57 building this workflow. So what we're
53:58 going to do here is we are going to
53:59 click on add first step because every
54:01 workflow needs a trigger that basically
54:03 starts the workflow. So, I'm going to
54:05 type in Google Drive because what we're
54:08 going to do is we are going to pull in a
54:10 document from our Google Drive in order
54:12 to vectorize it. So, I'm going to choose
54:14 a trigger which is on changes involving
54:15 a specific folder. And what we have to
54:17 do now is connect our account. As you
54:19 can see, I'm already connected, but what
54:20 we're going to do is click on create new
54:22 credential in order to connect our
54:23 Google Drive account. And what we have
54:25 to do is go get a client ID and a
54:28 secret. So, what we want to do is click
54:29 on open docs, which is going to bring us
54:31 to Naden's documents on how to set up
54:33 this credential. We have a prerequisite
54:35 which is creating a Google Cloud
54:37 account. So I'm going to click on Google
54:38 Cloud account and we're going to set up
54:40 a new project. Okay. So I just signed
54:42 into a new account and I'm going to set
54:43 up a whole project and walk through the
54:45 credentials with you guys. You'll click
54:46 up here. You'll probably have something
54:48 up here that says like new project and
54:49 then you'll click into new project. All
54:51 we have to do now is um name it and you
54:54 you'll be able to start for free so
54:55 don't worry about that yet. So I'm just
54:56 going to name this one demo and I'm
54:58 going to create this new project. And
55:00 now up here in the top right you're
55:01 going to see that it's kind of spinning
55:02 up this project. and then we'll move
55:04 forward. Okay, so it's already done and
55:06 now I can select this project. So now
55:08 you can see up here I'm in my new
55:10 project called demo. I'm going to click
55:12 on these three lines in the top left and
55:14 what we're going to do first is go to
55:16 APIs and services and click on enabled
55:18 APIs and services. And what we want to
55:20 do is add the ones we need. And so right
55:22 now all I'm going to do is add Google
55:25 Drive. And you can see it's going to
55:27 come up with Google Drive API. And then
55:30 all we have to do is really simply click
55:31 enable. And there we I just enabled it.
55:33 So you can see here the status is
55:35 enabled. And now we have to set up
55:36 something called our OOTH consent
55:37 screen, which basically is just going to
55:40 let Nadn know that Google Drive and
55:43 Naden are allowed to talk to each other
55:44 and have permissions. So right here, I'm
55:46 going to click on OOTH consent screen.
55:48 We don't have one yet, so I'm going to
55:49 click on get started. I'm going to give
55:51 it a name. So we're just going to call
55:52 this one demo. Once again, I'm going to
55:54 add a support email. I'm going to click
55:56 on next. Because I'm not using a Google
55:59 Workspace account, I'm just using a, you
56:01 know,
56:02 nate88@gmail.com. I'm going to have to
56:03 choose external. I'm going to click on
56:05 next. For contact information, I'm
56:07 putting the same email as I used to
56:08 create this whole project. Click on next
56:11 and then agree to terms. And then we're
56:12 going to create that OOTH consent
56:15 screen. Okay, so we're not done yet. The
56:17 next thing we want to do is we want to
56:18 click on audience. And we're going to
56:20 add ourselves as a test user. So we
56:22 could also make the app published by
56:23 publishing it right here, but I'm just
56:25 going to keep it in test. And when we
56:26 keep it in test mode, we have to add a
56:28 test user. So I'm going to put in that
56:30 same email from before. And this is
56:31 going to be the email of the Google
56:32 Drive we want to access. So I put in my
56:34 email. You can see I saved it down here.
56:36 And then finally, all we need to do is
56:38 come back into here. Go to clients. And
56:40 then we need to create a new client.
56:42 We're going to click on web app. We're
56:45 going to name it whatever we want. Of
56:46 course, I'm just going to call this one
56:47 demo once again. And now we need to
56:50 basically add a redirect URI. So if you
56:52 click back in Nitn, we have one right
56:54 here. So, we're going to copy this, go
56:57 back into cloud, and we're going to add
56:58 a URI and paste it right in there, and
57:00 then hit
57:03 create, and then once that's created,
57:05 it's going to give us an ID and a
57:06 secret. So, all we have to do is copy
57:08 the ID, go back into Nit and paste that
57:10 right
57:11 here. And then we need to go grab our
57:13 secret from Google Cloud, and then paste
57:16 that right in there. And now we have a
57:18 little button that says sign in with
57:19 Google. So, I'm going to open that up.
57:21 It's going to pull up a window to have
57:22 you sign in. Make sure you sign in with
57:24 the same account that you just had
57:25 yourself as a test user. That one. And
57:28 then you'll have to continue. And then
57:30 here is basically saying like what
57:31 permissions do we have? Does anyone have
57:33 to your Google Drive? So I'm just going
57:34 to select all. I'm going to hit
57:36 continue. And then we should be good.
57:37 Connection successful and we are now
57:39 connected. And you may just want to
57:41 rename this credential so you know you
57:43 know which email it is. So now I've
57:44 saved my credential and we should be
57:46 able to access the Google Drive now. So,
57:48 what I'm going to do is I'm going to
57:49 click on this list and it's going to
57:50 show me the folders that I have in
57:52 Google Drive. So, that's awesome. Now,
57:55 for the sake of this video, I'm in my
57:56 Google Drive and I'm going to create a
57:57 new folder. So, new folder. We're going
57:59 to call this one um FAQ. Create this one
58:03 because we're going to be uploading an
58:05 FAQ document into it. So, here's my FAQ
58:07 folder um right here. And then what I
58:09 have is down here I made a policy and
58:12 FAQ document which looks like this. We
58:14 have some store policies and then we
58:15 also have some FAQs at the bottom. So,
58:17 all I'm going to do is I'm going to drag
58:19 in my policy and FAQ document into that
58:21 new FAQ folder. And then if we come into
58:25 NAN, we click on the new folder that we
58:27 just made. So, it's not here yet. I'm
58:29 just going to click on these dots and
58:30 click on refresh list. Now, we should
58:32 see the FAQ folder. There it is. Click
58:35 on it. We're going to click on what are
58:36 we watching this folder for. I'm going
58:38 to be watching for a file created. And
58:40 then, I'm just going to hit fetch test
58:43 event. And now we can see that we did in
58:45 fact get something back. So, let's make
58:47 sure this is the right one. Yep. So,
58:48 there's a lot of nasty information
58:50 coming through. I'm going to switch over
58:51 here on the right hand side. This is
58:52 where we can see the output of every
58:54 node. I'm going to click on table and
58:55 I'm just going to scroll over and there
58:57 should be a field called file name. Here
59:00 it is. Name. And we have policy and FAQ
59:02 document. So, we know we have the right
59:04 document in our Google Drive. Okay. So,
59:06 perfect. Every time we drop in a new
59:08 file into that Google folder, it's going
59:10 to start this workflow. And now we just
59:11 have to configure what happens after the
59:13 workflow starts. So, all we want to do
59:15 really is we want to pull this data into
59:17 n so that we can put it into our pine
59:20 cone database. So, off of this trigger,
59:22 I'm going to add a new node and I'm
59:24 going to grab another Google Drive node
59:26 because what happened is basically we
59:28 have the file ID and the file name, but
59:30 we don't have the contents of the file.
59:32 So, we're going to do a download file
59:33 node from Google Drive. I'm going to
59:35 rename this one and just call it
59:36 download file just to keep ourselves
59:38 organized. We already have our
59:40 credential connected and now it's
59:41 basically saying what file do you want
59:43 to download. We have the ability to
59:45 choose from a list. But if we choose
59:47 from the list, it's going to be this
59:48 file every time we run the workflow. And
59:50 we want to make this dynamic. So we're
59:52 going to change from list to by ID. And
59:54 all we have to do now is we're going to
59:56 look on the lefth hand side for that
59:57 file that we just pulled in. And we're
59:59 going to be looking for the ID of the
60:00 file. So I can see that I found it right
60:02 down here in the spaces array because we
60:05 have the name right here and then we
60:06 have the ID right above it. So, I'm
60:07 going to drag ID, put it right there in
60:10 this folder. It's coming through as a
60:11 variable called JSON ID. And that's just
60:14 basically referencing, you know,
60:15 whenever a file comes through on the the
60:17 Google Drive trigger. I'm going to use
60:19 the variable JSON. ID, which will always
60:21 pull in the files ID. So, then I'm going
60:23 to hit test step and we're going to see
60:24 that we're going to get the binary data
60:27 of this file over here that we could
60:28 download. And this is our policy and FAQ
60:30 document. Okay. So, there's step two. We
60:32 have the file downloaded in NADN. And
60:35 now it's just as simple as putting it
60:37 into pine cone. So before we do that,
60:39 let's head over to pine cone.io. Okay,
60:41 so now we are in pine cone.io, which is
60:43 a vector database provider. You can get
60:45 started for free. And what we're going
60:46 to do is sign up. Okay, so I just got
60:48 logged in. And once you get signed up,
60:50 you should see us a page similar to
60:52 this. It's a get started page. And what
60:54 we want to do is you want to come down
60:55 here and click on, you know, begin setup
60:57 because we need to create an index. So
60:59 I'm going to click on begin setup. We
61:02 have to name our index. So you can call
61:03 this whatever you want. We have to
61:05 choose a configuration for a text model.
61:08 We have to choose a configuration for an
61:09 embeddings model, which is sort of what
61:11 I talked about right in here. This is
61:13 going to turn our text chunks into a
61:15 vector. So what I'm going to do is I'm
61:17 going to choose text embedding three
61:19 small from OpenAI. It's the most cost
61:21 effective OpenAI embedding model. So I'm
61:23 going to choose that. Then I'm going to
61:25 keep scrolling down. I'm going to keep
61:26 mine as serverless. I'm going to keep
61:27 AWS as the cloud provider. I'm going to
61:29 keep this region. And then all I'm going
61:31 to do is hit create index. Once you
61:33 create your index, it'll show up right
61:34 here. But we're not done yet. You're
61:36 going to click into that index. And so I
61:37 already obviously have stuff in my
61:39 vector database. You won't have this.
61:40 What I'm going to do real quick is just
61:41 delete this information out of it. Okay.
61:44 So this is what yours should look like.
61:45 There's nothing in here yet. We have no
61:46 name spaces and we need to get this
61:48 configured. So on the left hand side, go
61:51 over here to API keys and you're going
61:53 to create a new API key. Name it
61:56 whatever you want, of course. Hit create
61:58 key. And then you're going to copy that
62:00 value. Okay, back in NDN, we have our
62:02 API key copied. We're going to add a new
62:05 node after the download file and we're
62:07 going to type in pine cone and we're
62:09 going to grab a pine cone vector store.
62:10 Then we're going to select add documents
62:12 to a vector store and we need to set up
62:14 our credential. So up here, you won't
62:16 have these and you're going to click on
62:18 create new credential. And all we need
62:19 to do here is just an API key. We don't
62:21 have to get a client ID or a secret. So
62:22 you're just going to paste in that API
62:24 key. Once that's pasted in there and
62:25 you've given it a name so you know what
62:26 this means. You'll hit save and it
62:28 should go green and we're connected to
62:30 Pine Cone and you can make sure that
62:32 you're connected by clicking on the
62:34 index and you should have the name of
62:36 the index right there that we just
62:37 created. So I'm going to go ahead and
62:39 choose my index. I'm going to click on
62:40 add option and we're going to be
62:42 basically adding this to a Pine Cone
62:43 namespace which back in here in Pine
62:45 Cone if I go back into my database my
62:48 index and I click in here you can see
62:50 that we have something called
62:51 namespaces. And this basically lets us
62:53 put data into different folders within
62:55 this one index. So if you don't specify
62:57 an index, it'll just come through as
62:59 default and that's going to be fine. But
63:00 we want to get into the habit of having
63:02 our data organized. So I'm going to go
63:04 back into NADN and I'm just going to
63:05 name this name space FAQ because that's
63:07 the type of data we're putting in. And
63:10 now I'm going to click out of this node.
63:12 So you can see the next thing that we
63:13 need to do is connect an embeddings
63:15 model and a document loader. So let's
63:17 start with the embeddings model. I'm
63:18 going to click on the plus and I'm going
63:20 to click on embeddings open AAI. And
63:22 actually, this is one thing I left out
63:23 of the Excalaw is that we also will need
63:25 to go get an OpenAI key. So, as you can
63:27 see, when we need to connect a
63:29 credential, you'll click on create new
63:30 credential and we just need to get an
63:32 API key. So, you're going to type in
63:33 OpenAI API. You'll click on this first
63:36 link here. If you don't have an account
63:37 yet, you'll sign in. And then once you
63:39 sign up, you want to go to your
63:40 dashboard. And then on the lefth hand
63:42 side, very similar thing to Pine Cone,
63:44 you'll click on API keys. And then we're
63:46 just going to create a new key. So you
63:47 can see I have a lot. We're going to
63:48 make a new one. And I'm calling
63:49 everything demo, but this is going to be
63:50 demo number three. Create new secret
63:53 key. And then we have our key. So we're
63:54 going to copy this and we're going to go
63:56 back into Nit. Paste that right here. We
63:58 paste it in our key. We've given in a
63:59 name. And now we'll hit save and we
64:01 should go green. Just keep in mind that
64:03 you may need to top up your account with
64:04 a few credits in order for you to
64:06 actually be able to run this model. Um,
64:08 so just keep that in mind. So then
64:10 what's really important to remember is
64:11 when we set up our pine cone index, we
64:13 use the embedding model text embedding
64:15 three small from OpenAI. So that's why
64:17 we have to make sure this matches right
64:19 here or this automation is going to
64:20 break. Okay, so we're good with the
64:22 embeddings and now we need to add a
64:24 document loader. So I'm going to click
64:25 on this plus right here. I'm going to
64:26 click on default data loader and we have
64:29 to just basically tell Pine Cone the
64:31 type of data we're putting in. And so
64:32 you have two options, JSON or binary. In
64:35 this case, it's really easy because we
64:37 downloaded a a Google Doc, which is on
64:39 the lefth hand side. You can tell it's
64:40 binary because up top right here on the
64:42 input, we can switch between JSON and
64:45 binary. And if we were uploading JSON,
64:47 all we'd be uploading is this gibberish
64:49 nonsense information that we don't need.
64:51 We want to upload the binary, which is
64:53 the actual policy and FAQ document. So,
64:55 I'm just going to switch this to binary.
64:57 I'm going to click out of here. And then
64:58 the last thing we need to do is add a
65:00 text splitter. So, this is where I was
65:01 talking about back in this Excal. we
65:04 have to split the document into
65:05 different chunks. And so that's what
65:07 we're doing here with this text
65:08 splitter. I'm going to choose a
65:10 recursive character text splitter.
65:12 There's three options and I won't dive
65:13 into the difference right now, but
65:15 recursive character text splitter will
65:17 help us keep context of the whole
65:18 document as a whole, even though we're
65:20 splitting it up. So for now, chunk size
65:22 is a th00and. That's just basically how
65:23 many characters am I going to put in
65:25 each chunk? And then is there going to
65:26 be any overlap between our chunks of
65:29 characters? So right now I'm just going
65:30 to leave it default a,000 and zero. So
65:33 that's it. You just built your first
65:35 automation for a rag pipeline. And now
65:37 we're just going to click on the play
65:38 button above the pine cone vector store
65:40 node in order to see it get vectorized.
65:42 So we're going to basically see that we
65:43 have four items that have left this
65:45 node. So this is basically telling us
65:47 that our Google doc that we downloaded
65:48 right here. So this document got turned
65:51 into four different vectors. So if I
65:53 click into the text splitter, we can see
65:54 we have four different responses and
65:56 this is the contents that went into each
65:59 chunk. So we can just verify this by
66:01 heading real quick into Pine Cone, we
66:03 can see we have a new name space that we
66:05 created called FAQ. Number of records is
66:07 four. And if we head over to the
66:09 browser, we can see that we do indeed
66:10 have these four vectors. And then the
66:12 text field right here, as you can see,
66:13 are the characters that were put into
66:15 each chunk. Okay, so that was the first
66:17 part of this workflow, but we're going
66:19 to real quick just make sure that this
66:21 actually works. So we're going to add a
66:22 rag chatbot. Okay. So, what I'm going to
66:24 do now is hit the tab, or I could also
66:26 have just clicked on the plus button
66:27 right here, and I'm going to type in AI
66:29 agent, and that is what we're going to
66:31 grab and pull into this workflow. So, we
66:33 have an AI agent, and let's actually
66:35 just put him right over here. Um, and
66:39 now what we need to do is we need to set
66:41 up how are we actually going to talk to
66:42 this agent. And we're just going to use
66:44 the default N chat window. So, once
66:46 again, I'm going to hit tab. I'm going
66:47 to type in chat. And we have a chat
66:49 trigger. And all I'm going to do is over
66:51 here, I'm going to grab the plus and I'm
66:53 going to drag it into the front of the
66:54 AI agent. So basically now whenever we
66:56 hit open chat and we talk right here,
66:58 the agent will read that chat message.
67:00 And we know this because if I click into
67:02 the agent, we can see the user message
67:04 is looking for one in the connected chat
67:07 trigger node, which we have right here
67:08 connected. Okay, so the first step with
67:10 an AI agent is we need to give it a
67:12 brain. So we need to give it some sort
67:14 of AI model to use. So we're going to
67:16 click on the plus right below chat
67:18 model. And what we could do now is we
67:20 could set up an OpenAI chat model
67:22 because we already have our API key from
67:23 OpenAI. But what I want to do is click
67:25 on open router because this is going to
67:27 allow us to choose from all different
67:30 chat models, not just OpenAIs. So we
67:32 could do Claude, we could do Google, we
67:33 could do Plexity. We have all these
67:35 different models in here which is going
67:36 to be really cool. And in order to get
67:37 an Open Router account, all you have to
67:39 do is go sign up and get an API key. So
67:42 you'll click on create new credential
67:43 and you can see we need an API key. So
67:45 you'll head over to openouter.ai. You'll
67:47 sign up for an account. And then all you
67:49 have to do is in the top right, you're
67:50 going to click on keys. And then once
67:52 again, kind of the same as all all the
67:54 other ones. You're going to create a new
67:55 key. You're going to give it a name.
67:57 You're going to click create. You have a
67:59 secret key. You're going to click copy.
68:01 And then when we go back into NN and
68:02 paste it in here, give it a name. And
68:04 then hit save. And we should go green.
68:05 We've connected to Open Router. And now
68:07 we have access to any of these different
68:09 chat models. So, in this case, let's use
68:12 let's use Claude um 3.5
68:17 Sonnet. And this is just to show you
68:19 guys you can connect to different ones.
68:21 But anyways, now we could click on open
68:22 chat. And actually, let me make sure you
68:24 guys can see him. If we say hello, it's
68:26 going to use its brain claw 3.5 sonnet.
68:29 And now it responded to us. Hi there.
68:30 How can I help you? So, just to validate
68:33 that our information is indeed in the
68:34 Pine Cone vector store, we're going to
68:36 click on a tool under the agent. We're
68:38 going to type in Pine Cone um and grab a
68:41 Pine Cone vector store and we're going
68:43 to grab the account that we just
68:44 selected. So, this was the demo I just
68:46 made. We're going to give it a name. So,
68:48 in this case, I'm just going to say
68:50 knowledge
68:51 base. We're going to give a description.
68:54 Call this tool to access the policy and
68:59 FAQ database. So, we're basically just
69:02 describing to the agent what this tool
69:03 does and when to use it. And then we
69:06 have to select the index and the name
69:08 space for it to look inside of. So the
69:09 index is easy. We only have one. It's
69:11 called sample. But now this is important
69:13 because if you don't give it the right
69:14 name space, it won't find the right
69:16 information. So we called ours FAQ. If
69:19 you remember in um our Pine Cone, we
69:21 have a namespace and we have FAQ right
69:23 here. So that's why we're doing FAQ. And
69:25 now it's going to be looking in the
69:26 right spot. So before we can chat with
69:28 it, we have to add an embeddings model
69:30 to our Pine Cone vector store, which
69:32 same thing as before. We're going to
69:33 grab OpenAI and we're going to use
69:35 embedding3 small and the same credential
69:37 you just made. And now we're going to be
69:39 good to go to chat with our rag agent.
69:41 So looking back in the document, we can
69:43 see we have some different stuff. So I'm
69:44 going to ask this chatbot what the
69:46 warranty policy is. So I'm going to open
69:48 up the chat window and say what is our
69:51 warranty policy? Send that off. And we
69:54 should see that it's going to use its
69:55 brain as well as the vector store in
69:57 order to create an answer for us because
69:59 it didn't know by
70:00 itself. So there we go. just finished up
70:03 and it said based on the information
70:05 from our knowledge base, here's the
70:06 warranty policy. We have one-year
70:08 standard coverage. We have, you know,
70:10 this email for claims processes. You
70:12 must provide proof of purchase and for
70:14 warranty exclusions that aren't covered,
70:16 damage due to misuse, water damage, blah
70:18 blah blah. Back in the policy
70:20 documentation, we can see that that is
70:22 exactly what we have in our knowledge
70:24 base for warranty policy. So, just
70:26 because I don't want this video to go
70:27 too long, I'm not going to do more
70:29 tests, but this is where you can get in
70:30 there and make sure it's working. One
70:31 thing to keep in mind is within the
70:33 agent, we didn't give it a system
70:34 prompt. And what a system prompt is is
70:36 just basically a message that tells the
70:38 agent how to do its job. So what you
70:41 could do is if you're having issues
70:42 here, you could say, you know, like this
70:43 is the name of our tool which is called
70:45 knowledgeb. You could tell the agent and
70:47 in system prompt, hey, like your job is
70:49 to help users answer questions about the
70:52 um you know, our policy database. You
70:54 have a tool called knowledgebase. You
70:56 need to use that in order to help them
70:58 answer their questions. and that will
70:59 help you refine the behavior of how this
71:01 agent acts. All right, so the next one
71:03 that we're doing is a customer support
71:05 workflow. And as always, you have to
71:07 figure out what is the trigger for my
71:08 workflow. In this case, it's going to be
71:10 triggered by a new email received. So
71:12 I'm going to click on add first step.
71:14 I'm going to type in Gmail. Grab that
71:16 node. And we have a trigger, which is on
71:18 message received right here. And we're
71:19 going to click on that. So what we have
71:21 to do now is obviously authorize
71:23 ourselves. So we're going to click on
71:25 create new credential right here. And
71:26 all we have to do here is use OOTH 2. So
71:28 all we have to do is click on sign in.
71:30 But before we can do that, we have to
71:31 come over to our Google Cloud once
71:32 again. And now we have to make sure we
71:34 enable the Gmail API. So we'll click on
71:36 Gmail API. And it'll be really simple.
71:38 We'll just have to click on enable. And
71:40 now we should be able to do that OOTH
71:41 connection and actually sign in. You'll
71:43 click on the account that you want to
71:44 access the Gmail. You'll give it access
71:46 to everything. Click continue. And then
71:49 we're going to be connected as you can
71:50 see. And then you'll want to name this
71:51 credential as always. Okay. So now we're
71:54 using our new credential. And what I'm
71:55 going to do is if I hit fetch test
71:57 event. So now we are seeing an email
71:59 that I just got in this inbox which in
72:01 this case was nencloud was granted
72:03 access to your Google account blah blah
72:05 blah. Um so that's what we just got.
72:08 Okay. So I just sent myself a different
72:09 email and I'm going to fetch that email
72:11 now from this inbox. And we can see that
72:13 the snippet says what is the privacy
72:15 policy? I'm concerned about my data and
72:17 passwords. And what we want to do is we
72:19 want to turn off simplify because what
72:21 this button is doing is it's going to
72:22 take the content of the email and
72:24 basically, you know, cut it off. So in
72:26 this case, it didn't matter, but if
72:28 you're getting long emails, it's going
72:29 to cut off some of the email. So if we
72:30 turn off simplify fetch test event, once
72:33 again, we're now going to get a lot more
72:34 information about this email, but we're
72:36 still going to be able to access the
72:37 actual content, which is right here. We
72:40 have the text, what is privacy policy?
72:41 I'm concerned about my data and
72:42 passwords. Thank you. And then you can
72:44 see we have other data too like what the
72:46 subject was, who the email is coming
72:48 from, what their name is, all this kind
72:49 of stuff. But the idea here is that we
72:52 are going to be creating a workflow
72:53 where if someone sends an email to this
72:56 inbox right here, we are going to
72:58 automatically look up the customer
72:59 support policy and respond back to them
73:00 so we don't have to. Okay. So the first
73:02 thing I'm actually going to do is pin
73:04 this data just so we can keep it here
73:05 for testing. Which basically means
73:07 whenever we rerun this, it's not going
73:08 to go look in our inbox. It's just going
73:10 to keep this email that we pulled in,
73:12 which helps us for testing, right? Okay,
73:14 cool. So, the next step here is we need
73:16 to have AI basically filter to see is
73:19 this email customer support related? If
73:21 yes, then we're going to have a response
73:23 written. If no, we're going to do
73:24 nothing because maybe the use case would
73:27 be okay, we're going to give it an
73:28 access to an inbox where we're only
73:30 getting customer support emails. But
73:32 sometimes maybe that's not the case. And
73:33 let's just say we wanted to create this
73:35 as sort of like an inbox manager where
73:36 we can route off to different logic
73:38 based on the type of email. So that's
73:40 what we're going to do here. So I'm
73:41 going to click on the plus after the
73:42 Gmail trigger and I'm going to search
73:44 for a text classifier node. And what
73:47 this does is it's going to use AI to
73:49 read the incoming email and then
73:50 determine what type of email it is. So
73:53 because we're using AI, the first thing
73:54 we have to do is connect a chat model.
73:56 We already have our open router
73:57 credential set up. So I'm going to
73:59 choose that. I'm going to choose the
74:00 credential and then I'm for this one,
74:01 let's just keep it with 40 mini. And now
74:03 this AI node actually has AI and I'm
74:07 going to click into the text classifier.
74:08 And the first thing we see is that
74:09 there's a text to classify. So all we
74:12 want to do here is we want to grab the
74:13 actual content of the email. So I'm
74:15 going to scroll down. I can see here's
74:17 the text, which is the email content.
74:18 We're going to drag that into this
74:20 field. And now every time a new email
74:23 comes through, the text classifier is
74:25 going to be able to read it because we
74:26 put in a variable which basically
74:28 represents the content of the email. So
74:30 now that it has that, it still doesn't
74:32 know what to classify it as or what its
74:34 options are. So we're going to click on
74:35 add category. The first category is
74:37 going to be customer support. And then
74:39 basically we need to give it a
74:40 description of what a customer support
74:42 email could look like. So I wanted to
74:44 keep this one simple. It's pretty vague,
74:46 but you could make this more detailed,
74:47 of course. And I just sent an email
74:49 that's related to helping out a
74:50 customer. They may be asking questions
74:52 about our policies or questions about
74:54 our products or services. And what we
74:56 can do is we can give it specific
74:57 examples of like here are some past
74:59 customer support emails and here's what
75:00 they've looked like. And that will make
75:02 this thing more accurate. But in this
75:03 case, that's all we're going to do. And
75:04 then I'm going to add one more category
75:06 that's just going to be other. And then
75:08 for now, I'm just going to say any email
75:10 that is not customer support related.
75:14 Okay, cool. So now when we click out of
75:16 here, we can see we have two different
75:18 branches coming off of this node, which
75:20 means when the text classifier decides,
75:21 it's either going to send it off this
75:23 branch or it's going to send it down
75:24 this branch. So let's quickly hit play.
75:27 It's going to be reading the email using
75:28 its brain. And now you can see it has
75:30 outputed in the customer support branch.
75:32 We can also verify by clicking into
75:34 here. And we can see customer support
75:35 branch has one item and other branch has
75:37 no items. And just to keep ourselves
75:39 organized right now, I'm going to click
75:41 on the other branch and I'm just going
75:42 to add an operation that says do nothing
75:44 just so we can see, you know, what would
75:46 happen if it went this way for now. But
75:48 now is where we want to configure the
75:49 logic of having an agent be able to read
75:52 the email, hit the vector database to
75:55 get relevant information and then help
75:56 us write an email. So I'm going to click
75:58 on the plus after the customer support
76:00 branch. I'm going to grab an AI agent.
76:02 So this is going to be very similar to
76:03 the way we set up our AI agent in the
76:05 previous workflow. So, it's kind of
76:06 building on top of each other. And this
76:08 time, if you remember in the previous
76:10 one, we were talking to it with a
76:12 connected chat trigger node. And as you
76:13 can see here, we don't have a connected
76:15 chat trigger node. So, the first thing
76:17 we want to do is change that. We want to
76:18 define below. And this is where you
76:20 would think, okay, what do we actually
76:22 want the agent to read? We want it to
76:23 read the email. So, I'm going to do the
76:25 exact same thing as before. I'm going to
76:26 go into the Gmail trigger node, scroll
76:29 all the way down until we can find the
76:30 actual email content, which is right
76:32 here, and just drag that right in.
76:34 That's all we're going to do. And then
76:35 we definitely want to add a system
76:36 message for this agent. We are going to
76:39 open up the system message and I'm just
76:40 going to click on expression so I can
76:42 expand this up full screen. And we're
76:44 going to write a system prompt. Again,
76:46 for the sake of the video, keeping this
76:47 prompt really concise, but if you want
76:49 to learn more about prompting, then
76:50 definitely check out my communities
76:52 linked down below as well as this video
76:53 up here and all the other tutorials on
76:56 my channel. But anyways, what we said
76:58 here is we gave it an overview and
76:59 instructions. The overview says you are
77:01 a customer support agent for TechHaven.
77:03 Your job is to respond to incoming
77:05 emails with relevant information using
77:06 your knowledgebased tool. And so when we
77:08 do hook up our Pine Cone vector
77:10 database, we're just going to make sure
77:11 to call it knowledgebase because that's
77:13 what the agent thinks it has access to.
77:15 And then for the instructions, I said
77:17 your output should be friendly and use
77:18 emojis and always sign off as Mr.
77:20 Helpful from TechHaven Solutions. And
77:23 then one more thing I forgot to do
77:24 actually is we want to tell it what to
77:26 actually output. So if we didn't tell
77:27 it, it would probably output like a
77:29 subject and a body. But what's going to
77:31 happen is we're going to reply to the
77:33 incoming email. We're not going to
77:34 create a new one. So we don't need a
77:36 subject. So I'm just going to say output
77:38 only the body content of the email. So
77:42 then we'll give it a try and see what
77:44 that prompt looks like. We may have to
77:45 come back and refine it, but for now
77:47 we're good. Um, and as you know, we have
77:49 to connect a chat model and then we have
77:50 to connect our pine cone. So first of
77:52 all, chat model, we're going to use open
77:54 router. And just to show you guys, we
77:56 can use a different type of model here.
77:58 Let's use something else. Okay. So,
78:00 we're going to go with Google Gemini 2.0
78:01 Flash. And then we need to add the Pine
78:03 Cone database. So, I'm going to click on
78:04 the plus under tool. I'm going to search
78:06 for Pine Cone Vector Store. Grab that.
78:09 And we have the operation is going to be
78:11 retrieving documents as a tool for an AI
78:13 agent. We're going to call this
78:16 knowledge capital B. And we're going to
78:20 once again just say call this tool to
78:22 access policy and FAQ information. We
78:27 need to set up the index as well as the
78:29 namespace. So sample and then we're
78:31 going to call the namespace, you know,
78:33 FAQ because that's what it's called in
78:35 our pine cone right here as you can see.
78:37 And then we just need to add our
78:38 embeddings model and we should be good
78:39 to go which is embedded OpenAI text
78:42 embedding three small. So we're going to
78:44 hit the play above the AI agent and it's
78:46 going to be reading the email. As you
78:47 can see once again the prompt user
78:49 message. It's reading the email. What is
78:50 the privacy policy? I'm concerned about
78:52 my data and my passwords. Thank you. So
78:55 we're going to hit the play above the
78:56 agent. We're going to watch it use its
78:57 brain. We're going to watch it call the
78:59 vector store. And we got an error. Okay.
79:02 So, I'm getting this error, right? And
79:04 it says provider returned error. And
79:06 it's weird because basically why it's
79:09 erroring is because of our our chat
79:10 model. And it's it's weird because it
79:12 goes green, right? So, anyways, what I
79:14 would do here is if you're experiencing
79:16 that error, it means there's something
79:17 wrong with your key. So, I would go
79:19 reset it. But for now, I'm just going to
79:20 show you the quick fix. I can connect to
79:22 a OpenAI chat model real quick. And I
79:25 can run this here and we should be good
79:26 to go. So now it's going to actually
79:29 write the email and output. Super weird
79:31 error, but I'm honestly glad I caught
79:33 that on camera to show you guys in case
79:34 you face that issue because it could be
79:36 frustrating. So we should be able to
79:37 look at the actual output, which is,
79:39 "Hey there, thank you for your concern
79:41 about privacy policy. At Tech Haven, we
79:43 take your data protection seriously." So
79:45 then it gives us a quick summary with
79:46 data collection, data protection,
79:48 cookies. If we clicked into here and
79:49 went to the privacy policy, we could see
79:51 that it is in fact correct. And then it
79:53 also was friendly and used emojis like
79:55 we told it to right here in the system
79:57 prompt. And finally, it signed off as
79:59 Mr. Helpful from Tech Haven Solutions,
80:00 also like we told it to. So, we're
80:02 almost done here. The last thing that we
80:04 want to do is we want to have it
80:05 actually reply to this person that
80:07 triggered the whole workflow. So, we're
80:09 going to click on the plus. We're going
80:10 to type in Gmail. Grab a Gmail node and
80:13 we're going to do reply to a message.
80:15 Once we open up this node, we already
80:17 know that we have it connected because
80:18 we did that earlier. We need to
80:20 configure the message ID, the message
80:22 type, and the message. And so all I'm
80:24 going to do is first of all, email type.
80:26 I'm going to do text. For the message
80:28 ID, I'm going to go all the way down to
80:29 the Gmail trigger. And we have an ID
80:31 right here. This is the ID we want to
80:33 put into the message ID so that it
80:35 responds in line on Gmail rather than
80:38 creating a new thread. And then for the
80:39 message, we're going to just drag in the
80:41 output from the agent that we just had
80:43 write the message. So, I'm going to grab
80:44 this output, put it right there. And now
80:46 you can see this is how it's going to
80:47 respond in
80:49 email. And the last thing I want to do
80:51 is I want to click on add option, append
80:54 nadn attribution, and then just check
80:55 that off. So then at the bottom of the
80:57 email, it doesn't say this was sent by
80:59 naden. So finally, we'll hit this test
81:02 step. We will see we get a success
81:04 message that the email was sent. And
81:06 I'll head over to the email to show you
81:07 guys. Okay, so here it is. This is the
81:09 one that we sent off to that inbox. And
81:11 then this is the one that we just got
81:12 back. As you can see, it's in the same
81:13 thread and it has basically the privacy
81:16 policy outlined for us. Cool. So, that's
81:18 workflow number two. Couple ways we
81:20 could make this even better. One thing
81:22 we could do is we could add a node right
81:24 here. And this would be another Gmail
81:25 one. And we could basically add a label
81:28 to this email. So, if I grab add label
81:31 to message, we would do the exact same
81:32 thing. We'd grab the message ID the same
81:34 way we grabbed it earlier. So, now it
81:36 has the message ID of the label to
81:38 actually create. And then we would just
81:40 basically be able to select the label we
81:41 want to give it. So in this case, we
81:43 could give it the customer support
81:44 label. We hit test step, we'll get
81:46 another success message. And then in our
81:48 inbox, if we refresh, we will see that
81:50 that just got labeled as customer
81:51 support. So you could add on more
81:53 functionality like that. And you could
81:54 also down here create more sections. So
81:57 we could have finance, you know, a logic
81:59 built out for finance emails. We could
82:01 have logic built out for all these other
82:02 types of emails and um plug them into
82:05 different knowledge bases as well. Okay.
82:06 So the third one we're going to do is a
82:08 LinkedIn content creator workflow. So,
82:10 what we're going to do here is click on
82:12 add first step, of course. And ideally,
82:14 you know, in production, what this
82:15 workflow would look like is a schedule
82:17 trigger, you know. So, what you could do
82:18 is basically say every day I want this
82:20 thing to run at 7:00 a.m. That way, I'm
82:22 always going to have a LinkedIn post
82:23 ready for me at, you know, 7:30. I'll
82:25 post it every single day. And if you
82:27 wanted it to actually be automatic,
82:28 you'd have to flick this workflow from
82:30 inactive to active. And, you know, now
82:32 it says, um, your schedule trigger will
82:34 now trigger executions on the schedule
82:36 you have defined. So now it would be
82:37 working, but for the sake of this video,
82:39 we're going to turn that off and we are
82:40 just going to be using a manual trigger
82:42 just so we can show how this works. Um,
82:44 but it's the same concept, right? It
82:46 would just start the workflow. So what
82:48 we're going to do from here is we're
82:49 going to connect a Google sheet. So I'm
82:51 going to grab a Google sheet node. I'm
82:53 going to click on get rows and sheet and
82:55 we have to create our credential once
82:57 again. So we're going to create new
82:58 credential. We're going to be able to do
83:00 ooth to sign in, but we're going to have
83:02 to go back to Google Cloud and we're
83:03 going to have to grab a sheet and make
83:05 sure that we have the Google Sheets API
83:07 enabled. So, we'll come in here, we'll
83:08 click enable, and now once this is good
83:10 to go, we'll be able to sign in using
83:12 OOTH 2. So, very similar to what we just
83:14 had to do for Gmail in that previous
83:16 workflow. But now, we can sign in. So,
83:18 once again, choosing my email, allowing
83:20 it to have access, and then we're
83:21 connected successfully, and then giving
83:23 this a good name. And now, what we can
83:25 do is choose the document and the sheet
83:26 that it's going to be pulling from. So,
83:28 I'm going to show you. I have one called
83:29 LinkedIn posts, and I only have one
83:31 sheet, but let's show you the sheet real
83:33 quick. So, LinkedIn posts, what we have
83:35 is a topic, a status, and a content. And
83:38 we're just basically going to be pulling
83:39 in one row where the status equals
83:42 to-do, and then we are going to um
83:44 create the content, upload it back in
83:46 right here, and then we're going to
83:48 change the status to created. So, then
83:50 this same row doesn't get pulled in
83:51 every day. So, how this is going to work
83:52 is that we're going to create a filter.
83:54 So the first filter is going to be
83:56 looking within the status column and it
83:58 has to equal to-do. And if we click on
84:01 test step, we should see that we're
84:02 going to get like all of these items
84:04 where there's a bunch of topics. But we
84:06 don't want that. We only want to get the
84:08 first row. So at the bottom here, add
84:10 option. I'm going to say return only
84:12 first matching row. Check that on. We'll
84:14 test this again. And now we're only
84:15 going to be getting that top row to
84:17 create content on. Cool. So we have our
84:19 first step here, which is just getting
84:21 the content from the Google sheet. Now,
84:23 what we're going to do is we need to do
84:24 some web search on this topic in order
84:27 to create that content. So, I'm going to
84:28 add a new node. This one's going to be
84:30 called an HTTP request. So, we're going
84:32 to be making a request to a specific
84:34 API. And in this case, we're going to be
84:35 using Tavly's API. So, go on over to
84:38 tavly.com and create a free account.
84:41 You're going to get a,000 searches for
84:42 free per month. Okay, here we are in my
84:44 account. I'm on the free researcher
84:46 plan, which gives me a thousand free
84:47 credits. And right here, I'm going to
84:49 add an API key. We're going to name it,
84:52 create a key, and we're going to copy
84:54 this value. And so, you'll start to get
84:55 to the point when you connect to
84:56 different services, you always need to
84:58 have some sort of like token or API key.
85:00 But anyways, we're going to grab this in
85:01 a sec. What we need to do now is go to
85:03 the documentation that we see right
85:04 here. We're going to click on API
85:06 reference. And now we have right here.
85:08 This is going to be the API that we need
85:10 to use in order to search the web. So,
85:12 I'm not going to really dive into like
85:14 everything about HTTP requests right
85:16 now. I'm just going to show you the
85:17 simple way that we can get this set up.
85:19 So first thing that we're going to do is
85:21 we obviously see that we're using an
85:22 endpoint called Tavali search and we can
85:24 see it's a post request which is
85:26 different than like a git request and we
85:28 have all these different things we need
85:29 to configure and it can be confusing. So
85:31 all we want to do is on the top right we
85:33 see this curl command. We're going to
85:35 click on the copy button. We're going to
85:37 go back into our NEN, hit import curl,
85:40 paste in the curl command, hit
85:43 import, and now the whole node magically
85:46 just basically filled in itself. So
85:48 that's really awesome. And now we can
85:50 sort of break down what's going on. So
85:51 for every HTTP request, you have to have
85:53 some sort of method. Typically, when
85:55 you're sending over data to a service,
85:58 which in this case, we're going to be
85:59 sending over data to Tavali. It's going
86:01 to search the web and then bring data
86:03 back to us. That's a post request
86:05 because we're sending over body data. If
86:08 we were just like kind of trying to hit
86:09 an and if we were just trying to access
86:12 like you know um bestbuy.com and we just
86:14 wanted to scrape the information that
86:16 could just be a simple git request
86:17 because we're not sending anything over
86:19 anyways then we're going to have some
86:20 sort of base URL and endpoint which is
86:22 right here. The base URL we're hitting
86:25 api.com/tavaly and then the endpoint
86:27 we're hitting is slash search. So back
86:30 in the documentation you can see right
86:31 here we have slash search but if we were
86:34 doing like an extract we would do slash
86:36 extract. So that's how you can kind of
86:37 see the difference with the endpoints.
86:39 And then we have a few more things to
86:40 configure. The first one of course is
86:42 our authorization. So in this case,
86:44 we're doing it through a header
86:45 parameter. As you can see right here,
86:46 the curl command set it up. Basically
86:48 all we have to do is replace this um
86:51 token with our API key from Tavi. So I'm
86:54 going to go back here, copy that key in
86:56 N. I'm going to get rid of token and
86:58 just make sure that you have a space
87:00 after the word bearer. And then you can
87:01 paste in your token. And now we are
87:03 connected to Tavi. But we need to
87:05 configure our request before we send it
87:07 off. So right here are the parameters
87:09 within our body request. And I'm not
87:10 going to dive too deep into it. You can
87:12 go to the documentation if you want to
87:13 understand like you know the main thing
87:15 really is the query which is what we're
87:17 searching for. But we have other things
87:18 like the topic. It can be general or
87:20 news. We have search depth. We have max
87:22 results. We have a time range. We have
87:24 all this kind of stuff. Right now I'm
87:26 just going to leave everything here as
87:28 default. We're only going to be getting
87:30 one result. And we're going to be doing
87:31 a general topic. We're going to be doing
87:33 basic search. But right now, if we hit
87:34 test step, we should see that this is
87:36 going to work. But it's going to be
87:37 searching for who is Leo Messi. And
87:39 here's sort of like the answer we get
87:40 back as well as a URL. So this is an
87:43 actual website we could go to about
87:45 Lionel Messi and then some content from
87:48 that website. Right? So we are going to
87:51 change this to an expression so that we
87:52 can put a variable in here rather than
87:54 just a static hard-coded who is Leo
87:56 Messi. We'll delete that query. And all
87:58 we're going to do is just pull in our
88:00 topic. So, I'm just going to simply pull
88:02 in the topic of AI image generation.
88:05 Obviously, it's a variable right here,
88:06 but this is the result. And then we're
88:08 going to test step. And this should
88:09 basically pull back an article about AI
88:11 image generation. And you know, so here
88:14 is a deep AI um link. We'll go to it.
88:18 And we can see this is an AI image
88:19 generator. So maybe this isn't exactly
88:21 what we're looking for. What we could do
88:23 is basically just say like, you know, we
88:24 could hardcode in search the web for.
88:28 And now it's going to be saying search
88:29 the web for AI image generation. We
88:31 could come in here and say yeah actually
88:32 you know let's get three results not
88:34 just one. And then now we could test
88:36 that step and we're going to be getting
88:37 a little bit different of a search
88:38 result. Um AI image generation uses text
88:42 descriptions to create unique visuals.
88:43 And then now you can see we got three
88:45 different URLs rather than just one.
88:47 Anyways, so that's our web search. And
88:49 now that we have a web search based on
88:51 our defined topic, we just need to write
88:53 that content. So I'm going to click on
88:55 the plus. I'm going to grab an AI agent.
88:58 And once again, we're not giving it the
89:00 connected chat trigger node to look at.
89:01 That's nowhere to be found. We're going
89:03 to feed in the research that was just
89:05 done by Tavi. So, I'm going to click on
89:07 expression to open this up. I'm going to
89:10 say article one with a colon and I'm
89:14 just going to drag in the content from
89:15 article one. I'm going to say article 2
89:18 with a colon and just drag in the
89:20 content from article 2. And then I'm
89:22 going to say article 3 colon and just
89:25 drag in the content from the third
89:27 article. So now it's looking at all
89:29 three article contents. And now we just
89:31 need to give it a system prompt on how
89:32 to write a LinkedIn post. So open this
89:34 up. Click on add option. Click on system
89:36 message. And now let's give it a prompt
89:38 about turning these three articles into
89:41 a LinkedIn post. Okay. So I'm heading
89:43 over to my custom GPT for prompt
89:45 architect. If you want to access this,
89:46 you can get it for free by joining my
89:48 free school community. Um you'll join
89:50 that. It's linked in the description and
89:51 then you can just search for prompt
89:53 architect and you should find the link.
89:54 Anyways, real quick, it's just asking
89:56 for some clarification questions. So,
89:58 anyways, I'm just shooting off a quick
89:59 reply and now it should basically be
90:01 generating our system prompt for us. So,
90:04 I'll check in when this is done. Okay,
90:05 so here is the system prompt. I am going
90:07 to just paste it in here and I'm just
90:09 going to, you know, disclaimer, this is
90:10 not perfect at all. Like, I don't even
90:12 want this tool section at all because we
90:14 don't have a tool hooked up to this
90:16 agent. Um, we're obviously just going to
90:17 give it a chat model real quick. So, in
90:19 this case, what I'm going to do is I'm
90:21 going to use Claude 3.5 Sonnet just
90:22 because I really like the way that it
90:23 writes content. So, I'm using Claude
90:25 through Open Router. And now, let's give
90:27 it a run and we'll just see what the
90:28 output looks like. Um, I'll just click
90:30 into here while it's running and we
90:31 should see that it's going to read those
90:32 articles and then we'll get some sort of
90:34 LinkedIn post back. Okay, so here it is.
90:37 The creative revolution is here and it's
90:38 AI powered. Gone are the days of hiring
90:41 expensive designers or struggling with
90:42 complex software. Today's entrepreneurs
90:44 can transform ideas into a stunning
90:46 visuals instantly using AI image
90:48 generators. So, as you can see, we have
90:50 a few emojis. We have some relevant
90:51 hashtags. And then at the end, it also
90:53 said this post, you know, it kind of
90:54 explains why it made this post. We could
90:56 easily get rid of that. If all we want
90:58 is the content, we would just have to
90:59 throw that in the system prompt. But now
91:01 that we have the post that we want, all
91:03 we have to do is send it back into our
91:05 Google sheet and update that it was
91:07 actually made. So, we're going to grab
91:09 another sheets node. We're going to do
91:10 update row and sheet. And this one's a
91:13 little different. It's not just um
91:14 grabbing stuff from a row. We're trying
91:16 to update stuff. So, we have to say what
91:18 document we want, what sheet we want.
91:20 But now, it's asking us what column do
91:21 we want to match on. So, basically, I'm
91:23 going to choose topic. And all we have
91:25 to do is go all the way back down to the
91:27 sheet. We're going to choose the topic
91:28 and drag it in right here. Which is
91:30 basically saying, okay, when this node
91:32 gets called, whenever the topic equals
91:35 AI image generation, which is a
91:37 variable, obviously, whatever whatever
91:38 topic triggered the workflow is what's
91:40 going to pop up here. We're going to
91:41 update that status. So, back in the
91:44 sheets, we can see that the status is
91:45 currently to-do, and we need to change
91:46 it to created in order for it to go
91:48 green. So, I'm just going to type in
91:50 created, and obviously, you have to
91:52 spell this correctly the same way you
91:53 have it in your Google Sheets. And then
91:55 for the content, all I'm going to do is
91:56 we're just going to drag in the output
91:58 of the AI agent. And as you can see,
92:00 it's going to be spitting out the
92:01 result. And now if I hit test step and
92:03 we go back into the sheet, we'll
92:04 basically watch this change. Now it's
92:06 created. And now we have the content of
92:08 our LinkedIn post as well with some
92:10 justification for why it created the
92:12 post like this. And so like I said, you
92:14 could basically have this be some sort
92:15 of, you know, LinkedIn content making
92:17 machine where every day it's going to
92:18 run at 7:00 a.m. It's going to give you
92:20 a post. And then what you could do also
92:22 is you can automate this part of it
92:24 where you're basically having it create
92:25 a few new rows every day if you give it
92:27 a certain sort of like general topic to
92:30 create topics on and then every day you
92:32 can just have more and more pumping out.
92:34 So that is going to do it for our third
92:35 and final workflow. Okay, so that's
92:37 going to do it for this video. I hope
92:39 that it was helpful. You know, obviously
92:40 we connected to a ton of different
92:42 credentials and a ton of different
92:43 services. We even made a HTTP request to
92:46 an API called Tavali. Now, if you found
92:48 this helpful and you liked this sort of
92:49 live step-by-step style and you're also
92:51 looking to accelerate your journey with
92:52 NAN and AI automations, I would
92:55 definitely recommend to check out my
92:56 paid community. The link for that is
92:57 down in the description. Okay, so
92:58 hopefully those three workflows taught
93:00 you a ton about connecting to different
93:02 services and setting up credentials.
93:04 Now, I'm actually going to throw in one
93:05 more bonus step-by-step build, which is
93:07 actually one that I shared in my paid
93:09 community a while back, and I wanted to
93:10 bring it to you guys now. So, definitely
93:12 finish out this course, and if you're
93:13 still looking for some more and you like
93:14 the way I teach, then feel free to check
93:15 out the paid community. The link for
93:16 that's down in the description. We've
93:18 got a course in there that's even more
93:19 comprehensive than what you're watching
93:20 right now on YouTube. We've also got a
93:22 great community of people that are using
93:23 Niten to build AI automations every
93:25 single day. So, I'd love to see you guys
93:27 in that community. But, let's move ahead
93:28 and build out this bonus workflow. Hey
93:31 guys. So, today I wanted to do a step by
93:34 step of an invoice workflow. And this is
93:37 because there's different ways to
93:39 approach stuff like this, right? There's
93:40 the conversation of OCR. There's a
93:42 conversation of maybe extracting text
93:44 from PDFs. Um, there's the conversation
93:46 of if you're always getting invoices in
93:49 the exact same format, you probably
93:50 don't need AI because you could use like
93:52 a code node to extract the different
93:54 parameters and then push that through.
93:56 So, that's kind of stuff we're going to
93:58 talk about today. And I I haven't showed
93:59 this one on YouTube. It's not like a
94:00 YouTube build, but it's not an agent.
94:02 It's an AI powered workflow. And I also
94:04 wanted to talk about like just the
94:05 foundational elements of connecting
94:07 pieces, thinking about the workflow. So,
94:09 what we're going to do first actually is
94:11 we're going to hop into Excalar real
94:13 quick.
94:14 and I'm going to create a new one. And
94:16 we're just going to real quickly
94:17 wireframe out what we're doing. So,
94:20 first thing we're going to draw out here
94:21 is the trigger. So, we'll make this one
94:24 yellow. We'll call this the
94:26 trigger. And what this is going to be is
94:30 invoice. Sorry, we're going to do new
94:34 invoice. And this is going to be
94:38 um Google Drive. So the Google Drive
94:41 node, it's going to be triggering the
94:43 workflow and it's going to be when a new
94:45 invoice gets dropped into
94:47 um the folder that we're watching. So
94:49 that's the trigger. From there, and like
94:52 I said, this is going to be a pretty
94:53 simple workflow. From there, what we're
94:55 going to do is basically it's going to
94:56 be a PDF. So the first thing to
94:59 understand is actually let me just put
95:02 Google Drive over here. So the first
95:04 thing to understand from here is
95:07 um you know what what do the invoices
95:11 look
95:12 like? These are the questions that we're
95:14 going to have. So the first one's what
95:15 do the invoices look like? Um because
95:19 that determines what happens next. So if
95:21 they are PDFs that happen every single
95:23 time and they're always in the same
95:25 format, then next we'd want to do okay
95:27 well we can just kind of extract the
95:29 text from this and then we can um use a
95:33 code node to extract the information we
95:34 need per each parameter. Now if it is a
95:39 scanned invoice where it's maybe not as
95:42 we're not maybe not as able to extract
95:44 text from it or like turn it into a text
95:46 doc, we'll probably have to do some OCR
95:48 element. Um, but if it's PDF that's
95:52 generated by a computer, so we can
95:54 extract the text, but they're not going
95:56 to come through the same every time,
95:57 which is what we have in this case. I
95:58 have two example invoices. So, we know
96:00 we're overall we're looking for like
96:02 business name, client name, invoice
96:04 number, invoice date, due date, payment
96:05 method, bank details, maybe stuff like
96:07 that, right? But both of these are
96:08 formatted very differently. They all
96:10 have the same information, but they're
96:12 formatted differently. So that's why we
96:15 can't that's why we want to use an AI
96:17 sort of information extractor node. Um
96:19 so that's one of the main questions. The
96:21 other ones we'd think about would be
96:22 like you
96:24 know where do they go? So once we get
96:27 them where do they go? Um you know the
96:30 frequency of them coming in and then
96:32 also
96:34 like really any other action. So bas
96:37 building off of where do they go? It's
96:38 also like what actions will we take? So,
96:42 does that mean um are we just going to
96:43 throw it in a CRM or are we just going
96:46 to throw it in a CRM or maybe a database
96:47 or are we also going to like send them
96:49 an automated follow-up based on you know
96:52 the email that we extract from it and
96:53 say, "Hey, we received your invoice.
96:54 Thanks." So, like what does that look
96:56 like? So, those are the questions we
96:57 were initially going to ask. Um and then
96:59 that helps us pretty much plan out the
97:01 next steps. So because we figured out
97:07 basically we figured out that we want to
97:11 extract the same like x amount of
97:15 information the x the same x
97:19 fields. So because we found out we want
97:21 to extract the same X
97:24 fields but the
97:27 formats may not be
97:29 [Music]
97:31 consistent. We will use an AI
97:35 information
97:38 extractor. Um that is just a long
97:40 sentence. So shorten this up a little
97:43 bit or sorry make it smaller a little
97:44 bit. Okay so we have
97:46 that.
97:48 Um the
97:51 invoice will be
97:56 um like
97:57 updated to our Google sheet which will
98:01 just be like a database of
98:05 invoice which I'll just call invoice
98:08 database and then a follow-up email can
98:14 sent or no not a follow-up email we'll
98:16 just say an
98:18 email, an internal email will be sent.
98:20 So, an email will be sent to the
98:22 internal billing team.
98:25 Okay, so this is what we've got, right?
98:29 We have our questions. We've kind of
98:30 answered the questions. So, now we know
98:31 what the rest of the flow is going to
98:32 look like. We already know this is not
98:34 going to be an agent. It's going to be a
98:35 workflow. So, what we're going to do is
98:37 we're going to add another node right
98:38 here, which is going to be, you know,
98:41 PDF comes in. And what we want to do is
98:43 we want to extract the text from that
98:47 PDF. Um let's make this text smaller. So
98:51 we're going to extract the text. And
98:52 we'll do this by using a
98:55 um extract text node. Okay, cool. Now
98:59 once we have the text extracted, what do
99:01 we need to
99:02 do? We need to
99:06 um just moving over these initial
99:09 questions. So we have the text
99:11 extracted. Extracted. What comes next?
99:13 What comes next is we need to
99:15 um like decide
99:18 on the fields to extract. And how do we
99:22 get this? We get this
99:24 from our invoice database. So let's
99:29 quickly set up the invoice database. I'm
99:31 going to do this
99:33 by opening up a Google
99:36 sheet which we are just going to call
99:41 oops invoice DB. So now we need to
99:45 figure out what we actually want to put
99:46 into our invoice DB. So first thing
99:48 we'll do is um you know we're pretending
99:51 that our business is called Green Grass.
99:53 So we don't need that. We don't need the
99:54 business information. We really just
99:55 need the client information. So invoice
99:58 number will be the first thing we want.
100:00 So, we're just setting up our database
100:01 here. So, invoice number. From there, we
100:04 want to get client name, client address,
100:06 client email, client phone.
100:08 So, client name, client email,
100:15 [Music]
100:16 oops, client name, client
100:19 email,
100:21 client address, and then we want
100:25 client phone. Okay, so we have those
100:28 five things. And let's see what else we
100:29 want. probably the amount. So, we'll
100:31 just do total amount
100:35 due, total amount,
100:41 um, and due
100:43 date. Invoice date and due date.
100:46 Okay. Invoice date and due date. Okay.
100:50 So, we have these, what are these?
100:52 Eight. Eight fields. And I'm just going
100:55 to change these colors so it looks
100:57 visually better for us. So, here are the
101:00 fields we have and this is what we want
101:01 to extract from every single invoice
101:02 that we are going to
101:04 receive. Cool. So, we know we have these
101:06 eight things. I'm just going to actually
101:09 No, we're
101:11 fine. So, we have our eight
101:14 fields to extract
101:17 um and then they're going to be pushed
101:18 to invoice DB and then we'll set up the
101:21 once we have these fields we can
101:23 basically um create our email. So this
101:25 is going to be an AI node that's going
101:29 to info extract. So it's going to
101:32 extract the eight fields that we have
101:35 here. So we're going to send the data
101:39 there and it's going to extract those
101:42 fields. Once we extract those
101:45 fields, we don't probably need to set
101:47 the data because because coming out of
101:49 this will basically be those eight
101:51 fields. So um you know every time what's
101:54 going to happen is actually sorry let
101:57 me add another node here so we can
101:59 connect these. So what's going to come
102:01 out of here is one item which will be
102:03 the one PDF and then what's coming out
102:05 of here will be eight items every time.
102:07 So that's what we've got. We could also
102:09 want to think about maybe if two
102:11 invoices get dropped in at the same
102:12 time. How do we want to handle that loop
102:14 or just push through? But we won't worry
102:16 about that yet. So we've got one item
102:17 coming in here. the node that's
102:19 extracting the info will push out the
102:20 eight items and the eight items only.
102:22 And then what we can do from there is
102:27 update invoice DB and then from there we
102:31 can also and this could be like out of
102:33 here we do two things or it could be
102:35 like a uh sequential if that makes
102:37 sense. So, well, what else we know we
102:39 need to do is we know that we also need
102:43 email billing team. And so, what I was
102:46 saying there
102:47 is we could either have it like this
102:49 where at the same time it branches off
102:51 and it does those two things. And it
102:52 really doesn't matter the order because
102:54 they're both going to happen either way.
102:55 So, for now, to keep the flow simple,
102:56 we'll just do this or we're going to
102:58 email the billing team.
103:01 Um, and what's going to happen is, you
103:05 know, essentially because this is
103:10 internal, because this is internal, we
103:12 already know like the billing email. So,
103:16 you know,
103:19 billing@acample.com. This is what we're
103:21 going to feed in because we already know
103:22 the billing email. We don't have to
103:23 extract this from anywhere. Um, so we
103:26 have all the info we need. We
103:30 will what else do we need to feed in
103:32 here? So some of these some of these
103:34 fields we'll have to filter in. So some
103:37 of the extracted
103:42 fields because like we want to say hey
103:45 you know we got this invoice on this
103:46 date um to this client and it's due on
103:50 this date. So, we'll have some of the
103:51 extracted fields. We'll have a billing
103:53 example and then potentially
103:56 like potentially like
103:59 previous or like an email template
104:02 potentially like that's that's something
104:03 we can think about or we can just prompt
104:06 an agent to send off the email.
104:11 So, yeah. Okay. Okay. So what we want to
104:14 do here is actually this. What we need
104:17 to do is the email has to be generated
104:20 somewhere. So before we feed into an
104:22 emailing team node and let me actually
104:25 change this. So we're going to have
104:26 green nodes be AI and then blue nodes
104:28 are going to be not AI. So we're going
104:30 to get another AI node right here which
104:32 is going to be craft
104:35 email. So we'll connect these pieces
104:37 once again.
104:40 Um, and so I hope this I hope you guys
104:43 can see like this is me trying to figure
104:44 out the workflow before we get into nit
104:46 because then we can just plug in these
104:47 pieces, right?
104:49 Um, and so I didn't even think about
104:51 this. I mean, obviously we would have
104:52 got in there and end and realized, okay,
104:54 well, we need an email to actually
104:56 configure these next fields, but that's
105:00 just how it works, right? So
105:03 anyways, this stuff is actually hooked
105:05 up to the wrong place. We need this to
105:06 be hooked up over here to the craft
105:07 email
105:09 tool. So, email template will also be
105:11 hooked up here. And then the billing
105:14 example will be hooked up. This is the
105:16 No, this will still go here because
105:18 that's actually the email team or the
105:19 email node.
105:21 So, email
105:23 node, send email node, which is an
105:27 action and we'll be feeding in this as
105:31 as the actual email. So the email that's
105:34 written by AI will be fed in. And I
105:37 think that ends the process, right? So
105:40 we'll just add a
105:41 quick Oops. We'll just add a quick
105:44 yellow note over here. And I always my
105:47 my colors always
105:49 change, but just trying to keep things
105:52 consistent. Like in here, we're just
105:53 saying, okay, the process is going to
105:54 end now. Okay, so this is our workflow,
105:56 right? New invoice PDF comes through. We
106:00 want to extract the text. We're using an
106:01 extract text node which is just going to
106:02 be a static extract from PDF PDF or
106:05 convert PDF to text file type of thing.
106:07 We'll get one item sent to an AI node to
106:09 extract the eight fields we need. The
106:11 eight items will be fed into the next
106:12 node which is going to update our Google
106:14 sheet. Um and I'll just also signify
106:16 here this is going to be a Google sheet
106:18 because it's important to understand the
106:19 integrations and like who's involved in
106:21 each process. So this is going to be
106:24 AI. This is going to be AI and that's
106:27 going to be an extract node. This is
106:29 going to be a Gmail node and then we
106:32 have the process end. Cool. So this is
106:33 our wireframe. Now we can get into naden
106:36 and start building out. We can see that
106:38 this is a very very sequential flow. We
106:40 don't need an agent. We just need two AI
106:42 nodes
106:43 here.
106:47 So let us get into niten and start
106:50 building this thing. So
106:51 um we know we know what's starting this
106:54 process which is which is a trigger. So,
106:55 I'm going to grab a Google Drive
106:57 trigger. We're going to do um on changes
106:59 to a specific file or no, no, specific
107:02 folder, sorry. Changes involving a
107:04 specific folder. We're going to choose
107:05 our folder, which is going to be the
107:08 projects folder, and we're going to be
107:09 watching for a file created.
107:12 So, we've got our ABC Tech Solutions.
107:15 I'm going to download this as a PDF real
107:17 quick. So, download as a PDF. I'm going
107:21 to go to my projects folder in the
107:23 drive, and I'm going to drag this guy in
107:24 here.
107:26 Um, there it is. Okay, so there's our
107:27 PDF. We'll come in here and we'll hit
107:30 fetch test event. So, we should be
107:32 getting our PDF. Okay,
107:34 nice. We will just make sure it's the
107:36 right one. So, we we should see a ABC
107:39 Tech Solutions Invoice. Cool. So, I'm
107:41 going to pin this data just so we have
107:42 it here. So, just for reference, pinning
107:44 data, all it does is just keeps it here.
107:46 So, if we were to refresh this this
107:48 page, we'll still have our pinned data,
107:50 which is that PDF to play with. But if
107:52 we would have not pinned it, then we
107:53 would have had to fetch test event once
107:54 again. So not a huge deal with something
107:56 like this, but if you're maybe doing web
107:58 hooks or API calls, you don't want to
108:00 have to do it every time. So you can pin
108:01 that data.
108:03 Um or like an output of an AI node if
108:06 you don't want to have to rerun the AI.
108:07 But anyway, so we have our our PDF. We
108:11 know next based on our wireframe. And
108:13 let me just call this um invoice
108:16 flow wireframe.
108:19 So we know next is we need to extract
108:21 text. So perfect. We'll get right into
108:23 NADN. We'll click on next and we will do
108:25 an extract from file. So let's see. We
108:28 want to extract from PDF. And
108:31 although what do we have
108:34 here? We don't have any binary. So we
108:39 were on the right track here, but we
108:40 forgot that in order to we get the we
108:42 get the PDF file ID, but we don't
108:44 actually have it. So what we need to do
108:46 here first is
108:50 basically download the file because we
108:54 need the binary to then feed that into
108:57 the extract text node.
109:00 So we need the
109:04 binary. So, sorry if that's like I mean
109:06 really small, but basically in order to
109:08 extract the text, we need to download
109:10 the file first to get the binary and
109:12 then we can um actually do that. So,
109:16 little little thing we missed in the
109:17 wireframe, but not a huge deal, right?
109:19 So, we're going to extend this one off.
109:20 We're going to do a Google Drive node
109:23 once again, and we're going to look at
109:25 download file. So, now we can say, okay,
109:27 we're downloading a file. Um, we can
109:30 choose from a list, but this has to be
109:32 dynamic because it's going to be based
109:33 on that new trigger every time. So, I'm
109:35 going to do by ID. And now on the lefth
109:37 hand side, we can look for the file ID.
109:39 So, I'm going to switch to schema real
109:41 quick. Um, so we can find the the ID of
109:44 the file. We're just going to have to go
109:46 through. So, we have a permissions ID
109:47 right here. I don't think that's the
109:48 right one. We have a spaces ID. I don't
109:51 think that's the right one either. We're
109:52 looking for an actual file ID.
109:56 So, let's see.
109:59 parents icon link, thumbnail link, and
110:04 sometimes you just have to like find it
110:06 and test things out, right?
110:09 So, I feel like I probably have just
110:12 skipped right over it. Otherwise, we'll
110:13 just try out some of these other
110:16 IDs. Maybe it is this one. Yeah, I think
110:19 Okay, sorry. I think it is this one
110:20 because we see the name is right here
110:22 and the ID is right here. So, we'll try
110:23 this. We're referencing that
110:25 dynamically. We also see in here we
110:27 could do a Google file conversion which
110:29 basically says um you know if it's docs
110:31 convert it to HTML if it's drawings
110:33 convert it to that. If it's this convert
110:35 it to that there's not a PDF one so
110:36 we'll leave this off and we'll hit test
110:39 step. So now we will see we got the
110:41 invoice we can click view and this is
110:43 exactly what we're looking at here with
110:44 the invoice. So this is the correct one.
110:46 Now since we have it in our binary data
110:48 over here we have binary. Now we can
110:50 extract it from the file. So um you know
110:54 on the left is the inputs on the right
110:56 is going to be our output. So we're
110:57 extracting from PDF. We're looking in
111:00 the input binary field called data which
111:01 is right here. So I'll hit test step and
111:05 now we have text. So here's the actual
111:07 text right um the invoice the
111:10 information we need and out of this is
111:11 what we're going to pass over to
111:12 extract. So let's go back to the
111:15 wireframe. We have our text extracted.
111:18 Now, what we want to do is extract um
111:20 the specific eight fields that we need.
111:22 So, hopping back into the workflow, we
111:25 know that this is going to be an AI
111:26 node. So, it's going to be an
111:27 information
111:28 extractor. We have to first of all
111:30 classify we we know that one item is
111:32 going in here and that's right here for
111:34 us in the table, which is the actual
111:35 text of the invoice. So, we can open
111:37 this up and we can see this is the text
111:38 of the
111:40 invoice. We want to do it from attribute
111:43 description. So, that's what it's
111:45 looking for. So, we can add our eight
111:46 attributes. So, we know there's going to
111:47 be eight of them, right? So, we can
111:48 create eight. But, let's just first of
111:50 all go into our database to see what we
111:52 want. So, the first one's invoice
111:53 number. So, I'm going to copy this over
111:55 here. Invoice number. And we just have
111:56 to describe what that is. So, I'm just
111:59 going to say the number of the
112:01 invoice. And this is required. We're
112:03 going to make them all required. So,
112:04 number of the invoice. Then we have the
112:06 client name. Paste that in
112:09 here. Um, these should all be pretty
112:11 self um explanatory. So the name of the
112:14 client we're going to make it
112:17 required client email. So this is going
112:20 to be a little bit repetitive
112:21 but the
112:24 email of the client and let me just
112:27 quickly copy this for the next
112:31 two client address. So there's client
112:34 address and we're going to
112:36 say the address of the client
112:43 required. And then what's the last one
112:45 here? Client phone. Paste that in there,
112:48 which is obviously going to be the phone
112:50 number of the client. And here we can
112:53 say, is this going to be a string or is
112:54 it going to be a number? I'm going to
112:56 leave it right now as a string just
112:58 because over here on the left you can
112:59 see the phone. We have parenthesis in
113:01 there. And maybe we want the format to
113:03 come over with the parenthesis and the
113:05 little hyphen. So let's leave it as a
113:07 string for now. We can always test and
113:08 we'll come back. But client phone, we're
113:10 going to leave that. We have total
113:13 amount. Same reason here. I'm going to
113:15 leave this one as a string because I
113:17 want to keep the dollar sign when we
113:18 send it over to sheets and we'll see how
113:19 it comes over. But the total amount of
113:23 invoice
113:26 required. What's coming next is invoice
113:28 date and due date. So, invoice
113:31 date and due date, we can say these are
113:34 going to be dates. So, we're changing
113:36 the var the data type here. They're both
113:37 required. And the date the invoice was
113:41 sent. And then we're going to
113:43 say the date the invoice is due. So,
113:47 we're going to make sure this works. If
113:48 we need to, we can get in here and make
113:49 these descriptions more descriptive. But
113:52 for now, we're good. We'll see if we
113:53 have any options. You're an expert
113:55 extraction algorithm. Only extracts
113:56 relevant information from the text. If
113:58 you do not know the value of the
113:59 attribute to extract, you may omit the
114:01 attributes value. So, we'll just leave
114:03 that as is. Um, and we'll hit test step.
114:06 It's going to be looking at this text.
114:08 And of course, we're using AI, so we
114:10 have to connect a chat model. So, this
114:12 will also alter the performance. Right
114:14 now, we're going to go with a Google
114:15 Gemini 20 flash. See if that's powerful
114:18 enough. I think it should be. And then,
114:20 we're going to hit play once again. So,
114:21 now it's going to be extracting
114:22 information using AI. And what's great
114:24 about this is that we already get
114:26 everything out here in its own item. So,
114:28 it's really easy to map this now into
114:30 our Google sheet. So, let's make sure
114:32 this is all correct. Um, invoice number.
114:35 That looks good. I'm going to open up
114:36 the actual one.
114:38 Yep. Client name ABC. Yep. Client email
114:41 finance at ABC
114:42 Tech.
114:44 Yep. Address and phone. We have address
114:48 and phone. Perfect. We have total amount
114:50 is 141 175.
114:53 14175. We have um March 8th and March
114:57 22nd. If we go back up here, March 8th,
114:59 March 22nd. Perfect. So, that one
115:00 extracted it. Well, and
115:04 um okay, so we have one item coming out,
115:07 but technically there's eight like
115:08 properties in there. So, anyways, let's
115:10 go back to our our uh wireframe. So,
115:12 after we extracted the eight items, what
115:14 do we do next? We're going to put them
115:16 into our Google Sheet um database. So,
115:20 what we know is we're going to grab a
115:21 Google Sheets. We're going to do an
115:23 append row because we're adding a row.
115:26 Um, we already have a credential
115:27 selected. So, hopefully we can choose
115:28 our invoice database. It's just going to
115:30 be the first sheet, sheet one. And now
115:32 what happens is we have to map the
115:34 columns. So, you can see these are
115:36 dragable. We can grab each one. If I go
115:38 to schema, it's a little more apparent.
115:40 So, we have these eight items. And it's
115:41 going to be really easy now that we use
115:42 an information extractor because we can
115:44 just map, you know, invoice number to
115:46 invoice number, client name, client
115:48 name, email, email. And it's referencing
115:51 these variables because every time after
115:54 we do our information extractor, they're
115:56 going to be coming out as JSON.output
115:58 and then invoice number. And then for
115:59 client name, JSON.output client name. So
116:02 we have these dynamic variables that
116:03 will happen every single time. And
116:05 obviously I'll show this when we do
116:06 another example, but we can keep mapping
116:08 everything in. And we also did it in
116:10 that order. So it's really really easy
116:12 to do. We're just dragging and dropping
116:14 and we are finished. Cool. So if I hit
116:19 test step here, this is going to give us
116:21 a message that says like here are the
116:23 fields basically. So there are the
116:24 fields. They're mapped correctly. Come
116:26 into the sheets. We now have
116:28 automatically gotten this updated in our
116:30 invoice database. And um that's that. So
116:34 let me just change some of these nodes.
116:36 So this is going to be update database.
116:39 Um this is information extractor extract
116:41 from file. I'm just going to say this is
116:44 download
116:46 binary. So now we know what's going on
116:48 in each step. And we'll go back to the
116:50 wireframe real quick. What happens after
116:51 we update the database? Now we need to
116:53 craft the email. And this is going to be
116:56 using AI. And what's going to go into
116:58 this is some of the extracted fields and
116:59 maybe an email template. What we're
117:01 going to do more realistically is just a
117:03 system prompt. So back into nitn let's
117:08 add a
117:10 um open AI message and model node. So
117:14 what we're going to do is we're going to
117:15 choose our model to talk to. In this
117:17 case we'll go 40 mini. It should be
117:19 powerful enough. And now we're going to
117:21 set up our system prompt and our user
117:23 prompt. So at this point if you don't
117:25 understand the
117:27 difference the system prompt is the
117:29 instructions. So we're telling this node
117:32 how to behave. So first I'm going to
117:33 change this node name to create email
117:36 because that's like obviously what's
117:38 going on keeping you organized. And now
117:39 how do we explain to this node what its
117:41 role is? So you are an email
117:45 expert. You will receive let me actually
117:48 just open this up. You will receive
117:54 um invoice information.
117:58 Your job is to notify the internal
118:02 billing
118:04 team that
118:07 um an invoice was
118:10 received. Receive/s sent. Okay. So,
118:13 honestly, I'm going to leave it at that
118:15 for now. It's really simple. If we
118:17 wanted to, we can get in here and change
118:18 the prompting as far as like here is the
118:21 format. Here is the way you should be
118:22 doing it. One thing I like to do is I
118:24 like to say, you know, this is like your
118:25 overview. And then if we need to get
118:27 more granular, we can give it different
118:28 sections like output or rules or
118:30 anything like that. I'm also going to
118:32 say you are an email expert
118:35 for green grass
118:38 corp named
118:42 [Music]
118:43 um named um Greeny. Okay, so we have
118:47 Greenie from Green Grass Corp. That's
118:49 our email expert that's going to email
118:51 the billing team every time this
118:53 workflow happens. So that's the
118:54 overview. Now in the user prompt, think
118:58 of this as like when you're talking to
118:59 chatbt. So obviously I had chatbt create
119:01 these
119:03 invoices chatgbt this when we say hello
119:06 that's a user message because this is an
119:08 interact like an an interaction and it's
119:10 going to change every time. But behind
119:12 the scenes in this chatbt openai has a
119:14 system prompt in here that's basically
119:16 like you're a helpful assistant. You
119:17 help you know users answer questions. So
119:19 this window right here that we type in
119:20 is our user message and behind the
119:24 scenes telling the node how to act is
119:26 our system prompt. Cool. So in here I
119:30 like to have dynamic information go into
119:32 the user message while I like to have
119:33 static information in the actual system
119:35 prompt. So except for maybe the except
119:37 the exception usually of
119:40 like giving it the current time and day
119:42 because that's an expression. So
119:44 anyways, let's change this to an
119:46 expression. Let's make this full screen.
119:48 We are going to be giving it the invoice
119:50 information that it needs to write the
119:53 email because that's what it that's what
119:55 it's expecting. In the system prompt, we
119:57 said you will receive invoice
119:59 information. So, first thing is going to
120:02 be invoice number. We are going to grab
120:05 invoice number and just drag it in.
120:08 We're going to grab client
120:09 name and just drag it in. So, it's going
120:12 to dynamically get these different
120:14 things every time, right?
120:17 So, let's say maybe it doesn't even we
120:19 don't need client email. Okay, maybe we
120:22 do. We want client
120:24 email. Um, so we'll give it that. But
120:27 the billing team right now doesn't need
120:28 the address or phone. Let's just say
120:30 that. But it does want we do want them
120:32 to know the total amount of that
120:36 invoice. And we definitely want them to
120:38 know the
120:40 invoice date and the invoice due date.
120:44 So we can we can now drag in these two
120:46 things. So this was us just being able
120:48 to customize what the AI node sees. Just
120:52 keep in mind if we don't drag anything
120:53 in here, even if it's all on the input,
120:56 the AI node doesn't see any of it. So
120:59 let's hit test step and we'll see the
121:00 type of email we get. We're going to
121:02 have to make some changes. I already
121:03 know because you know we have to
121:04 separate everything. But what it did is
121:07 it created a subject which is new
121:08 invoice received and then the invoice
121:10 number. Dear billing team, I hope this
121:12 message finds you well. We've received
121:13 an invoice that requires your attention
121:14 and then it lists out some information
121:16 and then it also signs off Greeny Green
121:18 Grass Corp.
121:20 So, first thing we want to do is um if
121:24 we go back to our
121:25 wireframe, what we have to send in, and
121:29 we didn't document this well enough
121:30 actually, but what goes into here is a
121:35 um you know, in order to send an email,
121:37 we need a two, we need a
121:40 subject, and we
121:42 need the email body.
121:46 So, that those are the three things we
121:48 need. the two is coming from here. So,
121:50 we know that. And the subject and email
121:52 are going to come from the um craft
121:55 email node. So, we have the the two and
121:58 then actually I'm going to move this up
121:59 here. So, now we can just see where
122:01 we're getting all of our pieces from.
122:03 So, the two is coming from internal
122:04 knowledge. This can be hardcoded, but
122:06 the subject and email are going to be
122:07 dynamic from the AI note. Cool. So what
122:11 we want to do now
122:13 is we're going to
122:17 say output and we're going to tell it
122:19 how to output information. So
122:22 output output the following
122:26 parameters separately and we're just
122:29 going to say subject and email. So now
122:33 it should be outputting two parameters
122:35 separately, but it's not going to
122:37 because even though it says here's the
122:39 subject and then it gives us a subject
122:40 and then it says here's the email and
122:42 gives us an email, they're still in one
122:43 field. Meaning if we hook up another
122:46 node which would be a Gmail send email
122:48 as we
122:49 know which is going to be where right
122:54 here. Okay, so now this is the next
122:56 node. Here's the fields we need. But as
122:58 you can see coming out of the create
123:00 email AI node, we have this whole
123:03 parameter called content which has the
123:06 subject and the email. And we need to
123:07 get these split up so that we can drag
123:08 one into the subject and one into the
123:10 two. Right? So first of all, I'm just
123:12 making these expressions just so we can
123:14 drag stuff in later. Um, and so that's
123:17 what we need to do. And our fix there is
123:20 we come into here and we just check this
123:22 switch that says output content is JSON,
123:25 which will then will rerun. And now
123:26 we'll get subject and
123:29 body. Subject and email in two different
123:31 fields right here. We can see which is
123:34 awesome because then we can open up our
123:36 send email node. We can grab our
123:38 subject. It's going to be dynamic. And
123:40 we can grab our email. It's going to be
123:41 dynamic. Perfect. We're going to change
123:43 this to text. And we're going to add an
123:45 option down here. And we're just going
123:47 to say append nadn attribution and turn
123:51 because we just don't want to see the
123:53 message at the bottom that says this was
123:55 sent by nadn. And if we go back to our
123:57 wireframe wherever that is over here, we
124:00 know that this is the email that's going
124:01 to be coming through or we're going to
124:03 be sending to every time because we're
124:04 sending internally. So we can put that
124:06 right in here, not as a variable. Every
124:09 time this is going to be sending to
124:10 billing@acample.com. So this really
124:12 could be fixed. It doesn't have to be an
124:13 expression. Cool.
124:16 So we will now hit test step and we can
124:20 see that we got this this email sent. So
124:21 let me open up a new
124:24 tab. Let me go
124:26 into whoa into our
124:29 Gmail. I will go to the sent items and
124:33 we will see we just got this billing
124:34 email. So obviously it was a fake email
124:35 but this is what it looks like. We've
124:37 received a new invoice from ABC Tech.
124:39 Please find the details below. We got
124:40 invoice number, client name, client
124:42 email, total amount, total invoice date,
124:45 due date. Please process these this
124:47 invoice
124:48 accordingly.
124:50 So that's perfect. Um, we could also, if
124:52 we wanted to, we could prompt it a
124:54 little bit differently to say, you know,
124:56 like this has been updated within the
124:59 database and, um, you can check it out
125:02 here. So, let's do that real quick. What
125:03 we're going to do is we're going to say
125:04 because we've already updated the
125:06 database, I'm going to come into our
125:07 Google sheet. I'm going to copy this
125:09 link and I'm going
125:12 to we're basically going to bake this
125:14 into the email.
125:17 So, I'm going to say we're going to give
125:19 it a section called
125:21 email. Inform the billing team of the
125:26 invoice.
125:28 let them know we have also updated this
125:34 in the invoice database and they can
125:38 view it here and we'll just give them
125:40 this link to that Google doc. So every
125:43 time they'll just be able to send that
125:44 over. So I'm going to hit test up. We
125:45 should see a new email over here which
125:47 is going to include that link I hope. So
125:50 there's the link. We'll run this email
125:53 tool again to send a new email. Hop back
125:55 into Google Gmail. We got a new one. And
125:59 now we can see we have this link. So you
126:01 can view it here. We've already updated
126:02 this in the invoice database. We click
126:05 on the link. And now we have our
126:06 database as well. So cool. Now let's say
126:09 at this point we're happy with our
126:11 prompting. We're happy with the email.
126:13 This is done. If we go back to the
126:14 wireframe, the email is the last node.
126:17 So um maybe just to make it look
126:19 consistent, we will just add over
126:20 something here that just says nothing.
126:23 And now we know that the process is done
126:25 because nothing to do. So this is
126:27 basically like this is what we
126:28 wireframed out. So we know that we're
126:31 happy with this process. We understand
126:32 what's going on. Um but now let's unpin
126:36 this data real quick and let's drop in
126:37 another invoice to make sure that even
126:39 though it's formatted differently. So
126:40 this XYZ formatted differently, but the
126:43 AI should still be able to extract all
126:45 the information that we need. So I'm
126:47 going to come in here and download this
126:48 one as a
126:50 PDF. We have it right there. I'm going
126:52 to drop it into our Google Drive. So, we
126:54 have XYZ Enterprises now. Come back into
126:58 the workflow and we'll hit test fetch
127:00 test event. Let's just make sure this is
127:02 the right
127:03 one. So, XYZ Enterprises. Nice. And I'm
127:06 just going to hit test workflow and
127:07 we'll watch it download, extract, get
127:10 the information, update the database,
127:12 create the email, send the email, and
127:13 then nothing else should happen after
127:15 that. So, boom, we're done. Let's click
127:19 into our email. Here we have our new
127:22 invoice received. So it updated
127:23 differently like the subjects dynamic
127:25 because it was from XYZ a different
127:27 invoice number. As you remember the ABC
127:29 one, it started with TH
127:31 AI and this one starts with INV. So
127:35 that's why the subject is different.
127:37 Dear billing team, we have received a
127:38 new invoice from XYZ Enterprises. Please
127:40 find the details below. There's the
127:42 number, the name, all this kind of
127:43 information. Um the total amount was
127:46 13856. Let's go make sure that's right.
127:49 Total amount
127:51 13856. Um March 8th March 22nd once
127:54 again. Is that
127:56 correct? March 8th March 22nd. Nice. And
128:01 finance XYZ XYZ. Perfect. Okay. The
128:04 invoice has been updated in the
128:05 database. You can view it here. So let's
128:06 click on that link. Nice. We got our
128:08 information populated into the
128:10 spreadsheet. As you can see, it all
128:12 looks correct to me as well. Our strings
128:14 are coming through nice and our dates
128:15 are coming through nice. So I'm going to
128:16 leave it as is. Now, keep in mind
128:18 because these are technically coming
128:19 through as strings, um, that's fine for
128:23 phone, but Google Sheets automatically
128:25 made these numbers, I believe. So, if we
128:27 wanted to, we could sum these up because
128:28 they're numbers. Perfect.
128:31 Okay, cool. So, that's how that works,
128:33 right? Um, that's the email. We
128:36 wireframed it out. We tested it with two
128:38 different types of invoices. They
128:40 weren't consistent formatting, which
128:42 means we couldn't probably have used a
128:43 code node, but the AI is able to read
128:45 this and extract it. As you can see
128:47 right here, we got the same eight items
128:49 extracted that we were looking for. So,
128:50 that's perfect. Um, cool. So, going to
128:54 call this one here. I
128:58 will yeah I will attach
129:00 the actual flow and I will attach the
129:05 just a picture of this wireframe I
129:06 suppose in this um post and by now you
129:10 guys have already seen that I'm sure but
129:12 yeah I hope this was helpful um the
129:15 whole process of like the way that I
129:16 approached and I know this was a 35minut
129:18 build so it's not like the same as like
129:20 building something more complex but as
129:22 far as like a general workflow you know
129:24 this is a pretty solid solid one to get
129:25 started with.
129:27 Um it it shows elements of using AI
129:30 within a simple workflow that's going to
129:32 be sequential and it shows like you know
129:34 the way we have to reference our
129:36 variables and how we have to drag things
129:38 in and um obviously the component of
129:41 like wireframing out in the beginning to
129:42 understand the full flow at least 80%
129:45 85% of the full flow before you get in
129:48 there. So cool. Hope you guys enjoy this
129:50 one and I will see you guys in the
129:52 community. Thanks. All right. All right,
129:54 I hope you guys enjoyed those
129:55 step-by-step builds. Hopefully, right
129:56 now, you're feeling like you're in a
129:57 really good spot with Naden and
129:59 everything starting to piece together.
130:01 This next video we're going to move into
130:02 is about APIs because in order to really
130:05 get more advanced with our workflows and
130:06 our AI agents, we have to understand the
130:08 most important thing, which is APIs.
130:11 They let our Nin workflows connect to
130:12 anything that you actually want to use.
130:13 So, it's really important to understand
130:14 how to set up. And when you understand
130:16 it, the possibilities are endless. And
130:18 it's really not even that difficult. So,
130:19 let's break it down. If you're building
130:21 AI agents, but you don't really
130:22 understand what an API is or how to use
130:24 them, don't worry. You're not alone. I
130:26 was in that exact same spot not too long
130:27 ago. I'm not a programmer. I don't know
130:29 how to code, but I've been teaching tens
130:31 of thousands of people how to build real
130:33 AI systems. And what changed the game
130:34 for me was when I understood how to use
130:36 APIs. So, in this video, I'm going to
130:38 break it down as simple as possible, no
130:40 technical jargon, and by the end, you'll
130:41 be confidently setting up API calls
130:43 within your own Agentic workflows. Let's
130:45 make this easy. So the purpose of this
130:47 video is to understand how to set up
130:48 your own requests so you can access any
130:50 API because that's where the power truly
130:52 comes in. And before we get into NDN and
130:54 we set up a couple live examples and I
130:56 show you guys my thought process when
130:58 I'm setting up these API calls. First I
131:00 thought it would just be important to
131:01 understand what an API really is. And
131:04 APIs are so so powerful because let's
131:05 say we're building agents within NADN.
131:08 Basically we can only do things within
131:10 NADN's environment unless we use an API
131:12 to access some sort of server. So
131:14 whether that's like a Gmail or a HubSpot
131:16 or Air Table, whatever we want to access
131:18 that's outside of Niden's own
131:20 environment, we have to use an API call
131:22 to do so. And so that's why at the end
131:24 of this video, when you completely
131:25 understand how to set up any API call
131:27 you need, it's going to be a complete
131:28 gamecher for your workflows and it's
131:31 also going to unlock pretty much
131:32 unlimited possibilities. All right, now
131:35 that we understand why APIs are
131:36 important, let's talk about what they
131:38 actually do. So API stands for
131:40 application programming interface. And
131:42 at the highest level in the most simple
131:43 terms, it's just a way for two systems
131:45 to talk to each other. So NAND and
131:47 whatever other system we want to use in
131:49 our automations. So keeping it limited
131:51 to us, it's our NAN AI agent and
131:53 whatever we want it to interact with.
131:55 Okay, so I said we're going to make this
131:56 as simple as possible. So let's do it.
131:58 What we have here is just a scenario
132:00 where we go to a restaurant. So this is
132:01 us right here. And what we do is we sit
132:03 down and we look at the menu and we look
132:05 at what food that the restaurant has to
132:06 offer. And then when we're ready to
132:08 order, we don't talk directly to the
132:10 kitchen or the chefs in the kitchen. We
132:12 talk to the waiter. So we'd basically
132:13 look at the menu. We'd understand what
132:14 we want. Then we would talk to the
132:16 waiter and say, "Hey, I want the chicken
132:18 parm." The waiter would then take our
132:19 order and deliver it to the kitchen. And
132:21 after the kitchen sees the request that
132:23 we made and they understand, okay, this
132:25 person wants chicken parm. I'm going to
132:26 grab the chicken parm, not the salmon.
132:28 And then we're basically going to feed
132:30 this back down the line through the
132:31 waiter all the way back to the person
132:33 who ordered it in the first place. And
132:34 so that's how you can see we use an HTTP
132:37 request to talk to the API endpoint and
132:40 receive the data that we want. And so
132:42 now a little bit more of a technical
132:43 example of how this works in NADN. Okay,
132:45 so here is our AI agent. And when it
132:47 wants to interact with the service, it
132:48 first has to look at that services API
132:50 documentation to see what is offered.
132:52 Once we understand that, we'll read that
132:54 and we'll be ready to make our request
132:56 and we will make that request using an
132:57 HTTP request. From there, that HTTP
133:00 request will take our information and
133:02 send it to the API endpoint. the
133:04 endpoint will look at what we ordered
133:05 and it will say, "Okay, this person
133:07 wants this data. So, I'm going to go
133:08 grab that. I'm going to send it back,
133:10 send it back to the HTTP request." And
133:12 then the HTTP request is actually what
133:14 delivers us back the data that we asked
133:16 and we know that it was available
133:17 because we had to look at the API
133:19 documentation first. So, I hope that
133:21 helps. I think that looking at it
133:22 visually makes a lot more sense,
133:24 especially when you hear, you know, HTTP
133:26 API endpoint, all this kind of stuff.
133:28 But really, it's just going to be this
133:29 simple. So now let me show an example of
133:31 what actually this looks like in Naden
133:33 and when you would use one and when you
133:34 wouldn't need to use one. So here we
133:36 have two examples where we're accessing
133:37 a service called open weather map which
133:39 basically just lets us grab the weather
133:41 data from anywhere in the world. And so
133:43 on the left what we're doing is we're
133:44 using open weather's native integration
133:46 within nadn. And so what I mean by
133:48 native integration is just that when we
133:49 go into nadn and we click on the plus
133:51 button to add an app and we want to see
133:53 like you know the different
133:54 integrations. It has air tableable it
133:56 has affinity it has airtop it has all
133:58 these AWS things. It has a ton of native
134:00 integrations and all that a native
134:02 integration is is an HTTP request but
134:05 it's just like wrapped up nicely in a UI
134:07 for us to basically fill in different
134:09 parameters. And so once you realize that
134:11 it really clears everything up because
134:13 the only time you actually need to use
134:14 an HTTP request is if the service you
134:16 want to use is not listed in this list
134:19 of all the native integrations. Anyways,
134:21 let me show you what I mean by that. So
134:23 like I said on the left we have Open
134:24 Weather Maps native integration. So
134:26 basically what we're doing here is we're
134:28 sending over, okay, I'm using open
134:29 weather map. I'm going to put in the
134:31 latitude and the longitude of the city
134:32 that I'm looking for. And as you can see
134:34 over here, what we get back is Chicago
134:36 as well as a bunch of information about
134:37 the current weather in Chicago. And so
134:39 if you were to fill this out, it's super
134:40 super intuitive, right? All you do is
134:42 put in the Latin long, you choose your
134:44 format as far as imperial or metric, and
134:46 then you get back data. And that's the
134:47 exact same thing we're doing over here
134:49 where we use an HTTP request to talk to
134:51 Open Weather's API endpoint. And so this
134:54 is just looks a little more scary and
134:55 intimidating because we have to set this
134:57 up ourselves. But if we zoom in, we can
134:59 see it's pretty simple. We're making a
135:00 git request to open weather maps URL
135:03 endpoint. And then we're putting over
135:05 the lat and the long, which is basically
135:07 the exact same from the one on the left.
135:09 And then, as you can see, we get the
135:11 same information back about Chicago, and
135:13 then some weather information about
135:14 Chicago. And so the purpose of that was
135:16 just to show you guys that these native
135:18 integrations, all we're doing is we're
135:20 accessing some sort of API endpoint. it
135:22 just looks simpler and easier and
135:24 there's a nice user interface for us
135:26 rather than setting everything up
135:27 manually. Okay, so hopefully that's
135:28 starting to make a little more sense.
135:30 Let's move down here to the way that I
135:32 think about setting up these HTTP
135:34 requests, which is we're basically just
135:36 setting up filters and making
135:37 selections. All we're doing is we're
135:39 saying, okay, I want to access server X.
135:42 When I access server X, I need to tell
135:44 it basically, what do I want from you?
135:45 So, it's the same way when you're going
135:47 to order some pizza. You have to first
135:48 think about which pizza shop do I want
135:50 to call? And then once you call them,
135:52 it's like, okay, I need to actually
135:53 order something. It has to be small,
135:54 medium, large. It has to be pepperoni or
135:56 cheese. You have to tell it what you
135:58 want and then they will send you the
135:59 data back that you asked for. So when
136:01 we're setting these up, we basically
136:03 have like five main things to look out
136:04 for. The first one you have to do every
136:06 time, which is a method. And the two
136:08 most common are going to be a get or a
136:09 post. Typically, a get is when you're
136:11 just going to access an endpoint and you
136:13 don't have to send over any information.
136:14 You're just going to get something back.
136:15 But a post is when you're going to send
136:17 over certain parameters and certain data
136:19 and say okay using this information send
136:21 me back what I'm asking for. The great
136:22 news is and I'll show you later when we
136:24 get into any end to actually do a live
136:26 example. It'll always tell you to say
136:28 you know is this a get or a post. Then
136:30 the next thing is the endpoint. You have
136:32 to tell it like which website or you
136:34 know which endpoint you want to actually
136:35 access which URL. From there we have
136:37 three different parameters to set up.
136:38 And also just realize that this one
136:40 should say body parameters. But this
136:42 used to be the most confusing part to
136:44 me, but it's really not too bad at all.
136:46 So, let's break it down. So, keep in
136:48 mind when we're looking at that menu,
136:49 that API documentation, it's always
136:51 going to basically tell us, okay, here
136:52 are your query parameters, here are your
136:54 header parameters, and here are your
136:55 body parameters. So, as long as you
136:56 understand how to read the
136:57 documentation, you'll be just fine. But
136:59 typically, the difference here is that
137:01 when you're setting up query parameters,
137:03 this is basically just saying a few
137:04 filters. So if you search pizza into
137:06 Google, it'll come
137:08 google.com/arch, which would be Google's
137:10 endpoint. And then we would have a
137:12 question mark and then Q equals and then
137:14 a bunch of different filters. So as you
137:15 can see right here, the first filter is
137:16 just Q equals pizza. And the Q is, you
137:19 know, it stands for query parameters.
137:21 And you don't even have to understand
137:22 that. That's just me showing you kind of
137:23 like a real example of how that works.
137:25 From there, we have to set up a header
137:26 parameter, which is pretty much always
137:28 going to exist. And I basically just
137:30 think of header parameters as, you know,
137:31 authorizing myself. So, usually when
137:34 you're doing some sort of API where you
137:35 have to pay, you have to get a unique
137:37 API key and then you'll send that key.
137:39 And if you don't put your key in, then
137:40 you're not going to be able to get the
137:41 data back. So, like if you're ordering a
137:43 pizza and you don't give them your
137:44 credit card information, they're not
137:46 going to send you a pizza. And usually
137:48 an API key is something you want to keep
137:49 secret because let's say, you know, you
137:51 put 10 bucks into some sort of API
137:52 that's going to create images for you.
137:54 If that key gets leaked, then anyone
137:56 could use that key and could go create
137:58 images for themselves for free, but
138:00 they'd be running down your credits. And
138:02 these can come in different forms, but I
138:03 just wanted to show you a really common
138:05 one is, you know, you'll have your key
138:06 value pairs where you'll put
138:08 authorization as the name and then in
138:10 the value you'll put bearer space your
138:12 API key or in the name you could just
138:15 put API_key and then in the value you'd
138:17 put your API key. But once again, the
138:19 API documentation will tell you how to
138:21 configure all this. And then finally,
138:23 the body parameters if you need to send
138:25 something over to get something back.
138:26 Let's say we're, you know, making an API
138:29 call to our CRM and we want to get back
138:31 information about John. We could send
138:33 over something like name equals John.
138:35 The server would then grab all records
138:37 that have name equal John and then it
138:39 would send them back to you. So those
138:40 are basically like the five main things
138:42 to look out for when you're reading
138:43 through API documentation and setting up
138:45 your HTTP request. But the beautiful
138:48 thing about living in 2025 is that we
138:51 now have the most beautiful thing in the
138:53 world, which is a curl command. And so
138:55 what a curl command is is it lets you
138:57 hit copy and then you basically can just
138:59 import that curl into nadn and it will
139:02 pretty much set up the request for you.
139:03 Then at that point it really is just
139:05 like putting in your own API key and
139:07 tweaking a few things if you want to. So
139:09 let's take a look at this curl statement
139:11 for a service called Tavi. As you can
139:13 see that's the endpoint is
139:14 api.tavi.com. All this basically does is
139:16 it lets you search the internet. So you
139:18 can see here this curl statement tells
139:19 us pretty much everything we need to
139:20 know to use this. So it's telling us
139:22 that it's going to be a post. It's
139:24 showing us the API endpoint that we're
139:25 going to be accessing. It shows us how
139:27 to set up our header. So that's going to
139:28 be authorization and then it's going to
139:30 be bearer space API token. It's
139:33 basically just telling us that we're
139:34 going to get this back in JSON format.
139:36 And then you can see all of these
139:37 different key value pairs right here in
139:39 the data section. And these are
139:40 basically going to be body parameters
139:41 where we can say, you know, query is who
139:43 is Leo Messi? So that's what we' be
139:45 searching the internet for. We have
139:46 topic equals general. We have search
139:48 depth equals basic. So hopefully you can
139:50 see all of these are just different
139:52 filters where we can choose okay do we
139:54 want you know do we want one max result
139:56 or do we want four or do we have a time
139:58 range or do we not. So this is really
140:00 just at the end of the day. It's
140:02 basically like ordering Door Dash
140:03 because what we would have up here is
140:05 you know like what actual restaurant do
140:07 we want to order food from? We would put
140:09 in our credit card information. We would
140:10 say do we want this to be delivered to
140:12 us? Do we want to pick it up? We would
140:13 basically say you know do you want a
140:15 cheeseburger? No pickles. No onions.
140:17 Like what are the different things that
140:18 you want to flip? Do you want a side? Do
140:19 you want fries? Or do you want salad?
140:21 Like, what do you want? And so once you
140:23 get into this mindset where all I have
140:25 to do is understand this documentation
140:27 and just tweak these little things to
140:28 get back what I want, it makes setting
140:31 up API calls so much easier. And if
140:33 another thing that kind of intimidates
140:35 you is the aspect of
140:37 JSON, it shouldn't because all it is is
140:39 a key value pair like we kind of talked
140:41 about. You know, this is JSON right here
140:43 and you're going to send your body
140:44 parameter over as JSON and you're also
140:46 going to get back JSON. So the more and
140:48 more you use it, you're going to
140:49 recognize like how easy it is to set up.
140:51 So anyways, I hope that that made sense
140:52 and broke it down pretty simply. Now
140:54 that we've seen like how it all works,
140:56 it's going to be really valuable to get
140:58 into niten. I'm going to open up a API
141:00 documentation and we're just going to
141:02 set up a few requests together and we'll
141:04 see how it works. Okay, so here's the
141:06 example. You know, I did open weather's
141:08 native integration and then also open
141:09 weather as an HTTP request. And you can
141:11 see it was like basically the exact same
141:13 thing. Um, so let's say that what we
141:15 want to do is we want to use Perplexity,
141:17 which if you guys don't know what
141:18 Perplexity is, it is basically, you
141:20 know, kind of similar to Chatbt, but it
141:22 has really good like internet search and
141:23 research. So let's say we wanted to use
141:25 this and hook it up to an AI agent, so
141:28 it can do web search for us. But as you
141:31 can see, if I type in Perplexity,
141:33 there's no native integration for
141:34 Perplexity. So that basically signals to
141:37 us, okay, we can only access Perplexity
141:39 using an HTTP request. And real quick
141:41 side note, if you're ever thinking to
141:42 yourself, hm, I wonder if I can have my
141:45 agent interact with blank. The answer is
141:47 yes, if there's API documentation. And
141:49 all you have to do typically to find out
141:51 if there's API documentation is just
141:53 come in here and be like, you know,
141:54 Gmail API documentation. And then we can
141:56 see Gmail API is a restful API, which
141:58 means it has an API and we can use it
142:00 within our automations. Anyways, getting
142:03 back to this example of setting up a
142:04 perplexity HTTP request. We have our
142:06 HTTP request right here and it's left
142:08 completely blank. So, as you can see, we
142:10 have our method, we have our endpoint,
142:12 we have query, header, and body
142:14 parameters, but nothing has been set up
142:16 yet. So, what we need to do is we would
142:17 head over to Perplexity, as you can see
142:19 right here. And at the bottom, there's
142:20 this little thing called API. So, I'm
142:22 going to click on that. And this opens
142:24 up this little page. And so, what I have
142:26 here is Perplexity's API. If I click on
142:28 developer docs, and then right here, I
142:30 have API reference, which is integrate
142:32 the API into your workflows, which is
142:34 exactly what we want to do. This page is
142:36 where people might get confused and it
142:38 looks a little bit intimidating, but
142:39 hopefully this breakdown will show you
142:40 how you can understand any API doc,
142:42 especially if there's a curl command.
142:44 So, all I'm going to do first of all is
142:45 I'm just going to right away hit copy
142:48 and make sure you know you're in curl.
142:49 If you're in Python, it's not the same.
142:51 So, click on curl. I copied this curl
142:53 command and I'm going to come back into
142:54 nit hit import curl and all I have to do
142:57 is paste. Click import and basically
142:59 what you're going to see is this HTTP
143:01 request is going to get basically
143:02 populated for us. So now we have the
143:04 method has been changed to post. We have
143:06 the correct URL which is the API
143:08 endpoint which basically is telling this
143:10 node, okay, we're going to use
143:11 Perplexity's API. You can see that the
143:13 curl had no query parameters. So that's
143:15 left off. It did turn on headers which
143:17 is basically just having us put our API
143:19 key in there. And then of course we have
143:21 the JSON body that we need to send over.
143:23 Okay. So at this point what I would do
143:24 is now that we have this set up, we know
143:26 we just need to put in a few things of
143:28 our own. So the first thing to tackle is
143:30 how do we actually authorize ourselves
143:32 into Perplexity? All right. All right.
143:33 So, I'm back in Perplexity. I'm going to
143:34 go to my account and click on settings.
143:36 And then all I'm going to do is
143:37 basically I need to find where I can get
143:39 my API key. So, on the lefth hand side,
143:41 if I go all the way down, I can see API
143:43 keys. So, I'll click on that. And all
143:45 this is going to do is this shows my API
143:47 key right here. So, I'll have to click
143:48 on this, hit copy, come back into NN,
143:51 and then all I'm going to do is I'm
143:52 going to just delete where this says
143:53 token, but I'm going to make sure to
143:55 leave a space after bearer and hit
143:57 paste. So now this basically authorizes
144:00 ourselves to use Perplexity's endpoint.
144:03 And now if we look down at the body
144:04 request, we can see we have this thing
144:06 set up for us already. So if I hit test
144:08 step, this is real quick going to make a
144:10 request over. It just hit Perplexity's
144:12 endpoint. And as you can see, it came
144:13 back with data. And what this did is it
144:15 basically searched Perplexity for how
144:17 many stars are there in our galaxy. And
144:20 that's where right here we can see the
144:21 Milky Way galaxy, which is our galaxy,
144:23 is estimated to contain between 100
144:25 billion and 400 billion stars, blah blah
144:27 blah. So we know basically okay if we
144:29 want to change how this endpoint works
144:30 what data we're going to get back this
144:32 right here is where we would change our
144:34 request and if we go back into the
144:35 documentation we can see what else we
144:37 have to set up. So the first thing to
144:39 notice is that there's a few things that
144:40 are required and then some things that
144:42 are not. So right here we have you know
144:43 authorization that's always required.
144:45 The model is always required like which
144:47 perplexity model are we going to use?
144:49 The messages are always required. So
144:51 this is basically a mix of a system
144:53 message and a user message. So here the
144:55 example is be precise and concise and
144:57 then the user message is how many stars
144:58 are there in the galaxy. So if I came
145:00 back here and I said you know um be
145:03 funny in your answer. So I'm basically
145:06 telling this model how to act and then
145:08 instead of how many stars are there in
145:09 the galaxy I'm just going to say how
145:11 long do cows live? And I'll make another
145:14 request off to perplexity. So you can
145:16 see what comes back is this longer
145:18 content. So it's not being precise and
145:20 concise and it says so you're wondering
145:22 how long cows live. Well, let's move
145:25 into the details. So, as you can see,
145:26 it's being funny. Okay, back into the
145:28 API documentation. We have a few other
145:30 things that we could configure, but
145:31 notice how these aren't required the
145:33 same way that these ones are. So, we
145:35 have max tokens. We could basically put
145:36 in an integer and say how many tokens do
145:39 you want to use at the maximum. We could
145:40 change the temperature, which is, you
145:42 know, like how random the response would
145:44 be. And this one says, you know, it has
145:45 to be between zero and two. And as we
145:47 keep scrolling down, you can see that
145:48 there's a ton of other little levers
145:50 that we can just tweak a little bit to
145:51 change the type of response that we get
145:53 back from Plexity. And so once you start
145:55 to read more and more API documentation,
145:57 you can understand how you're really in
145:58 control of what you get back from the
146:00 server. And also you can see like, you
146:02 know, sometimes you have to send over
146:03 booleans, which is basically just true
146:05 or false. Sometimes you can only send
146:07 over numbers. Sometimes you can only
146:09 send over strings. And sometimes it'll
146:10 tell you, you know, like what will the
146:12 this value default to? and also what are
146:14 the only accepted values that you
146:15 actually could fill out. So for example,
146:17 if we go back to this temperature
146:18 setting, we can see it has to be a
146:20 number and if you don't fill that out,
146:22 it's going to be 0.2. But we can also
146:24 see that if you do fill this out, it has
146:26 to be between zero or two. Otherwise,
146:28 it's not going to work. Okay, cool. So
146:30 that's basically how it works. We just
146:31 set up an HTTP request and we change the
146:34 system prompt and we change the user
146:35 prompt and that's how we can customize
146:36 this thing to work for us. And that's
146:39 really cool as a node because we can set
146:40 up, you know, a workflow to pass over
146:42 some sort of variable into this request.
146:44 So it searches the web for something
146:45 different every time. But now let's say
146:47 we want to give our agent access to this
146:48 tool and the agent will decide what am I
146:50 going to search the web for based on
146:52 what the human asks me. So it's pretty
146:54 much the exact same process. We'll click
146:55 on add a tool and we're going to add an
146:56 HTTP request tool only because Plexity
146:59 doesn't have a native integration. And
147:01 then once again you can see we have an
147:02 import curl button. So if I click on
147:04 this and I just import that same curl
147:05 that we did last time once again it
147:07 fills out this whole thing for us. So we
147:09 have post, we have the perplexity
147:11 endpoint, we have our authorization
147:13 bearer, but notice we have to put in our
147:14 token once again. And so a cool little
147:16 hack is let's say you know you're going
147:18 to use perplexity a lot. Rather than
147:20 having to go grab your API key every
147:22 single time, what we can do is we can
147:24 just send it over right here in the
147:25 authentication tab. So let me show you
147:27 what I mean by that. If I click into
147:29 authentication, I can click on generic
147:31 credential type. And then from here, I
147:33 can basically choose, okay, is this a
147:34 basic O, a bearer O, all this kind of
147:37 stuff. A lot of times it's just going to
147:38 be header off. So that's why we know
147:39 right here we can click on header off.
147:41 And as you can see, we know that because
147:42 we're sending this over as a header
147:44 parameter and we just did this earlier
147:45 and it worked. So as you can see, I have
147:48 header offs already set up. I probably
147:50 already have a Plexity one set up right
147:52 here. But I'm just going to go ahead and
147:53 create a new one with you guys to show
147:54 you how this works. So I just create a
147:56 new header off and all we have to do is
147:58 the exact same thing that we had down in
148:01 the request that we just sent over which
148:02 means in the name we're just going to
148:04 type in authorization with a capital A
148:06 and once again we can see in the API
148:08 docs this is how you do it. So
148:09 authorization and then we can see that
148:11 the value has to be capital B bearer
148:14 space API token. So I'm just going to
148:16 come into here bearer space API token
148:19 and then all I have to do is you know
148:21 first of all name this so we can can
148:22 save it and then if I hit save now every
148:26 single time we want to use perplexity's
148:28 endpoint we already have our credentials
148:30 saved. So that's great and then we can
148:31 turn off the headers down here because
148:33 we don't need to send it over twice. So
148:35 now all we have to do is change this
148:37 body request a little bit just to make
148:39 it more dynamic. So in order to make it
148:41 dynamic the first thing we have to do is
148:42 change this to an expression. Now, we
148:44 can see that we can basically add a
148:46 variable in here. And what we can do is
148:48 we can add a variable that basically
148:49 just tells the AI model, the AI agent,
148:52 here is where you're going to send over
148:54 your internet search query. And so we
148:57 already know that all that that is is
148:59 the user content right here. So if I
149:01 delete this and basically if I do two
149:04 curly braces and then within the curly
149:06 braces I do a dollar sign and I type in
149:08 from, I can grab a from AI function. And
149:10 this from AI function just indicates to
149:12 the AI agent I need to choose something
149:15 to send over here. And you guys will see
149:17 an example and it will make more sense.
149:19 I also did a full video breaking this
149:20 down. So if you want to see that, I'll
149:21 tag it right up here. Anyways, as you
149:23 can see, all we have to really do is
149:25 enter in a key. So I'm just going to do,
149:26 you know, two quotes and within the
149:28 quote, I'm going to put in search term.
149:30 And so now the agent will be reading
149:32 this and say, okay, whenever the user
149:34 interacts with me and I know I need to
149:35 search the internet, I'm just going to
149:37 fill this whole thing in with the search
149:39 term. So, now that that's set up, I'm
149:41 just going to change this request to um
149:43 actually I'm just going to call it web
149:44 search to make that super intuitive for
149:46 the AI agent. And now what we're going
149:48 to do is we are going to talk to the
149:49 agent and see if it can actually search
149:51 the web. Okay, so I'm asking the AI
149:53 agent to search the web for the best
149:55 movies. It's going to think about it.
149:57 It's going to use this tool right here
149:58 and then we'll basically get to go in
150:00 there and we can see what it filled in
150:02 in that search term placeholder that we
150:03 gave it. So, first of all, the answer it
150:05 gave us was IMDb, top 250, um, Rotten
150:09 Tomatoes, all this kind of stuff, right?
150:11 So, that's movie information that we
150:12 just got from Perplexity. And what I can
150:15 do is click into the tool and we can see
150:16 in the top left it filled out search
150:18 term with best movies. And we can even
150:20 see that in action. If we come down to
150:22 the body request that it sent over and
150:23 we expand this, we can see on the right
150:25 hand side in the result panel, this is
150:27 the JSON body that it sent over to
150:30 Perplexity and it filled it in with best
150:32 movies. And then of course what we got
150:34 back was our content from Perplexity,
150:36 which is, you know, here are some of the
150:37 best movies across major platforms. All
150:40 right, then real quick before we wrap up
150:41 here, I just wanted to talk about some
150:43 common responses that you can get from
150:45 your HTTP requests. So the rule of thumb
150:47 to follow is if you get data back and
150:49 you get a 200, you're good. Sometimes
150:52 you'll get a response back, but you
150:53 won't explicitly see a 200 message. But
150:55 if you're getting the data back, then
150:57 you're good to go. And a quick example
150:58 of this is down here we have that HTTP
151:00 request which we went over earlier in
151:02 this video where we went to open weather
151:04 maps API and you can see down here we
151:06 got code 200 and there's data coming
151:08 back and 200 is good that's a success
151:11 code. Now if you get a request in the
151:13 400s that means that you probably set up
151:15 the request wrong. So 400 bad request
151:18 that could mean that your JSON's
151:19 invalid. It could just mean that you
151:20 have like an extra quotation mark or you
151:22 have you know an extra comma something
151:24 as silly as that. So let me show a quick
151:26 example of that. We're going to test
151:27 this workflow and what I'm doing is I'm
151:28 trying to send over a query to Tavi. And
151:31 you can see what we get is an error that
151:32 says JSON parameter needs to be valid
151:34 JSON. And this would be a 400 error. And
151:36 the issue here is if we go into the JSON
151:38 body that we're trying to send over, you
151:40 can see in the result panel, we're
151:42 trying to send over a query that has
151:44 basically two sets of quotation marks.
151:46 If you can see that. But here's the
151:47 great news about JSON. It is so
151:49 universally used and it's been around
151:51 for so long that we could basically just
151:52 copy the result over to chatbt. Paste it
151:55 in here and say, I'm getting an error
151:57 message that says JSON parameter needs
151:59 to be valid JSON. What's wrong with my
152:01 JSON? And as you can see, it says the
152:02 issue with your JSON is the use of
152:04 double quotes around the string value in
152:06 this line. So now we'd be able to go fix
152:07 that. And if we go back into the
152:09 workflow, we take away these double
152:11 quotes right here. Test the step again.
152:12 Now you can see it's spinning and it's
152:14 going to work. and we should get back
152:16 some information about pineapples on
152:17 pizza. Another common error you could
152:19 run into is a 401, meaning unauthorized.
152:21 This typically just means that your API
152:23 key is wrong. You could also get a 403,
152:25 which is forbidden. That just means that
152:26 maybe your account doesn't have access
152:28 to this data that you're requesting or
152:30 something like that. And then another
152:31 one you could get is a 404, which
152:32 sometimes you'll get that if you type in
152:34 a URL that doesn't exist. It just means
152:36 this doesn't exist. We can't find it.
152:38 And a lot of times when you're looking
152:39 at the actual API documentation that you
152:41 want to set up a request to. So here's
152:43 an example with Tavi, it'll show you
152:45 what typical responses could look like.
152:47 So here's one where you know we're using
152:48 Tavi to search for who is Leo Messi.
152:50 This was an example we looked at
152:51 earlier. And with a 200 response, we are
152:54 getting back like a query, an answer
152:56 results, stuff like that. We could also
152:58 see we could get a 400 which would be
153:00 for bad request, you know, invalid
153:02 topic. We could have a 401 which means
153:04 invalid API key. We could get all these
153:06 other ones like 429, 432, but in general
153:09 400 is bad. And then even worse is a
153:12 500. And this just basically means
153:14 something's wrong with the server. Maybe
153:15 it doesn't exist anymore or there's a
153:17 bug on the server side. But the good
153:19 news about a 500 is it's not your fault.
153:21 You didn't set up the request wrong. It
153:22 just means something's wrong with the
153:24 server. And it's really important to
153:26 know that because if you think you did
153:27 something wrong, but it's really not
153:28 your fault at all, you may be banging
153:30 your head against the wall for hours. So
153:32 anyways, what I wanted to highlight here
153:33 is there's never just like a
153:35 one-sizefits-all. I know how to set up
153:37 this one API call so I can just set up
153:39 every single other API call the exact
153:40 same way. The key is to really
153:42 understand how do you read the API
153:44 documentation? How do you set up your
153:45 body parameters and your different
153:47 header parameters? And then if you start
153:48 to run into issues, the key is
153:50 understanding and actually reading the
153:52 error message that you're getting back
153:53 and adjusting from there. All right, so
153:55 that's going to do it for this video.
153:56 Hopefully this has left you feeling a
153:58 lot more comfortable with diving into
154:00 API documentation, walking through it
154:02 just step by step using those curl
154:04 commands and really just understanding
154:06 all I'm doing is I'm setting up filters
154:07 and levers here. I don't have to get
154:09 super confused. It's really not that
154:10 technical. I'm pretty much in complete
154:12 control over what my API is going to
154:15 send me back. The same way I'm in
154:16 complete control when I'm, you know,
154:18 ordering something on Door Dash or
154:19 ordering something on Amazon, whatever
154:21 it is. Hopefully by now the concept of
154:23 APIs and HTTP requests makes a lot more
154:25 sense. But really, just to drive it
154:26 home, what we're going to do is hop into
154:28 some actual setups in NADN of connecting
154:30 to some different popular APIs and walk
154:33 through a few more step by steps just to
154:35 really make sure that we understand the
154:37 differences that can come with different
154:38 API documentation and how you read it
154:40 and how you set up stuff like your
154:41 credentials and the body requests. So,
154:44 let's move into this next part, which I
154:45 think is going to be super valuable to
154:46 see different API calls in action. Okay,
154:49 so in nodn when we're working with a
154:50 large language model, whether that's an
154:52 AI agent or just like an AI node, what
154:54 happens is we can only access the
154:57 information that is in the large
154:59 language models training data. And a lot
155:00 of times that's not going to be super
155:02 up-to-date and real time. So what we
155:04 want to do is access different APIs that
155:06 let us search the web or do real-time
155:08 search. And what we saw earlier in that
155:11 third step-by-step workflow was we used
155:13 a tool called Tavi and we accessed it
155:15 through an HTTP request node which as
155:17 you guys know looks like this. And we
155:19 were able to use this to communicate
155:21 with Tavali's API server. So if we ever
155:24 want to access real-time information or
155:25 do research on certain search terms, we
155:28 have to use some sort of API to do that.
155:30 So, like I said, we talked about Tavi,
155:32 but in this video, I'm going to help you
155:34 guys set up Perplexity, which if you
155:36 don't know what it is, it's kind of like
155:38 Chat GBT, but it's really, really good
155:39 for web search and in-depth research.
155:42 And it has that same sort of like, you
155:43 know, chat interface as chatbt, but what
155:46 you also have is access to the API. So,
155:48 if I click on API, we can see this
155:50 little screen, but what we want to go to
155:51 is the developer docs. And in the
155:54 developer docs, what we're looking for
155:55 is the API reference. We can also click
155:57 on the quick start guide right here
155:58 which just shows you how you can set up
156:00 your API key and get all that kind of
156:01 stuff. So that's exactly what we're
156:03 going to do is set up an API call to
156:05 Perplexity. So I'm going to click on API
156:08 reference and what we see here is the
156:09 endpoint to access Perplexi's API. And
156:12 so what I'm going to do is just grab
156:13 this curl command from that right hand
156:15 side, go back into our NEN and I'm just
156:18 going to import the curl right into
156:19 here. And then all we have to do from
156:20 there is basically configure what we
156:22 want to research and put in our own API
156:24 key. So there we go. We have our node
156:27 pretty much configured. And now the
156:28 first thing we see we need to set up is
156:30 our authorization API key. And what we
156:32 could do is set this up in here as a
156:34 generic credential type and save it. But
156:36 right now we're just going to keep
156:37 things as simple as possible where we
156:38 imported the curl. And now I'm just
156:40 going to show you where to plug in
156:41 little things. So we have to go back
156:43 over to Perplexity and we need to go get
156:45 an API key. So I'm going to come over
156:46 here to the left and I'm going to click
156:47 on my settings. And hopefully in here
156:49 we're able to find where our API key
156:51 lives. Now we can see in the bottom left
156:53 over here we have API keys. And what I'm
156:55 going to do is come in here and just
156:56 create a new secret key. And we just got
156:58 a new one generated. So I'm just going
156:59 to click on this button, click on copy,
157:01 and all we have to do is replace the
157:03 word right here that says token. So I'm
157:05 just going to delete that. I'm going to
157:07 make sure to leave a space after the
157:08 word bearer. And I'm going to paste in
157:10 my Perplexity API key. So now we should
157:12 be connected. And now what we need to do
157:14 is we need to set up the actual body
157:16 request. So if I go back into the
157:17 documentation, we can see this is
157:19 basically what we're sending over. So
157:21 that first thing is a model, which is
157:23 the name of the model that will complete
157:24 your prompt. And if we wanted to look at
157:26 different models, we could click into
157:27 here and look at other supported models
157:29 from Perplexity. So it took us to the
157:31 screen. We click on models, and we can
157:32 see we have Sonar Pro or Sonar. We have
157:35 Sonar Deep Research. We have some
157:37 reasoning models as well. But just to
157:38 keep things simple, I'm going to stick
157:40 with the default model right now, which
157:41 is just sonar. Then we have an object
157:43 that we're sending over, which is
157:45 messages. And within the messages
157:47 object, we have a few things. So first
157:49 of all we're sending over content which
157:51 is the contents of the message in turn
157:52 of conversation. It can be in a string
157:54 or an array of parts. And then we have a
157:57 role which is going to be the role of
157:58 the speaker in the conversation. And we
158:00 have available options system user or
158:03 assistant. So what you can see in our
158:05 request is that we're sending over a
158:06 system message as well as a user
158:08 message. And the system message is
158:10 basically the instructions for how this
158:11 AI model on perplexity should act. And
158:13 then the user message is our dynamic
158:15 search query that is going to change
158:17 every time. And if we go back into the
158:19 documentation, we can see that there are
158:20 a few other things we could add, but we
158:22 don't have to. We could tell Perplexity
158:24 what is the max tokens we want to use,
158:26 what is the temperature we want to use.
158:27 We could have it only search for things
158:30 in the past week or day. So, this
158:32 documentation is basically going to be
158:34 all the filters and settings that you
158:36 have access to in order to customize the
158:38 type of results that you want to get
158:39 back. But, like I said, keeping this one
158:41 really simple. We just want to search
158:43 the web. All I'm going to do is keep it
158:45 as is. And if I disconnect this real
158:46 quick and we come in and test step, it's
158:48 basically going to be searching
158:49 perplexity for how many stars are there
158:51 in our galaxy. And then the AI model of
158:54 sonar is the one that's going to grab
158:56 all of these five sources and it's going
158:58 to answer us. And right here it says the
159:00 Milky Way galaxy, which is our home
159:02 galaxy, is estimated to contain between
159:04 100 billion and 400 billion stars. This
159:06 range is due to the difficulty blah blah
159:08 blah blah blah. So that's basically how
159:09 it was able to answer us because it used
159:11 an AI model called sonar. So now if we
159:14 wanted to make this search a little bit
159:15 more dynamic, we could basically plug
159:17 this in and you can see in here what I'm
159:19 doing is I'm just setting a search term.
159:20 So let's test this step. What happens is
159:23 the output of this node is a research
159:25 term. Then we could reference that
159:27 variable of research term right in here
159:29 in our actual body request to
159:31 perplexity. So I would delete this fixed
159:33 message which is how many stars are
159:35 there in our galaxy. And all I would do
159:36 is I'd drag in research term from the
159:38 left, put it in between the two quotes,
159:40 and now it's coming over dynamically as
159:43 anthropic latest developments. And all
159:45 I'd have to do now is hit test step. And
159:47 we will get an answer from Perplexity
159:49 about Anthropic's recent developments.
159:51 There we go. It just came back. We can
159:52 see there's five different sources right
159:54 here. It went to Anthropic, it went to
159:55 YouTube, it went to TechCrunch. And what
159:57 we get is that today, May 22nd, so real
160:00 time information, Claude Opus 4 was
160:03 released. And that literally came out
160:05 like 2 or 3 hours ago. So that's how we
160:07 know this is searching the web in real
160:09 time. And then all we'd have to do is
160:11 have, you know, maybe an AI model is
160:12 changing our search term or maybe we're
160:14 pulling from a Google sheet with a bunch
160:15 of different topics we need to research.
160:17 But whatever it is, as long as we are
160:18 passing over that variable, this actual
160:21 search result from Perplexity is going
160:22 to change every single time. And that's
160:25 the whole point of variables, right?
160:26 They they vary. They're dynamic. So, I
160:28 know that one was quick, but Perplexity
160:30 is a super super versatile tool and
160:32 probably an API that you're going to be
160:33 calling a ton of times. So, just wanted
160:35 to make sure I threw that in
160:38 there. So, Firecall is going to allow us
160:40 to turn any website into LLM ready data
160:43 in a matter of seconds. And as you can
160:45 see right here, it's also open source.
160:46 So, once you get over to Firecol, click
160:48 on this button and you'll be able to get
160:49 500 free credits to play around with. As
160:51 you can see, there's four different
160:52 things we can do with Firecrawl. We can
160:54 scrape, we can crawl, we can map or we
160:57 can do this new extract which basically
160:59 means we can give firecraw a URL and
161:01 also a prompt like can you please
161:02 extract the company name and the
161:04 services they offer and an icebreaker
161:06 out of this URL. So there's some really
161:08 cool use cases that we can do with
161:10 firecrawl. So in this video we're going
161:11 to be mainly looking at extract, but I'm
161:13 also going to show you the difference
161:14 between scrape and extract. And we're
161:16 going to get into end and connect up so
161:17 you can see how this works. But the
161:18 playground is going to be a really good
161:20 place to understand the difference
161:21 between these different endpoints. All
161:23 right, so for the sake of this video,
161:25 this is the website we're going to be
161:26 looking at. It's called quotes to
161:27 scrape. And as you can see, it's got
161:29 like 10 on this first page and it also
161:30 has different pages of different
161:32 categories of quotes. And as you can
161:33 see, if we click into them, there are
161:35 different quotes. So what I'm going to
161:36 do is go back to the main screen and I'm
161:37 going to copy the URL of this website
161:40 and we're going to go into niten. We're
161:41 going to open up a new node, which is
161:43 going to be an HTTP request. And this is
161:45 just to show you what a standard get
161:47 request to a static website looks like.
161:49 So we're going to paste in the URL, hit
161:51 test step, and on the right hand side,
161:53 we're going to get all the HTML back
161:55 from the quotes to scrape website. Like
161:57 I said, what we're looking at here is a
161:58 nasty chunk of HTML. It's pretty hard
162:00 for us to read, but basically what's
162:02 going on here is this is the code that
162:04 goes to the website in order to have it
162:06 be styled and different fonts and
162:07 different colors. So right here, what
162:09 we're looking at is the entire first
162:10 page of this website. So if we were to
162:12 search for Harry, if I copy this, we go
162:14 back into edit and we control F this.
162:17 You can see there is the exact quote
162:18 that has the word Harry. So everything
162:20 from the website's in here, it's just
162:22 wrapped up in kind of an ugly chunk of
162:23 HTML. Now hopping back over to the
162:26 fireall playground using the scrape
162:27 endpoint, we can replace that same URL.
162:30 We'll run this and it's going to output
162:32 markdown formatting. So now we can see
162:33 we actually have everything we're
162:35 looking for with a different quotes and
162:36 it's a lot more readable for a human. So
162:39 that's what a web scrape is, right? We
162:41 get the information back, whether that's
162:42 HTML or markdown, but then we would
162:44 typically feed that into some sort of
162:46 LLM in order to extract the information
162:47 we're looking for. In this case, we'd be
162:49 looking for different quotes. But what
162:52 we can do with extract is we can give it
162:53 the URL and then also say, hey, get all
162:56 of the quotes on here. And using this
162:57 method, we can say, not just these first
162:59 10 on this page. I want you to crawl
163:02 through the whole site and basically get
163:03 all of these quotes, all of these
163:04 quotes, all of these quotes, all of
163:06 these quotes. So it's going to be really
163:07 cool. So I'm going to show how this
163:09 works in firecrawl and then we're going
163:10 to plug it into noden. All right. So
163:11 what we're doing here is we're saying
163:13 extract all of the quotes and authors
163:14 from this website. I gave it the website
163:16 and now what it's doing is it's going to
163:18 generate the different parameters that
163:19 the LLM will be looking to extract out
163:22 of the content of the website. Okay. So
163:24 here's the run we're about to execute.
163:26 We have the URL and then we have our
163:27 schema for what the LLM is going to be
163:29 looking for. And it's looking for text
163:31 which would be the quote and it's a
163:33 string. And then it's also going to be
163:34 looking for the author of that quote
163:35 which is also a string. And then the
163:37 prompt we're feeding here to the LLM is
163:39 extract all quotes and their
163:40 corresponding authors from the website.
163:43 So we're going to hit run and we're
163:44 going to see that it's not only going to
163:46 go to that first URL, it's basically
163:48 going to take that main domain, which is
163:49 quotes to scrape.com, and it's going to
163:51 be crawling through the other sections
163:52 of this website in order to come back
163:54 and scrape all the quotes on there.
163:56 Also, quick plug, go ahead and use code
163:58 herk10 to get 10% off the first 12
164:00 months on your Firecrawl plan. Okay, so
164:03 it just finished up. As you can see, we
164:04 have 79 quotes. So down here we have a
164:07 JSON response where it's going to be an
164:09 object called quotes. And in there we
164:11 have a bunch of different items which
164:12 has you know text author text author
164:15 text author and we have pretty much
164:17 everything from that website now. Okay
164:19 cool. But what we want to do is look at
164:20 how we can do this in n so that we have
164:22 you know a list of 20 30 40 URLs that we
164:25 want to extract information from. We can
164:27 just loop through and send off that
164:28 automation rather than having to come in
164:30 here and type that out in firecrawl.
164:32 Okay. So what we're going to do is go
164:33 back into edit end. And I apologize
164:35 because there may be some jumping around
164:36 here, but we're basically just gonna
164:38 clear out this HTTP request and grab a
164:40 new one. Now, what we're going to do is
164:42 we want to go into Firecrawl's
164:43 documentation. So, all we have to do is
164:45 import the curl command for the extract
164:47 endpoint rather than trying to figure
164:48 out how to fill out these different
164:49 parameters. So, back in Firecrawl, once
164:51 you set up your account, up in the top
164:53 right, you'll see a button called docs.
164:54 You want to click into there. And now,
164:56 we can see a quick start guide. We have
164:57 different endpoints. And what we're
164:59 going to do is on the left, scroll down
165:00 to features and click on extract. And
165:03 this is what we're looking for. So,
165:04 we've got some information here. The
165:05 first thing to look at is when we're
165:07 using the extract, you can extract
165:08 structured data from one or multiple
165:10 URLs, including wild cards. So, what we
165:12 did was we didn't just scrape one single
165:14 page. We basically scraped through all
165:16 of the pages that had the main base
165:18 domain of um quotescrape.com or
165:21 something like that. And if you put a
165:23 asterk after it, it's going to basically
165:25 mean this is a wild card and it's going
165:26 to go scrape all pages that are after it
165:28 rather than just scraping this one
165:30 predefined page. As you can see right
165:33 here, it'll automatically crawl and
165:34 parse all the URLs it can discover, then
165:36 extract the requested data. And we can
165:38 see that's how it worked because if we
165:39 come back into the request we just made,
165:41 we can see right here that it added a
165:42 slash with an asterisk after quotes to
165:45 scrape.com. Okay. Anyway, so what we're
165:47 looking for here is this curl command.
165:48 This is basically going to fill out the
165:50 method, which is going to be a post
165:51 request. It's going to fill out the
165:52 endpoint. It'll fill out the content
165:54 type, and it'll show us how to set up
165:56 our authorization. And then we'll have a
165:58 body request that we'll need to make
165:59 some minor changes to. So in the top
166:02 right I'm going to click copy and I'm
166:03 going to come back into edit end. Hit
166:05 import curl. Paste that in there. Hit
166:07 import. And as you can see everything
166:08 pretty much just got populated. So like
166:10 I said the method is going to be a post.
166:12 We have the endpoint already set up. And
166:14 what I want to do is show you guys how
166:15 to set up this authorization so that we
166:16 can keep it saved forever rather than
166:18 having to put it in here in the
166:20 configuration panel every time. So first
166:22 of all, head back over to your
166:23 firecrawl. Go to API keys on the lefth
166:26 hand side. And you're just going to want
166:27 to copy that API key. So once you have
166:29 that copied, head back into NN. And now
166:31 let's look at how we actually set this
166:33 up. So typically what you do is we have
166:35 this as a header parameter. Not all
166:37 authorizations are headers, but this one
166:38 is a header. And the key or the name is
166:41 authorization and the value is bearer
166:44 space your API key. So what you'd
166:46 typically do is just paste in your API
166:48 key right there and you'd be good to go.
166:50 But what we want to do is we want to
166:51 save our firecrawl credential the same
166:53 way you'd save, you know, a Google
166:54 Sheets credential or a Slack credential.
166:58 So, we're going to come into
166:58 authentication, click on generic. We're
167:01 going to click on generic type and
167:02 choose header because we know down here
167:04 it's a header off. And then you can see
167:06 I have some other credentials already
167:07 saved. We're going to create a new one.
167:09 I'm just going to name this firecrawl to
167:11 keep ourselves organized. For the name,
167:12 we're going to put authorization. And
167:14 for the value, we're going to type
167:15 bearer with a capital B space and then
167:18 paste in our API key. And we'll hit
167:20 save. And this is going to be the exact
167:21 same thing that we just did down below,
167:23 except for now we have it saved. So, we
167:25 can actually flick this field off. We
167:27 don't need to send headers because we're
167:28 sending them right here. And now we just
167:30 need to figure out how to configure this
167:32 body request. Okay, so I'm going to
167:34 change this to an expression and open it
167:35 up just so we can take a look at it. The
167:37 first thing we notice is that by default
167:38 there are three URLs in here that we
167:40 would be extracting from. We don't want
167:41 to do that here. So I'm going to grab
167:42 everything within the array, but I'm
167:44 going to keep the two quotation marks.
167:45 Now all we need to do is put the URL
167:47 that we're looking to extract
167:48 information from in between these
167:49 quotation marks. So here I just put in
167:51 the quotes to scrape.com. But what we
167:53 want to do if you remember is we want to
167:55 put an asterisk after that so that it
167:57 will go and crawl all of the pages, not
167:59 just that first page and which would
168:01 only have like nine or 10 quotes. And
168:02 now the rest is going to be really easy
168:04 to configure because we already did this
168:05 in the playground. So we know exactly
168:07 what goes where. So I'm going to click
168:08 back into our playground example. First
168:10 thing is this is the quote that
168:11 firecross sent off. So I'm going to copy
168:13 that. Go back and edit in and I'm just
168:15 going to replace the prompts right here.
168:17 We don't want the company mission blah
168:18 blah blah. We want to paste this in here
168:20 and we're looking to extract all quotes
168:22 and their corresponding authors from the
168:24 website. And then next is basically
168:25 telling the LLM, what are you pulling
168:27 back? So, we just told it it's pulling
168:30 back quotes and authors. So, we need to
168:31 actually make the schema down here in
168:33 the body request match the prompt. So,
168:36 all we have to do is go back into our
168:37 playground. Right here is the schema
168:39 that we sent over in our example. And
168:40 I'm just going to click on JSON view and
168:42 I'm going to copy this entire thing
168:44 which is wrapped up in curly braces.
168:46 We'll come back into end and we'll start
168:48 after schema colon space. Replace all
168:51 this with what we just had in um fire
168:54 crawl. And actually I think I've noticed
168:55 the way that this copied over. It's not
168:57 going to work. So let me show you guys
168:58 that real quick. If we hit test step,
169:00 it's going to say JSON parameter needs
169:01 to be valid JSON. So what I'm going to
169:03 do is I'm going to copy all of this. Now
169:05 I came into chat GBT and I'm just saying
169:06 fix this JSON. What it's going to do is
169:08 it's going to just basically push these
169:10 over. When you copy it over from
169:12 Firecrol, it kind of aligns them on the
169:14 left, but you don't want that. So, as
169:15 you can see, it just basically pushed
169:16 everything over. We'll copy this into
169:18 our Nit end right there. And all it did
169:20 was bump everything over once. And now
169:21 we should be good to go. So, real quick
169:23 before we test this out, I'm just going
169:24 to call this extract. And then we'll hit
169:27 test step. And we should see that it's
169:28 going to be pulling. And it's going to
169:30 give us a message that says um true. And
169:33 it gives us an ID. And so now what we
169:34 need to do next is pull this ID back to
169:37 see if our request has been fulfilled
169:38 yet. So I'm back in the documentation.
169:40 And now we are going to look at down
169:43 here asynchronous extraction and status
169:45 checking. So this is how we check the
169:46 status of a request. As you saw, we just
169:48 made one. So here I'm going to click on
169:51 copy this curl command. We're going to
169:52 come back and end it in and we're going
169:54 to add another HTTP request and we're
169:56 going to import that in there. And you
169:57 can see this one is going to be a get
170:00 command. It's going to have a different
170:01 endpoint. And what we need to do if you
170:02 look back at the documentation is at the
170:04 end of the extract slash we have to put
170:06 the extract ID that we're looking to
170:09 check the status of. So back in n the ID
170:13 is going to be coming from the left hand
170:14 side the previous node every time. So
170:16 I'm just going to change the URL field
170:18 to an expression. Put a backslash and
170:21 then I'm going to grab the ID pull it
170:23 right in there and we're good to go.
170:24 Except we need to set up our credential.
170:26 And this is why it's great. We already
170:28 set this up as a generic as a header.
170:30 And now we can just pull in easily our
170:32 fire crawl off and hit test step. So
170:35 what happens now is our request hasn't
170:37 been done yet. So as you can see it
170:39 comes back as processing and the data is
170:41 an empty array. So what we're going to
170:43 set up real quick is something called
170:44 polling where we're basically checking
170:46 in on a specific ID which is this one
170:48 right here. And we're going to check and
170:50 if it's if it's empty, if the data field
170:51 is empty, then that means we're going to
170:53 wait a certain amount of time and come
170:55 back and try again. So after the
170:56 request, I'm going to add a if. So, this
170:59 is just basically going to help us
171:00 create our filter. So, we're dragging in
171:02 JSON.data, which as you can see is an
171:04 empty array, and we're just going to say
171:06 is empty. But one thing you have to keep
171:08 in mind is this doesn't match. As you
171:10 can see, we're dragging in an array, and
171:12 we were trying to do a filter of a
171:14 string. So, we have to go to array and
171:16 then say is empty. And we'll hit test
171:18 step. And this is going to say true. The
171:20 data field is empty. And so, if true,
171:23 what we want to do is we're going to add
171:24 a wait. And this will wait for, you
171:26 know, let's in in this case we'll just
171:28 say five seconds. So if we hit test
171:30 step, it's going to wait for five
171:31 seconds. And um I wish actually I
171:33 switched the logic so that this would be
171:35 on the bottom, but whatever. And then we
171:37 would just drag this right back into
171:38 here. And we would try it again. So now
171:41 after 5 seconds had passed or however
171:43 much time, we would try this again. And
171:45 now we can see that we have our item
171:46 back and the data field is no longer
171:48 empty because we have our quotes object
171:50 which has 83 quotes. So even got more
171:53 than that time we did it in the
171:54 playground. And I'm thinking this is
171:56 just because, you know, the extract is
171:57 kind of still in beta. So it may not be
171:59 super consistent, but that's still way
172:01 better than if we were to just do a
172:03 simple getit request. And then as you
172:05 can see now, if we ran this next step,
172:07 this would come
172:08 out. Ah, but this is interesting. So
172:11 before it knows what it's pulling back,
172:12 the JSON.data field is an array. And so
172:15 we're able to set up is the array empty?
172:17 But now it's an object. So we can't put
172:20 it through the same filter because we're
172:21 looking at a filter for an array. So
172:24 what I'm thinking here is we could set
172:25 up this continue using error output. So
172:27 because this this node would error, we
172:29 could hit test step and we could see now
172:30 it's going to go down the false branch.
172:33 And so this basically just means it's
172:34 going to let us continue moving through
172:36 the process. And we could do then
172:37 whatever we want to do down here.
172:38 Obviously this isn't perfect because I
172:40 just set this up to show you guys and
172:41 ran into that. But that's typically sort
172:43 of the way we would think is how can we
172:45 make this a little more dynamic because
172:46 it has to deal with empty arrays or
172:49 potentially full objects. Anyways, what
172:50 I wanted to show you guys now is back in
172:52 our request if we were to get rid of
172:54 this asterk. What would happen? So,
172:56 we're just going to run this whole
172:57 process again. I'll hit test workflow.
172:59 And now it's going to be sending that
173:00 request only to, you know, one URL
173:04 rather than the other one. Aha. And I'm
173:06 glad we are doing live testing because I
173:08 made the mistake of putting this in as
173:09 JSON ID which doesn't exist if we're
173:12 pulling from the weight node. So all we
173:14 have to do in here is get rid of JSON.
173:16 ID and pull in a basically a you know a
173:19 node reference variable. So we're going
173:21 to do two curly braces. We're going to
173:23 be pulling from the extract node. And
173:24 now we just want to say
173:27 item.json ID and we should be good to go
173:29 now. So I'm just going to refresh this
173:31 and we'll completely do it again. So
173:33 test workflow, we're doing the exact
173:35 same thing. It's not ready yet. So,
173:36 we're going to wait 5 seconds and then
173:38 we're going to go check again. We
173:40 hopefully should see, okay, it's not
173:41 ready still. So, we're going to wait
173:42 five more seconds. Come check again. And
173:45 then whenever it is ready now, as you
173:46 can see, it goes down this branch. And
173:48 we can see that we actually get our
173:50 items back. And what you see here is
173:52 that this time we only got 10 quotes.
173:54 Um, you know, it says nine, but
173:55 computers count from zero. But we only
173:57 got 10 quotes because um we didn't put
174:00 an asterisk after the URL. So, Firecrawl
174:04 didn't know I need to go scrape
174:05 everything out of this whole base URL.
174:07 I'm only going to be scraping this one
174:09 specific page, which is this one right
174:11 here, which does in fact only have 10
174:13 quotes. And by the way, super simple
174:15 template here, but if you want to try it
174:16 out and just plug in your API key and
174:18 different URLs, you can grab that in the
174:20 free school community. You'll hop in
174:22 there, you will click on YouTube
174:23 resources and click on the post
174:24 associated with this video, and you'll
174:26 have the JSON right there to download.
174:28 Once you download that, all you have to
174:29 do is import it from file right up here,
174:31 and you'll have the workflow. So,
174:33 there's a lot of cool use cases for
174:34 firecrawl. It'd be cool to be able to
174:35 pull from a a sheet, for example, of 30
174:38 or 40 or 50 URLs that we want to run
174:40 through and then update based on the
174:42 results. You could do some really cool
174:44 stuff here, like researching a ton of
174:45 companies and then having it also create
174:47 some initial outreach for you. So, I
174:48 hope you guys enjoyed that one.
174:50 Firecrawl is a super cool tool. There's
174:51 lots of functionality there and there's
174:53 lots of uses of AI in Firecrawl, which
174:55 is awesome. We're going to move into a
174:56 different tool that you can use to
174:57 scrape pretty much anything, which is
174:59 called Appify, which has a ton of
175:00 different actors, and you can scrape,
175:02 like I said, almost anything. So, let's
175:04 go into the setup video. So, Ampify is
175:06 like a marketplace for actors, which
175:08 essentially let us scrape anything on
175:09 the internet. As you can see right here,
175:10 we're able to explore 4,500 plus
175:12 pre-built actors for web scraping and
175:14 automation. And it's really not that
175:16 complicated. An actor is basically just
175:17 a predefined script that was already
175:19 built for us that we can just send off a
175:20 certain request to. So, you can think of
175:22 it like a virtual assistant where you're
175:23 saying, "Hey, I want you to I want to
175:24 use the Tik Tok virtual assistant and I
175:26 want you to scrape, you know, videos
175:28 that have the hashtag of AI content." Or
175:30 you could use the LinkedIn job scraper
175:32 and you could say, "I want to find jobs
175:33 that are titled business analyst." So,
175:35 there's just so many ways you could use
175:36 Appify. You could get leads from Google
175:38 Maps. You could get Instagram comments.
175:39 You could get Facebook posts. There's
175:41 just almost unlimited things you can do
175:43 here. You can even tap into Apollo's
175:44 database of leads and just get a ton. So
175:46 today I'm just going to show you guys in
175:48 NAN the easiest way to set up this Aify
175:50 actor where you're going to start the
175:52 actor and then you're going to just grab
175:53 those results. So what you're going to
175:54 want to do is head over to Aify using
175:56 the link in the description and then use
175:58 code 30 Nate Herk to get 30% off. Okay,
176:00 like I said, what we're going to be
176:02 covering today is a two-step process
176:03 where you make one request to Aify to
176:05 start up an actor and then you're going
176:07 to wait for it to finish up and then
176:08 you're just going to pull those results
176:10 back in. So let me show you what that
176:11 looks like. What I'm going to do is hit
176:12 test workflow and this is going to start
176:13 the Google Maps actor. And what we're
176:15 doing here is we're asking for dentists
176:17 in New York. And then if I go to my
176:18 Appify console and I go over here to
176:20 actors and click on the Google Maps
176:22 extractor one, if I click on runs, we
176:24 can see that there's one currently
176:25 finishing up right now. And now that
176:26 it's finished, I can go back into our
176:28 workflow. I can hook it up to the get
176:29 results node. Hit test step. And this is
176:32 going to pull in those 50 dentists that
176:34 we just scraped in New York. And you can
176:36 see this contains information like their
176:38 address, their website, their phone
176:39 number, all this kind of stuff. So you
176:41 can just basically scrape these lists of
176:43 leads. So anyways, that's how this
176:45 works, but let's walk through a live
176:46 setup. So once you're in your Appify
176:48 console, you click on the Appify store,
176:49 and this is where you can see all the
176:50 different actors. And let's do an
176:52 example of like a social media one. So
176:54 I'm going to click on this Tik Tok
176:55 scraper since it's just the first one
176:56 right here. And this may seem a little
176:58 bit confusing, but it's not going to be
177:00 too bad at all. We get to basically do
177:01 all this with natural language. So let
177:03 me show you guys how this works. So
177:04 basically, we have this configuration
177:06 panel right here. When you open up any
177:07 sort of actor, they won't always all be
177:09 the same, but in this one, what we have
177:11 is videos with this hashtag. So, we can
177:13 put something in. I put in AI content to
177:14 play around with earlier. And then you
177:16 can see it asks, how many videos do you
177:17 want back? So, in this case, I put 10.
177:19 Let's just put 25 for the sake of this
177:21 demo. And then you have the option to
177:22 add more settings. So, down here, we
177:24 could do, you know, we could add certain
177:25 profiles that we want to scrape. We
177:26 could add a different search
177:27 functionality. We could even have it
177:29 download the videos for us. So, once
177:31 you're good with this configuration, and
177:32 just don't over complicate it. Think of
177:34 it the same way you would like put in
177:35 filters on an e-commerce website or the
177:38 same way you would, you know, fill in
177:39 your order when you're door dashing some
177:41 food. So, now that we have this filled
177:42 out the way we want it, all I'm going to
177:44 do is come up to the top right and hit
177:45 API and click API endpoints. The first
177:48 thing we're going to do is we're going
177:49 to use this endpoint called run actor.
177:51 This is the one that's basically just
177:52 going to send a request to Apify and
177:54 start this process, but it's not going
177:55 to give us the live results back. That's
177:57 why the second step later is to pull the
177:59 results back. What you could do is you
178:00 could run the actor synchronously,
178:02 meaning it's going to send it off and
178:03 it's just going to spin in and it end
178:05 until we're done and until it has the
178:07 results. But I found this way to be more
178:09 consistent. So anyways, all you have to
178:10 do is click on copy and it's already
178:12 going to have copied over your appy API
178:15 key. So it's really, really simple. All
178:17 we're going to do here is open up a new
178:18 HTTP request. I'm going to just paste in
178:20 that URL that we just copied right here.
178:23 And that's basically all we have to do
178:24 except for we want to change this method
178:26 to post because as you can see right
178:28 here, it says post. And so this is
178:30 basically just us putting in the actor's
178:31 phone number. And so we're giving it a
178:33 call. But now what we have to do is
178:34 actually tell it what we want. So right
178:36 here, we've already filled this out. I'm
178:38 going to click on JSON and all I have to
178:40 do is just copy this JSON right here. Go
178:42 back into N. Flick this on to send a
178:44 body and we want to send over just JSON.
178:47 And then all I have to do is paste that
178:48 in there. So, as you can see, what we're
178:49 sending over to this Tik Tok scraper is
178:51 I want AI content and I want 25 results.
178:54 And then all this other stuff is false.
178:55 So, I'm just going to hit test step. And
178:56 so, this basically returns us with an ID
178:58 and says, okay, the actor started. If we
179:00 go back into here and we click on runs,
179:02 we can see that this crawler is now
179:04 running. and it's going to basically
179:06 tell us how much it costed, how long it
179:07 took, and all this kind of stuff. And
179:09 now it's already done. So, what we need
179:11 to do now is we need to click on API up
179:12 in the top right. Click on API endpoints
179:14 again and scroll all the way down to the
179:16 bottom where we can see get last run
179:19 data set items. So, all I need to do is
179:21 hit this copy button right here. Go back
179:23 into Nitn and then open up another HTTP
179:25 request. And then I'm just going to
179:27 paste that URL right in there once
179:29 again. And I don't even have to change
179:30 the method because if we go in here, we
179:32 can see that this is a get. So, all I
179:34 have to do is hit test step. And this is
179:36 going to pull in those 25 results from
179:38 our Tik Tok scrape based on the search
179:40 term AI content. So, you can see right
179:42 here it says 25 items. And just to show
179:44 you guys that it really is 25 items, I'm
179:46 just going to grab a set field. We're
179:47 going to just drag in the actual text
179:49 from here and hit test step. And it
179:51 should Oh, we have to connect a trigger.
179:53 So, I'm just going to move this trigger
179:55 over here real quick. And um what you
179:57 can do is because we already have our
179:58 data here, I can just pin it so we don't
180:00 actually have to run it again. But then
180:02 I'll hit test step. And now we can see
180:03 we're going to get our 25 items right
180:05 here, which are all of the text content.
180:08 So I think just the captions or the
180:09 titles of these Tik Toks. And we have
180:11 all 25 Tik Toks as you can see. So I
180:14 just showed you guys the two-step
180:15 method. And why I've been using it
180:17 because here's an example where I did
180:18 the synchronous run. So all I did was I
180:20 came to the Google maps and I went to
180:22 API endpoints and then I wanted to do
180:24 run actor synchronously which basically
180:26 means that it would run it in n and it
180:28 would spin until the results were done
180:30 and then it should feed back the output.
180:32 So I copied that I put it into here and
180:34 as you can see I just ran it with the
180:35 Google maps looking for plumbers and we
180:37 got nothing back. So that's why we're
180:39 taking this two-step approach where as
180:40 you can see here we're going to do that
180:41 exact same request. We're doing a
180:43 request for plumbers and we're going to
180:45 fire this off. And so nothing came back
180:47 in Nitn. But if we go to our actor and
180:49 we go to runs, we can see right here
180:50 that this was the one that we just made
180:52 for plumbers. And if we click into it,
180:54 we can see all the plumbers. So that's
180:55 why we're taking the two-step approach.
180:57 I'm going to make the exact same request
180:58 here for New York plumbers. And what I'm
181:00 going to do is just run this workflow.
181:02 And now I wanted to talk about what we
181:03 have to do because what happens is we
181:05 started the actor. And as you can see,
181:07 it's running right now. And then it went
181:08 to grab the results, but the results
181:10 aren't done yet. So that's why it comes
181:11 back and says this is an item, but it's
181:13 empty. So, what we want to do is we want
181:15 to go to our runs and we want to see how
181:17 long this is taking on average for 50
181:19 leads. As you can see, the most amount
181:20 of time it's ever taken was 19 seconds.
181:22 So, I'm just going to go in here and in
181:24 between the start actor and grab
181:26 results, I'm going to add a wait, and
181:28 I'm just going to tell this thing to
181:29 wait for 22 seconds just to be safe. And
181:31 now, what I'm going to do is just run
181:32 this thing again. It's going to start
181:33 the actor. It's going to wait for 22
181:35 seconds. So, if we go back into Ampify,
181:37 you can see that the actor is once again
181:38 running. After about 22 seconds, it's
181:41 going to pass over and then we should
181:43 get all 50 results back in our HTTP
181:45 request. There we go. Just finished up.
181:47 And now you can see that we have 50
181:48 items which are all of the plumbers that
181:51 we got in New York. So from here, now
181:53 that you have these 50 leads and
181:54 remember if you want to come back into
181:56 Ampify and change up your input, you can
181:58 change how many places you want to
182:00 extract. So if you changed this to 200
182:02 and then you clicked on JSON and you
182:03 copied in that body, you would now be
182:05 searching for 200 results. But anyways,
182:07 that's the hard part is getting the
182:09 leads into end. But now we have all this
182:10 data about them and we can just, you
182:12 know, do some research, send them off a
182:14 email, whatever it is, we can just
182:16 basically have this thing running 24/7.
182:18 And if you wanted to make this workflow
182:19 more advanced to handle a little bit
182:21 more dynamic amount of results. What
182:23 you'd want to use is a technique called
182:25 polling. So basically, you'd wait, you
182:27 check in, and then if the results were
182:28 all done, you continue down the process.
182:30 But if they weren't all done, you would
182:32 basically wait again and come back. And
182:34 you would just loop through this until
182:36 you're confident that all of the results
182:37 are done. So that's going to be it for
182:39 this one. I'll have this template
182:40 available in my free school community if
182:42 you want to play around with it. Just
182:43 remember you'll have to come in here and
182:44 you'll have to switch out your own API
182:46 key. And don't forget when you get to
182:47 Ampify, you can use code 30 Nate Herk to
182:49 get 30% off. Okay, so those were some
182:51 APIs that we can use to actually scrape
182:53 information. Now, what if we want to use
182:54 APIs to generate some sort of content?
182:57 We're going to look at an image
182:58 generation API from OpenAI and we're
183:00 going to look at a video generation API
183:02 called Runway. So these next two
183:03 workflows will explain how you set up
183:05 those API calls and also how you can
183:07 bake them into a workflow to be a little
183:09 bit more practical. So let's take a
183:11 look. So this workflow right here, all I
183:13 had to do was enter in ROI on AI
183:15 automation and it was able to spit out
183:17 this LinkedIn post for me. And if you
183:19 look at this graphic, it's insane. It
183:21 looks super professional. It even has a
183:22 little LinkedIn logo in the corner, but
183:24 it directly calls out the actual
183:26 statistics that are in the post based on
183:28 the research. And for this next one, all
183:29 I typed in was mental health within the
183:31 workplace and it spit out this post.
183:33 According to Deote Insights,
183:34 organizations that support mental health
183:36 can see up to 25% increase in
183:38 productivity. And as you can see down
183:40 here, it's just a beautiful graphic. So,
183:42 a few weeks ago when Chacht came out
183:43 with their image generation model, you
183:45 probably saw a lot of stuff on LinkedIn
183:46 like this where people were turning
183:48 themselves into action figures or some
183:50 stuff like this where people were
183:51 turning themselves into Pixar animation
183:54 style photos or whatever it is. And
183:55 obviously, I had to try this out myself.
183:57 And of course, this was very cool and
183:58 everyone was getting really excited. But
184:00 then I started to think about how could
184:01 this image generation model actually be
184:03 used to save time for a marketing team
184:06 because this new image model is actually
184:07 good at spelling and it can make words
184:09 that don't look like gibberish. It opens
184:11 up a world of possibilities. So here's a
184:13 really quick example of me giving it a
184:14 one-s sentence prompt and it spits out a
184:16 poster that looks pretty solid. Of
184:18 course, we were limited to having to do
184:20 this in chatbt and coming in here and
184:22 typing, but now the API is released, so
184:24 we can start to save hours and hours of
184:26 time. And so, the automation I'm going
184:27 to show with you guys today is going to
184:29 help you turn an idea into a fully
184:30 researched LinkedIn post with a graphic
184:33 as well. And of course, we're going to
184:34 walk through setting up the HTTP request
184:36 to OpenAI's image generation model. But
184:38 what you can do is also download this
184:40 entire template for free and you can use
184:42 it to post on LinkedIn or you can also
184:44 just kind of build on top of it to see
184:46 how you can use image generation to save
184:48 you hours and hours within some sort of
184:50 marketing process. So this workflow
184:52 right here, all I had to do was enter in
184:54 ROI on AI automation and it was able to
184:56 spit out this LinkedIn post for me. And
184:58 if you look at this graphic, it's
184:59 insane. It looks super professional. It
185:01 even has a little LinkedIn logo in the
185:03 corner, but it directly calls out the
185:05 actual statistics that are in the post
185:07 based on the research. So 74% of
185:09 organizations say their most advanced AI
185:11 initiatives are meeting or exceeding ROI
185:13 expectations right here. And on the
185:15 other side, we can see that only 26% of
185:17 companies have achieved significant
185:19 AIdriven gains so far, which is right
185:21 here. And I was just extremely impressed
185:23 by this one. And for this next one, all
185:24 I typed in was mental health within the
185:26 workplace. And to spit out this post,
185:28 according to Deote Insights,
185:29 organizations that support mental health
185:31 can see up to 25% increase in
185:33 productivity. And as you can see down
185:35 here, it's just a beautiful graphic.
185:37 something that would probably take me 20
185:38 minutes in Canva. And if you can now
185:40 push out these posts in a minute rather
185:42 than 20 minutes, you can start to push
185:43 out more and more throughout the day and
185:45 save hours every week. And because the
185:47 post is being backed by research, the
185:49 graphic is being backed by the research
185:50 post. You're not polluting anything into
185:53 the internet. A lot of people in my
185:54 comments call it AI slop. Anyways, let's
185:56 do a quick live run of this workflow and
185:58 then I'll walk through step by step how
185:59 to set up this API call. And as always,
186:01 if you want to download this workflow
186:02 for free, all you have to do is join my
186:04 free school community. link is down in
186:06 the description and then you can search
186:07 for the title of the video. You can go
186:09 into YouTube resources. You need to find
186:11 the post associated with this video and
186:13 then when you're in there, you'll be
186:14 able to download this JSON file and that
186:16 is the template. So you download the
186:18 JSON file. You'll go back into Nitn.
186:20 You'll open up a new workflow and in the
186:22 top right you'll go to import from file.
186:25 Import that JSON file and then there'll
186:26 be a little sticky note with a setup
186:28 guide just sort of telling you what you
186:29 need to plug in to get this thing to
186:31 work for you. Okay, quick disclaimer
186:32 though. I'm not actually going to post
186:33 this to LinkedIn. you certainly could,
186:35 but um I'm just going to basically send
186:37 the post as well as the attachment to my
186:39 email because I don't want to post on
186:41 LinkedIn right now. Anyways, as you can
186:43 see here, this workflow is starting with
186:45 a form submission. So, if I hit test
186:47 workflow, it's going to pop up with a
186:48 form where we have to enter in our email
186:51 for the workflow to send us the results.
186:53 Topic of the post and then also I threw
186:55 in here a target audience. So, you could
186:57 have these posts be kind of flavored
186:58 towards a specific audience if you want
187:00 to. Okay, so this form is waiting for
187:02 us. I put in my email. I put the topic
187:04 of morning versus night people and the
187:05 target audience is working adults. So,
187:07 we'll hit submit, close out of here, and
187:09 we'll see the LinkedIn post agent is
187:10 going to start up. It's using Tavi here
187:12 for research and it's going to create
187:14 that post and then pass the post on to
187:17 the image prompt agent. And that image
187:19 prompt agent is going to read the post
187:20 and basically create a prompt to feed
187:23 OpenAI's image generator. And as you can
187:26 see, it's doing that right now. We're
187:28 going to get that back as a base 64
187:30 string. And then we're just converting
187:32 that to binary so we can actually post
187:34 that on LinkedIn or send that in email
187:36 as an attachment and we'll break down
187:37 all these steps. But let's just wait and
187:39 see what these results look like here.
187:41 Okay, so all that just finished up. Let
187:43 me pop over to email. So in email, we
187:45 got our new LinkedIn post. Are you a
187:46 morning lark or a night owl? The science
187:48 of productivity. I'm not going to read
187:49 through this right now exactly, but
187:51 let's take a look at the image we got.
187:52 When are you most productive? In the
187:54 morning, plus 10% productivity or night
187:57 owls thrive in flexibility. I mean, this
187:59 is insane. This is a really good
188:00 graphic. Okay, so now that we've seen
188:02 again how good this is, let's just break
188:04 down what's going on. We're going to
188:05 start off with the LinkedIn post agent.
188:07 All we're doing is we're feeding in two
188:09 things from the form submission, which
188:11 was what is the topic of the post, as
188:12 well as who's the target audience. So
188:14 right here, you can see morning versus
188:15 night people and working adults. And
188:18 then we move into the actual system
188:19 prompt, which I'm not going to read
188:21 through this entire thing. If you
188:22 download the template, the prompt will
188:23 be in there for you to look at. But
188:25 basically I told it you are an AI agent
188:26 specialized in creating professional
188:28 educational and engaging LinkedIn posts
188:30 based on a topic provided by the user.
188:33 We told it that it has a tool called
188:34 Tavly that it will use to search the web
188:36 and gather accurate information and that
188:38 the post should be written to appeal to
188:40 the provided target audience. And then
188:42 basically just some more information
188:43 about how to structure the post, what it
188:45 should output and then an example which
188:47 is basically you receive a topic. You
188:49 search the web, you draft the post and
188:51 you format it with source citations,
188:53 clean structure, optional hashtags and a
188:55 call to action at the end. And as you
188:56 can see what it outputs is a super clean
188:59 LinkedIn post right here. So then what
189:01 we're going to do is basically we're
189:02 feeding this output directly into that
189:05 next agent. And by the way, they're both
189:06 using chat GBT 4.1 through open router.
189:10 All right, but before we look at the
189:11 image prompt agent, let's just take a
189:12 look at these two things down here. So
189:14 the first one is the chat model that
189:15 plugs into both image prompt agent and
189:17 the LinkedIn post agent. So all you have
189:19 to do is go to open router, get an API
189:20 key, and then you can choose from all
189:22 these different models. And in here, I'm
189:23 using
189:24 GPT4.1. And then we have the actual tool
189:26 that the LinkedIn agent uses for its
189:29 research which is Tavi. And what we're
189:31 doing here is we're sending off a post
189:32 request using an HTTP request tool to
189:35 the Tavi endpoint. So this is where
189:38 people typically start to feel
189:39 overwhelmed when trying to set up these
189:40 requests because it can be confusing
189:42 when you're trying to look through that
189:43 API documentation. Which is exactly why
189:45 in my paid community I created a APIs
189:47 and HTTP requests deep dive because
189:49 truthfully you need to understand how to
189:51 set up these requests because being able
189:54 to connect to different APIs is where
189:56 the magic really happens. So Tavi just
189:58 lets your LLM connect to the web and
190:00 it's really good for web search and it
190:02 also gives you a thousand free searches
190:03 per month. So that's the plan that I'm
190:05 on. Anyways, once you're in here and you
190:06 have an account and you get an API key,
190:08 all I did was went to the Tavali search
190:10 endpoint and you can see we have a curl
190:12 statement right here where we have this
190:14 endpoint. We have post as the method we
190:17 have this is how we authorize ourselves
190:18 and this is all going to be pretty
190:20 similar to the way that we set up the
190:21 actual request to OpenAI's image
190:23 generation API. So, I'm not going to
190:25 dive into this too much. When you
190:26 download this template, all you have to
190:27 do is plug in your Tavi API. But later
190:30 in this video when we walk through
190:32 setting up the request to OpenAI, this
190:34 should make more sense. Anyways, the
190:36 main thing to take away from this tool
190:38 is that we're using a placeholder for
190:39 the request because in the request we
190:41 sent over to Tavali, we basically say,
190:43 okay, here's the search query that we're
190:44 going to search the internet for. And
190:46 then we have all these other little
190:47 settings we can tweak like the topic,
190:49 how many results, how many chunks per
190:51 source, all this kind of stuff. All we
190:52 really want to touch right now is the
190:54 query. And as you can see, I put this in
190:57 curly braces, meaning it's a
190:58 placeholder. I'm calling the placeholder
191:00 search term. And down here, I'm defining
191:02 that placeholder as what the user is
191:04 searching for. So, as you can see, this
191:06 data in the placeholder is going to be
191:07 filled in by the model. So, based on our
191:09 form submission, when we asked it to,
191:11 you know, create a LinkedIn post about
191:13 morning versus night people, it fills
191:15 out the search term with latest research
191:17 on productivity, morning people versus
191:19 night people, and that's basically how
191:21 it searches the internet. And then we
191:22 get our results back. And now it creates
191:24 a LinkedIn post that we're ready to pass
191:26 off to the next agent. So the output of
191:29 this one gets fed into this next one,
191:31 which all it has to do is read the
191:32 output. As you can see right here, we
191:34 gave it the LinkedIn post, which is the
191:36 full one that we just got spit out. And
191:38 then our system message is basically
191:39 telling it to turn that into an image
191:41 prompt. This one is a little bit longer.
191:43 Not too bad, though. I'm not going to
191:45 read the whole thing, but essentially
191:46 we're telling it that it's going to be
191:48 an AI agent that transforms a LinkedIn
191:50 post into a visual image prompt for a
191:53 textto-image AI generation model. So, we
191:56 told it to read the post, identify the
191:58 message, identify the takeaways, and
192:00 then create a compelling graphic prompt
192:02 that can be used with a textto image
192:04 generator. We gave it some output
192:05 instructions like, you know, if there's
192:06 numbers, try to work those into the
192:08 prompt. Um, you can use, you know, text,
192:10 charts, icons, shapes, overlays,
192:12 anything like that. And then the very
192:14 bottom here, we just gave it sort of
192:15 like an example prompt format. And you
192:17 can see what it spits out is a image
192:20 prompt. So it says a dynamic split
192:21 screen infographic style graphic. Left
192:24 side has a sunrise, it's bright yellow,
192:25 and it has morning larks plus 10%
192:27 productivity. And the right side is a
192:29 morning night sky, cool blue gradients,
192:32 a crescent moon, all this kind of stuff.
192:33 And that is exactly what we saw back in
192:35 here when we look at our image. And so
192:38 this is just so cool to me because first
192:39 of all, I think it's really cool that it
192:41 can read a post and kind of use its
192:42 brain to say, "Okay, this would be a
192:44 good, you know, graphic to be looking at
192:46 while I'm reading this post." But then
192:47 on top of that, it can actually just go
192:49 create that for us. So, I think this
192:51 stuff is super cool. You know, I
192:52 remember back in September, I was
192:53 working on a project where someone
192:55 wanted me to help them with LinkedIn
192:57 automated posting and they wanted visual
192:59 elements as well and I was like, uh, I
193:00 don't know, like that might have to be a
193:02 couple month away thing when we have
193:04 some better models and now we're here.
193:05 So, it's just super exciting to see. But
193:07 anyways, now we're going to feed that
193:08 output, the image prompt into the HTTP
193:12 request to OpenAI. So, real quick, let's
193:14 go take a look at OpenAI's
193:16 documentation. So, of course, we have
193:18 the GBT image API, which lets you
193:20 create, edit, and transform images.
193:22 You've got different styles, of course.
193:24 You can do like memes with a with text.
193:26 You can do creative things. You can turn
193:28 other images into different images. You
193:30 can do all this kind of stuff. And this
193:31 is where it gets really cool, these
193:33 posters and the visuals with words
193:35 because that's the kind of stuff where
193:36 typically AI image gen like wasn't there
193:38 yet. And one thing real quick in your
193:41 OpenAI account, which is different than
193:42 your chatbt account, this is where you
193:44 add the billing for your OpenAI API
193:46 calls. You have to have your
193:48 organization verified in order to
193:50 actually be able to access this model
193:51 through API. Right now, it took me 2
193:54 minutes. You basically just have to
193:55 submit an ID and it has to verify that
193:57 you're human and then you'll be verified
193:59 and then you can use it. Otherwise,
194:00 you're going to get an error message
194:01 that looks like this that I got earlier
194:02 today. But anyways, the verification
194:04 process does not take too long. Anyways,
194:06 then you're going to head over to the
194:07 API documentation that I will have
194:08 linked in the description where we can
194:10 see how we can actually create an image
194:12 in NAN. So, we're going to dive deeper
194:14 into this documentation in the later
194:16 part of this video where I'm walking
194:17 through a step-by-step setup of this.
194:19 But, we're using the endpoint um which
194:21 is going to create an image. So, we have
194:23 this URL right here. We're going to be
194:24 creating a post request and then we just
194:27 obviously have our things that we have
194:28 to configure like the prompt in the
194:30 body. We have to obviously send over
194:32 some sort of API key. We have to, you
194:34 know, we can choose the size. We can
194:36 choose the model. All this kind of
194:37 stuff. So back in NN, you can see that
194:39 I'm sending a post request to that
194:41 endpoint. For the headers, I set up my
194:43 API key right here, but I'm going to
194:44 show you guys a better way to do that in
194:46 the later part of this video. And then
194:47 for the body, we're saying, okay, I want
194:49 to use the GBT image model. Here's the
194:51 actual prompt to use for the image which
194:52 we dragged in from the image prompt
194:54 agent. And then finally the size we just
194:56 left it as that 1024 * 1024 square
194:59 image. And so this is interesting
195:01 because what we get back is we get back
195:03 a massive base 64 code. Like this thing
195:07 is huge. I can't even scroll right now.
195:08 My screen's kind of frozen. Anyways, um
195:11 yeah, there it goes. It just kind of
195:12 lagged. But we got back this massive
195:13 file. We can see how many tokens this
195:15 was. And then what we're going to do is
195:18 we're going to convert that to binary
195:20 data. So that's how we can actually get
195:21 the file as an image. As you can see now
195:23 after we turn that nasty string into a
195:27 file, we have the binary image right
195:28 over here. So all I did was I basically
195:31 just dragged in this field right here
195:32 with that nasty string. And then when
195:34 you hit test step, you'll get that
195:36 binary data. And then from there, you
195:38 have the binary data, you have the
195:39 LinkedIn post. All you have to do is,
195:41 you know, activate LinkedIn, drag it
195:43 right in there. Or you can just do what
195:45 I did, which is I'm sending it to myself
195:47 in email. And of course, before you guys
195:49 yell at me, let's just talk about how
195:50 much this run costed me. So, this was
195:53 4,273 tokens. And if we look at this API
195:55 and we go down to the pricing section,
195:57 we can see that for image output tokens,
195:59 which was generated images, it's going
196:01 to be 40 bucks for a million tokens,
196:03 which comes out to about 17 cents. If
196:05 you can see that right here, hopefully I
196:06 did the math right. But really, for the
196:08 quality and kind of for the industry
196:09 standard I've seen for price, that's on
196:11 the cheaper end. And as you can see down
196:12 here, it translates roughly to 2 cents,
196:14 7 cents, 19 cents per generated image
196:17 for low, medium, blah blah blah blah
196:18 blah. But anyways, now that that's out
196:20 of the way, let's just set up an HTTP
196:22 request to that API and generate an
196:25 image. So, I'm going to add a first
196:26 step. I'm just going to grab an HTTP
196:28 request. So, I'm just going to head over
196:30 to the actual API documentation from
196:31 OpenAI on how to create an image and how
196:34 to hit this endpoint. And all we're
196:35 going to do is we're going to copy this
196:36 curl command over here on the right. If
196:38 it you're not seeing a curl command, if
196:39 you're seeing Python, just change that
196:40 to curl. Copy that. And then we're going
196:42 to go back into Nitn. Hit import curl.
196:45 Paste that in there. And then once we
196:47 hit import, we're almost done. So that
196:49 curl statement basically just autopop
196:50 populated almost everything we need to
196:52 do. Now we just have a few minor tweaks.
196:54 But as you can see, it changed the
196:55 method to post. It gave us the correct
196:57 URL endpoint already. It has us sending
196:59 a header, which is our authorization,
197:01 and then it has our body parameters
197:02 filled out where all we'd really have to
197:04 change here is the prompt. And if we
197:06 wanted to, we can customize this kind of
197:07 stuff. And that's why it's going to be
197:09 really helpful to be able to understand
197:10 and read API documentation so you know
197:13 how to customize these different
197:14 requests. Basically, all of these little
197:16 things here like prompt, background,
197:18 model, n, output format, they're just
197:20 little levers that you can pull and
197:22 tweak in order to change your output.
197:23 But we're not going to dive too deep
197:25 into that right now. Let's just see how
197:26 we can create an image. Anyways, before
197:28 we grab our API key and plug that in,
197:30 when you're in your OpenAI account, make
197:32 sure that your organization is verified.
197:33 Otherwise, you're going to get this
197:34 error message and it's not going to let
197:35 you access the model. Doesn't take long.
197:37 Just submit an ID. And then also make
197:39 sure that you have billing information
197:40 set up so you can actually pay for um an
197:43 image. But then you're going to go down
197:45 here to API keys. You're going to create
197:47 new secret key. This one's going to be
197:49 called image test just for now. And then
197:52 you're going to copy that API key. Now
197:55 back in any then it has this already set
197:56 up for us where all we need to do is
197:58 delete all this. We're going to keep the
198:00 space after bearer. And we can paste in
198:01 our API key like that. and we're good to
198:03 go. But if you want a better method to
198:06 be able to save this key in Nadn so you
198:08 don't have to go find it every time.
198:11 What you can do is come to
198:11 authentication, go to general or
198:14 actually no it's generic and then you're
198:15 going to choose header off and we know
198:17 it's header because right here we're
198:18 sending headers as a header parameter
198:20 and this is where we're authorizing
198:21 oursel. So we're just going to do the
198:22 same up here with the header off. And
198:24 then we're going to create a new one.
198:26 I'm just going to call this one openai
198:28 image just so we can keep ourselves
198:30 organized.
198:31 And then you're going to do the same
198:33 thing as what we saw down in that header
198:34 parameter field. Meaning the
198:37 authorization is the name and then the
198:39 value was bearer space API key. So
198:43 that's all I'm going to do. I'm going to
198:44 hit save. We are now authorized to
198:47 access this endpoint. And I'm just going
198:49 to turn off sending headers because
198:51 we're technically sending headers right
198:52 up here with our authentication. So we
198:55 should be good now. Right now we'll be
198:56 getting an image of a cute baby sea
198:58 otter. Um, and I'm just going to say
199:01 making pancakes. And we'll hit test
199:03 step. And this should be running right
199:05 now. Um, okay. So, bad request. Please
199:07 check your parameters. Invalid type for
199:09 n. It expected an integer, but it got a
199:12 string instead. So, if you go back to
199:13 the API documentation, we can see n
199:16 right here. It should be integer or
199:18 null, and it's also optional. So, I'm
199:20 just going to delete that. We don't
199:21 really need
199:22 that. And I'm going to hit test step.
199:24 And while that's running real quick,
199:26 we'll just go back at n. And this
199:27 basically says the number of images to
199:29 generate must be between 1 and 10. So
199:31 that's like one of those little levers
199:32 you could tweak like I was talking about
199:34 if you want to customize your request.
199:36 But right now by default it's only going
199:38 to give us one. Looks like this HTTP
199:40 request is working. So I'll check in
199:42 with you guys in 20 seconds when this is
199:45 done. Okay. So now that that finished
199:46 up, didn't take too long. We have a few
199:48 things and all we really need is this
199:50 base 64. But we can see again this one
199:52 costed around 17. And now we just have
199:55 to turn this into binary so we can
199:57 actually view an image. So I'm going to
199:59 add a plus after the HTTP request. I'm
200:01 just going to type in binary. And we can
200:04 see convert to file, which is going to
200:06 convert JSON data to binary data. And
200:09 all we want to do here is move a B 64
200:11 string to file because this is a B 64
200:14 JSON. And this basically represents the
200:15 image. So I'm going to drag that into
200:17 there. And then when I hit test step, we
200:19 should be getting a binary image output
200:22 in a field called data. As you can see
200:24 right here, and this should be our image
200:25 of a cute sea otter making pancakes. As
200:28 you can see, um it's not super
200:30 realistic, and that's because the prompt
200:32 didn't have any like photorealistic,
200:34 hyperrealistic elements in there, but
200:36 you can easily make it do so. And of
200:38 course, I was playing around with this
200:39 earlier, and just to show you guys, you
200:40 can make some pretty cool realistic
200:41 images, here was um a post I made about
200:45 um if ancient Rome had access to
200:47 iPhones. And obviously, this is not like
200:49 a real Twitter account. Um, but this is
200:51 a dinosaurs evolved into modern-day
200:53 influencers. This was just for me
200:54 testing like an automation using this
200:56 API and auto posting, but not as
200:59 practical as like these LinkedIn
201:00 graphics. But if you guys want to see a
201:02 video sort of like this, let me know. Or
201:04 if you also want to see a more evolved
201:05 version of the LinkedIn posting flow and
201:07 how we can make it even more robust and
201:09 even more automated, then definitely let
201:10 me know about that as
201:13 well. Okay. Okay. So, all I have to do
201:15 in this form submission is enter in a
201:17 picture of a product, enter in the
201:18 product name, the product description,
201:20 and my email address. And we'll send
201:22 this off, and we'll see the workflow
201:23 over here start to fire off. So, we're
201:26 going to upload the photo. We're going
201:27 to get an image prompt. We're going to
201:28 download that photo. Now, we're creating
201:30 a professional graphic. So, after our
201:32 image has been generated, we're
201:33 uploading it to a API to get a public
201:35 URL so we can feed that URL of the image
201:38 into Runway to generate a professional
201:40 video. Now, we're going to wait 30
201:41 seconds and then we'll check in to see
201:42 if the video is done. If it's not done
201:44 yet, we're going to come down here and
201:45 pull, wait five more seconds, and then
201:47 go check in. And we're going to do this
201:48 infinitely until our video is actually
201:50 done. So, anyways, it just finished up.
201:52 It ended up hitting this check eight
201:54 times, which indicates I should probably
201:55 increase the wait time over here. But
201:57 anyways, let's go look at our finished
201:58 products. So, we just got this new
201:59 email. Here are the requested marketing
202:01 materials for your toothpaste. So,
202:03 first, let's look at the video cuz I
202:04 think that's more exciting. So, let me
202:05 open up this link. Wow, we got a
202:06 10-second video. It's spinning. It's 3D.
202:08 The lighting is changing. This looks
202:10 awesome. And then, of course, it also
202:12 sends us that image. in case we want to
202:13 use that as well. And one of the steps
202:15 in the workflow is that it's going to
202:16 upload your original image to your
202:17 Google Drive. So here you can see this
202:19 was the original and then this was the
202:20 finished product. So now you guys have
202:22 seen a demo. We're going to build this
202:23 entire workflow step by step. So stick
202:25 with me because by the end of this
202:27 video, you'll have this exact system up
202:28 and running. Okay. So when we're setting
202:30 up a system where we're creating an
202:32 image from text and then we're creating
202:33 a video from that image, the two most
202:35 important things are going to be that
202:37 image prompt and that video prompt. So
202:38 what we're going to do is head over to
202:39 my school community. The link for that
202:41 will be down in the description. It's a
202:42 free school community. And then what
202:43 you're going to do is either search for
202:44 the title of this video or click on
202:46 YouTube resources and find the post
202:48 associated with this video. And when you
202:50 click into there, there'll be a doc that
202:52 will look like this or a PDF and it will
202:54 have the two prompts that you'll need in
202:55 order to run the system. So head over
202:57 there, get that doc, and then we can hop
202:59 into the step by step. And that way we
203:00 can start to build this workflow and you
203:02 guys will have the prompts to plug right
203:03 in. Cool. So once you have those, let's
203:06 get started on the workflow. So as you
203:07 guys know, a workflow always has to
203:09 start with some sort of trigger. So in
203:11 this case, we're going to be triggering
203:12 this workflow with a form submission. So
203:14 I'm just going to grab the native NAN
203:16 form on new form event. So we're going
203:18 to configure what this form is going to
203:19 look like and what it's going to prompt
203:20 a user to input. And then whenever
203:22 someone actually submits a response,
203:24 that's when the workflow is going to
203:26 fire off. Okay. So I'm going to leave
203:27 the authentication as none. The form
203:29 title, I'm just putting go to market.
203:31 For the form description, I'm going to
203:32 say give us a product photo, title, and
203:36 description, and we'll get back to you
203:37 with professional marketing materials.
203:40 And if you guys are interested in what I
203:41 just used to dictate that text, there'll
203:43 be a link for Whisper Flow down in the
203:44 description. And now we need to add our
203:46 form elements. So the first one is going
203:47 to be not a text. We're going to have
203:50 them actually submit a file. So click on
203:52 file. This is going to be required. I
203:54 only want them to be allowed to upload
203:55 one file. So I'm going to switch off
203:56 multiple files. And then for the field
203:59 name, we're just going to say product
204:01 photo. Okay. So now we're going to add
204:03 another one, which is going to be the
204:04 product title. So I'm just going to
204:05 write product title. This is going to be
204:07 text. For placeholder, let's just put
204:09 toothpaste since that was the example.
204:10 This will be a required field. So, the
204:12 placeholder is just going to be the gray
204:13 text that fills in the text box so
204:15 people are kind of they know what to put
204:17 in. Okay, we're adding another one
204:18 called product description. We'll make
204:21 this one required. We'll just leave the
204:22 placeholder blank cuz you don't need it.
204:24 And then finally, what we need to get
204:25 from them is an email, but instead of
204:27 doing text, we can actually make it
204:28 require a valid email address. So, I'm
204:30 just going to call it email and we'll
204:32 just say like
204:34 namele.com so they know what a valid
204:36 email looks like. We'll make that
204:37 required because we have to send them an
204:38 email at the end with their materials.
204:40 And now we should be good to go. So if I
204:42 hit test step, we'll see that it's going
204:44 to open up a form submission and it has
204:45 everything that we just configured. And
204:47 now let me put in some sample data real
204:48 quick. Okay, so I put a picture of a
204:50 clone bottle. The title's clone. I said
204:52 the clone smells very clean and fresh
204:54 and it's a very sophisticated scent
204:55 because we're going to have that
204:57 description be used to sort of help
204:58 create that text image prompt. And then
205:00 I just put my email. So I'm going to
205:02 submit this form. We should see that
205:03 we're going to get data back right here
205:05 in our NIN, which is the binary photo.
205:07 This is the product photo that I just
205:08 submitted. And then we have our actual
205:10 table of information like the title, the
205:13 description, and the email. And so when
205:15 I'm building stuff step by step, what I
205:17 like to do is I get the data in here,
205:18 and then I pretty much will just build
205:20 node by node, testing the data all the
205:22 way through, making sure that nothing's
205:23 going to break when variables are being
205:25 passed from left to right in this
205:27 workflow. Okay, so the next thing that
205:28 we need to do is we have this binary
205:30 data in here and binary data is tough to
205:33 reference later. So what I'm going to do
205:34 is I'm just going to upload it straight
205:35 to our Google Drive so we can pull that
205:37 in later when we need it to actually
205:39 edit that image. Okay, so that's our
205:41 form trigger. That's what starts the
205:42 workflow. And now what we're going to do
205:44 next is we want to upload that original
205:46 image to Google Drive so we can pull it
205:48 in later and then use it to edit the
205:50 image. So what I'm going to do is I'm
205:51 going to click on the plus. I'm going to
205:53 type in Google Drive. And we're going to
205:54 grab a Google Drive operation. That is
205:56 going to be upload file. So, I'll click
205:58 on upload file. And at this point, you
206:00 need to connect your Google Drive. So,
206:02 I'm not going to walk through that step
206:03 by step, but I have a video right up
206:04 here where I do walk through it step by
206:06 step. But basically, you're just going
206:08 to go to Docs. You have to open up a
206:10 sort of Google Cloud profile or a
206:12 console, and then you just have to
206:14 connect yourself and enable the right
206:15 credentials and APIs. Um, but like I
206:17 said, that video will walk through it.
206:19 Anyways, now what we're doing is we have
206:20 to upload the binary field right here to
206:23 our Google Drive. So, it's not called
206:25 data. We can see over here it's called
206:27 product photo. So, I'm just going to
206:28 copy and paste that right there. So,
206:29 it's going to be looking for that
206:30 product photo. And then we have to give
206:32 it a name. So, that's why we had the
206:34 person submit a title. So, all I'm going
206:36 to do is for the name, I'm going to make
206:38 this an expression instead of fixed
206:40 because this name is going to change
206:42 based on the actual product coming
206:43 through. I'm going to drag in the
206:45 product title from the left right here.
206:47 So now the the photo in Google Drive is
206:49 going to be called cologne and then I'm
206:51 just going to in parenthesis say
206:53 original. So because this is an
206:55 expression, it basically means whenever
206:56 someone submits a form, whatever the
206:58 title is, it's going to be title and
207:00 then it's going to say original. And
207:01 that's how we sort of control that to be
207:03 dynamic. Anyways, then I'm just choosing
207:05 what folder to go in. So in my drive,
207:06 I'm going to choose it to go to a folder
207:08 that I just made called um product
207:10 creatives. So once we have that
207:12 configured, I'm going to hit test step.
207:14 We're going to wait for this to spin. it
207:15 means that it's trying to upload it
207:16 right now. And then once we get that
207:18 success message, we'll quickly go to our
207:20 Google Drive and make sure that the
207:21 image is actually there. So there we go.
207:23 It just came back. And now I'm going to
207:25 click into Google Drive, click out of
207:26 the toothpaste, and we can see we have
207:27 cologne. And that is the image that we
207:29 just submitted in NAN. All right. Now
207:31 that we've done that, what we want to do
207:33 is we want to feed the data into an AI
207:35 node so that it can create a text image
207:37 prompt. So I'm going to click on the
207:38 plus. I'm going to grab an AI agent. And
207:41 before we do anything in here, I'm first
207:43 of all going to give it its brain. So,
207:44 I'm going to click on the plus under
207:45 chat model. I'm personally going to grab
207:47 an open router chat model, which
207:49 basically lets you connect to a ton of
207:51 different things. Um, let me see. Open
207:53 router.ai. It basically lets you connect
207:55 your agents to all the different models.
207:57 So, if I click on models up here, we can
207:59 see that it just lets you connect to
208:00 Gemini, Anthropic, OpenAI, Deepseek. It
208:03 has all these models and all in one
208:04 place. So, go to open router, get an API
208:06 key, and then once you come back into
208:08 here, all you have to do is connect your
208:09 API key. And what I'm going to use here
208:11 is going to be 4.1. And then I'm just
208:14 going to name this so we know which one
208:15 I'm using here. And then we now have our
208:18 agent accessing
208:20 GPT4.1. Okay. So now you're going to go
208:22 to that PDF that I have in the school
208:24 community and you're just going to copy
208:26 this product photography prompt. Grab
208:29 that. Go back to the AI agent and then
208:31 you're going to click on add option. Add
208:33 a system message. And then we're
208:34 basically just going to I'm going to
208:36 click on expression and expand this full
208:38 screen so you guys can see it better.
208:39 But I'm just going to paste that prompt
208:40 in here. And this is going to tell the
208:42 AI agent how to take what we're giving
208:44 it and turn it into a text image
208:47 optimized prompt for professional style,
208:51 you know, studio photography. So, we're
208:53 not done yet because we have to actually
208:55 give it the dynamic information from our
208:57 form submission every time. So, that's a
208:59 user message. That's basically what it's
209:01 going to look at. So, the user message
209:02 is what the agent's going to look at
209:03 every time. And the system message is
209:05 basically like here are your
209:07 instructions. So for the user message,
209:09 we're not going to be using a connected
209:10 chat trigger node. We're going to define
209:11 below. And when we want to make sure
209:13 that this changes every time, we have to
209:15 make sure it's an expression. And then
209:17 I'm just going to drill down over here
209:19 to the form submission. And I'm going to
209:20 say, okay, here's what we're going to
209:21 give this agent. It's going to get the
209:24 product, which the person submitted to
209:26 us in the form, and we can drag in the
209:29 product, which was cologne, as you can
209:31 see on the right. And then they also
209:33 gave us a description. So, all I have to
209:36 do now is drag in the product
209:37 description. And so, now every time the
209:38 agent will be looking at whatever
209:40 product and description that the user
209:42 submitted in order to create its prompt.
209:44 So, I'm going to hit test step. We'll
209:46 see right now it's using its chat model
209:48 GPT4.1. And it's already created that
209:50 prompt for us. So, let's just give it a
209:51 quick read. Hyperrealistic photo of
209:53 sophisticated cologne bottle,
209:54 transparent glass, sleek minimalistic
209:56 design, silver metal cap, all this. But
209:59 what we have to do is we have to make
210:00 sure that the image isn't being created
210:02 just on this. It has to look at this,
210:04 but it also has to look at the actual
210:06 original image. So that's why our next
210:08 step is going to be to redownload this
210:10 file and then we're going to push it
210:11 over to the image generation model. So
210:13 at this point, you may be wondering like
210:15 why are we going to upload the file if
210:16 we're just going to download it again?
210:18 And the reason why I had to do that is
210:19 because when we get the file in the form
210:21 of binary, we want to send the binary
210:24 data into the HTTP request right here
210:26 that actually generates the image. And
210:28 we can't reference the binary way over
210:30 here if it's only coming through over
210:32 here. So, we upload it so that we can
210:34 then download it and then send it right
210:35 back in. And so, if that doesn't make
210:37 sense yet, it probably will once we get
210:38 over to the stage. But that's why.
210:41 Anyways, next step is we're going to
210:43 download that file. So, I'm going to
210:44 click on this plus. We're going to be
210:45 downloading it from Google Drive and
210:47 we're going to be using the operation
210:48 download file. So, we already should be
210:51 connected because we've set up our
210:52 Google credentials already. The
210:54 operation is going to be download the
210:55 resources a file and instead of choosing
210:57 from a list, we're going to choose by
210:59 ID. And all we're going to do is
211:00 download that file that we previously
211:02 uploaded every time. So I'm going to
211:03 come over here, the Google Drive, upload
211:05 photo node, drag in the ID, and now we
211:08 can see that's all we have to do. If we
211:09 hit test step, we'll get back that file
211:11 that we originally uploaded. And we can
211:13 just make sure it's the cologne bottle.
211:15 Okay, but now it's time to basically use
211:16 that downloaded file and the image
211:19 prompt and send that over to an API
211:21 that's going to create an image for us.
211:23 So we're going to be using OpenAI's
211:25 image generator. So here is the
211:26 documentation. we have the ability to
211:28 create an image or we can create an
211:30 image edit which is what we want to do
211:32 because we wanted to look at the photo
211:33 and our request. So typically what you
211:36 can do in this documentation is you can
211:38 copy the curl command but this curl
211:40 command is actually broken so we're not
211:41 going to do that. If you copied this one
211:43 up here to actually just create an image
211:44 that one would work fine but there's
211:46 like a bug with this one right now. So
211:47 anyways I'm going to go into our n I'm
211:50 going to hit the plus. I'm going to grab
211:51 an HTTP request and now we're going to
211:54 configure this request. So, I'm going to
211:57 walk through how I'm reading the API
211:58 documentation right here to set this up.
212:00 I'm not going to go super super
212:01 in-depth, but if you get confused along
212:03 the way, then definitely check out my
212:04 paid course. The link for that down in
212:06 the description. I've got a full course
212:07 on deep diving into APIs and HTTP
212:10 requests. Anyways, the first thing we
212:11 see is we're going to be making a post
212:13 request to this endpoint. So, the first
212:15 thing I'm going to do is copy this
212:16 endpoint. We're going to paste that in.
212:18 And then we're also going to make sure
212:19 the method is set to post. So, the next
212:21 thing that we have to do is authorize
212:23 ourselves somehow. So over here I can
212:25 see that we have a header and the name
212:26 is going to be authorization and then
212:28 the value is going to be bearer space R
212:31 open AI key. So that's why I set up a
212:33 header authentication already. So in
212:35 authentication I went to generic and
212:36 then I went to header and then you can
212:39 see I have a bunch of different headers
212:40 already set up. But what I did here is I
212:42 chose my OpenAI one where basically all
212:44 I did was I typed in here authorization
212:46 and then in the value I typed in bearer
212:48 space and then I pasted my API key in
212:50 there. And now I have my OpenAI
212:52 credential saved forever. Okay. So the
212:54 first thing we have to do in our body
212:56 request over to OpenAI is we have to
212:58 send over the image to edit. So that's
213:00 going to be in a field called image. And
213:02 then we're sending over the actual
213:03 photo. So what I'm going to do is I'm
213:05 going to click on send body. I'm going
213:07 to use form data. And now we can set up
213:10 the different names and values to send
213:12 over. So the first thing is we're going
213:13 to send over this image right here on
213:15 the lefth hand side. And this is in a
213:16 field called data. And it's binary. So,
213:18 I'm going to choose instead of form
213:19 data, I'm going to send over an NAN
213:21 binary file. The name is going to be
213:23 image because that's what it said in the
213:24 documentation. And the input data field
213:26 name is data. So, I'm just going to copy
213:28 that, paste it in there. And this
213:30 basically means, okay, we're sending
213:32 over this picture. The next thing we
213:34 need to send over is a prompt. So, the
213:36 name of this field is going to be
213:37 prompt. I'm just going to copy that, add
213:39 a new parameter, and call it prompt. And
213:42 then for the value, we want to send over
213:43 the prompt that we had our AI agent
213:45 write. So, I'm going to click into
213:46 schema and I'm just going to drag over
213:47 the output from the AI agent right
213:49 there. And now that's an expression. So,
213:51 the next thing we want to send over is
213:53 what model do we want to use? Because if
213:54 we don't put this in, it's going to
213:56 default to dolly 2, but we want to use
213:58 gpt-image- one. So, I'm going to copy
214:01 GPT- image- one. We're going to come
214:04 back into here, and I'm going to paste
214:05 that in as the value, but then the name
214:08 is model because, as you can see in
214:09 here, right there, it says model. So
214:11 hopefully you guys can see that when
214:13 we're sending over an API call, we just
214:15 have all of these different options
214:16 where we can sort of tweak different
214:18 settings to change the way that we get
214:20 the output back. And then you have some
214:22 other options, of course, like quality
214:23 or size. But right now, we're just going
214:25 to leave all that as default and just go
214:27 with these three things to keep it
214:28 simple. And I'm going to hit test step
214:30 and we'll see if this is working. Okay,
214:32 never mind. I got an error and I was
214:34 like, okay, I think I did everything
214:35 right. The reason I got the error is
214:36 because I don't have any more credits.
214:38 So, if you get this error, go add some
214:40 credits. Okay, so added more credits.
214:42 I'm going to try this again and I'll
214:43 check back in. But before I do that, I
214:45 wanted to say me clearly, I've been like
214:48 spamming this thing with creating images
214:50 cuz it's so cool. It's so fun. But
214:52 everyone else in the world has also been
214:53 doing that. So, if you're ever getting
214:55 some sort of like errors where it's like
214:56 a 500 type of error where it means like
214:58 something's going on on the server side
215:00 of things or you're seeing like some
215:02 sort of rate limit stuff, keep in mind
215:04 that there's there's a limit on how many
215:06 images you can send per minute. I don't
215:07 think that's been clearly defined on
215:09 GPT- image-1. But also, if the OpenAI
215:13 server is receiving way too many
215:14 requests, that is also another reason
215:16 why your request may be failing. So,
215:18 just keep that in mind. Okay, so now it
215:20 worked. We just got that back. But what
215:22 you'll notice is we don't see an image
215:23 here or like an image URL. So, what we
215:25 have to do is we have this base 64
215:27 string and we have to turn that into
215:30 binary data. So, what I'm going to do is
215:32 after this node, I'm going to add one
215:33 that says um convert to file. So we're
215:37 going to convert JSON data to binary
215:38 data and we're going to do B 64. So all
215:41 I have to do now is show this data on
215:43 the lefth hand side. Grab the base 64
215:45 string. And then when we hit test step,
215:47 we should get a binary file over here,
215:48 which if we click into it, this should
215:50 be our professional looking photo. Wow,
215:52 that looks great. It even got the
215:54 wording and like the same fonts right.
215:55 So that's awesome. And by the way, if we
215:58 click into the results of the create
216:00 image where we did the image edit, we
216:01 can see the tokens. And with this model,
216:04 it is basically $10 for a million input
216:06 tokens and $40 for a million output
216:09 tokens. So right here, you can see the
216:10 difference between our input and output
216:12 tokens. And this one was pretty cheap. I
216:13 think it was like 5 cents. Anyways, now
216:15 that we have that image right here as
216:16 binary data, we need to turn that into a
216:19 video using an API called Runway. And so
216:21 if we go into Runway and we go first of
216:23 all, let's look at the price. For a
216:25 5second video, 25 cents. For a 10-second
216:27 video, 50 cents. So that's the one we're
216:28 going to be doing today. But if we go to
216:30 the API reference to read how we can
216:32 turn an image into a video, what we need
216:34 to look at is how we actually send over
216:36 that image. And what we have to do here
216:38 is send over an HTTPS URL of the image.
216:42 So we somehow have to get this binary
216:43 data in NADN to a public image that
216:46 runway can access. So the way I'm going
216:48 to be doing that is with this API that's
216:50 free called image BB. And um it's a free
216:53 image hosting service. And what we can
216:55 do is basically just use its API to send
216:57 over the binary data and we'll get back
216:59 a public URL. So come here, make a free
217:02 account. You'll grab your API key from
217:03 up top. And then we basically have
217:05 here's how we set this up. So what I'm
217:07 going to do is I'm going to copy the
217:08 endpoint right there. We're going to go
217:10 back into naden and I'm going to add an
217:12 HTTP request. And let me just configure
217:15 this up. We'll put it over here just to
217:16 keep everything sort of square. But now
217:18 what I'm going to do in here is paste
217:20 that endpoint in as our URL. You can
217:22 also see that it says this call can be
217:24 done using post or git. But since git
217:26 requests are limited by the max amount
217:28 of length, you should probably do post.
217:29 So I'm just going to go back in here and
217:30 change this to a post. And then there
217:32 are basically two things that are
217:33 required. The first one is our API key.
217:35 And then the second one is the actual
217:37 image. Anyways, this documentation is
217:39 not super intuitive. I can sort of tell
217:41 that this is a query parameter because
217:43 it's being attached at the end of the
217:45 endpoint with a question mark and all
217:46 this kind of stuff. And that's just
217:47 because I've looked at tons of API
217:49 documentation. So, what I'm going to do
217:51 is go into nit. We're going to add a
217:53 generic credential type. It's going to
217:55 be a query off. Where where was query?
217:57 There we go. And then you can see I've
217:58 already added my image BB. But all
218:00 you're going to do is you would add the
218:02 name as a key. And then you would just
218:03 paste in your API key. And that's it.
218:05 And now we've authenticated ourselves to
218:07 the service. And then what's next is we
218:09 need to send over the image in a field
218:10 called image. So I'm going to go back in
218:12 here. I'm going to send over a body
218:14 because this allows us to actually send
218:15 over n binary fields. And I'm not going
218:18 to do n binary. I'm going to do form
218:20 data because then we can name the field
218:21 we're sending over. Like I said, not
218:23 going to deep dive into how that all
218:24 works, but the name is going to be image
218:26 and then the input data field name is
218:28 going to be data because that's how it's
218:30 seen over here. And this should be it.
218:32 So, real quick, I'm just going to change
218:33 this to get URL. And then we're going to
218:36 hit test step, which is going to send
218:37 over that binary data to image BB. And
218:40 it hopefully should be sending us back a
218:42 URL. And it sent back three of them. I'm
218:44 going to be using the middle one that's
218:45 just called URL because it's like the
218:47 best size and everything. You can look
218:48 at the other ones if you want on your
218:50 end, but this one is going to load up
218:52 and we should see it's the image that we
218:54 got generated for us. It takes a while
218:55 to load up on that first time, but as
218:57 you can see now, it's a publicly
218:58 accessible URL and then we can feed it
219:00 into runway. So that's exactly our next
219:03 step. We're going to add another request
219:05 right here. It's going to be an HTTP and
219:07 this one we're going to configure to hit
219:08 runway. So here's a good example of we
219:11 can actually use a curl command. So I'm
219:12 going to click on copy over here when
219:14 I'm in the runway. Generate a video from
219:16 image. Come back into Naden, hit import
219:19 curl, and paste that in there and hit
219:21 import. And this is going to basically
219:22 configure everything we need. We just
219:24 have to tweak a few things. Typically,
219:26 most API documentation nowadays will
219:27 have a curl command. The edit image one
219:29 that we set up earlier was just a little
219:31 broken. Imag is just a free service, so
219:33 sometimes they don't always. But let's
219:35 configure this node. So, the first thing
219:37 I see is we have a header off right
219:39 here. And I don't want to send it like
219:40 this. I want to send it up as a generic
219:42 type so I can save it. Otherwise, you'd
219:44 have to go get your API key every time
219:45 you wanted to use Runway. So, as you can
219:47 see, I've already set up my Runway API
219:49 key. So, I have it plugged in, but what
219:51 you would do is you'd go get your API
219:53 key from Runway. And then you'd see,
219:55 okay, how do we actually send over
219:56 authentication? It comes through with
219:58 the name authorization. And then the
220:00 header is bearer space API key. So,
220:03 similar to the last one. And then that's
220:05 all you would do in here when you're
220:06 setting up your runway credential.
220:07 Authorization bearer space my API key.
220:11 And then because we have ourselves
220:12 authenticated up here, we can flick off
220:14 that headers. And all we have to do now
220:15 is configure the actual body. Okay, so
220:17 first things first, what image are we
220:19 sending over to get turned into a video
220:21 in that name prompt image? We're going
220:23 to get rid of that value. And I'm just
220:24 going to drag in the URL that we wanted
220:27 that we got from earlier, which was that
220:28 picture I s I showed you guys. So now
220:30 runway sees that image. Next, we have
220:33 the seed, which if you want to look at
220:34 the documentation, you can play with it,
220:36 but I'm just going to get rid of that.
220:37 Then we have the model, which we're
220:38 going to be using, Gen 4 Turbo. We then
220:41 have the prompt text. So, this is where
220:42 we're going to get rid of this. And
220:44 you're going to go back to that PDF you
220:46 downloaded from my free school, and
220:47 you're going to paste this prompt in
220:49 there. So, this prompt basically gives
220:51 us that like 3D spinning effect where it
220:53 just kind of does a slow pan and a slow
220:55 rotate. And that's what I was looking
220:56 for. If you're wanting some other type
220:58 of video, then you can tweak that
220:59 prompt, of course. For the duration, if
221:02 you look in the documentation, it'll say
221:04 the duration only basically allows five
221:06 or 10. So, I'm just going to change this
221:08 one to 10. And then the last one was
221:10 ratio. And I'm just going to make the
221:11 square. So here are the accepted ratio
221:13 values. I'm going to copy 960 by 960.
221:16 And we're just going to paste that in
221:17 right there. And actually before we hit
221:19 test step, I've realized that we're
221:20 missing something here. So back in the
221:22 documentation, we can see that there's
221:24 one thing up here which is required,
221:25 which is a header. X-runway- version.
221:28 And then we need to set the value to
221:30 this. So I'm going to copy the header.
221:33 And we have to enable headers. I I
221:35 deleted it earlier, but we're going to
221:36 enable that. So we have the version. And
221:37 then I'm just going to go copy the value
221:38 that it needs to be set to and we'll
221:41 paste that in there as the value.
221:42 Otherwise, this would not have worked.
221:44 Okay, so that should be configured. But
221:46 before we test it out, I want to show
221:48 you guys how I set up the polling flow
221:49 like this that you saw in the demo. So
221:52 what we're going to do here is we need
221:54 to go see like, okay, once we send over
221:57 our request right here to get a video
221:59 from our image, it's going to return an
222:01 ID and that doesn't mean anything to us.
222:03 So what we have to do is get our task.
222:06 So that is the basically we send over
222:07 the ID that it gives us and then it'll
222:10 come back and say like the status equals
222:12 pending or running or we'll say
222:14 completed. So what I'm going to do is
222:15 copy this curl command for getting task
222:18 details. We're going to hook it up to
222:20 this node as an HTTP request. We're
222:23 going to import that
222:24 curl. Now that's pretty much set up. We
222:27 have our authorization which I'm going
222:28 to delete that because as you know we
222:30 just configured that earlier as a header
222:32 off. So, I'm just going to come in here
222:33 and grab my Runway API key. There it is.
222:37 I couldn't find it for some reason. Um,
222:39 we have the version set up. And now all
222:41 we have to do is drag in the actual ID
222:43 from the previous one. So, real quick,
222:45 I'm just going to make this an
222:45 expression. Delete ID. And now we're
222:48 pretty much set up. So, first of all,
222:50 I'm going to test this one, which is
222:51 going to send off that request to runway
222:53 and say, "Hey, here's our image. Here's
222:54 the prompt. Make a video out of it." And
222:56 as you can see, we got back an ID. Now
222:59 I'm going to use this next node and I'm
223:01 going to drag in that ID from earlier.
223:03 And now it's saying, okay, we're going
223:04 to check in on the status of this
223:06 specific task. And if I hit test step,
223:08 what we're going to see is that it's not
223:09 yet finished. So it's going to come back
223:11 and say, okay, status of this run or
223:13 status of this task is running. So
223:15 that's why what I'm going to do is add
223:18 if. And this if is going to be saying,
223:20 okay, does this status field right here,
223:24 does that equal running in all caps?
223:26 Because that's what it equals right now.
223:28 If yes, what we're going to do is we are
223:31 going to basically wait for a certain
223:32 amount of time. So here's the true
223:34 branch. I'm going to wait and let's just
223:36 say it's 5 seconds. So I'll just call
223:38 this five seconds. I'm going to wait for
223:41 5 seconds and then I'm going to come
223:42 back here and try again. So as you saw
223:44 in the demo, it basically tried again
223:46 like seven or eight times. And this just
223:48 ensures that it's never going to move on
223:50 until we actually have a finished photo.
223:53 So what you could also do is basically
223:54 say does status equal completed or
223:56 whatever it means when it completes.
223:57 That's another way to do it. You just
223:59 have to be careful to make sure that
224:00 whatever you're setting here as the
224:01 check is always 100% going to work. And
224:05 then what you do is you would continue
224:07 the rest of the logic down this path
224:08 once that check has been complete. And
224:10 then of course you probably don't want
224:11 to have this check like 10 times every
224:13 single time. So what you would do is
224:14 you'd add a weight step here. And once
224:17 you know about how long it takes, you'd
224:18 add this here. So last time I had it at
224:21 30 seconds and it waited like eight
224:22 times. So let's just say I'm going to
224:23 wait 60 seconds here. So then when this
224:26 flow actually runs, it'll wait for a
224:27 minute, check. If it's still not done,
224:29 it'll continuously loop through here and
224:30 wait 5 seconds every time until we're
224:32 done. Okay, there we go. So now status
224:34 is succeeded. And what I'm going to do
224:36 is just view this video real quick.
224:37 Hopefully this one came out nicely.
224:39 Let's take a
224:41 look. Wow, this is awesome. Super clean.
224:45 It's rotating really slowly. It's a full
224:46 10-second video. You can tell it's like
224:49 a 3D image. This is awesome. Okay, cool.
224:52 So now if we test this if branch, we'll
224:54 see that it's going to go down the other
224:55 one which is the false branch because
224:57 it's actually completed. And now we can
224:59 with confidence shoot off the email with
225:01 our materials. So I'm going to grab a
225:03 Gmail node. I'm going to click send a
225:04 message. And we are going to have this
225:07 configured hopefully because you've
225:08 already set up your Google stuff. And
225:09 now who do we send this to? We're going
225:11 to go grab that email from the original
225:13 form submission which is all the way
225:14 down here. We're going to make the
225:16 subject, which I'm just going to say
225:19 marketing materials, and then a colon.
225:22 And we'll just drag in the actual title
225:24 of the product, which in here was
225:26 cologne. I'm changing the email type to
225:28 text just because I want to. Um, we're
225:30 going to make the body an expression.
225:32 And we're just going to say like,
225:35 hey, here is your photo. And obviously
225:39 this can be customized however you want.
225:41 But for the photo, what we have to do is
225:43 grab that public URL that we generated
225:45 earlier. So right here there is the
225:47 photo URL. Here is your video. And for
225:51 the video, we're going to drag in the
225:52 URL we just got from the output of that
225:55 um runway get task check. So there is
225:58 the video URL. And then I'm just going
226:00 to say cheers. Last thing I want to do
226:02 is down here append edit an attribution
226:05 and turn that off. This just ensures
226:07 that the email doesn't say this email
226:09 was sent by NAN. And now if we hit test
226:12 step right here, this is pretty much the
226:13 end of the process. And we can go ahead
226:15 and check. Uh-oh. Okay, so not
226:18 authorized. Let me fix that real quick.
226:19 Okay, so I just switched my credential
226:20 because I was using one that had
226:21 expired. So now this should go through
226:23 and we'll go take a look at the email.
226:25 Okay, so did something wrong. I can
226:27 already tell what happened is this is
226:28 supposed to be an expression and
226:29 dynamically come through as the title of
226:31 the product, but we accidentally somehow
226:33 left off a curly brace. So, if I come
226:35 back into here and and add one more
226:37 curly brace right here to the
226:38 description or sorry, the subject now,
226:40 we should be good. I'll hit test step
226:42 again. And now we'll go take a look at
226:44 that email. Okay, there we go. Now, we
226:46 have the cologne and we have our photo
226:48 and our video. So, let's click into the
226:49 video real
226:52 quick. I'm just so amazed. This is this
226:54 is just so much fun. It look the the
226:55 lighting and the the reflections. It's
226:57 it's all just
226:59 perfect. And then we'll click into the
227:01 photo just in case we want to see the
227:03 actual image. And there it is. This also
227:05 looks awesome. All right, so that's
227:07 going to do it for today's video. I hope
227:09 you guys enjoyed this style of walking
227:10 step by step through some of the API
227:12 calls and sort of my thought process as
227:14 to how I set up this workflow. Okay, at
227:16 this point I think you guys probably
227:17 have a really good understanding of how
227:19 these AI workflows actually function and
227:22 you're probably getting a little bit
227:22 antsy and want to build an actual AI
227:24 agent. Now, so we're about to get into
227:26 building your first AI agent step by
227:28 step. But before that, just wanted to
227:30 drive home the concept of AI workflows
227:32 versus AI agents one more time and the
227:35 benefits of using workflows. But of
227:37 course, there are scenarios where you do
227:38 need to use an agent. So, let's break it
227:40 down real quick. Everyone is talking
227:42 about AI agents right now, but the truth
227:44 is most people are using them completely
227:46 wrong and admittedly myself included.
227:48 It's such a buzzword right now and it's
227:50 really cool in n to visually see your
227:52 agents think about which tools they have
227:54 and which ones to call. So, a lot of
227:56 people are just kind of forcing AI
227:57 agents into processes where you don't
227:59 really need it. But in reality, a simple
228:01 AI workflow is not only going to be
228:03 easier to build, it's going to be more
228:04 cost- effective and also more reliable
228:06 in the long run. If you guys don't know
228:07 me, my name's Nate. And for a while now,
228:09 I've been running an agency where we
228:10 deliver AI solutions to clients. And
228:12 I've also been teaching people from any
228:14 background how to build out these things
228:15 practically and apply them to their
228:17 business through deep dive courses as
228:19 well as live calls. So, if that sounds
228:21 interesting to you, definitely check out
228:22 the community with the link in the
228:23 description. But let's get into the
228:24 video. So, we're going to get into Naden
228:26 and I'm going to show you guys some
228:27 mistakes of when I've built agents when
228:29 I should have been building AI
228:30 workflows. But before that, I just
228:31 wanted to lay out the foundations here.
228:34 So, we all know what chatbt is. At its
228:35 core, it's a large language model that
228:37 we talk to with an input and then it
228:39 basically just gives us an output. So,
228:40 if we wanted to leverage chatbt to help
228:42 us write a blog post, we would ask it to
228:44 write a blog post about a certain topic.
228:46 It would do that and then it would give
228:47 us the output which we would then just
228:48 copy and paste somewhere else. And then
228:50 came the birth of AI agents, which is
228:52 when we actually were able to give tools
228:54 to our LLM so that they could not only
228:56 just generate content for us, but they
228:57 could actually go post it or go do
228:59 whatever we wanted to do with it. AI
229:01 agents are great and there's definitely
229:02 a time and a place for them because they
229:03 have different tools and basically the
229:05 agent will use its brain to understand,
229:06 okay, I have these three tools based on
229:08 what the user is asking me. Do I call
229:10 this one and then do I output or do I
229:12 call this one then this one or do I need
229:14 to call all three simultaneously? It has
229:16 that option and it has the variability
229:18 there. So, this is going to be a
229:19 non-deterministic workflow. But the
229:22 reality is most of the processes that
229:23 we're trying to enhance for our clients
229:26 are pretty deterministic workflows that
229:28 we can build out with something more
229:29 linear where we still have the same
229:30 tools. We're still using AI, but we have
229:33 everything going step one, step two,
229:34 step three, step four, step five, step
229:36 six, which is going to reduce the
229:38 variability there. It's going to be very
229:40 deterministic and it's going to help us
229:42 with a lot of things. So stick with me
229:43 because I'm going to show you guys an AI
229:45 agent video that I made on YouTube a few
229:47 months back and I started re-evaluating
229:49 it. Like why would I ever build out the
229:50 system like that? It's so inefficient.
229:52 So I'll show you guys that in a sec. But
229:54 real quick, let's talk about the pros of
229:55 AI workflows over AI agents. And I
229:57 narrowed it down to four main points.
229:59 The first one is reliability and
230:00 consistency. One of the most important
230:02 concepts of building an effective AI
230:04 agent is the system prompt because it
230:05 has to understand what its tools are,
230:07 when to use each one, and what the end
230:08 goal is. and it's on its own to figure
230:10 out which ones do I need to call in
230:12 order to provide a good output. But with
230:14 a workflow, we're basically keeping it
230:15 on track and there's no way that the
230:17 process can sort of deviate from the
230:18 guardrails that we've set up because it
230:20 has to happen in order and it can't
230:22 really go anywhere else. So this makes
230:24 systems more reliable because there's
230:25 never going to be a transfer of data
230:27 between workflows where things may get
230:28 messed up or incorrect mappings being
230:30 sent across, you know, agent to a
230:32 different agent or agent to tool. We're
230:34 just basically able to go through the
230:36 process linearly. So the next one is
230:38 going to be cost efficiency. When we're
230:40 using an agent and it has different
230:41 tools, every time it hits a tool, it's
230:44 going to go back to its brain. It's
230:45 going to rerun through its system prompt
230:46 and it's going to think about what is my
230:48 next step here. And every time you're
230:49 accessing that AI agent's brain, it
230:51 costs you money. So if we're able to
230:53 eliminate that aspect of decision-m and
230:55 just say, okay, you you finished step
230:57 two, now you have to go on to step
230:58 three. There's no decision to be made.
231:00 We don't have to make that extra API
231:02 call to think about what comes next, and
231:04 we're saving money. Number three is
231:06 easier debugging and maintenance. When
231:08 we have an AI workflow, we can see
231:10 exactly which node errors. We can see
231:12 exactly what mappings are incorrect and
231:13 what happened here. Whereas with an AI
231:16 agent workflow, it's a little bit
231:17 tougher because there's a lot of
231:18 manipulating the system prompt and
231:20 messing with different tool
231:21 configurations. And like I said, there's
231:23 data flowing between agent to tool or
231:25 between agent to subworkflow. And that's
231:27 where a lot of things can happen that
231:28 you don't really have full visibility
231:30 into. And then the final one is
231:31 scalability. kind of backpacks right off
231:33 of number three. But if you wanted to
231:35 add more nodes and more functionality to
231:36 a workflow, it's as simple as, you know,
231:38 plugging in a few more blocks here and
231:40 there or adding on to the back. But when
231:41 you want to increase the functionality
231:43 of an AI agent, you're probably going to
231:44 have to give it more tools. And when you
231:46 give it more tools, you're going to have
231:47 to refine and add more lines to the
231:50 system prompt, which could work great
231:52 initially, but then previous
231:53 functionality, the first couple tools
231:55 you added, those might stop working or
231:57 those may become less consistent. So
231:59 basically, the more control that we have
232:00 over the entire workflow, the better. AI
232:02 is great. There are times when we need
232:04 to make decisions and we need that
232:05 little bit of flexibility. But if a
232:07 decision doesn't have to be made, why
232:09 would we leave that up to the AI to
232:10 hallucinate 5 or 10% of the time when we
232:13 could basically say, "Hey, this is going
232:14 to be 100% consistent." Anyways, I've
232:16 made a video that talks a little bit
232:17 more about this stuff, as well as other
232:19 things I've learned over the first 6
232:20 months of building agents. If you want
232:22 to watch that, I'll link it up here. But
232:23 let's hop into n and take a look at some
232:25 real examples. Okay, so the first
232:27 example I want to share with you guys is
232:29 a typical sort of rag agent. And for
232:31 some reason it always seems like the
232:32 element of rag has to be associated with
232:34 an agent, but it really doesn't. So what
232:36 we have is a workflow where we're
232:38 putting a document from Google Drive
232:39 into Pine Cone. We have a customer
232:41 support agent and then we have a
232:42 customer support AI workflow. And both
232:44 of the blue box and the green box, they
232:46 do the exact same thing, but this one's
232:47 going to be more efficient and we also
232:49 have more control. So let's break this
232:50 down. Also, if you want to download this
232:52 template to play around with, you can
232:53 get it for free if you go to my free
232:54 school community. The link for that's
232:55 down in the description as well. You'll
232:57 come into here, click on YouTube
232:58 resources, and click on the post
233:00 associated with this video. And then the
233:01 workflow will be right here for you to
233:03 download. Okay, so anyways, here is the
233:05 document that we're going to be looking
233:06 at. It has policy and FAQ information.
233:08 We've already put it into Pine Cone. As
233:10 you can see, it's created eight vectors.
233:12 And now what we're going to do is we're
233:13 going to fire off an email to the
233:14 customer support agent to see how it
233:16 handles it. Okay, so we just sent off,
233:18 do you offer price matching or bulk
233:20 discounts? We'll come back into the
233:21 workflow, hit run, and we should see the
233:22 customer support agent is hitting the
233:24 vector database, and it's also hitting
233:26 its reply email tool. But what you'll
233:28 notice is that it hit its brain. So,
233:29 Google Gemini 2.0 Flash in this case,
233:32 not a huge deal because it's free. But
233:33 if you were using something else, it's
233:35 going to have hit that API three
233:36 different times, which would be three
233:37 separate costs. So, let's check and see
233:40 if it did this correctly. So, in our
233:42 email, we got the reply, "We do not
233:43 offer price matching currently, but we
233:45 do run promotions and discounts
233:46 regularly. Yes, bulk orders may qualify
233:48 for a discount. Please contact our sales
233:50 team at salestechhaven.com for
233:52 inquiries. So, let's go validate that
233:54 that's correct. So, in the FAQ section
233:56 of this doc, we have that they don't
233:57 offer price matching, but they do run
233:58 promotions and discounts regularly. And
234:00 then for bulk discounts, um you have to
234:02 hit up the sales team. So, it answered
234:04 correctly. Okay. So, now we're going to
234:06 run the customer support AI workflow
234:08 down here. It's going to grab the email.
234:09 It's going to search Pine Cone. It's
234:11 going to write the email. I'll explain
234:12 what's going on here in a sec. And then
234:13 it responds to the customer. So, there's
234:15 four steps here. It's going to be an
234:16 email trigger. It's going to search the
234:18 knowledge base. It's going to write the
234:19 email and then respond to the customer
234:21 in an email. So, why would we leave that
234:23 up to the agent to decide what it needs
234:25 to do if it's always going to happen in
234:26 those four steps every time? All right,
234:28 here's the email we just got in reply.
234:30 As you can see, this is the one that the
234:31 agent wrote, and this one looks a lot
234:32 better. Hello, thank you for reaching
234:34 out to us. In response to your inquiry,
234:36 we currently do not offer price
234:37 matching. However, we do regularly run
234:39 promotions and discounts, so be sure to
234:41 keep an eye out for those. That's
234:42 accurate. Regarding bulk discounts, yes,
234:45 they may indeed qualify for a discount.
234:47 So reach out to our sales team. If you
234:48 have any other questions, please feel
234:50 free to reach out. Best regards, Mr.
234:51 Helpful, TechHaven. And obviously, I
234:53 told it to sign off like that. So, now
234:56 that we've seen that, let's actually
234:57 break down what's going on. So, it's the
234:59 same trigger. You know, we're getting an
235:00 email, and as you can see, we can find
235:02 the text of the email right here, which
235:03 was, "Do you guys offer price matching
235:05 or bulk discounts?" We're feeding that
235:07 into a pine cone node. So, if you guys
235:09 didn't know, you don't even need these
235:10 to be only tools. You can have them just
235:12 be nodes. where we're searching for the
235:14 prompts that is, do you guys offer price
235:16 matching or bulk discounts? And maybe
235:18 you might want an AI step between the
235:20 trigger and the search to maybe like
235:22 formulate a query out of the email if
235:24 the email is pretty long. But in this
235:25 case, that's all we did. And now we can
235:27 see we got those four vectors back, same
235:29 way we would have with the agent. But
235:31 what's cool is we have a lot more
235:32 control over it. So as you can see, we
235:35 have a vector and then we have a score,
235:36 which basically ranks how relevant it
235:38 the vector was to the query that we sent
235:40 off. And so we have some pretty low ones
235:42 over here, but what we can do is say,
235:44 okay, we only want to keep if the score
235:46 is greater than 04. So it's only going
235:48 to be keeping these two, as you can see,
235:50 and it's getting rid of these two that
235:51 aren't super relevant. And this is
235:53 something that's a lot easier to control
235:54 in this linear flow compared to having
235:56 the agent try to filter through vector
235:59 results up here. Anyways, then we're
236:00 just aggregating however many results it
236:02 pulls back. if it's four, if it's three,
236:04 or if it's just one, it's still just
236:06 going to aggregate them together so that
236:07 we can feed it into our OpenAI node
236:09 that's going to write the email. So
236:11 basically, in the user prompt, we said,
236:12 "Okay, here's the customer inquiry.
236:14 Here's the original email, and here's
236:15 the relevant knowledge that we found.
236:17 All you have to do now is write an
236:18 email." And so by giving this AI node
236:20 just one specific goal, it's going to be
236:22 more quality and consistent with its
236:24 outputs rather than we gave the agent
236:26 multiple jobs. It had to not only write
236:28 the email, but it also had to figure out
236:30 how to search through information and
236:31 figure out what the next step was. So
236:33 this node, it only has to focus on one
236:35 thing. It has the knowledge handed to it
236:37 on a silver platter to write the email
236:38 with. And basically, we said, you're Mr.
236:40 Helpful, a customer support rep for Tech
236:42 Haven. Your job is to respond to
236:44 incoming customer emails with accurate
236:45 information from the knowledge base. You
236:47 must only answer using relevant
236:48 knowledge provided to you. Don't make
236:50 anything up. We gave it the tone and
236:52 then we said only output the body in a
236:53 clean format. it outputs that body and
236:56 then all it had to do is map in the
236:57 correct message ID and the correct
236:59 message content. Simple as that. So, I
237:02 hope this makes sense. Obviously, it's a
237:03 lot cooler to watch the agent do
237:05 something like that up here, but this is
237:06 basically the exact same flow and I
237:08 would argue that it's going to be a lot
237:10 better, more consistent, and cheaper.
237:12 Okay, so now to show an example where I
237:14 released this as a YouTube video and a
237:15 couple weeks later I was like, why did I
237:17 do it like that? So, what we have here
237:18 is a technical analyst. And so basically
237:21 we're talking to it through Telegram and
237:23 it has one tool which is basically going
237:25 to get a chart image and then it's going
237:27 to analyze the chart image and then it
237:28 sends it back to us in Telegram. And
237:30 this is the workflow that it's actually
237:31 calling right here where we're making an
237:33 HTTP request to chart- image. We're
237:35 getting the chart, downloading it,
237:37 analyzing the image, sending it back,
237:38 and then responding back to the agent.
237:40 So there's basically like two transfers
237:42 of data here that we don't need because
237:44 as you can see down here, we have the
237:45 exact same process as one simple AI
237:49 workflow. So there's going to be much
237:50 much less room for error here. But first
237:52 of all, let's demo how this works and
237:54 then we'll demo the actual AI workflow.
237:56 Okay, so it should be listening to us
237:57 now. I'm going to ask it to analyze
237:59 Microsoft. And as you can see, it's now
238:00 hitting that tool. We won't see this
238:02 workflow actually in real time just
238:04 because it's like calling a different
238:06 execution, but this is the workflow that
238:07 it's calling down here. I can actually
238:08 just it's basically calling this right
238:10 here. Um, so what it's going to do is
238:12 it's going to send us an image and then
238:14 a second or two later it's going to send
238:16 us an actual analysis. So there is
238:18 Microsoft's stock chart and now it's
238:20 creating that analysis as you can see
238:21 right up here and then it's going to
238:22 send us that analysis. We just got it.
238:24 So if you want to see the full video
238:26 that I made on YouTube, I'll I'll tag it
238:28 right up here. But not going to dive too
238:29 much into what's actually happening. I
238:31 just want to prove that we can do the
238:32 exact same thing down here with a simple
238:35 workflow. Although right here, I did
238:36 evolve this workflow a little bit. So
238:38 it's it's not only looking at NASDAQ,
238:39 but it can also choose different
238:41 exchanges and feed that into the API
238:43 call. But anyways, let's make this
238:45 trigger down here active and let's just
238:47 show off that we can do the exact same
238:49 thing with the workflow and it's going
238:51 to be better. So, test workflow. This
238:55 should be listening to us. Now, I'm just
238:56 going to ask it to um we'll do a
238:58 different one. Analyze uh Bank of
239:00 America. So, now it's getting it. It is
239:02 going to be downloading the chart.
239:04 Actually, want to open up Telegram so we
239:05 can see downloading the chart, analyzing
239:07 the image. It's going to send us that
239:08 image and then pretty much immediately
239:11 after it should be able to send us that
239:12 analysis. So we don't have that awkward
239:15 2 to 5 second wait. Obviously we're
239:17 waiting here. But as soon as this is
239:19 done, we should get the both the image
239:20 and the text simultaneously. There you
239:22 go. And so you can see the results are
239:24 basically the same. But this one is just
239:27 going to be more consistent. There's no
239:28 transfer of data between workflow.
239:30 There's no need to hit an AI model to
239:31 decide what tool I need to use. It is
239:33 just going to be one seamless flow. You
239:36 can al also get this workflow in the
239:37 free school community if you want to
239:38 play around with it. Just wanted to
239:39 throw that out there. Anyways, that's
239:41 going to wrap us up here. I just wanted
239:42 to close off with this isn't me bashing
239:45 on AI agents. Well, I guess a little bit
239:46 it was. AI agents are super powerful.
239:49 They're super cool. It's really
239:50 important to learn prompt engineering
239:52 and giving them different tools, but
239:54 it's just about understanding, am I
239:55 forcing an agent into something that
239:57 doesn't need it? Am I exposing myself to
239:59 the risk of lower quality outputs, less
240:02 consistency, more difficult time scaling
240:04 this thing? Things along those lines.
240:06 And so that's why I think it's super
240:07 important to get into something like
240:08 Excal wireframe out the solution that
240:11 you're looking to build. Understand what
240:12 are all the steps here. What are the
240:14 different API calls or different people
240:16 involved? What could happen here? Is
240:18 this deterministic or is there an aspect
240:20 of decision-m and variability here?
240:23 Essentially, is every flow going to be
240:24 the same or not the same? Cool. So now
240:27 that we have that whole concept out of
240:29 the way, I think it's really important
240:30 to understand that so that when you're
240:31 planning out what type of system you're
240:33 going to build, you're actually doing it
240:34 the right way from the start. But now
240:36 that we understand that, let's finally
240:38 set up our first AI agent together.
240:40 Let's move into that video. All right,
240:42 so at this point you guys are familiar
240:43 with Naden. You've built a few AI
240:45 workflows and now it's time to actually
240:47 build an AI agent, which gets even
240:49 cooler. So before we actually hop into
240:51 there and do that, just want to do a
240:52 quick refresher on this little diagram
240:54 we talked about at the beginning of this
240:55 video, which is the anatomy of an AI
240:57 agent. So we have our input, we have our
240:59 actual AI agent, and then we have an
241:01 output. The AI agent is connected to
241:03 different tools, and that's how it
241:04 actually takes action. And in order to
241:06 understand which tools do I need to use,
241:08 it will look at its brain and its
241:10 instructions. The brain comes in the
241:11 form of a large language model, which in
241:13 this video, we'll be using open router
241:15 to connect to as many different ones as
241:17 we want. and you guys have already set
241:19 up your open router credentials. Then we
241:20 also have access to memory which I will
241:22 show you guys how we're going to set up
241:23 in nadn. Then finally it uses its
241:26 instructions in order to understand what
241:27 to do and that is in the form of a
241:29 system prompt which we will also see in
241:31 naden. So all of these elements that
241:33 we've talked about will directly
241:34 translate to something in nen and I will
241:37 show you guys and call out exactly where
241:38 these are so there's no confusion. So
241:41 we're going to hop in nitn and you guys
241:43 know that a new workflow always starts
241:45 with a trigger. So, I'm going to hit tab
241:46 and I'm going to type in a chat trigger
241:49 because we want to just basically be
241:50 able to talk to our AI agent right here
241:52 in the native Nadm chat. So, there is
241:55 our trigger and what I'm going to do is
241:57 click the plus and add an AI agent right
241:59 after this trigger so we can actually
242:00 talk to it. And so, this is what it
242:02 looks like. You know, we have our AI
242:03 agent right here, but I'm going to click
242:04 into it so we can just talk about the
242:06 difference between a user message up
242:07 here and a system message that we can
242:09 add down here. So going back to the
242:11 example with chatbt and with our diagram
242:15 when we're talking to chat gbt in our
242:16 browser every single time we type and
242:18 say something to chatbt that is a user
242:21 message because that message coming in
242:23 is dynamic every time. So you can see
242:25 right here the source for the prompt
242:27 that the AI agent will be listening for
242:29 as if it was chatbt is the connected
242:31 chat trigger node. So we're set up right
242:33 here and the agent will be reading that
242:35 every time. If we were feeding in
242:37 information to this agent that wasn't
242:39 coming from the chat message trigger,
242:40 we'd have to change that. But right now,
242:42 we're good. And if we go back to our
242:43 diagram, this is basically the input
242:45 that we're feeding into the AI agent.
242:46 So, as you can see, input goes into the
242:48 agent. And that's exactly what we have
242:50 right here. Input going into the agent.
242:53 And then we have the system prompt. So,
242:54 I'm going to click back into the agent.
242:56 And we can see right here, we have a
242:57 system message, which is just telling
242:58 this AI agent, you are a helpful
243:00 assistant. So, right now, we're just
243:02 going to leave it as that. And back in
243:03 our diagram that is right here, its
243:05 instructions, which is called a system
243:07 prompt. So the next thing we can see
243:08 that we need is we need to give our AI
243:10 agent a brain, which will be a large
243:12 language model and also memory. So I'm
243:14 going to flick back into N. And you can
243:16 see we have two options right here. The
243:18 first one is chat model. So I'm first of
243:19 all just going to click on the plus for
243:21 chat model. I'm going to choose open
243:22 router. And we've already connected to
243:24 open router. And now I just get to
243:26 choose from all of these different chat
243:27 models to use. So I'm just going to go
243:29 ahead and choose a GBT 4.1 Mini.
243:34 And I'm just going to rename this node
243:35 GPT 4.1 mini just so we know which one
243:38 we're
243:41 using. Cool. So now we have our input,
243:43 our AI agent, and a brain. But let's
243:45 give it some memory real quick, which is
243:47 as simple as just clicking the plus
243:48 under memory. And I'm just going to for
243:50 now choose simple memory, which stores
243:52 it in and it end. There's no credentials
243:54 required. And as you can see, the
243:56 session ID is looking for the connected
243:58 chat trigger node. because we're using
244:00 the connected chat trigger node, we
244:01 don't have to change anything. We are
244:03 good to go. So, this is basically the
244:06 core part of the agent, right? So, what
244:07 I can do is I can actually talk to this
244:09 thing. So, I can say, "Hey," and we'll
244:10 see what it says back. It's going to use
244:12 its memory. It's going to um use its
244:15 brain to actually answer us. And it
244:16 says, "Hello, how can I assist you?" I
244:18 can say, "My name is Nate. I am 23 years
244:24 old." And now what I'm going to
244:25 basically test is that it's storing all
244:27 of this as memory and it's going to know
244:28 that. So now it says, "Nice to meet you,
244:30 Nate. How can I help you?" Now I'm going
244:31 to ask you, you
244:33 know, what's my name and how old am I?
244:38 So we'll send that off. And now it's
244:40 going to be able to answer us. Your name
244:41 is Nate and you are 23 years old. How
244:43 can I assist you further? So first of
244:45 all, the reason it's being so helpful is
244:47 because its system message says you're a
244:49 helpful assistant. The next piece would
244:51 be it's using its brain to answer us and
244:54 it's using its memory to make sure it's
244:55 not forgetting stuff about our current
244:57 conversation. So those are the three
245:00 parts right there. Input, AI agent,
245:02 brain, and instructions. And now it's
245:04 time to add the tools. So in this
245:07 example, we're going to build a super
245:08 simple personal assistant AI agent that
245:10 can do three things. It's going to be
245:12 able to look in our contact database in
245:15 order to grab contact information. with
245:17 that contact information. It's going to
245:18 be able to send an email and it's going
245:20 to be able to create a calendar event.
245:23 So, first thing we're going to do is
245:24 we're going to set up our contact
245:26 database. And what I'm going to do for
245:27 that is just I have this Google sheet.
245:29 Really simple. It just says name and
245:31 email. This could be maybe you have your
245:32 contacts in Google contacts. You could
245:34 connect that or an Air Table base or
245:36 whatever you want. This is just the
245:38 actual tool, the actual integration that
245:40 we want to make to our AI agent. So,
245:42 what I'm going to do is throw in a few
245:44 rows of example names and emails in
245:46 here. Okay. So, we're just going to
245:47 stick with these three. We've got
245:48 Michael Scott, Ryan Reynolds, and Oprah
245:50 Winfrey. And now, what we're going to be
245:51 able to do is have our AI agent look at
245:53 this contact database whenever we ask it
245:55 to send an email to someone or make a
245:57 calendar event with someone. If I go
245:59 back and add it in, the first thing we
246:00 have to do is add a tool to actually
246:02 access this Google sheet. So, I'm going
246:03 to click on tool. I'm going to type in
246:05 Google sheet. It's as simple as that.
246:07 And you can see we have a Google Sheets
246:08 tool. So, I'm going to click on that.
246:10 And now we have to set up our
246:11 credential. You guys have already
246:13 connected to Google Sheets in the
246:15 previous workflow, so it shouldn't be
246:16 too difficult. So choose your
246:17 credential. And then the first thing is
246:19 a tool description. What we're going to
246:20 do is we are going to just set this
246:22 automatically. And this basically
246:24 describes to the AI agent what does this
246:26 tool do. So we could set it manually and
246:28 describe ourselves, but if you just set
246:30 it automatically, the AI is going to be
246:32 pretty good at understanding what it
246:33 needs to do with this tool. The next
246:35 thing is a resource. So what are we
246:37 actually looking for? We're looking for
246:38 a sheet within a document, not an entire
246:40 document
246:41 itself. Then the operation is we want to
246:44 just get rows. So I'm going to leave it
246:45 all as that. And then what we need to do
246:47 is actually choose our document and then
246:49 the sheet within that document that we
246:50 want to look at. So for document, I'm
246:52 going to choose contacts. And for sheet,
246:54 there's only one. I'm just going to
246:56 choose sheet one. And then the last
246:57 thing I want to do is just give this
246:59 actual tool a pretty intuitive name. So
247:01 I'm just going to call this
247:03 contacts database. There you go. So now
247:06 it should be super clear to this AI
247:08 agent when to use this tool. We may have
247:09 to do some system prompting actually to
247:11 say like, hey, here are the different
247:12 tools you have. But for now, we're just
247:14 going to test it out and see if it
247:15 works. So what I'm going to do is open
247:17 up the chat and just ask it, can you
247:19 please get Oprah Winfreyy's contact
247:21 information. There we go. We'll send
247:23 that off and we will watch it basically
247:25 think. And then there we go. Boom. It
247:27 hit the Google Sheet tool that we wanted
247:29 it to. And if I open up the chat, it
247:30 says Oprah Winfreyy's contact
247:32 information is email opra winfrey.com.
247:35 If we go into the base, we can see that
247:37 is exactly what we put for her contact
247:39 information. Okay, so we've confirmed
247:41 that the agent knows how to use this
247:43 tool and that it can properly access
247:44 Google Sheets. The next step now is to
247:46 add another tool to be able to send
247:48 emails. So, I'm going to move this thing
247:49 over. I'm going to add another tool and
247:51 I'm just going to search for Gmail and
247:53 click on Gmail tool. Once again, we've
247:55 already covered credentials. So,
247:57 hopefully you guys are already logged in
247:58 there. And then what we need to do is
248:00 just configure the rest of the tool. So
248:02 tool description set automatically
248:04 resource message operation send and then
248:08 we have to fill out the two the subject
248:10 the email type and the message. What
248:12 we're able to do with our AI agents and
248:14 tools is something super super cool. We
248:17 can let our AI agent decide how to fill
248:19 out these three fields that will be
248:21 dynamic. And all I have to do is click
248:23 on this button right here to the right
248:24 that says let the model define this
248:26 parameter. So I'm going to click on that
248:27 button. And now we can see that it says
248:29 defined automatically by the model. So
248:32 basically if I said hey can you send an
248:33 email to Oprah Winfrey saying this um
248:36 and this it would then interpret our
248:39 message our user input and it would then
248:42 fill out who's this going to who's the
248:45 subject and who's the email. So I'll
248:46 show you guys an example of that. It's
248:47 super cool. So I'm just going to click
248:49 on this button for subject and also this
248:51 button for message. And now we can see
248:53 the actual AI use its brain to fill out
248:56 these three fields.
248:58 And then also I'm just going to change
248:59 the email type to text because I like it
249:01 how it comes through as text. So real
249:04 quick, just want to change this name to
249:06 send email. And all we have to do now is
249:08 we're going to chat with our agent and
249:10 see if it's able to send that email. All
249:12 right. So I'm sending off this message
249:13 that asks to send an email to Oprah
249:15 asking how she's doing and if she has
249:17 plans this weekend. And what happened is
249:19 it went straight to the send email tool.
249:21 And the reason it did that is because in
249:23 its memory, it remembered that it
249:25 already knows Oprah Winfreyy's contact
249:26 information. So if I open chat, it says
249:29 the email's been sent asking how she's
249:31 doing and if she has plans this weekend.
249:32 Is there anything else that you would
249:34 like to do? So real quick before we go
249:36 see if the email actually did get sent,
249:38 I'm going to click into the tool. And
249:39 what we can see is on this left hand
249:41 side, we can see exactly how it chose to
249:44 fill out these three fields. So for the
249:46 two, it put oprafree.com, which is
249:48 correct. For the subject, it put
249:50 checking in. And for the message, it put
249:52 hi Oprah. I hope this weekend finds you
249:54 well. How are you doing? Do you have any
249:55 plans? Best regards, Nate. And another
249:58 thing that's really cool is the only
250:00 reason that it signed off right here as
250:01 best regards Nate is because once again,
250:03 it used its memory and it remembers that
250:05 our name is Nate. That's how it filled
250:07 out those fields. Let me go over to my
250:09 email and we'll take a look. So, in our
250:11 sent, we have the checking in subject.
250:13 We have the message that we just read in
250:15 and it in. And then we have this little
250:17 thing at the bottom that says this email
250:18 was automatically sent by NADN. We can
250:20 easily turn that off if we go into NADN.
250:22 Open up the tool. We add an option at
250:25 the bottom that says append naden
250:26 attribution. And then we just turn off
250:28 the append naden attribution. And as you
250:30 can see if we click on add options,
250:31 there are other things that we can do as
250:33 well. Like we can reply to the sender
250:34 only. We can add a sender name. We can
250:36 add attachments. All this other stuff.
250:39 But at a high level and real quick
250:41 setup, that is the send email tool. And
250:42 keep in mind, we still haven't given our
250:44 agent any sort of system prompt besides
250:47 saying you're a helpful assistant. So,
250:48 super cool stuff. All right, cool. And
250:51 now for the last tool, what we want to
250:52 do is add
250:53 a create calendar event. So, I'm going
250:56 to search calendar and grab a Google
250:59 calendar node. We already should be set
251:01 up. Or if you're not, actually, all you
251:02 have to do is just create new credential
251:04 and sign in real quick because you
251:06 already went and created your whole
251:07 Google Cloud thing.
251:10 We're going to leave the description as
251:11 automatic. The resource is an event. The
251:13 operation is create. The calendar is
251:15 going to be one that we choose from our
251:17 account. And now we have a few things
251:19 that we want to fill out for this tool.
251:22 So basically, it's asking what time is
251:23 the event going to start and what time
251:24 is the event going to end. So real
251:26 quick, I'm just going to do the same
251:27 thing. I'm going to let the model decide
251:29 based on the way that we interact with
251:30 it with our input. And then real quick,
251:33 I just want to add one more field, which
251:34 is going to be a summary. And basically
251:36 whatever gets filled in right here for
251:38 summary is what's going to show up as
251:39 the name of the event in Google
251:41 calendar. But once again we're going to
251:42 let the model automatically define this
251:44 field. So let's call this node create
251:49 event. And actually one more thing I
251:51 forgot to do is we want to add an
251:52 attendee. So we can actually let the
251:54 agent add someone to an event as well.
251:56 So that is the new tool. We're going to
251:58 hit save. And remember no system
252:00 prompts. Let's see if we can create a
252:02 calendar event with Michael Scott. All
252:04 right. All right. So, we're asking for
252:05 dinner with Michael at 6 p.m. What's
252:08 going to happen is it probably Okay, so
252:11 we're going to have to do some prompting
252:12 because we don't know Michael Scott's
252:14 contact information yet, but it went
252:15 ahead and tried to create that email.
252:17 So, it said that it created the event
252:19 and let's click into the tool and see
252:20 what happened. So, it tried to send the
252:23 event invite to
252:26 michael.scottample.com. So, it
252:27 completely made that up because in our
252:29 contacts base, Michael Scott's email is
252:31 mikegreatcott.com. So, it got that
252:33 wrong. That's the first thing it got
252:35 wrong. The second thing it got wrong was
252:38 the actual start and end date. So, yes,
252:40 it made the event for 6 p.m., but it
252:42 made it for 6 p.m. on April 27th, 2024,
252:45 which was over a year ago. So, we can
252:48 fix this by using the system prompt. So,
252:50 what I'm going to do real quick is go
252:52 into the system prompt, and I'm just
252:54 going to make it just an expression and
252:55 open it up full screen real quick. What
252:57 I'm going to say next is you must always
253:00 look in the contacts database before
253:03 doing something like creating an event
253:05 or sending an email. You need the
253:08 person's email address in order to do
253:10 one of those
253:12 actions. Okay, so that's a really simple
253:14 thing we can add. And then also what I
253:16 want to tell it is what is today's
253:17 current date and time? So that if I say
253:19 create an event for tomorrow or create
253:20 an event for today, it actually gets the
253:22 date right. So, I'm just going to say
253:24 here is the current date slashtime. And
253:28 all I have to do to give it access to
253:29 the current date and time is do two
253:31 curly braces. And then right here you
253:33 can see dollar sign now which says a
253:35 date time representing the current
253:36 moment. So if I click on that on the
253:39 right hand side in the result panel you
253:40 can see it's going to show the current
253:42 date and time. So we're happy with that.
253:44 Our system prompt has been a little bit
253:45 upgraded and now we're going to just try
253:47 that exact same query again and we'll
253:49 see what happens. So, I'm going to click
253:50 on this little repost message button.
253:53 Send it again. And hopefully now, there
253:55 we go. It hits the contact database to
253:57 get Michael Scott's email. And then it
253:59 creates the calendar event with Michael
254:00 Scott. So, down here, it says, I've
254:02 created a calendar event for dinner with
254:04 Michael Scott tonight at 6. If you need
254:06 any more assistance, feel free to ask.
254:07 So, if I go to my calendar, we can see
254:10 we have a 2-hour long dinner with
254:11 Michael Scott. If I click onto it, we
254:14 can see that the guest that was invited
254:17 mikegreatscott.com, which is exactly
254:18 what we see in our contact database. And
254:21 so, you may have noticed it made this
254:22 event for 2 hours because we didn't
254:23 specify. If I said, "Hey, create a
254:25 15-minute event," it would have only
254:27 made it 15 minutes. So, what I'm going
254:29 to do real quick is a loaded prompt.
254:31 Okay, so fingers crossed. We're saying,
254:33 "Please invite Ryan Reynolds to a party
254:34 tonight that's only 30 minutes long at 8
254:36 p.m. and send him an email to confirm."
254:39 So, what happened here? It went to go
254:41 create an event and send an email, but
254:43 it didn't get Ryan Reynolds email first.
254:45 So, if we click into this, we can see
254:47 that it sent an email to
254:48 ryan.rrensacample.com. That's not right.
254:50 And it went to create an event at
254:52 ryan.rerensacample.com. And that's not
254:54 right either. But the good news is if we
254:56 go to calendar, we can see that it did
254:58 get the party right as far as it's 8
254:59 p.m. and only 15 minutes. So, because it
255:02 didn't take the right action, it's not
255:04 that big of a deal. We know now that we
255:06 have to go and refine the system prompt.
255:08 So to do that, I'm going to open up the
255:10 agent. I'm going to click into the
255:11 system prompt. And we are going to fix
255:14 some stuff up. Okay. So I added two
255:16 sentences that say, "Never make up
255:17 someone's email address. You must look
255:19 in the contact database tool." So as you
255:21 guys can see, this is pretty natural
255:22 language. We're just instructing someone
255:24 how to do something as if we were
255:25 teaching an intern. Okay. So what I'm
255:27 going to do real quick is clear this
255:28 memory. So I'm just going to reset the
255:30 session. And now we're starting from a
255:31 clean slate. And I'm going to ask that
255:33 exact same query to do that multi-step
255:35 thing with Ryan Reynolds. All right.
255:37 Take two. We're inviting Ryan Reynolds
255:38 to a party at 9:00 p.m. There we go.
255:40 It's hitting the contacts database. And
255:42 now it's going to hit the create event
255:43 and the send email tool at the same
255:45 time. Boom. I've scheduled a 30-minute
255:47 party tonight at 9:00 p.m. and invited
255:49 Ryan Reynolds. So, let's go to our
255:51 calendar. We have a 9 p.m. party for 30
255:53 minutes long, and it is
255:55 ryanpool.com, which is exactly what we
255:57 see in our contacts database. And then,
255:59 if we go to our email, we can see now
256:01 that we have a party invitation for
256:03 tonight to ryanpool.com. But what you'll
256:06 notice is now it didn't sign off as Nate
256:08 because I cleared that memory. So this
256:11 would be a super simple fix. We would
256:12 just want to go to the system prompt and
256:14 say, "Hey, when you're sending emails,
256:15 make sure you sign off as Nate." So
256:18 that's going to be it for your first AI
256:19 agent build. This one is very simple,
256:21 but also hopefully really opens your
256:24 eyes to how easy it is to plug in these
256:26 different tools. And it's really just
256:27 about your configurations and your
256:29 system prompts because system prompting
256:31 is a really important skill and it's
256:33 something that you kind of have to just
256:34 try out a lot. You have to get a lot of
256:36 reps and it's a very iterative process.
256:38 But anyways, congratulations. You just
256:40 built your first AI agent in probably
256:42 less than 20 minutes and now add on a
256:44 few more tools. Play around with a few
256:46 more parameters and just see how this
256:47 kind of stuff works. In this section,
256:49 what I'm going to talk about is dynamic
256:51 memory for your AI agents. So if you
256:54 remember, we had just set up this agent
256:56 and we were using simple memory and this
256:58 was basically helping us keep
256:59 conversation history. But what we didn't
257:02 yet talk about was the session ID and
257:05 what that exactly means. So basically
257:07 think of a session ID as some sort of
257:09 unique identifier that identifies each
257:12 separate conversation. So, if I'm
257:14 talking to you, person A, and you ask me
257:18 something, I'm gonna go look at
257:19 conversations from our conversation,
257:22 person A and Nate, and then I can read
257:24 that for context and then respond to
257:25 you. But if person B talks to me, I'm
257:28 going to go look at my conversation
257:29 history with person B before I respond
257:31 to them. And that way, I keep two people
257:34 and two conversations completely
257:35 separate. So, that's what a session ID
257:37 is. So, if we were having some sort of
257:39 AI agent that was being triggered by an
257:41 email, we would basically want to set
257:43 the session ID as the email address
257:46 coming in because then we know that the
257:47 agent's going to be uniquely responding
257:50 to whoever actually sent that email that
257:52 triggered it. So, just to demonstrate
257:55 how that works, what I'm going to do is
257:56 just manipulate the session ID a little
257:58 bit. So, I'm going to come into here and
258:00 I'm going to instead of using the chat
258:02 trigger node for the session ID, I'm
258:04 going to just define it below. And I'm
258:06 just going to do that exact example that
258:07 I just talked to you guys about with
258:09 person A and person B. So I'm just going
258:10 to put a lowercase A in there as the
258:13 session ID
258:15 key. So once I save that, what I'm going
258:17 to do is just say hi. Now it's going to
258:20 respond to me. It's going to update the
258:21 conversation history and say hi. I'm
258:22 going to say my name is
258:26 um Bruce. I don't know why I thought of
258:27 Bruce, but my name's Bruce. And now it
258:30 says nice to meet you Bruce. How can I
258:31 assist you? Now what I'm going to do is
258:34 I'm going to change the session ID to B.
258:36 We'll hit save. And I'm just going to
258:38 say what's my
258:39 name? What's my name? And it's going to
258:42 say I don't have access to your name
258:44 directly. If you'd like, you can provide
258:46 your name or any other details you want
258:48 me to know. How can I assist you today?
258:50 So person A is Bruce. Person B is no
258:52 name. And what I'm going to do is go
258:54 back to putting the key as A. Hit save.
258:57 And now if I say, "What is my name?"
259:01 with a misspelled my, it's going to say,
259:03 "Hey,
259:04 Bruce." There we go. Your name is Bruce.
259:06 How can I assist you further? And so
259:08 that's just a really quick demo of how
259:10 you're able to sort of actually have
259:12 dynamic um conversations with multiple
259:15 users in one single agent flow because
259:17 you can make this field dynamic. So,
259:20 what I'm going to do to show you guys a
259:21 practical use of this, let's say you're
259:23 wanting to connect your agent to Slack
259:25 or to Telegram or to WhatsApp or to
259:27 Gmail. You want the memory to be dynamic
259:29 and you want it to be unique for each
259:31 person that's interacting with it. So,
259:33 what I have here is a Gmail trigger. I'm
259:35 going to hit test workflow, which should
259:36 just pull in an email. So, when we open
259:38 up this email, we can see like the
259:39 actual body of the email. We can see,
259:41 you know, like history. We can see a
259:43 thread ID, all this kind of stuff. But
259:45 what I want to look at is who is the
259:46 email from? Because then if I feed this
259:48 into the AI agent and first of all we
259:51 would have to change the actual um user
259:53 message. So we are no longer talking to
259:55 our agent with the connected chat
259:57 trigger node, right? We're connecting to
259:59 it with Gmail. So I'm going to click to
260:01 find below. The user message is
260:03 basically going to be whatever you want
260:04 the agent to look at. So don't even
260:07 think about end right now. If you had an
260:08 agent to help you with your emails, what
260:10 would you want it to read? You'd want it
260:11 to read maybe a combination of the
260:13 subject and the body. So that's exactly
260:15 what I'm going to do. I'm just going to
260:17 type in subject. Okay, here's the
260:19 subject down here. And I'm going to drag
260:20 that right in there. And then I'm just
260:22 going to say body. And then I would drag
260:24 in the actual body snippet. And it's a
260:27 snippet right now because in the actual
260:28 Gmail trigger, we have this flicked on
260:31 as simplified. If we turn that off, it
260:33 would give us not a snippet. It would
260:34 give us a full email body. But for right
260:36 now, for simplicity, we'll leave it
260:37 simplified. But now you can see that's
260:39 what the agent's going to be reading
260:40 every time, not the connected chat
260:42 trigger node. And before we hit test
260:44 step, what we want to do is we want to
260:47 the sender of this email also the
260:50 session key for the simple memory. So
260:52 we're going to define below and what I'm
260:54 going to do is find the from field which
260:56 is right here and drag that in. So now
260:58 whenever we get a new email, we're going
261:00 to be looking at conversation history
261:02 from whoever sent that email to trigger
261:04 this whole workflow. So I'll hit save
261:06 and basically what I'm going to do is
261:08 just run the agent. And what it's going
261:10 to do is update the memory. It's going
261:11 to be looking at the correct thing and
261:13 it's taking some action for us. So,
261:15 we'll take a look at what it does. But
261:17 basically, it said the invitation email
261:18 for the party tonight has been sent to
261:20 Ryan. If you need any further
261:21 assistance, please let me know. And the
261:23 reason why it did that is because the
261:25 actual user message basically was saying
261:27 we're inviting Ryan to a party. So,
261:30 hopefully that clears up some stuff
261:31 about dynamic um user messages and
261:34 dynamic memory. And now you're on your
261:36 way to building some pretty cool Jetic
261:38 workflows. And something important to
261:39 touch on real quick is with the memory
261:41 within the actual node. What you'll
261:43 notice is that there is a context window
261:45 length parameter. And this says how many
261:47 past interactions the model receives as
261:49 context. So this is definitely more of
261:50 the short-term memory because it's only
261:52 going to be looking at the past five
261:53 interactions before it crafts its
261:55 response. And this is not just with a
261:57 simple memory node. What we have here is
261:59 if I delete this connection and click on
262:00 memory, you can see there are other
262:02 types of memory we can use for our AI
262:04 agents. Let's say for example we're
262:05 doing Postgress which later in this
262:07 course you'll see how to set this up.
262:09 But in Postgress you can see that
262:10 there's also a context window length. So
262:12 just to show you guys an example of like
262:14 what that actually looks like. What
262:15 we're going to do is just connect back
262:16 to here. I'm going to drag in our chat
262:18 message trigger which means I'm going to
262:20 have to change the input of the AI
262:22 agent. So we're going to get rid of this
262:23 whole um defined below with the subject
262:26 and body. We're going to drag in the
262:27 connected chat trigger node. Go ahead
262:29 and give this another save. And now I'm
262:31 just going to come into the chat and
262:32 say, "Hello, Mr. Agent. What is going on
262:37 here? We have the memory is messed up."
262:39 So remember, I just changed the session
262:41 ID from our chat trigger to the Gmail
262:45 trigger um the address, the email
262:48 address of whoever just sent us the
262:49 email. So I'm going to have to go change
262:50 that again. I'm just going to simply
262:52 choose connected chat trigger node. And
262:54 now it's referencing the correct session
262:56 ID. Our variable is green. We're good to
262:57 go. We'll try this again. Hello, Mr.
262:59 Agent. It's going to talk to us. So,
263:01 just save that as
263:03 memory. My name is
263:07 Nate. Okay. Nice to meet you, Nate. How
263:10 can I assist you? My favorite color is
263:14 blue. And I'm going to say, you know,
263:17 tell me about myself. Okay. So, it's
263:21 using all that memory, right? We
263:22 basically saw a demo of this, but it
263:24 basically says, other than your name and
263:26 your favorite color is blue, what else
263:27 is there about you? So if I go into the
263:29 agent and I click over here into the
263:31 agent logs, we can see the basically the
263:34 order of operations that the agent took
263:36 in order to answer us. So the first
263:38 thing that it does is it uses its simple
263:40 memory. And that's where you can see
263:41 down here, these are basically the past
263:43 interactions that we've had, which was
263:46 um hello Mr. Agent, my name is Nate, my
263:49 favorite color is blue. And this would
263:50 basically cap out at five interactions.
263:52 So that's all we're basically saying in
263:54 this context window length right here.
263:57 So, just wanted to throw that out there
263:58 real quick. This is not going to be
264:00 absolutely unlimited memory to remember
264:02 everything that you've ever said to your
264:04 agent. We would have to set that up in a
264:06 different way. All right, so you've got
264:07 your agent up and running. You have your
264:08 simple memory set up, but something that
264:10 I alluded to in that video was setting
264:12 up memory outside of NADN, which could
264:14 be something like Postgress. So in this
264:16 next one, we're going to walk through
264:17 the full setup of creating a superbase
264:19 account, connecting your Postgress and
264:21 your Superbase so that you can have your
264:23 short-term memory with Postgress and
264:25 then you can also connect a vector
264:26 database with Superbase. So let's get
264:28 started. So today I'm going to be
264:29 showing you guys how to connect
264:30 Postgress SQL and Superbase to Nadin. So
264:33 what I'm going to be doing today is
264:34 walking through signing up for an
264:35 account, creating a project, and then
264:36 connecting them both to NADN so you guys
264:38 can follow every step of the way. But
264:40 real quick, Postgress is an open- source
264:41 relational database management system
264:43 that you're able to use plugins like PG
264:45 vector if you want vector similarity
264:46 search. In this case, we're just going
264:47 to be using Postgress as the memory for
264:49 our agent. And then Superbase is a
264:50 backend as a service that's kind of
264:52 built on top of Postgress. And in
264:54 today's example, we're going to be using
264:55 that as the vector database. But don't
264:56 want to waste any time. Here we are in
264:58 Naden. And what we know we're going to
264:59 do here for our agent is give it memory
265:00 with Postgress and access to a vector
265:03 database in Superbase. So for memory,
265:05 I'm going to click on this plus and
265:06 click on Postgress chat memory. And then
265:07 we'll set up this credential. And then
265:09 over here we want to click on the plus
265:10 for tool. We'll grab a superbase vector
265:12 store node and then this is where we'll
265:13 hook up our superbase credential. So
265:15 whenever we need to connect to these
265:16 thirdparty services what we have to do
265:18 is come into the node go to our
265:19 credential and then we want to create a
265:21 new one. And then we have all the stuff
265:22 to configure like our host our username
265:24 our password our port all this kind of
265:26 stuff. So we have to hop into superbase
265:28 first create account create a new
265:30 project and then we'll be able to access
265:31 all this information to plug in. So here
265:33 we are in Superbase. I'm going to be
265:34 creating a new account like I said just
265:35 so we can walk through all of this step
265:37 by step for you guys. So, first thing
265:38 you want to do is sign up for a new
265:39 account. So, I just got my confirmation
265:41 email. So, I'm going to go ahead and
265:42 confirm. Once you do that, it's going to
265:43 have you create a new organization. And
265:45 then within that, we create a new
265:46 project. So, I'm just going to leave
265:47 everything as is for now. It's going to
265:48 be personal. It's going to be free. And
265:50 I'll hit create organization. And then
265:52 from here, we are creating a new
265:53 project. So, I'm going to leave
265:54 everything once again as is. This is the
265:55 organization we're creating the project
265:56 in. Here's the project name. And then
265:58 you need to create a password. And
266:00 you're going to have to remember this
266:00 password to hook up to our Subabase node
266:02 later. So, I've entered my password. I'm
266:04 going to copy this because like I said,
266:06 you want to save this so you can enter
266:07 it later. And then we'll click create
266:08 new project. This is going to be
266:10 launching up our project. And this may
266:11 take a few minutes. So, um, just have to
266:14 be patient here. As you can see, we're
266:15 in the screen. It's going to say setting
266:16 up project. So, we pretty much are just
266:18 going to wait until our project's been
266:19 set up. So, while this is happening, we
266:21 can see that there's already some stuff
266:22 that may look a little confusing. We've
266:23 got project API keys with a service ro
266:25 secret. We have configuration with a
266:27 different URL and some sort of JWT
266:29 secret. So, I'm going to show you guys
266:30 how you need to access what it is and
266:32 plug it into the right places in Naden.
266:35 But, as you can see, we got launched to
266:36 a different screen. The project status
266:38 is still being launched. So, just going
266:39 to wait for it to be complete. So,
266:41 everything just got set up. We're now
266:42 good to connect to NAN. And what you
266:44 want to do is typically you'd come down
266:45 to project settings and you click on
266:47 database. And this is where everything
266:48 would be to connect. But it says
266:50 connection string has moved. So, as you
266:51 can see, there's a little button up here
266:52 called connect. So, we're going to click
266:53 on this. And now, this is where we're
266:55 grabbing the information that we need
266:56 for Postgress. So this is where it gets
266:58 a little confusing because there's a lot
266:59 of stuff that we need for Postgress. We
267:01 need to get a host, a username, our
267:03 password from earlier when we set up the
267:04 project, and then a port. So all we're
267:06 looking for are those four things, but
267:08 we need to find them in here. So what
267:09 I'm going to do is change the type to
267:10 Postgress SQL. And then I'm going to go
267:13 down to the transaction pooler, and this
267:15 is where we're going to find the things
267:16 that we need. The first thing that we're
267:17 looking for is the host, which if you
267:18 set it up just like me, it's going to be
267:20 after the -h. So it's going to be AWS,
267:22 and then we have our
267:24 region.pool.subase.com. So we're going
267:26 to grab that, copy it, and then we're
267:28 going to paste that into the host
267:29 section right there. So that's what it
267:31 should look like for host. Now we have a
267:32 database and a username to set up. So if
267:34 we go back into that superbase page, we
267:36 can see we have a D and a U. So the D is
267:38 going to stay as Postgress, but for
267:40 user, we're going to grab everything
267:41 after the U, which is going to be
267:43 postgress.com, and then these um
267:45 different characters. So I'm going to
267:47 paste that in here under the user. And
267:49 for the password, this is where you're
267:50 going to paste in the password that you
267:51 use to set up your Subbase project. And
267:53 then finally at the bottom, we're
267:54 looking for a port, which is by default
267:56 5342. But in this case, we're going to
267:58 grab the port from the transaction
267:59 pooler right here, which is following
268:01 the lowercase P. So we have 6543. I'm
268:04 going to copy that, paste that into here
268:05 as the port. And then we'll hit save.
268:07 And we'll see if we got connection
268:09 tested successfully. There we go. We got
268:10 green. And then I'm just going to rename
268:11 this so I can keep it organized. So
268:13 there we go. We've connected to
268:14 Postgress as our chat memory. We can see
268:16 that it is going to be using the
268:17 connected chat trigger node. That's how
268:19 it's going to be using the key to store
268:20 this information. and it's going to be
268:22 storing it in a table in Subabase called
268:23 Naden chat histories. So real quick, I'm
268:25 going to talk to the agent. I'm just
268:26 going to disconnect the subbase so we
268:28 don't get any errors. So now when I send
268:29 off hello AI agent, it's going to
268:31 respond to us with something like hey,
268:32 how can I help you today? Hello, how can
268:34 I assist you? And now you can see that
268:35 there were two things stored in our
268:37 Postgress chat memory. So we'll switch
268:38 over to superbase. And now we're going
268:40 to come up here in the left and go to
268:41 table editor. We can see we have a new
268:43 table that we just created called NAN
268:45 chat histories. And then we have two
268:46 messages in here. So the first one as
268:48 you can see was a human type and the
268:49 content was hello AI agent which is what
268:51 we said to the AI agent and then the
268:53 second one was a type AI and this is the
268:56 AI's response to us. So it said hello
268:58 how can I assist you today. So this is
268:59 where all of your chats are going to be
269:01 stored based on the session ID and just
269:03 once again this session ID is coming
269:04 from the connected chat trigger node. So
269:06 it's just coming from this node right
269:08 here. As you can see, there's the
269:09 session ID that matches the one in our
269:11 our chat memory table. And that is how
269:14 it's using it to store sort of like the
269:16 unique chat conversations. Cool. Now
269:18 that we have Postgress chat memory set
269:20 up, let's hook up our Superbase vector
269:22 store. So, we're going to drag it in.
269:24 And then now we need to go up here and
269:26 connect our credentials. So, I'm going
269:27 to create new credential. And we can see
269:28 that we need two things, a host and a
269:30 service role secret. And the host is not
269:33 going to be the same one as the host
269:34 that we used to set up our Postgress. So
269:36 let's hop into Superbase and grab this
269:37 information. So back in Superbase, we're
269:39 going to go down to the settings. We're
269:41 going to click on data API and then we
269:43 have our project URL and then we have
269:45 our service ro secret. So this is all
269:47 we're using for URL. We're going to copy
269:49 this, go back to Subase, and then we'll
269:50 paste this in as our host. As you can
269:52 see, it's supposed to be HTTPS
269:54 um and then your Superbase account. So
269:56 we'll paste that in and you can see
269:58 that's what we have.co. Also, keep in
270:00 mind this is because I launched up an
270:02 organization and a project in
270:03 Superbase's cloud. If you were to
270:05 self-host this, it would be a little
270:06 different because you'd have to access
270:07 your local host. And then of course, we
270:09 need our service ro secret. So back in
270:11 Superbase, I'm going to reveal, copy,
270:13 and then paste it into an end. So let me
270:14 do that real quick. And as you can see,
270:16 I got that huge token. Just paste it in.
270:17 So what I'm going to do now is save it.
270:19 Hopefully it goes green. There we go. We
270:20 have connection tested successfully. And
270:22 then once again, just going to rename
270:23 this. The next step from here would be
270:25 to create our Superbase vector store
270:27 within the platform that we can actually
270:28 push documents into. So you're going to
270:30 click on docs right here. You are going
270:31 to go to the quick start for setting up
270:33 your vector store and then all you have
270:35 to do right here is copy this command.
270:36 So in the top right, copy this script.
270:38 Come back into Subabase. You'll come on
270:40 the lefth hand side to SQL editor.
270:42 You'll paste that command in here. You
270:43 don't change anything at all. You'll
270:44 just hit run. And then you could should
270:46 see down here success. No rows returned.
270:48 And then in the table editor, we'll have
270:49 a new table over here called documents.
270:51 So this is where when we're actually
270:52 vectorizing our data, it's going to go
270:54 into this table. Okay. Okay. So, I'm
270:56 just going to do a real quick example of
270:57 putting a Google doc into our Subbase
270:59 vector database just to show you guys
271:00 that everything's connected the way it
271:02 should be and working as it should. So,
271:03 I'm going to grab a Google Drive node
271:05 right here. I'm going to click download
271:06 file. I'm going to select a file to
271:08 download which in this case I'm just
271:10 going to grab body shop services terms
271:11 and conditions and then hit test step.
271:13 And we'll see the binary data which is a
271:15 doc file over here. And now we have that
271:17 information. And what we want to do with
271:19 it is add it to superbase superbase
271:21 vector store. So, I'm going to type in
271:22 superbase. We'll see vector store. The
271:25 operation is going to be add documents
271:26 to vector store. And then we have to
271:28 choose the right credential because we
271:30 have to choose the table to put it in.
271:31 So this is in this case we already made
271:33 a table. As you can see in our superbase
271:34 it's called documents. So back in here
271:36 I'm going to choose the credential I
271:38 just made. I'm going to choose insert
271:39 documents and I'm going to choose the
271:41 table to insert it to not the N chat
271:43 histories. We want to insert this to
271:45 documents because this one is set up for
271:47 vectorization. From there I have to
271:49 choose our document loader as well as
271:50 our embeddings. So I'm not really going
271:52 to dive into exactly what this all means
271:53 right now. If you're kind of confused
271:55 and you're wanting a deeper dive on rag
271:57 and building agents, definitely check
271:58 out my paid community. We've got
271:59 different deep dive topics about all
272:01 this kind of stuff. But I'm just going
272:02 to set this up real quick so we can see
272:03 the actual example. I'm just choosing
272:05 the binary data to load in here. I'm
272:07 choosing the embedding and I'm choosing
272:08 our text splitter which is going to be
272:10 recursive. And so now all I have to do
272:11 here is hit run. It's going to be taking
272:13 that binary data of that body shop file.
272:15 It split it up. And as you can see
272:16 there's three items. So if we go back
272:18 into our Superbase vector store and we
272:21 refresh, we now see three items in our
272:23 vector database and we have the
272:25 different content and all this
272:26 information here like the standard oil
272:28 change, the synthetic oil change is
272:29 coming from our body shop document that
272:31 I have right here that we put in there
272:32 just to validate the rag. And we know
272:35 that this is a vector database store
272:36 rather than a relational one because we
272:38 can see we have our vector embedding
272:39 over here which is all the dimensions.
272:41 And then we have our metadata. So we
272:42 have stuff like the source and um the
272:44 blob type, all this kind of stuff. And
272:46 this is where we could also go ahead and
272:47 add more metadata if we wanted to.
272:49 Anyways, now that we have vectors in our
272:51 documents table, we can hook up the
272:53 actual agent to the correct table. So in
272:55 here, what I'm going to call this is um
272:58 body shop. For the description, I'm
273:00 going to say use this to get information
273:03 about the body shop. And then from the
273:06 table name, we have to choose the
273:07 correct table, of course. So we know
273:08 that we just put all this into something
273:10 called documents. So I'm going to choose
273:11 documents. And finally, we just have to
273:13 choose our embeddings, of course, so
273:15 that it can embed the query and pull
273:16 stuff back accurately. And that's pretty
273:18 much it. We have our AI agent set up.
273:20 So, let's go ahead and do a test and see
273:22 what we get back. So, I'm going to go
273:24 ahead and say what brake services are
273:25 offered at the body shop. It's going to
273:27 update the Postgress memory. So, now
273:29 we'll be able to see that query. It hit
273:30 the Superbase vector store in order to
273:32 retrieve that information and then
273:34 create an augmented generated answer for
273:36 us. And now we have the body shop offers
273:38 the following brake services. 120 per
273:40 axle for replacement, 150 per axle for
273:43 rotor replacement, and then full brake
273:45 inspection is 30 bucks. So, if we click
273:48 back into our document, we can see that
273:49 that's exactly what it just pulled. And
273:51 then, if we go into our vector database
273:53 within Subase, we can find that
273:55 information in here. But then we can
273:56 also click on NAN chat history, and we
273:58 can see we have two more chats. So, the
274:00 first one was a human, which is what we
274:01 said. What brake services are offered at
274:03 the body shop? And then the second one
274:05 was a AI content, which is the body shop
274:07 offers the following brake services,
274:09 blah blah blah. And this is exactly what
274:10 it just responded to us with within NADN
274:13 down here as you can see. And so keep in
274:14 mind this AI agent has zero prompting.
274:16 We didn't even open up the system
274:17 message. All that's in here is you are a
274:19 helpful assistant. But if you are
274:20 setting this up, what you want to do is
274:22 you know explain its role and you want
274:23 to tell it you know you have access to a
274:25 vector database. It is called X. It has
274:28 information about X Y and Z and you
274:29 should use it when a client asks about X
274:32 Y and Z. Anyways that's going to be it
274:33 for this one. Subase and Postgress are
274:35 super super powerful tools to use to
274:37 connect up as a database for your
274:38 agents, whether it's going to be
274:39 relational or vector databases and
274:41 you've got lots of options with, you
274:42 know, self-hosting and some good options
274:44 for security and scalability there. Now
274:46 that you guys have built an agent and
274:47 you see the way that an agent is able to
274:49 understand what tools it has and which
274:50 ones it needs to use, what's really
274:52 really cool and powerful about NAND is
274:55 that we can have a tool for an AI agent
274:58 be a custom workflow that we built out
274:59 in Nadn or we can build out a custom
275:02 agent in Naden and then give our main
275:04 agent access to call on that lower
275:06 agent. So what I'm about to share with
275:08 you guys next is an architecture you can
275:10 use when you're building multi- aent
275:11 systems. It's basically called having an
275:13 orchestrator agent and sub agents or
275:15 parent agents and child agents. So,
275:17 let's dive into it. I think you guys
275:18 will think it's pretty cool. So, a
275:20 multi- aent system is one where we have
275:22 multiple autonomous AI agents working
275:24 together in order to get the job done
275:26 and they're able to talk to each other
275:27 and they're able to use the tools that
275:28 they have access to. What we're going to
275:30 be talking about today is a type of
275:31 multi- aent system called the
275:32 orchestrator architecture. And basically
275:34 what that means that we have one agent
275:36 up here. I call it the parent agent and
275:38 then I call these child agents. But we
275:40 have an orchestrator agent that's able
275:41 to call on different sub aents. And the
275:44 best way to think about it is this
275:46 agent's only goal is to understand the
275:48 intent of the user. Whether that's
275:50 through Telegram or through email,
275:51 whatever it is, understanding that
275:53 intent and then understanding, okay, I
275:55 have access to these four agents and
275:57 here is what each one is good at. Which
275:59 one or which ones do I need to call in
276:01 order to actually achieve the end goal?
276:03 So, in this case, if I'm saying to the
276:05 agent, can you please write me a quick
276:08 blog post about dogs and send that to
276:11 Dexter Morgan, and can you also create a
276:13 dinner event for tonight at 6 p.m. with
276:14 Michael Scott? And thank you. Cool. So,
276:18 this is a pretty loaded task, right? And
276:20 can you imagine if this one agent had
276:22 access to all of these like 15 or
276:25 however many tools and it had to do all
276:27 of that itself, it would be pretty
276:29 overwhelmed and it wouldn't be able to
276:30 do it very accurately. So, what you can
276:32 see here is it is able to just
276:34 understand, okay, I have these four
276:35 agents. They each have a different role.
276:37 Which ones do I need to call? And you
276:38 can see what it's doing is it called the
276:39 contact agent to get the contact
276:41 information. Right now, it's calling the
276:43 content creator agent. And now that
276:44 that's finished up, it's probably going
276:45 to call the calendar agent to make that
276:47 event. And then it's going to call the
276:48 email agent in order to actually send
276:50 that blog that we had the content
276:52 creator agent make. And then you can see
276:54 it also called this little tool down
276:55 here called Think. If you want to see a
276:56 full video where I broke down what that
276:58 does, you can watch it right up here.
276:59 But we just got a response back from the
277:01 orchestrator agent. So, let's see what
277:03 it said. All right, so it said, "The
277:04 blog post about dogs has been sent to
277:06 Dexter Morgan. A dinner event for
277:07 tonight at 6 p.m. with Michael Scott has
277:09 been created. And if you need anything
277:10 else, let me know." And just to verify
277:12 that that actually went through, you can
277:13 see we have a new event for dinner at 6
277:14 p.m. with Michael Scott. And then in our
277:16 email and our scent, we can see that we
277:18 have a full blog post sent to Dexter
277:20 Morgan. And you can see that we also
277:22 have a link right here that we can click
277:23 into, which means that the content
277:24 creator agent was able to do some
277:26 research, find this URL, create the blog
277:28 post, and send that back to the
277:29 orchestrator agent. And then the
277:31 orchestrator agent remembered, okay, so
277:32 I need to send a blog post to Dexter
277:34 Morgan. I've got his email from the
277:36 contact agent. I have the blog post from
277:37 the content creator agent. Now all I
277:39 have to do is pass it over to the email
277:40 agent to take care of the rest. So yes,
277:42 it's important to think about the tools
277:44 because if this main agent had access to
277:45 all those tools, it would be pretty
277:47 overwhelming. But also think about the
277:48 prompts. So, in this ultimate assistant
277:50 prompt, it's pretty short, right? All I
277:52 had to say was, "You're the ultimate
277:54 assistant. Your job is to send the
277:55 user's query to the correct tool. You
277:57 should never be writing emails or ever
277:59 creating summaries or doing anything.
278:00 You just need to delegate the task." And
278:02 then what we did is we said, "Okay, you
278:04 have these six tools. Here's what
278:05 they're called. Here's when you use
278:06 them." And it's just super super clear
278:08 and concise. There's almost no room for
278:10 ambiguity. We gave it a few rules, an
278:12 example output, and basically that's it.
278:14 And now it's able to interpret any query
278:16 we might have, even if it's a loaded
278:17 query. As you can see, in this case, it
278:19 had to call all four agents, but it
278:20 still got it right. And then when it
278:22 sends over something to like the email
278:24 agent, for example, we're able to give
278:25 this specific agent a very, very
278:27 specific system prompt because we only
278:29 have to tell it about you only have
278:31 access to these email tools. And this is
278:33 just going back to the whole thing about
278:35 specialization. It's not confusing. It
278:37 knows exactly what it needs to do. Same
278:39 thing with these other agents. You know,
278:40 the calendar agent, of course, has its
278:41 own prompts with its own set of calendar
278:43 tools. The contact agent has its own
278:45 prompt with its own set of contact
278:46 tools. And then of course we have the
278:48 content creator agent which has to know
278:50 how to not only do research using its
278:52 tavly tool but it also has to format the
278:54 blog post with you know proper HTML. As
278:57 you can see here there was like a title
278:59 there were headings there were you know
279:00 inline links all that kind of stuff. And
279:02 so because we have all of this
279:04 specialized can you imagine if we had
279:06 all of that system prompt thrown into
279:08 this one agent and gave it access to all
279:09 the tools just wouldn't be good. And if
279:12 you're still not convinced, think about
279:13 the fact that for each of these
279:15 different tasks, because we know what
279:16 each agent is doing, we're able to give
279:18 it a very specific chat model because,
279:20 you know, like for something like
279:21 content creation, I like to use cloud
279:23 3.7, but I wouldn't want to use
279:24 something as expensive as cloud 3.7 just
279:26 to get contacts or to add contacts to my
279:28 contact database. So that's why I went
279:31 with Flash here. And then for these
279:32 ones, I'm using 4.1 Mini. So you're able
279:34 to have a lot more control over exactly
279:36 how you want your agents to run. And so
279:38 I pretty much think I hit on a lot of
279:39 that, but you know, benefits of
279:40 multi-agent system, more reusable
279:43 components. So now that we have built
279:44 out, you know, an email agent, whenever
279:46 I'm building another agent ever, and I
279:48 realize, okay, maybe it would be nice
279:49 for this agent to have a couple email
279:51 functions. Boom, I just give it access
279:53 to the email agent because we've already
279:54 built it and this email agent can be
279:56 called on by as many different workflows
279:57 as we want. And when we're talking about
279:59 reusable components, that doesn't have
280:01 to just mean these agents are reusable.
280:04 It could also be workflows that are
280:05 reusable. So, for example, if I go to
280:07 this AI marketing team video, if you
280:08 haven't watched it, I'll leave a link
280:09 right up here. These tools down here,
280:12 none of these are agents. They're all
280:14 just workflows. So, for example, if I
280:15 click into the video workflow, you can
280:17 see that it's sending data over to this
280:19 workflow. And even though it's not an
280:20 agent, it still is going to do
280:22 everything it needs to do and then send
280:24 data back to that main agent. Similarly,
280:26 with this create image tool, if I was to
280:28 click into it real quick, you can see
280:30 that this is not an agent, but what it's
280:31 going to do is it's going to take
280:32 information from that orchestrator agent
280:34 and do a very specific function. That
280:36 way, this main agent up here, all it has
280:38 to do is understand, I have these
280:40 different tools, which one do I need to
280:41 use. So, reusable components and also
280:43 we're going to have model flexibility,
280:45 different models for different agents.
280:46 We're going to have easier debugging and
280:48 maintenance because like I said with the
280:49 whole prompting thing, if you tried to
280:51 give that main agent access to 25 tools
280:54 and in the prompt you have to say here's
280:56 when you use all 25 tools and it wasn't
280:58 working, you wouldn't know where to
280:59 start. You would feel really overwhelmed
281:01 as to like how do I even fix this
281:02 prompt. So by splitting things up into
281:04 small small tasks and specialized areas,
281:07 it's going to make it so much easier.
281:09 Exactly like I just covered point number
281:10 four, clear prompts logic and better
281:12 testability. And finally, it's a
281:14 foundation for multi-turn agents or
281:15 agent memory. Just because we're sending
281:17 data from main agent to sub agent
281:19 doesn't mean we're losing that context
281:20 of like we're talking to Nate right now
281:22 or we're talking to Dave right now. We
281:24 can still have that memory pass between
281:26 workflows. So things get really really
281:28 powerful and it's just pretty cool.
281:31 Okay, so we've seen a demo. I think you
281:32 guys understand the benefits here. Just
281:34 one thing I wanted to throw out before
281:35 we get into like a live build of a
281:37 multi- aent system is just because this
281:40 is cool and there's benefits doesn't
281:42 mean it's always the right thing to do.
281:44 So if you're forcing a multi-agent
281:46 orchestrator framework into a process
281:47 that could be a simple single agent or a
281:50 simple AI workflow, all you're going to
281:52 be doing is you're going to be
281:53 increasing the latency. You're going to
281:54 be increasing the cost because you're
281:55 making more API calls and you're
281:58 probably going to be increasing the
281:59 amount of error just because kind of the
282:02 golden rule is you want to eliminate as
282:04 much data transfer between workflows as
282:06 you can because that's where you can run
282:08 into like some issues. But of course
282:10 there are times when you do need
282:11 dedicated agents for certain functions.
282:13 So, let's get into a new workflow and
282:15 build a really simple example of an
282:17 orchestrator agent that's able to call
282:18 on a sub agent. All right. So, what
282:21 we're going to be doing here is we're
282:22 going to build an orchestrator agent.
282:24 So, I'm going to hit tab. I'm going to
282:25 type in AI agent and we're going to pull
282:27 this guy in. And we're just going to be
282:28 talking to this guy using that little
282:29 chat window down here for now. So, first
282:32 thing we need to do as always is connect
282:33 a brain. I'm going to go ahead and grab
282:35 an open router. And we're just going to
282:36 throw in a 4.1 mini. And I'll just
282:39 change this name real quick so we can
282:40 see what we're using. And from here,
282:43 we're basically just going to connect to
282:44 a subworkflow. And then we'll go build
282:46 out that actual subworkflow agent. So
282:48 the way we do it is we click on this
282:50 plus under tool. And what we want to do
282:52 is call nen workflow tool because you
282:54 can see it says uses another nen
282:56 workflow as a tool. Allows packaging any
282:58 naden node as a tool. So it's super
283:00 cool. That's how we can send data to
283:01 these like custom things that we built
283:03 out. As you saw earlier when I showed
283:05 that little example of the marketing
283:06 team agent, that's how we can do it. So
283:08 I'm going to click on this. And
283:10 basically when you click on this,
283:11 there's a few things to configure. The
283:13 first one is a description of when do
283:15 you use this tool. You'll kind of tell
283:17 the agent that here and you'll also be
283:18 able to tell a little bit in a system
283:20 prompt, but you have to tell it when to
283:21 use this tool. And then the next thing
283:23 is actually linking the tool. So you can
283:24 see we can choose from a list of our
283:27 different workflows in NAN. You can see
283:28 I have a ton of different workflows
283:30 here, but all you have to do is you have
283:31 to choose the one that you want this
283:32 orchestrator agent to send data to. And
283:35 one thing I want to call attention to
283:36 here is this text box which says the
283:38 tool will call the workflow you defined
283:40 below and it will look in the last node
283:42 for the response. The workflow needs to
283:44 start with an execute workflow trigger.
283:46 So what does this mean? Let's just go
283:48 build another workflow and we will see
283:50 exactly what it means. So I'm going to
283:51 open up a new workflow which is going to
283:52 be our sub agent. So, I'm going to hit
283:54 tab to open up the nodes. And it's
283:55 obviously prompting us to choose a
283:57 trigger. And we're going to choose this
283:58 one down here that says when executed by
284:00 another workflow, runs the flow when
284:02 called by the execute workflow node from
284:04 a different tool. So, basically, the
284:06 only thing that can access this node and
284:07 send data to this node is one of these
284:10 bad boys right here. So, these two
284:12 things are basically just connected and
284:13 data is going to be sending between
284:15 them. And what's interesting about this
284:16 node is you can have a couple ways that
284:18 you accept data. So, by default, I
284:20 usually just put it on accept all data.
284:21 And this will put things into a field
284:23 right here called query. But if you
284:25 wanted to, you could also have it send
284:26 over specific fields. So, if you wanted
284:29 to only get like, you know, a phone
284:30 number and you wanted to get a name and
284:32 you wanted to get an email and you
284:34 wanted those all to already be in three
284:36 separate fields, that's how you could do
284:38 that. And a practical example of that
284:39 would be in my marketing team right here
284:41 in the create image. You can see that
284:43 I'm sending over an image title, an
284:44 image prompt, and a chat ID. And that's
284:47 another good example of being able to
284:48 send, you know, like memory over because
284:51 I have a chat ID coming from here, which
284:53 is memory to the agent right here. But
284:55 then I can also send that chat ID to the
284:57 next workflow if we need memory to be
284:59 accessed down here as well. So in this
285:01 case, just to start off, we're not going
285:02 to be sending over specified fields.
285:04 We're just going to do accept all data
285:06 and let us connect an AI agent to this
285:08 guy. So I'm going to type in AI agent.
285:10 We'll pull this in. The first thing we
285:12 need to do is we need to change this
285:14 because we're not going to be talking
285:16 through the connected chat trigger node
285:17 as we know because we have this trigger
285:20 right here. So what we're going to do is
285:21 save this workflow. So now it should
285:23 actually register an end that we have
285:24 this workflow. I'm going to go back in
285:26 here and we're just going to connect it.
285:27 So we know that it's called subwork sub
285:29 aent. So grab that right there. And now
285:32 you can see it says the sub workflow is
285:34 set up to receive all input data.
285:35 Without specific inputs, the agent will
285:37 not be able to pass data to this tool.
285:39 you can define the specific inputs in
285:40 the trigger. So that's exactly what I
285:42 just showed you guys with changing that
285:44 right there. So what I want to do is
285:45 show how data gets here so we can
285:47 actually map it so the agent can read
285:49 it. So what we need to do before we can
285:51 actually test it out is we need to make
285:52 sure that this orchestrator agent
285:54 understands what this tool will do and
285:56 when to use it. So let's just say that
285:57 this one's going to be an email agent.
285:59 First thing I'm going to do is just
286:00 intuitively name this thing email agent.
286:03 I'm then going to type in the
286:04 description call this tool to take any
286:07 email actions. So now it should
286:10 basically, you know, signal to this guy
286:12 whenever I see any sort of query come in
286:14 that has to do with email. I'm just
286:16 going to pass that query right off to
286:17 this tool. So as you can see, I'm not
286:19 even going to add a system message to
286:21 this AI agent yet. We're just going to
286:22 see if we can understand. And I'm going
286:24 to come in here and say, "Please send an
286:26 email to Nate asking him how he's
286:28 doing."
286:30 So, we fire that off and hopefully it's
286:32 going to call this tool and then we'll
286:33 be able to go in there and see the query
286:35 that we got. The reason that this
286:36 errored is because we haven't mapped
286:38 anything. So, what I'm going to do is
286:39 click on the tool. I'm going to click on
286:41 view subexecution. So, we can pop open
286:43 like the exact error that just happened.
286:45 And we can see exactly what happened is
286:47 that this came through in a field called
286:49 query. But the main agent is not looking
286:52 for a field called query. It's looking
286:53 for a field called chat input. So I'm
286:55 just going to click on debug and editor
286:57 so we can actually pull this in. Now all
286:59 I have to do is come in here, change
287:00 this to define below, and then just drag
287:02 in the actual query. And now we know
287:04 that this sub agent is always going to
287:06 receive the orchestrator agents message.
287:09 But what you'll notice here is that the
287:10 orchestrator agent sent over a message
287:12 that says, "Hi Nate, just wanted to
287:13 check in and see how you're doing. Hope
287:15 all is well." So there's a mistake here
287:17 because this main agent ended up
287:19 basically like creating an email and
287:21 sending it over. All we wanted to do is
287:23 basically just pass the message along.
287:25 So what I would do here is come into the
287:27 system prompt and I'm just going to
287:31 overview. You are an orchestrator agent.
287:34 Your only job is to delegate the task to
287:37 the correct tool. No need to write
287:40 emails or create
287:42 summaries. There we go. So just with a
287:44 very simple line, that's all we're going
287:45 to do. And before we shoot that off, I'm
287:47 just going to go back into the sub
287:48 workflow and we have to give this thing
287:50 an actual brain. so that it can process
287:52 messages. We're just going to go with a
287:54 4.1 mini once again. Save that. So, it
287:57 actually reflects on this main agent.
287:58 And now, let's try to send off this
288:00 exact same query. And we'll see what it
288:01 does this time. So, it's calling the
288:04 email agent tool. It shouldn't error
288:06 because we we we fixed it. But, as you
288:09 can see now, it just called that tool
288:10 twice. So, we have to understand why did
288:12 it just call the sub agent twice. First
288:14 thing I'm going to do is click into the
288:16 main agent and I'm going to click on
288:17 logs. And we can see exactly what it
288:19 did. So when it called the email agent
288:21 once again it sent over a subject which
288:23 is checking in and an actual email body.
288:25 So we have to fix the prompting there
288:26 right? But then the output which is
288:28 basically what that sub workflow sent
288:30 back said here's a slightly polished
288:32 version of your message for a warm and
288:33 clear tone blah blah blah. And then for
288:35 some reason it went and called that
288:36 email agent again. So now it says please
288:38 send the following email and it sends it
288:40 over again. And then the sub agent says
288:43 I can't send emails directly but here's
288:45 the email you can send. So, they're both
288:47 in this weird loop of thinking they are
288:48 creating them an email, but not actually
288:50 being able to send them. So, let's take
288:51 a look and see how we can fix that. All
288:53 right, so back in the sub workflow, what
288:55 we want to do now is actually let this
288:56 agent have the ability to send emails.
288:58 Otherwise, they're just going to keep
288:59 doing that endless loop. So, I'm going
289:01 to add a tool and type in Gmail. We're
289:03 going to change this to a send message
289:05 operation. I'm just going to rename this
289:08 send email. And we're just going to have
289:10 the two be defined by the model. We're
289:12 going to have the subject be defined by
289:14 the model. and we're going to have the
289:16 message be defined by the model. And all
289:17 this means is that ideally, you know,
289:19 this query is going to say, hey, send an
289:21 email to nateample.com asking what's up.
289:25 The agent would then interpret that and
289:26 it would fill out, okay, who is it going
289:28 to? What's the subject and what's the
289:29 message? It would basically just create
289:30 it all itself using AI. And the last
289:33 thing I'm going to do is just turn off
289:34 the Nent attribution right there. And
289:36 now let's give it another shot. And keep
289:38 in mind, there's no system prompt in
289:39 this actual agent. And I actually want
289:42 to show you guys a cool tip. So when
289:43 you're building these multi- aent
289:45 systems and you're doing things like
289:47 sending data between flows, if you don't
289:49 want to always go back to the main agent
289:51 to test out like how this one's working,
289:53 what you can do is come into here and we
289:55 can just edit this query and just like
289:57 set some mock data as if the main agent
289:59 was sending over some stuff. So I'm
290:00 going to say like we're pretending the
290:02 orchestrator agent sent over to the sub
290:04 workflow. send an email to
290:08 nate@example.com asking what's up and
290:12 we'll just get rid of that R. And then
290:14 now you can see that's the query. That's
290:15 exactly what this agent's going to be
290:17 looking at right here. And if we hit
290:18 play above this AI agent, we'll see that
290:20 hopefully it's going to call that send
290:22 email tool and we'll see what it did. So
290:24 it just finished up. We'll click into
290:25 the tool to see what it did. And as you
290:27 can see, it sent it to Nate example. It
290:29 made the subject checking in and then
290:31 the message was, "Hey Nate, just wanted
290:32 to check in and see what's up. best your
290:34 name. So, my thought process right now
290:36 is like, let's get everything working
290:38 the way we want it with this agent
290:39 before we go back to that orchestrator
290:41 agent and fix the prompting there. So,
290:43 one thing I don't like is that it's
290:44 signing off with best your name. So, we
290:46 have a few options here. We could do
290:48 that in the system prompt, but same
290:50 thing with like um specialization. If
290:52 this tool is specialized in sending
290:54 emails, we might as well instruct it how
290:56 to send emails in this tool. So for the
290:58 message, I'm going to add a description
290:59 and I'm going to say always sign off
291:01 emails
291:03 as Bob. And that really should do it. So
291:07 because we have this mock data right
291:08 here, I don't have to go and, you know,
291:10 send another message. I can just test it
291:12 out again and see what it's going to do.
291:14 So it's going to call the send email
291:15 tool. It's going to make that message.
291:17 And now we will go ahead and look and
291:18 see if it's signed off in a better way.
291:20 Right here, we can see now it's signing
291:21 off best, Bob. So, let's just say right
291:24 now we're happy with the way that our
291:25 sub agent's working. We can go ahead and
291:28 come back into the main agent and test
291:29 it out again. All right. So, I'm just
291:31 going to shoot off that same message
291:32 again that says, "Send an email to Nate
291:34 asking him how he's doing." And this
291:35 will be interesting. We'll see what it
291:37 sends over. It was one run and it says,
291:38 "Could you please provide Nate's email
291:40 address so I can send the message?" So,
291:42 what happened here was the subexecution
291:45 realized we don't have Nate's email
291:46 address. And that's why it basically
291:48 responded back to this main agent and
291:49 said, "I need that if I need to send the
291:51 message." So if I click on subexecution,
291:53 we will see exactly what it did and why
291:55 it did that and it probably didn't even
291:57 call that send email tool. Yeah. So it
291:59 actually failed and it failed because it
292:01 tried to fill out the two as Nate and it
292:03 realized that's not like a valid email
292:05 address. So then because this sub agent
292:08 responds with could you please provide
292:09 Nate's email address so I can send the
292:11 message. That's exactly what the main
292:13 agent saw right here in the response
292:15 from this agent tool. So that's how
292:16 they're able to talk to each other, go
292:17 back and forth, and then you can see
292:19 that the orchestrator agent prompted us
292:20 to actually provide Nate's email
292:22 address. So now we're going to try,
292:23 please send an email to nativeample.com
292:25 asking him how the project is coming
292:26 along. We'll shoot that off and
292:29 everything should go through this time
292:30 and it should basically say, oh, which
292:32 project are you referring to? This will
292:34 help me provide you with the most
292:35 accurate and relevant update. So once
292:37 again, the sub agent is like, okay, I
292:39 don't have enough information to send
292:40 off that message, so I'm going to
292:42 respond back to that orchestrator agent.
292:44 And just because we actually need one to
292:46 get through, let me shoot off one more
292:47 example. Okay, hopefully this one's
292:49 specific enough. We have an email
292:50 address. We have a specified name of a
292:52 project. And we should see that
292:54 hopefully it's going to send this email
292:55 this time. Okay, there we go. The email
292:57 asking Nate how Project Pan is coming
292:58 along. It's been sent. Anything else you
293:00 need? So, at this point, it would be
293:02 okay. Which other agents could I add to
293:04 the system to make it a bit easier on
293:06 myself? The first thing naturally to do
293:08 would be I need to add some sort of
293:09 contact agent. Or maybe I realize that I
293:12 don't need a full agent for that. Maybe
293:14 that needs to just be one tool. So
293:16 basically what I would do then is I'd
293:17 add a tool right here. I would grab an
293:18 air table because that's where my
293:20 contact information lives. And all I
293:22 want to do is go to contacts and choose
293:24 contacts. And now I just need to change
293:27 this to search. So now this tool's only
293:30 job is to return all of the contacts in
293:32 my contact database. I'm just going to
293:34 come in here and call this contacts. And
293:36 now keep in mind once again there's
293:38 still nothing in the system prompt about
293:39 here are the tools you have and here's
293:41 what you do. I just want to show you
293:42 guys how intelligent these models can be
293:44 before you even prompt them. And then
293:46 once you get in there and say, "Okay,
293:47 now you have access to these seven
293:48 agents. Here's what each of them are
293:50 good at, it gets even cooler." So, let's
293:53 try one more thing and see if it can use
293:54 the combination of contact database and
293:56 email agent. Okay, so I'm going to fire
293:58 this off. Send an email to Dexter Morgan
294:00 asking him if he wants to get lunch. You
294:02 can see that right away it used the
294:03 contacts database, pulled back Dexter
294:05 Morgan's email address, and now we can
294:07 see that it sent that email address over
294:08 to the email agent, and now we have all
294:10 of these different data transfers
294:12 talking to each other, and hopefully it
294:13 sent the email. All right, so here's
294:15 that email. Hi, Dexter. Would you like
294:16 to get lunch sometime soon? Best Bob.
294:18 The formatting is a little off. We can
294:19 fix that within the the tool for the
294:21 email agent. But let's see if we sent
294:23 that to the right email, which is
294:24 dextermiami.com. If we go into our
294:26 contacts database, we can see right here
294:28 we have dextermorggan dextermiami.com.
294:30 And like I showed you guys earlier, what
294:32 you want to do is get pretty good at
294:33 reading these agent logs. So you can see
294:35 how your agents are thinking and what
294:36 data they're sending between workflows.
294:38 And if we go to the logs here, we can
294:40 see first of all, it used its GPT4.1
294:42 mini model brain to understand what to
294:45 do. It understood, okay, I need to go to
294:46 the contacts table. So I got my contact
294:48 information. Then I need to call the
294:50 email agent. And what I sent over to the
294:52 email agent was send an email to
294:55 dextermiami.com asking him if he wants
294:57 to get lunch. And that was perfect. All
294:59 right. All right, so that's going to do
295:00 it for this one. Hopefully this opened
295:02 your eyes to the possibilities of these
295:03 multi- aent systems in N&N and also
295:05 hopefully it taught you some stuff
295:06 because I know all of this stuff is like
295:08 really buzzwordy sometimes with all
295:10 these agents agents agents but there are
295:12 use cases where it really is the best
295:13 path but it's all about like
295:15 understanding what is the end goal and
295:16 how do I want to evolve this workflow
295:18 and then deciding like what's the best
295:20 architecture or system to use. So that
295:23 was one type of architecture for a
295:24 multi-agent system called the
295:26 orchestrator architecture. But that's
295:28 not the only way to have multiple agents
295:30 within a workflow or within a system. So
295:32 in this next section, I'm going to break
295:33 down a few other architectures that you
295:35 can use so that you can understand
295:37 what's possible and which one fits your
295:39 use case best. So let's dive right in.
295:42 So in my ultimate assistant video, we
295:44 utilize an agentic framework called
295:45 parent agent. So as you can see, we have
295:47 a parent agent right here, which is the
295:48 ultimate assistant that's able to send
295:50 tasks to its four child agents down
295:52 here, which are different workflows that
295:54 we built out within NAND. If you haven't
295:56 seen that video, I'll tag it right up
295:57 here. But how it works is that the
295:58 ultimate assistant could get a query
295:59 from the human and decide that it needs
296:01 to send that query to the email agent,
296:03 which looks like this. And then the
296:04 email agent will be able to use its
296:05 tools in Gmail and actually take action.
296:08 From there, it responds to the parent
296:09 agent and then the parent agent is able
296:11 to take that response back from this
296:12 child agent and then respond to us in
296:14 Telegram. So, it's a super cool system.
296:15 It allows us to delegate tasks and also
296:17 these agents can be activated in any
296:19 specific order. It doesn't always have
296:20 to be the same. But is this framework
296:22 always the most effective? No. So today
296:24 I'm going to be going over four
296:25 different agentic frameworks that you
296:26 can use in your end workflows. The first
296:28 one we're going to be talking about is
296:29 prompt chaining. The second one is
296:31 routing. The third one is
296:32 parallelization. And the fourth one is
296:34 evaluator optimizer. So we're going to
296:36 break down how they all work, what
296:37 they're good at. But make sure you stick
296:38 around to the end because this one, the
296:40 evaluator optimizer, is the one that's
296:41 got me most excited. So before we get
296:43 into this first framework, if you want
296:45 to download these four templates for
296:46 free so you can follow along, you can do
296:48 so by joining my free school community.
296:50 You'll come in here, click on YouTube
296:51 resources, click on the post associated
296:53 with this video, and then you'll have
296:54 the workflow right here to download. So,
296:56 the link for that's down in the
296:57 description. There's also going to be a
296:58 link for my paid community, which is if
297:00 you're looking for a more hands-on
297:01 approach to learning NAND. We've got a
297:03 great community of members who are also
297:04 dedicated to learning NAN, sharing
297:06 resources, sharing challenges, sharing
297:07 projects, stuff like that. We've got a
297:09 classroom section where we're going over
297:10 different deep dive topics like building
297:11 agents, vector databases, APIs, and HTTP
297:14 requests. And I also just launched a new
297:15 course where I'm doing the step-by-step
297:16 tutorials of all the videos that I've
297:18 shown on YouTube. And finally, we've got
297:20 five live calls per week to make sure
297:21 that you're getting questions answered,
297:22 never getting stuck, and also networking
297:24 with individuals in the space. We've
297:26 also got guest speakers coming in in
297:27 February, which is super exciting. So,
297:29 I'd love to see you guys in these calls.
297:30 Anyways, back to the video here. The
297:32 first one we're going to be talking
297:33 about is prompt chaining. So, as you can
297:34 see, the way this works, we have three
297:36 agents here, and what we're doing is
297:38 we're passing the output of an agent
297:39 directly as the input into the next
297:42 agent, and so on so forth. So, here are
297:44 the main benefits of this type of
297:45 workflow. It's going to lead to improved
297:47 accuracy and quality because each step
297:49 focuses on a specific task which will
297:51 help reduce errors and hallucinations.
297:52 Greater control over each step. We can
297:54 refine the system prompt of the outline
297:56 writer and then we can refine the prompt
297:57 of the evaluator. So we can really tweak
297:59 what's going on and how data is being
298:01 transferred. Specialization is going to
298:03 lead to more effective agents. So as you
298:05 can see in this example, we're having
298:06 one agent write the outline. One of them
298:09 evaluates the outline and makes
298:10 suggestions. And then finally, we pass
298:12 that revised outline to the blog writer
298:14 who's in charge of actually writing the
298:15 blog. So this is going to lead to a much
298:17 more cohesive, thought through actual
298:20 blog in the end compared to if we would
298:21 just fed in all of this system prompt
298:24 into one agent. And then finally, with
298:26 this type of framework, we've got easier
298:27 debugging and optimization because it's
298:28 linear. We can see where things are
298:30 going wrong. Finally, it's going to be
298:31 more scalable and reusable as we're able
298:32 to plug in different agents wherever we
298:34 need them. Okay, so what we have to do
298:35 here is we're just going to enter in a
298:37 keyword, a topic for this um blog. So,
298:40 I'm just going to enter in coffee, and
298:42 we'll see that the agents start going to
298:43 work. So, the first one is an outline
298:44 writer. Um, one thing that's also really
298:46 cool about this framework and some of
298:47 the other ones we're going to cover is
298:49 that because we're splitting up the
298:50 different tasks, we're able to utilize
298:52 different large language models. So, as
298:53 you can see, the outline writer, we gave
298:55 20 Flash because it's it's free. Um,
298:58 it's it's powerful, but not super
298:59 powerful, and we just need a brief
299:00 outline to be written here. And then we
299:02 can pass this on to the next one that
299:03 uses 40 Mini. It's a little more
299:04 powerful, a little more expensive, but
299:06 still not too bad. and we want this more
299:08 powerful chat model to be doing the
299:10 evaluating and refining of the outline.
299:12 And then finally, for the actual blog
299:13 writing content, we want to use
299:15 something like Claw 3.5 or even Deepseek
299:17 R1 because it's going to be more
299:18 powerful and it's going to take that
299:20 revised outline and then structure a
299:21 really nice blog post for us. So that's
299:24 just part of the specialization. Not
299:25 only can we split up the tasks, but we
299:27 can plug and play different chat models
299:29 where we need to rather than feeding
299:31 everything through one, you know, one
299:33 Deep Seeker, one blog writer at the very
299:35 beginning. So, this one's finishing up
299:36 here. It's about to get pushed into a
299:38 Google doc where we'll be able to go
299:39 over there and take a look at the blog
299:41 that it got for us about coffee. So,
299:43 looks like it just finished up. Here we
299:45 go. Detailed blog post based on option
299:47 one, a comprehensive guide to coffee.
299:49 Here's our title. Um, we have a rich
299:51 history of coffee from bean to cup. We
299:54 have um different methods. We have
299:55 different coffee varieties. We have all
299:57 this kind of stuff, health benefits and
299:59 risks. Um, and as you can see, this
300:01 pretty much was a four-page blog. We've
300:03 got a conclusion at the end. Anyways,
300:04 let's dive into what's going on here.
300:06 So, the concept is passing the output
300:08 into the input and then taking that
300:10 output and passing it into the next
300:11 input. So, here we have here's the topic
300:14 to write a blog about which all it got
300:15 here was the word coffee. That's what we
300:17 typed in. The system message is that you
300:18 are an expert outline writer. Your job
300:20 is to generate a structured outline for
300:22 a blog post with section titles and key
300:24 points. So, here's the first draft at
300:25 the outline using 20 flash. Then, we
300:28 pass that into an outline evaluator
300:30 that's using for Mini. We said here's
300:32 the outline. We gave it the outline of
300:34 course and then the system message is
300:36 you're an expert blog evaluator. Your
300:38 job is to revise this outline and make
300:39 sure it hits these four criteria which
300:41 are engaging introduction, clear section
300:43 breakdown, logical flow, and then a
300:44 conclusion. So we told it to only output
300:46 the revised outline. So now we have a
300:48 new outline over here. And finally,
300:50 we're sending that into a Claude 3.5
300:52 blog writer where we gave it the revised
300:54 outline and just said, "You're an expert
300:56 blog writer. Generate a detailed blog
300:58 post using this outline with well
300:59 ststructured paragraphs and engaging
301:01 content." So that's how this works. You
301:03 can see it will be even more powerful
301:04 once we hook up, you know, like some
301:05 internet search functionality and if we
301:07 added like an editor at the end before
301:09 it actually pushed it into the the
301:10 Google doc or whatever it is. But that's
301:12 how this framework works. But let's move
301:14 into aic framework number two. Now we're
301:16 going to talk about the routing
301:17 framework. In this case, we have an
301:19 initial LLM call right here to classify
301:21 incoming emails. And based on that
301:23 classification, it's going to route it
301:24 up as high priority, customer support,
301:26 promotion, their finance, and billing.
301:28 And as you can see, there's different
301:29 actions that are going to take place. We
301:31 have different agents depending on what
301:32 type of message comes through. So the
301:34 first agent, which is the text
301:35 classifier here, basically just has to
301:37 decide, okay, which agent do I need to
301:39 send this email off to? Anyways, why
301:41 would you want to use routing? Because
301:42 you're going to have an optimized
301:43 response handling. So as we can see in
301:45 this case, we're able to set up
301:46 different personas for each of our
301:47 agents here rather than having one
301:49 general AI response agent. Then this can
301:52 be more scalable and modular. It's going
301:54 to be faster and more efficient. And
301:55 then you can also introduce human
301:56 escalation for critical issues like we
301:58 do up here with our high priority agent.
302:00 And finally, it's just going to be a
302:01 better user experience for for your team
302:03 and also your customers. So I hit test
302:06 step. What we're getting here is an
302:07 email that I just sent to myself that
302:08 says, "Hey, I need help logging into my
302:10 account. Can you help me?" So this email
302:12 classifier is going to label this as
302:13 customer support. As soon as we hit
302:15 play, it's going to send it down the
302:16 customer support branch right here. As
302:17 you can see, we got one new item. What's
302:19 going on in this step is that we're just
302:20 labeling it in our Gmail as a customer
302:22 support email. And then finally, we're
302:24 going to fire it off to the customer
302:25 support agent. In this case, this one is
302:27 trained on customer support activities.
302:29 Um, this is where you could hook up a
302:30 customer support database if you needed.
302:32 And then what it's going to do is it's
302:33 going to create an email draft for us in
302:35 reply to the email that we got. So,
302:37 let's go take a look at that. So, here's
302:38 the email we got. Hey, I need help
302:39 logging into my account. As you can see,
302:41 our agent was able to label it as
302:42 customer support. And then finally, it
302:44 created this email, which was, "Hey,
302:45 Nate, thanks for reaching out. I'd be
302:46 happy to assist you with logging into
302:48 your account. Please provide me with
302:49 some more details um about the issue
302:51 you're experiencing, blah blah blah."
302:52 And then this one signs off, "Best
302:54 regards, Kelly, because she's the
302:55 customer support rep." Okay, let's take
302:56 a look at a different example. Um, we'll
302:58 pull in the trigger again and this time
303:00 we're going to be getting a different
303:01 email. So, as you can see, this one
303:02 says, "Nate, this is urgent. We need
303:03 your outline tomorrow or you're fired."
303:05 So, hopefully this one gets labeled as
303:06 high priority. It's going to go up here
303:08 to the high priority branch. Once again,
303:10 we're going to label that email as high
303:11 priority. But instead of activating an
303:13 email draft reply tool, this one has
303:15 access to a Telegram tool. So, what it's
303:17 going to do is text us immediately and
303:18 say, "Hey, this is the email you got.
303:20 You need to take care of this right
303:21 away." Um, and obviously the logic you
303:23 can choose of what you want to happen
303:25 based on what route it is, but let's
303:26 see. We just got telegram message,
303:28 urgent email from Nate Hkelman stating
303:29 that an outline is needed by tomorrow or
303:31 there will be serious consequences,
303:33 potential termination. So that way it
303:35 notifies us right away. We're able to
303:36 get into our email manually, you know,
303:38 get get caught up on the thread and then
303:39 respond how we need to. And so pretty
303:41 much the same thing for the other two.
303:42 Promotional email will get labeled as
303:44 promotion. We come in here and see that
303:45 we are able to set a different persona
303:47 for the pro promotion agent, which is
303:49 you're in charge of promotional
303:50 opportunities. Your job is to respond to
303:52 inquiries in a friendly, professional
303:53 manner and use this email to send reply
303:55 to customer. Always sign off as Meredith
303:57 from ABC Corp. So, each agent has a
303:59 different sort of persona that it's able
304:01 to respond to. In finance agent, we have
304:03 we have this agent signing off as a as
304:05 Angela from ABC Corp. Um, anyways, what
304:08 I did here was I hooked them all up to
304:10 the same chat model and I hooked them
304:11 all up to the same tool because they're
304:13 all going to be sending an email draft
304:16 here. As you can see, we're using from
304:18 AAI to determine the subject, the
304:19 message, and the thread ID, which it's
304:21 going to pull in from the actual Gmail
304:23 trigger, or sorry, the Gmail trigger is
304:24 not using from AAI. We're we're mapping
304:26 in the Gmail trigger because every time
304:29 an email comes through, it can just look
304:30 at that um email in order to determine
304:33 the thread ID for sending out an email.
304:36 But you don't have to connect them up to
304:37 the same tool. I just did it this way
304:38 because then I only had to create one
304:39 tool. Same thing with the different chat
304:41 models based on the, you know,
304:43 importance of what's going through each
304:44 route. You could switch out the chat
304:46 models. We could have even used a
304:47 cheaper, easier one for the
304:48 classification if we wanted to, but in
304:50 this case, I just hooked them all up to
304:52 a 40 mini chat model. Anyways, this was
304:54 just a really simple example of routing.
304:56 You could have 10 different routes, you
304:57 could have just two different routes,
304:58 but the idea is that you're using one
305:00 agent up front to determine which way to
305:02 send off the data. Moving on to the
305:04 third framework, we've got
305:05 parallelization. What we're going to do
305:06 here is be using three different agents,
305:08 and then we're going to merge their
305:09 outputs, aggregate them together, and
305:11 then feed them all into a final agent to
305:12 sort of, you know, throw it all into one
305:14 response. So what this is going to do is
305:16 give us faster analysis rather than
305:18 processing everything linearly. So in
305:20 this case we're going to be sending in
305:21 some input and then we're going to have
305:22 one agent analyze the emotion behind it,
305:25 one agent do the intent behind it, and
305:26 then one agent analyze any bias rather
305:29 than doing it one by one. They're all
305:30 going to be working simultaneously and
305:31 then throwing their outputs together. So
305:33 it can decrease the latency there.
305:35 They're going to be specialized, which
305:36 means we could have specialized system
305:37 prompts like we do here. We also could
305:39 do specialized um large language models
305:41 again where we could plug in different
305:42 different models if we wanted to maybe
305:44 feed through the same prompt use cloud
305:46 up here, OpenAI down here and then you
305:48 know DeepSeek down here and then combine
305:49 them together to make sure we're getting
305:51 the best thoughtout answer. Um
305:53 comprehensive review and then more
305:55 scalability as well. But how this one's
305:56 going to work is we're putting in an
305:57 initial message which is I don't trust
305:59 the mainstream media anymore. They
306:00 always push a specific agenda and ignore
306:02 real issues. People need to wake up and
306:04 stop believing everything they see on
306:05 the news. So, we're having an emotion
306:07 agent, first of all, analyze the
306:08 emotional emotional tone, categorize it
306:10 as positive, neutral, negative, or mixed
306:13 with a brief explanation. The intent
306:15 agent is going to analyze the intent
306:17 behind this text, and then finally, the
306:18 bias agent is going to analyze this text
306:20 for any potential bias. So, we'll hit
306:23 this off. Um, we're going to get those
306:24 three separate analysises um or
306:26 analysis, and then we're going to be
306:28 sending that into a final agent that's
306:30 going to basically combine all those
306:32 outputs and then write a little bit of
306:33 report based on our input. So, as you
306:36 can see, right now, it's waiting here
306:37 for um the input from the bias agent.
306:40 Once that happens, it's going to get
306:41 aggregated, and now it's being sent into
306:42 the final agent, and then we'll take a
306:44 look at um the report that we got in our
306:47 Google doc. Okay, just finished up.
306:49 Let's hop over to Docs. We'll see we got
306:50 an emotional tone, intent, and bias
306:52 analysis report. Overview is that um the
306:55 incoming text has strong negative
306:57 sentiment towards mainstream media. Yep.
306:59 Emotional tone is negative sentiment.
307:01 Intent is persuasive goal. Um, the bias
307:03 analysis has political bias,
307:05 generalization, emotional language, lack
307:07 of evidence. Um, it's got
307:08 recommendations for how we can make this
307:10 text more neutral, revised message, and
307:12 then let's just read off the conclusion.
307:13 The analysis highlights a significant
307:15 level of negativity and bias in the
307:17 original message directed towards
307:18 mainstream media. By implementing the
307:20 suggested recommendations, the author
307:21 can promote a more balanced and credible
307:23 perspective that encourages critical
307:25 assessment of media consumption, blah
307:26 blah blah. So, as you can see, that's
307:28 going to be a much better, you know,
307:30 comprehensive analysis than if we would
307:32 have just fed the initial input into an
307:34 agent and said, "Hey, can you analyze
307:36 this text for emotion, intent, and
307:37 bias?" But now, we got that split up,
307:39 merged together, put into the final one
307:41 for, you know, a comprehensive review
307:43 and an output. And it's going to turn
307:45 the the, you know, data in into data out
307:48 process. It's going to be a lot more
307:49 efficient. Finally, the one that gets me
307:51 the most excited, um, the evaluator
307:53 optimizer framework, where we're going
307:54 to have an evaluator agent decide if
307:56 what's passing through is good or not.
307:58 If it's good, we're fine, but if it's
308:00 not, it's going to get optimized and
308:01 then sent back to the evaluator for more
308:03 evaluation. And this is going to be an
308:05 endless loop until the evaluator agent
308:06 says, "Okay, finally, it's good enough.
308:08 We'll send it off." So, if you watch my
308:10 human in the loop video, it's going to
308:11 be just like that where we were
308:13 providing feedback and we were the ones
308:14 basically deciding if it was good to go
308:16 or not. But in this case, we have an
308:17 agent that does that. So it's going to
308:19 be optimizing all your workflows on the
308:21 back end without you being in the loop.
308:23 So obviously the benefits here are that
308:24 it's going to ensure high quality
308:26 outputs. It's going to reduce errors and
308:27 manual review. It's going to be flexible
308:29 and scalable. And then it's going to
308:31 optimize the AI's performance because
308:32 it's sort of an iterative approach that
308:35 um you know focuses on continuous
308:36 improvement from these AI generated
308:39 responses. So what we're doing here is
308:40 we have a biography agent. What we told
308:42 this agent to do is um basically write a
308:45 biography. You're an expert biography
308:46 writer. You'll receive information about
308:48 a person. Your job is to create an
308:49 entire profile using the information
308:51 they give you. And I told it you're
308:52 allowed to be creative. From there,
308:55 we're setting the bio. And we're just
308:56 doing this here so that we can continue
308:58 to feed this back over and over. That
309:00 way, if we have five revisions, it'll
309:02 still get passed every time. The most
309:04 recent version to the agent and also the
309:06 most recent version when it's approved
309:08 will get pushed up here to the Google
309:09 doc. Then we have the evaluator agent.
309:11 What we told this agent to do is um
309:14 evaluate the biography. Your job is to
309:16 provide feedback. We gave a criteria.
309:18 So, make sure that it includes a quote
309:20 from the person. Make sure it's light
309:21 and humorous and make sure it has no
309:23 emojis. Only need to output the
309:25 feedback. If the biography is finished
309:27 and all criteria are met, then all you
309:29 need to output is finished. So, then we
309:31 have a check to say, okay, does the
309:33 output from the evaluator agent say
309:34 finished or is it feedback? If it's
309:36 feedback, it's going to go to the
309:37 optimizer agent and continue on this
309:39 loop until it says finished. Once it
309:41 finally says finished, as you can see,
309:42 we set JSON.output, output which is the
309:45 output from the evaluator agent equals
309:47 finished. When that happens, it'll go up
309:49 here and then we'll see it in our Google
309:51 doc. But then what we have in the actual
309:52 optimizer agent is we're giving it the
309:54 biography and this is where we're
309:56 referencing the set field where we
309:58 earlier right here where we set the bio.
310:00 This way the optimizer agent's always
310:01 getting the most updated version of the
310:04 bio. And then we're also going to get
310:05 the feedback. So this is going to be the
310:06 output from the evaluator agent because
310:08 if it does go down this path, the
310:10 evaluator agent, it means that it output
310:12 feedback rather than saying finished. So
310:14 it's getting feedback, it's getting the
310:16 biography, and then we're saying you're
310:17 an expert reviser. Your job is to take
310:19 the biography and optimize it based on
310:20 the feedback. So it gets all it needs in
310:22 the user message, and then it outputs us
310:24 a better optimized version of that
310:26 biography. Okay, so let's do an example
310:28 real quick. Um, if you remember in the
310:30 biography agent, well, all we have to do
310:31 is give it a, you know, some information
310:33 about a person to write a biography on.
310:35 So, I'm going to come in here and I'm
310:36 just going to say Jim 42
310:40 um, lives by the ocean. Okay, so that's
310:44 all we're going to put in. We'll see
310:45 that it's writing a brief biography
310:47 right now. And then we're going to see
310:48 it get evaluated. We're going to see if
310:50 it, you know, met those criteria. If it
310:52 doesn't, it's going to get sent to the
310:53 optimizer agent. the optimizer agent is
310:56 going to get um basically the criteria
310:58 it needs to hit as well as the original
311:00 biography. So here's the evaluator
311:02 agent. Look at that. It decides that it
311:03 wasn't good enough. Now it's being sent
311:05 to the optimizer agent who is going to
311:07 optimize the bio, send it back and then
311:09 hopefully on the second run it'll go up
311:11 and get published in the docs. If it's
311:12 not good enough yet, then it will come
311:14 back to the agent and it will optimize
311:15 it once again. But I think that this
311:17 agent will do a good job. There we go.
311:18 We can see it just got pushed up into
311:20 the doc. So let's take a look at our
311:21 Google doc. Here's a biography for Jim
311:24 Thompson. He lives in California. He's
311:26 43. Um, ocean enthusiast, passion,
311:29 adventure, a profound respect for
311:31 nature. It talks about his early life,
311:33 and obviously he's making all this up.
311:35 Talks about his education, talks about
311:37 his career, talks about his personal
311:38 life. Here we have a quote from Jim,
311:40 which is, "I swear the fish are just as
311:42 curious about me as I am about them."
311:43 We've even got another quote. Um, a few
311:45 dad jokes along the way. Why did the
311:47 fish blush? Because it saw the ocean's
311:49 bottom. So, not sure I completely get
311:50 that one. Oh, no. I get that one. Um
311:53 anyways then hobbies, philosophy, legacy
311:55 and a conclusion. So this is you know a
311:57 pretty optimized blog post. It meets all
311:59 the criteria that we had put into our
312:00 agents as far as you know this is what
312:02 you need to evaluate for. It's very
312:03 light. There's no emojis. Threw some
312:05 jokes in there and then it has some
312:06 quotes from Jim as well. So as you can
312:08 see all we put in was Jim 43 lives by
312:11 the ocean and we got a whole basically a
312:12 story written about this guy. And once
312:14 again just like all of these frameworks
312:16 pretty much you have the flexibility
312:17 here to change out your model wherever
312:19 you want. So let's say we don't really
312:20 mind up front. we could use something
312:22 really cheap and quick and then maybe
312:24 for the actual optimizer agent we want
312:25 to plug in something a little more um
312:27 you know with reasoning aspect like
312:28 deepse R1 potentially. Anyways, that's
312:31 all I've got for you guys today. Hope
312:32 this one was helpful. Hope this one, you
312:34 know, sparked some ideas for next time
312:36 you're going into edit end to build an
312:37 agentic workflow. Maybe looking at I
312:39 could actually have structured my
312:40 workflow in this framework and it would
312:42 have been a little more efficient than
312:43 the current way I'm doing it. Like I
312:44 said, these four templates will be in
312:46 the free school community if you want to
312:47 download them and just play around with
312:48 them to understand what's going on,
312:50 understand, you know, when to use each
312:52 framework, stuff like that. All right,
312:53 so we understand a lot of the components
312:55 that actually go into building an
312:56 effective agent or an effective agent
312:58 system, but we haven't really yet spent
313:00 a lot of time on prompting, which is
313:02 like 80% of an agent. It's so so
313:04 important. So, in this next section,
313:05 we're going to talk about my methodology
313:07 when it comes to prompting a tools
313:08 agent, and we're going to do a quick
313:10 little live prompting session near the
313:12 end. So, if that sounds good to you,
313:13 let's get started. Building AI agents
313:15 and hooking up different tools is fun
313:16 and all, but the quality and consistency
313:18 of the performance of your agents
313:19 directly ties back to the quality of the
313:21 system prompt that you put in there.
313:23 Anyways, today what we're going to be
313:24 talking about is what actually goes into
313:25 creating an effective prompt so that
313:27 your agents perform as you want them to.
313:29 I'm going to be going over the most
313:30 important thing that I've learned while
313:31 building out agents and prompting them
313:33 that I don't think a lot of people are
313:34 doing. So, let's not waste any time and
313:36 get straight into this one. All right,
313:37 so I've got a document here. If you want
313:39 to download this one to follow along or
313:40 just have it for later, you can do so by
313:42 joining my free school community. The
313:43 link for that's down in the description.
313:44 You'll just click on YouTube resources
313:46 and find the post associated with this
313:47 video and you'll be able to download the
313:49 PDF right there. Anyways, what we're
313:51 looking at today is how we can master
313:52 reactive prompting for AI agents in NAD.
313:55 And the objective of this document here
313:57 is to understand what prompting is, why
313:58 it matters, develop a structured
314:00 approach to reactive prompting when
314:02 building out AI agents, and then learn
314:04 about the essential prompt components.
314:05 So, let's get straight into it and start
314:07 off with just a brief introduction. What
314:09 is prompting? Make sure you stick around
314:11 for this one because once we get through
314:12 this doc, we're going to hop into NN and
314:14 do some live prompting examples. So,
314:15 within our agents, we're giving them a
314:17 system prompt. And this is basically
314:18 just coding them on how to act. But
314:20 don't be scared of the word code because
314:22 we're just using natural language
314:23 instead of something like Python or
314:25 JavaScript. A good system prompt is
314:27 going to ensure that your agent is
314:28 behaving in a very clear, very specific,
314:30 and a very repeatable way. So, instead
314:32 of us programming some sort of Python
314:34 agent, what we're doing is we're just
314:36 typing in, "You're an email agent. Your
314:37 job is to assist the user by using your
314:39 tools to take the correct action."
314:41 Exactly as if we were instructing an
314:42 intern. And why does prompting matter?
314:45 I'm sure by now you guys already have a
314:46 good reason in your head of why
314:47 prompting matters, and it's pretty
314:49 intuitive, but let's think about it like
314:51 this as well. Agents are meant to be
314:53 running autonomously, and they don't
314:55 allow that back and forth interaction
314:56 like chatbt. Now, yes, there can be some
314:58 human in the loop within your sort of
315:00 agentic workflows, but ideally you put
315:02 in an input, it triggers the automation,
315:05 triggers the agent to do something, and
315:06 then we're getting an output. Unlike
315:08 chatbt where you ask it to help you
315:09 write an email, and you can say, "Hey,
315:10 make that shorter," or you can say,
315:12 "Make it more professional." We don't
315:14 have that um luxury here. We just need
315:15 to trust that it's going to work
315:17 consistently and high quality. So, our
315:19 goal as prompters is to get the prompts
315:21 right the first time so that the agent
315:23 functions correctly every single time
315:25 it's triggered. So, the key rule here is
315:26 to keep the prompts clear, simple, and
315:28 actionable. You don't want to leave any
315:29 room for misinterpretation. Um, and
315:32 also, less is more. Sometimes I'll see
315:34 people just throw in a novel, and that's
315:35 just obviously going to be more
315:37 expensive for you, and also just more
315:38 room to confuse the agent. So, less is
315:40 more. So, now let's get into the biggest
315:42 lesson that I've learned while prompting
315:44 AI agents, which is prompting needs to
315:46 be done reactively. I see way too many
315:49 people doing this proactively, throwing
315:51 in a huge system message, and then just
315:52 testing things out. This is just not the
315:54 way to go. So let's dive into what that
315:56 actually means to be prompting
315:57 reactively. First of all, what is
315:59 proactive prompting? This is just
316:01 writing a long detailed prompt up front
316:03 after you have all your tools configured
316:04 and all of the sort of, you know,
316:06 standard operating procedures configured
316:08 and then you start testing it out. The
316:10 problem here is that you don't know all
316:12 the possible edge cases and errors in
316:14 advance and debugging is going to be a
316:16 lot more difficult because if something
316:17 breaks, you don't know which part of the
316:19 prompt is causing the issue. You may try
316:21 to fix something in there and then the
316:22 issue originally you were having is
316:24 fixed, but now you cause a new issue and
316:26 it's just going to be really messy as
316:27 you continue to add more and more and
316:28 you end up just confusing both yourself
316:30 and the agent. Now, reactive prompting
316:32 on the other hand is just starting with
316:33 absolutely nothing and adding a tool,
316:35 testing it out, and then slowly adding
316:37 sentence by sentence. And as you've seen
316:39 in some of my demos, we're able to get
316:41 like six tools hooked up, have no prompt
316:43 in there, and the agent's still working
316:44 pretty well. At that point, we're able
316:46 to start adding more lines to make the
316:47 system more robust.
316:49 But the benefits here of reactive
316:50 prompting are pretty clear. The first
316:53 one is easier debugging. You know
316:54 exactly what broke the agent. Whether
316:56 that's I added this sentence and then
316:58 the automation broke. All I have to do
316:59 is take out that sentence or I added
317:01 this tool and I didn't prompt the tool
317:03 yet. So that's what caused the
317:04 automation to break. So I'm just going
317:05 to add a sentence in right here about
317:06 the tool. This is also going to lead to
317:08 more efficient testing because you can
317:10 see exactly what happens before you hard
317:12 prompt in fixes. And essentially, you
317:14 know, I'll talk about hard prompting
317:15 more later, but essentially what it is
317:17 is um you're basically seeing an error
317:20 and then you're hard prompting in the
317:22 error within the system prompt and
317:23 saying, "Hey, like you just did this.
317:25 That was wrong. Don't do that again."
317:27 And we can only do that reactively
317:28 because we don't know how the agent's
317:29 going to react before we test it out.
317:31 Finally, we have the benefit that it
317:33 prevents over complicated prompts that
317:34 are hard to modify later. If you have a
317:37 whole novel in there and you're getting
317:39 errors, you're not going to know where
317:40 to start. You're going to be
317:40 overwhelmed. So, taking it step by step,
317:43 starting with nothing and adding on
317:44 things slowly is the way to go. And so,
317:46 if it still isn't clicking yet, let's
317:48 look at a real world example. Let's say
317:49 you're teaching a kid to ride a bike. If
317:51 you took a proactive approach, you'd be
317:53 trying to correct the child's behavior
317:56 before you know what he or she is going
317:57 to do. So, if you're telling the kid to
318:00 keep your back straight, lean forward,
318:01 you know, don't tilt a certain way,
318:03 that's going to be confusing because now
318:05 the kid is trying to adjust to all these
318:06 things you've said and it doesn't even
318:08 know what it was going to do, what he or
318:10 she was going to do in the in the
318:11 beginning. But if you're taking a
318:13 reactive approach and obviously maybe
318:15 this wasn't the best example cuz you
318:16 don't want your kid to fall, but you let
318:18 them ride, you see what they're doing,
318:20 you know, if they're leaning too much to
318:22 the left, you're going to say, "Okay,
318:23 well, maybe you need to lean a little
318:24 more to the right to center yourself
318:26 up." um and only correct what they
318:28 actually need to have corrected. This is
318:30 going to be more effective, fewer
318:31 unnecessary instructions, and just more
318:33 simple and less overwhelming. So, the
318:35 moral of the story here is to start
318:37 small, observe errors, and fix one
318:39 problem at a time. So, let's take a look
318:41 at some examples of reactive prompting
318:42 that I've done in my ultimate assistant
318:44 workflow. As you can see right here, I'm
318:45 sure you guys have seen that video by
318:46 now. If you haven't, I'll link it right
318:48 up here. But, I did a ton of reactive
318:50 prompting in here because I have one
318:52 main agent calling four different
318:53 agents. And then within those sub
318:55 agents, they all have different tools
318:56 that they need to call. So this was very
318:58 very reactive when I was prompting this
319:00 workflow or this system of agents. I
319:03 started with no persistent prompt at
319:04 all. I just connected a tool and I
319:06 tested it out to see what happened. So
319:07 an an example would be I hooked up an
319:09 email agent, but I didn't give it in any
319:10 instructions and I running the AI to see
319:12 if it will call the tool automatically.
319:14 A lot of times it will and then it only
319:16 comes to when you add another different
319:17 agent that you need to prompt in, hey,
319:19 these are the two agents you have.
319:20 Here's when to use each one. So anyways,
319:22 adding prompts based on errors. Here I
319:24 have my system prompts. So if you guys
319:26 want to pause it and read through, you
319:27 can take a look. But you can see it's
319:28 very very simple. I've got one example.
319:30 I've got basically one brief rule and
319:32 then I just have all the tools it has
319:34 and when to use them. And it's very very
319:35 concise and not overwhelming. And so
319:38 what I want you guys to pay attention to
319:40 real quick is in the overview right
319:41 here. I said, you know, you're the
319:43 ultimate personal assistant. Your job is
319:44 to send the user's query to the correct
319:46 tool. That's all I had at first. And
319:48 then I was getting this error where I
319:49 was saying, "Hey, write an email to
319:51 Bob." And what was happening is it
319:53 wasn't sending that query to the email
319:56 tool, which is supposed to do. It itself
319:58 was trying to write an email even though
319:59 it has no tool to write an email. So
320:01 then I reactively came in here and said,
320:03 "You should never be writing emails or
320:05 creating event summaries. You just need
320:06 to call the correct tool." And that's
320:08 not something I could have proactively
320:09 put in there because I didn't really
320:10 expect the agent to be doing that. So I
320:12 saw the error and then I basically
320:14 hardcoded in what it should not be doing
320:16 and what it should be doing. So another
320:18 cool example of hard coding stuff in is
320:19 using examples. You know, we all
320:21 understand that examples are going to
320:22 help the agent understand what it needs
320:24 to do based on certain inputs and how to
320:26 use different tools. And so right here
320:27 you can see I added this example, but
320:29 we'll also look at it down here because
320:30 I basically copied it in. What happened
320:32 was the AI failed in a very specific
320:34 scenario. So I added a concrete example
320:36 where I gave it an input, I showed the
320:38 actions it should take, and then I gave
320:40 it the output. So in this case, what
320:41 happened was I asked it to write an
320:43 email to Bob and it tried to send an
320:45 email or try it tried to hit the send
320:46 email agent, but it didn't actually have
320:48 Bob's email address. So the email didn't
320:49 get sent. So what I did here was I put
320:51 in the input, which was send an email to
320:53 Bob asking him what time he wants to
320:55 leave. I then showed the two actions it
320:56 needs to take. The first one was use the
320:58 contact agent to get Bob's email. Send
321:00 this email address to the email agent
321:02 tool. And then the second action is use
321:03 the email agent to send the email. And
321:05 then finally, the output that we want
321:07 the personal assistant to say back to
321:08 the human is, "The email has been sent
321:10 to Bob. Anything else I can help you
321:11 with?" The idea here is you don't need
321:13 to put examples in there that are pretty
321:14 intuitive and that the agent's going to
321:16 get right already. You only want to put
321:17 in examples where you're noticing common
321:19 themes of the agents failing to do this
321:21 every time. I may as well hardcode in
321:23 this example input and output and tool
321:26 calls. So, step four is to debug one
321:28 error at a time. always change one thing
321:30 and one thing only at a time so you know
321:32 exactly what you changed that broke the
321:34 automation. Too too often I'll see
321:36 people just get rid of an entire section
321:38 and then start running things and now
321:40 it's like okay well we're back at square
321:41 one because we don't know exactly what
321:43 happened. So you want to get to the
321:44 point where you're adding one sentence,
321:46 you're hitting run and it's either
321:47 fixing it or it's not fixing it and then
321:49 you know exactly what to do. You know
321:50 exactly what broke or fixed your
321:52 automation. And so one thing honestly I
321:53 want to admit here is I created that
321:55 system prompt generator on my free
321:57 school community. Um, and really the
321:59 idea there was just to help you with the
322:00 formatting because I don't really use
322:02 that thing anymore because the fact that
322:04 doing that is very proactive in the
322:06 sense that we're dropping in a sort of a
322:08 query into chat GBT, the custom GPT I
322:10 built, it's giving us a system prompt
322:12 and then we're putting that whole thing
322:13 in the agent and then just running it
322:14 and testing it. And in that case, you
322:16 don't know exactly what you should
322:17 change to fix little issues. So, just
322:19 wanted to throw that out there. I don't
322:21 really use that system prompt generator
322:22 anymore. I now always like handcraft my
322:25 prompts. Anyways, from there, what you
322:27 want to do is scale up slowly. So once
322:29 you confirm that the agent is
322:30 consistently working with its first tool
322:32 and its first rule in its prompt, then
322:34 you can slowly add more tools and more
322:36 prompt rules. So here's an example.
322:38 You'll add a tool. You'll add a sentence
322:40 in the prompt about the tool. Test out a
322:42 few scenarios. If it's working well, you
322:44 can then add another tool and keep
322:45 testing out and slowly adding pieces.
322:47 But if it's not, then obviously you'll
322:48 just hard prompt in the changes of what
322:50 it's doing wrong and how to fix that.
322:52 From there, you'll just test out a few
322:53 more scenarios. Um, and then you can
322:55 just kind of rinse and repeat until you
322:56 have all the functionality that you're
322:58 looking for. All right, now let's look
322:59 at the core components of an effective
323:01 prompt. Each agent you design should
323:03 follow a structured prompt to ensure
323:04 clarity, consistency, and efficiency.
323:07 Now, there's a ton of different types of
323:09 prompting you can do based on the role
323:10 of agent. Ultimately, they're going to
323:12 fall under one of these three buckets,
323:14 which is toolbased prompting,
323:16 conversational prompting, or like
323:17 content creation type prompting, and
323:20 categorization/ealuation prompting. And
323:22 the reason I wanted to highlight that is
323:23 because obviously if we're creating like
323:24 a content creation agent, we're not
323:26 going to say what tools it has if it has
323:27 no tools. But um yeah, I just wanted to
323:29 throw that out there. And another thing
323:30 to keep in mind is I really like using
323:32 markdown formatting for my prompts. As
323:34 you can see these examples, we've got
323:35 like different headers with pound signs
323:37 and we're able to specify like different
323:39 sections. We can use bolded lists. We
323:40 can use numbered lists. I've seen some
323:42 people talk about using XML for
323:44 prompting. I'm not a huge fan of it
323:45 because um as far as human readability,
323:48 I think markdown just makes a lot more
323:49 sense. So that's what I do. Anyways, now
323:52 let's talk about the main sections that
323:53 I include in my prompts. The first one
323:55 is always a background. So whether this
323:56 is a role or a purpose or a context, I
324:00 typically call it something like an
324:01 overview. But anyways, just giving it
324:03 some sort of background that defines who
324:04 the agent is, what its overall goal is.
324:07 And this really sets the foundation of,
324:08 you know, sort of identifying their
324:10 persona, their behavior. And if you
324:12 don't have the section, the agent is
324:14 kind of going to lack direction and it's
324:16 going to generate really generic or
324:17 unfocused outputs. So set its role and
324:21 this could be really simple. You can
324:22 kind of follow this template of you are
324:23 a blank agent designed to do blank. Your
324:25 goal is blank. So you are a travel
324:27 planning AI assistant that helps users
324:29 plan their vacations. Your goal is to
324:31 pro provide detailed personalized travel
324:32 itineraries based on the user's input.
324:35 Then we have tools. This is obviously
324:36 super super important when we're doing
324:38 sort of non-deterministic agent
324:40 workflows where they're going to have a
324:41 bunch of different tools and they have
324:42 to use their brain, their chat model to
324:44 understand which tool does what and when
324:46 to use each one. So, this section tells
324:48 the agent what tools it has access to
324:50 and when to use them. It ensures the AI
324:52 selects the right tool for the right
324:53 task. And a well structured tools
324:55 section prevents confusion and obviously
324:57 makes AI more efficient. So, here's an
324:59 example of what it could look like. We
325:00 have like the markdown header of tools
325:02 and then we have like a numbered list.
325:04 We're also showing that the tools are in
325:05 bold. This doesn't have to be the way
325:06 you do it, but sometimes I like to show
325:08 them in bold. Um, and it's you can see
325:10 it's really simple. It's it's not too
325:12 much. It's not overwhelming. It's not
325:13 too um you know, it's just very clear.
325:16 Google search, use this tool when the
325:17 user asks for real-time information.
325:19 Email sender, use this tool when the
325:21 user wants to send a message. Super
325:22 simple. And what else you can do is you
325:24 can define when to use each tool. So
325:26 right here we say we have a contact
325:27 database. Use this tool to get contact
325:29 information. You must use this before
325:31 using the email generator tool because
325:34 otherwise it won't know who to send the
325:35 email to. So you can actually define
325:36 these little rules. Keep it very clear
325:38 within the actual tool layer of the
325:41 prompt. And then we have instructions. I
325:43 usually call them rules as you can see.
325:44 Um, you could maybe even call it like a
325:46 standard operating procedure. But what
325:48 this does, it outlines specific rules
325:49 for the agent to follow. It dictates the
325:52 order of operations at a high level.
325:54 Just keep in mind, you don't want to say
325:55 do this in this order every time because
325:57 then it's like, why are you even using
325:58 an agent? The whole point of an agent is
326:00 that it's, you know, it's taking an
326:01 input and something happens in this
326:03 black box where it's calling different
326:04 tools. It may call this one twice. It
326:06 may call this one three times. It may
326:07 call them none at all. Um, the idea is
326:10 that it's variable. It's not
326:11 deterministic. So, if you're saying do
326:13 it and this every time, then you should
326:15 just be using a sequential workflow. It
326:17 shouldn't even be an agent. But
326:18 obviously, the rules section helps
326:20 prevent misunderstandings. So, here's
326:22 like a high level instruction, right?
326:23 You're greeting the user politely. If
326:25 the user provides incomplete
326:26 information, you ask follow-up
326:27 questions. Use the available tools only
326:29 when necessary. Structure your response
326:31 in clear, concise sentences. So, this
326:33 isn't saying like you do this in this
326:34 order every time. It's just saying when
326:35 this happens, do this. If this happens,
326:37 do that. So, here's an example for AI
326:39 task manager. When a task is added, you
326:41 confirm with the user. If a deadline is
326:43 missing, ask the user to specify one. If
326:45 a task priority is high, send a
326:46 notification. Store all tasks in the
326:48 task management system. So, it's very
326:50 clear, too. Um, we don't need all these
326:52 extra filler words because remember, the
326:54 AI can understand what you're saying as
326:56 long as it has like the actual context
326:58 words that have meaning. You don't need
326:59 all these little fillers. Um, you don't
327:01 need these long sentences. So, moving on
327:03 to examples, which you know, sample
327:05 inputs and outputs and also actions
327:07 within those between the inputs and
327:09 outputs. But this helps the AI
327:11 understand expectations by showing real
327:12 examples. And these are the things that
327:14 I love to hard code in there, hard
327:15 prompt in there. Because like I said,
327:18 there's no point in showing an example
327:19 if the AI was already going to get that
327:21 input and output right every time. You
327:23 just want to see what it's messing up on
327:24 and then put an example in and show it
327:26 how to fix itself. So more clear
327:28 guidance and it's going to give you more
327:30 accurate and consistent outputs. Here's
327:31 an example where we get the input that
327:33 says, can you generate a trip plan for
327:34 Paris for 5 days? The action you're
327:36 going to take is first call the trip
327:37 planner tool to get X, Y, and Z. Then
327:40 you're going to take another action
327:41 which is calling the email tool to send
327:43 the itinerary. And then finally, the
327:44 output should look something like this.
327:46 Here's a 5-day Paris itinerary. Day 1,
327:49 day 2, day 3, day 4, day 5. And then I
327:51 typically end my prompts with like a
327:53 final notes or important reminders
327:55 section, which just has like some
327:56 miscellaneous but important reminders.
327:58 It could be current date and time, it
327:59 could be rate limits, it could be um
328:02 something as simple as like don't put
328:03 any emojis in the output. Um, and
328:07 sometimes why I do this is because
328:09 something can get lost within your
328:11 prompt. And sometimes like I I've thrown
328:13 the today's date up top, but then it
328:14 only actually realizes it when it's in
328:16 the bottom. So playing around with the
328:18 actual like location of your things can
328:19 be sometimes help it out. Um, and so
328:22 having a final notes section at the
328:23 bottom, not with too many notes, but
328:25 just some quick things to remember like
328:26 always format responses as markdown.
328:28 Here's today's date. If unsure about an
328:30 answer, say I don't have that
328:31 information. So just little
328:33 miscellaneous things like that. Now, I
328:35 wanted to quickly talk about some
328:36 honorable mentions because like I said
328:38 earlier, the prompt sections and
328:40 components varies based on the actual
328:42 type of agent you're building. So, in
328:44 the case of like a content creator agent
328:46 that has no tools, um you wouldn't give
328:48 it a tool section, but you may want to
328:50 give it an output section. So, here's an
328:51 output section that I had recently done
328:53 for my voice travel agent. Um, which if
328:55 you want to see that video, I'll drop a
328:57 link right here. But what I did was I
328:59 just basically included rules for the
329:00 output because the output was very
329:01 specific with HTML format and it had to
329:03 be very structured and I wanted
329:05 horizontal lines. So I created a whole
329:07 section dedicated towards output format
329:09 as you can see. And because I used three
329:11 pound signs for these subsections, the
329:13 agent was able to understand that all
329:15 this rolled up into the format of the
329:17 output section right here. So anyways, I
329:19 said the email should be structured as
329:21 HTML that will be sent through email.
329:23 Use headers to separate each section.
329:25 Add a horizontal line to each section.
329:26 Um, I said what it what should be in the
329:28 subject. I said what should be in the
329:29 introduction section. I said how you
329:31 should list these departure dates,
329:33 return dates, flights for the flight
329:34 section. Um, here's something where I
329:36 basically gave it like the HTML image
329:39 tag and I showed how to put the image in
329:41 there. I showed to make I said like make
329:42 a inline image rather than um an
329:45 attachment. I said to have each resort
329:47 with a clickable link. I also was able
329:49 to adjust the actual width percentage of
329:51 the image by specifying that here in the
329:53 prompt. Um, so yeah, this was just
329:56 getting really detailed about the way we
329:57 want the actual format to be structured.
329:59 You can see here we have activities that
330:00 I actually misspelled in my agent, but
330:02 it didn't matter. Um, and then finally
330:04 just a sign off. And then just some
330:06 final additional honorable mentions,
330:08 something like memory and context
330:10 management, um, some reasoning, some
330:12 error handling, but typically I think
330:14 that these can be just kind of one or
330:15 two sentences that can usually go in
330:17 like the rules or instructions section,
330:19 but it depends on the use case, like I
330:21 said. So, if it needs to be pretty
330:22 robust, then creating an individual
330:24 section at the bottom called memory or
330:26 error handling could be worth it. It
330:28 just depends on, like I said, the actual
330:31 use case and the goal of the agent.
330:32 Okay, cool. So, now that we've got
330:34 through that document, let's hop into
330:35 Nitn and we'll just do some really quick
330:37 examples of some reactive live
330:38 prompting. Okay, so I'm going to hit
330:40 tab. I'm going to type in AI agent.
330:42 We're going to grab one and we're going
330:43 to be communicating with it through this
330:44 connected chat trigger node. Now, I'm
330:46 going to add a chat model real quick
330:47 just so we can get set up up and
330:49 running. We have our 40 Mini. We're good
330:51 to go. And just a reminder, there is
330:52 zero assistant prompt in here. All it is
330:54 is that you are a helpful assistant. So,
330:57 what's the first thing to do is we want
330:58 to add a tool. Test it out. So, I'm
331:00 going to add a um Google calendar tool.
331:03 I'm just going to obviously select my
331:05 calendar to pull from. I'm going to, you
331:07 know, fill in those parameters using the
331:08 model by clicking that button. And I'm
331:10 just going to say this one's called
331:11 create event. So, we have create event.
331:14 And so, now we're going to do our test
331:15 and see if the tool is working properly.
331:17 I'm going to say create an event for
331:20 tonight at 700 p.m. So send this off. We
331:23 should see the agents able to understand
331:25 to use this create event tool because
331:27 it's using an automatic description. But
331:29 now we see an issue. It created the
331:31 start time for October 12th, 2023 and
331:34 the end time for also October 12th,
331:36 2023. So this is our first instance of
331:38 reactive prompting. It's calling the
331:39 tool correctly. So we don't really need
331:41 to prompt in like the actual tool name
331:43 yet. Um it's probably best practice just
331:45 to just to do so. But first, I'm just
331:47 going to give an overview and say you
331:49 are a calendar. Actually, no. I'm just
331:52 going to say you are a helpful assistant
331:54 because that's all it is right now. And
331:56 we don't know what else we're adding
331:57 into this guy. But now we'll just say
331:59 tools is create event just so it's
332:02 aware. Use this to create an event. And
332:06 then we want to say final notes. um here
332:11 is the current date and time because
332:14 that's where it messed up is because it
332:16 didn't know the current date and time
332:17 even though it was able to call the
332:18 correct tool. So now we'll just send
332:20 this same thing off again and that
332:22 should have fixed it. We reactively
332:24 fixed the error and um we're just making
332:26 sure that it is working as it should
332:28 now. Okay, there we go. It just hit the
332:30 tool and it says the event has been
332:31 created for tonight at 7 p.m. And if I
332:34 click into my calendar, you can see
332:35 right there we have the event that was
332:36 just created. So cool. Now that's
332:38 working. What we're going to do now is
332:39 add another tool. So, we'll drag this
332:40 one over here. And let's say we want to
332:42 do a send email tool. We're going to
332:44 send a message. We're going to change
332:46 the name to send email. And just so you
332:48 guys are aware like how it's able to
332:50 know right here, tool description, we're
332:52 setting automatically. If we set
332:53 manually, we would just say, you know,
332:55 use this tool to send an email. But we
332:57 can just keep it simple. Leave it as set
332:59 automatic. I'm going to turn on to
333:01 subject and message as defined by the
333:04 model. And that's going to be it. So now
333:06 we just want to test this thing again
333:07 before we add any prompts. We'll say
333:09 send an email to
333:12 bobacample.com asking what's up. We'll
333:15 send this off. Hopefully it's hitting
333:16 the right tool. So we should see there
333:17 we go. It hit the send email tool and
333:19 the email got sent. We can come in here
333:21 and check everything was sent correctly.
333:23 Although what we noticed is it's signing
333:24 off as best placeholder your name and we
333:27 don't want to do that. So let's come in
333:28 here and let's add a tool section for
333:31 this tool and we'll tell it how to how
333:33 to act. So send email. That's another
333:35 tool it has. And we're going to say use
333:37 this to send an
333:39 email. Then we're going to say sign off
333:41 emails as Frank. Okay. So that's
333:45 reactively fixing an error we saw. I'm
333:47 just now going to send off that same
333:48 query. We already know that it knows how
333:50 to call the tool. So it's going to do
333:51 that once again. There we go. We see the
333:53 email was sent. And now we have a sign
333:55 off as Frank. So that's two problems
333:56 we've seen. And then we've added one
333:58 super short line into the system prompt
334:00 and fixed those problems. Now let's do
334:02 something else. Let's say in Gmail we
334:04 want to be able to label an email. And
334:08 in order to label an email, as you can
334:10 see, add label to a message, we need a
334:13 message ID and we need a label name or
334:15 an ID for that label. And this is we
334:17 could choose from a list, but more
334:19 realistically, we want the label ID to
334:21 be pulled in dynamically. So if we need
334:23 to get these two things, what we have to
334:24 do is first get emails and also get
334:26 labels. So first I'm going to do get
334:28 many. I'm going to say this is using,
334:30 you know, we're we're calling this tool
334:32 get get emails. And then we don't want
334:34 to return all. We want to do a limit.
334:37 And we also want to choose from a
334:38 sender. So we'll have this also be
334:40 dynamically chosen. So cool. We don't
334:44 have a system prompt in here about this
334:45 tool, but we're just going to say get my
334:48 last email from Nate Herkman. So we'll
334:52 send that off. It should be hitting the
334:53 get emails tool, filling in Nate Herkman
334:55 as the sender. And now we can see that
334:57 we just got this email with a subject
334:59 hello. We have the message ID right
335:01 here. So that's perfect. And now what we
335:03 need to do is we need to create a tool
335:04 to get the label ID. So I'm going to
335:06 come in here and I'm going to say um get
335:08 many and we're going to go to label.
335:11 We're going to do um actually we'll just
335:14 return all. That works. There's not too
335:16 many labels in there. Um and we have to
335:17 name this tool of course. So we're going
335:19 to call this get labels. So once again
335:22 there's no tools in or no prompt in here
335:24 about these two tools at all. and we're
335:26 gonna say get my
335:29 email labels. We'll see if it hits the
335:31 right tool. There we go. It did. And it
335:34 is going to basically just tell us, you
335:36 know, here they are. So, here are our
335:37 different labels. Um, and here are the
335:40 ones that we created. So, promotion,
335:42 customer support, high priority,
335:43 finance, and billing. Cool. So, now we
335:46 can try to actually label an email. So,
335:48 that email that we just got from um from
335:51 Nate Hkelman that said hello, let's try
335:54 to label that one. So, I'm going to add
335:55 another Gmail tool, and this one's going
335:57 to be add a label to a message. And we
336:00 need the message ID and the label ID.
336:01 So, I'm just going to fill these in with
336:03 the model parameter, and I'm going to
336:05 call this tool add label. So, there's no
336:09 prompting for these three tools right
336:12 here, but we're going to try it out
336:13 anyway and see what happens. So, add a
336:17 promotion label to my last email
336:20 from Nate
336:22 Herklman. Send that off. See what
336:24 happens? It's getting emails. It tried
336:27 to add a label before. So, now we're
336:29 kind of We got in that weird loop. As
336:30 you can see, it tried to add a label
336:32 before it got labels. So, it didn't know
336:34 what to do, right? Um, we'll click into
336:36 here. We'll see that I don't really
336:38 exactly know what happened. Category
336:40 promotions. Looking in my inbox,
336:42 anything sent from Nate Hkelman, we have
336:43 the email right here, but it wasn't
336:44 accurately labeled. So, let's go back
336:47 into our agent and prompt this thing a
336:48 little bit better to understand how to
336:50 use these tools. So, I'm going to
336:52 basically go into the tools section here
336:53 and I'm going to tell it about some more
336:55 tools that it has. So, get emails,
336:57 right? This one was it was already
336:59 working properly and we're just saying
337:01 use this to get emails. Now, we have to
337:04 add get labels. We're just saying use
337:07 this to get
337:10 labels. Um, and we know that we want it
337:13 to use this before actually trying to
337:14 add a label, but we're not going to add
337:16 that yet. We're going to see if it can
337:17 work with a more minimalistic prompt.
337:19 And then finally, I'm going to say add
337:21 labels. And this one is use this tool to
337:24 add a label to an email. Okay. So now
337:28 that we just have very basic tool
337:30 descriptions in here, we don't actually
337:32 say like when to use it or how. So I'm
337:34 going to try this exact same thing
337:35 again. Add a promotion label to my last
337:37 email from Nate HKman. Once again, it
337:39 tried to use ad label before and it
337:41 tried to just call it twice as you can
337:42 see. So not working. So back in email, I
337:46 just refreshed and you can see the email
337:47 is still not labeled correctly. So,
337:50 let's do some more reactive prompting.
337:51 What we're going to do now is just say
337:53 in order to add labels, so in the
337:55 description of the ad label tool, I'm
337:56 going to say you must
337:59 first use get
338:01 emails to get the message ID. And
338:06 actually, I want to make sure that it
338:07 knows that this is a tool. So, what I'm
338:08 going to do is I'm going to put it in in
338:10 a quote, and I'm going to make it the
338:11 exact same capitalization as we defined
338:13 over here. So you must first use get
338:15 emails to get the message
338:17 ID of the email to
338:20 label. Then you must use get
338:24 labels to get the label ID of the email
338:29 to label. Okay. So we added in this one
338:32 line. So if it's still not working, we
338:33 know that this line wasn't enough. I'm
338:35 going to hit save and I'm going to try
338:36 the exact same thing again. Add a
338:38 promotion label to my last email. So
338:39 it's getting now it's getting labels and
338:42 now it still had an error with adding
338:43 labels. So, we'll take a look in here.
338:44 Um, it said that it did it successfully,
338:46 but obviously didn't. It filled in label
338:50 127 blah blah blah. So, I think the
338:53 message ID is correct, but the label ID
338:54 is not. So, what I'm going to try now is
338:57 reactively prompting in here. I'm going
338:58 to say the label ID of the email to
339:03 label. We'll try that. We'll see if that
339:05 fixes it. It may not. We'll have to keep
339:07 going. So, now we'll see. It's going to
339:09 at least it fixed the order, right? So,
339:10 it's getting emails and getting labels
339:11 first. And now look at that. We
339:14 successfully got a labeled email. As you
339:15 can see, we have our um maybe we didn't.
339:19 We'll have to go into Gmail and actually
339:20 check. Okay, never mind. We did. As you
339:22 can see, we got the promotion email for
339:24 this one from Nate Hookman that says
339:26 hello. And um yeah, that's just going to
339:28 be a really cool simple example of how
339:32 we sort of take on the process of
339:34 running into errors, adding lines, and
339:36 being able to know exactly what caused
339:37 what. So, I know the video was kind of
339:38 simple and I went through it pretty
339:39 fast, but I think that it's going to be
339:41 a good lesson to look back on as far as
339:43 the mindset you have and approaching
339:45 reactively prompting and adding
339:46 different tools and testing things
339:48 because at the end of the day, building
339:49 agents is a super super testheavy
339:52 iterative, you know, refining process of
339:55 build, test, change, build, test,
339:57 change, all that kind of stuff. All
339:58 right, so these next sections are a
339:59 little bit more miscellaneous, but cool
340:01 little tips that you can play around
340:02 with with your AI agents. We're going to
340:04 be talking about output parsing, human
340:06 in the loop, error workflows, and having
340:08 an agent have a dynamic brain. So, let's
340:11 get into it. All right, so output
340:12 parsing. Let's talk about what it
340:15 actually means and why you need to use
340:16 it. So, just to show you guys what we're
340:18 working with, I'm just going to come in
340:20 here real quick and ask our agent to
340:21 create an email for us. And when it does
340:23 this, the idea is that it's going to
340:25 create a subject and a body so that we
340:27 could drag this into a Gmail node. So
340:30 actually before I ask it to do that,
340:32 let's just say we're we're dragging in a
340:33 Gmail node and we want to have this guy
340:36 send an email. We're if I can find this
340:38 node which is right up here. Okay, send
340:39 a message. Now what you can see is that
340:42 we have different fields that we need to
340:43 configure the two, the subject and the
340:46 message. So ideally when we're asking
340:48 the agent to create an email, it will be
340:51 able to output those three different
340:52 things. So let me just show an example
340:54 of that. Please send an email to
340:58 nateample.com asking what's up. We need
341:01 the to the subject and the
341:04 email. Okay, so ideally we wouldn't say
341:06 that every time because um we would have
341:09 that in the system prompt. The issue is
341:11 this workflow doesn't let you run if the
341:12 node is errored and it's errored because
341:14 we didn't fill out stuff. So I'm just
341:15 going to resend this message. But let me
341:17 show you guys exactly why we need to use
341:19 an output parser. So it outputs the two
341:21 to the subject and the message. And if
341:23 we actually click into it though, the
341:24 issue is that it comes through all in
341:26 one single, you know, item called
341:30 output. And so you can see we have the
341:31 two, the subject, and the message. And
341:33 now if I went into here to actually map
341:35 these variables, I couldn't have them
341:37 separated or I would need to separate
341:39 them in another step because I want to
341:41 drag in the dynamic variable, but I can
341:43 only reference all of it at once. So
341:45 that's not good. That's not what we
341:47 want. That's why we need to connect an
341:48 output parser. So I'm going to click
341:50 into here. And right here there's an
341:52 option that says require specific output
341:53 format. And I'm going to turn that on.
341:55 What that does is it just gave us
341:57 another option to our AI agent. So
341:59 typically we basically right here have
342:00 chat model, memory, and tool. But now we
342:03 have another one called output parser.
342:04 So this is awesome. I'm going to click
342:06 onto the output parser. And you can see
342:08 that we have basically three options.
342:10 99.9% of the time you are just going to
342:12 be using a structured output parser
342:14 which means you're able to give your
342:17 agent basically a defined JSON schema
342:20 and it will always output stuff in that
342:22 schema if you need to have it kind of be
342:25 a little bit automatically fixed with AI
342:28 like I said I almost never have to use
342:29 this but that's what you would use the
342:31 autofixing output parser for so if I
342:33 click on the structured output parser
342:35 what happens is right now we see a JSON
342:37 example so if we were to talk to our
342:39 agent and say hey can you um you know
342:41 tell me some information about
342:42 California. It would output the state in
342:44 one string item called state and then
342:48 would also output an array of cities LA,
342:50 San Francisco, San Diego. So what we
342:53 want to do is we want to quickly define
342:54 to our AI agent how to output
342:56 information and we know that we wanted
342:58 to output based on this node. We need a
343:01 two, we need a subject, and we need a
343:03 message. So don't worry, you're not
343:05 going to have to write any JSON
343:07 yourself. I'm going to go to chatgbt and
343:09 say, "Help me write a JSON example for a
343:12 structured output parser in NADN. I need
343:15 the AI agent to output a two field, a
343:18 subject field, and a body field." We'll
343:22 just go ahead and send this off. And as
343:24 you guys know, all LLMs are trained
343:26 really well on JSON. It's going to know
343:28 exactly what I'm asking for here. And
343:29 all I'm going to have to do is copy this
343:31 and paste that in. So once this finishes
343:33 up, it's very simple. Two, subject body.
343:36 And it's being a little extra right now
343:38 and giving me a whole example body, but
343:39 I just have to copy that. I have to go
343:41 into here and just replace that JSON
343:43 example. Super simple. And now hopefully
343:48 I don't even have to prompt this guy at
343:49 all. And we'll give it a try. But if
343:51 it's not working, what we would do is we
343:53 would prompt in here and say, "Hey, here
343:54 is basically how we want you to output
343:56 stuff. Here's your job." All that kind
343:57 of stuff, right? But let me just resend
343:59 this message. We'll take a look. We'll
344:01 see that it called its output parser
344:02 because this is green. And now let's
344:05 activate the Gmail node and click in.
344:07 Perfect. So what we see on this left
344:09 hand side now is we have a two, we have
344:11 a subject, and we have a body, which
344:13 makes this so much easier to actually
344:14 map out over here and drag in. So in
344:19 different agents in this course, you're
344:21 going to see me using different
344:22 structured output parsers, whether that
344:24 is to get to subject and body, whether
344:27 that is to create different stories,
344:28 stuff like that. Let me just show one
344:30 more quick example of like a different
344:31 way you could use this. I'm going to
344:32 delete this if I can actually delete it.
344:35 And we are going to just change up the
344:37 structure output parser. So let's say we
344:40 want an AI agent
344:41 to create a story for us. So I'm going
344:44 to just talk to this guy again. Help me
344:48 write a different JSON example where I
344:51 want to have the agent output a title of
344:54 the story, an array of characters, and
344:57 then three different scenes. Okay. So
345:00 we'll send that off and see what it
345:01 does. And just keep in mind it's
345:03 creating this JSON basically a template
345:05 that's telling your agent how to output
345:07 information. So we would basically say,
345:09 "Hey, create me a story about um a
345:12 forest." And it would output a title,
345:14 three characters, and three different
345:16 scenes as you can see here. So we'll
345:19 copy this. We'll paste this into here.
345:22 And once again, I'm not even going to
345:23 prompt the agent. And let's see how it
345:25 does. Please create me a story about an
345:29 airplane.
345:31 Okay, we'll go ahead and take a look at
345:33 what this is going to do. This one's
345:35 going to spin a little bit longer. Oh,
345:36 wow. Didn't even take too long. So, it
345:38 called the structured output parser. And
345:40 now, let's click into the agent and see
345:41 how it output. Perfect. So, we have the
345:44 title is the adventure of Skyward the
345:47 airplane. We have four characters,
345:49 Skyward, Captain Jane, Navigator Max,
345:51 and ground engineer Leo. And then you
345:54 can see we have four different scenes
345:56 that each come with a scene number and a
345:57 description. So if we wanted to, we
345:59 could have this be like, you know, maybe
346:01 we want an image prompt for each of
346:03 these scenes. So we can feed that into
346:04 an image generation model and we would
346:05 just have to go into that chatbt and
346:07 say, "Hey, for each scene, add another
346:09 field called image prompt." And it would
346:11 just basically take care of it. So just
346:12 wanted to show you how this works, how
346:14 easy it is to set up these different
346:15 JSON structured output parsers and why
346:18 it's actually valuable to do within. So
346:21 hopefully that opened your eyes a little
346:22 bit. Appreciate your time.
346:27 Okay, our workflow is actively listening
346:29 for us in Telegram and I'm going to ask
346:30 it to make an expost about coffee at
346:32 night. So, as you can see, this first
346:33 agent is going to search the internet
346:35 using Tavi and create that initial X
346:37 post for us. Now, we just got a message
346:39 back in our Telegram that says, "Hey, is
346:41 this post good to go?" Drinking coffee
346:42 at night can disrupt your sleep since
346:44 caffeine stays in your system for hours,
346:45 often leading to poorer sleep quality.
346:48 So, what I'm going to do is click on
346:49 respond. And this gives us the ability
346:50 to give our agent feedback on the post
346:52 that it initially created. So, here is
346:54 that response window and I'm going to
346:55 provide some feedback. So, I'm telling
346:56 the agent to add at the end of the tweet
346:58 unless it's decaf. And as soon as I hit
347:00 submit, we're going to see this go down
347:02 the path. It's going to get classified
347:03 as a denial message. And now the
347:05 revision agent just made those changes
347:07 and we have another message in our
347:08 telegram with a new X post. So now, as
347:10 you can see, we have a new post. I'm
347:11 going to click on respond and open up
347:13 that window. And what we can see here is
347:14 now we have the changes made that we
347:16 requested. At the end, it says unless
347:18 it's decaf. So now all we have to do is
347:20 respond good to go. And as soon as we
347:21 submit this, it's going to go up down
347:23 the approval route and it's going to get
347:25 submitted and posted to X. So, here we
347:27 go. Let's see that in action. I'll hit
347:28 submit and then we're going to watch it
347:29 get posted onto X. And let's go check
347:31 and make sure it's there. So, here's my
347:33 beautiful X profile. And as you can see,
347:34 I was playing around with some tweets
347:35 earlier. But right here, we can see
347:37 drinking coffee at night can disrupt
347:38 your sleep. We have the most recent
347:40 version because it says unless it's
347:41 decaf. And then we can also click into
347:43 the actual blog that Tavi found to pull
347:45 this information from. So, now that
347:47 we've seen this workflow in action,
347:48 let's break it down. So the secret that
347:50 we're going to be talking about today is
347:51 the aspect of human in the loop, which
347:53 basically just means somewhere along the
347:55 process of the workflow. In this case,
347:56 it's happening right here. The workflow
347:58 is going to pause and wait for some sort
348:00 of feedback from us. That way, we know
348:02 before anything is sent out to a client
348:04 or posted on social media, we've
348:06 basically said that we 100% agree that
348:08 this is good to go. And if the initial
348:10 message is not good to go, we have the
348:12 ability to have this unlimited revision
348:14 loop where it's going to revise the
348:16 output over and over until we finally
348:18 agree that it's good to go. So, we have
348:20 everything color coded and we're going
348:21 to break it down as simple as possible.
348:23 But before we do that here, I just
348:24 wanted to do a real quick walkthrough of
348:26 a more simple human in the loop because
348:28 what's going on up here is it's just
348:30 going to say, "Do you like this?" Yes or
348:31 no compared to down here where we
348:33 actually give textbased feedback. So,
348:35 we'll break them both down, but let's
348:36 start up here real quick. And by the
348:37 way, if you want to download the
348:38 template for free and play around with
348:40 either of these flows, you can get that
348:42 in my free school community. The link
348:43 for that will be down in the
348:44 description. And when it comes to human
348:45 in the loop in Naden, if you click on
348:47 the plus, you can see down here, human
348:48 in the loop, wait for approval or human
348:51 input before continuing. You click on
348:53 it, you can see there's a few options,
348:54 and they all just use the operation
348:56 called send and wait for response. So
348:58 obviously there's all these different
348:59 integrations, and I'm sure more will
349:01 even start to roll out, but in this
349:03 example, we're just using Telegram.
349:04 Okay, so taking a look at this more
349:05 simple workflow, we're going to send off
349:06 the message, make an expost about AI
349:08 voice agents. What's happening is the
349:10 exact same thing as the demo where this
349:11 agent is going to search the web and
349:13 then it's going to create that initial
349:14 content for us. And now we've hit that
349:16 human in the loop step. As you can see,
349:18 it's spinning here purple because it's
349:20 waiting for our approval. So in our
349:21 Telegram, we see the post. It asks us if
349:23 this is good to go. And let's just say
349:25 that we don't like this one, and we're
349:26 going to hit decline. So when I hit
349:27 decline, it goes down this decision
349:29 point where it basically says, you know,
349:31 did the human approve? Yes or no. If
349:32 yes, we'll post it to X. If no, it's
349:34 going to send us a denial message, which
349:36 basically just says post was denied.
349:38 Please submit another request. And so
349:40 that's really cool because it gives us
349:41 the ability to say, okay, do we like
349:43 this? Yes. And it will get posted.
349:44 Otherwise, just do nothing with it. But
349:46 what if we actually want to give it
349:48 feedback so that it can take this post?
349:49 We can give it a little bit of criticism
349:51 and then it will make another one for us
349:53 and it just stays in that loop rather
349:55 than having to start from square one. So
349:56 that's exactly what I did down here with
349:58 the human and loop 2.0 know where we're
349:59 able to give textbased feedback instead
350:02 of just saying yes or no. So now we're
350:04 going to break down what's going on
350:05 within every single step here. So what
350:07 I'm going to do is I'm going to click on
350:08 executions. I'm going to go to the one
350:10 that we did in the live demo and bring
350:12 that into the workflow so we can look at
350:14 it. So what we're going to do is just do
350:15 another live run and walk through step
350:18 by step the actual process of this
350:20 workflow. So I'm going to hit test
350:21 workflow. I'm going to pull up Telegram
350:23 and then I'm going to ask it to make us
350:24 an expost. Okay, so I'm about to fire
350:26 off make me an expost about crocodiles.
350:28 So sent that off. This expost agent is
350:31 using its GPT41 model as well as Tavly
350:34 search to do research, create that post,
350:37 and now we have the human in the loop
350:38 waiting for us. So before we go look at
350:40 that, let's break down what's going on
350:42 up front. So the first phase is the
350:43 initial content. This means that we have
350:45 a telegram trigger, and that's how we're
350:46 communicating with this workflow. And
350:48 then it gets fed into the first agent
350:50 here, which is the expost agent. Let's
350:52 click into the expost agent and just
350:53 kind of break down what's going on here.
350:54 here. So, the first thing to notice is
350:56 that we're looking for some sort of
350:57 prompt. The agent needs some sort of
350:59 user message that it's going to look at.
351:01 In this case, we're not doing the
351:03 connected chat trigger node. We're
351:04 looking within our Telegram node because
351:06 that's where the text is actually coming
351:08 through. So, on this lefth hand side, we
351:09 can see all I basically did was right
351:11 here is the text that we typed in, make
351:13 me an expost about crocodiles. And all I
351:15 did was I dragged this right into here
351:17 as the user message. And that is what
351:18 the agent is actually looking at in
351:20 order to take action. And then the other
351:21 thing we did was gave the agent a system
351:23 message which basically defines its
351:25 behavior. And so here's what we have.
351:27 The overview is you are an AI agent
351:29 responsible for creating expost based on
351:31 a user's request. Your instructions are
351:33 to always use the Tavly search tool to
351:35 find accurate information. Write an
351:37 informative engaging tweet, include a
351:39 brief reference to the source directly
351:40 in the tweet and only output the tweet.
351:43 We listed its tool which it only has one
351:45 called tavly search and we told it to
351:46 use this for real-time web search and
351:48 then just gave it an example basically
351:50 saying okay here's an input you may get
351:52 here's the action you will take and then
351:54 here's the output that we want you to
351:56 output and then we just gave them final
351:57 notes and I know I may be read through
351:59 this pretty quick but keep in mind you
352:01 can download the template for free and
352:02 the prompt will be in there and then
352:03 what you could do is you can click on
352:04 the logs for an agent and you can
352:06 basically look at its behavior so we can
352:08 see that it used its chat model GBT4.1
352:11 read through the system prompt decided
352:12 said, "Okay, I need to go use tably
352:14 search." So, here's how it searched for
352:16 crocodile information. And then it used
352:18 its model again to actually create that
352:20 short tweet right here. And then we'll
352:22 just take a quick look at what's going
352:23 on within the actual Tavi search tool
352:25 here. So, if you download this template,
352:27 all you'll have to do is plug in your
352:28 own credential. Everything else should
352:30 be set up for you. But, let me just
352:32 break it down real quick. So, if you go
352:33 to tavly.com and create an account, you
352:35 can get a,000 free searches per month.
352:37 So, that's the kind of plan I'm on. But
352:39 anyways, here is the documentation. You
352:41 can see right here we have the Tavi
352:42 search endpoint which is right here. All
352:44 we have to do is authorize ourselves. So
352:46 we'll have an authorization as a header
352:48 parameter and then we'll do bearer space
352:50 our API token. So that's how you'll set
352:52 up your own credential. And then all I
352:53 did was I copied this data field into
352:55 the HTTP request. And this is where you
352:57 can do some configuration. You can look
352:59 through the docs to see how you want to
353:00 make this request. But all I wanted to
353:02 do here was just change the search
353:03 query. So back in end you can see in my
353:05 body request I I changed the query by
353:08 using a placeholder. Right here it says
353:10 use a placeholder for any data to be
353:11 filled in by the model. So I changed the
353:13 query to a placeholder called search
353:15 term. And then down here I defined the
353:17 search term placeholder as what the user
353:18 is searching for. So what this means is
353:20 the agent is going to interpret our
353:22 query that we sent in telegram. It's
353:24 then going to use this tavly tool and
353:27 basically use its brain to figure out
353:28 what should I search for. And in this
353:30 case on the lefth hand side you can see
353:31 that it filled out the search term with
353:33 latest news or facts about crocodiles.
353:36 And then we get back our response with
353:38 information and a URL. And then it uses
353:40 all of this in order to actually create
353:42 that post. Okay. So, here's where it may
353:44 seem like it's going to get a little
353:45 tricky, but it's not too bad. Just bear
353:47 with me. And I wanted to do some color
353:48 coding here so we could all sort of stay
353:50 on the same page. So, what we're doing
353:52 now is we're setting the post. And this
353:54 is super important because we need to be
353:56 able to reference the post later in the
353:57 workflow. whether that's when we're
353:59 actually sending it over to X or when
354:02 we're making a revision and we need the
354:04 revision agent to look at the original
354:05 post as well as the feedback from the
354:07 human. So in the set node, all we're
354:10 doing is we're basically setting a field
354:11 called post and we're dragging in a
354:13 variable called JSON.output. And this
354:15 just means that it's going to be
354:17 grabbing the output from this agent or
354:19 the revision agent no matter what. As
354:20 you can see, it's looped back into this
354:22 set because if we're defining a variable
354:24 using dollar sign JSON, it means that
354:26 we're going to be looking for whatever
354:27 node immediately finished right before
354:29 this one. And so that's why we have to
354:31 keep this one kind of flexible because
354:32 we want to make sure that at the end of
354:34 the day, if we made five or six or seven
354:36 revisions, that only the most recent
354:38 version will actually be posted on X. So
354:41 then we move into the human in the loop
354:42 phase of this workflow. And as you can
354:44 see, it's still spinning. It's been
354:45 spinning this whole time while we've
354:46 been talking, but it's waiting for our
354:48 response. So anyways, it's a send and
354:50 wait for a response operation. As you
354:51 can see right here, the chat ID is
354:54 coming from our Telegram trigger. So if
354:55 I scroll down in the Telegram trigger on
354:57 the lefth hand side, you can see that I
354:59 have a chat ID right here. And all I did
355:00 was I dragged this in right here.
355:02 Basically just meaning, okay, whoever
355:03 communicates with this workflow, we need
355:05 to send and get feedback from that
355:07 person. So that's how we can make this
355:08 dynamic. And then I just made my message
355:10 basically say, hey, is this good to go?
355:12 And then I'm dragging in the post that
355:14 we set earlier. So this is another
355:16 reason why it's important is because we
355:18 want to request feedback on the most
355:20 recent version as well, not the first
355:21 one we made. And then like I mentioned
355:23 within all of these human in the loop
355:24 nodes, you have a few options. So you
355:26 can do free text, which is what we're
355:28 doing here. Earlier what we did was
355:29 approval, which is basically you can
355:31 say, hey, is there an approve button? Is
355:32 there an approve and a denial button?
355:34 How do you want to set that up? But this
355:35 is why we're doing free text because it
355:37 allows for us to actually give feedback,
355:39 not just say yes or no. Cool. So what
355:40 we're going to do now is actually give
355:43 our feedback. So, I'm going to come into
355:45 here. We have our post about crocodiles.
355:47 So, I'm going to hit respond and it's
355:49 going to open up this new page. And so,
355:50 yes, it's a little annoying that this
355:51 form has to pop up in the browser rather
355:53 than natively in Telegram or whatever,
355:56 you know, Slack, Gmail, wherever you're
355:58 doing the human in the loop, but I'm
355:59 sure that'll be a fix that'll come soon.
356:00 But, it's just right now, I think it's
356:01 coming through a web hook. So, they just
356:03 kind of have to do it like this.
356:04 Anyways, let's say that we want to
356:06 provide some feedback and say make this
356:07 shorter. So, I'm going to say make this
356:09 shorter. And as I submit it, you're
356:11 going to see it go to this decision
356:13 point and then it's going to move either
356:14 up or down. And this is pretty clearly a
356:16 denial message. So we'll watch it get
356:18 denied and go down to the revision agent
356:20 as you can see. And just like that that
356:22 quickly, we already have another one to
356:24 look at. So before we look at it and
356:26 give feedback, let's just look at what's
356:28 actually going on within this decision
356:29 point. So in any automation, you get to
356:31 a point where you have to make a
356:32 decision. And what's really cool about
356:34 AI automation is now we can use AI to
356:36 make a decision that typically a
356:37 computer couldn't because a typical
356:39 decision would be like is this number
356:41 greater than 10 or less than 10. But now
356:42 it can read this text that we submitted.
356:44 Make this shorter and it can say okay is
356:46 this approved or declined. And basically
356:48 I just gave it some short definitions of
356:50 like what an approval message might look
356:52 like and what a denial message might
356:53 look like. And you can look through that
356:55 if you download the template. But as you
356:56 can see here it pushed this message down
356:58 the declined branch because we asked it
357:00 to make a revision. And so it goes down
357:01 the denial branch which leads into the
357:03 revision agent. And this one's really
357:05 really simple. All we did here was we
357:07 gave it two things as the user message.
357:09 We said here's the post to revise. So as
357:12 you can see it's this is the initial
357:13 post that the first agent made for us.
357:15 And then here is the human feedback. So
357:17 it's going to look at this. It's going
357:18 to look at this and then it's going to
357:19 make those changes because all we said
357:21 in the system prompt was you're an
357:23 expert Twitter writer. Your job is to
357:24 take an incoming post and revise it
357:26 based on the feedback that the human
357:27 submitted. And as you can see here is
357:29 the output. it made the tweet a lot
357:31 shorter. And that's the beauty of using
357:32 the set node is because now we loop that
357:34 back in. The most recent version has
357:36 been submitted to us for feedback. So,
357:38 let's open that up real quick in our
357:40 Telegram. And now you can see that the
357:41 shorter tweet has been submitted to us.
357:43 And it's asking for a response. So, at
357:45 this point, let's say we're good to go
357:46 with this tweet. I'm going to click
357:47 respond. Open up this tab. Recent
357:49 crocodile attacks in Indonesia.
357:50 Highlight the need for caution in their
357:52 habitats. Stay safe. We've got a few
357:54 emojis. And I'm just going to say, let's
357:56 just say send it off because it can
357:58 interpret multiple ways of saying like
358:00 yes, it's good to go. So, as soon as I
358:02 hit submit, we're going to watch it go
358:03 through the decision point and then post
358:05 on our X. So, you see that right here,
358:07 text classifier, and now it has been
358:09 posted to X. And I just gave our X
358:11 account a refresh. You can see that we
358:12 have that short tweet about recent
358:14 crocodile attacks. Okay, so now that
358:16 we've seen another example of a live run
358:17 through, a little more detailed, let me
358:19 talk about why I made the color coding
358:21 like this. So the set note here, its job
358:23 is basically just I'm going to be
358:24 grabbing the most recent version of the
358:27 post because then I can feed it into the
358:29 human in the loop. I can then feed that
358:31 into the revision if we need to make
358:33 another revision because you want to be
358:34 able to make revisions on top of
358:36 revisions. You don't want to be only
358:38 making revisions on the first one.
358:39 Otherwise, you're going to be like,
358:40 what's the point? And then also, of
358:42 course, you want to post the most recent
358:44 version, not the original one, because
358:46 again, what's the point? So in here, you
358:47 can see there's two runs. The first one
358:49 was the first initial content creation
358:52 and then the second one was the revised
358:53 one. Similarly, if we click into the
358:55 next node which was request feedback,
358:57 the first time we said make this shorter
358:59 and then the second time we said send it
359:01 off. And then if we go into the next
359:02 node which was the text classifier, we
359:04 can see the first time it got denied
359:06 because we said make this shorter and
359:08 the second time it said send it off and
359:10 it got approved. And that's basically
359:12 the flow of you know initial creation.
359:14 We're setting the most recent version.
359:16 We're getting feedback. We're making a
359:18 decision using AI. And as you can tell
359:20 for the text classifier, I'm using 2.0
359:22 Flash rather than GPT 4.1. And then of
359:25 course, if it's approved, it gets
359:27 posted. If it's not, it makes revisions.
359:29 And like I said, this is unlimited
359:30 revisions. And it's revisions on top of
359:32 revisions. So when it comes to Human in
359:34 the Loop, you can do it in more than
359:35 just Telegram, too. So if you click on
359:37 the plus, you can see right here, Human
359:38 in the Loop, wait for approval or human
359:40 input before continuing. We've got
359:42 Discord, Gmail, Chat, Outlook, Telegram,
359:45 Slack. We have a lot of stuff you can
359:46 do. However, so far with my experience,
359:48 it's been limited to one workflow. And
359:51 what do I mean by that? It's kind of
359:52 tough to do this when you're actually
359:54 giving an agent a tool that's supposed
359:56 to be waiting for human approval. So,
359:58 let me show you what I mean by that.
359:59 Okay, so here's an agent where I tried
360:00 to do a human in the loop tool because
360:02 we have the send and wait message
360:04 operation as a tool for an agent. So,
360:06 let me show you what goes on here. We'll
360:08 hit test workflow. Okay, so I'm going to
360:09 send off get approval for this message.
360:11 Hey John, just wanted to see if you had
360:13 the meeting minutes. And you're going to
360:14 watch that it's going to call the get
360:15 approval tool, but here's the issue. So,
360:19 it's waiting for a response, right? And
360:21 we have the ability to respond, but the
360:23 waiting is happening at the agent level.
360:25 It really should be waiting down here
360:26 for the tool because, as you saw in the
360:28 previous example, the response from this
360:30 should be the actual feedback from the
360:32 human. And we haven't submitted that
360:33 yet. And right now, the response from
360:35 this tool is literally just the message.
360:38 So, what you'll see here is if I go back
360:40 into Telegram and I click on respond and
360:41 we open up this tab, it basically just
360:43 says no action required. And if I go
360:45 back into the workflow, you can see it's
360:47 still spinning here and there's no way
360:49 for this to give another output. So, it
360:51 just doesn't really work. And so, what I
360:52 was thinking was, okay, why don't I just
360:54 make another workflow where I just use
360:56 the actual node like we saw on the
360:57 previous one. That should work fine
360:59 because then it should just spin down
361:00 here on the tool level until it's ready.
361:03 And so, let me show you what happens if
361:04 we do that. Okay, so like I said, I
361:05 built a custom tool down here which is
361:07 called get approval. It would be sending
361:08 the data to this workflow, it would send
361:10 off an approval message using the send
361:12 and wait, and it doesn't really work. I
361:14 even tried adding a wait here. But what
361:16 happens typically is when you use a
361:18 workflow to call another one, it's going
361:20 to be waiting and looking in the last
361:21 node of that workflow for the response,
361:23 but it doesn't yet work yet with these
361:26 operations. And I'll show you guys why,
361:27 and I'm sure NNN will fix this soon, but
361:29 it's just not there yet. So, I'm just
361:30 going to send off the exact same query,
361:32 get approval for this message. We'll see
361:34 it call the tool and basically as you
361:35 can see it finished up instantly and now
361:38 it's waiting here and we already did get
361:40 a message back in telegram which
361:41 basically said ready to go hey John just
361:43 wanted to see if you had the meeting
361:44 minutes and it gives us the option to
361:45 approve or deny and if we click into the
361:48 subworkflow this one that it actually
361:50 sent data to. We can see that the
361:51 execution is waiting. So this workflow
361:53 is properly working because it's waiting
361:55 here for human approval. But if we go
361:57 back into the main flow it's waiting
361:59 here at the agent level rather than
362:01 waiting here. So, there's no way for the
362:03 agent to actually get our live feedback
362:05 and use that to take action how it needs
362:07 to. So, I just wanted to show you guys
362:09 that I had been experimenting with this
362:10 as a tool. It's not there yet, but I'm
362:12 sure it will be here soon. And when it
362:14 is, you can bet that I'll have a video
362:16 out about
362:19 it. Today, I'm going to be showing you
362:21 guys how you can set up an error
362:22 workflow in NAN so that you can log all
362:24 of your errors as well as get notified
362:26 every time one of your active workflows
362:27 fails. The cool part is all we have to
362:29 do is set up one error workflow and then
362:31 we can link that one to all of our
362:32 different active workflows. So I think
362:34 you'll be pretty shocked how quick and
362:35 easy this is to get set up. So let's get
362:37 into the video. All right, so here's the
362:38 workflow that we're going to be using
362:39 today as our test workflow that we're
362:41 going to purposely make error and then
362:43 we're going to capture those errors in a
362:44 different one and feed that into a
362:46 Google sheet template as well as some
362:47 sort of Slack or email notification. And
362:50 if you haven't seen my recent video on
362:51 using this new think tool in edit then
362:52 I'll tag it right up here. Anyways, in
362:54 order for a workflow to trigger an error
362:56 workflow, it has to be active. So, first
362:58 things first, I'm going to make this
362:59 workflow active. There we go. This one
363:00 has been activated. And now, what I'm
363:02 going to do is go back out to my NAD.
363:04 We're going to create a new workflow.
363:05 And this is going to be our error logger
363:07 workflow. Okay. So, you guys are going
363:09 to be pretty surprised by how simple
363:10 this workflow is going to be. I'm going
363:11 to add a first step. And I'm going to
363:13 type an error. And as you can see,
363:14 there's an error trigger, which says
363:16 triggers the workflow when another
363:17 workflow has an error. So, we're going
363:18 to bring this into the workflow. We
363:20 don't have to do anything to configure
363:21 it. You can see that what we could do is
363:23 we could fetch a test event just to see
363:24 what information could come back. But
363:27 what we're going to do is just trigger a
363:28 live one because we're going to get a
363:29 lot more information than what we're
363:31 seeing right here. So, quickly pay
363:33 attention to the fact that I named this
363:34 workflow error logger. I'm going to go
363:36 back into my ultimate assistant active
363:38 workflow. Up in the top right, I'm going
363:40 to click on these three dots, go down to
363:41 settings, and then right here, there's a
363:43 setting called error workflow, which as
363:45 you can see, a second workflow to run if
363:46 the current one fails. The second
363:48 workflow should always start with an
363:50 error trigger. And as you saw, we just
363:52 set that up. So, all I have to do is
363:53 choose a workflow. I'm going to type an
363:55 error and we called it error logger. So
363:57 I'm going to choose that one, hit save.
363:59 And now these two workflows are
364:00 basically linked so that if this
364:02 workflow ever has an error that stops
364:04 the workflow, it's going to be captured
364:06 in our second one over here with the
364:08 information. So let's see a quick
364:09 example of that. Okay, so this workflow
364:11 is active. It has a telegram trigger as
364:13 you can see. So I'm going to drag in my
364:14 telegram and I'm just going to say,
364:16 "Hey." And what's going to happen is
364:17 obviously we're going to get a response
364:19 back because this workflow is active and
364:21 it says, "How can I assist you today?"
364:23 Now, what I'm going to do is I'm just
364:24 going to get rid of the chat model. So,
364:26 this agent essentially has no brain. I'm
364:28 going to hit save. We're going to open
364:29 up Telegram again, and we're going to
364:31 say, "Hey." And now, we should see that
364:33 we're not going to get any response back
364:34 in Telegram. If we go into the
364:36 executions of this ultimate assistant,
364:38 you can see that we just got an error
364:39 right now. And that was when we just
364:41 sent off the query that said, "Hey," and
364:42 it errored because the chat model wasn't
364:44 connected. So, if we hop into our error
364:46 logger workflow and click on the
364:48 executions, we should see that we just
364:49 had a new execution. And if we click
364:52 into it, we'll see all the information
364:53 that came through. So what it's going to
364:55 tell us is the ID of the execution, the
364:57 URL of the workflow, the name of the
364:59 workflow, and then we'll also see what
365:01 node errored and the error message. So
365:03 here under the object node, we can see
365:05 different parameters. We can see what's
365:06 kind of how the node's configured. We
365:08 can see the prompt even. But what we're
365:10 interested in is down here we have the
365:11 name, which is ultimate assistant. And
365:13 then we have the message, which was a
365:14 chat model sub node must be connected
365:17 and enabled. So anyways, we have our
365:19 sample data. I'm going to hit copy to
365:21 editor, which just brings in that
365:22 execution into here so we can play with
365:24 it. And now what I want to do is map up
365:26 the logic of first of all logging it in
365:28 a Google sheet. So here's the Google
365:30 sheet template I'm going to be using.
365:31 We're going to be putting in a
365:32 timestamp, a workflow name, the URL of
365:35 the workflow, the node that errored, and
365:36 the error message. If you guys want to
365:38 get this template, you can do so by
365:39 joining my free school community. The
365:40 link for that's down in the description.
365:42 Once you join the community, all you
365:43 have to do is search for the title of
365:44 the video up top, or you can click on
365:46 YouTube resources, and you'll find the
365:48 post. And then in the post is where
365:49 you'll see the link to the Google sheet
365:51 template. Anyways, now that we have this
365:53 set up, all we have to do is go back
365:54 into our error logger. We're going to
365:56 add a new node after the trigger. And
365:57 I'm going to grab a sheets node. What we
365:59 want to do is append a row in sheets. Um
366:02 I'm just going to call this log error.
366:04 Make sure I choose the right credential.
366:05 And then I'm going to choose the sheet
366:06 which is called error logs. And so now
366:08 we can see we have the values we need to
366:10 send over to these different columns. So
366:11 for time stamp, all I'm going to do is
366:13 I'm actually going to make an expression
366:14 and I'm just going to do dollar sign
366:16 now. And this is basically just going to
366:18 send over to Google Sheets the current
366:19 time whenever this workflow gets
366:21 triggered. And if you don't like the way
366:22 this is coming through, you can play
366:23 around with format after dollar sign
366:26 now. And then you'll be able to
366:27 configure it a little bit more. And you
366:28 can also ask chat to help you out with
366:30 this JavaScript function. And feel free
366:32 to copy this if you want. I'm pulling in
366:34 the full year, month, day, and then the
366:35 time. Okay, cool. Then we're just pretty
366:37 much going to drag and drop the other
366:38 information we need. So the first thing
366:40 is the workflow name. And to get to
366:42 that, I'm going to close out of the
366:43 execution. and then we'll see the
366:44 workflow and we can pull in the name
366:45 right there which is ultimate personal
366:47 assistant. For the URL, I'm going to
366:49 open back up execution and grab the URL
366:51 from here. For node, all I have to do is
366:54 look within the node object. We're going
366:55 to scroll down until we see the name of
366:57 the node which is right here, the
366:59 ultimate assistant. And then finally,
367:01 the error message, which should be right
367:02 under that name right here. Drag that
367:04 in, which says a chat model sub node
367:06 must be connected and enabled. So now
367:08 that we're good to go here, I'm going to
367:09 test step and then we'll check our
367:10 Google sheet and make sure that that
367:11 stuff comes through correctly.
367:13 And as you can see, it just got
367:15 populated and we have the URL right
367:16 here, which if we clicked into, it would
367:18 take us to that main ultimate personal
367:20 assistant workflow. As you can see, when
367:22 this loads up, and it takes us to the
367:23 execution that actually failed as well,
367:25 so we could sort of debug. So now we
367:27 have an error trigger that will update a
367:29 Google sheet and log the information.
367:31 But maybe we also want to get notified
367:32 when there's an error. So I'm just going
367:34 to drag this off right below and I'm
367:35 going to grab the Slack node and I'm
367:38 going to choose to send a message right
367:40 here. and then we'll just configure what
367:41 we want to send over. Okay, so we're
367:43 going to be sending a message to a
367:44 channel. I'm going to choose the channel
367:46 all awesome AI stuff. And then we just
367:48 need to configure what the actual
367:50 message is going to say. So I'm going to
367:51 change this to an expression, make this
367:52 full screen and let's fill this out. So
367:55 pretty much just customize this however
367:57 you want. Let's say I want to start off
367:58 with workflow error and we will put the
368:02 name of the workflow. So I'll just close
368:04 out of here, throw that in there. So now
368:06 it's going to come through saying
368:06 workflow error ultimate personal
368:08 assistant. And then I'm going to say
368:10 like what node errored at what time and
368:12 what the error message was. So first
368:14 let's grab the name of the node. Um if I
368:16 just have to scroll down to name right
368:17 here. So ultimate assistant errored at
368:21 and I'm going to do that same dollar
368:23 sign now function. So it says ultimate
368:25 assistant errored at
368:27 2025417. And then I'm just going to go
368:29 down and say the error message was and
368:34 we're just going to drag in the error
368:36 message. There we go.
368:38 And then finally, we'll just provide a
368:40 link to the workflow. So see this
368:43 execution here. And then we'll drag in
368:45 the link, which is all the way up top.
368:48 And we should be good to go. And then if
368:49 you want to make sure you're not sending
368:50 over a little message at the bottom that
368:52 says this was sent from Nad, you're
368:54 going to add an option. You're going to
368:55 click on include link to workflow. And
368:56 then you're going to turn that off. And
368:58 now we hit test up. And we hop into
368:59 Slack. And we can see we got workflow
369:01 error ultimate personal assistant. We
369:02 have all this information. We can click
369:03 into this link. and we don't have this
369:05 little message here that says automated
369:06 with this NN workflow. So maybe you
369:09 could just set up a channel dedicated
369:10 towards error logging, whatever it is.
369:12 Okay, so let's save this real quick and
369:14 um let's just do another sort of like
369:17 example. Um one thing to keep in mind is
369:18 there's a difference between the
369:20 workflow actually erroring out and going
369:22 red and just something not working
369:24 correctly. And I'll show you exactly
369:25 what I meant by that. So this example
369:27 actually triggered the error workflow
369:29 because the execution on this side is
369:32 red and it shows an error. But what
369:33 happens is, for example, with our Tavly
369:35 tool right here, I have no
369:36 authentication pulled up. So this tool
369:38 is not going to work. But if I come into
369:40 Telegram and say search the web for
369:42 Apples, it's going to work. This this
369:45 workflow is going to go green even
369:46 though this tool is not going to work.
369:48 And we'll see exactly why. So as you can
369:49 see, it says I'm currently unable to
369:51 search the web due to a connection
369:52 error. So if we go into the execution,
369:54 we can see that this thing went green
369:56 even though it didn't work the way we
369:57 wanted to. But what happened is the tool
369:59 came back and it was green and it
370:01 basically just didn't work because our
370:02 authentication wasn't correct. And then
370:04 you can even see in the think node, it
370:06 basically said the web search function
370:07 is encountering an authentication error.
370:09 I need to let the user know the search
370:10 isn't currently available and offer
370:11 alternative ways to help blah blah blah.
370:13 But all of these nodes actually went
370:15 green and we're fine. So this example
370:18 did not trigger the error logger. As you
370:19 can see, if we check here, there's
370:21 nothing. We check in Slack, there's
370:22 nothing. So what we can do is we'll
370:24 actually make something error. So I'll
370:26 go into this memory and it's going to be
370:28 looking for a session ID within the
370:29 telegram trigger and I'm just going to
370:31 add an extra d. So this variable is not
370:33 going to work. It's probably going to
370:34 error out and now we'll actually see
370:36 something happen with our error
370:38 workflow. So I'm just going to say hey
370:40 and we will watch basically nothing will
370:42 come back
370:44 here. Okay, that confused me but I
370:47 realized I didn't save the workflow. So
370:48 now that we've saved it, this is not
370:49 going to work. So let's once again say
370:51 hey. And we should see that nothing's
370:52 going to come back over here. Um, I
370:54 believe if we go into our error logger,
370:56 we should see something pop through. We
370:57 just got that row and you can see the
370:59 node changed, the error message changed,
371:01 all that kind of stuff. And then in
371:02 Slack, we got another workflow error at
371:04 a new time and it was a different node.
371:07 And finally, we can just come into our
371:08 error logger workflow and click on
371:09 executions. And we'll see the newest run
371:12 was the one that we just saw in our logs
371:14 and in our Slack, which was the memory
371:17 node that aired. As you can see right
371:19 here, simple memory. And so really the
371:21 question then becomes, okay, well what
371:22 happens if this workflow in itself
371:24 errors too. I really don't foresee that
371:26 happening unless you're doing some sort
371:27 of crazy AI logic over here. But it
371:30 really needs to just be as simple as
371:31 you're mapping variables from here
371:32 somewhere else. So you really shouldn't
371:34 see any issues. Maybe an authentication
371:36 issue, but I don't know. Maybe if this
371:38 if this workflow is erring for you a
371:39 ton, you probably are just doing
371:40 something wrong. Anyways, that's going
371:42 to do it for this one. I know it was a
371:43 quicker one, but hopefully if you didn't
371:45 know about this, it's something that
371:46 you'll implement and it will be helpful.
371:51 If you've ever wondered which AI model
371:53 to use for your agents and you're tired
371:54 of wasting credits or overpaying for
371:56 basic tasks, then this video is for you
371:58 because today I'm going to be showing
371:59 you a system where the AI agent picks
372:01 its brain dynamically based on the task.
372:04 This is not only going to save you
372:05 money, but it's going to boost
372:06 performance and we're also getting full
372:08 visibility into the models that it's
372:09 choosing based on the input and we'll
372:11 see the output. That way, all we have to
372:13 do is come back over here, update the
372:14 prompt, and continue to optimize the
372:16 workflow over time. As you can see,
372:18 we're talking to this agent in Slack.
372:19 So, what I'm going to do is say, "Hey,
372:21 tell me a joke." You can see my failed
372:22 attempts over there. And it's going to
372:23 get this message. As you can see, it's
372:25 picking a model, and then it's going to
372:27 answer us in Slack, as well as log the
372:29 output. So, we can see we just got the
372:30 response, why don't scientists trust
372:32 Adams? Because they make up everything.
372:33 And if I go to our model log, we can see
372:35 we just got the input, we got the
372:37 output, and then we got the model which
372:38 was chosen, which in this case was
372:40 Google Gemini's 2.0 Flash. And the
372:42 reason it chose Flash is because this
372:44 was a simple input with a very simple
372:45 output and it wanted to choose a free
372:47 model so we're not wasting credits for
372:48 no reason. All right, let's try
372:50 something else. I'm going to ask it to
372:51 create a calendar event at 1 p.m. today
372:53 for lunch. Once this workflow fires off,
372:55 it's going to choose the model. As you
372:56 can see, it's sending that over to the
372:58 dynamic agent to create that calendar
373:00 event. It's going to log that output and
373:02 then send us a message in Slack. So,
373:04 there we go. I just have created the
373:06 calendar event for lunch at 1 p.m.
373:07 today. If you need anything else, just
373:09 let me know. We click into the calendar
373:10 real quick. There is our launch event at
373:12 one. And if we go to our log, we can see
373:14 that this time it used OpenAI's GBT 4.1
373:16 mini. All right, we'll just do one more
373:18 and then we'll break it down. So, I'm
373:20 going to ask it to do some research on
373:21 AI voice agents and create a blog post.
373:23 Here we go. It chose a model. It's going
373:25 to hit Tavi to do some web research.
373:27 It's going to create us a blog post, log
373:29 the output, and send it to us in Slack.
373:31 So, I'll check in when that's done. All
373:33 right, so it just finished up and as you
373:35 can see, it called the Tavly tool four
373:36 times. So, it did some in-depth
373:38 research. It logged the output and we
373:40 just got our blog back in Slack as you
373:42 can see. Wow. It is pretty thorough. It
373:45 talks about AI voice agents, the rise of
373:47 voice agents. Um there's key trends like
373:49 emotionally intelligent interactions,
373:51 advanced NLP, real-time multilingual
373:53 support, all this kind of stuff. Um
373:55 that's the whole blog, right? It ends
373:56 with a conclusion. And if you're
373:57 wondering what model it used for this
373:58 task, let's go look at our log. We can
374:00 see that it ended up using Claude 3.7
374:03 sonnet. And like I said, it knew it had
374:04 to do research. So it hit the tabletly
374:06 tool four different times. The first
374:08 time it searched for AI voice agents
374:09 trends, then it searched for case
374:12 studies, then it searched for growth
374:14 statistics, and then it searched for
374:16 ethical considerations. So, it made us a
374:18 pretty like holistic blog. Anyways, now
374:21 that you've seen a quick demo of how
374:22 this works, let's break down how I set
374:24 this up. So, the first things first,
374:26 we're talking to it in Slack and we're
374:27 getting a response back in Slack. And as
374:29 you can see, if I scroll up here, I had
374:31 a a few fails at the beginning when I
374:33 was setting up this trigger. So, if
374:34 you're trying to get it set up in Slack,
374:35 um it can be a little bit frustrating,
374:37 but I have a video right up here where I
374:38 walk through exactly how to do that.
374:40 Anyways, the key here is that we're
374:41 using Open Router as the chat model. So,
374:44 if you've never used Open Router, it's
374:45 basically a chat model that you can
374:47 connect to and it basically will let you
374:48 route to any model that you want. So, as
374:50 you can see, there's 300 plus models
374:52 that you can access through Open Router.
374:54 So, the idea here is that we have the
374:56 first agent, which is using a free model
374:57 like Gemini 2.0 Flash. we have this one
375:00 choosing which model to use based on the
375:02 input. And then whatever this model
375:04 chooses, we're using down here
375:05 dynamically for the second agent to
375:07 actually use in order to use its tools
375:09 or produce some sort of output for us.
375:11 And just so you can see what that looks
375:12 like, if I come in here, you can see
375:14 we're using a variable. But if I got rid
375:15 of that and we change this to fixed, you
375:17 can see that we have all of these models
375:18 within our open router dynamic brain to
375:21 choose from. But what we do is instead
375:23 of just choosing from one of these
375:24 models, we're basically just pulling the
375:26 output from the model selector agent
375:28 right into here. And that's the one that
375:30 it uses to process the next steps. Cool.
375:33 So let's first take a look at the model
375:34 selector. What happens in here is we're
375:36 feeding in the actual text that we sent
375:38 over in Slack. So that's pretty simple.
375:40 We're just sending over the message. And
375:42 then in the system message here, this is
375:44 where we actually can configure the
375:45 different models that the AI agent has
375:47 access to. So I said, "You're an agent
375:49 responsible for selecting the most
375:50 suitable large language model to handle
375:52 a given user request. Choose only one
375:54 model from the list below based strictly
375:55 on each model's strengths." So we told
375:57 it to analyze the request and then
375:59 return only the name of the model. We
376:01 gave it four models. Obviously, you
376:02 could give it more if you wanted to. And
376:04 down here, available models and
376:05 strengths. We gave it four models and we
376:07 basically defined what each one's good
376:09 at. You could give it more than four if
376:10 you wanted to, but just for this sake of
376:12 the demo, I only gave it four. And then
376:13 we basically said, return only one of
376:16 the following strings. And as you can
376:17 see in this example, it returned
376:19 anthropic claude 3.7 sonnet. And so one
376:21 quick thing to note here is when you use
376:23 Gemini 2.0 flash, for some reason it
376:25 likes to output a new line after a lot
376:28 of these
376:29 strings. So all I had to do later is I
376:32 clean up this new line and I'll show you
376:33 exactly what I mean by that. But now we
376:35 have the output of our model and then we
376:37 move on to the actual Smartyp Pants
376:38 agent. So in this one, we're giving it
376:40 the same user message as the previous
376:42 agent where we're just basically coming
376:44 to our Slack trigger and we're dragging
376:45 in the text from Slack. And what I
376:47 wanted to show you guys is that here we
376:49 have a system message and all I gave it
376:51 was the current date and time. So I
376:52 didn't tell it anything about using Tavi
376:54 for web search. I didn't tell it how to
376:55 use its calendar tools. This is just
376:57 going to show you that it's choosing a
376:58 model intelligent enough to understand
377:00 the tools that it has and how to use
377:02 them. And then of course the actual
377:04 dynamic brain part. We looked at this a
377:06 little bit, but basically all I did is I
377:07 pulled in the output of the previous
377:09 agent, the model selector agent. And
377:12 then, like I said, we had to just trim
377:13 up the end because if you just dragged
377:16 this in and Open Router was trying to
377:18 reference a model that had a new line
377:20 character after it, it would basically
377:21 just fail and say this model isn't
377:23 available. So, I trimmed up the end and
377:25 that's why. And you can see in my Open
377:26 Router account, if I go to my activity,
377:29 we can see which models we've used and
377:31 how much they've costed. So, anyways,
377:32 Gemini 2.0 Flash is a free model, but if
377:35 we use it through open router, they have
377:36 to take a little bit of a, you know,
377:38 they got to get some kickback there. So,
377:39 it's not exactly free, but it's really,
377:41 really cheap. But the idea here is, you
377:42 know, Claude 3.7 sonnet is more
377:44 expensive and we don't need to use it
377:46 all the time, but if we want our agent
377:48 to have the capability of using Claude
377:50 at some point, then we probably would
377:51 just have to plug in Claude. But now, if
377:53 you use this method, if you want to talk
377:55 to the agent just about some general
377:56 things or looking up something on your
377:58 calendar or sending an email, you don't
378:00 have to use Claude and waste these
378:01 credits. You could go ahead and use a
378:02 free model like 2.0 Flash or still a
378:05 very powerful cheap model like GPT 4.1
378:07 Mini. And that's not to say that 2.0
378:09 Flash isn't super powerful. It's just
378:11 more of a lightweight model. It's very
378:12 cheap. Anyways, that's just another cool
378:14 thing about Open Router. That's why I've
378:15 gotten in the habit of using it because
378:16 we can see the tokens, the cost, and the
378:19 breakdown of different models we've
378:20 used. From there, we're feeding the
378:22 output into a Google sheet template,
378:23 which by the way, you can download this
378:24 workflow as well as these other ones
378:26 down here that we'll look at in a sec.
378:28 You can download all this for free by
378:29 joining my Free School community. All
378:31 you have to do is go to YouTube
378:32 resources or search for the title of
378:34 this video and when you click on the
378:35 post associated with this video, you'll
378:37 have the JSON which is the end workflow
378:39 to download as well as you'll see this
378:41 Google sheet template somewhere in that
378:42 post so that you can just basically copy
378:44 it over and then you can plug everything
378:46 into your environment. Anyways, just
378:48 logging the output of course and we're
378:50 sending over a timestamp. So I just
378:51 said, you know, whatever time this
378:53 actually runs, you're going to send that
378:54 over the input. So the Slack message
378:56 that triggered this workflow. The
378:57 output, I'm basically just bringing the
378:59 output from the Smartyp Pants agent
379:01 right here. And then the model is the
379:02 output from the model selector agent.
379:04 And then all that's left to do is send
379:06 the response back to the human in Slack
379:08 where we connected to that same channel
379:09 and we're just sending the output from
379:11 the agent. So hopefully this is just
379:14 going to open your eyes to how you can
379:15 set up a system so that your actual main
379:17 agent is dynamically picking a brain to
379:19 optimize your cost and performance. And
379:21 in a space like AI where new models are
379:23 coming out all the time, it's important
379:25 to be able to test out different ones
379:26 for their outputs and see like what's
379:28 going on here, but also to be able to
379:30 compare them. So, two quick tools I'll
379:32 show you guys. This first one is Vellum,
379:34 which is an LLM leaderboard. You can
379:35 look at like reasoning, math, coding,
379:38 tool use. You have all this stuff. You
379:40 can compare models right here where you
379:41 can select them and look at their
379:43 differences. And then also down here is
379:45 model comparison with um all these
379:48 different statistics you can look at.
379:49 You can look at context, window, cost,
379:50 and speed. So, this is a good website to
379:53 look at, but just keep in mind it may
379:54 not always be completely up to date.
379:55 Right here, it was updated on April
379:57 17th, and today is the 30th, so doesn't
380:00 have like the 4.1 models. Anyways,
380:02 another one you could look at is this LM
380:04 Arena. So, I'll leave the link for this
380:05 one also down in the description. You
380:07 can basically compare different models
380:08 by chatting with them like side by side
380:09 or direct. People give ratings and then
380:11 you can look at the leaderboard for like
380:13 an overview or for text or for vision or
380:16 for whatever it is. just another good
380:17 tool to sort of compare some models.
380:19 Anyways, we'll just do one more quick
380:21 before we go on to the example down
380:22 below. Um because we haven't used the
380:24 reasoning model yet and those are
380:26 obviously more expensive. So, I'm asking
380:28 you a riddle. I said you have three
380:29 boxes. One has apples, one has only
380:31 oranges, and one has a mix of both.
380:33 They're all incorrectly labeled and you
380:35 can pick one fruit from the box without
380:36 looking. How can you label all boxes
380:38 correctly? So, let's see what it does.
380:40 Hopefully, it's using the reasoning
380:42 model. Okay, so it responded with a
380:44 succinct way to see it is to pick one
380:45 piece of fruit from the box labeled
380:47 apples and oranges. Since that label is
380:49 wrong, the box must actually contain
380:50 only apples or only oranges. Whatever
380:53 fruit you draw tells you which single
380:54 fruit box that really is. Once you know
380:56 which box is purely apples or purely
380:58 oranges, you can use the fact that all
381:00 labels are incorrect to deduce the
381:02 proper labels for the remaining two
381:04 boxes. And obviously, I had chatbt sort
381:06 of give me that riddle and that's
381:07 basically the answer it gave back. So,
381:09 real quick, let's go into our log and
381:11 we'll see which model it used. And it
381:13 used OpenAI's 01 reasoning model. And of
381:16 course, we can just verify that by
381:17 looking right here. And we can see it is
381:18 OpenAI 01. So, one thing I wanted to
381:20 throw out there real quick is that Open
381:22 Router does have sort of like an auto
381:24 option. You can see right here, Open
381:26 Router/auto, but it's not going to give
381:28 you as much control over which models
381:30 you can choose from, and it may not be
381:31 as costefficient as being able to define
381:34 here are the four models you have, and
381:36 here's when to use each one. So, just to
381:37 show you guys like what that would do if
381:39 I said, "Hey," it's going to use its
381:40 model and it's going to pick one based
381:42 on the input. And here you can see that
381:43 it used GPT4 mini. And then if I go
381:46 ahead and send in that same riddle that
381:47 I sent in earlier, remember earlier it
381:49 chose the reasoning model, but now it's
381:51 going to choose probably not the
381:52 reasoning model. So anyways, looks like
381:54 it got the riddle right. And we can see
381:55 that the model that it chose here was
381:57 just GPT40. So I guess the argument is
381:59 yes, this is cheaper than using 01. So
382:00 if you want to just test out your
382:02 workflows by using the auto function, go
382:04 for it. But if you do want more control
382:05 over which models to use, when to use
382:07 each one, and you want to get some
382:08 higher outputs in certain scenarios,
382:10 then you want to take probably the more
382:12 custom route. Anyways, just thought I'd
382:13 drop that in there. But let's get back
382:14 to the video. All right, so now that
382:16 you've seen how this agent can choose
382:17 between all those four models, let's
382:19 look at like a different type of example
382:20 here. Okay, so down here we have a rag
382:22 agent. And this is a really good use
382:23 case in my mind because sometimes you're
382:25 going to be chatting with a knowledge
382:26 base and it could be a really simple
382:28 query like, can you just remind me what
382:30 our shipping policy is? Or something
382:31 like that. But if you wanted to have
382:33 like a comparison and like a deep lookup
382:35 for something in the knowledge base,
382:36 you'd probably want more of a, you know,
382:38 a more intelligent model. So we're doing
382:40 a very similar thing here, right? This
382:41 agent is choosing the model with a free
382:43 model and then it's going to feed in
382:45 that selection to the dynamic brain for
382:47 the rag agent to do its lookup. And um
382:49 what I did down here is I just put a
382:51 very simple flow if you wanted to
382:52 download a file into Superbase just so
382:55 you can test out this Superbase rag
382:57 agent up here. But let's chat with this
382:59 thing real quick. Okay, so here is my
383:00 policy and FAQ document, right? And then
383:02 I have my Subbase table where I have
383:04 these four vectors in the documents
383:06 table. So what we're going to do is
383:07 query this agent for stuff that's in
383:09 that policy and FAQ document. And we're
383:11 going to see which model it uses based
383:13 on how complex the query is. So if I go
383:15 ahead and fire off what is our shipping
383:17 policy, we'll see that the model
383:18 selector is going to choose a model,
383:20 send it over, and now the agent is
383:22 querying Superbase and it's going to
383:23 respond with here's Tech Haven's
383:25 shipping policy. Orders are processed
383:26 within 1 to two days. standard shipping
383:28 takes 3 to seven business days, blah
383:29 blah blah. And if we compare that with
383:31 the actual documentation, you can see
383:33 that that is exactly what it should have
383:35 responded with. And you'll also notice
383:36 that in this example, we we're not
383:38 logging the outputs just because I
383:39 wanted to show a simple setup. But we
383:41 can see the model that it chose right
383:43 here was GPT 4.1 mini. And if we look in
383:46 this actual agent, you can see that we
383:48 only gave it two options, which was GPT
383:50 4.1 mini and anthropic cloud 3.5 sonnet,
383:52 just because of course I just wanted to
383:54 show a simple example. But you could up
383:56 this to multiple models if you'd like.
383:58 And just to show that this is working
384:00 dynamically, I'm going to say what's the
384:02 difference between our privacy policy
384:03 and our payment policy. And what happens
384:05 if someone wants to cancel their order
384:06 or return an item? So, we'll see.
384:08 Hopefully, it's choosing the cloud model
384:10 because this is a little bit more
384:11 complex. Um, it just searched the vector
384:14 database. We'll see if it has to go back
384:15 again or if it's writing an answer. It
384:17 looks like it's writing an answer right
384:18 now. And we'll see if this is accurate.
384:20 So, privacy versus payment. We have
384:22 privacy focuses on data protection.
384:24 payment covers accepted payment methods.
384:26 Um what happens if someone wants to
384:27 cancel the order? We have order
384:28 cancellation can be cancelled within 12
384:30 hours. And we have a refund policy as
384:32 well. And if we go in here, we could
384:34 validate that all this information is on
384:36 here. And we can see this is how you
384:38 cancel. And then this is how you refund.
384:41 Oh yeah, right here. Visit our returns
384:42 and refund page. And we'll see what it
384:44 says is that here is our return and
384:46 refund policy. And all this information
384:47 matches exactly what it says down here.
384:50 Okay. So those are the two flows I
384:52 wanted to share with you guys today.
384:53 Really, I just hope that this is going
384:54 to open your eyes to the fact that you
384:56 can have models be dynamic based on the
384:58 input, which really in the long run will
385:00 save you a lot of tokens for your
385:02 different chat models. All right, so now
385:04 we're going to move on to web hooks,
385:05 which I remember seemed really
385:06 intimidating as well, just like APIs and
385:08 HTTP requests, but they're really even
385:10 simpler. So, we're going to dive into
385:12 what exactly they are and show an
385:14 example of how that works in NN. And
385:16 then I'm going to show you guys two
385:17 workflows that are triggered by NAN web
385:19 hooks and then we send data back to that
385:21 web hook. So, don't worry, you guys will
385:22 see exactly what I'm talking about.
385:24 Let's get into it. Okay, web hooks. So,
385:27 I remember when I first learned about
385:29 APIs and HTTP requests, and then I was
385:31 like, what in the world is a web hook?
385:34 They're pretty much the same thing
385:36 except for, think about it like this.
385:38 The web hook, rather than us sending off
385:41 data somewhere or like sending off an
385:43 API call, we are the one that's waiting
385:46 for an API call. We're just waiting and
385:48 listening for data. So let me show you
385:51 an example of what that actually looks
385:53 like. So here you can see we have a web
385:55 hook trigger and a web hook is always
385:57 going to come in the form of a trigger
385:58 because essentially our end workflow is
386:01 waiting for data to be sent to it.
386:03 Whether that's like a form is submitted
386:04 and now the web hook gets it or whatever
386:07 that is we are waiting for the data
386:09 here. So when I click into the web hook
386:10 what we see is we have a URL and this is
386:13 basically the URL that wherever we're
386:15 sending data from is going to send data
386:18 to. So later in this course, I'm going
386:21 to show you an example where I do like
386:22 an 11labs voice agent. And so our end
386:25 web hook URL right here, that's where 11
386:28 Labs is sending data to. Or I'll show
386:29 you an example with lovable where I
386:31 build a little app and then our app is
386:33 sending data to this URL. So that's how
386:35 it works, right? Important things to
386:37 remember is you still have to set up
386:38 your method. So if you are setting up
386:40 some sort of request on a different
386:42 service and you're sending data to this
386:44 web hook, it's probably going to be a
386:45 post. So, you'll want to change that and
386:47 make sure that these actually align.
386:49 Anyways, what we're going to do is we're
386:51 going to change this to a post because I
386:52 I just know it's going to be post. And
386:54 this is our web hook URL, which is a
386:56 test URL. So, I'm going to click on the
386:59 button to copy it. And what I'm going to
387:01 do is take this and I'm going to go into
387:02 Postman, which is just kind of like an
387:04 API platform that I use to show some
387:06 demos of how we can send these requests.
387:08 So, I'm going to click on send an API
387:10 request in here. This basically just
387:12 lets us test out and see if our web
387:14 hook's working. So what I'm going to do
387:16 is I'm going to change the request to
387:18 post. I'm going to enter the web hook
387:20 URL from my NAND web hook. Okay. And now
387:23 basically what we have is the ability to
387:25 send over certain information. So I'm
387:27 just going to go to body. I'm going to
387:28 send over form data. And now you can see
387:31 just like JSON, it's key value pairs. So
387:33 I'm just going to send over a field
387:35 called text. And the actual value is
387:37 going to be hello. Okay. So that's it.
387:39 I'm going to click on send. But what
387:41 happens is we're going to get a request
387:43 back which is a 404 error. It says the
387:45 web hook is not registered and basically
387:48 there's a hint that says click the test
387:50 workflow button. So because this
387:53 workflow I'm sorry because the web hook
387:55 is supposed to be listening right now
387:57 it's not listening. And the reason it's
387:58 not listening is because we are in an
388:00 act inactive workflow like we've talked
388:02 about before and we haven't clicked
388:03 listen for test event. So if I click
388:05 listen now you can see it is listening
388:08 for this URL. Okay. So, I go back into
388:11 Postman. I hit send. And now it's going
388:13 to say workflow was started. I come back
388:15 into here. We can see that the node has
388:17 executed. And what we have is our text
388:20 that we entered right there in the body,
388:21 which was text equals hello. We also get
388:23 all this other random stuff that we
388:24 don't really need. Um, I don't even know
388:27 what this stuff really stands for. We
388:28 can see our host was our our nit cloud
388:30 account. All this kind of stuff. Um, but
388:33 that's not super important for us right
388:35 now, right? I just wanted to show that
388:36 that's how it works. So, they're both
388:38 configured as post. Our postman is
388:41 sending data to this address and we saw
388:45 that it worked right. So what comes next
388:47 is the fact that we can respond to this
388:50 web hook. So right now we're set to
388:52 respond immediately which would be
388:54 sending data back right away. But let's
388:56 say later you'll see an example in 11
388:58 labs and my end workflow we where we
389:00 want to grab data do something with it
389:02 and send something back. And how that
389:04 would work is we would change this
389:05 method to using respond to web hook node
389:08 and then we basically like add like
389:09 maybe an AI agent right here and then
389:11 after the AI agent we would basically
389:13 just go respond to web hook and as you
389:15 can see it just returns data to that
389:17 same web hook address. So that would
389:18 just be sending data back to lovable 11s
389:21 postman wherever we actually got the
389:23 initial request from we would do
389:25 something with that data and send it
389:26 back to that web hook. So really, it's
389:29 the exact same way that we think about
389:31 APIs except for we are now the API
389:33 server rather than the person who's
389:35 sending the request. So if you think
389:36 about the example with um being at a
389:39 restaurant, you know, like we would look
389:41 at the menu, we would send off a request
389:44 through the waiter to the kitchen and
389:46 then the kitchen would get that request
389:47 via a web hook. They would create the
389:50 food and then they would send it back to
389:52 the actual person via responding to web
389:55 hook. So that's all it is. is we are
389:56 just on the other side of the table now.
389:59 And then one last important thing to
390:00 know about web hooks in NN is ideally
390:03 you have to make it active. So we would
390:05 click on active but what it's going to
390:06 tell us is that you can now make calls
390:09 to your production web hook URL no
390:11 longer the test URL. So if you remember
390:14 in here we have test and production and
390:16 what I copied into Postman was the test.
390:18 So if I go back into Postman and I hit
390:20 send, nothing happens, right? But if I
390:23 now go to production URL, copy the
390:26 production, go into Postman and paste in
390:28 the production URL, hit send. There we
390:30 go. Workflow was started because that's
390:33 the actual active workflow production
390:35 URL. So I can click on executions and we
390:38 can see this is the newest one we just
390:40 got when we made our workflow active and
390:41 it did in fact start. And just to prove
390:43 to you that that's how it works, let me
390:45 change the body which now instead of
390:47 saying hello, it's going to
390:49 say active run.
390:54 Oops. And we'll send that off. Go into
390:57 edit end and we'll basically just watch
390:58 a new execution will pop up because it's
391:01 actively listening. I'm not doing
391:02 anything. There you go. You see it pop
391:03 up. And if we click into the actual web
391:06 hook data, we will see right here the
391:08 text says active run. Cool. So that's
391:11 web hooks. Hopefully that clears up any
391:12 confusion that you may have had
391:13 regarding web hooks. But let's dive into
391:15 some examples in NAND where we have a
391:17 web hook trigger and then we're also
391:18 configuring that other third party app
391:20 that's going to send data to our web
391:22 hook and trigger the
391:27 workflow. Hey there, I'm Archer. What
391:29 can I do for you? Hey Archer, can you
391:31 help me send an
391:32 email? Of course, I'd be delighted to
391:35 help. Who's the email for and what's it
391:37 about? Just give me the details and I'll
391:40 get it sent out. Awesome. Yeah, I just
391:43 wanted to send one to Phil. I wanted to
391:44 ask about an update for the project that
391:46 we discussed last week. Got it. So, you
391:49 want to send an email to Phil asking
391:51 about a project update? No
391:53 problem. I'll handle that. Just hang
391:55 tight while I send this off. All done.
391:58 It's been sent to Phil. He'll be getting
392:00 that email any minute. Anything else I
392:02 can help you with? Yeah, could you
392:03 actually go ahead and help me send
392:04 another one?
392:06 Of course. I'm always happy to lend a
392:08 hand, or rather an email address. Who is
392:10 this email for and what's it about? Just
392:12 give me the details and I'll whip it up.
392:15 Just another one to Phil. I forgot to
392:16 mention that I wanted to see if he wants
392:18 to get lunch tomorrow.
392:22 All right, another email to Phil. This
392:24 time to ask about lunch tomorrow. I'm on
392:26 it. Just a sec. Gotcha. The email is on
392:29 its way to Phil. He'll be sure to see
392:31 your invitation for lunch tomorrow. Let
392:32 me know if you need anything else. No,
392:35 that's going to be it. Thanks, Archer.
392:37 You're very welcome. Always happy to
392:39 help, especially when it comes to
392:40 emails. happy to handle any other
392:42 messages you need to send in the future.
392:44 Have a great day. Okay, so that was a
392:46 quick demo of the super cool
392:48 conversational voice agent that we built
392:49 using 11 Labs and Nad. His name's Archer
392:52 and he helps us send emails. As you can
392:54 tell, he was very enthusiastic about
392:56 sending emails. So, here's that first
392:58 email that we asked Archer to send to
392:59 Phil. Hi, Phil. I hope this message
393:01 finds you well. I'm writing to inquire
393:02 about the project update we discussed
393:03 last week. Could you please share the
393:05 latest developments at your earliest
393:06 convenience? Looking forward to your
393:07 response. Best Nate. And then we asked
393:09 Archer to send another email just asking
393:11 if he wants to get lunch tomorrow to
393:12 Phil. So, hi Phil. I was wondering if
393:15 you're available for lunch tomorrow. Let
393:16 me know what works for you. Best Nate.
393:17 So, now that we've seen a quick demo, we
393:19 heard the voice. We've seen the emails
393:20 actually come through. We're going to
393:21 hop back into Nad and we're going to
393:22 explain what's going on here so that you
393:24 guys can get this sort of system up and
393:26 running for yourselves. Okay, so there
393:27 are a few things that I want to break
393:28 down here. First of all, just within
393:30 NAN, whenever you're building an AI
393:32 agent, as you guys should know, there's
393:33 going to be an input and then that input
393:35 is going to be fed into the agent. The
393:37 agent's going to use its system prompt
393:38 and its brain to understand what tools
393:41 it needs to hit. It's going to use those
393:42 tools to take action and then there's
393:44 going to be some sort of output. So, in
393:46 the past when we've done tutorials on
393:47 personal assistants, email agents,
393:49 whatever it was, rag agents, usually
393:51 that the input that we've been using has
393:52 been something like Telegram or Gmail or
393:56 even just the NAN chat trigger. Pretty
393:58 much all we're switching out here for
393:59 the input and the output is 11 Labs. So,
394:02 we're going to be getting a post request
394:04 from 11 Labs, which is going to send
394:05 over the body parameters like who the
394:07 email is going to, um, what the message
394:09 is going to say, stuff like that. And
394:11 then the agent once it actually does
394:12 that, it's going to respond using this
394:14 respond to web hook node. So, we'll get
394:16 into 11 Labs and I'll show you guys how
394:17 I prompted the agent and everything like
394:18 that in 11 Labs. But first, let's take a
394:21 quick look at what's going on in the
394:22 super simple agent setup here in NN. So,
394:25 these are tools that I've used multiple
394:26 times on videos on my channel. The first
394:28 one is contact data. So, it's just a
394:30 simple Google sheet. This is what it
394:31 looks like. Here's Phil's information
394:33 with the correct Gmail that we were
394:34 having information sent to. And then I
394:36 just put other ones in here just to sort
394:37 of dummy data. But all we're doing is
394:39 we're hooking up the tool um Google
394:42 Sheets. It's going to be reading get
394:44 rows sheet within the document. We link
394:46 the document. That's pretty much all we
394:47 had to do. Um and then we just called it
394:49 contact data so that when we're
394:50 prompting the agent, it knows when to
394:52 use this tool, what it has. And then the
394:54 actual tool that sends emails is the
394:56 send email tool. So in here we're
394:58 connecting a Gmail tool. Um this one is
395:01 you know we're using all the from AI
395:03 functions which makes it really really
395:05 easy. Um we're sending a message of
395:07 course and so the from AI function
395:09 basically takes the query coming in from
395:11 the agent and understands um dynamically
395:14 the AI is looking for okay what's the
395:16 email address based on the user's
395:17 message. Okay we grab the email address
395:19 we're going to put it in the two
395:20 parameter. How can we make a subject out
395:22 of this message? We'll put it here. And
395:24 then how can we actually construct an
395:26 email body and we put it there. So
395:28 that's all that's going on here. Here
395:29 we've got our tools. We've obviously got
395:31 a chat model. In this case, we're just
395:32 using um
395:34 GPT40. And then we have the actual
395:37 what's taking place within the agent. So
395:39 obviously there's an input coming in. So
395:41 that's where we define this information.
395:43 Input agent output and then the actual
395:46 system message for the agent. So the
395:48 system message is a little bit different
395:49 than the user agent. The system message
395:51 is defining the role. This is your job
395:53 as an agent. This is what you should be
395:55 doing. These are the tools you have. And
395:57 then the user message is like each
395:58 execution, each each run, each time that
396:01 we interact with the agent through 11
396:03 Labs, it's going to be a different user
396:05 message coming in, but the system
396:06 message is always going to remain the
396:07 same as it's the prompt for the AI
396:09 agents behavior. Anyways, let's take a
396:11 look at the prompt that we have here.
396:13 First, the overview is that you are an
396:15 AI agent responsible for drafting and
396:17 sending professional emails based on the
396:19 user's instructions. You have access to
396:20 two tools, contact data to find email
396:23 addresses and send email to compose and
396:25 send emails. Your objective is to
396:27 identify the recipient's contact
396:28 information, draft a professional email
396:31 and sign off as Nate before sending. The
396:34 tools you have obviously uh contact
396:36 data. It retrieves email addresses based
396:37 on the name. So we have an example input
396:39 John Doe. Example output an email
396:41 address and then send email. Sends an
396:43 email with a subject and a body. The
396:45 example input here is an email address.
396:47 Um subject and a body with example email
396:49 subject body. Um so that's what we have
396:52 for the system message. And then for the
396:55 um user message, as you can see, we're
396:57 basically just saying um okay, so the
396:59 email is going to be for this person and
397:01 the email content is going to be this.
397:02 So in this case, this execution it was
397:04 the email's for Phil and the email
397:06 content is asking about lunch tomorrow.
397:08 So that's all that we're being fed in
397:10 from 11 Labs. And then the agent takes
397:13 that information to grab the contact
397:15 information and then it uses its AI
397:17 brain to make the email message.
397:20 Finally, it basically just responds to
397:22 the web hook with um the email to Phil
397:25 regarding lunch tomorrow has been
397:26 successfully sent and then 11 Labs
397:28 captures that response back and then it
397:30 can respond to us with gotcha. We were
397:32 able to send that off for you. Is there
397:33 anything else you need? So, that's
397:35 pretty much all that's going on here. Um
397:37 if you see in the actual web hook, what
397:39 we're getting here is, you know, there's
397:41 different things coming back. We have
397:42 different little technical parameters,
397:44 all this kind of stuff. all that we want
397:46 to configure and I'll show you guys how
397:48 we configure this in 11 Labs is the the
397:50 JSON body request that's being sent
397:52 over. So we're in table format. If we
397:54 went to JSON, we could see down here
397:56 we're looking at body. In the body, we
397:58 set up two fields to send over from 11
398:00 Labs to Nidend using that post request
398:02 web hook. The first field that we set up
398:05 was two. And as you can see, that's when
398:07 the 11 Labs model based on what we say
398:11 figures out who the email is going to
398:13 and puts that there and then figures out
398:15 what's the email content. What do you
398:16 want me to say in this email? And then
398:17 throws that in here. So, um, that's how
398:20 that's going to work as far as setting
398:22 up the actual web hook node right here.
398:25 Um, we have a we wanted to switch this
398:27 to a post method because 11 Labs is
398:29 sending us information. Um, we have a
398:32 test URL and a production URL. The test
398:34 one we use for now and we have to
398:36 manually have naden listen for a test
398:38 event. Um I will show an example of what
398:41 happens if we don't actually do this
398:42 later in the video. But when you push
398:44 the app into production, you make the
398:46 workflow active, you would want to put
398:48 this web hook in 11 Labs as the
398:50 production URL rather than the test URL
398:52 so that you can make sure that the
398:54 stuff's actually coming over. We put our
398:56 path as end just to clean up this URL.
398:59 All that it does is changes the URL. Um
399:01 and then authentication we put none. And
399:03 then finally for response instead of
399:04 doing immediately or wait when last node
399:06 finishes we want to do using respond to
399:08 web hook node. That way we get the
399:11 information the agent takes place and
399:12 then responds and then all we have here
399:13 is respond to web hook. So it's very
399:15 simple as you can see it's only you know
399:17 really four nodes you know the email the
399:19 brain um and then the two tools and the
399:22 web hooks. So um hopefully that all made
399:24 sense. We are going to hop into 11 labs
399:28 and start playing around with this
399:29 stuff. Also, quick side note, if you
399:31 want to hop into this workflow, check
399:32 out the prompts, play around with how I
399:34 configured things. Um, you'll be able to
399:36 download this workflow for free in the
399:37 free school community. Link for that
399:39 will be down in the description. You'll
399:40 just come into here, you'll click on
399:41 YouTube resources, you will click on the
399:43 post associated with this video, and
399:45 then you're able to download the
399:46 workflow right here. Once you download
399:48 the workflow, you can import it from
399:49 file, and then you will have this exact
399:52 canvas pop up on your screen. Then, if
399:54 you're looking to take your skills with
399:55 Naden a little bit farther, feel free to
399:56 check out my paid community. The link
399:58 for that will also be down in the
399:59 description. Great community in here. A
400:01 lot of people obviously are learning NAN
400:03 and um asking questions, sharing builds,
400:05 sharing resources. Got a great classroom
400:07 section going over, you know, client
400:09 builds and some deep dive topics as well
400:11 as five live calls per week. So, you can
400:13 always make sure you're getting your
400:13 questions answered. Okay. Anyways, back
400:15 to the video. So, in 11 Labs, this is
400:18 the email agent. This is just the test
400:19 environment where we're going to be
400:20 talking to it to try things out. So,
400:22 we'll go back and we'll see how we
400:23 actually configured this agent. And if
400:25 you're wondering why I named him
400:26 Marcher, it's just because his actual
400:28 voice is Archer. So, um, that wasn't my
400:30 creativity there. Anyways, once we are
400:32 in the configuration section of the
400:34 actual agent, we need to set up a few
400:35 things. So, first is the first message.
400:37 Um, we pretty much just when we click on
400:39 call the agent, it's going to say, "Hey
400:40 there, I'm Marcher. What can I do for
400:42 you?" Otherwise, um, if we leave this
400:43 blank, then we will be the ones to start
400:45 the conversation. But from there, you
400:47 will set up a system prompt. So in here,
400:49 this is a prompt I have is you are a
400:51 friendly and funny personal assistant
400:53 who loves helping the user with tasks in
400:54 an upbeat and approachable way. Your
400:56 role is to assist the user with sending
400:58 emails. When the user provides details
401:00 like who the email is for and what's it
401:02 about, you will pass that information to
401:04 the NAN tool and wait for its response.
401:06 I'll show you guys in a sec how we
401:08 configure the NAN tool and how all that
401:10 works. But anyways, once you get
401:12 confirmation from NAN that the email was
401:14 sent, cheerfully let the user know it's
401:15 done and ask if there's anything else
401:17 you can help with. Keep your tone light,
401:19 friendly, and witty while remaining
401:20 efficient and clear in your responses.
401:22 So, as you can see in the system prompt,
401:24 I didn't even really put in anything
401:25 about the way it should be conversating
401:27 as far as like sounding natural and
401:30 using filler words and um and sometimes
401:33 I do that to make it sound more natural,
401:34 but this voice I found just sounded
401:36 pretty good just as is. Then, we're
401:38 setting up the large language model. Um,
401:40 right now we're using Gemini 1.5 Flash
401:42 just because it says it's the fastest.
401:43 You have other things you can use here,
401:44 but I'm just sticking with this one. And
401:46 so this is what it uses to extract
401:48 information pretty much out of the
401:50 conversation to pass it to NAND or
401:52 figure out how it's going to respond to
401:53 you. That's what's going on here. And
401:55 then with temperature, um, I talked
401:57 about I like to put a little bit higher,
401:59 especially for some fun use cases like
402:00 this. Um, basically this is just the
402:02 randomness and creativity of the
402:03 responses generated so that it's always
402:05 going to be a little different and it's
402:06 going to be a little fun um, the higher
402:08 you put it. But if you wanted it to be
402:09 more consistent and you had like, you
402:11 know, you were trying to get some sort
402:12 of information back
402:15 um right the way you want it, then you
402:16 would probably want to lower this a
402:17 little bit. Um and then you have stuff
402:19 like knowledge base. So if this was
402:21 maybe like um a customer support, you'd
402:24 be able to put some knowledge base in
402:25 there. Or if you watch my previous voice
402:27 video about um sort of doing voice rag,
402:30 you could still do the sending it to
402:32 NADN, hitting a vector database from
402:33 Naden and then getting the response
402:35 back. But anyways, um, in this case,
402:38 this is where we set up the tool that we
402:39 were able to call up here as you saw in
402:41 the system prompt. So the tool NAN, this
402:44 is where you're putting the web hook
402:45 from your the web hook URL from NAN.
402:49 That's where you're putting that right
402:50 here. As you can see, um, web hook- test
402:52 NAN. The method is going to be a post.
402:54 So we can send information from 11 Labs
402:56 to NAN. And we just named it Naden to
403:00 make the system prompt make more sense
403:01 for um just just for me when I was
403:03 creating this. It makes sense to send
403:05 something to the tool called Naden.
403:07 Anyways, as you can see, the description
403:09 is use this tool to take action upon the
403:11 user's request. And so we can pretty
403:12 much just leave it as that. We don't
403:14 have any headers or authorization going
403:15 in here, but we do need to send over
403:17 body parameters. Um otherwise, if we
403:19 didn't have this, nothing would be sent
403:20 over to Naden at all. So the description
403:23 of the body parameters is in a friendly
403:26 way ask the user to provide the name of
403:28 the recipient and what the email is
403:30 about unless they already provided that
403:31 information. So the LLM is understanding
403:34 when it's conversating with the human it
403:36 needs to extract the name of this person
403:38 to send an an email to and then actually
403:41 what is the email going to have. As you
403:42 can see we didn't have to put in like oh
403:44 what's the subject of the email because
403:46 our AI agent in N8N can use its brain to
403:49 figure out a subject. So we have two
403:51 parameters that we're setting over. If
403:53 you remember when we were in here, we
403:55 got the two parameters from the body
403:56 right here, which was two and email
403:58 content. And so that's as you can see
404:00 what we set up here. So the first one
404:02 was a string. It was called two and this
404:04 is who the email is going to. And then
404:06 the second one was also a string. It's
404:07 called email content. And this is what
404:09 is the email about. So we hit save
404:12 changes. Now we have a tool that gets
404:13 called whenever um the voice agent
404:16 realizes it has information to send over
404:18 to N to send an email. and it has the
404:20 right parameters to do so. So now we
404:22 have this voice agent pretty much set up
404:23 here with its tools and its system
404:24 prompt. We're going to test the agent.
404:26 And remember earlier I talked about the
404:28 fact that right now we're testing. So we
404:30 have to have the web hook actively
404:31 listening. Once this is in production,
404:33 it's going to be listening all the time.
404:34 But right now we have to manually hit
404:36 test event before we call it. Otherwise,
404:38 it's not going to work. So I'm going to
404:39 talk to Archer, ask him to send an
404:41 email. It's going to go through and then
404:42 we're going to ask him to send another
404:43 email where we don't hit this web hook
404:45 test event and then we'll see what he
404:47 says. You're probably just going to say
404:49 he couldn't access the database or he
404:51 couldn't find the contact information.
404:52 Something like that. Hey there, I'm
404:53 Archer. What can I do for you? Hey
404:56 Archer, can you help me send an email?
404:58 Of course. I'd love to help. Who's the
405:00 email for and what's it about? Tell me
405:02 the details and I'll whip it up in a
405:03 jiffy. Sweet. Um, it's going to be for
405:06 Phil. Okay, so the email is for Phil.
405:09 What's it about? I'm ready to get this
405:10 email sent out. Yeah, just let him know
405:13 that I'm caught in traffic and I'm going
405:15 to be late to the meeting.
405:17 Got it. So, you want to let Phil know
405:19 you're running late because of traffic.
405:21 I'll get that email sent out right away.
405:24 All done. I just sent the email to Phil
405:26 letting him know you're running late.
405:28 Anything else I can help you with? Yeah,
405:30 I'm actually going to need to send
405:31 another one. No problem. Who's this one
405:34 for and what's it about? I'm ready to
405:35 send email number two. Yeah. Can you let
405:38 Phil know that um I actually just drove
405:40 my car off a bridge?
405:43 Oh my goodness. I can't send an email
405:45 like that. Maybe you should call Phil
405:47 instead. Is there someone else you want
405:49 to send an email to?
405:53 Um, no. Can you send an email to Phil?
405:56 I'm so sorry, but I can't send an email
405:58 like that. It sounds like you're in a
405:59 difficult situation. Is there someone
406:02 else you can reach out to for help?
406:06 Okay, didn't expect that. So, I guess
406:07 the model doesn't want to say something
406:08 like that. We'll try again. Um, workflow
406:11 is not active. So, let's see. Hey there,
406:14 I'm Archer. What can I do for you? Hey,
406:16 Archer, can you send an email?
406:19 Of course, I'd be happy to help you with
406:21 that. Who is the email for and what is
406:23 it about? I'll get it sent out in a
406:25 jify.
406:26 Just wanted to touch base with Phil
406:28 about um the meeting later today.
406:32 Okay. So, you want to send an email to
406:34 Phil about the meeting later today. Got
406:36 it. I'll get this done right away.
406:38 Anything else I can help with today?
406:39 Oops. Looks like there was an error
406:41 sending that email. It's possible
406:43 there's a typo in the email address or
406:45 something is wrong on my end. Let me try
406:47 again. Can you please double check the
406:48 email address? Okay. Anyway, so that's
406:50 how that works. As you can see, the
406:52 second time the web hook wasn't active,
406:54 so wasn't able to send that um that
406:56 email for us because it pretty much
407:01 endnot passed through. So, that's going
407:03 to be it for this one. I hope that
407:04 everything made sense. Um it's just
407:05 really cool how easy it basically is to
407:07 switch out an input and you can have the
407:09 agent function the same. Obviously, a
407:11 few things would change as you start to
407:12 add more tools. Your user message would
407:14 have to be tweaked a little bit. You'd
407:15 have to tweak the actual system prompts
407:16 a little bit. But, as you can see in
407:18 this one, kept it very, very simple.
407:19 Basically, just told it its role. Gave
407:21 it the the two tools and how to use
407:23 them. And as you can see, um it was
407:25 pretty seamless as far as being able to
407:27 have the agent fill in things, make the
407:29 messages, and then send them off pretty
407:33 easily. Today, we're going to be talking
407:35 about how you can build anything with
407:36 Lovable and NAN. So we're going to be
407:38 doing a live build of spinning up a web
407:40 page with lovable and then also building
407:42 the backend on nit. But first of all, I
407:44 wanted to go over high level what this
407:46 architecture looks like. So right here
407:47 is lovable. This is what we're starting
407:49 off with. And this is where we're going
407:50 to be creating the interface that the
407:52 user is interacting with. What we do
407:53 here is we type in a prompt in natural
407:55 language and Lovable basically spins up
407:57 that app in seconds. And then we're able
407:59 to talk back and forth and have it make
408:01 minor fixes for us. So what we can do is
408:03 when the user inputs information into
408:05 our lovable website it can send that
408:07 data to nadn the nadn workflow that
408:09 we're going to set up can you know use
408:11 an agent to take action in something
408:13 like gmail or slack air tableable or
408:15 quickbooks and then naden can send the
408:17 data back to lovable and display it to
408:20 the user and this is really just the tip
408:21 of the iceberg there's also some really
408:23 cool integrations with lovable and
408:25 superbase or stripe or resend so there's
408:27 a lot of ways you can really use lovable
408:29 to develop a full web app and so while
408:31 we're talking high We just wanted to
408:32 show you an example flow of what this
408:34 naden could look like where we're
408:35 capturing the information the user is
408:37 sending from lovable via web hook. We're
408:40 feeding that to a large language model
408:41 to create some sort of content for us
408:43 and then we're sending that back and it
408:44 will be displayed in the Lovable web
408:46 app. So let's head over to Lovable and
408:48 get started. So if you've never used
408:49 Lovable before, don't worry. I'm going
408:51 to show you guys how simple it is. You
408:52 can also sign up using the link in the
408:54 description for double the credits.
408:56 Okay, so this is all I'm going to start
408:57 with just to show you guys how simple
408:58 this is. I said, "Help me create a web
409:00 app called Get Me Out of This, where a
409:02 user can submit a problem they're
409:03 having." Then I said to use this image
409:05 as design inspiration. So, I Googled
409:07 landing page design inspiration, and I'm
409:09 just going to take a quick screenshot of
409:10 this landing page, copy that, and then
409:12 paste it into Lovable. And then we'll
409:14 fire this off. Cool. So, I just sent
409:16 that off. And on the right hand side,
409:17 we're seeing it's going to spin up a
409:19 preview. So, this is where we'll see the
409:20 actual web app that it's created and get
409:22 to interact with it. Right now, it's
409:24 going to come through and start creating
409:25 some code. And then on the lefth hand
409:26 side is where we're going to have that
409:27 back and forth chat window to talk to
409:29 lovable in order to make changes for us.
409:31 So right now, as you can see, it's going
409:33 to be creating some of this code. We
409:34 don't need to worry about this. Let's go
409:36 into nit real quick and get this
409:37 workflow ready to send data to. Okay, so
409:40 here we are in Nen. If you also haven't
409:42 used this app before, there'll be a link
409:43 for it down in the description. It's
409:44 basically just going to be a workflow
409:45 builder and you can get a free trial
409:47 just to get started. So you can see I
409:49 have different workflows here. We're
409:50 going to come in and create a new one.
409:52 And what I'm going to do is we're gonna
409:53 add a first step that's basically
409:54 saying, okay, what actually triggers
409:56 this workflow. So I'm gonna grab a web
409:58 hook. And so all a web hook is is, you
410:00 know, it looks like this. And this is
410:02 basically just a trigger that's going to
410:04 be actively listening for something to
410:06 send data to it. And and data is
410:08 received at this URL. And so right now
410:10 there's a test URL and there's a
410:11 production URL. Don't worry about that.
410:13 We're going to click on this URL to copy
410:15 it to our clipboard. And basically we
410:17 can give this to Lovable and say, "Okay,
410:18 whenever a user puts in a problem
410:21 they're having, you're going to send the
410:22 data to this web hook." Cool. So hopping
410:24 over to Lovable. As you can see, it's
410:26 still coding away and looks like it's
410:27 finishing up right now. And it's saying,
410:29 "I've created a modern problem-solving
410:30 web app with a hero section, submission
410:32 form, and feature section in blue
410:34 color." Um, looks like there's an error.
410:36 So all we have to do is click on try to
410:37 fix, and it should go back in there and
410:39 continue to spin up some more code.
410:40 Okay, so now it looks like it finished
410:42 that up. And as you can see, we have the
410:44 website filled up. And so it created all
410:46 of this with just uh an image as
410:48 inspiration as well as just me telling
410:50 it one sentence, help me create a web
410:51 app called get me out of this where a
410:53 user can submit a problem they're
410:54 having. So hopefully this should already
410:55 open your eyes to how powerful this is.
410:57 But let's say for the sake of this demo,
410:59 we don't want all this. We just kind of
411:00 want one simple landing page where they
411:02 send a problem in. So all I'd have to do
411:04 is on this lefth hand side, scroll down
411:05 here and say make this page more simple.
411:09 We only need one
411:12 field which is what
411:15 problem can we help with? So we'll just
411:19 send that off. Very simple query as if
411:21 we were just kind of talking to a
411:22 developer who was building this website
411:24 for us and we'll see it modify the code
411:26 and then we'll see what happens. So down
411:27 here you can see it's modifying the code
411:29 and now we'll see what happens. It's
411:31 just one interface right here. So it's
411:32 created like a title. It has these
411:34 different buttons and we could easily
411:35 say like, okay, when someone clicks on
411:36 the home button, take them here. Or when
411:38 someone clicks on the contact button,
411:40 take them here. And so there's all this
411:41 different stuff we can do, but for the
411:42 sake of this video, we're just going to
411:43 be worrying about this interface right
411:45 here. And just to give it some more
411:46 personality, what we could do is add in
411:49 a logo. So I can go to Google and search
411:51 for a thumbs up logo PNG. And then I can
411:54 say add this logo in the top left. So
411:59 I'll just paste in that image. We'll
412:01 fire this off to lovable. And it should
412:03 put that either right up here or right
412:05 up here. We'll see what it does. But
412:07 either way, if it's not where we like
412:08 it, we can just tell it where to put it.
412:10 Cool. So, as you can see, now we have
412:11 that logo right up there. And let's say
412:13 we didn't like this, all we'd have to do
412:14 is come up to a previous version, hit on
412:16 these three dots, and hit restore. And
412:18 then it would just basically remove
412:19 those changes it just made. Okay. So,
412:21 let's test out the functionality over
412:22 here. Let's say a problem is we want to
412:24 get out of Oh, looks like the font is
412:26 coming through white. So, we need to
412:28 make sure this is changed.
412:39 And boom, we just told it to change the
412:41 text to black and now it's black and we
412:43 can see it. So anyways, I want to say
412:45 get me out of a boring meeting. So we'll
412:49 hit get me out of this and we'll see
412:51 what happens. It says submitting and
412:53 nothing really happens. Even though it
412:55 told us, you know, we'll get back to you
412:56 soon. Nothing really happened. So, what
412:58 we want to do is we want to make sure
413:00 that it knows when we hit this button,
413:02 it's going to send that data to our
413:03 Naden web hook. So, we've already copied
413:05 that web hook to our clipboard, but I'm
413:06 just going to go back into Naden. We
413:08 have the web hook. We'll click on this
413:09 right here back into lovable. Basically
413:11 just saying when I click get me out of
413:13 this, so this button right here, send
413:14 the data to this web hook. And also,
413:16 what we want to do is say as a
413:20 post request because it's going to be
413:22 sending data. So, we're going to send
413:24 that off. And while it's making that
413:25 change to the code, real quick, we want
413:27 to go into edit end and make sure that
413:29 our method for this web hook is indeed
413:31 post. So I don't want to dive into too
413:32 much what that means really, but Lovable
413:35 is going to be sending a post request to
413:37 our web hook. Meaning there's going to
413:38 be stuff within this web hook like body
413:40 parameters and different things. And so
413:42 if this wasn't configured as a post
413:43 request, it might not work. So you'll
413:46 see once we actually get the data and we
413:47 catch it in any of them. But anyways,
413:49 now when the users click on get me out
413:51 of this, the form will send the problem
413:53 description to your web hook via a post
413:55 request. So let's test it out. So we're
413:57 going to say I forgot to prepare a brief
413:58 for my meeting. We're going to go back
414:00 and end it in real quick and make sure
414:01 we hit listen for test event. So now our
414:03 web hook is actively listening back in
414:05 lovable. We'll click get me out of this
414:06 and we will see what happens. We can
414:08 come and end it in and we can now see we
414:10 got this information. So here's the body
414:12 I was talking about where we're
414:13 capturing a problem which is I forgot to
414:15 prepare a brief for my meeting. So, we
414:18 now know that Lovable is able to send
414:19 data to NAND. And now it's on us to
414:22 configure what we want to happen in NAND
414:24 so we can send the data back to Lovable.
414:26 Cool. So, what I'm going to do is I'm
414:27 going to click on the plus that's coming
414:28 off of the web hook. And I'm going to
414:30 grab an AI agent. What this is going to
414:32 do is allow us to connect to a different
414:34 chat model and then the agent's going to
414:36 be able to take this problem and produce
414:38 a response. And I'm going to walk
414:40 through the step by step, but if you
414:41 don't really want to worry about this
414:42 and you just want to worry about the
414:43 lovable side of things, you can download
414:45 the finished template from my free
414:47 school community. I'll link that down in
414:48 the description. That way, you can just
414:50 plug in this workflow and just give
414:52 lovable your noden web hook and you'll
414:53 be set up. But anyways, if you join the
414:55 free school community, you'll click on
414:56 YouTube resources, click on the post
414:58 associated with this video, and you'll
415:00 be able to download the JSON right here.
415:02 And then when you have that JSON, you
415:03 can come into Nadn, open up a new
415:05 workflow, click these three dots on the
415:07 top, and then click import from file.
415:08 And when you open that up, it'll just
415:10 have the finished workflow for you right
415:12 here. But anyways, what I'm going to do
415:13 is click into the AI agent. And the
415:15 first thing is we have to configure what
415:17 information the agent is going to
415:19 actually read. So first of all, we're
415:21 going to set up that as a user prompt.
415:22 We're going to change this from
415:24 connected chat trigger node to define
415:26 below because we don't have a connected
415:28 chat trigger node. We're using a web
415:29 hook as we all know. So we're going to
415:31 click on define below and we are
415:33 basically just going to scroll down
415:34 within the web hook node where the
415:36 actual data we want to look at is which
415:38 is just the problem that was submitted
415:40 by the user. So down here in the body we
415:42 have a problem and we can just drag that
415:44 right in there and that's basically all
415:46 we have to do. And maybe we just want to
415:47 define to the agent what it's looking
415:48 at. So we'll just say like the problem
415:52 and then we'll put a colon. So now you
415:53 can see in the result panel this is what
415:55 the agent will be looking at. And next
415:57 we need to give it a system message to
415:58 understand what it's doing. So, I'm
416:00 going to click on add option, open up a
416:02 system message, and I am going to
416:04 basically tell it what to do. So, here's
416:06 a system message that I came up with
416:07 just for a demo. You're an AI excuse
416:09 generator. Your job is to create clever,
416:11 creative, and context appropriate
416:13 excuses that someone could use to avoid
416:15 or get out of a situation. And then we
416:17 told it to only return the excuse and
416:19 also to add a touch of humor to the
416:21 excuses. So, now before we can actually
416:22 run this to see how it's working, we
416:24 need to connect its brain, which is
416:26 going to be an AI chat model. So, what
416:27 I'm going to do is I'm going to click on
416:28 this plus under chat model. For this
416:31 demo, we'll do an OpenAI chat model. And
416:33 you have to connect a credential if you
416:34 haven't done so already. So, you would
416:36 basically come into here, click create
416:37 new credential, and you would just have
416:39 to insert your API key. So, you can just
416:41 Google OpenAI API. You'll click on API
416:44 platform. You can log in, and once
416:46 you're logged in, you just have to go to
416:47 your dashboard, and then on the left,
416:48 you'll have an API key section. All
416:50 you'll have to do is create a new key.
416:52 We can call this one um test lovable.
416:56 And then when you create that, you just
416:58 copy this value. Go back into Nitn.
416:59 Paste that right here. And then when you
417:01 hit save, you are now connected to
417:03 OpenAI's API. And we can finally run
417:05 this agent real quick. If I come in here
417:07 and hit test step, we will see that it's
417:09 going to create an excuse for I forgot
417:11 to prepare a brief for my meeting, which
417:13 is sorry, I was too busy trying to bond
417:15 with my coffee machine. Turns out it
417:16 doesn't have a prepare briefs setting.
417:19 So basically what we have is we're
417:20 capturing the problem that a user had.
417:22 We're using an AI agent to create a
417:25 excuse. And then we need to send the
417:26 data back to Lovable. So all we have to
417:28 do here is add the plus coming off of
417:30 the agent. We're going to call this a
417:32 respond to web hook node. And we're just
417:34 going to respond with the first incoming
417:35 item, which is going to be the actual
417:37 response from the agent. But all we have
417:39 to do also to configure this is back in
417:41 the web hook node, there's a section
417:43 right here that says respond, instead of
417:45 responding immediately, we want to
417:46 respond using the respond to web hook
417:49 node. So now it will be looking over
417:51 here, and that's how it's going to send
417:52 data back to lovable. So this is pretty
417:54 much configured the way we need it, but
417:56 we have to configure Lovable now to wait
417:58 for this response. Okay. So what I'm
418:00 telling Lovable is when the data gets
418:02 sent to the web hook, we wait for the
418:04 response from the web hook, then output
418:06 that in a field that says here is your
418:08 excuse. So we'll send this off to
418:09 Lovable and see what it comes up with.
418:12 Okay, so now it said that I've added a
418:13 new section that displays here is your
418:14 excuse along with the response message
418:16 from the web hook when it's received. So
418:18 let's test it out. First, I'm going to
418:20 go back and edit in and we're going to
418:21 hit test workflow. So the web hook is
418:23 now listening for us. So we'll come into
418:24 our lovable web app and say I want to
418:26 skip a boring meeting. We'll hit get me
418:30 out of this. So now that data should be
418:32 captured in Naden. It's running. And now
418:34 the output is I just realized my pet
418:36 goldfish has a lifealtering decision to
418:38 make regarding his tank decorations and
418:40 I simply cannot miss this important
418:41 family meeting. So it doesn't look
418:43 great, but it worked. And if we go into
418:45 edit end, we can see that this run did
418:47 indeed finish up. And the output over
418:48 here was I just realized my pet goldfish
418:50 has a lifealtering decision blah blah
418:52 blah. So basically what what's happening
418:54 is the web hook is returning JSON which
418:56 is coming through in a field called
418:57 output and then we have our actual
418:59 response which is exactly what lovable
419:02 sent through. So it's not very pretty
419:03 and we can basically just tell it to
419:04 clean that up. So what I just did is I
419:06 said only return the output fields value
419:09 from the web hook response not the raw
419:11 JSON. So we wanted to just output this
419:13 right here which is the actual excuse.
419:15 And so some of you guys may not even
419:16 have had this problem pop up. I did a
419:18 demo of this earlier just for testing
419:20 and I basically walked through these
419:21 same steps and this wasn't happening.
419:23 But you know sometimes it happens.
419:26 Anyways, now it says the form only
419:27 displays the value from the output
419:29 field. So let's give it another try. So
419:31 back in we're going to hit test
419:32 workflow. So it's listening for us in
419:34 lovable. We're going to give it a
419:35 problem. So I'm saying I overslept and
419:37 I'm running late. I'm going to click get
419:38 me out of this. And we'll see the
419:39 workflow just finished up. And now we
419:41 have the response in a clean format
419:43 which is I accidentally hit the snooze
419:44 button until it filed for a restraining
419:46 order against me for harassment. Okay.
419:48 So now that we know that the
419:49 functionality within N is working. It's
419:51 sending data back. We want to customize
419:53 our actual interface a little bit. So
419:55 the first thing I want to do just for
419:56 fun is create a level system. So every
419:58 time someone submits a problem, they're
420:00 going to get a point. And if they get
420:01 five points, they'll level up. If they
420:02 get 20 total points, they'll level up
420:04 again. Okay. So I just sent off create a
420:06 dynamic level system. Every time a user
420:08 submits a problem, they get a point.
420:11 Everyone starts at level one and after
420:12 five points, they reach level two. Then
420:14 after 50 more points, they reach level
420:15 three. And obviously, we'd have to bake
420:17 in the rest of the the levels and how
420:18 many points you need. But this is just
420:20 to show you that this is going to
420:21 increase every time that we submit a
420:23 problem. And also, you'd want to have
420:24 some sort of element where people
420:26 actually log in and get authenticated.
420:28 And you can store that data in Superbase
420:29 or in um you know, Firebase, whatever it
420:31 is, so that everyone's levels are being
420:33 saved and it's specific to that person.
420:36 Okay, so looks like it just created a
420:38 level system. It's reloading up our
420:40 preview so we can see what that looks
420:41 like now. Um, looks like there may have
420:43 been an error, but now, as you can see
420:45 right here, we have a level system. So,
420:47 let's give it another try. I'm going to
420:48 go into Nitn. We're going to hit test
420:50 workflow. So, it's listening once again,
420:52 and we're going to describe a problem.
420:53 So, I'm saying my boss is mean. I don't
420:54 want to talk to him. We're going to hit
420:56 submit. The NN workflow is running right
420:58 now on the back end. And we just got a
420:59 message back, which is, I'd love to
421:01 chat, but I've got a hot date with my
421:02 couch and binge watching the entire
421:04 season of Awkward Bosses. And you can
421:05 see that we got a point. So, four more
421:07 points to unlock level two. But before
421:09 we continue to throw more prompts so
421:10 that we get up to level two, let's add
421:12 in one more cool
421:13 functionality. Okay, so I'm just firing
421:16 off this message that says add a drop
421:18 down after what problem can we help with
421:20 that gives the user the option to pick a
421:22 tone for the response. So the options
421:24 can be realistic, funny, ridiculous, or
421:26 outrageous. And this data of course
421:28 should be passed along in that web hook
421:31 to NADN because then we can tell the
421:33 agent to say okay here's the problem and
421:35 here's the tone of an excuse the user is
421:37 requesting and now it can make a request
421:39 or a response for us. So looks like it's
421:42 creating that change right now. So now
421:44 we can see our dropown menu that has
421:45 realistic, funny, ridiculous, and
421:47 outrageous. As you can see before you
421:48 click on it, it's maybe not super clear
421:50 that this is actually a drop down. So
421:51 let's make that more clear. And what I'm
421:53 going to do is I'm going to take a
421:54 screenshot of this section right here.
421:56 I'm going to copy this and I'm just
421:58 going to paste it in here and say make
422:00 this more clear that it is a drop-own
422:04 selection and we'll see what it does
422:06 here. Okay, perfect. So, it just added a
422:08 little arrow as well as a placeholder
422:10 text. So, that's way more clear. And now
422:12 what we want to do is test this out.
422:13 Okay, so now to test this out, we're
422:14 going to hit test workflow. But just
422:16 keep in mind that this agent isn't yet
422:18 configured to also look at the tone. So
422:20 this tone won't be accounted for yet.
422:22 But what we're going to do is we have I
422:23 overslept and the response is going to
422:25 be funny. We'll hit generate me a or
422:28 sorry get me out of this. So we have a
422:30 response and our level went up. We got
422:32 another point. But if we go into Nit, we
422:34 can see that it didn't actually account
422:36 for the tone yet. So all we have to do
422:37 is in the actual user message, we're
422:40 basically just going to open this up and
422:41 also add a tone. And we can scroll all
422:43 the way down here and we can grab the
422:45 tone from the body request. And now it's
422:48 getting the problem as well as the tone.
422:50 And now in the system prompt, which is
422:51 basically just defining to the agent its
422:53 role. We have to tell it how to account
422:55 for different tones. Okay, so here's
422:57 what I came up with. I gave it some more
422:58 instructions and I said, "You're going
423:00 to receive a problem as well as a tone.
423:02 And here are the possible tones, which
423:03 are realistic, funny, ridiculous, and
423:05 outrageous." And I kind of said what
423:07 that means. And then I said, "Your
423:09 excuse should be one to three sentences
423:10 long, and match the selected tone." So
423:12 that's all we're going to do. We're
423:13 going to hit save. Okay. So now that
423:15 it's looking at everything, we're going
423:16 to hit test workflow. The web hook's
423:18 listening. We'll come back into here and
423:19 we're going to submit. I broke my
423:20 friend's iPhone and the response tone
423:22 should be outrageous. So, we're going to
423:23 send that off. And it's loading because
423:26 our end workflow is triggering. And now
423:27 we just got it. We also got a message
423:29 that says we earned a point. So, right
423:31 here, we now only need two more for
423:32 level two. But the excuse is I was
423:34 trying to summon a unicorn with my
423:36 telekinetic powers and accidentally
423:38 transformed your iPhone into a rogue
423:39 toaster that launched itself off the
423:41 counter. I swear it was just trying to
423:43 toast a bagel. Okay, so obviously that's
423:45 pretty outrageous and that's how we know
423:46 it's working. So, I'm sure you guys are
423:48 wondering what would you want to do if
423:49 you didn't want to come in here and
423:51 every single time make this thing, you
423:53 know, test workflow. What you would do
423:55 is you'd switch this to an active
423:56 workflow. Now, basically, we're not
423:59 going to see the executions live anymore
424:00 with all these green outlines. But
424:03 what's happening now is it's using the
424:04 production URL. So, we're going to have
424:06 to copy the production URL, come back
424:08 into Lovable, and just basically say I
424:11 switched the URL or sorry, let's call I
424:14 switched the web hook to this. And we'll
424:17 paste that in there, and it should just
424:19 change the data. The logic should be all
424:21 the exact same because we've already
424:23 built that into this app, but we're just
424:25 going to switch the web hook. So, now we
424:26 don't have to go click test workflow
424:28 every time in NAN. And super excited. We
424:31 have two more problems to submit and
424:32 then we'll be level two. So now it says
424:34 the web hook URL has been updated. So
424:36 let's test it out. As you can see in
424:37 here, we have an active workflow. We're
424:39 not hitting test workflow. We're going
424:41 to come in here and submit a new
424:42 problem. So we are going to say um I
424:45 want to take four weeks off work, but my
424:51 boss won't let me. We are going to make
424:54 the response tone. Let's just do a
424:56 realistic one. And we'll click get me
424:58 out of this. It's now calling that
425:00 workflow that's active and it's
425:01 listening. So we got a point. We got our
425:02 response which is I've been dealing with
425:04 some unforeseen family matters that need
425:06 my attention. I believe taking 4 weeks
425:08 off will help me address them properly.
425:09 I plan this time to use this time to
425:11 ensure everything is in order so I can
425:12 return more focused and productive. I
425:14 would definitely say that that's
425:15 realistic. What we can do is come into
425:17 NAN. We can click up here on our
425:19 executions and we can see what just
425:20 happened. So this is our most recent
425:22 execution and if we click into here it
425:25 should have been getting the problem
425:26 which was I want to take four weeks off
425:28 work and the tone which was realistic.
425:30 Cool. Cool. So, now that we know that
425:31 our active new web hook is working,
425:33 let's just do one more query and let's
425:36 earn our level two status. I'm also
425:38 curious to see, you know, we haven't
425:39 worked in any logic of what happens when
425:41 you hit level two. Maybe there's some
425:42 confetti. Maybe it's just a little
425:44 notification. We're about to find out.
425:46 Okay, so I said I got invited on a
425:47 camping trip, but I hate nature. We're
425:49 going to go with ridiculous and we're
425:50 going to send this off. See what we get
425:52 and see what level two looks like. Okay,
425:55 so nothing crazy. We could have worked
425:57 in like, hey, you know, make some
425:58 confetti pop up. All we do is we get
426:00 promoted to level two up here. But, you
426:01 know, as you can see, the bar was
426:02 dynamic. It moved and it did promote us
426:04 to level two. But the excuse is, I'd
426:06 love to join, but unfortunately, I just
426:08 installed a new home system that detects
426:10 the presence of grass, trees, and
426:11 anything remotely outdoorsy. If I go
426:13 camping, my house might launch an
426:15 automated rescue mission to drag me back
426:16 indoors. So, that's pretty ridiculous.
426:19 And also, by the way, up in the preview,
426:20 you can make it mobile. So, we can see
426:22 what this would look like on mobile.
426:23 Obviously, it's not completely optimized
426:24 yet, so we'd have to work on that. But
426:26 that's the ability to do both desktop
426:28 and mobile. And then when you're finally
426:30 good with your app, up in the top right,
426:31 we can hit publish, which is just going
426:33 to show us that we can connect it to a
426:34 custom domain or we can publish it at
426:37 this domain that is made for us right
426:38 here. Anyways, that is going to be it
426:40 for today's video. This is really just
426:42 the tip of the iceberg with, you know,
426:43 nodn already has basically unlimited
426:45 capabilities. But when you connect that
426:47 to a custom front end when you don't
426:49 have to have any sort of coding
426:51 knowledge, as you can see, all of these
426:52 prompts that I use in here was just me
426:54 talking to it as if I was talking to a
426:56 developer. And it's really, really cool
426:58 how quick we spun this up. All right,
426:59 hopefully you guys thought that was
427:00 cool. I think that 11 Labs is awesome
427:02 and it's cool to integrate agents with
427:04 that as well as lovable or bolt. or
427:06 these other vibe coding apps that let
427:08 you build things. That would have taken
427:09 so much longer and you would have kind
427:11 of had to know how to code. So, really
427:13 cool. So, we're nearing the end of the
427:14 course, but it would be pretty shameful
427:16 if I didn't at least cover what MCP
427:18 servers are because they're only going
427:20 to get more commonly used as we evolve
427:23 through the space. So, we're going to
427:25 talk about MCP servers. We're going to
427:26 break it down as simple as possible. And
427:28 then I'm going to do a live setup where
427:30 I'm self-hosting NADN in front of you
427:31 guys step by step. and then I'm going to
427:33 connect to a community node in NN that
427:36 lets us access some MCP servers. So,
427:38 let's get into it. Okay, so model
427:40 context protocol. I swear the past week
427:43 it's been the only thing I've seen in
427:45 YouTube comments, YouTube videos,
427:47 Twitter, LinkedIn, it's just all over.
427:49 And I don't know about you guys, but
427:51 when I first started reading about this
427:52 kind of stuff, I was kind of intimidated
427:55 by it. I didn't completely understand
427:56 what was going on. It was very techy
427:58 and, you know, kind of abstract. I also
428:00 felt like I was getting different
428:02 information based on every source. So,
428:04 we're going to break it down as simple
428:06 as possible how it makes AI agents more
428:08 intelligent. Okay, so we're going to
428:10 start with the basics here. Let's just
428:11 pretend we're going back to Chad GBT,
428:13 which is, you know, a large language
428:15 model. What we have is an input on the
428:17 left. We're able to ask it a question.
428:19 You know, help me write this email, tell
428:20 me a joke, whatever it is. We feed in an
428:22 input. The LM thinks about it and
428:25 provides some sort of answer to us as an
428:26 output. And that's really all that
428:28 happens. The next evolution was when we
428:30 started to give LLM tools and that's
428:33 when we got AI agents because now we
428:36 could ask it to do something like write
428:37 an email but rather than just writing
428:39 the email and giving it back to us it
428:41 could call a tool to actually write that
428:42 email and then it would tell us there
428:45 you go the job's done. And so this
428:46 really started to expand the
428:47 capabilities of these LLM because they
428:49 could actually take action on our behalf
428:51 rather than just sort of assisting us
428:53 and getting us 70% of the way there. And
428:55 so before we start talking about MCP
428:57 servers and how that enhances our agents
428:59 abilities, we need to talk about how
429:01 these tools work and sort of the
429:03 limitations of them. Okay, so sticking
429:05 with that email example, let's pretend
429:06 that this is an email agent that's
429:08 helping us take action in email. What
429:10 it's going to do is each tool has a very
429:12 specific function. So this first tool
429:14 over here, you can see this one is going
429:15 to label emails. The second tool in the
429:17 middle is going to get emails and then
429:18 this third one on the right is going to
429:20 send emails. So if you watched my
429:21 ultimate assistant video, if you
429:23 haven't, I'll tag it right up here. What
429:24 happened was we had a main agent and
429:26 then it was calling on a separate agent
429:27 that was an email agent. And as you can
429:29 see here was all of its different tools
429:31 and each one had one very specific
429:33 function that it could do. And it was
429:35 basically just up to the email agent
429:36 right here to decide which one to use
429:38 based on the incoming query. And so the
429:40 reason that these tools aren't super
429:42 flexible is because within each of these
429:44 configurations, we basically have to
429:46 hardcode in what is the operation I'm
429:48 doing here and what's the resource. And
429:50 then we can feed in some dynamic things
429:52 like different message ids or label ids.
429:54 Over here you know the operation is get
429:56 the resources message. So that won't
429:58 change. And then over here the operation
430:00 is that we're sending a message. And so
430:02 this was really cool because agents were
430:04 able to use their brains whatever large
430:06 language model we had plugged into them
430:07 to understand which tool do I need to
430:09 use. And it still works pretty well. But
430:11 when it comes to being able to scale
430:12 this up and you want to interact with
430:14 multiple different things, not just
430:15 Gmail and Google Calendar, you also want
430:17 to interact with a CRM and different
430:19 databases, that's where it starts to get
430:22 a little confusing. So now we start to
430:24 interact with something called an MCP
430:26 server. And it's basically just going to
430:28 be a layer between your agent and
430:30 between the tools that you want to hit,
430:32 which would be right here. And so when
430:33 the agent sends a request to the
430:35 specific MCP server, in this case, let's
430:37 pretend it's notion, it's going to get
430:39 more information back than hey, what
430:41 tools do I have? And what's the
430:42 functionality here? It's also going to
430:43 get information about like what are the
430:45 resources there, what are the schemas
430:46 there, what are the prompts there, and
430:48 it uses all of that to understand how to
430:51 actually take the action that we asked
430:53 back here in the whole input that
430:54 triggered the workflow. when it comes to
430:56 different services talking to each
430:57 other. So in this case Nadn and notion
431:01 there's been you know a standard in the
431:03 way that we send data across and we get
431:04 data back which has been the rest APIs
431:07 and these standards are really important
431:08 because we have to understand how can we
431:10 actually format our data and send it
431:12 over and know that it's going to be
431:14 received in the way that we intend it to
431:16 be. And so that's exactly what was going
431:17 on back up here where every time that we
431:19 wanted to interact with a specific tool
431:21 we were hitting a specific endpoint. So
431:24 the endpoint for labeling emails was
431:25 different for the endpoint for sending
431:27 emails. And besides just those endpoints
431:29 or functions being different, there was
431:31 also different things that we had to
431:32 configure within each tool call. So over
431:35 here you can see what we had to do was
431:37 in order to send an email, we have to
431:39 give it who it's going to, what the
431:41 subject is, the email type, and the
431:43 message, which is different from the
431:44 information we need to send to this
431:45 tool, which is what's the message ID you
431:47 want to label, and what is the label
431:49 name or ID to give to that message. By
431:52 going through the MCP server, it's
431:54 basically going to be a universal
431:55 translator that takes the information
431:57 from the LLM and it enriches that with
432:00 all of the information that we need in
432:01 order to hit the right tool with the
432:03 right schema, fill in the right
432:04 parameters, access the right resources,
432:07 all that kind of stuff. The reason I put
432:08 notion here for an example of an MCP
432:10 server is because within your notion,
432:13 you'll have multiple different databases
432:14 and within those databases, you're going
432:16 to have tons of different columns and
432:18 then all of those, you know, are going
432:20 to have different pages. So, being able
432:21 to have the MCP server translate back to
432:23 your agent, here are all of the
432:25 databases you have. Here is the schema
432:27 or the different fields or columns that
432:29 are in each of your databases. Um, and
432:32 also here are the actions you can take.
432:33 Now, using that information, what do you
432:35 want to do? Real quick, hopping back to
432:37 the example of the ultimate assistant.
432:39 What we have up here is the main agent
432:41 and then it had four child workflows,
432:43 child agents that it could hit that had
432:45 specializations in certain areas. So the
432:48 Gmail agent, which we talked about right
432:49 down here, the Google calendar agent,
432:51 the contact agent, which was Air Table,
432:54 and then the content creator agent. So
432:56 all that this agent had to do was
432:57 understand, okay, based on what's coming
432:59 in, based on the request from the human,
433:01 which of these different tools do I
433:03 actually access? And we can honestly
433:04 kind of think of these as MCP servers.
433:07 Because once the query gets passed off
433:09 to the Gmail agent, the Gmail agent down
433:11 here is the one that understands here
433:13 are the tools I have, here are the
433:14 different like, you know, parameters I
433:16 need to fill out. I'm going to take care
433:17 of it and then we're going to respond
433:18 back to the main agent. This system made
433:21 things a little more dynamic and
433:22 flexible because then we didn't have to
433:24 have the ultimate assistant hooked up to
433:25 like 40 different tools, you know, all
433:28 the combinations of all of these. And it
433:29 made its job a little more easier by
433:31 just delegating the work to different
433:32 MCP servers. And obviously, these aren't
433:35 MCP servers, but it's kind of the same
433:36 concept. The difference here is that
433:39 let's say all of a sudden Gmail adds
433:41 more functionality. We would have to
433:42 come in here and add more tools in this
433:44 case. But what's going on with the MCP
433:46 servers is whatever MCP server that
433:48 you're accessing, it's on them to
433:51 continuously keep that server updated so
433:53 that people can always access it and do
433:56 what they need to do. By this point, it
433:58 should be starting to click, but maybe
433:59 it's not 100% clear. So, we're going to
434:01 look at an actual example of like what
434:03 this really looks like in action. But
434:05 before we do, just want to cover one
434:06 thing, which is, you know, the agent
434:08 sending over a request to a server. the
434:10 server translates it in order to get all
434:12 this information and get the tool calls,
434:14 all that kind of stuff. Um, and what's
434:16 going on here is called MCP protocol.
434:18 So, we have the client, which is just
434:20 the interface that we're using. In this
434:21 case, it's NN. It could be your claude
434:23 or your, you know, coding window,
434:25 whatever it is. And then we're sending
434:27 over something to the MCP server, and
434:29 that's called MCP protocol. Also, one
434:31 thing to keep in mind here that I'm not
434:32 going to dive into, but if you were to
434:34 create your own MCP server and it had
434:35 access to all of your own resources,
434:37 your schemas, your tools, all that kind
434:39 of stuff, you just got to be careful
434:40 there. There's some security concerns
434:42 because if anyone was getting into that
434:44 server, they could basically ask for
434:45 anything back. So, that's something that
434:47 was brought up in my paid community. We
434:49 were having a great discussion about MCP
434:51 and stuff like that. So, just keep it in
434:53 mind. So, let's look more at an example
434:55 in Naden once again. So coming down
434:57 here, let's pretend that we have this
434:59 beautiful air table agent that we built
435:01 out in NAN. As you can see, it has these
435:04 um seven different tools, which is get
435:06 record, update record, get bases, create
435:09 record, search record, delete record,
435:10 and get bases schema. The reason we
435:12 needed all of these different tools is
435:14 because, as you know, they each have
435:15 different operations inside of them, and
435:17 then they each have different parameters
435:19 to be filled out. So the agent takes
435:20 care of all of that. But this could be a
435:22 lot more lean of a system if we were
435:24 able to access Air Table's MCP server as
435:27 you see what we're doing right here
435:28 because this is able to list all the
435:30 tools that we have available in Air
435:32 Table. So here you can see I asked the
435:34 Air Table agent what actions do I have?
435:36 It then listed these 13 different
435:38 actions that we have which are actually
435:39 more than the seven we had built out
435:40 here. And we can see we have list
435:42 records, search records, and then 11
435:45 more. And this is actually just the
435:47 agent telling us the human what we have
435:48 access to. But what the actual agent
435:51 would look at in order to use the tool
435:52 is a list of the tools where it would be
435:54 here's the name, here's the description
435:56 of when you use this tool, and then
435:57 here's the schema of what you need to
436:00 send over to this tool. Because when
436:01 we're listing records, we have to send
436:03 over different information like the base
436:04 ID, the table ID, max records, how we
436:07 want to filter, which is different than
436:08 if we want to list tables because we
436:10 need a base ID and a detail label. So
436:12 all of this information coming back from
436:14 the MCP server tells the agent how it
436:17 needs to fill out all of these
436:18 parameters that we were talking about
436:19 earlier where it's like send email. You
436:21 have different things than you need to
436:22 fill out for labeling emails. So once
436:25 the agent gets this information back
436:27 from the MCP server, it's going to say
436:29 okay well I know that I need to use the
436:31 search records tool because the user
436:33 asked me to search for records with the
436:35 name Bob in it. So I have this schema
436:38 that I need to use and I'm going to use
436:39 my air tableable execute tool in order
436:41 to do so. And basically what it's going
436:43 to do is going to choose which tool it
436:44 needs based on the information it was
436:46 fed previously. So in this case the air
436:48 table execute tool would search records
436:50 and it would do it by filling in this
436:52 schema of information that we need to
436:53 pass over to air tableable. So now I
436:55 hope you can see how basically what's
436:57 going on in this tool is all 13 tools
436:59 wrapped up into one and then what's
437:01 going on here is just feeding all the
437:03 information we need in order to make the
437:04 correct decision. So, this is the
437:06 workflow we were looking at for the
437:07 demo. We're not going to dive into this
437:09 one because it's just a lot to look at.
437:10 I just wanted to put a ton of MCP
437:12 servers in one agent and see that even
437:14 if we had no system prompt, if it could
437:16 understand which one to use and then
437:18 still understand how to call its tools.
437:19 So, I just thought that was a cool
437:20 experiment. Obviously, what's next is
437:22 I'm going to try to build some sort of
437:23 huge, you know, personal type assistant
437:25 with a ton of MCP servers. But for now,
437:27 let's just kind of break it down as
437:28 simple as possible by looking at an
437:30 individual MCP agent. And so I I don't
437:33 know why I called it an MCP agent. In
437:35 this case, it's just kind of like a
437:36 firecrawl agent with access to firecraws
437:39 MCP server. So yeah. Okay. So taking a
437:42 look at firecraw agent, we're going to
437:43 ask what tools do you have? It's hitting
437:45 the firecrawl actions right now in order
437:48 to pull back all of the resources. And
437:50 as you can see, it's going to come back
437:51 and say, hey, we have these, you know,
437:52 nine actions you can take. I don't know
437:54 if it's nine, but it's going to be
437:55 something like that. It was nine. So as
437:57 you can see, we have access to scrape,
437:58 map, crawl, batch scrape, all this other
438:01 stuff. And what's really cool is that if
438:02 we click into here, we can see that we
438:04 have a description for when to use each
438:06 tool and what you actually need to send
438:07 over. So if we want to scrape, it's a
438:09 different schema to fill out than if we
438:11 want to do something like extract. So
438:13 let's try actually asking it to do
438:14 something. So let's say um extract the
438:19 rewards program name from um
438:23 chipotle.com. So we'll see what it does
438:25 here. Obviously, it's going to do the
438:27 same thing, listing its actions, and
438:28 then it should be using the firecrawl
438:31 extract method. So, we'll see what comes
438:34 back out of that tool. Okay, it went
438:36 green. Hopefully, we actually got a
438:37 response. It's hitting it again. So,
438:39 we'll see what happened. We'll dive into
438:41 the logs after this. Okay, so on the
438:43 third run, it finally says the rewards
438:44 program is called Chipotle Rewards. So,
438:47 let's take a look at run one. It used
438:49 firecrawl extract and it basically
438:51 filled in the prompt extract the name of
438:53 the rewards program. It put it in as a
438:54 string. We got a request failed with
438:56 status code 400. So, not sure what
438:58 happened there. Run two, it did a
439:00 firecross scrape. We also got a status
439:01 code 400. And then run three, what it
439:04 did was a firecall scrape once again,
439:06 and it was able to scrape the entire
439:08 thing. And then it used its brain to
439:09 figure out what the rewards program was
439:11 called. Taking a quick look at the
439:12 firewall documentation, we can see that
439:14 a 400 error code means that the
439:16 parameters weren't filled out correctly.
439:18 So what happened here was basically it
439:20 just didn't fill these out exactly
439:21 correctly the schema of like the prompt
439:23 and everything to send over. And so
439:25 really these kind of issues just come
439:26 down to a matter of you know making the
439:28 tool parameters more robust and also
439:31 more prompting within the actual
439:32 firecrawl agent itself. But it's pretty
439:34 cool that it was able to understand okay
439:36 this didn't work. Let me just try some
439:37 other things. Okay, so real quick just
439:39 wanted to say if you want to hop into
439:41 Nit and test out these MCP nodes, you're
439:43 going to have to self-host your
439:44 environment because you need to use the
439:46 community nodes and you can only access
439:48 those if you are
439:51 self-hosted. Today we're going to be
439:53 going through the full setup of
439:54 connecting MCP servers to NN. I'm going
439:57 to walk through how you self-host your
439:58 NN. I'm going to walk through how you
439:59 can install the community node and then
440:01 how to actually set up the community
440:02 node. The best part is you don't have to
440:04 open up a terminal or a shell and type
440:06 in any install commands. All we have to
440:08 do is connect to the servers through
440:09 NIND. So, if that sounds like something
440:11 that interests you, let's dive into it.
440:13 Make sure you guys stick around for the
440:14 end of this one because we're going to
440:15 talk about the current limitations of
440:17 these MCP nodes. We're going to talk
440:18 about some problems you may face that no
440:20 one else is talking about and really
440:21 what does it mean to actually be able to
440:23 scale these agents with MCP servers.
440:25 Now, there are a ton of different
440:26 platforms that you can use to host NN.
440:28 The reason I'm using Alstio is because
440:29 it's going to be really simple for
440:30 deploying and managing open- source
440:32 software. Especially with something like
440:34 NN, you can pretty much deploy it in
440:35 just a few clicks and it's going to take
440:37 care of installation, configuration,
440:39 security, backups, updates, all this
440:41 kind of stuff. So, there's no need for
440:43 you to have that DevOps knowledge
440:44 because I certainly don't. So, that's
440:47 why we're going with Alstio. It's also
440:49 SOCK 2 and GDPR compliant. So, that's
440:51 important. Anyways, like I said, we're
440:53 going to be going through the full
440:54 process. So, I'm going to click on free
440:55 trial. I'm going to sign up with a new
440:57 account. So, I'm going to log out and
440:58 sign up as a new user. Okay. Now that I
441:00 entered that, we're already good to go.
441:01 The first thing I'm going to do is set
441:02 up a payment method so that we can
441:04 actually spin up a service. So, I went
441:05 down to my account in the lefth hand
441:07 side and then I clicked on payment
441:08 options and I'm going to add a card real
441:09 quick. Now that that's been added, it's
441:11 going to take a few minutes for our
441:12 account to actually be approved. So, I'm
441:14 just going to wait for that. You can see
441:15 we have a support ticket that got opened
441:16 up, which is just waiting for account
441:19 activation. Also, here's the approval
441:21 email I got. Just keep in mind it says
441:22 it'll be activated in a few minutes
441:23 during business hours, but if you're
441:25 doing this at night or on the weekends,
441:26 it may take a little longer. Okay, there
441:28 we go. We are now activated. So, I'm
441:29 going to come up here to services and
441:30 I'm going to add a new service. What
441:32 we're going to do is just type in nadn
441:34 and it's going to be a really quick
441:35 oneclick install. Basically, I'm going
441:37 to just be deploying on htzner as a
441:39 cloud provider. I'm going to switch to
441:41 my region and then you have different
441:43 options for service plans. So, these
441:44 options obviously have different numbers
441:46 of CPUs, different amount of RAM and
441:48 storage. I'm going to start right now on
441:50 just the medium. I would keep in mind
441:51 that MCP servers can be kind of resource
441:53 intensive. So, if you are running
441:55 multiple of them and your environment is
441:57 crashing, then you're probably just
441:58 going to want to come in here and
441:59 upgrade your service plan. So, we can
442:01 see down here, here is the estimated
442:02 hourly price. Here's the plan we're
442:04 going with. And I'm going to go ahead
442:05 and move forward. Now, we're going to
442:06 set up the name. So, this will pop up as
442:08 your domain for your NAND environment.
442:10 Then, I went ahead and called this Nad-
442:11 demo. What you can do here is you can
442:13 add more volume. So, if you wanted to,
442:15 you could increase the amount of
442:16 storage. And as you can see down here,
442:17 it's going to increase your hourly
442:18 price. I'm not going to do that, but you
442:20 do have that option. And then of course
442:22 you have some advanced configuration for
442:24 software updates and system updates.
442:25 Once again, I'm just going to leave that
442:26 as is. And then you can also choose the
442:28 level of support that you need. You can
442:30 scan through your different options
442:31 here. Obviously, you'll have a different
442:32 price associated with it. But on the
442:34 default plan, I'm just going to continue
442:36 with level one support. And now I'm
442:38 going to click on create service. Okay.
442:40 So, I don't have enough credits to
442:41 actually deploy this service. So, I'm
442:42 going to have to go add some credits in
442:44 my account. So, back in the account, I
442:46 went to add credits. And now that I have
442:47 a card, I can actually add some credits.
442:49 So, I'm going to agree to the terms and
442:50 add funds. Payment successful. Nice. We
442:52 have some money to play with. Down here,
442:54 we can see 10 credits. This is also
442:55 where we'll see how much we're spending
442:57 per hour once we have this service up
442:59 and running. Unfortunately, we have to
443:00 do that all again. So, let me get back
443:01 to the screen we were just on. Okay, now
443:03 we're back here. I'm going to click
443:04 create service. We're deploying your
443:06 service. Please wait. And this is
443:07 basically just going to take a few
443:08 minutes to spin up. Okay, so now what we
443:10 see is the service is currently running.
443:11 We can click into the service and we
443:13 should be able to get a link that's
443:14 going to take us to our NN instance. So,
443:16 here's what it looks like. We can see
443:17 it's running. and we have all these
443:18 different tabs and all these different
443:19 things to look through. We're going to
443:20 keep it simple today and not really dive
443:22 into it. But what we're going to do is
443:23 come down here to our network and this
443:24 is our actual domain to go to. So if I
443:27 select all of this and I just click go
443:29 to this app, it's going to spin up our
443:31 NN environment and because this is the
443:32 first time we're visiting it. We just
443:34 have to do the setup. Okay. So once we
443:35 have that configured, going to hit next.
443:37 We have to do some fun little onboarding
443:38 where it's going to ask us some
443:39 questions right here. So then when
443:41 you're done with that, you just got to
443:42 click get started and you now have this
443:44 option to get some paid features for
443:45 free. I'm going to hit skip and we're
443:47 good to go. We are in NAN. So what's
443:49 next is we need to install a community
443:50 node. So if you come down here to your
443:52 settings and you click on settings, um
443:55 you can see you're on the community
443:56 plan. We can go all the way down here to
443:58 community nodes. And now we have to
443:59 install a community node. So in the
444:01 description we have the GitHub
444:02 repository for this NAD nodes MCP that
444:05 was made by Nerding. And you can see
444:06 there's some information on how to
444:07 actually install this. But all we have
444:09 to do is basically just copy this line
444:10 right here. I'm just going to copy NAN-
444:12 Nodes MCP. Click on install community
444:15 node. Put that in there. Hit understand.
444:17 And so the reason you can only do this
444:18 on self-hosted is because these nodes
444:20 are not a native verified node from
444:23 Naden. So it's just like, you know,
444:24 we're downloading it from a public
444:25 source, at least the code. And then we
444:27 hit install. Package installed. We can
444:29 now see we have one community node,
444:31 which is the MCP. Cool. So I'm going to
444:33 leave my settings and I'm going to open
444:35 up a new workflow. And we're just going
444:36 to hit tab to see if we have the actual
444:38 node. So if I type in MCP, we can see
444:40 that we have MCP client and we have this
444:42 little block, which just means that it
444:43 is part of the community node. So, I'm
444:45 going to click into here, and we can see
444:47 we have some different options. We can
444:48 execute a tool. We can get a prompt
444:50 template. We can list available prompts,
444:52 list available resources, list available
444:54 tools, and read a resource. Right now,
444:56 let's go with list available tools. Um,
444:58 the main one we'll be looking at is
444:59 listing tools and then executing tools.
445:01 So, quick plug for the school community.
445:03 If you're looking for a more hands-on
445:04 learning experience, as well as wanting
445:06 to connect with over 700 members who are
445:08 also dedicated to this rapidly evolving
445:10 space, then definitely give this
445:11 community a look. We have great
445:13 discussions, great guest speakers as you
445:14 can see. We also have a classroom
445:16 section with stuff like building agents,
445:17 vector databases, APIs and HTTP request,
445:20 step-by-step builds. All the live calls
445:22 are recorded, all this kind of stuff.
445:23 So, if this sounds interesting to you,
445:24 then I'd love to see you in a live call.
445:26 Anyways, let's get back to the video.
445:28 So, obviously, we have the operation,
445:29 but we haven't set up a credential yet.
445:31 So now what you're going to do is go to
445:32 a different link in the description
445:34 which is the GitHub repository for
445:36 different MCP servers and we can pretty
445:38 much connect to any of these like I said
445:40 without having to run any code in our
445:42 terminal and install some stuff at least
445:44 because we're hosting in the cloud. If
445:46 we're hosting locally it may be a little
445:47 different. Okay, so I've seen a ton of
445:49 tutorials go over like Brave Search or
445:50 Firecrawl. Um so let's try to do
445:52 something a little more fun. I think
445:53 first we'll start off with Airbnb
445:55 because this one is going to be free.
445:56 You don't even have to go get an API
445:58 key. So that's really cool. So, I'm
445:59 going to click into this Airbnb MCP
446:01 server. There's a bunch of stuff going
446:02 on here. And if you understand GitHub
446:04 and repositories and some code, you can
446:06 look through like the Docker file and
446:08 everything, which is pretty cool. But
446:09 for us non techies, all we have to do is
446:12 come down here. It's going to tell us
446:13 what tools are available. But we just
446:15 need to look at how to actually install
446:16 this. And so, all we're looking for is
446:18 the MPX type installer. And so after my
446:21 testing, I tried this one first, but it
446:23 wouldn't let us execute the tool because
446:25 we need to use this thing that is ignore
446:26 robots text, which just basically lets
446:28 us actually access the platform. So you
446:30 can see here we have a command, which is
446:32 npx, and then we have an array of
446:33 arguments, which is -y, this open B&B
446:36 thing, and then also the ignore robots
446:38 text. So first of all, I'm just going to
446:39 grab the command, which is npx. Copy
446:42 that. Go back and edit in, and we're
446:43 going to create a new credential. This
446:45 one's going to be for Airbnb. So I'm
446:47 just going to name this so we have it
446:48 kept. And then we're just going to paste
446:49 the command right into there, mpx. Now
446:52 we can see we have arguments to fill
446:53 out. So I'm going to go back into that
446:55 documentation. We can see the arguments
446:57 are -ash-y. And then the next one is the
446:59 open B&B. And then the next one is
447:01 ignore robots text. So we're going to
447:03 put them in one by one. So first is the
447:05 dashy. Now I'm going to go back and grab
447:07 the at@
447:09 openb put a space and then paste it in
447:11 there. And then I'm going to put another
447:12 space. And then we're going to grab this
447:14 last part which is the ignore robots
447:16 txt. So once we paste that in there, we
447:18 can basically just hit save. As you can
447:20 see, we've connected successfully. Um
447:21 the credential is now in our space and
447:23 we didn't have to type in anything in a
447:24 terminal. And now if we hit test step,
447:26 we should be able to pull in the tools
447:28 that this MCP server gives us access to.
447:30 So it's as easy as that. As you can see,
447:32 there are two tools. The first one is
447:33 Airbnb search. Here's when you use it,
447:35 and then here's the schema to send over
447:37 to that tool. And then the second one is
447:39 Airbnb listing details. Here's when you
447:41 want to use that, and then here's the
447:43 schema that you would send over. And now
447:44 from here, which is really cool, we can
447:46 click on another node, which is going to
447:47 be an MCP client once again. And this
447:49 time, we want to execute a tool. We
447:51 already have our credential set up. We
447:53 just did that together. And now all we
447:54 have to do is configure the tool name
447:56 and the tool parameters. So just as a
447:57 quick demo that this actually works. The
447:59 tool name, we're going to drag in Airbnb
448:01 search, as you can see. And then for the
448:03 parameter, we can see these are the
448:04 different things that we need to fill
448:05 out. And so all I'm going to do is just
448:07 send over a location. So I obviously
448:10 hardcoded in location equals Los
448:12 Angeles. That's all we're going to try.
448:13 And now we're going to hit test step and
448:14 we should see that we're getting Airbnbs
448:16 back that are in Los Angeles. There we
448:19 go. We have um ton of different items
448:21 here. So, let's actually take a look at
448:23 this listing. So, if I just copy this
448:25 into the browser, we should see an
448:27 Airbnb arts district guest house. This
448:29 is in Culver City, California. And
448:31 obviously, we could make our search more
448:32 refined if we were able to also put in
448:34 like a check-in and checkout date, how
448:36 many adults, how many children, how many
448:38 pets. We could specify the price, all
448:40 this kind of stuff. Okay, cool. So that
448:42 was an example of how we search through
448:43 an MCP server to get the tools and then
448:45 how we can actually execute upon that
448:46 tool. But now if we want to give our
448:48 agent access to an MCP server, what we
448:51 would do is obviously we're going to add
448:52 an AI agent. We are first of all going
448:54 to come down here, give it a chat input
448:56 so we can actually talk to the agent. So
448:58 we'll add that right here. And now we
449:00 obviously need to connect a chat model
449:01 so that the agent has a brain and then
449:03 give it the MCP tools. So first of all,
449:05 just to connect a chat model, I'm just
449:06 going to grab an open AI. I'm sorry for
449:08 being boring, but all we have to do is
449:09 create a credential. So, if you go to
449:11 your OpenAI account and grab an API key.
449:13 So, here's my account. As you can see, I
449:15 have a ton of different keys, but I'm
449:16 just going to create a new one. This is
449:17 going to be MCP test and then all we
449:19 have to do is copy that key. Come back
449:21 and end it in and we're going to paste
449:23 that right in here. So, there's our key.
449:25 Hit save. We'll go green. We're good to
449:26 go. We're connected to OpenAI. And now
449:29 we can choose our model. So, for Mini is
449:30 going to work just fine here. Now, to
449:32 add a tool once again, we're going to
449:33 add the MCP client tool right here. And
449:35 let's just do Airbnb one more time. So,
449:38 we're connected to Airbnb list tools and
449:40 I'm just going to say what tools do I
449:43 have and what's going to happen is it
449:46 errored because the NAND nodes MCP tool
449:49 is not recognized yet even though the
449:50 MCP nodes are. So, we have to go back
449:53 into Alstio real quick and change one
449:55 thing. So, coming back into the GitHub
449:57 repository for the NN MCP node, we can
449:59 see it gives us some installation
450:01 information, right? But if we go all the
450:03 way down to how to use it as a tool, um
450:05 if I can scroll all the way down here.
450:06 So here is an example of using it as a
450:08 tool. You have to set up the environment
450:10 variable within your hosting
450:12 environment. So whether it's Allesio or
450:14 Render or Digital Ocean or wherever
450:16 you're doing it, it'll be a little
450:17 different, but you just have to navigate
450:18 down to where you have environment
450:19 variables. We have to set nad community
450:23 package_allow tool usage. We have to set
450:26 that to equal true. So I'm going to come
450:28 back into our Alstio service. And right
450:30 here we have the software which is NAN
450:32 version latest. And what we can do is we
450:33 can you know restart, view app logs. We
450:35 can change the version here or we can
450:37 update the config which if we open this
450:39 up it may look a little intimidating but
450:41 all we're looking for is right here we
450:43 have environment and we can see we have
450:45 like different stuff with our Postgress
450:47 with our web hook tunnel URLs all this
450:49 kind of stuff and so at the bottom I'm
450:50 just going to add a new line and I'm
450:52 just going to paste in that command we
450:53 had which was nadn community packages
450:55 allow and then instead of an equal I'm
450:57 going to put a colon and now we have
450:59 that nadn community packages allow is
451:02 set to true and I'm just adding a space
451:03 after the colon so now it's link and all
451:06 we're just going to do is hit update and
451:07 restart. And so this is going to respin
451:09 up our instance. Okay, so it looks like
451:10 we are now finished up. I'm going to go
451:12 ahead and close out of this. We can see
451:13 that our instance is running. So now I'm
451:15 going to come back into here and I
451:16 actually refresh this. So our agent's
451:18 gone. So let me get him back real quick.
451:20 All right, so we have our agent back.
451:21 We're going to go ahead and add that MCP
451:23 tool once again. Right here we are going
451:25 to have our credential already set up.
451:27 The operation is list tools. And now
451:28 let's try one more time asking it what
451:31 tools do you have?
451:33 And it knows to use this node because
451:35 it's the operation here is list tools.
451:37 So it's going to be pretty intelligent
451:38 about it. Now it's able to actually call
451:40 that tool because we set up that
451:41 environment variable. So let's see what
451:43 Airbnb responds with as far as what
451:44 tools it actually can use. Cool. So I
451:47 have access to the following tools.
451:48 Airbnb search and listing details. Now
451:50 let's add the actual tool that's going
451:52 to execute on that tool. So Airbnb um
451:56 once again we have a credential already
451:57 set up. The operation we're going to
451:58 choose execute tool instead. And now we
452:00 have to set up what is going on within
452:02 this tool. So the idea here is that when
452:04 the client responds with okay I have
452:06 Airbnb search and I have Airbnb listing
452:08 details the agent will then figure out
452:10 based on what we asked which one do I
452:13 use and the agent has to pass that over
452:15 to this next one which is actually going
452:16 to execute. So what we want to do here
452:19 is the tool name cannot be fixed because
452:21 we want to make this dynamic. So, I'm
452:23 going to change this to an expression
452:24 and I'm going to use the handy from AI
452:26 function here, which is basically we're
452:27 just going to tell the AI agent, okay?
452:30 You know, based on what's going on, you
452:32 choose which tool to use and you're
452:34 going to put that in here. So, I'm going
452:35 to put in quotes tool and then I'm going
452:38 to just define what that means. And in
452:40 quotes after a comma, I'm going to say
452:43 the tool selected. So, we'll just leave
452:45 it as simple as that. And then what's
452:47 really cool is for the tool parameters,
452:49 this is going to change based on the
452:51 actual tool selected because there's
452:52 different schemas or parameters that you
452:54 can send over to the different tools. So
452:57 we're going to start off by just hitting
452:58 this button, which lets the model define
453:00 this parameter. It's going to get back
453:02 what not only what tool am I using, but
453:04 what schema do I need to send over. So
453:05 it should be intelligent enough to
453:07 figure it out for simple queries. So
453:09 let's change this name to Airbnb
453:12 execute. I'm going to change this other
453:14 one to Airbnb tools and then we'll have
453:17 the agent try to figure out what's going
453:18 on. And just a reminder, there's no
453:20 system prompt in here. It literally just
453:22 says your helpful assistant. So, we'll
453:24 see how intelligent this stuff is. Okay,
453:25 so I'm asking it to search for Airbnbs
453:27 in Chicago for four adults. Let's try
453:29 that off. We should obviously be using
453:31 the Airbnb search tool. And then we want
453:34 to see if it can fill out the parameters
453:35 with a location, but also how many
453:37 adults are going to be there because
453:38 earlier all we did was location. So, we
453:41 got a successful response already back.
453:43 Once this finishes up, we should see
453:45 potentially a few links down here that
453:46 actually link to places. So, here we go.
453:49 Um, luxury designer penthouse Gold
453:51 Coast. It's apartment. It has three
453:53 bedrooms, eight beds. So, that
453:54 definitely fits four guests. And you can
453:56 also see it's going to give us the price
453:57 per night as well as, you know, the
453:59 rating and just some other information.
454:01 So, let's click into this one real quick
454:02 and we'll take a look. Make sure it
454:03 actually is in Chicago and it has all
454:05 the stuff. This one does have 10 guests.
454:07 So, awesome. And we can see we got five
454:09 total listings. So without having to
454:12 configure, you know, here's the API
454:14 documentation and here's how we set up
454:15 our HTTP request, we're already able to
454:18 do some pretty cool Airbnb searches. So
454:20 let's take a look in the Airbnb execute
454:21 tool. We can see that what it sent over
454:24 was a location as well as a number of
454:25 adults, which is absolutely perfect. The
454:27 model was able to determine how to
454:29 format that and send it over as JSON.
454:31 And then we got back our actual search
454:33 results. And now we're going to do
454:34 something where you actually do need an
454:35 API key because most of these you are
454:37 going to need an API key. So we're going
454:39 to go ahead and do Brave search because
454:40 you can search the web um using Brave
454:42 Search API. So we're going to click into
454:44 this and all we have to do is once again
454:46 we can see the tools here but we want to
454:48 scroll down and see how you actually
454:49 configure it. So the first step is to go
454:51 to Brave Search and get an API key. You
454:53 can click on this link right here and
454:55 you'll be able to sign in and get 2,000
454:56 free queries and then you'll grab your
454:58 API key. So I'm going to log in real
454:59 quick. So it may send you a code to your
455:01 email to verify it. You'll just put in
455:03 the code, of course, and then we're
455:04 here. As you can see, I've only done one
455:06 request so far. I'm going to click on
455:08 API keys on this lefth hand side, and
455:10 we're just going to copy this token, and
455:11 then we can put it into our
455:12 configuration. So, let's walk through
455:14 how we're going to do that. So, I'm
455:15 going to come in here and add a new
455:16 tool. We're going to add another MCP
455:18 client tool, and we're going to create a
455:19 new credential because we're no longer
455:21 connecting to Airbnb's server. We're
455:23 connecting to Brave Search Server. So,
455:26 create new credential. Let me just name
455:27 this one real quick so we don't get
455:28 confused. And then of course we have to
455:30 set up our command, our arguments, and
455:32 our environments. And this is where
455:33 we're going to put our actual API key.
455:35 Okay, so first things first, the
455:37 command. Coming back into the Brave
455:38 Search MCP server documentation, we can
455:41 see that we can either do Docker, but
455:42 what we're doing every time we're
455:44 connecting to this in NN is going to be
455:46 MPX. So our command once again is MPX.
455:49 Copy that, paste it into the command.
455:51 And now let's go back and get our
455:52 arguments, which is always going to
455:53 start off with
455:55 -ashy. Then after that, put a space.
455:57 We're going to connect to this MCP
455:59 server, which is the Brave Search. And
456:01 then you can see that's it. In the
456:02 Airbnb one, we had to add the robots
456:04 text. In this one, we didn't. So,
456:05 everyone is going to configure a little
456:07 bit differently, but all you have to do
456:08 is just read through the command, the
456:10 arguments, and then the environment
456:11 variables. And in this case, unlike the
456:13 Airbnb one, we actually do need an API
456:15 key. So, what we're going to do is we're
456:16 going to put in all caps
456:19 brave_api_key. So, in the environment
456:21 variables, I'm going to change this to
456:22 an expression just so we can actually
456:24 see. Brave API_key. And then I'm going
456:27 to put an equals and then it says to put
456:29 your actual API key. So that's where
456:30 we're going to paste in the API key from
456:32 Brave Search. Okay. So I put in my API
456:34 key. Obviously I'm going to remove that
456:35 after this video gets uploaded. But now
456:37 we'll hit save and we'll make sure that
456:38 we're good to go. Cool. And now we're
456:40 going to actually test this out. So I'm
456:41 going to call this
456:44 Brave Search Tools. Um and then before
456:48 we add the actual execute tool, I'm just
456:49 going to ask and make sure it works. So
456:52 what Brave Search tools do you have?
456:57 And it knows of course to hit the brave
456:58 search because we gave it a good name.
457:00 And it should be pulling back with its
457:01 different functions which I believe
457:02 there are
457:04 two. Okay. So we have Brave web search
457:06 and we have Brave local search. We also
457:08 have, you know, of course the
457:09 description of when to use each one and
457:11 the actual schemas to send over. So
457:13 let's add a tool and make sure that it's
457:15 working. We're going to click on the
457:16 plus. We're going to add an MCP client
457:18 tool. We already have our Brave
457:19 credential connected. We're going to
457:20 change the operation to execute tool.
457:23 And once again, we're going to fill in
457:24 the tool name and the parameters. So for
457:26 the tool name, same exact thing. We're
457:28 going to do from AI. And once again,
457:30 this is just telling the AI what to fill
457:32 in here. So we're going to call it tool.
457:34 We're going to give it a very brief
457:35 description of the tool
457:37 selected. And then we are just going to
457:39 enable the tool parameters to be filled
457:41 out by the model automatically. Final
457:42 thing is just to call this Brave search
457:46 execute. Cool. There we go. So now we
457:48 have um two functions for Airbnb, two
457:52 for Brave search, and let's make sure
457:53 that the agent can actually distinguish
457:54 between which one to use. So I'm going
457:57 to say search the web for information
458:00 about AI agents. So we'll send that off.
458:04 Looks like it's going straight to the
458:05 Brave Search execute. So we may have to
458:07 get into the system prompt and tweak it
458:08 a little bit. Now it's going back to the
458:10 Brave Search tools to understand, okay,
458:12 what actions can I take? And now it's
458:14 going back to the Brave Search execute
458:15 tool. And hopefully this time it'll get
458:17 it right. So, it looks like it's going
458:19 to compile an answer right now based on
458:21 its search result and then we'll see
458:23 exactly what happened. There we go. So,
458:25 we have looks like Oh, wow. It gave us
458:27 nine different articles. Um, what are AI
458:30 agents by IBM? We can click into here to
458:32 read more. So, this takes us straight to
458:34 IBM's article about AI agents. We have
458:36 one also from AWS. We can click into
458:38 there. There's Amazon. And let's go all
458:40 the way to the bottom. We also have one
458:42 on agents from Cloudflare. So, let's
458:44 click into here. And we can see it took
458:46 us exactly to the right place. So super
458:48 cool. We didn't have to configure any
458:50 sort of API documentation. As you can
458:51 see in Brave Search, if we wanted to
458:53 connect to this a different way, we
458:55 would have had to copy this curl
458:56 command, statically set up the different
458:58 headers and the parameters. But now with
459:00 this server, we can just hit it right
459:02 away. So let's take a look in the agent
459:04 logs, though, because we want to see
459:05 what happened. So the first time it
459:07 tried to go straight to the execute tool
459:09 and as you can see it filled in the
459:10 parameters incorrectly as well as the
459:12 actual tool name because it didn't have
459:14 the information from the server. Then it
459:16 realized okay I need to go here first so
459:18 that I can find out what I can do. I
459:20 tried to use a tool called web search as
459:22 you can see earlier web search. But what
459:24 I needed to do was use a tool called
459:25 brave web search. So now on the second
459:28 try back to the tool it got it right and
459:30 it said brave web search. It also filled
459:32 out some other information like how many
459:34 articles are we looking for and what's
459:35 the offset. So if we were to come back
459:37 in here and say get me one article
459:41 on dogs. Let's see what it would do. So
459:43 hopefully it's going to fill in the
459:44 count as one. Once again it went
459:46 straight to the tool and it may I was
459:48 going to say if we had memory in the
459:50 agent it probably would have worked
459:51 because it would have seen that it used
459:52 brave web search previously but there's
459:55 no memory here. So, it did the exact
459:56 same pattern and we would basically just
459:58 have to prompt in this agent, hey,
460:00 search the MCP server to get the tools
460:03 before you try to execute a tool. But
460:05 now we can see it found one article.
460:07 It's called it's just Wikipedia. So, we
460:08 can click in here and see it's dog on
460:10 Wikipedia. But if we click into the
460:12 actual Brave search execute tool, we can
460:14 see that what it filled out for the
460:15 query was dogs and it also knew to make
460:17 the count one rather than last time it
460:19 was 10. Okay. Okay, so something I want
460:21 you guys to keep in mind is when you're
460:22 connecting to different MCP servers, the
460:25 setup will always be the same where
460:27 you'll look in the GitHub repository,
460:29 you'll look at the command, which will
460:30 be npx, you'll look at the arguments,
460:32 which will be -ashy, space, the name of
460:35 the server, and then sometimes there'll
460:36 be more. And then after that, you'll do
460:38 your environment variable, which is
460:39 going to be a credential, some sort of
460:40 API key. So here, what we did was we
460:43 asked Air Table to list its actions. And
460:44 in this case, as you can see, it has 13
460:46 different actions. And within each
460:48 action, there's going to be different
460:49 parameters to send over. So, when you
460:51 start to scale up to some of these MCP
460:52 servers that have more actions and more
460:54 parameters, you're going to have to be a
460:56 little more specific with your
460:57 prompting. As you can see in this agent,
461:00 there's no prompting going on. It's just
461:01 your helpful assistant. And what I'm
461:03 going to try is in my Air Table, I have
461:05 a base called contacts, a table called
461:07 leads, and then we have this one record.
461:09 So, let's try to ask it to get that
461:11 record. Okay. So, I'm asking it to get
461:12 the records in my Air Table base called
461:14 contacts, in my table called leads.
461:16 Okay, so we got the error receive tool
461:19 input did not match expected schema. And
461:21 so this really is because what has to
461:23 happen here is kind of complex. It has
461:24 to first of all go get the bases to grab
461:26 the base ID and then it has to go grab
461:28 the tables in that base to get the table
461:31 ID and then it has to formulate that
461:33 over in a response over here. As you can
461:35 see, if the operation was to list
461:36 records, it has to fill out the base ID
461:38 and the table ID in order to actually
461:40 get those records back. So that's why
461:42 it's having trouble with that. And so a
461:43 great example of that is within my email
461:45 agent for my ultimate assistant. In
461:48 order to do something like label emails,
461:50 we have to send over the message ID of
461:52 the email that we want to label. And we
461:54 have to send over the ID of the label to
461:56 actually add to that message. And in
461:57 order to do those two things, we first
461:59 have to get all emails to get the
462:01 message ID. And then we have to get
462:02 labels to get the label ID. So it's a
462:04 multi-step process. And that's why this
462:06 agent with minimal prompting and not a
462:08 super robust parameter in here. It's
462:10 literally just defining by the model,
462:12 it's a little bit tough. But if I said
462:13 something like get my air table bases,
462:16 we'll see if it can handle that because
462:18 that's more of a one-step function. And
462:20 it looks like it's having trouble
462:21 because if we click into this actions,
462:23 we can see that the operation of listing
462:24 bases sends over an empty array. So it's
462:28 having trouble being able to like send
462:29 that data over. Okay, so I'm curious
462:31 though. I went into my Air Table and I
462:33 grabbed a base ID. Now I'm going to ask
462:35 what tables are in this air table base
462:37 ID and I gave it the base ID directly so
462:39 it won't have to do that list basis
462:40 function. And now we can see it actually
462:42 is able to call the tool hopefully. So
462:44 it's green and it probably put in that
462:46 base ID and we'll be able to see what
462:48 it's doing here. But this just shows you
462:50 there are still obviously some
462:51 limitations and I'm hoping that Nad will
462:53 make a native you know MCP server node.
462:55 But look what it was able to do now is
462:57 it has here are the tables within the
462:59 air table base ID that we provided and
463:01 these are the four tables and this is
463:03 correct. And so now I'm asking it what
463:04 records are in the air table base ID of
463:06 this one and the table ID of this one.
463:09 And it should be able to actually use
463:10 its list records tool now in order to
463:12 fill in those different parameters. And
463:14 hopefully we can see our record back
463:16 which should be Robert California. So we
463:18 got a successful tool execute as you can
463:20 see. Let's wait for this to pop back
463:22 into the agent and then respond to us.
463:24 So now we have our actual correct
463:25 record. Robert California Saber custom
463:28 AI solution all this kind of stuff. And
463:29 as you can see, that's exactly what
463:31 we're looking at within our actual Air
463:32 Table base. And so, I just thought that
463:34 that would be important to show off here
463:36 how this is like really cool, but it's
463:38 not fully there yet. So, I definitely
463:39 think it will get there, especially if
463:41 we get some more native integrations
463:42 with Naden. But, I thought that that
463:43 would be a good demo to show the way
463:45 that it needs to fill in these
463:46 parameters in order to get records. And,
463:49 you know, this type of example applies
463:51 to tons of different things that you'll
463:52 do within MCP servers. So, there's one
463:55 more thing I want to show you guys real
463:56 quick, just so you will not be banging
463:58 your head against the wall the way I was
463:59 a couple days ago when I was trying to
464:01 set up Perplexity. So, because you have
464:02 all these different servers to choose
464:03 from, you may just trust that they're
464:05 all going to be the exact same and
464:06 they're going to work the same. So, when
464:07 I went to set up the Plexity ask MCP
464:10 server, I was pretty excited. Command
464:11 was mpx. I put in my arguments. I put in
464:13 my environment variable, which was my
464:15 perplexity API key. And you can see I
464:17 set this up exactly as it should be. My
464:18 API keys in there. I triple checked to
464:20 make sure it was correct. And then when
464:22 I went to test step, basically what
464:23 happened was couldn't connect to the MCP
464:25 server. Connection closed. And so after
464:27 digging into what this meant, because I
464:29 set up all these other ones, as you can
464:31 see in here, I did these and I have more
464:32 that I've connected to. The reason why
464:34 this one isn't working, I imagine, is
464:37 because on the server side of things, on
464:38 Perplexity side of things, it's either
464:40 going undergoing maintenance or it's not
464:42 fully published yet. And it's not
464:44 anything wrong with the way that you're
464:45 deploying it. So, I just wanted to throw
464:47 that out there because there may be some
464:48 other ones in this big list that are not
464:50 fully there yet. So, if you are
464:52 experiencing that error and you know
464:53 that you're filling out that, you know,
464:54 MPX and the arguments and the
464:56 environment variable correct, then
464:58 that's probably why don't spend all day
465:00 on it. Just wanted to throw that out
465:01 there because, you know, I had I had a
465:04 moment the other day. Well, it's been a
465:06 fun journey. I appreciate you guys
465:07 spending all this time with me. We've
465:08 got one more section to close off on and
465:11 this is going to be kind of just the
465:12 biggest lessons that I had learned over
465:14 the first six months of me building AI
465:16 agents as a non-programmer. Let's go.
465:18 Because everyone's talking about this
465:20 kind of stuff, there's a lot of hype and
465:21 there's a lot of noise to cut through.
465:22 So, the first thing I want to do is talk
465:24 about the hard truths about AI agents
465:25 and then I'll get into the seven lessons
465:27 that I've learned over the past six
465:28 months building these things. So, the
465:30 first one is that most AI agent demos
465:32 online are just that, they're demos. So,
465:34 the kind of stuff that you're going to
465:35 see on LinkedIn, blog posts, YouTube,
465:38 admittedly, my own videos as well, these
465:40 are not going to be productionready
465:42 builds or productionready templates that
465:43 you could immediately start to plug into
465:45 your own business or try to sell to
465:46 other businesses. You'll see all sorts
465:48 of cool use cases like web researchers,
465:50 salespeople, travel agents. Just for
465:52 some context, these are screenshots of
465:54 some of the videos I've made on YouTube.
465:56 This one is like a content creator. This
465:57 one is a human and loop calendar agent.
465:59 We've got a technical analyst. We have a
466:01 personal assistant with all its agents
466:02 over here. stuff like that. But the
466:04 reality is that all of these pretty much
466:06 are just going to be, you know, proof of
466:07 concepts. They're meant to open
466:09 everyone's eyes to what this kind of
466:11 stuff looks like visually, how you can
466:12 spin this kind of stuff up, the
466:14 fundamentals that go into building these
466:15 workflows. And at least me personally,
466:17 my biggest motivation in making these
466:18 videos is to show you guys how you can
466:21 actually start to build some really cool
466:22 stuff with zero programming background.
466:24 And so why do I give all those templates
466:26 away for free? It's because I want you
466:27 guys to download them, hit run, see the
466:30 data flow through and understand what's
466:31 going on within each node rather than
466:33 being able to sell that or use it
466:34 directly in your business because
466:36 everyone has different integrations.
466:37 Everyone's going to have different
466:38 system prompting and different little
466:40 tweaks that they need for an automation
466:42 to be actually high value for them.
466:44 Besides that, a lot of this is meant to
466:46 be within a testing environment, but if
466:47 you push it into production and you
466:48 expose it to all the different edge
466:50 cases and tons of different users,
466:52 things are going to come through
466:53 differently and the automation is going
466:54 to break. And what you need to think
466:56 about is even these massive companies in
466:58 the space like Apple, Google, Amazon,
467:00 they're also having issues with AI
467:02 reliability like what we saw with Apple
467:04 intelligence having to be delayed. So if
467:06 a company like this with a massive
467:07 amount of resources is struggling with
467:09 some of these productionready
467:10 deployments, then it's kind of
467:12 unrealistic to think that a beginner or
467:14 non-programmer in these tools can spin
467:16 up something in a few days that would be
467:18 fully production ready. And by that I
467:20 just mean like the stuff you see online.
467:21 You could easily get into nodn, build
467:23 something, test it, and get it really
467:25 robust in order to sell it. That's not
467:27 what I'm saying at all. Just kind of the
467:28 stuff you see online isn't there yet.
467:31 Now, the second thing is being able to
467:32 understand the difference between AI
467:33 agents and AI workflows. And it's one of
467:36 those buzzwords that everyone's kind of
467:37 calling everything an agent when in
467:39 reality that's not the truth. So, a lot
467:41 of times people are calling things AI
467:42 agents, even if they're just sort of
467:44 like an AI powered workflow. Now, what's
467:46 an AI powered workflow? Well, as you can
467:48 see right down here, this is one that I
467:49 had built out. And this is an AI powered
467:51 workflow because it's very sequential.
467:53 As you can see, the data moves from here
467:55 to here to here to here to here to here.
467:57 And it goes down that process every
467:59 time. Even though there are some
468:00 elements in here using AI like this
468:02 basic chain and this email writing
468:04 agent. Now, this has a fixed amount of
468:05 steps and it flows in this path every
468:07 single time. Whereas something over here
468:09 like an AI agent, it has different tools
468:11 that it's able to call and based on the
468:13 input, we're not sure if it's going to
468:14 call each one once or it's going to call
468:16 this one four times or if it's going to
468:17 call this one and then this one. So
468:19 that's more of a non-deterministic
468:20 workflow. And that's when you need to
468:22 use something like an AI agent. The
468:24 difference here is that it's choosing
468:25 its own steps. The process is not
468:27 predefined, meaning every time we throw
468:29 an input, we're not sure what's going to
468:31 happen and what we're going to get back.
468:32 And then the agent also loops, calls its
468:35 tools, it observes what happens, and
468:37 then it reloops and thinks about it
468:38 again until it realizes, okay, based on
468:41 the input, I've done my job. Now I'm
468:43 going to spit something out. And so
468:44 here's just a different visualization
468:46 of, you know, an AI agent with an input,
468:48 the agent has decision, and then there's
468:49 an output or this AI workflow where we
468:52 have an input, tool one, LLM call, tool
468:54 two, tool three, output where it's going
468:56 to happen in that process every single
468:58 time. And the truth is that most
468:59 problems don't require true AI agents.
469:02 they can simply be solved with building
469:04 a workflow that is enhanced with AI. And
469:07 a common mistake, and I think it's just
469:08 because of all the hype around AI
469:09 agents, is that people are opting
469:11 straight away to set up an agent. Like
469:13 in this example right here, let's say
469:14 the input is a form trigger where we're
469:16 getting a form response. We're using
469:18 this tool to clean up the data. We're
469:19 using this LLM call. So it's an AI
469:21 enhanced workflow to actually write a
469:23 personalized email. We're using this to
469:25 update the CRM and then we're using this
469:26 to send the email and then we get the
469:28 output back as the human. We could also
469:30 set this up as a AI agent where we're
469:33 getting the form response. We're sending
469:34 this agent the information and it can
469:36 choose, okay, first I'm going to clean
469:37 the data and then I'm going to come back
469:39 here and think about it and then I'm
469:40 going to update the CRM and then I'm
469:42 going to create an email and then I'm
469:43 going to send the email and then I'm
469:45 going to output and respond to the human
469:46 and tell it that, you know, we we did
469:48 that job for you. But because this
469:50 process is pretty linear, it's going to
469:51 be a lot more consistent if we do a
469:53 workflow. It's going to be easier to
469:54 debug. Whereas over here, the agent may
469:56 mess up some tool calls and do things in
469:58 the wrong order. So it's better to just
470:00 structure it out like that. And so if we
470:02 start approaching using these no code
470:03 tools to build AI workflows first, then
470:06 we can start to scale up to agents once
470:07 we need more dynamic decision-m and tool
470:09 calling. Okay, but that's enough of the
470:11 harsh truths. Let's get into the seven
470:13 most important lessons I've learned over
470:15 the six months of building AI agents as
470:17 a non-programmer. So the first one is to
470:19 build workflows first. And notice I
470:21 don't even say AI workflows here, I say
470:23 workflows. So, over the past six months
470:25 of building out these systems and
470:27 hopping on discovery calls with clients
470:29 where I'm trying to help them implement
470:30 AI into their business processes, we
470:32 always start by, you know, having them
470:34 explain to me some of their pain points
470:36 and we talk through processes that are
470:38 repetitive and processes that are a big
470:40 time suck. And a lot of times they'll
470:42 come in, you know, thinking they need an
470:43 AI agent or two. And when we really
470:45 start to break down this process, I
470:47 realize this doesn't need to be an
470:48 agent. This could be an AI workflow. And
470:49 then we break down the process even more
470:51 and I'm like, we don't even need AI
470:52 here. We just need rule-based automation
470:55 and we're going to send data from A to B
470:57 and just do some manipulation in the
470:59 middle. So let's look at this flowchart
471:01 for example. Here we have a form
471:02 submission. We're going to store data.
471:03 We're going to route it based on if it's
471:05 sales, support, or general. We'll have
471:07 that ticket or notification. Send an
471:09 automated acknowledgement. And then
471:11 we'll end the process. So this could be
471:13 a case where we don't even need AI. If
471:15 we're having the forms come through and
471:16 there's already predefined these three
471:18 types which are either sales, support,
471:19 or general, that's a really easy
471:21 rules-based automation. Meaning, does
471:24 inquiry type equal sales? If yes, we'll
471:26 go this way and so on and so forth. Now,
471:28 maybe there's AI we need over here to
471:30 actually send that auto acknowledgement
471:32 or it could be as simple as an automated
471:33 message that we're able to define based
471:35 on the inquiry type. Now, if this the
471:38 form submission is just a a block of
471:41 text and we need an AI to read it,
471:43 understand it and decide if it's sales,
471:45 support, or general, then we would need
471:47 AI right here. And that's where we would
471:49 have to assess what the data looks like
471:51 coming in and then what we need to do
471:52 with the data. So, it's always important
471:54 to think about, do we even need AI here?
471:56 Because a lot of times when we're trying
471:57 to cut off some of that lowhanging
471:59 fruit, when we realize that we're doing
472:00 some of this stuff too manually, we
472:02 don't even need AI yet. We're just going
472:03 to create a few workflow automations and
472:06 then we can start getting more advanced
472:07 with adding AI in certain steps. So
472:09 hopefully this graphic adds a little
472:11 more color here. On the left we're
472:12 looking at a rule-based sort of filter
472:14 and on the right we're looking at an AI
472:16 powered filter. So let's take a look at
472:18 the left one first. We have incoming
472:20 data. So let's just say we're routing
472:21 data off based on if someone's budget is
472:24 greater than 10 or less than 10.
472:26 Hopefully it's greater than 10. Um so
472:28 the filter here is is X greater than 10?
472:32 If yes, we'll send it up towards tool
472:34 one. If no, we're going to send it down
472:36 towards tool two. And those are the only
472:37 two options because those are the only
472:39 two buckets that a number can fit into.
472:41 Unless I guess it's exactly equal to 10.
472:43 I probably should have made this sign a
472:45 greater than or equal to, but anyways,
472:46 you guys get the point. Now, over here,
472:48 if we're looking at an AI powered sort
472:50 of filter right here, we're using a
472:51 large language model to evaluate the
472:53 incoming data, answer some sort of
472:55 question, and then route it off based on
472:58 criteria. So incoming data we have to
473:00 look at or sorry not we the AI is
473:02 looking at what type of email this is
473:04 because this uses some element of
473:07 reasoning or logic or decision-m
473:09 something that actually needs to be able
473:10 to read the context and understand the
473:12 meaning of what's coming through in
473:14 order to make that decision. This is
473:15 where before AI we would have to have a
473:17 human in the loop. We'd have to have a
473:19 human look at this data and analyze
473:20 which way it's going to go rather than
473:22 being able to write some sort of code or
473:24 filter to do so because it's more than
473:28 just like what words exist. It's
473:29 actually like when these words come
473:31 together in sentences and paragraphs,
473:33 what does it mean? So AI is able to read
473:35 that and understand it and now it can
473:37 decide if it's a complaint, if it's
473:39 billing or if it's promotion and then
473:41 based on what type it is, we'll send it
473:42 off to a different tool to take the next
473:44 action. So the big takeaway here is to
473:46 find the simplest approach first. You
473:49 may not even need an agent at all. So
473:51 why would you add more complexity if you
473:52 don't have to? And also if you start to
473:54 learn the fundamentals of workflow
473:56 automation, data flow, logic, creative
473:59 problem solving, all that kind of stuff,
474:00 it's going to make it so much easier
474:02 when you decide to scale up and start
474:03 building out these multi-aggentic
474:05 systems as far as, you know, sending
474:07 data between workflows and understanding
474:09 routing. Your life's going to be a lot
474:11 easier. So only use AI where it actually
474:13 is going to provide value. And also
474:15 using AI and hitting an LLM isn't free
474:18 typically. And I mean if you're
474:19 self-hosting, but anyways, it's not
474:22 free. So why would you want to spend
474:23 that extra money in your workflow if you
474:24 don't have to? You can scale up when you
474:26 need the system to decide the steps on
474:28 its own, when you need it to handle more
474:30 complex multi-step reasoning, and when
474:32 you needed to control usage dynamically.
474:34 And I highlighted those three words
474:36 because that's very like human sounding,
474:38 right? Decide, reason, dynamic. Okay,
474:41 moving on to lesson number two. This is
474:43 to wireframe before you actually get in
474:45 there and start building. One of the
474:46 biggest mistakes that I made early on
474:48 and that I see a ton of people making
474:49 early on is jumping straight into their
474:51 builder, whatever it is, and trying to
474:53 get the idea in their head onto a canvas
474:56 without mapping it out at all. And this
474:58 causes a lot of problems. So, the three
475:00 main ones here are you you start to
475:01 create these messy, over complicated
475:03 workflows because you haven't thought
475:04 out the whole process yet. You're going
475:06 to get confused over where you actually
475:08 need AI and where you don't. and you may
475:10 end up spending hours and hours
475:11 debugging, trying to revise um all this
475:15 kind of stuff because you didn't
475:16 consider either a certain integration up
475:18 front or a certain functionality up
475:20 front or you didn't realize that this
475:21 could be broken down into different
475:22 workflows and it would make the whole
475:24 thing more efficient. I can't tell you
475:25 how many times when I started off
475:27 building these kind of things that I got
475:28 almost near the end and I realized I
475:31 could have done this with like 20 less
475:33 nodes or I could have done this in two
475:34 workflows and made it a lot simpler. So,
475:36 I end up just deleting everything and
475:37 restarting. So what we're looking at
475:39 right here are a different Excalibraw
475:40 wireframes that I had done. As you can
475:42 see, I kind of do them differently each
475:43 time. There's not really a, you know,
475:45 defined way that you need to do this
475:47 correctly or correct color coding or
475:49 shapes. The idea here is just to get
475:51 your thoughts from your head onto a
475:53 paper or onto a screen and map it out
475:56 before you get into your workflow
475:57 builder because then in the process of
476:00 mapping things out, you're going to
476:01 understand, okay, there may be some
476:02 complexities here or I need all of this
476:04 functionality here that I didn't think
476:05 of before. And this isn't really to say
476:07 that there's one correct way to
476:08 wireframe. As you can see, sometimes I
476:10 do it differently. Um, there's not like
476:12 a designated schema or color type or
476:14 shape type that you should be using.
476:16 Whatever makes sense to you really. But
476:18 the idea here is even if you don't want
476:19 to wireframe and visually map stuff out,
476:22 it's just about planning before you
476:23 actually start building. So, how can you
476:26 break this whole project? You know, a
476:28 lot of people ask me, I have an input
476:29 and I know what that looks like and I
476:31 know what I want to get over here, but
476:33 in between I have no idea what that
476:34 looks like. So, how can we break this
476:36 whole project into workflows? And each
476:39 workflow is going to have like
476:40 individual tasks within that workflow.
476:42 So, breaking it down to as many small
476:44 tasks as possible makes it a lot more
476:46 easy to handle. Makes it a lot less
476:48 overwhelming than looking at the entire
476:49 thing at once and thinking, how do I get
476:51 from A to Z? And so, what that looks
476:53 like to either wireframe or to just
476:55 write down the steps is you want to
476:57 think about what triggers this workflow.
476:59 How does this process start? And what
477:01 does the data look like coming in that
477:03 triggers it? From there, how does the
477:05 data move? Where does it go? Am I able
477:07 to send it down one path? Do I have to
477:09 send it off different ways based on some
477:11 conditional logic? Do I need some aspect
477:13 of AI to take decisions based on the
477:15 different types of data coming through?
477:17 You know, what actions have to be taken?
477:19 Where do we need rag or API calls
477:21 involved? Where do we need to go out
477:23 somewhere to get more external data to
477:26 enrich the context going through to the
477:27 next LLM? What integrations are
477:29 involved? So, if you ask yourself these
477:31 kind of questions while you're writing
477:33 down the steps or while you're
477:34 wireframing out the skeleton of the
477:36 build, you are going to answer so many
477:38 more questions, especially if it comes
477:39 to, you know, you're trying to work with
477:41 a client and you're trying to understand
477:42 the scope of work and understand what
477:44 the solution is going to look like. If
477:46 you wireframe it out, you're going to
477:47 have questions for them that they might
477:49 have not have thought of either, rather
477:50 than you guys agree on a scope of work
477:52 and you start building this thing out
477:53 and then all of a sudden there's all
477:54 these complexities. Maybe you priced way
477:56 too low. Maybe you don't know the
477:58 functionality. And the idea here is just
478:01 to completely align on what you're
478:02 trying to build and what the client
478:04 wants or what you're trying to build and
478:06 what you're actually going to do in your
478:07 canvas. So there's multiple use cases,
478:09 but the idea here is that it's just
478:11 going to be so so helpful. And because
478:13 you're able to break down every single
478:15 step and every task involved, you'll
478:17 have a super clear idea on if it's going
478:18 to be an agent or if it's going to be a
478:20 workflow because you'll see if the stuff
478:21 happens in the same order or if there's
478:23 an aspect of decision-m involved. So,
478:26 when I'm approaching a client build or
478:28 an internal automation that I'm trying
478:29 to build for myself, there is no way
478:31 that more than half my time is spent in
478:33 the builder. pretty much upfront I'm
478:36 doing all of the wireframing and
478:37 understanding what this is going to look
478:38 like because the goal here is that we're
478:40 basically creating a step-by-step
478:42 instruction manual of how to put the
478:43 pieces together. You should think of it
478:45 as if you're putting together a Lego
478:46 set. So, you would never grab all the
478:48 pieces from your bag of Legos, rip it
478:51 open, and just start putting them
478:52 together and trying to figure out where
478:54 what goes where. You're always going to
478:55 have right next to you that manual where
478:57 you're looking at like basically the
478:58 step-by-step instructions and flipping
478:59 through. So, that's what I do with my
479:01 two monitors. On the left, I have my
479:02 wireframe. On the right, I have my NADN
479:04 and I'm just looking back and forth and
479:06 connecting the pieces where I know the
479:07 integrations are supposed to be. You
479:09 need a clear plan. Otherwise, you're not
479:10 going to know how everything fits
479:12 together. It's like you were trying to,
479:14 you know, build a 500 piece puzzle, but
479:16 you're not allowed to look at the actual
479:17 picture of a completed puzzle, and
479:19 you're kind of blindly trying to put
479:20 them together. You can do it. It can
479:22 work, but it's going to take a lot
479:24 longer. Moving on to number three, we
479:25 have context is everything. The AI is
479:27 only going to be as good as the
479:29 information that you provide it. It is
479:31 really cool. The tech has come so far.
479:32 These AI models are super super
479:34 intelligent, but they're pre-trained.
479:36 So, they can't just figure things out,
479:37 especially if they're operating within a
479:39 specific domain where there's, you know,
479:41 industry jargon or your specific
479:43 business processes. It needs your
479:45 subject matter expertise in order to
479:47 actually be effective. It doesn't think
479:48 like we do. It doesn't have past
479:50 experiences or intuition, at least right
479:52 away. We can give it stuff like that. It
479:54 only works with the data it's given. So,
479:56 garbage in equals garbage out. So, what
479:58 happens if you don't provide high
479:59 quality context? Hallucination. The AI
480:02 is going to start to make up stuff. Tool
480:03 misuse. It's not going to use the tools
480:05 correctly and it's going to fail to
480:06 achieve your tasks that you need it to
480:08 do. And then vague responses. If it
480:10 doesn't have clear direction and a clear
480:11 sight of like what is the goal? What am
480:13 I trying to do here? It is just not
480:15 going to be useful. It's going to be
480:16 generic and it's going to sound very
480:18 obviously like it came from a chat GBT.
480:20 So, a perfect example here is the
480:22 salesperson analogy. Let's say you hire
480:24 a superstar salesman who is amazing,
480:27 great sales technique. He understands
480:29 how to build rapport, closing
480:30 techniques, communication skills, just
480:32 like maybe you're taking a GPT40 model
480:35 out of the box and you're plugging it
480:36 into your agent. Now, no matter how good
480:38 that model is or the salesperson is,
480:41 there are going to be no closed sales
480:43 without the subject matter expertise,
480:45 the business process knowledge, you
480:46 know, understanding the pricing, the
480:48 features, the examples, all that kind of
480:50 stuff. So, the question becomes, how do
480:52 you actually provide your AI agents with
480:54 better context? And there are three main
480:56 ways here. The first one is within your
480:57 agent you have a system prompt. So this
480:59 is kind of like the fine-tuning of the
481:01 model where we're training it on this is
481:03 your role. This is how you should
481:04 behave. This is what you're supposed to
481:05 do. Then we have the sort of memory of
481:08 the agent which is more of the
481:09 short-term memory we're referring to
481:11 right here where it can understand like
481:13 the past 10 interactions it had with the
481:15 user based on the input stuff like that.
481:17 And then the final aspect which is very
481:19 very powerful is the rag aspect where
481:21 it's able to go retrieve information
481:22 that it doesn't currently have but it's
481:24 able to understand what do I need to go
481:26 get and where can I go get it. So it can
481:28 either hit different APIs to get
481:29 real-time data or it can hit its
481:31 knowledge base that hopefully is syncing
481:33 dynamically and is updated. So either
481:35 way it's reaching outside of its system
481:38 prompt to get more information from
481:40 these external sources. So anyways
481:42 preloaded knowledge. This is basically
481:44 where you tell the agent its job, its
481:46 description, its role. As if on day one
481:48 of a summer internship, you told the
481:50 intern, "Okay, this is what you're going
481:52 to do all summer." You would define its
481:54 job responsibilities. You would give key
481:55 facts about your business, and you would
481:57 give it rules and guidelines to follow.
481:59 And then we move on to the user specific
482:01 context, which is just sort of its
482:02 memory based on the person it's
482:04 interacting with. So, this reminds the
482:06 AI what the customer has already asked,
482:08 previous troubleshooting steps that have
482:09 been taken, maybe information about the
482:11 customer. And without this user context,
482:14 specific memory, the AI is going to ask
482:16 the same questions over and over. It's
482:17 going to forget what's already been
482:19 conversated about, and it'll probably
482:21 just annoy the end user with repetitive
482:24 information and not very tailored
482:26 information. So we're able to store
482:27 these past interactions so that the AI
482:29 can see it before it responds and before
482:31 it takes action so that it's actually
482:33 more seamless like a human conversation.
482:35 It's more natural and efficient. And
482:36 then we have the aspect of the real-time
482:38 context. This is because there's some
482:40 information that's just too dynamically
482:42 changing or too large to fit within the
482:44 actual system prompt of the agent. So
482:46 instead of relying on this predefined
482:48 knowledge, we can retrieve this context
482:50 dynamically. So maybe it's as simple as
482:51 we're asking the agent what the weather
482:53 is. So, it hits that weather API in
482:55 order to go access real-time current
482:56 information about the weather. It pulls
482:58 it back and then it responds to us. Or
483:00 it could be, you know, we're asking
483:01 about product information within a
483:02 database. So, it could go hit that
483:04 knowledge base what that has all of our
483:06 product information and it will search
483:07 through it, look for what it needs, and
483:09 then pull it back and then respond to us
483:11 with it. So, that's the aspect of Rag
483:13 and it's super super powerful. Okay. And
483:15 this is a great segue from Rag. Now,
483:17 we're talking about vector databases and
483:19 when not to use a vector database. So, I
483:21 think something similar happened here
483:23 with vector databases as the same way it
483:25 happened with AI agents is that it was
483:26 just some cool magic buzzword and it
483:29 sounded like almost too good to be true.
483:31 So, everyone just started overusing them
483:33 and overusing the term. And that's
483:35 definitely something that I have to
483:37 admit that I fell victim to because when
483:39 I first started building this stuff, I
483:41 was taking all types of data, no matter
483:42 what it was, and I was just chucking it
483:44 into a vector database and chatting with
483:46 it. And because you know 70% of the time
483:48 I was getting the right answers. I was
483:50 like this is so cool because it's that
483:52 you know as you can see based on this
483:53 illustration it is sort of like that
483:56 multi-dimensional data representation.
483:58 It's a multi-dimensional space where the
484:00 data points that you were storing are
484:02 stored as these little vectors these
484:03 little dots everywhere. And they're not
484:05 just placed in there. They're placed in
484:07 there intelligently because the actual
484:09 context of the chunk that you're putting
484:11 into the vector database it's placed
484:13 based on its meaning. So, it's embedded
484:16 based on all these numerical
484:17 representations of data. As you can see,
484:19 like right up here, this is what the
484:21 sort of um embedding dimensions look
484:23 like. And each point has meaning. And
484:25 so, it's placed somewhere where other
484:27 things are placed that are similar.
484:29 They're placed near them. So, over here
484:30 we have like, you know, animals, cat,
484:32 dog, wolf, those are placed similarly.
484:34 We have like fruits over here, but also
484:35 like tech stuff because Google's here
484:37 and Apple, which isn't the fruit, but
484:39 it's also the tech brand. So, you know,
484:41 it also kind of shifts as as you embed
484:43 more vectors in there. So, it's just
484:45 like multi-changing. It's very
484:46 intelligent and the agent's able to scan
484:48 everything and grab back all the chunks
484:50 that are relevant really quickly. And
484:52 like I said, it's just kind of one of
484:53 those buzzwords that super cool.
484:55 However, even though it sounds cool,
484:58 after building these systems for a
484:59 while, I learned that vector databases
485:01 are not always necessary for most
485:03 business automation needs. If your data
485:05 is structured and it needs exact
485:07 retrieval, which a lot of times company
485:09 data is very structured and you do need
485:11 exact retrieval, a relational database
485:13 is going to be much better for that use
485:14 case. And you know, just because it's a
485:17 buzzword, that's exactly what it is, a
485:20 buzz word. So that doesn't always mean
485:21 it's the best tool for the job. So
485:23 because in college I studied business
485:24 analytics, I've had a little bit of a
485:26 background with like databases,
485:28 relational databases, and analytics. Um,
485:31 but if you don't really understand the
485:32 difference between structured and
485:33 unstructured data and what a relational
485:35 database is, we'll go over it real
485:37 quick. Structured data is basically
485:39 anything that can fit into rows and
485:41 columns because it has an organized sort
485:44 of predictable schema. So in this
485:46 example, we're looking at customer data
485:47 and we have two different tables and
485:49 this is relational data because over
485:51 here we have a customer ID column. So
485:53 customer ID 101 is Alice and we have
485:56 Alice's email right here. Customer ID
485:58 102 is Bob. We have Bob's email and then
486:00 we have a different table that is able
486:02 to relate back to this customer lookup
486:04 table because we match on the fields
486:06 customer ID. Anyways, this is an order
486:08 table it looks like. So we have order
486:10 one by customer ID 101 and the product
486:12 was a laptop. And we may think okay well
486:14 we're looking at order one. Who was
486:16 that? We can relate it back to this
486:18 table based on the customer ID and then
486:20 we can look up who that user was. So
486:22 there's a lot of use cases out there.
486:23 When I said, you know, a lot of business
486:24 data is going to be structured like user
486:27 profiles, sales records, you know,
486:29 invoice details, all this kind of stuff.
486:32 You know, even if it's not a relational
486:33 aspect of linking two tables together,
486:35 if it's structured data, which is going
486:36 to be, you know, a lot of chart stuff,
486:39 number stuff, um, Excel sheets, Google
486:42 Sheets, all that kind of stuff, right?
486:44 And if it's structured data, it's going
486:45 to be a lot more efficient to query it
486:47 using SQL rather than trying to
486:49 vectorize it and put it into a vector
486:51 database for semantic search.
486:53 So we said as a non-programmer, if
486:56 you're, you know, I'm sure you've been
486:57 hearing SQL quering and maybe you don't
486:59 understand exactly what it is. This is
487:01 what it is, right? So we're almost kind
487:03 of using natural language to extract
487:05 information, but we could have, you
487:07 know, half a million records in a table.
487:09 And so it's just a quicker way to
487:10 actually filter through that stuff to
487:11 get what we need. So in this case, let's
487:14 say the SQL query we're doing is based
487:16 on the user question of can you check
487:19 the status of my order for a wireless
487:21 mouse placed on January 10th. On the
487:23 left, we have an orders table. And this
487:25 is the information we need. These are
487:26 the fields, but there may be 500,000
487:28 records. So we have to filter through it
487:30 really quickly. And how we would do this
487:32 is we would say, okay, first we're going
487:33 to do a select statement, which just
487:35 means, okay, we just want to see order
487:36 ID, order date, order status, because
487:38 those are the only columns we care
487:39 about. We want to grab it from the
487:40 orders table. So, this table and then
487:42 now we set up our filters. So, we're
487:44 just looking for only rows where product
487:46 name equals wireless mouse because
487:48 that's the product she bought. And then
487:50 um and the order date is January 10,
487:54 2024. So, we're just saying whenever
487:57 these two conditions are met, that's
487:59 when we want to grab those records and
488:01 actually look at them. So, that's an
488:03 example of like what a SQL query is
488:04 doing. And then on the other side of
488:06 things, we have unstructured data, which
488:08 is usually the best use case for
488:10 unstructured data going into a vector
488:11 database, based on my experience, is
488:13 just vectorizing a ton of text. So big
488:16 walls of text, chunking them up,
488:17 throwing them into a vector database,
488:19 and they're placed, you know, based on
488:20 the meaning of those chunks, and then
488:21 can be grabbed back semantically,
488:23 intelligently by the agent. But anyways,
488:26 this is a quick visualization that I
488:27 made right over here. Let's say we have
488:29 um a ton tons of PDFs, and they're just
488:31 basically policy information. We take
488:33 that text, we chunk it up. So, we're
488:35 just splitting it based on the
488:36 characters within the actual content.
488:38 And then each chunk becomes a ve a
488:40 vector, which is just one of these dots
488:41 in this threedimensional space. And
488:43 they're placed in different areas, like
488:45 I said, based on the actual meaning of
488:48 these chunks. So, super cool stuff,
488:50 right? So then when the agent wants to,
488:52 you know, look in the vector database to
488:53 pull some stuff back, it basically makes
488:55 a query and vectorizes that query
488:57 because it will be placed near other
488:59 things that are related and then it will
489:01 grab like everything that's near it and
489:02 that's how it pulls back if we're doing
489:04 like a nearest neighbor search. But
489:05 don't want to get too technical here. I
489:07 wanted to show an example of like why
489:09 that's beneficial. So on the left we
489:12 have product information about blankets
489:15 and on the right we also have product
489:17 information about blankets and we just
489:18 decided on the right it's a vector
489:20 database on the left it's a relational
489:22 database and so let's say we hooked this
489:25 up to you know a customer chatbot on a
489:27 website and the customer asked I'm
489:29 looking for blankets that are fuzzy now
489:32 if it was a relational database the
489:35 agent would be looking through and
489:36 querying for you know where the
489:38 description contains the word fuzzy or
489:40 Maybe material is contains the word
489:42 fuzzy. And because there's no instances
489:44 of the word fuzzy right here, we may get
489:46 nothing back. But on the other side of
489:49 things, when we have the vector
489:50 database, because each of these vectors
489:52 are placed based on the meaning of their
489:54 description and their material, the
489:56 agent will be able to figure out, okay,
489:58 if I go over here and I pull back these
490:00 vectors, these are probably fuzzy
490:02 because I understand that it's cozy
490:03 fleece or it's um, you know, handwoven
490:06 cotton. So that's like why there's some
490:08 extra benefits there because maybe it's
490:10 not a word for word match, but the agent
490:12 can still intelligently pull back stuff
490:14 that's similar based on the actual
490:15 context of the chunks and the meaning.
490:17 Okay, moving on to number five. Why
490:20 prompting is critical for AI agents. Um,
490:22 we already talked about it a little bit,
490:24 I guess, in the context is everything
490:26 section because prompting is giving it
490:28 more context, but this should be a whole
490:31 lesson in itself because it is truly an
490:34 art. And you have to find that fine line
490:36 between you don't want to over prompt it
490:38 and you want to minimize your token
490:39 usage, but you also want to give it
490:40 enough information. But, um, when people
490:43 think of prompting, they think of
490:44 chatgbt, as you can see right here,
490:46 where you have the luxury of talking to
490:47 chat, it's going to send you something
490:49 back. You can tell it, hey, make that
490:50 shorter, or hey, make it more
490:52 professional. It'll send it back and you
490:53 can keep going back and forth and making
490:55 adjustments until you're happy with it
490:57 and then you can finally accept the
490:58 output. But when we're dealing with AI
491:00 agents and we're trying to make these
491:02 systems autonomous, we only have one
491:04 shot at it. So, we're going to put in a
491:05 system prompts right here that the agent
491:07 will be able to look at every time
491:08 there's like an input and we have to
491:10 trust that the output and the actions
491:12 taken before the output are going to be
491:14 high quality. And so, like I said, this
491:16 is a super interesting topic and if you
491:18 want to see a video where I did more of
491:19 a deep dive on it, you can check it out.
491:20 I'll tag it right here. Um, where I
491:22 talked about like this lesson, but the
491:24 biggest thing I learned building these
491:26 agents over the past six months was
491:28 reactive prompting is way better than
491:31 proactive prompting. Admittedly, when I
491:33 started prompting, I did it all wrong. I
491:35 was lazy and I would just like grab a
491:38 custom GPT that I saw someone use on
491:40 YouTube for, you know, a prompt
491:42 generator that generates the most
491:43 optimized prompts for your AI agents. I
491:45 think that that's honestly a bunch of
491:46 garbage. I even have created my own AI
491:49 agent system prompt architect and I
491:51 posted it in my community and people are
491:52 using it, but I wouldn't recommend to
491:54 use it to be honest. Um, nowadays I
491:57 think that the best practice is to write
491:58 all of your prompts from scratch by hand
492:01 from the beginning and start with
492:02 nothing. So, that's what I meant by
492:04 saying reactive prompting. Because if
492:06 you're grabbing a whole, you know, let's
492:07 say you have 200 lines of prompts and
492:09 you throw it in here into your system
492:10 prompt and then you just start testing
492:11 your agent, you don't know what's going
492:14 on and why the agent's behaving as it
492:16 is. You could have an issue pop up and
492:19 you add a different line in the system
492:20 prompt and the issue that you originally
492:23 were having is fixed, but now a new
492:24 issues popped up and you're just going
492:26 to be banging your head against the wall
492:28 trying to debug this thing by taking out
492:30 lines, testing, adding lines, testing.
492:32 it's just going to be such a painful
492:34 process when in reality what you should
492:36 do is reactive prompt. So start with
492:38 nothing in the system prompt. Give your
492:40 agent a tool and then test it. Throw in
492:42 a couple queries and see if you're
492:44 liking what's coming back. You're going
492:45 to observe that behavior and then you
492:47 have the ability to correct the system
492:49 prompt reactively. So based on what you
492:51 saw, you can add in a line and say,
492:53 "Hey, don't do that." Or, you know, this
492:55 worked. Let's add another tool and add
492:57 another prompt now or another line in
492:58 the prompt. Because what we know right
493:01 now is that it's working based on what
493:03 we have. That way if we do add a line
493:06 and then we test and then we observe the
493:08 behavior and we see that it broke, we
493:10 know exactly what broke this automation
493:12 and we can pinpoint it rather than if we
493:13 threw in a whole pre-generated system
493:16 prompt. So that's the main reason why I
493:17 don't do that anymore. And then it's
493:19 just that loop of test, reprompt, test
493:22 again, reprompt. Um, and what's super
493:24 cool about this is because you can
493:27 basically hard prompt your agent with
493:29 things in the system prompt because
493:31 you're able to show it examples of, you
493:33 know, hey, I just asked you this and you
493:35 took these steps. That was wrong. Don't
493:37 do that again. This is what you should
493:39 have done. And basically, if you give it
493:40 that example within the system prompt,
493:42 you're training this thing to not behave
493:44 like that. And you're only improving the
493:45 consistency of your agent's performance.
493:48 So the the key elements of a strong AI
493:50 agent prompt and this isn't like every
493:52 single time. These are the five things
493:54 you should have because every agent's
493:55 different. For example, if you're
493:57 creating a context creation agent, you
493:59 wouldn't need a tool section really if
494:01 it's not if it doesn't have any tools.
494:02 You' just be prompting it about its
494:03 output and about its role. But anyways,
494:05 the first one that we're talking about
494:07 is role. This is sort of just like
494:08 telling the AI who it is. So this could
494:10 be as simple as like you're a legal
494:12 assistant specializing in corporate law.
494:13 Your job is to summarize contracts in
494:16 simple terms and flag risky clauses.
494:18 Something like that. It gives the AI
494:20 clear purpose and it helps the model
494:22 understand the tone and the scope of its
494:24 job. Without this, the AI is not going
494:26 to know how to frame responses and
494:27 you're going to get either very random
494:28 outputs or you're going to get very
494:30 vague outputs that are very clearly
494:32 generated by AI. Then of course you have
494:34 the context which is going to help the
494:36 agent understand, you know, what is
494:37 actually coming in every time because
494:39 essentially you're going to have
494:40 different inputs every time even though
494:41 the system prompt is the same. So saying
494:43 like this is what you're going to
494:44 receive, this is what you're going to do
494:46 with it, um this is your end goal. So
494:48 that helps tailor the whole process and
494:49 make it more seamless as well. That's
494:51 one common mistake I actually see with
494:52 people's prompting when they start is
494:54 they forget to define what are you going
494:55 to be getting every time? Because the
494:57 agency, they're going to be getting a
494:58 ton of different emails or maybe a ton
494:59 of different articles, but it needs to
495:01 know, okay, this information that you're
495:02 throwing at me, what is it? Why am I
495:04 getting it? Then of course the tool
495:06 instructions. So when you're building a
495:08 tools agent, this is the most important
495:09 thing in my mind. Yes, it's good to add
495:12 rules and show like when you use each
495:13 thing, but having an actual section for
495:15 your tools is going to increase the
495:17 consistency a lot. At least that's what
495:19 I found because this tells the AI
495:21 exactly what tools are available, when
495:23 to use them, how they work. Um, and this
495:26 is really going to ensure correct tool
495:28 usage rather than the AI trying to go
495:29 off of like these sort of guidelines
495:32 because it's a nondeterministic workflow
495:34 and um trying to trying to guess of
495:36 which one will do what and um yeah, have
495:39 a tool section and define your tools.
495:41 Then you've got your rules and
495:42 constraints and this is going to help
495:44 prevent hallucination. It's going to
495:45 help the agent stick to sort of like a
495:47 standard operating procedure. Now, you
495:49 just have to be careful here because you
495:50 don't want to say something like do all
495:52 of these in this order every time
495:54 because then it's like why are you even
495:56 using an agent? You should just be using
495:57 a workflow, right? But anyways, just
495:59 setting some foundational like if X do
496:02 Y, if Z do A, like that sort of thing.
496:06 And then finally, examples, which I
496:08 think are super super important, but I
496:10 would never just put these in here
496:11 blind. I would only use examples to
496:13 directly counter and directly uh correct
496:16 something that's happened. So what I
496:18 alluded to earlier with the hard
496:19 prompting. So let's say you give the
496:20 agent an input. It calls tool one and
496:22 then it gives you an output that's just
496:24 incorrect, completely incorrect. You'd
496:26 want to give it in the example, you
496:28 could show, okay, here's the input I
496:29 just gave you. Now here's what you
496:30 should have done. Call tool two and then
496:33 call tool three and then give me the
496:34 output. And then it knows like, okay,
496:36 that's what I did. This is what I should
496:37 have done. So if I ever get an input
496:39 similar to this, I can just call these
496:40 two tools because I know that's an
496:42 example of like how it should behave. So
496:44 hard prompting is really really going to
496:46 come in handy and not just in the
496:48 examples but also just with the rest of
496:50 your system prompt. All right, moving on
496:52 to number six. We have scaling agents
496:55 can be a nightmare. And this is all part
496:57 of like one of the hard truths I talked
496:59 about earlier where a lot of the stuff
497:00 you see online is a great proof of
497:02 concept, a great MVP, but if you were to
497:04 try to push this into production in your
497:06 own business, you're going to notice
497:07 it's not there yet. Because when you
497:09 first build out these AI agents,
497:10 everything can seem to work fine. It's a
497:11 demo. It's cool. It really opens your
497:13 eyes to, you know, the capabilities, but
497:16 it hasn't usually gone under that
497:17 rigorous testing and evaluation and
497:20 setting up these guard rails um and all
497:23 of that, you know, continuous monitoring
497:24 that you need to do to evaluate its
497:26 performance before you can push it out
497:28 to all, you know, 100 users that you
497:30 want to eventually push it out to. You
497:32 know, on a single user level, if you
497:34 have a few hallucinations every once in
497:35 a while, it's not a huge deal. But as
497:38 you scale the use case, you're just
497:40 going to be scaling hallucinations and
497:42 scaling problems and scaling all these
497:44 failures. So that's where it gets
497:45 tricky. You can start to get retrieval
497:47 issues as your database grows. It's
497:48 going to be harder for your agent to cut
497:50 through the noise and grab what it
497:51 needs. So you're going to get more, you
497:53 know, inaccuracies. You're going to have
497:54 some different performance bottlenecks
497:56 and the agents, you know, latency is
497:57 going to increase. you're going to start
497:59 to get inconsistent outputs and you're
498:00 going to experience all those edge cases
498:02 that you hadn't thought of when you were
498:04 the only one testing because, you know,
498:05 there's just an infinite amount of
498:06 scenarios that an agent could be exposed
498:08 to. So, a good little lesson learned
498:10 here would be to scale vertically before
498:12 you start to try to scale horizontally,
498:14 which um we'll break that down. And I
498:16 made this little visualization so we can
498:17 see what that means. So, let's say we
498:19 want to help this business with their
498:21 customer support, sales, inventory, and
498:23 HR management. Rather than building out
498:26 little building blocks of tools within
498:28 each of these processes, let's try to
498:30 perfect one area first vertically and
498:33 then we'll start to move across the
498:34 organization and look at doing other
498:35 things and scaling to more users. So,
498:37 because we can focus on this one area,
498:40 we can set up a knowledge base and set
498:41 up like the data sources and build that
498:43 automated pipeline. We can set up how
498:45 this kind of stuff gets organized with
498:46 our sub workflows. We can set up, you
498:48 know, an actual agent that's going to
498:50 have different tool calls. And within
498:52 this process, what we have over here are
498:55 evaluations, monitoring performance, and
498:57 then setting up those guard rails
498:58 because we're testing throughout this,
499:01 you know, ecosystem vertically and and
499:03 getting exposure to all these different
499:04 edge cases before we try to move into
499:06 other, you know, areas where we need to
499:08 basically start this whole process
499:09 again. We want to have done the
499:11 endto-end system first, understand you
499:14 know the problems that may arise, how to
499:16 make it robust and how to evaluate and
499:18 you know iterate over it before we start
499:20 making more automations. And so like I
499:22 alluded to earlier, if you try to start
499:24 scaling horizontally too quick before
499:26 you've done all these testing, you are
499:28 going to notice that hallucinations are
499:29 going to increase. Your retrieval
499:31 quality is going to drop as more users
499:33 users come in. The agent's handling more
499:35 memory. it's handling more um more
499:38 knowledge in its database to try to cut
499:39 through your response times are going to
499:41 slow and then you're just going to get
499:42 more inconsistent results. And so you
499:44 can do things like, you know, setting
499:45 strict retrieval rules and guard rails.
499:47 You could do stuff like segmenting your
499:49 data into different vector databases
499:51 based on the context or different name
499:53 spaces or different, you know,
499:54 relational databases. You could use
499:56 stuff like um asynchronous processing or
499:58 caching in order to improve that
500:00 response time. And then you could also
500:02 look at doing stuff like only you know
500:04 um having an agent evaluate and making
500:06 sure that the confidence on these
500:08 responses are above a certain threshold
500:10 otherwise we'll you know request human
500:12 help and not actually respond ourselves
500:14 or the agent wouldn't respond itself. So
500:17 the seventh one is that no code tools
500:19 like nadn have their limits. They're
500:21 super great. They're really empowering
500:23 non-developers to get in here and spin
500:25 up some really cool automations. And
500:27 it's really like the barrier to entry is
500:29 so low. you can learn how to build this
500:30 stuff really quickly, which is why I
500:32 think it's awesome and you know, it's
500:33 the main tool that I use um personally
500:35 and also within my agency. But when you
500:38 start to get into what we just talked
500:39 about with lesson number six, scaling
500:41 and making these things really robust
500:43 and production ready, you may notice
500:45 some limits with no code tools like NE.
500:47 Now, the reason I got into building
500:49 stuff like this is because, you know,
500:51 obviously non-programmer and it has a
500:54 really nice drag and drop interface
500:55 where you can build these workflows very
500:57 visually without writing scripts. So,
500:59 Nen is, you know, basically open source
501:01 because you can self-host it. The code
501:03 is accessible. Um, and it's built on top
501:05 of Langchain, which is just like a
501:07 basically a language that helps connect
501:08 to different things and create these
501:10 like agents. Um, and because of that,
501:13 it's just wrapped up really pretty for
501:14 us in a graphical user interface where
501:16 we can interact with it in that drag and
501:18 drop way without having to get in there
501:20 and hands- on keyboard write code. And
501:23 it has a ton of pre-built integrations
501:25 as you can see right here. Connect
501:26 anything to everything. Um, I think
501:28 there's like a thousand integrations
501:29 right here. And all of these different
501:30 integrations are API calls. They're just
501:33 wrapped up once again in a pretty way
501:35 for us in a user interface. And like I
501:37 talked about earlier, when I started, I
501:39 didn't even know what an API was. So the
501:40 barrier entry was super low. I was able
501:42 to configure this stuff easily. And
501:43 besides these built-in integrations,
501:45 they have these really simple tool
501:46 calls. So development is really fast
501:48 with building workflows compared to
501:49 traditional coding. um the modularity
501:52 aspect because you can basically build
501:53 out a workflow, you can save that as a
501:55 tool and then you can call that tool
501:57 from any other workflow you want. So
501:58 once you build out a function once,
502:00 you've basically got it there forever
502:01 and it can be reused which is really
502:03 cool. And then my favorite aspect about
502:05 n and the visual interface is the visual
502:07 debugging because rather than having 300
502:09 lines of code and you know you're
502:11 getting errors in line 12 and line 45,
502:13 you're going to see it's going to be red
502:15 or it's going to be green and you know
502:17 if it's green you're good and if you see
502:18 red there's an error. So you know
502:20 exactly usually you know exactly where
502:22 the problem's coming from and you're
502:23 able to get in there look at the
502:25 execution data and get to the bottom of
502:26 it pretty quick. But overall these no
502:29 code platforms are great. They allow us
502:30 to connect APIs. We can connect to
502:32 pretty much anything because we have an
502:33 HTTP request within NADN. Um they're
502:37 going to be really really good for
502:38 rulebased decision-m like super solid.
502:40 Um if we're creating workflows that's
502:42 just going to do some data manipulation
502:43 and transferring data around you know
502:45 your typical ETL based on the structured
502:47 logic super robust. you can make some
502:49 really really awesome basic AI powered
502:51 workflows where you're integrating
502:52 different LLMs. You've got all the
502:54 different chat models basically that you
502:55 can connect to um for you know different
502:57 classification or content generation or
502:59 outreach anything like that. Um your
503:01 multi-agentic workflows because like I
503:03 said earlier you have the aspect of
503:05 creating different tools um as workflows
503:07 as well as creating agents as workflows
503:09 that you can call on from multiple
503:10 agents. So you can really get into some
503:12 cool multi-agentic inception thing going
503:14 on with with agents calling agents
503:16 calling agents. um and passing data
503:19 between different workflows and then
503:21 just the orchestration of AI services,
503:23 coordinating multiple AI tools within a
503:25 single process. So that's the kind of
503:27 stuff that NN is going to be super super
503:29 good at. And now the hidden limitations
503:31 of these noode AI workflow/ aent
503:34 builders. Let's get into it. Now, in my
503:36 opinion, this stuff really just comes
503:38 down to when we're trying to get into
503:40 like enterprise solutions at scale with
503:41 a ton of users and a ton of
503:43 authentication and a ton of data.
503:44 Because if you're building out your own
503:46 internal automations, you're going to be
503:48 solid. Like there's not going to be
503:49 limitations. If you're building out, you
503:50 know, proof of concepts and MVPs, um,
503:53 YouTube videos, creating content, like
503:55 you can do it all, I would say. But when
503:57 you need to start processing, you know,
503:58 massive data sets that are going to
504:00 scale to thousands or millions of users,
504:03 your performance can slow down or even
504:04 fail. And that's maybe where you'd want
504:06 to rely on some custom code backend to
504:08 actually spin up these more robust
504:11 functionalities. In these agentic
504:13 systems, tool calling is really, really
504:14 critical. The agent needs to be able to
504:16 decide which one to use and do it
504:18 efficiently. And like I talked about,
504:20 Nen is built on top of lang chain. It
504:22 provides a structured way to call AI
504:24 models and APIs, but it lacks some of
504:26 that flexibility of writing that really
504:28 custom code within there for complex
504:30 decision-m. And then when it comes to
504:32 authentication at scale, it can struggle
504:34 with like secure large scale
504:36 authentication and data access control.
504:38 Obviously, you can hook up to external
504:40 systems to help with some of that
504:41 processing, but when it comes to maybe
504:43 like handling OOTH tokens and all these
504:45 encrypted credentials and session
504:47 management, not that it's not doable
504:49 with NN, um it just seems like getting
504:52 in there with some custom code, it could
504:54 be quicker and more robust. And also,
504:57 that's coming from someone who doesn't
504:59 actually do that myself. Um, just some
505:01 stuff I've heard and you know, with
505:03 what's going on within the agency. Now
505:05 ultimately it seems like if you are
505:06 delivering this stuff at scale for some
505:08 big clients um the best approach is
505:10 going to be a mix a hybrid of no code
505:13 and custom code because you can use NN
505:15 to spin up stuff really quick. You've
505:17 got that modularity you can orchestrate
505:20 automate you know connect to anything
505:22 you need but then working in every once
505:23 in a while some custom Python script for
505:26 some of that complex you know large
505:27 scale processing and data handling. And
505:30 when you combine these two together,
505:31 you're going to be able to spin some
505:32 stuff up a lot quicker, and that's going
505:34 to be pretty robust and powerful. Thanks
505:37 so much for making it all the way to the
505:38 end of this course. I know it's pretty
505:40 massive, but I wanted to pack it with a
505:42 ton of value, and hopefully you guys did
505:43 find it valuable as well, and you feel a
505:45 lot more comfortable right now building
505:46 AI workflows and AI agents than when you
505:49 started this course. If you enjoyed or
505:51 if you learned something new, please
505:52 give it a like and a subscribe. It
505:54 definitely helps me out a ton. Um, like
505:55 I said, super happy that you made it to
505:57 the end of the course. And if you did
505:59 and if you appreciate my teaching style
506:01 or you want to even go more in depth
506:02 than this course right here, then
506:04 definitely check out my paid community.
506:05 The link for that is down in the
506:06 description. It's a community full of
506:08 people who are learning how to build and
506:10 are building a automations using naden
506:12 and a lot of them are coming from no
506:13 code backgrounds as well. So great place
506:15 to get some questions answered,
506:17 brainstorm people, collaborate on
506:19 projects, stuff like that. And we also
506:21 have five live calls per week. So, make
506:22 sure you jump in there and meet other
506:23 people in the space as well as make sure
506:25 you're not getting stuck and you can get
506:26 your questions answered on a call. Like
506:28 I said, would be great to see you in the
506:29 community. But anyways, thanks so much
506:31 for making it to the very end of this
506:33 huge course. Appreciate you guys and I
506:35 will see you in the next video. Thanks
506:36 so much everyone.