WEBVTT

00:00.440 --> 00:03.680
Okay, next one is a boring one because you know it.

00:03.720 --> 00:09.480
Well, I've brought in the same send email tool that we used before.

00:09.680 --> 00:13.920
So this is we're using the decorator the function tool.

00:13.920 --> 00:18.680
If you remember you use that decorator if you want to convert a function into something that can be

00:18.680 --> 00:19.080
a tool.

00:19.080 --> 00:23.040
And it will generate all of that JSON gumph for you behind the scenes.

00:23.320 --> 00:29.320
So this is send email the subject and a body, and it sends out an email with the given subject in the

00:29.320 --> 00:29.560
body.

00:29.560 --> 00:31.680
We're going to use Send Grid as before.

00:31.720 --> 00:35.960
Hopefully you still have your account handy and you have it in your env file.

00:36.000 --> 00:38.400
Remember to change this email.

00:38.440 --> 00:44.280
Let me change this to your verified email.

00:44.880 --> 00:49.040
And yes, and please do also change this one.

00:49.040 --> 00:54.840
Again, don't send me lots of emails with AI generated content, but by all means send me emails with

00:54.840 --> 00:55.680
your questions.

00:55.720 --> 01:02.600
Of course I always welcome them, but I don't welcome AI generated search deep research things as much.

01:03.070 --> 01:11.150
Uh, so then uh, content would be, uh, the HTML version, and then we send the email exactly as before.

01:11.350 --> 01:12.550
That is our tool.

01:12.750 --> 01:15.630
You don't need to see this, but I'm going to show it to you anyway.

01:15.630 --> 01:19.030
You remember that if I just print this.

01:19.070 --> 01:20.110
What's it doing here?

01:20.150 --> 01:26.590
If I just print this out, we should see that we get a function tool with a description and so on.

01:26.590 --> 01:30.750
And if you're not sure why this has happened, then do look up decorators.

01:30.750 --> 01:35.870
Make sure you understand how decorators work and how they're able to convert a function like this.

01:36.630 --> 01:37.310
Okay.

01:37.350 --> 01:41.390
With that in mind, this is an email agent.

01:41.390 --> 01:42.910
This is all old hat to you.

01:42.910 --> 01:44.590
Now we've done this several times.

01:44.790 --> 01:50.870
The instructions are you're able to send a nicely formatted HTML email based on a detailed report.

01:51.350 --> 01:56.270
You'll be provided with with a with a detailed report, you should use your tool to send one email,

01:56.310 --> 02:03.350
providing the report converted into a clean, well presented HTML with a subject line.

02:03.670 --> 02:06.190
So you can see I'm no longer trying to break things out.

02:06.300 --> 02:11.820
I'm giving this agent full discretion to come up with a subject line, to rewrite the email, to do

02:11.820 --> 02:18.620
the whole lot using GPT four or mini, and we're providing it with the one tool to actually send the

02:18.620 --> 02:19.260
email.

02:19.260 --> 02:21.180
So that is our email agent.

02:21.180 --> 02:23.580
And that is something which is old news to you.

02:23.580 --> 02:24.500
You know, it's super.

02:24.500 --> 02:26.220
Well, okay.

02:26.620 --> 02:28.940
We're about we're about to get real.

02:29.140 --> 02:36.100
And so I will, uh, take a pause for a second and then we will get into the real meat of the project.

02:36.740 --> 02:37.460
Okay.

02:37.740 --> 02:43.060
So we have another agent again that's going to use structured outputs.

02:43.380 --> 02:45.740
So this is the researcher.

02:46.300 --> 02:51.260
So you are a senior researcher tasked with writing a cohesive report for a query.

02:51.420 --> 02:56.940
You'll be provided with the original query and some initial research done by a research assistant.

02:56.980 --> 03:01.860
You come up with an outline for the report that describes the structure and flow of the report, and

03:01.860 --> 03:08.260
then generate the report and return that as your final output should be in markdown, it should be lengthy

03:08.260 --> 03:13.050
The detailed 5 to 10 pages of content of at least a thousand words.

03:13.370 --> 03:16.530
Okay, so that has framed the situation.

03:16.970 --> 03:18.770
Now we're going to use structured outputs.

03:18.810 --> 03:24.530
Again we're going to have a report data pedantic object a subclass of base model.

03:24.650 --> 03:30.010
It has a short summary which we begin with a short 2 to 3 sentence summary.

03:30.210 --> 03:35.610
The full markdown final report and then some follow up suggestions.

03:35.770 --> 03:38.570
Suggested topics to research further.

03:39.370 --> 03:41.410
And so this is an agent.

03:41.570 --> 03:43.010
It will take these instructions.

03:43.010 --> 03:46.010
It will use GPT four or mini the output type.

