WEBVTT

00:00.120 --> 00:02.000
Welcome back everybody.

00:02.000 --> 00:09.120
The Mac, PC, Linux people reunite for our video where we now start to work with our project.

00:09.120 --> 00:10.240
Your environment is set up.

00:10.240 --> 00:15.240
You should be looking at cursor looking nice and clean like this X out of any windows that are open,

00:15.280 --> 00:17.200
have it look a bit like like me.

00:17.240 --> 00:20.240
And then on the left here you've got the directories.

00:20.520 --> 00:26.520
The first one up here one foundations represents the directory for week one where we are right now.

00:26.560 --> 00:33.240
We open that up and I'd like you to click on lab one that comes up right here at the top.

00:33.240 --> 00:38.680
Here is a little section that tells you about the setup folder, which has all of the setup guide that

00:38.880 --> 00:40.880
by this point you should have already covered it all.

00:40.880 --> 00:41.920
So it should be fine.

00:42.040 --> 00:46.160
And then the guides folder has a bunch of useful guides.

00:46.160 --> 00:52.560
It has some stuff to take you through intermediate level Python, and it also has beginner Python.

00:52.560 --> 00:56.840
If you're new to Python coding, then it will take you through some self-study guides there.

00:56.840 --> 00:59.160
If you're willing to to to do that, I think it will be.

00:59.200 --> 00:59.730
It will.

00:59.730 --> 01:00.530
It will need some time.

01:00.530 --> 01:02.170
Investment will be well worth it.

01:02.170 --> 01:05.930
And then for intermediate level Python there's important stuff there too.

01:06.090 --> 01:07.610
There's a bunch of stuff.

01:07.650 --> 01:12.650
One of the things that comes up a lot in agents is working with async code.

01:12.690 --> 01:14.530
There's async stuff in there.

01:14.570 --> 01:20.370
There's also going to be things about generators which are very important, and a lot of good intermediate

01:20.370 --> 01:22.330
level Python material in there.

01:22.650 --> 01:28.330
If you're also not as experienced with coding, there's there's going to be stuff about debugging how

01:28.330 --> 01:29.610
to go about debugging.

01:29.730 --> 01:34.690
If you get something called a name error, that's something which has always got a way to work at a

01:34.690 --> 01:35.170
name error.

01:35.170 --> 01:36.650
So there's good details on that too.

01:36.690 --> 01:37.970
So please do look at the guides.

01:37.970 --> 01:39.330
I've put tons of stuff in there.

01:39.370 --> 01:41.770
There's also a troubleshooting guide if things go wrong.

01:41.810 --> 01:46.370
Troubleshooting takes you through every step, including some great diagnostics at the end.

01:47.170 --> 01:52.610
And then this next little comment here is saying that these labs think of it a bit like it's like an

01:52.610 --> 01:53.210
e book.

01:53.250 --> 01:57.090
It's got content and information as well as things to try.

01:57.370 --> 02:01.670
And what you'll find is that what you'll see as we go through this may be different.

02:01.710 --> 02:05.150
What you have may look different to what I go through right now.

02:05.190 --> 02:06.430
And you may say, well, that's annoying.

02:06.430 --> 02:07.590
I wish it was all the same.

02:07.590 --> 02:08.550
But here's the thing.

02:08.550 --> 02:13.430
The reason is because I like to keep adding more stuff, make it current.

02:13.470 --> 02:16.630
I try and make it very clear when it's something new that I've added.

02:16.710 --> 02:22.310
I bring in extra information to keep it up to date, and when people struggle and they hit problems

02:22.510 --> 02:25.910
or they need something explained better, I can put that in there.

02:25.950 --> 02:30.790
And that means that everyone benefits from where some people have struggled or I haven't explained something.

02:30.790 --> 02:32.110
Well, I can add it in there.

02:32.110 --> 02:33.990
So for me it's super important to do that.

02:34.270 --> 02:39.310
And the reason I don't come back and record all the videos as I do it well, first of all, that would

02:39.310 --> 02:43.350
take a lot of time and I'd rather spend time getting the this up to date.

