WEBVTT

00:00.150 --> 00:01.380
-: Hey, welcome back.

00:01.380 --> 00:02.910
And in this video we're gonna have a look at

00:02.910 --> 00:05.250
how you can use tools,

00:05.250 --> 00:08.190
and also persistence, inside of LangGraph.

00:08.190 --> 00:10.380
Firstly, we're gonna just import a couple of packages

00:10.380 --> 00:13.200
and then after that we are also going

00:13.200 --> 00:15.930
to see if you have your open AI, API key

00:15.930 --> 00:17.310
specifically for that, as well.

00:17.310 --> 00:19.470
So I'm just gonna run this Python.

00:19.470 --> 00:21.150
And the other thing we're gonna need

00:21.150 --> 00:22.608
is something called Tavily.

00:22.608 --> 00:25.440
And Tavily is a great search engine that you can use,

00:25.440 --> 00:28.560
they offer a free amount specifically of credits.

00:28.560 --> 00:31.140
And the main benefit of using Tavily is

00:31.140 --> 00:34.170
that you can easily connect your large language models

00:34.170 --> 00:37.290
with text-based results that come back from Google search.

00:37.290 --> 00:40.200
So, rather than you having to use a Google search,

00:40.200 --> 00:43.290
API wrapper and get the text from the webpages,

00:43.290 --> 00:45.030
all of that is handled automatically

00:45.030 --> 00:47.970
for you using a package like Tavily.

00:47.970 --> 00:50.010
So that's also one of the requirements.

00:50.010 --> 00:53.190
And then I'm also gonna set my API key for Tavily.

00:53.190 --> 00:55.201
So I'm just gonna copy that in

00:55.201 --> 00:58.290
and then we're gonna use the Tavily results,

00:58.290 --> 01:01.440
and you can see this is the tool that we'll be using,

01:01.440 --> 01:04.410
and we've set a max results of two

01:04.410 --> 01:06.150
and then we wrap that in a Python list

01:06.150 --> 01:07.440
'cause we're gonna use a list of tools

01:07.440 --> 01:09.437
and you can even invoke a tool.

01:09.437 --> 01:12.060
So you can say, like, "What's a node in LangGraph?"

01:12.060 --> 01:13.830
And you'll see that it gives us a couple

01:13.830 --> 01:15.357
of different results and you've got the URL

01:15.357 --> 01:18.153
and the content specifically of those.

01:19.020 --> 01:21.030
Now, the next thing that we need to do

01:21.030 --> 01:23.460
is we need to annotate our state.

01:23.460 --> 01:26.580
And you can see we have a state graph being set up

01:26.580 --> 01:27.750
and that is being set up

01:27.750 --> 01:30.750
using this state-typed dictionary we have,

01:30.750 --> 01:32.340
which has a list of messages

01:32.340 --> 01:34.380
which are also being appended to using

01:34.380 --> 01:37.260
that add messages that will merge in the left

01:37.260 --> 01:39.390
and right messages easily.

01:39.390 --> 01:40.860
So that's a nice helper function

01:40.860 --> 01:43.590
and we're gonna be using the GPT-4 O model

01:43.590 --> 01:46.140
and then also making sure that we've got these tools.

01:46.140 --> 01:49.620
So we have a list of tools that you can see

01:49.620 --> 01:51.300
with the Tavily search results,

01:51.300 --> 01:54.000
and What we're gonna do is then take our chat model,

01:54.000 --> 01:56.730
which is this LLM, and we're gonna bind those tools to it.

01:56.730 --> 01:59.520
And different types of providers like Anthropic

01:59.520 --> 02:03.150
and Grok will also provide you with the ability

02:03.150 --> 02:06.330
to add tools to your large language models.

02:06.330 --> 02:07.920
We've got a function here called chatbot,

02:07.920 --> 02:10.530
which is basically what we had before,

02:10.530 --> 02:13.140
and it returns a key of messages

