WEBVTT

1
00:00:01.220 --> 00:00:04.140
Hi, and welcome to AI in C#,

2
00:00:04.460 --> 00:00:07.200
where we go into the Microsoft Agent Framework,

3
00:00:07.700 --> 00:00:10.760
and more specifically in this video, looking at

4
00:00:10.760 --> 00:00:11.380
workflows.

5
00:00:12.640 --> 00:00:14.880
This is my first video in the workflows,

6
00:00:15.260 --> 00:00:17.700
so I will give you a short introduction,

7
00:00:18.180 --> 00:00:19.980
and then we're going to go in and

8
00:00:19.980 --> 00:00:24.080
see a sample of an agent-assisted workflow,

9
00:00:24.900 --> 00:00:27.220
where we will be making some pizzas.

10
00:00:28.050 --> 00:00:31.860
So, but let's learn a bit about the

11
00:00:31.860 --> 00:00:35.780
concepts, and they have two main concepts in

12
00:00:35.780 --> 00:00:39.240
all of this, and that is executors and

13
00:00:39.240 --> 00:00:39.780
edges.

14
00:00:41.350 --> 00:00:46.660
So a workflow are simply just pieces of

15
00:00:46.660 --> 00:00:50.140
code that you want to run, stringed together

16
00:00:50.140 --> 00:00:51.980
in a flow.

17
00:00:52.800 --> 00:00:55.560
So the flow could be just from one

18
00:00:55.560 --> 00:00:58.040
box to another, it could be one box,

19
00:00:58.500 --> 00:01:02.340
but if something else, something go out, you

20
00:01:02.340 --> 00:01:06.620
can fan out, and then aggregate, fan in,

21
00:01:07.340 --> 00:01:13.740
and there's multiple different concepts in such workflows.

22
00:01:14.160 --> 00:01:16.340
If you know workflows in general, you know

23
00:01:16.340 --> 00:01:19.160
that there's a lot of different cases and

24
00:01:19.160 --> 00:01:20.020
stuff you can do.

25
00:01:20.780 --> 00:01:22.880
But what we are going to do is,

26
00:01:23.000 --> 00:01:26.120
we are going to build the executors, and

27
00:01:26.120 --> 00:01:27.820
we are going to define the edges on

28
00:01:27.820 --> 00:01:30.300
how these executors talk to each other.

29
00:01:32.240 --> 00:01:34.580
And in order to better understand it, I

30
00:01:34.580 --> 00:01:38.240
made a small sample, which we'll go to.

31
00:01:40.360 --> 00:01:44.000
And the smaller workflows are in general, the

32
00:01:44.000 --> 00:01:46.840
more contrived they are, but I've tried to

33
00:01:46.840 --> 00:01:49.680
make something that could be sort of realistic,

34
00:01:50.500 --> 00:01:52.380
and for that reason, it's also a little

35
00:01:52.380 --> 00:01:55.660
bigger to see in code, but it's more

36
00:01:55.660 --> 00:01:58.740
realistic compared to just having a workflow that

37
00:01:58.740 --> 00:02:01.240
went from one box to another, and then

38
00:02:01.240 --> 00:02:01.540
ended.

39
00:02:02.940 --> 00:02:05.000
So the idea is that we have a

40
00:02:05.000 --> 00:02:08.720
user that are hungry, and they, via a

41
00:02:08.720 --> 00:02:12.860
chatbot or some kind of input field, just

42
00:02:12.860 --> 00:02:13.920
ask for a pizza.

43
00:02:16.440 --> 00:02:20.340
And then we will put that order into

44
00:02:20.340 --> 00:02:23.460
a workflow, and the first thing we'll do

45
00:02:23.460 --> 00:02:25.920
is we'll have an order parser that will

46
00:02:25.920 --> 00:02:29.300
turn out what have the customer actually asked

47
00:02:29.300 --> 00:02:32.580
for, and turn that into something that are

48
00:02:32.580 --> 00:02:33.300
more structured.

49
00:02:35.380 --> 00:02:38.320
Then we will parse that structure that the

50
00:02:38.320 --> 00:02:41.740
AI will build here into a stock checker,

51
00:02:42.080 --> 00:02:44.340
which right now don't have any AI, but

52
00:02:44.340 --> 00:02:46.720
it could have, but it could also have

53
00:02:46.720 --> 00:02:52.360
tool calling to a real inventory management system,