02:43.590 --> 02:49.750
But also because that would erase some of the progress that people have made with videos they've watched.

02:49.750 --> 02:53.870
And it can be quite jarring if you're in the middle of a series and then the videos are changing under

02:53.870 --> 02:54.150
you.

02:54.350 --> 03:00.280
So it's really worked out better for me to keep these labs up to date as much as I can.

03:00.320 --> 03:02.720
So treat the labs like a resource.

03:02.720 --> 03:08.560
And the way that I suggest that you work with me is watch the video of me going through a lab.

03:08.600 --> 03:10.280
I'll go through it, I'll explain it.

03:10.280 --> 03:11.520
I'll execute things.

03:11.640 --> 03:15.840
I wouldn't necessarily suggest that you do it at the same time as me, because that's not really the

03:15.840 --> 03:16.400
point.

03:16.440 --> 03:22.200
The point is, as soon as I've done a lab, you come back and you go through it step by step yourself,

03:22.360 --> 03:27.320
and you use that as a way to build the learning, add in print statements and so on.

03:28.040 --> 03:29.680
Okay, a couple more things to say on this.

03:29.880 --> 03:36.520
I'm using here things called notebooks, which are a particular type of Python code that's organized

03:36.520 --> 03:38.280
in this way into cells.

03:38.400 --> 03:42.600
And there's going to be there's a guide on on how to use notebooks like this if you're not familiar

03:42.600 --> 03:43.240
with them.

03:43.240 --> 03:48.120
And I know that a lot of people from an engineering background initially get a bit frustrated like this

03:48.120 --> 03:50.560
because they'd rather work with just Python code.

03:50.800 --> 03:52.760
We will work with Python code as well.

03:52.760 --> 03:57.490
We're going to use both, but this kind of notebook has its place.

03:57.490 --> 04:03.330
It's very useful for research and development, which is an important part of being an AI engineer.

04:03.610 --> 04:09.210
And it's also great for learning because you can run things step by step, experiment, tweak, put

04:09.210 --> 04:10.810
in print statements, and learn.

04:10.850 --> 04:13.370
And so there is a benefit to this too.

04:13.490 --> 04:19.010
So even if you're not used to these kinds of notebooks, there are I promise you there's good stuff

04:19.010 --> 04:19.490
here too.

04:19.530 --> 04:23.770
And we will also do some Python coding using normal modules.

04:24.250 --> 04:24.970
All right.

04:25.010 --> 04:27.730
That's the end of of all of the details.

04:27.930 --> 04:30.330
Let's get to running this first lab.

04:31.450 --> 04:31.970
Okay.

04:32.010 --> 04:36.650
The first step is to go to the top right just here where you see select kernel.

04:36.690 --> 04:41.090
You click there and you have to choose your Python environment.

04:41.090 --> 04:44.890
And the way you do that is you type Python environments right here.

04:44.890 --> 04:49.770
And this first one up here with the star that says venv.

04:49.810 --> 04:50.890
It says recommended.

04:50.890 --> 04:52.810
And it's right in this directory.

04:52.930 --> 04:54.870
That is the one you want to pick.

04:55.110 --> 05:00.990
And hopefully that's going to come up really clear for you as Python 3.12 at the top.

05:01.030 --> 05:03.550
And once you've done that, it will be set up here.

05:03.550 --> 05:06.990
And you'll always when you come to a new lab you'll need to do that.

05:07.030 --> 05:10.270
And so so do bear that in mind for it to work.

05:10.550 --> 05:11.110
Okay.

05:11.510 --> 05:18.190
And then as like a final, final little thing here, it's, uh, got one more link to my LinkedIn in

05:18.190 --> 05:23.350
case in case you haven't succumbed by this point, remember that you can always link them with me.

05:23.510 --> 05:24.230
All right.

05:24.590 --> 05:30.310
So now what we do is we come here to the first of the cells.

05:30.350 --> 05:32.990
Each these things are called cells, these code cells.

05:32.990 --> 05:34.830
And we're going to do an import.

05:34.830 --> 05:36.110
And what import are we going to do.

05:36.110 --> 05:39.270
Well we're going to do this import here from dot env.