03:46.010 --> 03:49.330
This is where you specify that we're using structured outputs.

03:49.370 --> 03:52.410
The output type is the report data.

03:52.650 --> 03:56.290
And there we have our our report writer.

03:56.610 --> 03:58.370
And this is our writer agent.

03:58.370 --> 04:05.010
And this is the final building block before we get to the actual flow through this project.

04:05.890 --> 04:06.490
Okay.

04:06.530 --> 04:07.530
So it's crunch time.

04:07.530 --> 04:10.810
We have five functions for me to show you.

04:10.810 --> 04:12.440
But they're relatively simple.

04:12.440 --> 04:14.080
They're pretty straightforward.

04:14.080 --> 04:18.120
So here they are the I'm going to show you three and then two.

04:18.560 --> 04:25.840
The first three, the ones that are going to execute a search using the two agents that we defined before

04:25.880 --> 04:28.320
the planner agent and the search agent.

04:28.320 --> 04:30.560
And these functions, you can see they're very short.

04:30.560 --> 04:31.480
They're very simple.

04:31.480 --> 04:34.920
Let me tell you what they each do plan searches.

04:34.960 --> 04:35.400
All right.

04:35.400 --> 04:41.520
This very simply calls runner run for our planner agent passing in the query.

04:41.960 --> 04:45.200
And we make a query and that gets passed into the planet agent.

04:45.200 --> 04:49.880
Remember the planner agent is the one that will then come back with a number of searches.

04:50.280 --> 04:52.960
So we'll then count how many searches there are and print that.

04:52.960 --> 04:59.600
And we will return that final output, which is in the form of that search list.

04:59.640 --> 05:00.760
That's what formatted it.

05:00.760 --> 05:06.640
Again, it is this thing here, the web search plan, a list of web search items.

05:07.080 --> 05:07.760
All right.

05:07.800 --> 05:08.680
Back we go.

05:09.280 --> 05:10.000
Okay.

05:10.600 --> 05:16.310
So then the next function is perform searches.

05:16.310 --> 05:19.950
This is when we're actually going to do the searches for each of these.

05:19.990 --> 05:23.990
Now do you remember I showed you that asyncio a while ago?

05:24.030 --> 05:26.670
That was the great way that you can run things in parallel.

05:26.870 --> 05:28.550
Perfect time for it right now.

05:28.870 --> 05:38.150
So we're going to create a bunch of async IO tasks to search for each item, for each item in the the

05:38.190 --> 05:39.670
results of the searches.

05:39.670 --> 05:45.910
This this this is the Pydantic object that searches feel gives you the list of the search items.

05:45.910 --> 05:48.750
And for each item we were going to call search searches.

05:48.790 --> 05:51.750
The next function we'll talk about we're going to call search.

05:51.910 --> 05:52.430
We're going to.

05:52.470 --> 05:56.310
This gives you a coroutine so we can turn that into a into a task.

05:56.510 --> 06:02.470
And then we can use this gather approach that I told you about async gather.

06:02.470 --> 06:09.990
If you then await that, it will run all of these tasks in parallel and the results will go into results.

06:10.750 --> 06:12.470
And then we will put finished.

06:12.990 --> 06:14.790
So hopefully I didn't lose you there.

06:14.790 --> 06:19.900
Basically all I'm saying is we take the results from the planner and we just search for all of these

06:19.900 --> 06:23.900
things in parallel using the search agent.

06:24.340 --> 06:26.780
And this is how we actually use the search agent.

06:26.940 --> 06:28.420
We give it an input.

06:28.620 --> 06:31.300
And what we're actually doing is we don't just tell it the query.

06:31.340 --> 06:33.780
We also tell it the reason that we're searching for that.

06:33.820 --> 06:37.580
Remember I said there's more than one one reason why we asked for a reason.

06:37.620 --> 06:40.260
It's also so we can give some context here.

06:40.500 --> 06:47.580
And then we, uh, we we run the search agent and then we return the final output of the search.

06:48.340 --> 06:49.060
Okay.

06:49.540 --> 06:51.860
Hopefully you followed these three.

06:51.900 --> 06:57.420
If not, come back and look at these as such short functions that that it should make sense.

06:57.940 --> 07:00.940
And then finally some housekeeping.

07:01.100 --> 07:02.300
Two functions.

07:02.420 --> 07:05.500
One of them to write the report, one of them to send the email.

07:05.780 --> 07:09.060
The writing the report will use a writer agent.

07:09.100 --> 07:15.180
It will, uh, run that agent that is going to reconstitute the output in HTML.

07:15.460 --> 07:20.570
And then finally we will write an email using the email agent.

07:20.890 --> 07:23.930
And that will then complete the process.

07:24.410 --> 07:29.050
So I should run these two to define these two functions.

