WEBVTT

00:00.160 --> 00:04.720
So, look, I don't know if you're anything like me, but I'm having something of a change of heart.

00:04.960 --> 00:11.960
So I started this week quite clearly with OpenAI agents SDK as my favorite, and obviously with crew

00:12.000 --> 00:17.000
as my second favorite, and being a little bit skeptical of Landgraf because you sign up for a lot.

00:17.160 --> 00:18.680
But I'm coming around.

00:18.720 --> 00:20.080
I'm having a really great time.

00:20.080 --> 00:23.920
And what I've got to show you today, I feel like you're going to be there, right there with me.

00:24.280 --> 00:27.480
I'm actually becoming a serious fan of Landgraf.

00:27.640 --> 00:30.920
Uh, and there's some really cool stuff, so see what you think.

00:31.160 --> 00:35.760
Uh, I'm, uh, I'm suddenly feeling treacherous against OpenAI agents SDK.

00:36.160 --> 00:37.760
Uh, so, uh, welcome.

00:37.760 --> 00:44.520
Welcome to week four, day four, introducing a new project sidekick, and I can't wait to tell you

00:44.520 --> 00:45.000
about it.

00:45.120 --> 00:46.280
So what are we going to do today?

00:46.280 --> 00:47.560
How are we going to go deeper?

00:47.600 --> 00:49.960
You know, we always go a bit deeper with each of these.

00:50.160 --> 00:55.600
So first of all I'm going to introduce I'm going to unveil a new tool which is going to be incredibly

00:55.600 --> 00:59.520
powerful and which is going to allow us to do very different things.

00:59.760 --> 01:03.320
We're going to talk about structured outputs, something that we've I mean, it's been a recurring theme.

01:03.320 --> 01:04.320
We've done that in each of these.

01:04.320 --> 01:05.880
We'll use it here too.

01:06.220 --> 01:11.860
And we're also going to build a proper multi-agent workflow in Landgraaf so that you see it really coming

01:11.900 --> 01:17.860
together, the equivalent of the handoff in OpenAI agents SDK, or having a crew of agents.

01:17.860 --> 01:19.540
We will be doing that.

01:20.020 --> 01:24.540
And as a reminder, on the diagram I did last time, that brings it all together.

01:24.540 --> 01:26.060
Remember the terminology?

01:26.220 --> 01:33.380
A super step is a complete invocation of the graph, and each super step represents like one user input

01:33.380 --> 01:37.740
coming in and then flowing it through your graph of agents and tools.

01:37.900 --> 01:42.420
And then those blue diagrams are representing the graph that gets executed.

01:42.420 --> 01:47.660
The state is managed through that graph, and reducers are called to make sure that the state object,

01:47.940 --> 01:52.340
which is an immutable object, is maintained and managed through that.

01:52.340 --> 01:58.300
But between the super steps, you use checkpointing as your way of maintaining state.

01:58.300 --> 02:03.020
And checkpointing is very powerful, and it lets you do things like rewind the clock and put your state

02:03.020 --> 02:05.140
back to any prior point.

02:05.660 --> 02:08.620
So with that quick recap, let's go to the lab.

02:09.100 --> 02:09.620
All right.

02:09.620 --> 02:14.520
So we get started in week four and we're going to go to lab number three.

02:14.560 --> 02:14.960
Week four.

02:15.000 --> 02:15.360
Day four.

02:15.400 --> 02:16.120
Lab three.

02:16.480 --> 02:19.400
Uh, it's, as I say, the start of an awesome project.

02:19.400 --> 02:21.080
I am super happy with this.

02:21.080 --> 02:22.520
I hope you will be too.

02:22.800 --> 02:24.520
We do some imports.

02:25.200 --> 02:25.880
Takes a while.

02:25.880 --> 02:27.280
There's a lot of stuff to go.

02:27.360 --> 02:28.800
And then we've got this empty cell here.

02:28.800 --> 02:29.640
Why have we got empty cell?

02:29.680 --> 02:31.520
Because of course we have to do load.

02:31.560 --> 02:34.320
Dot override is true.

02:35.280 --> 02:38.000
This is second nature to you at this point.

02:38.320 --> 02:38.880
Okay.