54
00:02:52.620 --> 00:02:55.000
and what we have.

55
00:02:56.320 --> 00:02:59.100
But essentially, it's just a hard-coded thing

56
00:02:59.100 --> 00:03:01.540
that some stocks can be missing, and if

57
00:03:01.540 --> 00:03:04.800
it's missing, it should go and make a

58
00:03:04.800 --> 00:03:07.540
warning where we use an AI to generate

59
00:03:07.540 --> 00:03:10.700
some kind of message back to the user,

60
00:03:11.060 --> 00:03:13.580
and if they want to have some replacement

61
00:03:13.580 --> 00:03:14.840
of some of the stock.

62
00:03:16.300 --> 00:03:19.140
And if all stock is there, we of

63
00:03:19.140 --> 00:03:21.520
course have some success, and we can make

64
00:03:21.520 --> 00:03:21.920
the pizza.

65
00:03:23.420 --> 00:03:29.500
So this would be a fairly simple workflow,

66
00:03:29.820 --> 00:03:32.260
but it will also be an AI-assisted

67
00:03:32.260 --> 00:03:38.300
workflow, in that these two executors have some

68
00:03:38.300 --> 00:03:39.220
AI injected.

69
00:03:40.300 --> 00:03:42.980
But beyond that, we could have made this

70
00:03:42.980 --> 00:03:46.160
with any other workflow, NuGet package, if we

71
00:03:46.160 --> 00:03:48.160
wanted to, but given that it is here,

72
00:03:48.420 --> 00:03:50.360
we will of course use them together.

73
00:03:51.880 --> 00:03:55.100
So let's go into code and see all

74
00:03:55.100 --> 00:03:58.980
this in action, and we'll just simply take

75
00:03:58.980 --> 00:04:01.520
it line by line here, and then we

76
00:04:01.520 --> 00:04:03.160
will see it up and running.

77
00:04:04.920 --> 00:04:07.180
So first up, we have our configuration, just

78
00:04:07.180 --> 00:04:11.700
our setup of our agents, and we have

79
00:04:11.700 --> 00:04:14.980
made a small agent factory here, just to

80
00:04:14.980 --> 00:04:18.339
fill it out here, because we need two

81
00:04:18.339 --> 00:04:18.899
agents.

82
00:04:19.480 --> 00:04:25.560
One that is an order taker, and in

83
00:04:25.560 --> 00:04:28.120
this case, we're using structured output to get

84
00:04:28.120 --> 00:04:31.120
a pizza order, and the pizza order is

85
00:04:31.120 --> 00:04:34.780
just something that have a size, what toppings

86
00:04:34.780 --> 00:04:37.900
they want, and at some point, what kind

87
00:04:37.900 --> 00:04:39.840
of warnings are there to this order.

88
00:04:44.010 --> 00:04:48.350
So the agent here is just take whatever

89
00:04:48.350 --> 00:04:50.950
the customer asks for, and turn it into

90
00:04:50.950 --> 00:04:52.890
a pizza order, and that's the only thing

91
00:04:52.890 --> 00:04:53.710
it can do.

92
00:04:54.970 --> 00:04:58.930
The other one is, if there's any problems

93
00:04:58.930 --> 00:05:03.730
with the pizza, it should explain to the

94
00:05:03.730 --> 00:05:07.330
customer or to the user that their pizza

95
00:05:07.330 --> 00:05:10.670
order can't be met, so we don't give

96
00:05:10.670 --> 00:05:15.270
a stock answer, but a real answer from

97
00:05:15.270 --> 00:05:16.030
an agent.

98
00:05:16.950 --> 00:05:20.230
So nothing new here, we have done this

99
00:05:20.230 --> 00:05:23.410
all the other places we have gone through

100
00:05:23.410 --> 00:05:23.950
this code.

101
00:05:24.190 --> 00:05:27.270
I've just put it out into a separate

102
00:05:27.270 --> 00:05:32.170
class, so it doesn't fill up, and we

103
00:05:32.170 --> 00:05:34.830
don't get the full meaning of this.

104
00:05:37.260 --> 00:05:40.880
Next up, we have four executors, because as

105
00:05:40.880 --> 00:05:43.360
we saw in our thing here, we have

106
00:05:43.360 --> 00:05:45.460
one, two, three, four, so we need four

107
00:05:45.460 --> 00:05:46.020
of these.