05:40.150 --> 05:47.030
And you can see that cursor is already suggesting what we could do right now from dot env import load

05:47.030 --> 05:48.030
dot env.

05:49.030 --> 05:53.480
And I hope you're familiar with what it means to import a function from a module, but if not, then

05:53.480 --> 05:57.000
please do check out the guides for a refresher on that.

05:57.000 --> 06:02.320
But I'm now going to run this code cell by simply pressing shift followed by return or enter.

06:02.320 --> 06:04.600
And that executes the cell and it's done.

06:05.080 --> 06:07.160
So the next thing we're going to do is use that function.

06:07.160 --> 06:08.200
And this is how we do it.

06:08.240 --> 06:11.800
We say load dot env and I'm getting prompted already.

06:11.800 --> 06:12.240
There it is.

06:12.240 --> 06:14.480
Load dot env override equals true.

06:14.680 --> 06:15.680
So what does this do.

06:15.720 --> 06:19.560
Load dot env is just a utility function which does something very specific.

06:19.760 --> 06:26.040
It looks for a file with a very particular name in your project root directory.

06:26.240 --> 06:31.440
And that file name happens to be, as you probably guessed, the name dot e.

06:32.440 --> 06:37.880
And it's assuming that that is where you're setting some of the environment variables that you want

06:37.880 --> 06:39.520
to use for this project.

06:39.520 --> 06:44.600
And it's just a utility that looks at that file, interprets it, and sets environment variables as

06:44.600 --> 06:45.040
a result.

06:45.040 --> 06:46.080
That's all it does.

06:46.200 --> 06:51.130
And override is true is just a nice little trick to know about by default.

06:51.170 --> 06:51.730
Load.

06:51.970 --> 06:52.290
Env.

06:52.330 --> 06:58.410
If you've already got an environment variable set, perhaps with your profile, then that takes priority.

06:58.410 --> 06:59.050
And it won't.

06:59.090 --> 07:00.290
It won't overwrite it.

07:00.450 --> 07:02.730
And that can be a nasty little gotcha.

07:02.810 --> 07:07.890
Because if in the past you've set up an open AI API key and you've and you've stored it somewhere global

07:07.890 --> 07:12.850
on your computer, that would take priority and you wouldn't be able to figure out why on earth OpenAI

07:12.850 --> 07:14.050
is rejecting your key.

07:14.610 --> 07:18.330
And so it turns out that this, as you can imagine, was a common problem in the past.

07:18.330 --> 07:23.250
And and I have learned to tell people to always put override equals true, which means that what's in

07:23.250 --> 07:25.490
the env file takes priority.

07:25.690 --> 07:27.730
And we run this by pressing shift enter.

07:27.890 --> 07:30.810
And now our environment variables will be set.

07:31.130 --> 07:32.610
So let's check that.

07:33.370 --> 07:35.610
This next cell does an import OS.

07:35.890 --> 07:42.810
And then we look for an environment variable that's called OpenAI API key which is exactly what we named

07:42.810 --> 07:44.410
it in the env file.

07:44.650 --> 07:50.870
And if it exists we're going to print it exists and it begins and give the first few letters.

07:50.910 --> 07:53.070
Otherwise it's going to say it's not set.

07:53.110 --> 07:54.950
Please go to the troubleshooting guide.

07:54.990 --> 07:57.350
I press shift and enter to run this.

07:57.350 --> 07:58.230
And there we go.

07:58.270 --> 08:00.110
The OpenAI key exists.

08:00.230 --> 08:02.070
It begins scmproj.

08:02.670 --> 08:05.750
All is good and I hope all is good for you too.

08:05.910 --> 08:07.910
If not, go to the troubleshooting guide.

08:08.790 --> 08:09.310
Okay.

08:09.350 --> 08:12.110
And now we have a super important import statement.

08:12.110 --> 08:15.990
And it looks like this from OpenAI import OpenAI.

08:16.710 --> 08:21.270
So if that seems weird to you, why is one in lowercase and one not anything like that?

08:21.270 --> 08:22.670
Again, go to the guides.

08:22.670 --> 08:26.750
I'll explain the difference between classes and modules and all the rest.

