WEBVTT

1
00:00:00.270 --> 00:00:01.560
<v ->Hey there. Eden here.</v>

2
00:00:01.560 --> 00:00:04.050
And this video was refilmed to match

3
00:00:04.050 --> 00:00:06.450
the latest version of LangGraph

4
00:00:06.450 --> 00:00:07.560
because things have changed

5
00:00:07.560 --> 00:00:09.510
since this video was previously filmed.

6
00:00:09.510 --> 00:00:11.580
And the version I'm going to be using

7
00:00:11.580 --> 00:00:13.173
for this video is 1.0.5.

8
00:00:14.730 --> 00:00:17.070
And the important thing to you to note for this video

9
00:00:17.070 --> 00:00:21.840
is that it's updated according to LangGraph 1.+.

10
00:00:21.840 --> 00:00:23.985
Now let's go to main.py

11
00:00:23.985 --> 00:00:28.110
and let's start assemble all of the pieces together

12
00:00:28.110 --> 00:00:30.540
and let's build our LangGraph graph.

13
00:00:30.540 --> 00:00:32.490
So let's start with the imports.

14
00:00:32.490 --> 00:00:35.400
Let's import Literal from typing.

15
00:00:35.400 --> 00:00:39.123
Let's go and import AIMessage and ToolMessage.

16
00:00:40.410 --> 00:00:44.130
And let's go and import from LangGraph the end node,

17
00:00:44.130 --> 00:00:45.630
the start node.

18
00:00:45.630 --> 00:00:48.628
And we want to import a StateGraph.

19
00:00:48.628 --> 00:00:50.639
And the StateGraph is only going

20
00:00:50.639 --> 00:00:52.800
to hold a list of messages.

21
00:00:52.800 --> 00:00:55.680
So that's why I am also importing MessageState.

22
00:00:55.680 --> 00:00:57.678
And we implemented this from scratch

23
00:00:57.678 --> 00:01:00.960
in the previous section of the reflection agent.

24
00:01:00.960 --> 00:01:04.800
However, we can import it from LangGraph prebuilt.

25
00:01:04.800 --> 00:01:07.350
So eventually the StateGraph is going to have

26
00:01:07.350 --> 00:01:09.150
a state of the MessageState,

27
00:01:09.150 --> 00:01:11.820
which is simply a list of messages.

28
00:01:11.820 --> 00:01:14.897
And let's see, import from our chains PY file,

29
00:01:14.897 --> 00:01:18.270
the reviser chain, we have it right over here

30
00:01:18.270 --> 00:01:22.050
and the first responder chain, which we have it over here.

31
00:01:22.050 --> 00:01:25.502
We also want to import from the tool executor PY file

32
00:01:25.502 --> 00:01:27.840
the execute tool variables,

33
00:01:27.840 --> 00:01:30.480
which is going to be a tool node.

34
00:01:30.480 --> 00:01:32.610
So it's going to be running our tools.

35
00:01:32.610 --> 00:01:35.340
This is going to be running our search tool concurrently.

36
00:01:35.340 --> 00:01:38.700
And let's define Max Iterations equals 2.

37
00:01:38.700 --> 00:01:41.877
So this means we want only two iterations

38
00:01:41.877 --> 00:01:45.210
of revision, draft, revision, draft

39
00:01:45.210 --> 00:01:46.740
and we want to limit this.

40
00:01:46.740 --> 00:01:49.676
In the future, if we want to integrate LLM

41
00:01:49.676 --> 00:01:53.700
as a judge architecture, we can not limit it by the number,

42
00:01:53.700 --> 00:01:55.861
but make an LLM call to decide

43
00:01:55.861 --> 00:01:57.870
whether we want to resume or not.

44
00:01:57.870 --> 00:01:59.340
And we're going to be implementing

45
00:01:59.340 --> 00:02:01.740
these kinds of architecture in the next section

46
00:02:01.740 --> 00:02:03.750
of the course where we're going to build