108
00:05:48.580 --> 00:05:49.960
Could some of them have been together?

109
00:05:50.180 --> 00:05:51.120
Of course they could.

110
00:05:51.420 --> 00:05:53.760
Could everything have just been in one class

111
00:05:53.760 --> 00:05:54.580
with if statements?

112
00:05:54.580 --> 00:05:57.620
Yes, it could, but the idea is, of

113
00:05:57.620 --> 00:06:00.360
course, that you can make these executors.

114
00:06:00.800 --> 00:06:04.200
You can perhaps even make executors that can

115
00:06:04.200 --> 00:06:09.720
be reused across multiple workflows, and in general

116
00:06:09.720 --> 00:06:11.960
just that you don't need to string all

117
00:06:11.960 --> 00:06:12.520
this up.

118
00:06:14.820 --> 00:06:18.840
Beyond that, the workflows can be resumed and

119
00:06:18.840 --> 00:06:21.900
suspended, and have human in the loop, and

120
00:06:21.900 --> 00:06:23.820
be long running, and all kinds of things,

121
00:06:23.860 --> 00:06:25.500
but that will be for another video.

122
00:06:25.500 --> 00:06:27.400
For this one, we're just going to make

123
00:06:27.400 --> 00:06:28.240
a simple one.

124
00:06:30.270 --> 00:06:33.330
So let's go back to code, and see

125
00:06:33.330 --> 00:06:34.990
our first executor.

126
00:06:35.550 --> 00:06:38.010
So our first executor is an order parser,

127
00:06:38.430 --> 00:06:40.690
and as we can see, it gets the

128
00:06:40.690 --> 00:06:42.210
order taker agent in.

129
00:06:44.120 --> 00:06:46.890
And if we look at an executor, the

130
00:06:46.890 --> 00:06:51.010
way they work is you make a class,

131
00:06:51.770 --> 00:06:57.770
and you make it extend the reflection executor.

132
00:06:58.330 --> 00:07:02.110
They are all called reflection executor, so that's

133
00:07:02.110 --> 00:07:03.370
the only one at the moment.

134
00:07:04.530 --> 00:07:06.830
And it's of type this, and we give

135
00:07:06.830 --> 00:07:07.290
it a name.

136
00:07:09.150 --> 00:07:11.850
And then we need to tell what kind

137
00:07:11.850 --> 00:07:14.710
this executor, what should it do.

138
00:07:15.510 --> 00:07:18.370
Well, in our case, we wanted to handle

139
00:07:18.370 --> 00:07:22.350
a message, and that message would be that

140
00:07:22.350 --> 00:07:25.450
it has an input of string, meaning that

141
00:07:25.450 --> 00:07:28.630
the order from the user as a string,

142
00:07:29.210 --> 00:07:31.570
and the output should be the pizza order.

143
00:07:33.050 --> 00:07:36.310
And when we have this interface, we need

144
00:07:36.310 --> 00:07:38.530
to implement a handle async here.

145
00:07:39.050 --> 00:07:42.350
We could have this interface multiple times, so

146
00:07:42.350 --> 00:07:44.850
it could have been that it was in

147
00:07:44.850 --> 00:07:48.170
text, but it could also be an MP4

148
00:07:48.170 --> 00:07:56.070
file with the voice of the user, and

149
00:07:56.070 --> 00:07:57.710
we could parse that, and so on.

150
00:07:58.430 --> 00:08:02.350
So an executor can have multiple handles if

151
00:08:02.350 --> 00:08:06.250
need be, but in the above case, we'll

152
00:08:06.250 --> 00:08:07.210
just keep one.

153
00:08:08.150 --> 00:08:11.230
And here we just do normal agent work.

154
00:08:11.230 --> 00:08:16.450
We're going to use structured output to get

155
00:08:16.450 --> 00:08:19.670
a pizza order back, so we're essentially just

156
00:08:19.670 --> 00:08:21.430
taking the string and turning it into an

157
00:08:21.430 --> 00:08:21.770
object.

158
00:08:24.500 --> 00:08:26.420
We'll set a breakpoint here, so we can

159
00:08:26.420 --> 00:08:28.640
see that in a little while.

160
00:08:31.820 --> 00:08:35.580
Next up, we have our stock checker, so

161
00:08:35.580 --> 00:08:38.080
our stock checker is fairly simple.

162
00:08:38.220 --> 00:08:40.000
It's just going to take a pizza order