08:26.750 --> 08:32.390
But we are now going to execute this, and if this gives you any problems at all, then that might suggest

08:32.390 --> 08:34.550
a problem with your UV environment.

08:34.590 --> 08:38.950
Troubleshooting guide and always contact me if you get stuck in any way.

08:38.990 --> 08:40.590
I'm here to unstick you.

08:40.990 --> 08:41.750
All right.

08:41.910 --> 08:46.030
So what we're now going to do is create an instance of this class.

08:46.070 --> 08:48.040
Now I tend to always do it this way.

08:48.080 --> 08:49.880
OpenAI equals OpenAI.

08:50.120 --> 08:55.000
And that can be a bit confusing to people because again, when we're using the same word OpenAI, the

08:55.000 --> 09:01.920
proper way to call this would be something like OpenAI Python client, because what we're doing is creating

09:01.920 --> 09:05.000
an instance of the Python client library.

09:05.000 --> 09:08.280
But I just call that OpenAI because it's just simpler and shorter.

09:08.280 --> 09:10.120
But but that's what it stands for.

09:10.160 --> 09:12.320
We're creating an instance of that class.

09:12.320 --> 09:13.640
And let's run that right now.

09:14.000 --> 09:18.240
And it's worth bearing in mind that some people think that when you do this, you're creating something

09:18.240 --> 09:23.280
to do with the actual, like GPT large language model locally, but you're not.

09:23.480 --> 09:32.320
OpenAI is a lightweight library for connecting to OpenAI's endpoints on the cloud, so this is just

09:32.320 --> 09:34.960
what people sometimes call a client library.

09:34.960 --> 09:42.640
It's just a simple wrapper library around endpoints that calls HTTP endpoints to call the API that's

09:42.640 --> 09:43.640
running in the cloud.

09:43.640 --> 09:44.920
And that's all it is.

09:44.960 --> 09:49.530
It's a it's a simple lightweight class for that purpose only.

09:49.970 --> 09:52.170
So with that, let's keep going.

09:52.930 --> 09:57.370
What we're now going to do is create a list called messages.

09:57.370 --> 10:00.570
And this is a format that I hope most of you are very familiar with.

10:00.690 --> 10:03.570
On my LM engineering course, we do this one to death.

10:03.930 --> 10:06.130
And if you're not, I'll trumpet some extra stuff on the guys.

10:06.130 --> 10:10.610
I'm not going to explain too much of it right now, but conversations with large language models are

10:10.610 --> 10:16.090
often represented in this format that OpenAI invented and has become ubiquitous everywhere.

10:16.370 --> 10:20.970
Lists of dictionaries where each dictionary has a role and a content.

10:20.970 --> 10:23.410
And in this case we say the role is user.

10:23.450 --> 10:27.410
The content is this simple question what is two plus two?

10:27.730 --> 10:34.330
So we run that and now we're going to actually make a call to OpenAI and check everything is working

10:35.170 --> 10:35.770
okay.

10:35.810 --> 10:39.650
And so now we're going to come here and type the code to call OpenAI.

10:39.770 --> 10:42.250
And cursor is going to make this very easy for us.

10:42.250 --> 10:52.550
We're just going to type response equals open I dot and it's a chat dot completions dot create.

10:52.550 --> 10:55.310
And you can see that cursor is already filling that in for us.

10:55.310 --> 10:58.510
I can just press tab and it's going to complete that right away.

10:58.710 --> 11:01.670
And it's going to say the model is GPT four mini.

11:01.670 --> 11:03.110
And the messages are messages.

11:03.110 --> 11:04.110
That's perfect.

11:04.310 --> 11:10.070
And it's also going to take the response, take the first choice dot message content and print it.

11:10.070 --> 11:11.990
And that's exactly what we want to do.

11:12.310 --> 11:15.950
This structure of calling OpenAI is something that is so common these days.

11:15.950 --> 11:20.070
If you're new to it, then take a look and I'll try and cover some in the guides.

11:20.070 --> 11:25.710
But people who are familiar with this will see this as a very simple way to call OpenAI.