47
00:02:03.750 --> 00:02:05.670
an agentic correct solution.

48
00:02:05.670 --> 00:02:08.790
So let's start by implementing our graph nodes.

49
00:02:08.790 --> 00:02:10.350
So let's start with the first node,

50
00:02:10.350 --> 00:02:12.090
which is called the draft node.

51
00:02:12.090 --> 00:02:14.340
So this node is going to receive the state,

52
00:02:14.340 --> 00:02:17.430
which I remind you only has a list of messages.

53
00:02:17.430 --> 00:02:21.150
And we simply want to draft the response.

54
00:02:21.150 --> 00:02:24.270
So we want to call the first responder chain

55
00:02:24.270 --> 00:02:26.820
and we are going to give it when we invoke it

56
00:02:26.820 --> 00:02:30.750
in the messages key, the state in the messages place.

57
00:02:30.750 --> 00:02:32.730
So this is going to take all of the messages

58
00:02:32.730 --> 00:02:34.890
that we have in the graph and send it.

59
00:02:34.890 --> 00:02:37.470
And when we start to execute this graph,

60
00:02:37.470 --> 00:02:39.570
the first message is going to be

61
00:02:39.570 --> 00:02:42.660
the human message with our user input.

62
00:02:42.660 --> 00:02:44.970
So when we're going to get a response

63
00:02:44.970 --> 00:02:46.380
from the first responder,

64
00:02:46.380 --> 00:02:49.470
we're going to be getting an answer question.

65
00:02:49.470 --> 00:02:51.810
This is going to be the type of the response.

66
00:02:51.810 --> 00:02:53.610
So it's going to have an answer,

67
00:02:53.610 --> 00:02:55.230
it's going to have the reflection,

68
00:02:55.230 --> 00:02:58.710
so what needs to change, what is missing,

69
00:02:58.710 --> 00:03:01.590
what is superfluous, and the search queries.

70
00:03:01.590 --> 00:03:03.480
So these are going to be the search queries

71
00:03:03.480 --> 00:03:05.070
which we want to run later.

72
00:03:05.070 --> 00:03:06.930
And lastly, once we get this response,

73
00:03:06.930 --> 00:03:11.310
we want to append it into our messages key in our state.

74
00:03:11.310 --> 00:03:13.710
So this line over here is going to take the message

75
00:03:13.710 --> 00:03:15.720
and it's going to append it to the state.

76
00:03:15.720 --> 00:03:17.010
So in the same way,

77
00:03:17.010 --> 00:03:20.220
let's go and let's implement the revised node.

78
00:03:20.220 --> 00:03:22.860
And this is going to revise the answer

79
00:03:22.860 --> 00:03:27.750
based on the tool results, which was the Pydantic critique.

80
00:03:27.750 --> 00:03:30.450
And here, we simply want to take our reviser chain

81
00:03:30.450 --> 00:03:32.010
and we want to invoke it

82
00:03:32.010 --> 00:03:34.230
with all the messages we have so far.

83
00:03:34.230 --> 00:03:35.730
And in the first iteration,

84
00:03:35.730 --> 00:03:38.070
it's going to be the result of the first result.

85
00:03:38.070 --> 00:03:39.690
After we get a response,

86
00:03:39.690 --> 00:03:42.720
we want to append it to the graph state as well.

87
00:03:42.720 --> 00:03:45.450
And before we go and implement our graph,

88
00:03:45.450 --> 00:03:48.060
let's go and remember what we're trying to do here.

89
00:03:48.060 --> 00:03:53.060
So we want to limit the number of iterations we do here.

90
00:03:53.550 --> 00:03:56.970
And the way we want to limit it is with a magic number,

91
00:03:56.970 --> 00:03:58.590
which in our case is 2.

92
00:03:58.590 --> 00:04:02.580
So we want to have only at most two iterations here.

93
00:04:02.580 --> 00:04:04.140
And this is a heuristic.