163
00:08:40.000 --> 00:08:42.820
in and return a pizza order out.

164
00:08:45.240 --> 00:08:48.420
And if we do that, we just get

165
00:08:48.420 --> 00:08:48.940
our order.

166
00:08:49.540 --> 00:08:52.700
We loop to all the different toppings that

167
00:08:52.700 --> 00:08:57.120
the previous step extracted from us, and then

168
00:08:57.120 --> 00:08:59.140
we have hard-coded here right now that

169
00:08:59.140 --> 00:09:03.120
if it's mushrooms, one of the toppings, we

170
00:09:03.120 --> 00:09:04.780
simulate that that's out of stock.

171
00:09:05.040 --> 00:09:06.420
In real life, we will, of course, have

172
00:09:06.420 --> 00:09:09.340
had some code here, or maybe even an

173
00:09:09.340 --> 00:09:13.780
agent that could figure out if it said

174
00:09:13.780 --> 00:09:18.800
the word mushroom or mushrooms or some kind

175
00:09:18.800 --> 00:09:23.380
of shiitake mushroom or whatever, so an AI

176
00:09:23.380 --> 00:09:28.480
could help us find the right topping for

177
00:09:28.480 --> 00:09:29.820
just based on text.

178
00:09:30.840 --> 00:09:33.500
But in this case, we're just simulating that

179
00:09:33.500 --> 00:09:36.420
if it's mushrooms we are out of, we

180
00:09:36.420 --> 00:09:39.020
will add a warning to our pizza order,

181
00:09:39.820 --> 00:09:41.880
or else we'll just write out that we

182
00:09:41.880 --> 00:09:45.800
are able to add that topping onto the

183
00:09:45.800 --> 00:09:47.320
pizza and reduce the stock.

184
00:09:49.680 --> 00:09:53.020
So we'll also set a breakpoint here when

185
00:09:53.020 --> 00:09:54.140
we get to that.

186
00:09:57.950 --> 00:10:01.530
Next we have the two end results, either

187
00:10:01.530 --> 00:10:04.930
a success, which is fairly simple, we'll just

188
00:10:04.930 --> 00:10:10.090
say pizza okay, or a warning where we

189
00:10:10.090 --> 00:10:14.010
give an agent, because we want to check

190
00:10:14.010 --> 00:10:17.090
the warning, get all the warning text out,

191
00:10:17.450 --> 00:10:22.110
and pass that into the agent that it

192
00:10:22.110 --> 00:10:24.270
needs to explain what we are out of

193
00:10:24.270 --> 00:10:25.490
and what they can do.

194
00:10:26.350 --> 00:10:28.550
And here we will probably send an email

195
00:10:28.550 --> 00:10:33.050
or an SMS message or whatever our system

196
00:10:33.050 --> 00:10:33.510
would do.

197
00:10:35.950 --> 00:10:42.280
So these are the four we have, but

198
00:10:42.280 --> 00:10:47.460
now we need to explain the edges.

199
00:10:48.000 --> 00:10:50.100
This one here is of course starting the

200
00:10:50.100 --> 00:10:54.020
workflow, but one, two, three edges.

201
00:10:56.380 --> 00:11:00.080
And the first edge is just passing along,

202
00:11:00.480 --> 00:11:02.620
so we are simply going in and building

203
00:11:02.620 --> 00:11:03.920
a workflow builder.

204
00:11:04.860 --> 00:11:07.480
And what we are telling the workflow builder

205
00:11:07.480 --> 00:11:10.360
is that the first executor should be the

206
00:11:10.360 --> 00:11:12.380
order parser, which we saw here.

207
00:11:15.260 --> 00:11:17.440
So that would always be the start of

208
00:11:17.440 --> 00:11:18.140
this workflow.

209
00:11:18.840 --> 00:11:22.080
And then we are telling it make an

210
00:11:22.080 --> 00:11:24.940
edge, meaning draw an arrow between these two

211
00:11:24.940 --> 00:11:28.720
boxes, from the order parser to the stock

212
00:11:28.720 --> 00:11:29.120
checker.

213
00:11:30.420 --> 00:11:33.960
And there, it is very important that we

214
00:11:33.960 --> 00:11:37.060
then see that this one had an output

215
00:11:37.060 --> 00:11:40.760
of a pizza order, while this had an