02:13.140 --> 02:16.770
with the invoked state of the messages with the tools.

02:16.770 --> 02:18.470
So we're gonna add that as a node.

02:19.470 --> 02:20.640
Now we need to create a function

02:20.640 --> 02:22.563
to run the tools if they are called,

02:23.910 --> 02:25.590
just to show you that the sort of

02:25.590 --> 02:27.960
the lower level implementation,

02:27.960 --> 02:30.810
remember that your chat bot can return

02:30.810 --> 02:34.260
that it wants to call several tools in one message.

02:34.260 --> 02:36.090
And so what we need is something

02:36.090 --> 02:37.770
that will have all of the tools

02:37.770 --> 02:39.750
with the names of those tools

02:39.750 --> 02:43.710
and we also have a call here which basically goes

02:43.710 --> 02:45.000
and tries to get the messages.

02:45.000 --> 02:48.600
And if there aren't any messages then it will raise an error

02:48.600 --> 02:50.460
and it makes the outputs,

02:50.460 --> 02:53.910
and for each message doc tool calls,

02:53.910 --> 02:55.170
it will get the tool call,

02:55.170 --> 02:57.840
and it will find that tool by its name

02:57.840 --> 03:02.400
and invoke it with a tool call with the ARGs of that

03:02.400 --> 03:05.910
and it will append the outputs as tool messages

03:05.910 --> 03:09.720
with the content from the json.dumps is the content

03:09.720 --> 03:12.060
and the name and the tool call ID.

03:12.060 --> 03:14.550
The tool call IDs are quite important

03:14.550 --> 03:16.170
because that tells that this, you know,

03:16.170 --> 03:19.080
that what message this tool call is responding to.

03:19.080 --> 03:21.690
And then we return the messages with the outputs

03:21.690 --> 03:24.300
and then you can see we've got a basic tool node

03:24.300 --> 03:26.190
which takes in a bunch of tools

03:26.190 --> 03:28.920
and we can use our original graph builder

03:28.920 --> 03:31.020
to add on this new tool node.

03:31.020 --> 03:33.570
Now once, because we've got two nodes,

03:33.570 --> 03:35.940
now we've got the chat bot node and the tools node,

03:35.940 --> 03:39.330
the next thing we have to do is we have to link these things

03:39.330 --> 03:42.750
and recall that edges are the way that we can connect nodes

03:42.750 --> 03:43.920
inside of a state machine.

03:43.920 --> 03:45.960
So, if we're thinking about a state machine

03:45.960 --> 03:48.480
and how these kinds of nodes, you know, might look,

03:48.480 --> 03:50.520
you might have something that looks a little bit like this

03:50.520 --> 03:52.800
where you've got H for Human

03:52.800 --> 03:55.050
and LLM for Large Language Model

03:55.050 --> 03:57.480
and you could have some types of nodes

03:57.480 --> 04:00.180
where you've got these sort of bubbles and black boxes

04:00.180 --> 04:04.020
and you can see the arrows pointing to the directional flow.

04:04.020 --> 04:06.870
And we can think of these black arrows

04:06.870 --> 04:09.150
in the middle here as the edges.

04:09.150 --> 04:11.730
Okay? And the great thing about LangGraph

04:11.730 --> 04:14.910
is we can have these cyclical loops where, you know,

04:14.910 --> 04:17.070
and we can also have conditional edges.

04:17.070 --> 04:19.110
So, a conditional edge might look like this

04:19.110 --> 04:21.240
where we have a node here

04:21.240 --> 04:25.260
and we decide whether we should progress to this next one.

04:25.260 --> 04:27.720
So I'll do blue for conditional.

04:27.720 --> 04:29.160
We might progress here,

04:29.160 --> 04:33.300
or we might go and we might go and do something else

04:33.300 --> 04:35.490
and then go back into here, right?

04:35.490 --> 04:37.890
So this might be something that we do.