11:25.710 --> 11:29.990
And if we run this, we get the response to the question what is two plus two?

11:30.030 --> 11:32.110
We get two plus two equals four.

11:32.350 --> 11:37.350
So we know we are connected to OpenAI and so far so good.

11:38.150 --> 11:41.230
So hopefully you're now comfortable that we can both call OpenAI.

11:41.270 --> 11:42.270
We can get responses.

11:42.270 --> 11:48.560
We can use the very standard chat completions API structure and cursor will fill it in for us if we

11:48.560 --> 11:49.680
ever forget what it is.

11:50.000 --> 11:52.600
But now let's ask a harder question.

11:52.600 --> 11:55.200
It's time for us to be a little bit agentic.

11:55.200 --> 11:58.240
We're going to put one foot in the agent camp.

11:58.280 --> 12:02.760
It's more a workflow than an agentic I but but still it's getting there.

12:02.960 --> 12:04.600
We're going to ask a question.

12:04.640 --> 12:09.360
Please propose a hard, challenging question to assess someone's IQ.

12:09.520 --> 12:12.240
Respond only with the question.

12:12.240 --> 12:13.760
So that's going to be our question.

12:13.760 --> 12:17.800
And we're going to put that into the standard messages structure.

12:18.280 --> 12:19.920
And now we're going to ask it.

12:19.920 --> 12:23.800
So again we say response and it's already filling it in for us.

12:23.800 --> 12:25.280
We press tab to complete that.

12:25.280 --> 12:26.280
We press tab.

12:26.320 --> 12:27.960
But we're just going to change this slightly.

12:27.960 --> 12:34.600
We're going to make this reply equals maybe I should make this like like question equals.

12:34.600 --> 12:37.600
So we're going to take back the what comes back and we're going to make it question.

12:37.600 --> 12:39.800
And then we'll just print the question again.

12:39.800 --> 12:41.080
Cursor fills that in.

12:41.120 --> 12:42.450
Let's run that.

12:42.450 --> 12:43.250
And here we go.

12:43.250 --> 12:45.730
Here we have a question from OpenAI.

12:46.290 --> 12:50.570
If a train leaves a station traveling at 60 miles an hour and another train is a different station,

12:50.570 --> 12:53.490
120 miles away at the same time traveling 90.

12:53.610 --> 12:56.290
How far from the first station will the two trains meet?

12:56.330 --> 12:58.810
A nice brain teaser right there.

12:59.570 --> 13:03.450
So what we're going to do now is we're going to take this question, and we're going to make a second

13:03.450 --> 13:06.410
call to an LLM to answer the question.

13:06.410 --> 13:11.490
And that's why I describe this as an agentic pattern, because it is making multiple calls.

13:11.490 --> 13:16.090
We are orchestrating multiple calls to llms to solve a bigger problem.

13:16.090 --> 13:18.410
And so it's going to be relatively easy.

13:18.450 --> 13:22.210
We're simply going to continue this by again making another messages.

13:22.250 --> 13:28.370
Look at how cursor fills it in for us messages with role as a user and the content is that question.

13:28.490 --> 13:29.130
Great.

13:29.130 --> 13:30.170
Let's run that.

13:30.330 --> 13:31.450
That is now messages.

13:31.450 --> 13:34.330
And now we're going to ask OpenAI again.

13:34.490 --> 13:39.570
So we're going to say response is OpenAI create.

13:39.770 --> 13:43.670
And again, cursor fills it all in and it fills in the answer.

13:43.670 --> 13:48.430
And it's even clever enough to recommend that we call it answer instead of question.

13:48.750 --> 13:50.150
Honestly it's incredible.

13:50.390 --> 13:52.430
So this is exactly what we want to do.

13:52.470 --> 13:58.110
We're making the same kind of call to OpenAI's chat completions API.

13:58.150 --> 14:01.150
The simplest way to call OpenAI in the cloud.

14:01.430 --> 14:06.110
And we are now getting back the answer to the question, and we will print that answer.

14:06.110 --> 14:09.350
And I believe the answer we're looking for is 48, I think.

14:09.550 --> 14:10.310
Let's see.