216
00:11:40.760 --> 00:11:42.160
input of a pizza order.

217
00:11:42.520 --> 00:11:45.040
If these don't fit, the workflow will not

218
00:11:45.040 --> 00:11:45.380
run.

219
00:11:46.360 --> 00:11:48.620
It will simply just stop at the first

220
00:11:48.620 --> 00:11:48.940
step.

221
00:11:51.850 --> 00:11:55.150
But again, a simple case here, we're just

222
00:11:55.150 --> 00:11:57.910
parsing along after one have finished at work,

223
00:11:58.330 --> 00:11:59.670
the second one will take over.

224
00:12:02.260 --> 00:12:05.980
And then, once we have the output of

225
00:12:05.980 --> 00:12:09.800
our stock checker that enhanced the order with

226
00:12:09.800 --> 00:12:13.360
warnings or not, we go in and add

227
00:12:13.360 --> 00:12:17.480
a switch edge, meaning we are going to

228
00:12:17.480 --> 00:12:19.760
branch into two different things.

229
00:12:21.380 --> 00:12:23.760
And the way we branch is we build

230
00:12:23.760 --> 00:12:26.520
an add switch, and we do a switch

231
00:12:26.520 --> 00:12:30.280
builder, where we add a case that says,

232
00:12:30.660 --> 00:12:34.800
if the warning is zero, then it's a

233
00:12:34.800 --> 00:12:35.220
success.

234
00:12:35.360 --> 00:12:37.740
If the warning is different from zero, then

235
00:12:37.740 --> 00:12:38.380
it's a warning.

236
00:12:40.380 --> 00:12:44.140
And that is actually everything to define our

237
00:12:44.140 --> 00:12:44.580
workflow.

238
00:12:46.080 --> 00:12:48.060
But you can imagine you could make a

239
00:12:48.060 --> 00:12:51.720
much more advanced workflow if you wanted to.

240
00:12:54.890 --> 00:12:58.620
And again, there is multiple steps here for

241
00:12:58.620 --> 00:13:04.140
various fan out, meaning take this one step

242
00:13:04.140 --> 00:13:08.000
and start these two steps, or fan in,

243
00:13:08.540 --> 00:13:12.820
take these two, three, four steps, and aggregate

244
00:13:12.820 --> 00:13:15.220
them into one step, and so on.

245
00:13:15.440 --> 00:13:18.120
But more on that in future videos.

246
00:13:19.520 --> 00:13:21.580
But for now, we're just going to build

247
00:13:21.580 --> 00:13:24.620
our workflow, and now we have the option

248
00:13:24.620 --> 00:13:25.360
to run it.

249
00:13:26.740 --> 00:13:28.640
And in order to run it, we, of

250
00:13:28.640 --> 00:13:29.480
course, need some input.

251
00:13:29.940 --> 00:13:31.740
And in our case, we've just hard-coded

252
00:13:31.740 --> 00:13:34.920
here, make a big pepperoni pizza with mushrooms

253
00:13:34.920 --> 00:13:35.680
and onions.

254
00:13:38.500 --> 00:13:40.300
And then we are going to use this

255
00:13:40.300 --> 00:13:45.100
in-process execution, which will go in and

256
00:13:45.100 --> 00:13:51.240
stream our workflow, meaning we can, on the

257
00:13:51.240 --> 00:13:55.360
fly, see that something happens, because workflows could

258
00:13:55.360 --> 00:13:57.380
be several hours, perhaps.

259
00:13:58.160 --> 00:14:01.360
So we can see live what is going

260
00:14:01.360 --> 00:14:01.720
on.

261
00:14:02.820 --> 00:14:05.320
We could also just have run it, and

262
00:14:05.320 --> 00:14:07.520
then we will first see the results at

263
00:14:07.520 --> 00:14:09.100
the very end of the workflow.

264
00:14:09.880 --> 00:14:15.220
But we're giving our in-process executor our

265
00:14:15.220 --> 00:14:19.240
workflow and our input, and we get a

266
00:14:19.240 --> 00:14:22.160
streaming run, which we can then watch here.

267
00:14:23.120 --> 00:14:25.200
And watch means we can get the various

268
00:14:25.200 --> 00:14:26.180
workflow events.

269
00:14:26.820 --> 00:14:29.180
So there's various events you can get.

270
00:14:30.220 --> 00:14:32.620
So, for example, this is every time an