94
00:04:04.140 --> 00:04:05.652
This is not the best way to do it.

95
00:04:05.652 --> 00:04:08.130
Of course, if you want to make it much more advanced,

96
00:04:08.130 --> 00:04:10.470
we can add an LLM as a judge here.

97
00:04:10.470 --> 00:04:12.930
But for this example, we want to limit it to two.

98
00:04:12.930 --> 00:04:14.550
So in order to count

99
00:04:14.550 --> 00:04:17.610
and to know in which iteration we are,

100
00:04:17.610 --> 00:04:20.130
let's take a look of what's happening here.

101
00:04:20.130 --> 00:04:23.730
So I remind you that we are using function calling

102
00:04:23.730 --> 00:04:26.370
to structure our LLMs output here.

103
00:04:26.370 --> 00:04:28.170
So this kind of response is going

104
00:04:28.170 --> 00:04:29.730
to come from function calling.

105
00:04:29.730 --> 00:04:32.730
And so in order to limit our number of iterations

106
00:04:32.730 --> 00:04:34.013
to two iterations,

107
00:04:34.013 --> 00:04:37.440
because we want to count the number of tool calls

108
00:04:37.440 --> 00:04:40.620
because each tool call is going to be an LLM response

109
00:04:40.620 --> 00:04:42.450
according to our structured output here.

110
00:04:42.450 --> 00:04:43.290
So when we invoke,

111
00:04:43.290 --> 00:04:45.870
the responder is going to be one tool call here.

112
00:04:45.870 --> 00:04:48.870
Executing the tools will not result in tool calls

113
00:04:48.870 --> 00:04:50.610
because it's going to be tool nodes.

114
00:04:50.610 --> 00:04:53.460
So there isn't an LLM making a tool call over here.

115
00:04:53.460 --> 00:04:55.190
And when we're going to run our advisor chain,

116
00:04:55.190 --> 00:04:57.330
we're going to receive a tool call.

117
00:04:57.330 --> 00:04:59.790
So the condition to finish the job

118
00:04:59.790 --> 00:05:01.887
and to endo graph is going to be

119
00:05:01.887 --> 00:05:05.490
if we have more than two tool calls,

120
00:05:05.490 --> 00:05:07.800
this is one, this is two.

121
00:05:07.800 --> 00:05:10.080
And in the second iteration

122
00:05:10.080 --> 00:05:12.540
we're going to have three tool calls.

123
00:05:12.540 --> 00:05:15.060
And here we're going to have four tool calls.

124
00:05:15.060 --> 00:05:17.460
So this number is going to be greater than two.

125
00:05:17.460 --> 00:05:18.960
So this is what we're going to be doing

126
00:05:18.960 --> 00:05:21.780
in the conditional edge here after the reviser chain.

127
00:05:21.780 --> 00:05:23.850
So let's go and implement its logic.

128
00:05:23.850 --> 00:05:27.150
So the conditional edge is going to be called event loop

129
00:05:27.150 --> 00:05:29.730
and it's going to receive the state as an input,

130
00:05:29.730 --> 00:05:31.500
which is going to be a list of messages.

131
00:05:31.500 --> 00:05:33.180
So it's going to return either,

132
00:05:33.180 --> 00:05:35.310
we want to go and execute tools.

133
00:05:35.310 --> 00:05:37.734
So either from here we want to go to execute tools

134
00:05:37.734 --> 00:05:40.200
or we want to go and end.

135
00:05:40.200 --> 00:05:41.880
So this is going to be end here.

136
00:05:41.880 --> 00:05:43.290
And this is the conditional edge.

137
00:05:43.290 --> 00:05:47.880
It goes to the end or it goes to the execute tools here.

138
00:05:47.880 --> 00:05:49.560
So the way we want to do it,

139
00:05:49.560 --> 00:05:52.710
we want to go and count the number of tool calls.

140
00:05:52.710 --> 00:05:56.460
So this is simply iterating over the messages key,