07:29.090 --> 07:30.690
These two these five functions.

07:30.890 --> 07:34.370
And now we should be ready for showtime.

07:35.050 --> 07:35.330
All right.

07:35.330 --> 07:40.250
And if you're one of the people that doesn't like the way that I just execute code and talk to it,

07:40.290 --> 07:43.290
it's sort of lazy, then you're going to be happy.

07:43.290 --> 07:48.050
This time I will type the code so that we get to do this part together.

07:48.050 --> 07:50.210
So it is a moment of truth.

07:50.210 --> 07:57.010
We're going to say, like with trace research, Trace Curse is already filling it in.

07:57.130 --> 07:58.130
I'm not.

07:58.170 --> 07:59.170
No, no luck for me.

07:59.170 --> 08:01.570
Well, I'm going to ignore what curse is saying here.

08:01.850 --> 08:03.450
I'm not looking at that.

08:03.450 --> 08:06.610
So we're going to print a message like starting research.

08:06.970 --> 08:08.570
Sometimes cursor is too good.

08:09.130 --> 08:10.650
All right, let's get rid of cursor.

08:10.690 --> 08:11.730
No cheating.

08:14.810 --> 08:17.210
I'm not looking I'm not looking at what cursor is saying.

08:17.250 --> 08:17.610
Search.

08:17.770 --> 08:19.290
What if I type something different?

08:20.090 --> 08:22.050
Confuse cursor.

08:22.050 --> 08:22.080
sir.

08:22.600 --> 08:23.080
All right.

08:23.120 --> 08:24.040
Now search.

08:24.600 --> 08:25.440
That doesn't work.

08:25.440 --> 08:25.800
It's still.

08:25.800 --> 08:27.040
It still figures it out.

08:27.080 --> 08:28.560
All right, but there we go.

08:28.600 --> 08:29.240
It knows.

08:29.240 --> 08:34.160
So the first thing we're going to do is have a variable called search plan, which is going to await

08:34.200 --> 08:35.560
planning the searches.

08:35.560 --> 08:38.040
So if you come up here there is planning the searches.

08:38.040 --> 08:39.520
So that's the first step.

08:39.520 --> 08:40.400
We do that.

08:40.560 --> 08:41.040
All right.

08:41.040 --> 08:43.880
The next step is the search results.

08:43.880 --> 08:46.040
We're going to perform the searches.

08:46.040 --> 08:50.160
So we come up here we perform the searches passing in the search plan.

08:50.200 --> 08:53.360
That's the next step of this which we also await.

08:53.360 --> 08:57.000
The next thing we need to do is actually run the report.

08:57.000 --> 09:02.600
So we await writing the report, passing in the query and the search results.

09:03.040 --> 09:05.680
And cursor knows well as do you.

09:05.760 --> 09:09.920
You already saying what we need to do next is send the email.

09:09.920 --> 09:12.040
And that really is it.

09:12.200 --> 09:16.600
I can take out the and then I can print.

09:17.040 --> 09:22.960
All right we won't we will do something different to what cursor suggests to show that we have some

09:22.960 --> 09:24.000
autonomy here.

09:24.000 --> 09:25.910
We're not just ruled by the machines.

09:25.950 --> 09:27.510
Okay, there we go.

09:27.550 --> 09:28.350
Let's kick this off.

09:28.350 --> 09:29.470
Let's have this running.

09:29.910 --> 09:31.790
So it's starting the research.

09:31.830 --> 09:33.270
It's planning the searches.

09:33.270 --> 09:34.870
It will perform through searches.

09:34.870 --> 09:35.990
So it's.

09:36.030 --> 09:37.310
And it's already finished.

09:37.310 --> 09:37.590
So.

09:37.590 --> 09:41.950
So it used an agent to figure out what three searches to do.

09:41.990 --> 09:49.030
And then for each of those, it used a remote, a hosted, uh, tool from OpenAI to actually carry out

09:49.070 --> 09:49.990
that search.

09:50.030 --> 09:51.710
It got back all of the results.

09:51.710 --> 09:58.310
We're now using an agent to synthesize the results and turn it into a report using.

09:58.550 --> 10:05.150
It's going to generate a report in markdown, and then it's going to turn that into an HTML email.

10:05.670 --> 10:08.790
So um, we will let it do its thing.

10:09.150 --> 10:10.230
Let's just come back up.

10:10.230 --> 10:14.910
The final report is is is in this format which has markdown as one of the, the parts of it.

10:14.910 --> 10:18.070
And that's the part we're now doing the writing email.

10:18.070 --> 10:23.990
And it's in writing the email that it will both come up with a subject line, and it will also write

10:23.990 --> 10:25.830
it as an HTML email.

10:25.870 --> 10:28.270
And in a second, hopefully I will receive that email.
