WEBVTT

00:00.160 --> 00:01.240
And we're back.

00:01.360 --> 00:07.800
I left you with a day for the land grant ideas to marinate, and hopefully they have marinated well,

00:07.800 --> 00:11.520
and you're now ready to actually go and do something.

00:11.520 --> 00:16.560
But as always, I do like to repeat a couple of times because repetition helps with these things.

00:16.560 --> 00:23.480
So one more time in Landgraaf an agent workflow, a particular pattern for how you will run an agent

00:23.600 --> 00:26.160
system is represented as a graph.

00:26.200 --> 00:33.200
Like a tree structure, use state to represent the current snapshot of affairs, the state of the world

00:33.360 --> 00:41.880
at any one point, and you build nodes and edges which are Python functions, and a node decides how

00:41.880 --> 00:47.960
to go from one state to another, and edges or nodes do the work, they actually carry out something

00:47.960 --> 00:52.080
which has consequences and edges decide what to do next.

00:52.080 --> 00:53.560
Once a node has run.

00:54.640 --> 01:00.640
And you'll remember I talked about five steps, and I tried to make it clear that the thing that's a

01:00.640 --> 01:06.840
bit of a like a head twister is that these five steps that I'm talking about, they all happen when

01:06.840 --> 01:10.830
you run your code, and they happen before you can even run your agents.

01:10.830 --> 01:16.190
So when you run your code, there is this prething that has five steps in it, and then the agent running

01:16.230 --> 01:22.910
and that prething is what would be called graph building that that is laying out what you want to do,

01:23.190 --> 01:25.350
and then you kick it off to actually do it.

01:25.590 --> 01:31.230
And those five steps, of course, you define your state class describing the information that will

01:31.230 --> 01:32.110
be maintained.

01:32.390 --> 01:34.150
You start the graph builder.

01:34.630 --> 01:36.670
You then create a node or many.

01:36.790 --> 01:39.470
You create edges to hook it all up or many.

01:39.630 --> 01:43.590
And then you compile the graph and you're now ready for primetime.

01:43.830 --> 01:44.630
All right.

01:44.630 --> 01:49.910
So I want to get a little bit deeper about the state before we get to the code.

01:49.950 --> 01:55.230
The final thing before the code so state is what's known as immutable.

01:55.230 --> 01:58.590
It's a word that that people like to say a lot and hopefully know what it means.

01:58.590 --> 01:59.150
But you might not.

01:59.150 --> 02:00.390
So let me be very clear.

02:00.430 --> 02:06.470
What it means to be immutable is that you will never change the contents of this object.

02:06.470 --> 02:12.430
It is something which, once you've created it and assigned the values to it, it keeps those values.

02:12.430 --> 02:15.790
And you don't ever do what's called mutating it, which is changing it.

02:16.270 --> 02:21.710
And, and that's, that's important because, uh, state is something which is going to represent a

02:21.710 --> 02:22.510
snapshot of the system.

02:22.510 --> 02:24.550
You want to be able to always go back to that snapshot.

02:24.630 --> 02:29.590
It's something which which in itself, if the contents of that state changes, you wouldn't be able

02:29.590 --> 02:31.590
to maintain that snapshot.

02:31.990 --> 02:38.190
Uh, so just to get concrete on what that means, what that means is that if you when you write the

02:38.190 --> 02:44.310
function for a node, that function is going to be a function which quite simply receives a state as

02:44.310 --> 02:47.870
its input and it returns a state as its output.

02:47.910 --> 02:53.710
And the thing that it returns is different, a different object, a different instance of state than

02:53.710 --> 02:54.870
the one that came in.

02:54.910 --> 03:00.110
So in this example called my counting node, let's imagine that we have a state object.

03:00.110 --> 03:03.790
And the only thing that it has is a field called count.

03:03.830 --> 03:06.470
And count is something which is a number that counts.

03:06.790 --> 03:10.390
Uh, and the purpose of my counting node is to add one to count.

03:10.630 --> 03:14.590
So I realize this is quite artificial, but just to give you a clear sense of it.

03:14.630 --> 03:16.390
So this is a function, my counting node.

03:16.390 --> 03:18.470
It takes a state, old state.

03:18.750 --> 03:22.310
It it collects the count that is stored within old state.

03:22.350 --> 03:23.270
Old state dot count.

03:23.310 --> 03:30.060
It adds one to it and then it doesn't return like the old state object doesn't try and set count in

03:30.060 --> 03:30.700
old state.

03:30.740 --> 03:37.980
No, it creates a new state object and sets the new state's count to be this incremented count and it

03:37.980 --> 03:39.820
returns that new state object.

03:39.820 --> 03:45.140
And I realize I'm belaboring the point as I often do, but it's an important one, and you need to keep

03:45.140 --> 03:45.820
this in mind.

03:45.820 --> 03:48.580
And otherwise you'll get in all sorts of traps.

03:49.700 --> 03:55.460
So there's one more complication for each of the fields in your state.

03:55.460 --> 04:01.860
You can optionally specify a special function to be associated with that field.

04:02.340 --> 04:03.940
And you're specifying this to Landgraf.

04:03.980 --> 04:08.100
You're saying to Landgraf, hey, I want you to know that for this field in my state, it's a special

04:08.100 --> 04:11.060
field that has a reducer, this function called a reducer.

04:11.100 --> 04:14.300
Reducer is the technical name for this kind of function.

04:14.700 --> 04:20.740
And the job of the reducer function is that when you ever update, when you ever return a new state,

04:20.780 --> 04:23.180
I was going to say update the state, but that might be confusing.

04:23.180 --> 04:27.740
Whenever you return a new state, which is a new version based on an old state, you've done something.

04:27.740 --> 04:29.100
You've returned a new state.

04:29.580 --> 04:36.900
Landgraf can use this reducer function to decide how to combine each the specified field in your new

04:37.060 --> 04:40.060
state with the current state, you see that.

04:40.060 --> 04:45.420
So it can use this function called a reducer, so that if you have a field maybe it's count, maybe

04:45.420 --> 04:46.500
it's a different field.

04:46.500 --> 04:49.740
It would use that to combine it with the old state.

04:50.460 --> 04:53.980
Now, now that I've said that, you're probably thinking about that for a second and you're like, hang

04:53.980 --> 04:56.500
on, why, why, why would you need to do that?

04:56.500 --> 04:57.780
We've got a node like this.

04:57.780 --> 04:58.740
We've got the old state.

04:58.740 --> 04:59.820
We can do that ourselves.

04:59.860 --> 05:03.780
We can just simply update the field in whatever way we want.

05:03.820 --> 05:07.460
Why do we need to specify a reducer function separately?

05:07.460 --> 05:08.460
Well, here's why.

05:08.780 --> 05:14.220
Because this means that that graph can run multiple nodes at the same time.

05:14.220 --> 05:17.100
They can all be running and they're all returning state.

05:17.100 --> 05:23.340
And there's no risk that one node runs and it overwrites the progress that a different node made at

05:23.340 --> 05:24.180
the same time.

05:24.420 --> 05:28.740
If for any field that has a reducer like this, it will always be able to work, they'll be able to

05:28.780 --> 05:31.540
combine different states behind the scenes.

05:31.540 --> 05:36.580
And that's that's the kind of that's the clever trick that allows that to be so.

05:36.580 --> 05:39.940
So you'll see when if this is seeming a little bit abstract, it's going to be concrete.

05:39.940 --> 05:42.820
When we look at the code, we will indeed use a reducer.

05:42.820 --> 05:46.740
And it's going to be super clear why we need to do that and how it helps.