141
00:05:56.460 --> 00:05:58.140
iterating through all the messages.

142
00:05:58.140 --> 00:06:00.510
If it is a tool call, we want to call it.

143
00:06:00.510 --> 00:06:03.870
And here we get the number of the tool visits we have here.

144
00:06:03.870 --> 00:06:05.552
So if this number is going

145
00:06:05.552 --> 00:06:09.810
to be greater than max iterations, which is two,

146
00:06:09.810 --> 00:06:11.700
then we want to finish

147
00:06:11.700 --> 00:06:14.250
'cause it's going to be three or it's going to be four.

148
00:06:14.250 --> 00:06:18.210
And if not, we want to go to execute tools.

149
00:06:18.210 --> 00:06:20.160
So this is going to ensure us

150
00:06:20.160 --> 00:06:22.740
we are running this architecture only twice.

151
00:06:22.740 --> 00:06:24.690
The loop here is running only twice.

152
00:06:24.690 --> 00:06:26.790
And now let's go and implement the graph.

153
00:06:26.790 --> 00:06:29.640
We want to build a StateGraph

154
00:06:29.640 --> 00:06:31.950
which is going to receive the message state,

155
00:06:31.950 --> 00:06:34.440
which is I remind you a list of messages.

156
00:06:34.440 --> 00:06:37.230
We want to add the draft node,

157
00:06:37.230 --> 00:06:39.990
which is going to be this function over here.

158
00:06:39.990 --> 00:06:42.780
We want to add the execute tools nodes,

159
00:06:42.780 --> 00:06:47.010
which is going to be the execute tool node we created here.

160
00:06:47.010 --> 00:06:49.110
And lastly, we want the revised node

161
00:06:49.110 --> 00:06:51.570
to be this revised node we implement of here.

162
00:06:51.570 --> 00:06:53.790
Cool. So we finished with the nodes.

163
00:06:53.790 --> 00:06:56.400
So we have this object right over here,

164
00:06:56.400 --> 00:06:58.080
we have the execute tools nodes,

165
00:06:58.080 --> 00:06:59.910
and we have the reviser node here.

166
00:06:59.910 --> 00:07:02.430
So let's define the first responder here.

167
00:07:02.430 --> 00:07:04.457
The responder, let's define it as the first node,

168
00:07:04.457 --> 00:07:05.700
the draft node.

169
00:07:05.700 --> 00:07:09.750
So let me add an edge from the start of the graph to draft.

170
00:07:09.750 --> 00:07:11.940
So this is going to take the user input

171
00:07:11.940 --> 00:07:14.400
and execute now the reviser agent.

172
00:07:14.400 --> 00:07:16.061
And now we want to go,

173
00:07:16.061 --> 00:07:20.010
after we do that, we get the first response,

174
00:07:20.010 --> 00:07:22.620
we get a critique for it, and we get search results.

175
00:07:22.620 --> 00:07:23.790
So now we want to go

176
00:07:23.790 --> 00:07:26.400
and we want to execute the tools with the tools node.

177
00:07:26.400 --> 00:07:28.598
So let's define an edge from the draft node

178
00:07:28.598 --> 00:07:31.320
into the execute tools node.

179
00:07:31.320 --> 00:07:33.390
And now, after we execute the tools,

180
00:07:33.390 --> 00:07:36.300
we want to go to the reviser node.

181
00:07:36.300 --> 00:07:39.000
So let's create an edge from the execute tool node

182
00:07:39.000 --> 00:07:40.710
to the revised node.

183
00:07:40.710 --> 00:07:43.290
And lastly, after we finish the revised node,

184
00:07:43.290 --> 00:07:45.900
now we want to define the conditional branch.

185
00:07:45.900 --> 00:07:48.540
So let's go and add the conditional edge

186
00:07:48.540 --> 00:07:49.950
from the revised node.

187
00:07:49.950 --> 00:07:53.880
The logic is going to be the event look we have over here.