04:37.890 --> 04:39.870
So, you can think of it like a little bit like this,

04:39.870 --> 04:42.920
so, we might go into here,

04:42.920 --> 04:45.120
so this is kind of what I'm thinking.

04:45.120 --> 04:47.040
So we've got a node

04:47.040 --> 04:52.040
and we might conditionally go into this node.

04:52.920 --> 04:54.766
You can think of this as the conditional node.

04:54.766 --> 04:57.085
(keyboard keys rapidly clicking)

04:57.085 --> 04:59.843
And we can think of this as if we've passed

05:01.180 --> 05:03.330
a certain check continue, right?

05:03.330 --> 05:05.250
And we'll go to the continue node.

05:05.250 --> 05:09.540
And what's important about this is we essentially have

05:09.540 --> 05:14.010
between this node here and this continue node,

05:14.010 --> 05:17.430
we have a conditional edge, right?

05:17.430 --> 05:20.670
Sometimes we're going back in, sometimes we're going here.

05:20.670 --> 05:23.580
So, this edge is fairly conditional

05:23.580 --> 05:24.870
and you can think of it like maybe

05:24.870 --> 05:27.150
you will have two different conditions.

05:27.150 --> 05:30.090
One goes to the blue and one goes to the green

05:30.090 --> 05:31.080
and decides to continue.

05:31.080 --> 05:32.610
So that's what we're gonna have a look at now.

05:32.610 --> 05:35.760
It's pretty simple, it's just mapping, you know,

05:35.760 --> 05:37.680
this node to that node based on a condition

05:37.680 --> 05:39.580
and this node to the conditional node,

05:41.697 --> 05:42.530
based on a condition, as well.

05:42.530 --> 05:43.620
So, let's have a look at that.

05:43.620 --> 05:46.560
So we've got this route tools function

05:46.560 --> 05:51.180
and you can see we are returning a string of literal,

05:51.180 --> 05:53.670
so basically just a string of Veeva tools

05:53.670 --> 05:58.080
or this underscore, underscore, end, underscore, underscore.

05:58.080 --> 06:02.160
Now, what you'll see is if we have a list,

06:02.160 --> 06:04.200
get the AI message.

06:04.200 --> 06:08.550
If the messages exist there, we're gonna get that instead.

06:08.550 --> 06:12.060
And if we don't have any of those, we raise an error,

06:12.060 --> 06:13.837
and we basically have this bit where we say,

06:13.837 --> 06:18.000
"If this AI message has tool calls,

06:18.000 --> 06:20.070
and the tool calls is greater than zero,

06:20.070 --> 06:23.700
I want to go into this tools node.

06:23.700 --> 06:27.120
Else, I want to just return with this end."

06:27.120 --> 06:29.040
Now the end is a very special node

06:29.040 --> 06:32.310
because it represents the end of the state machine.

06:32.310 --> 06:35.913
And what we then do is with our route tools function,

06:36.810 --> 06:40.020
we are then going to map the route tools

06:40.020 --> 06:41.250
with the outputs of these.

06:41.250 --> 06:42.840
So you can see we've got the return of tools

06:42.840 --> 06:47.280
and the return of end, the return of tools gets matched

06:47.280 --> 06:50.760
to our tools node that we created earlier, right?

06:50.760 --> 06:52.980
And I'll just scroll up to just remind you,

06:52.980 --> 06:55.440
this is where we created the tools node, right?

06:55.440 --> 06:57.390
So if I was to make this more explicit

06:57.390 --> 06:59.340
I would call this the tools node

06:59.340 --> 07:01.530
and then if I was to go down here,

07:01.530 --> 07:04.950
then this tools would then map to the tools node here.

07:04.950 --> 07:05.783
Okay?

07:07.620 --> 07:09.720
It's this bit which is actually mapping it.

07:09.720 --> 07:10.650
'Cause you can think of it, like,

07:10.650 --> 07:12.540
we have this route tools function,