271
00:14:32.620 --> 00:14:34.740
executor is done, but it could also be

272
00:14:34.740 --> 00:14:37.220
every time an executor starts, every time the

273
00:14:37.220 --> 00:14:38.280
workflow starts.

274
00:14:38.960 --> 00:14:44.460
And there can be groups inside workflows called

275
00:14:44.460 --> 00:14:45.840
super steps.

276
00:14:46.820 --> 00:14:49.180
But for now, we are just going to

277
00:14:49.180 --> 00:14:51.800
check every time something ends.

278
00:14:52.460 --> 00:14:54.980
We will just write it out as completed.

279
00:14:55.600 --> 00:14:58.640
The executors, by themselves, take care of the

280
00:14:58.640 --> 00:14:58.940
rest.

281
00:15:01.360 --> 00:15:05.310
So now I think we should just set

282
00:15:05.310 --> 00:15:07.730
a breakpoint and walk through it while we

283
00:15:07.730 --> 00:15:10.350
see the output.

284
00:15:11.430 --> 00:15:17.410
So I am running the wrong one.

285
00:15:17.570 --> 00:15:20.110
Let me quickly do this.

286
00:15:21.950 --> 00:15:23.670
And let's see it in action then.

287
00:15:27.120 --> 00:15:30.120
So we're getting our configuration, and we are

288
00:15:30.120 --> 00:15:32.980
building our executors.

289
00:15:32.980 --> 00:15:35.760
So they don't do anything at build time.

290
00:15:35.860 --> 00:15:38.240
They are just being marked up.

291
00:15:39.480 --> 00:15:41.500
Then we're going to make our edges and

292
00:15:41.500 --> 00:15:43.840
our switches, and we can also set some

293
00:15:43.840 --> 00:15:46.580
breakpoints in our switch so we can see

294
00:15:46.580 --> 00:15:50.340
that a little while.

295
00:15:51.840 --> 00:15:54.700
So now I'm going to start to run.

296
00:15:55.040 --> 00:15:57.180
And as we saw, we set a breakpoint

297
00:15:57.180 --> 00:15:58.800
in the pass order.

298
00:16:00.820 --> 00:16:04.180
So we set a breakpoint in the executor

299
00:16:04.180 --> 00:16:06.280
here, and we're going to set one in

300
00:16:06.280 --> 00:16:06.800
success.

301
00:16:07.200 --> 00:16:08.900
Not that we're going to read it because

302
00:16:08.900 --> 00:16:10.800
we are asking for mushrooms.

303
00:16:12.460 --> 00:16:14.400
And we're going to set one here.

304
00:16:18.050 --> 00:16:21.490
So whenever I start this, it now begins.

305
00:16:22.150 --> 00:16:23.850
And the first thing that happens is we

306
00:16:23.850 --> 00:16:26.590
hit the order parser, and the input was

307
00:16:26.590 --> 00:16:29.170
a string that just was make a big

308
00:16:29.170 --> 00:16:31.430
pepperoni pizza with mushroom and onions.

309
00:16:32.830 --> 00:16:34.430
And we are going to take that message

310
00:16:34.430 --> 00:16:37.370
and just use our agent in order to

311
00:16:37.370 --> 00:16:41.570
get our response back, which will be some

312
00:16:41.570 --> 00:16:47.410
JSON, in this case a large pizza with

313
00:16:47.410 --> 00:16:50.990
toppings pepperoni, mushrooms, and onions, and no warnings,

314
00:16:51.170 --> 00:16:52.670
of course, because we don't have any.

315
00:16:54.230 --> 00:16:57.430
And that is what this deserialize will do,

316
00:16:57.590 --> 00:16:59.570
so we actually have a real object.

317
00:17:00.170 --> 00:17:01.350
And that is the one we are going

318
00:17:01.350 --> 00:17:02.990
to give back to the system.

319
00:17:05.730 --> 00:17:08.950
So pressing F5, we now ended up in

320
00:17:08.950 --> 00:17:12.589
the second step, the check, the stock checker,

321
00:17:12.950 --> 00:17:18.190
and we have our object so we can

322
00:17:18.190 --> 00:17:19.770
work with that.

323
00:17:20.569 --> 00:17:24.130
And our first topping is pepperoni, which is

324
00:17:24.130 --> 00:17:24.730
just okay.

325
00:17:25.770 --> 00:17:27.510
So we'll write out that it's okay.