188
00:07:53.880 --> 00:07:56.670
And the third argument here is going to be a list

189
00:07:56.670 --> 00:08:00.720
that is going to tell LangGraph which nodes can go

190
00:08:00.720 --> 00:08:03.870
and execute after this conditional edge.

191
00:08:03.870 --> 00:08:07.140
So this is going to help when we visualize the graph here

192
00:08:07.140 --> 00:08:10.530
and here, we want to give it execute tools and end,

193
00:08:10.530 --> 00:08:12.437
which those values need to match the values

194
00:08:12.437 --> 00:08:14.640
that we return from here, from the literals.

195
00:08:14.640 --> 00:08:16.170
We can see right over here.

196
00:08:16.170 --> 00:08:18.780
Let's go now and compile the graph

197
00:08:18.780 --> 00:08:21.000
and let's go and print it.

198
00:08:21.000 --> 00:08:23.430
So I'm going to print it with Mermaid.

199
00:08:23.430 --> 00:08:27.237
So here, let me go and copy now the description of our graph

200
00:08:27.237 --> 00:08:29.430
and let's go and visualize it with Mermaid.

201
00:08:29.430 --> 00:08:32.700
So let me go to mermaid.live.

202
00:08:32.700 --> 00:08:34.440
So I'll pasted all of the code here.

203
00:08:34.440 --> 00:08:36.998
So this is the flow execution of our graph here.

204
00:08:36.998 --> 00:08:38.250
And notice here,

205
00:08:38.250 --> 00:08:40.740
this conditional edge from the revised node.

206
00:08:40.740 --> 00:08:43.200
After the revised node, we have the conditional step

207
00:08:43.200 --> 00:08:44.910
either to go and finish

208
00:08:44.910 --> 00:08:47.310
or to go and make another search query

209
00:08:47.310 --> 00:08:50.730
and start revising according to the new query.

210
00:08:50.730 --> 00:08:53.700
So let me go now back to the code here

211
00:08:53.700 --> 00:08:55.590
and let's go and invoke it.

212
00:08:55.590 --> 00:08:57.540
So in order to invoke her graph,

213
00:08:57.540 --> 00:08:59.940
we want to give it a list of messages.

214
00:08:59.940 --> 00:09:02.340
So I'm going to create here a dictionary

215
00:09:02.340 --> 00:09:05.220
and I want to put here the messages field here.

216
00:09:05.220 --> 00:09:07.320
And this is going to be a dictionary.

217
00:09:07.320 --> 00:09:09.510
So the role is going to be user,

218
00:09:09.510 --> 00:09:11.453
I remind you link chain is going to go

219
00:09:11.453 --> 00:09:13.860
and cast this into a human message

220
00:09:13.860 --> 00:09:15.420
because the role here is user,

221
00:09:15.420 --> 00:09:18.990
and the content is going to be right about AI-Powered SOC.

222
00:09:18.990 --> 00:09:20.850
autonomous soc problem domain,

223
00:09:20.850 --> 00:09:24.390
list startups that have raised capital on that.

224
00:09:24.390 --> 00:09:26.430
And after we go and execute it,

225
00:09:26.430 --> 00:09:29.430
we want to go and take last message.

226
00:09:29.430 --> 00:09:31.320
So let me run this in the bag

227
00:09:31.320 --> 00:09:34.920
and let me show you where we take our answer from.

228
00:09:34.920 --> 00:09:36.630
So this is now running

229
00:09:36.630 --> 00:09:39.480
and we can see we got here to this breakpoint

230
00:09:39.480 --> 00:09:41.370
and let's go and check the response.

231
00:09:41.370 --> 00:09:43.110
So if we'll go to res,

232
00:09:43.110 --> 00:09:46.110
we can see all of the messages that we have here

233
00:09:46.110 --> 00:09:48.600
and we're going to review everything in length meet.

234
00:09:48.600 --> 00:09:51.030
But I want to show you the last message