07:12.540 --> 07:16.020
the outputs of these are the keys inside of the dictionary.

07:16.020 --> 07:17.281
So, tools and end,

07:17.281 --> 07:21.330
which get mapped to either tools or tools node,

07:21.330 --> 07:22.800
depending upon what you decided

07:22.800 --> 07:24.480
to call your tools node.

07:24.480 --> 07:27.390
So, now that I've just gone and update that

07:27.390 --> 07:29.580
and I'll just run this and, yeah,

07:29.580 --> 07:31.980
this has given me an error 'cause that node already exists,

07:31.980 --> 07:33.120
which is fine,

07:33.120 --> 07:35.730
then what we can do is we can compile this graph

07:35.730 --> 07:38.010
and this probably already gives us an error

07:38.010 --> 07:40.050
because we've already compiled the graph.

07:40.050 --> 07:42.300
So ,you can only run these types of things once

07:42.300 --> 07:44.040
because, otherwise, you will get an error.

07:44.040 --> 07:47.430
But if we have a look at our graph, you have the start,

07:47.430 --> 07:50.460
we've set the entry point as the chat bot,

07:50.460 --> 07:54.510
and we've got the different types of of nodes.

07:54.510 --> 07:56.880
So we could also have a look at the nodes,

07:56.880 --> 07:59.430
and you can see we have a start node,

07:59.430 --> 08:02.790
we have a chat bot node and we have a tool node.

08:02.790 --> 08:06.870
Yeah, and the conditional edges is basically going

08:06.870 --> 08:08.040
to do something like this.

08:08.040 --> 08:10.410
If we look, so we'll start here,

08:10.410 --> 08:12.360
we'll go into the chat bot node,

08:12.360 --> 08:14.760
if there are tools, we will go and do those,

08:14.760 --> 08:16.110
and we'll go back into chat bot.

08:16.110 --> 08:18.150
And if there are no more tool calls,

08:18.150 --> 08:20.883
then we will also then just end the chat bot.

08:21.750 --> 08:23.430
And now we can ask the bot questions

08:23.430 --> 08:25.110
outside of its training data.

08:25.110 --> 08:27.450
So, I've got a little while true here

08:27.450 --> 08:30.450
and we have, if the user enters quit or exit or queue,

08:30.450 --> 08:32.490
it will break and print goodbye.

08:32.490 --> 08:35.160
Otherwise, it will stream the graph with the messages

08:35.160 --> 08:37.260
of a two-pull object in the list

08:37.260 --> 08:38.880
where you've got the user and the user input.

08:38.880 --> 08:41.280
And we're just printing out the event values

08:41.280 --> 08:43.080
inside of the LangGraph.

08:43.080 --> 08:44.527
So if I now run this and say,

08:44.527 --> 08:46.650
"Hey, how are you?"
(keyboard keys tapping)

08:46.650 --> 08:48.060
There aren't any tool calls here.

08:48.060 --> 08:50.040
So, the assistant has basically gone straight

08:50.040 --> 08:53.190
from the chat bot node directly to the end node, right?

08:53.190 --> 08:56.340
So, there's a very simple architecture we have

08:56.340 --> 08:57.930
here with this conditional edge

08:57.930 --> 08:59.850
where we're either going into the tools node

08:59.850 --> 09:01.170
or we're going to the end node

09:01.170 --> 09:03.547
after we've invoked the model so it can say,

09:03.547 --> 09:04.909
"I am good, thanks.
(keyboard keys clicking)

09:04.909 --> 09:08.250
What tools do you have available?"

09:08.250 --> 09:10.920
And this probably also won't call a tool.

09:10.920 --> 09:13.710
It says we've got Tavily search

09:13.710 --> 09:16.560
and we also have multi-tool use.

09:16.560 --> 09:20.631
Now, one thing we might wanna say is, "Can you search

09:20.631 --> 09:24.540
on Google for digital marketing leads?"

