WEBVTT

00:00.230 --> 00:00.890
Welcome.

00:00.890 --> 00:04.340
In this video, we're going to have a look at a concept called time travel.

00:04.490 --> 00:10.520
A time travel is a way for you to be able to replay certain events that have happened inside of your

00:10.520 --> 00:11.420
line graph.

00:11.450 --> 00:15.440
This is a great way for you to easily roll back certain scenarios.

00:15.440 --> 00:16.670
So let's dive in.

00:16.910 --> 00:22.010
Firstly, we're going to import a couple of packages, and we're going to need to set up the OpenAI

00:22.010 --> 00:25.190
API key and the Tahvili API key.

00:25.460 --> 00:29.720
You can also if you want, set up a Langsamt API key as well.

00:29.900 --> 00:32.270
Now just a bit more on time travel.

00:32.270 --> 00:38.210
You know, in a typical chatbot workflow, you know your users respond to certain messages and won the

00:38.210 --> 00:40.940
conversation, or the chat history ends, then that's kind of finish.

00:40.940 --> 00:45.800
And we can obviously look to how you can add memory to that chat history, and also how you can add

00:45.800 --> 00:47.300
a human in the loop node.

00:47.300 --> 00:52.130
But this kind of takes a bit further in terms of what happens if your user wants to start from a previous

00:52.130 --> 00:58.510
response, or if the user wants to be able to rewind part of the graph execution, but to maybe correct

00:58.510 --> 00:59.710
certain types of mistakes.

00:59.710 --> 01:03.070
And so you can use line graphs built in time travel functionality.

01:03.070 --> 01:06.760
And we'll be looking at a method that's called the Getstate history.

01:06.760 --> 01:12.880
And the Getstate history method basically has all of the graph snapshots for the entire duration of

01:12.880 --> 01:14.350
that land graph execution.

01:14.350 --> 01:18.040
So we've got a couple of imports that we that we have here.

01:18.040 --> 01:21.160
And we've got the line graph state, which is just the messages.

01:21.160 --> 01:25.450
And we've got an annotated reducer function telling it to add in the extra message.

01:25.450 --> 01:28.420
This flag, we've seen it before the off screen.

01:28.420 --> 01:31.150
And we've also got our request assistance tool.

01:31.150 --> 01:34.240
And we set up our tools are basically being tavileh.

01:34.240 --> 01:39.790
And we also bind to the LM both the tools and the request assistance tool.

01:40.560 --> 01:47.610
Now, this chatbot node here will basically determine whether the ask human should be set to true,

01:47.610 --> 01:50.220
and also invokes the response as well.

01:50.220 --> 01:52.080
But we have the graph that we start building.

01:52.080 --> 01:56.490
We add the chatbot node the tools node which contains the tool node.

01:56.610 --> 02:02.430
Combining combining our research results tool, we have the create response which will return a tool

02:02.430 --> 02:09.400
message, and the human node which typically won't actually be used in terms of the actual graph, will

02:09.400 --> 02:10.870
just be updating.

02:10.990 --> 02:15.130
Just before we and interrupting before we actually hit that node.

02:15.160 --> 02:20.980
Now we also have a select node function and you'll see if the state is ask human.

02:20.980 --> 02:22.450
Then we go to the human node.

02:22.480 --> 02:24.430
Else we return this tools condition.

02:24.430 --> 02:27.880
And the tools condition will just basically route to the tools node.

02:27.880 --> 02:32.690
So the tools condition like if there's a tool then what it will do is it will go into this tool node.

02:32.690 --> 02:36.140
Here we've got the conditional edges that are set up.

02:36.140 --> 02:43.820
And we are um, going to be using a SQLite saver from a connection string of memory and putting that

02:43.820 --> 02:44.780
in as a check pointer.

02:44.780 --> 02:47.600
And notice here how it interrupting before the human node.

02:47.930 --> 02:52.850
Now now that this is run, let's have a look and see what our graph looks like after it's been compiled.

02:52.850 --> 02:56.030
You can see we're starting in in here and going into the chatbot mode.

02:56.030 --> 03:00.470
And then we're either going into the human in the loop node or we're we're doing tools.

03:00.470 --> 03:02.300
And then after that we're then ending.

03:02.300 --> 03:05.120
So let's let's get our graph doing a couple of steps.

03:05.120 --> 03:08.180
So I'm going to ask it to say you know I'm learning line graph.

03:08.180 --> 03:09.140
Can you do some research.

03:09.140 --> 03:13.940
And you can see it's decided to make a tool call to table search engine results.

03:13.940 --> 03:18.070
And here's the information it's provided back I can say you know, that's helpful.

03:18.070 --> 03:20.260
They want to build an autonomous agent with that.