14:10.510 --> 14:12.150
So we'll get that to print.

14:12.710 --> 14:14.070
And here we go.

14:14.310 --> 14:20.630
A bunch of information right here written with 48 at the end there.

14:21.710 --> 14:22.870
And you may know this already.

14:22.910 --> 14:26.710
You recognize that this has come back in a form of markdown.

14:26.710 --> 14:31.430
It's got some markdown stuff in it which llms love to talk in markdown.

14:31.430 --> 14:37.070
We can just add in a little code in here and we can do from there.

14:37.990 --> 14:38.510
Ha ha.

14:38.510 --> 14:38.640
Ah.

14:38.920 --> 14:40.200
Is it spooky?

14:40.240 --> 14:46.280
It is spooky the way cursor does this sometimes from IPython display, import markdown and display.

14:46.280 --> 14:49.040
And then the next line that cursor is telling us to write.

14:49.200 --> 14:50.760
I don't really have a job here, do I?

14:50.920 --> 14:53.720
Display markdown, but the only thing it's got wrong.

14:53.720 --> 14:55.000
Thank goodness it got something wrong.

14:55.000 --> 14:58.400
Is that what we actually want to display is the answer, not the question.

14:58.400 --> 15:04.160
So if we do that and we run this, then we see the answer formatted nicely.

15:04.160 --> 15:11.360
I'll let you read through its work and it comes up with the conclusion of 48 miles.

15:11.640 --> 15:12.840
Uh, so there we go.

15:13.120 --> 15:20.120
That is our first semi agentic pattern, built just in a few minutes.

15:20.200 --> 15:24.480
If any of that was unfamiliar to you, check out the guides, play with it, look at it.

15:24.520 --> 15:26.920
And as I say, congratulations on getting here.

15:26.920 --> 15:30.560
But at the end of this lab there is an exercise.

15:30.560 --> 15:34.040
And I do encourage you to do the exercises.

15:34.040 --> 15:40.130
This is where you really get to to show that you've done this, you may be thinking, okay, there wasn't

15:40.130 --> 15:45.530
much commercial about this project, and I do like to try and weave commercial angles in wherever I

15:45.530 --> 15:48.250
can to make this applicable to business.

15:48.370 --> 15:53.130
And so I've got an exercise for you to now make this applicable slightly to business.

15:53.330 --> 16:02.010
So we are going to try and ask an LLM, first of all, to pick a business area that might be worth exploring

16:02.010 --> 16:04.170
for an AI opportunity.

16:04.690 --> 16:12.450
Secondly, to identify a pain point in that business sector that it's decided on, and then that that's

16:12.450 --> 16:15.130
one that it needs to explicitly explain.

16:15.130 --> 16:19.290
What is that challenge that might be ripe for an agentic solution.

16:19.290 --> 16:25.810
And then the third step will be to actually propose an agentic AI solution to that problem.

16:26.170 --> 16:34.050
So I would like you in this empty cell here, probably assisted by cursor, uh, to, to to go through

16:34.050 --> 16:37.230
and make this happen with three calls to LMS.

16:37.430 --> 16:43.430
First of all, you put something in this message to explain that you want it to pick a business sector.

16:43.910 --> 16:47.350
Then you get back the response based on that response.

16:47.470 --> 16:54.550
You read in the business idea, and then you will repeat these three steps in order to get the the pain

16:54.550 --> 16:59.830
point, and then to get the Agentic AI solution and print them all out.

16:59.830 --> 17:07.390
Print them in markdown if you wish, uh, in nicely formatted, and use that as a way both to to experiment

17:07.390 --> 17:13.830
with some agentic workflows and also actually to get some commercial benefit, to get perhaps an interesting

17:13.830 --> 17:19.350
idea about a way that you can apply Agentic AI to a real business pain point.

17:19.830 --> 17:20.510
All right.

17:20.510 --> 17:22.230
I hope you enjoy that challenge.

17:22.230 --> 17:28.190
If you have any problems with it, of course, then you can either get help from from ChatGPT or cursor,

17:28.190 --> 17:34.990
or just drop me a note and I will see you for the final lecture for this first day.