09:24.540 --> 09:28.050
And then what it's gonna do is it's then gonna go through

09:28.050 --> 09:31.500
and it's gonna use this chat bot and use the tools

09:31.500 --> 09:33.000
and then it's gonna go back here

09:33.000 --> 09:35.160
and if there aren't any more tools to call,

09:35.160 --> 09:36.660
it's then gonna end.

09:36.660 --> 09:38.610
And so what you can see here is it decided

09:38.610 --> 09:41.490
to call Tavily search here,

09:41.490 --> 09:44.460
and then it also then provided the actual answer here.

09:44.460 --> 09:46.500
So it gave us a marketing deep dive

09:46.500 --> 09:48.030
and so that's basically it.

09:48.030 --> 09:50.730
So, congratulations, you've figured out how

09:50.730 --> 09:53.970
to add a tool in a way which works inside of LangGraph,

09:53.970 --> 09:55.420
which is really, really cool.

09:56.400 --> 09:57.840
Now the next thing that we wanna cover

09:57.840 --> 09:59.700
is adding memory to this chat bot.

09:59.700 --> 10:01.560
So we've got a conditional edge,

10:01.560 --> 10:03.390
which will either call the tool,

10:03.390 --> 10:05.460
or it will just end the chat bot.

10:05.460 --> 10:07.080
Now, the next thing we have to look at

10:07.080 --> 10:10.230
is how do we specifically save the state

10:10.230 --> 10:12.090
of which our graph is currently in?

10:12.090 --> 10:14.610
This is important because you might want to

10:14.610 --> 10:16.170
save the state of the graph,

10:16.170 --> 10:18.150
you might want to reload the graph,

10:18.150 --> 10:20.190
you might wanna update parts of that graph,

10:20.190 --> 10:22.620
and then, you know, getting some human feedback.

10:22.620 --> 10:24.630
And, so, where you can use this concept

10:24.630 --> 10:26.250
called a check pointer,

10:26.250 --> 10:30.390
and we're using the thread ID as the unique identifier

10:30.390 --> 10:32.790
for a specific type of graph state,

10:32.790 --> 10:35.730
which will be automatically saved to a database.

10:35.730 --> 10:38.640
Now, we're using the SQL lite saver

10:38.640 --> 10:41.760
and we're deciding to store that directly inside of memory,

10:41.760 --> 10:43.770
but there are different types of persistence

10:43.770 --> 10:44.820
that you might want to know about.

10:44.820 --> 10:47.550
So there is a persistence notebook

10:47.550 --> 10:49.590
inside of LangChain's documentation

10:49.590 --> 10:51.690
that provides for PostgreSQL.

10:51.690 --> 10:54.000
So I'd recommend having a look at that

10:54.000 --> 10:56.310
and I'll leave a link in this lecture

10:56.310 --> 10:59.940
for how they've implemented the PostgreSQL check pointer

10:59.940 --> 11:02.700
for if you want to use that for your production systems.

11:02.700 --> 11:04.350
Let's have a look at how we could do this

11:04.350 --> 11:06.600
purely using the memory check pointer.

11:06.600 --> 11:10.440
And we are then going to replace the basic tool node

11:10.440 --> 11:14.220
with LangChain's built-in tool node and tools condition,

11:14.220 --> 11:15.990
which basically do the exact same things

11:15.990 --> 11:17.763
with the parallel tool cooling,

11:18.630 --> 11:19.950
but it's basically wrapped up

11:19.950 --> 11:21.780
and you don't have to worry about that.

11:21.780 --> 11:23.910
So, you can see here we're now importing

11:23.910 --> 11:25.470
a couple of prebuilt things.

11:25.470 --> 11:26.940
So you've got this tool node

11:26.940 --> 11:29.090
that basically does the same thing as this.

11:31.860 --> 11:32.850
Right?

11:32.850 --> 11:34.380
So you're getting the tools by the name,