02:38.880 --> 02:46.880
So I also I'm going to introduce this time asynchronous Landgraf using Landgraf in async mode, uh,

02:46.920 --> 02:48.600
which I promised was going to happen this week.

02:49.080 --> 02:52.680
And it's very similar to using long chain in sync mode.

02:52.880 --> 03:02.960
Uh, when we used to call tools to run a tool, you can now call await tool dot to run the tool asynchronously,

03:02.960 --> 03:04.240
but passing in the same inputs.

03:04.240 --> 03:05.480
Otherwise it's just the same.

03:05.760 --> 03:12.360
And to invoke the graph, if we would have said tool graph invoke state before, we can now say await

03:12.400 --> 03:14.400
graph a invoke state.

03:14.600 --> 03:20.340
So that is just simply a way to run a graph in asynchronous mode.

03:20.340 --> 03:21.940
And that is what we're going to be doing.

03:22.540 --> 03:26.820
Uh, for the state, I'm going to again be using a typed dict.

03:27.060 --> 03:31.540
So that means that it looks very much like when we use pydantic objects, you just have one field I'm

03:31.540 --> 03:33.220
going to have called messages.

03:33.260 --> 03:34.420
It is annotated.

03:34.420 --> 03:35.740
The type is a list.

03:35.740 --> 03:41.660
And this is telling Landgraf we want it to use ad messages, which is a canned function that you can

03:41.700 --> 03:42.220
import.

03:42.220 --> 03:47.660
We want that to be the reducer, which is going to keep on adding messages whenever we return that as

03:47.660 --> 03:49.620
our state from a node.

03:49.900 --> 03:53.140
And we will start a graph builder with that state.

03:53.940 --> 03:54.580
Okay.

03:54.860 --> 03:55.900
So far so good.

03:56.100 --> 03:56.620
Okay.

03:56.660 --> 04:00.300
Next up we are going to create a tool that we did last time.

04:00.300 --> 04:01.620
So we can do it nice and quickly.

04:01.620 --> 04:04.780
Here it is the push notification tool.

04:05.020 --> 04:07.220
We define our function push.

04:07.220 --> 04:14.740
And then we wrap it package it in a tool called tool push which describes what it is it calls the function.

04:15.100 --> 04:19.060
And that is all we need to do okay.

04:19.380 --> 04:21.610
Now now it gets exciting.

04:22.090 --> 04:23.050
Playwright.

04:23.090 --> 04:24.210
Do you know what playwright is?

04:24.250 --> 04:28.130
Playwright is one of these browser automation bits of software.

04:28.170 --> 04:34.090
It's considered the sort of the new the next generation of selenium, which many, many people have

04:34.090 --> 04:34.290
used.

04:34.330 --> 04:35.530
I've used selenium an awful lot.

04:35.570 --> 04:42.290
Playwright is by Microsoft and it's a, it's a it's a very nice framework for running a browser.

04:42.290 --> 04:45.210
And it's traditionally originally used for testing.

04:45.210 --> 04:47.170
So it's used for test purposes.

04:47.650 --> 04:52.610
And a lot of people also use it for web scraping, because if you just try and request a web page,

04:52.610 --> 04:57.650
you just get back like the server content, if you use something like Selenium or Playwright, you can

04:57.650 --> 05:03.450
actually render it in a browser, run the JavaScript, paint the page, and then use that to actually

05:03.450 --> 05:04.410
get the content.

05:04.730 --> 05:12.890
So playwright is a is a powerful tool for running a browser window, and it can do so what they call

05:12.890 --> 05:16.490
headless, which means you don't even see the browser windows, just like running behind the scenes

05:16.690 --> 05:22.490
or not headless headful in which case you see the browser screen yourself and you can interact with

05:22.490 --> 05:22.850
it.

05:23.010 --> 05:24.170
So that is playwright.

05:24.170 --> 05:25.330
You may already know it.

05:25.370 --> 05:26.830
A lot of people use playwright.

05:26.830 --> 05:28.230
This is how you install it.

05:28.230 --> 05:31.910
You type playwright install to do it on on Windows and Mac OS or on Linux.

05:31.950 --> 05:35.750
It's this longer command and it will then be installed.