326
00:17:28.410 --> 00:17:31.590
The second topping is our mushrooms, which we'll

327
00:17:31.590 --> 00:17:32.810
simulate as out of stock.

328
00:17:35.970 --> 00:17:38.470
And then we had the onions, which was

329
00:17:38.470 --> 00:17:39.130
also okay.

330
00:17:40.350 --> 00:17:43.030
And then we're just going to return the

331
00:17:43.030 --> 00:17:45.530
message back because we manipulated it using the

332
00:17:45.530 --> 00:17:50.870
warnings And now we hit our switch with

333
00:17:50.870 --> 00:17:53.630
our case, and it will ask us, or

334
00:17:53.630 --> 00:17:56.250
it will check, hey, how many warnings are

335
00:17:56.250 --> 00:17:56.430
there?

336
00:17:56.590 --> 00:17:57.170
There's one.

337
00:17:57.710 --> 00:18:00.130
So we're not going to hit this step.

338
00:18:02.670 --> 00:18:03.350
Is this one?

339
00:18:03.550 --> 00:18:03.830
Yeah.

340
00:18:04.430 --> 00:18:04.910
Okay.

341
00:18:05.410 --> 00:18:07.650
So now we are actually going to hit

342
00:18:07.650 --> 00:18:12.730
our events if we press along, and we'll

343
00:18:12.730 --> 00:18:16.870
get our order, our message here, with our

344
00:18:16.870 --> 00:18:19.710
warning of out of ingredients mushrooms.

345
00:18:21.010 --> 00:18:23.210
We're going to make that into a string,

346
00:18:25.920 --> 00:18:29.820
so just out of ingredient mushrooms, and we

347
00:18:29.820 --> 00:18:33.060
will give that to the AI in order

348
00:18:33.060 --> 00:18:35.860
for it to make a nice response back.

349
00:18:35.860 --> 00:18:38.420
I'm sorry, but we can't fulfil the order,

350
00:18:38.720 --> 00:18:39.360
and so on.

351
00:18:40.440 --> 00:18:45.180
And we end up having the full workflow.

352
00:18:45.680 --> 00:18:46.360
We passed the order.

353
00:18:46.640 --> 00:18:47.300
It completed.

354
00:18:47.880 --> 00:18:49.180
We added pepperoni.

355
00:18:49.840 --> 00:18:52.040
We were out of stock with mushrooms, but

356
00:18:52.040 --> 00:18:53.320
we added the onions.

357
00:18:54.820 --> 00:18:56.300
We did stop.

358
00:18:56.460 --> 00:18:57.220
It completed.

359
00:18:57.680 --> 00:18:59.900
We couldn't fulfil the order, and we used

360
00:18:59.900 --> 00:19:05.300
an AI to write out our apology to

361
00:19:05.300 --> 00:19:05.800
the user.

362
00:19:07.460 --> 00:19:11.340
So that is actually everything there is to

363
00:19:11.340 --> 00:19:11.840
workflows.

364
00:19:12.340 --> 00:19:16.760
This is a workflow that are fairly small.

365
00:19:17.000 --> 00:19:20.840
I can imagine myself building lots of bigger

366
00:19:20.840 --> 00:19:23.900
and bigger stuff, and I can imagine myself

367
00:19:23.900 --> 00:19:28.040
building some generic executors that I can use

368
00:19:28.040 --> 00:19:35.080
across multiple workflows, like sending emails, checking values

369
00:19:35.080 --> 00:19:39.160
in various systems, and so on, because you

370
00:19:39.160 --> 00:19:40.940
can just put agents in them.

371
00:19:41.560 --> 00:19:44.820
So it's just a way of having a

372
00:19:44.820 --> 00:19:47.880
nice structure compared to trying a lot of

373
00:19:47.880 --> 00:19:50.680
if and else statements in there.

374
00:19:52.360 --> 00:19:55.360
I will, of course, make multiple other videos

375
00:19:55.360 --> 00:19:57.480
on fan in, fan out, and so on,

376
00:19:57.540 --> 00:20:00.300
but now you have the general idea on

377
00:20:00.300 --> 00:20:02.560
what a workflow is and how you build

378
00:20:02.560 --> 00:20:02.980
it up.

379
00:20:03.740 --> 00:20:06.800
So hopefully, it was beneficial, and see you

380
00:20:06.800 --> 00:20:07.320
in the next one.