03:20.260 --> 03:22.720
And then, you know, it sounds like a fascinating project.

03:22.720 --> 03:26.380
Just let us know if you've got any need for assistance or guidance along the way.

03:26.380 --> 03:32.950
Now this is where it gets quite interesting where we can use this graph dot get state history function.

03:32.950 --> 03:36.640
So this get state history function is a generator object.

03:36.640 --> 03:40.330
And if we look at what is inside here we'll just do a have a look at the first one.

03:40.330 --> 03:45.280
You'll see we get a stationery shop which has a values key.

03:45.280 --> 03:49.990
And the values on this has all of the messages.

03:49.990 --> 03:54.280
It also has things like, you know the boolean states of the graph.

03:54.280 --> 03:55.360
Ask human.

03:55.480 --> 03:58.060
There's other things that you could look at as well on here.

03:58.060 --> 04:00.790
But so for example let's scroll along.

04:00.790 --> 04:07.200
You can obviously get other things like when this when this was created at what the what the parent

04:07.200 --> 04:07.920
config is.

04:07.920 --> 04:10.980
And also notice we get a thread timestamp.

04:10.980 --> 04:14.340
And we also have some metadata as well at usage metadata.

04:14.340 --> 04:21.180
So a couple of different things that can be useful to know about I would generally say that yeah, the

04:21.180 --> 04:23.790
most important things are going to be this thread timestamp.

04:23.790 --> 04:30.010
And as well as that you know also getting the values out for specific different bits of the state history.

04:30.040 --> 04:33.640
In our scenario, we're going to loop over the get state history function.

04:34.150 --> 04:36.820
And we pass in the config for the graph.

04:36.820 --> 04:38.350
So we pass in the runnable config.

04:38.350 --> 04:43.930
And the reason why we pass in the config here is if you remember earlier, the config actually contains

04:43.930 --> 04:44.620
the thread id.

04:44.620 --> 04:51.340
And so this tells the graph exactly where to get the state history from for this specific thread.

04:51.430 --> 04:57.290
Now we can then say okay, well let's print all the messages and the length of those and what bits of

04:57.290 --> 04:58.790
the state will be coming next.

04:58.790 --> 05:04.250
And you'll see that if we're looking from the bottom up, because when you do checkpointing, you're

05:04.250 --> 05:05.750
actually working in reverse.

05:05.750 --> 05:10.880
You can see that, you know, the last piece of state we had, we sort of had no next state to go to.

05:10.880 --> 05:15.410
This one we had the chatbot states go to and then this one here we started again.

05:15.410 --> 05:19.250
And so maybe we want to roll back to a previous state.

05:19.250 --> 05:22.130
So in this scenario I've said let's go back to a lake for three.

05:22.130 --> 05:23.990
So let's have a look at that as well.

05:23.990 --> 05:25.580
So I'm going to just run that code.

05:26.540 --> 05:32.690
And now you can see that we have the next node in our in our graph execute is now the chatbot node.

05:32.690 --> 05:37.760
Additionally if you have a look at this when we do when we get the runnable config from that, that

05:37.760 --> 05:43.510
state snapshot config gets us the runnable config on that specific snapshot.

05:43.510 --> 05:48.910
And what's interesting about this is it adds on this thread RTS, which is the timestamp of when that

05:48.910 --> 05:50.410
specific checkpoint happened.

05:50.410 --> 05:55.270
And that's useful because then we can basically go inside our graph stream.

05:55.270 --> 06:00.190
We can say, well, we're not going to add any new input for now, but we just want to replay from here

06:00.190 --> 06:00.760
onwards.

06:00.760 --> 06:06.550
And what you'll see is we're able to replay this new thing here, which is the message straight off,

06:06.550 --> 06:08.050
which is the AI message.

06:08.740 --> 06:15.610
So that's a really great way for us to be able to easily roll back the graph implementation to a specific

06:15.610 --> 06:17.590
point and then rerun the graph.

06:17.800 --> 06:22.810
It's also worth noting that you could as well also have added input into this.

06:22.810 --> 06:24.490
So there's no reason why.

06:24.490 --> 06:30.120
You know, if you wanted, you could also revert the graph back to that implementation, but then also

06:30.120 --> 06:32.070
add on additional inputs.

06:32.100 --> 06:38.670
And so time travel gives you the ability as the developer to decide to the user.

06:38.670 --> 06:42.360
Can they revert back to a previous state inside of the graph execution.

06:42.360 --> 06:44.400
What kind of corrections can they do?

06:44.400 --> 06:49.860
All of these things are really, really useful for building these kind of state machine hierarchical

06:49.860 --> 06:50.790
workflows.

06:50.790 --> 06:54.840
That means that users are going to be able to interact with your app more effectively.