05:35.750 --> 05:37.790
And if you have problems with that, then let me know.

05:37.790 --> 05:38.870
But hopefully not.

05:39.430 --> 05:41.350
Okay, one other thing to mention.

05:41.350 --> 05:43.190
One other little detail here.

05:43.230 --> 05:46.470
And this is just for running it in a notebook.

05:46.790 --> 05:53.550
Um, one of the problems, one of the challenges with async IO is that Asyncio runs an event loop.

05:53.830 --> 05:58.430
Um, and when you when it runs an event loop, it runs this thing that's just constantly making sure

05:58.430 --> 06:01.230
that it's running anything that's being awaited.

06:01.270 --> 06:05.190
And then when it's holding on IO, it runs something else that's being awaited.

06:05.550 --> 06:10.510
Uh, and one of the problems is that that async IO only supports one event loop.

06:10.510 --> 06:15.590
And if there's an event loop running, you can't within that event loop, run another event loop.

06:15.590 --> 06:20.630
And we're running an event loop as part of running, uh, this notebook right now.

06:20.750 --> 06:24.990
And so that can cause problems when you try and kick off async processes within async processes.

06:25.230 --> 06:32.290
Uh, and so there is this package called nest async IO that's quite popular, which you can just simply

06:32.290 --> 06:38.570
use this and then it like patches async IO so that you can have an event loop within an event loop.

06:38.730 --> 06:42.890
And as you will soon understand from me prattling away, we're going to want that because we're going

06:42.890 --> 06:48.890
to want to run playwright asynchronously, because we're going to build an agent that can drive playwright.

06:48.890 --> 06:52.090
And so we're going to need that concept of an event loop within an event loop.

06:52.090 --> 06:55.250
But when we later put this into Python code, we actually won't need this anymore.

06:55.250 --> 06:56.410
But we'll need it for now.

06:56.650 --> 06:57.210
All right.

06:57.250 --> 06:58.730
That's a long sidebar.

06:58.730 --> 06:59.610
That's over.

06:59.770 --> 07:01.370
But now comes the magic.

07:01.570 --> 07:08.330
So one of the incredible things about Landgraf and Long Chain, I'm becoming a convert of both, is

07:08.330 --> 07:12.890
that they come with so many great tools out of the box.

07:13.210 --> 07:15.850
Many of them are in the community package.

07:15.890 --> 07:20.410
There's actually a couple of different ways that you can run a playwright.

07:20.410 --> 07:22.050
There's two sets of tools.

07:22.050 --> 07:25.050
One of them is a more simplistic one that's just a bit higher level.

07:25.210 --> 07:29.890
This one that I've got here, uh, the Playwright Browser Toolkit.

07:29.890 --> 07:35.050
This is a lower level set of tools which provides a bunch of different tools.

07:35.090 --> 07:37.310
Let's just We're gonna create this.

07:37.310 --> 07:43.670
So this is this is, um, creating an asynchronous playwright browser, and then it's building a toolkit

07:43.670 --> 07:45.030
from that browser.

07:45.030 --> 07:48.190
And now we've, we've got the tools into a variable tools.

07:48.190 --> 07:49.590
So I'm just going to print these.

07:49.750 --> 07:53.630
And here are all of the tools that we get in this package.

07:53.630 --> 08:00.110
We get something that lets you uh, click on an element in a web page, navigate the browser to a particular

08:00.110 --> 08:06.750
web page, go to the previous web page like press the back button, extract text from a web page, extract

08:06.790 --> 08:10.830
hyperlinks, get elements, and then the current web page.

08:11.110 --> 08:17.150
Uh, so it gives you quite granular control over what's going on in this playwright browser.

08:17.750 --> 08:22.310
So again, to recap, playwright allows you to launch a browser window.

08:22.510 --> 08:28.670
And then this Landgraaf or Lang chain set of tools gives us a series of tools that will allow us to

08:28.710 --> 08:35.310
interact with that browser open windows, navigate, read the text, read the elements, do that kind

08:35.310 --> 08:35.870
of thing.

08:36.070 --> 08:37.110
That's pretty cool.

08:37.110 --> 08:41.710
And that is something we're going to be able to arm our agent to be able to use.