11:34.380 --> 11:35.910
you're deciding what tools to call.

11:35.910 --> 11:38.730
You are then appending the results into the messages,

11:38.730 --> 11:40.119
as tool messages.

11:40.119 --> 11:44.130
And we've also got this tools condition

11:44.130 --> 11:45.870
and this tools condition, you'll see,

11:45.870 --> 11:47.280
if you look at the literal of that,

11:47.280 --> 11:50.820
we'll just either route to tools or it will route to end,

11:50.820 --> 11:53.850
based on whether there are some tools to to see.

11:53.850 --> 11:55.440
So, it's basically that bit there,

11:55.440 --> 11:57.240
You've got that tools condition.

11:57.240 --> 12:00.930
So, then we've got our chat bots, we add our chat bot node,

12:00.930 --> 12:05.370
we are setting up the graph and we have a tool node.

12:05.370 --> 12:08.610
And notice how the tool node now is much slower,

12:08.610 --> 12:12.720
sorry, much of reduced amount of sort of code,

12:12.720 --> 12:15.000
and we add that to the tools node.

12:15.000 --> 12:17.580
Then we add our conditional edges on the chat bot

12:17.580 --> 12:19.980
where it's over routing directly to tools

12:19.980 --> 12:21.333
or it's routing to end.

12:22.304 --> 12:24.810
We add a edge from the tools back

12:24.810 --> 12:27.540
to the chat bot just in case tools are called.

12:27.540 --> 12:30.093
And we also set the entry 0.2 chat bots.

12:31.410 --> 12:32.550
Right.

12:32.550 --> 12:36.450
So, I'm gonna just get rid of this user session

12:36.450 --> 12:37.800
to which is happening above.
(keyboard keys clicking)

12:37.800 --> 12:39.510
So I'm just gonna run these.

12:39.510 --> 12:42.150
And, now, instead of just compiling the graph,

12:42.150 --> 12:44.100
we also add a check pointer here.

12:44.100 --> 12:46.110
And that check pointer will basically,

12:46.110 --> 12:48.480
it's an optional check pointer which will save that

12:48.480 --> 12:51.930
to either an online database or local memory.

12:51.930 --> 12:52.763
If we have a look here,

12:52.763 --> 12:54.390
we haven't changed anything inside

12:54.390 --> 12:56.370
of this LangGraph state machine.

12:56.370 --> 12:58.230
We still have the start node,

12:58.230 --> 13:00.810
which is basically chat bot,

13:00.810 --> 13:02.160
and then we go into tools.

13:02.160 --> 13:04.740
If we have any more tools, we then call those

13:04.740 --> 13:07.710
and add into them until we're finished and then we end.

13:07.710 --> 13:10.350
And if there aren't any tools then we directly end.

13:10.350 --> 13:12.930
Now, we set up a runnable config,

13:12.930 --> 13:14.970
and this is the bit that gives you the ability

13:14.970 --> 13:17.010
to load previous checkpoints

13:17.010 --> 13:19.110
and also update previous checkpoints.

13:19.110 --> 13:21.750
So, it's very important that you have a thread ID

13:21.750 --> 13:25.110
inside of your runnable configuration as you pass

13:25.110 --> 13:28.530
that into the app.stream or the graph.stream.

13:28.530 --> 13:31.200
So you can see here, "Hi, my name is James Phoenix,"

13:31.200 --> 13:34.830
we can pass in a message and we pass in the config

13:34.830 --> 13:37.710
and the stream mode just to have a look at the values.

13:37.710 --> 13:40.110
And then we're pretty printing that so you can see

13:40.110 --> 13:42.120
that we've passed in this message

13:42.120 --> 13:44.887
and we then also have, you know,

13:44.887 --> 13:47.160
"How can I help you today?"

13:47.160 --> 13:49.560
And then if we look at a different,

13:49.560 --> 13:51.990
if we look at, like, the same config,

13:51.990 --> 13:54.210
so using the same config as before.