235
00:09:51.030 --> 00:09:53.400
is going to be an AI message.

236
00:09:53.400 --> 00:09:56.610
And this AI message is going to have a tool call.

237
00:09:56.610 --> 00:09:58.980
Let's go and look for the tool calls.

238
00:09:58.980 --> 00:10:00.810
Here we can see we have the tool calls.

239
00:10:00.810 --> 00:10:04.410
It's going to be a tool call where we're going to have

240
00:10:04.410 --> 00:10:05.967
the revised answer.

241
00:10:05.967 --> 00:10:09.780
And the answer here is going to be here in the args here.

242
00:10:09.780 --> 00:10:11.310
See, this is the answer.

243
00:10:11.310 --> 00:10:14.400
So let's go, and according to the structure,

244
00:10:14.400 --> 00:10:18.180
let's go now and let's format the response and print it.

245
00:10:18.180 --> 00:10:22.110
So I want to check if the last message is an AI message.

246
00:10:22.110 --> 00:10:25.650
And if this AI message has a tool call,

247
00:10:25.650 --> 00:10:27.480
I want to take the tool call,

248
00:10:27.480 --> 00:10:30.120
the first one because we're only going to have one,

249
00:10:30.120 --> 00:10:33.113
I want to go to the args and I want to go

250
00:10:33.113 --> 00:10:35.970
and check out the answer key here.

251
00:10:35.970 --> 00:10:38.790
And let's go and print also the rest of the messages.

252
00:10:38.790 --> 00:10:41.370
So let me now go and stop this execution.

253
00:10:41.370 --> 00:10:43.500
Let's go and run it again.

254
00:10:43.500 --> 00:10:44.790
And after we run it,

255
00:10:44.790 --> 00:10:47.700
I will show you in length meet the entire trace.

256
00:10:47.700 --> 00:10:48.990
So let me go now

257
00:10:48.990 --> 00:10:51.600
and let me run everything from the beginning

258
00:10:51.600 --> 00:10:54.240
and I want to show you the printed answer.

259
00:10:54.240 --> 00:10:57.390
And here we can see we got here an answer.

260
00:10:57.390 --> 00:10:59.400
Let me go to the top here.

261
00:10:59.400 --> 00:11:03.180
We can see AI Driven and Autonomous SOC, Problem Domain,

262
00:11:03.180 --> 00:11:05.204
Traditional SOC, face alert overload,

263
00:11:05.204 --> 00:11:08.790
manual triage delays and shortage of skilled analytics,

264
00:11:08.790 --> 00:11:10.800
AI powered SOC apply supervised,

265
00:11:10.800 --> 00:11:13.419
unsupervised machine learning and graph analytics

266
00:11:13.419 --> 00:11:16.244
to reduce false positives by up to 50%

267
00:11:16.244 --> 00:11:20.190
and automate 70% over routine alerts

268
00:11:20.190 --> 00:11:23.490
cutting investigation time by 70 to 90%.

269
00:11:23.490 --> 00:11:26.730
Autonomous SOC extend low risk response, quarantine emails,

270
00:11:26.730 --> 00:11:29.430
isolating endpoints and reconfiguring firewall,

271
00:11:29.430 --> 00:11:34.430
shrinking dwell time and MTTR two under five minutes

272
00:11:34.770 --> 00:11:36.570
in finance and healthcare.

273
00:11:36.570 --> 00:11:39.450
MTTR is Median Time To Response.

274
00:11:39.450 --> 00:11:41.910
And here we can see startups by maturity tier

275
00:11:41.910 --> 00:11:45.390
and the leaders which are Darktrace, Vectra,

276
00:11:45.390 --> 00:11:47.547
the Scale Up, Exabeam, Cybereason

277
00:11:47.547 --> 00:11:52.380
and the Innovators, Deep Instinct, SecBI and Blumira.

278
00:11:52.380 --> 00:11:53.213
All right.

279
00:11:53.213 --> 00:11:54.410
Here we have the list of messages.