13:54.210 --> 13:55.980
So if we're just having a look at that,

13:55.980 --> 13:57.960
which is the thread ID of one,

13:57.960 --> 14:00.630
then what we can do is say, "Remember my name,"

14:00.630 --> 14:02.760
and you can see that it does know

14:02.760 --> 14:05.550
that my name is James Phoenix, which is a good thing.

14:05.550 --> 14:07.470
Now, the problem that we run into

14:07.470 --> 14:09.990
is if we change this thread ID,

14:09.990 --> 14:12.450
you're gonna see the previous message.

14:12.450 --> 14:14.460
It doesn't really know who I am anymore

14:14.460 --> 14:17.190
because it's not using that thread ID, right?

14:17.190 --> 14:21.060
So, the thread ID is the way that the graph is able

14:21.060 --> 14:24.810
to determine specifically what, you know, who you are.

14:24.810 --> 14:29.550
And that's coming from earlier when we loaded the graph,

14:29.550 --> 14:32.700
we actually used a check pointer, right?

14:32.700 --> 14:35.790
So in real time that check pointer is being loaded

14:35.790 --> 14:39.750
and it's being differently attributed to the thread IDs

14:39.750 --> 14:42.300
inside of the SQL lite database.

14:42.300 --> 14:47.300
Now, if we're having a look, we can also modify,

14:47.370 --> 14:50.550
yeah, so the only change that we've made to the thread ID,

14:50.550 --> 14:52.860
but we can also have a look at a few checkpoints

14:52.860 --> 14:53.880
across these different threads.

14:53.880 --> 14:56.220
So, we can get the state of a graph

14:56.220 --> 14:57.660
by taking the configuration.

14:57.660 --> 14:59.790
So, we've got the thread idea of one

14:59.790 --> 15:01.470
and you can see this is the snapshot.

15:01.470 --> 15:03.540
So you get access to things like the DOT values,

15:03.540 --> 15:05.280
which is all the messages.

15:05.280 --> 15:07.230
And there's also a lot more things

15:07.230 --> 15:09.000
that you can have a look at inside of there.

15:09.000 --> 15:10.800
There's, for example, the.next,

15:10.800 --> 15:12.600
which we'll just have a look at over here.

15:12.600 --> 15:15.840
So the snapshot.next shows that there's nothing else

15:15.840 --> 15:18.630
to do on on the graph, right?

15:18.630 --> 15:20.040
But there's lots of different ones, as well.

15:20.040 --> 15:22.230
You can look at the parent configuration,

15:22.230 --> 15:24.270
there's lots of different attributes

15:24.270 --> 15:26.070
that you might find interesting.

15:26.070 --> 15:27.930
There's metadata, for example,

15:27.930 --> 15:30.300
that you can attach specifically to the graph.

15:30.300 --> 15:33.330
And the.next is quite useful for determining

15:33.330 --> 15:35.950
what nodes would be useful to run next

15:36.870 --> 15:38.670
inside of the state machine.

15:38.670 --> 15:41.790
Now, the next node, you know, obviously, has reached an end.

15:41.790 --> 15:43.350
So, next is empty,

15:43.350 --> 15:46.920
but that's basically a little bit on the persistence

15:46.920 --> 15:49.260
and tool usage inside of LangGraph.

15:49.260 --> 15:51.150
Next, we're gonna have a look at

15:51.150 --> 15:53.400
how we can add human in a loop.

15:53.400 --> 15:55.110
So, we've got a chat bot now,

15:55.110 --> 15:57.510
we've added on the Tavily search tool,

15:57.510 --> 15:59.940
and we've also talked around persistence

15:59.940 --> 16:01.800
and how you can use persistence

16:01.800 --> 16:06.240
to specifically remember previous conversations you've had

16:06.240 --> 16:09.180
using a check pointer with the thread ID

16:09.180 --> 16:10.353
inside of LangGraph.
