WEBVTT

1
00:00:00.000 --> 00:00:05.000
Hi, and welcome to this AI and C-Sharp video on the Microsoft Agent Framework.

2
00:00:05.000 --> 00:00:14.000
Today is going to be a bit different, because this is about some of the things I don't use in the Agent Framework,

3
00:00:14.000 --> 00:00:23.000
and particularly around the workflows, because I simply cannot see why they are needed.

4
00:00:24.000 --> 00:00:33.000
There might just be me, it might just be my scenarios, but every time I try to use a workflow,

5
00:00:33.000 --> 00:00:37.000
I end up writing some regular code that is much simpler.

6
00:00:37.000 --> 00:00:46.228
So, and it is a big part of the Agent Framework, at least the name says it's the agent part that is

7
00:00:46.228 --> 00:00:47.906
an important part,

8
00:00:48.000 --> 00:00:59.000
but we have this entire workflow, agentic workflows and so on, but I just don't see the value in them.

9
00:00:59.000 --> 00:01:06.000
And again, it might be me, I would very much like an open discussion in the comments about this,

10
00:01:06.000 --> 00:01:11.000
because I want to see the light, but I haven't.

11
00:01:11.000 --> 00:01:18.000
And for that reason, let me show you some of the arguments and some examples I have made.

12
00:01:18.000 --> 00:01:21.000
So, let's jump in.

13
00:01:21.000 --> 00:01:26.000
And I have made various videos on this.

14
00:01:26.000 --> 00:01:33.000
I've made sequential workflows, concurrent workflows, handover workflows.

15
00:01:33.000 --> 00:01:42.000
I've done a human-in-the-loop, I've made the AI-assisted, where we are more manual in our workflows.

16
00:01:42.000 --> 00:01:48.000
I've looked at group chat and simply just threw it away, because there was no value in it.

17
00:01:48.000 --> 00:01:55.000
And also, I've looked at all the samples from Microsoft themselves, and there's samples,

18
00:01:55.000 --> 00:02:01.000
but there's no real business value in my book.

19
00:02:01.000 --> 00:02:06.000
So, it's not like I don't want to do stuff in sequence,

20
00:02:06.000 --> 00:02:11.000
but it's more cumbersome to do it in a workflow like this.

21
00:02:11.000 --> 00:02:20.000
And I know there's things about being able to checkpoint it and resume it and all these kinds of things.

22
00:02:20.000 --> 00:02:25.000
Again, the kind of things I do don't take that long.

23
00:02:25.000 --> 00:02:29.000
If a workflow runs for like five minutes, it's a long...

24
00:02:29.000 --> 00:02:34.000
An AI task runs for five minutes, and probably so are yours.

25
00:02:34.000 --> 00:02:38.000
So, again, I'm not saying that you can't use workflows,

26
00:02:38.000 --> 00:02:44.000
but I've also heard from a lot of people that just want to use workflows for workflow's sake,

27
00:02:44.000 --> 00:02:47.000
and I think that's wrong to do.

28
00:02:47.000 --> 00:02:51.000
That's the main part of this video, because let's see a concurrent...

29
00:02:51.000 --> 00:02:54.000
No, let's start with sequential. This is the simplest one.

30
00:02:54.000 --> 00:03:02.000
And I made an example back in the day where we took a summary agent and a translation agent

31
00:03:02.000 --> 00:03:09.000
and took some legal text and then let it first summarize it and then translate it.

32
00:03:09.000 --> 00:03:12.000
So, putting those two agents in sequence.

33
00:03:12.000 --> 00:03:17.000
And we can do that, and we can see we'll use 62 lines of code,

34
00:03:17.000 --> 00:03:24.000
and we need to do this streaming and turn token and watch for the events in order to get them out.

35
00:03:24.000 --> 00:03:32.000
And this is an object, so we need to know to turn it into a list of chess matches and so on.

36
00:03:32.000 --> 00:03:42.000
So, it can certainly be done, but up here I have the exact same kind of code for sequential.

37
00:03:42.000 --> 00:03:47.000
And it's even taking up a bit extra here, because I need a namespace and stuff,

38
00:03:47.000 --> 00:03:50.000
because I put it into a subclass.

39
00:03:50.000 --> 00:03:56.000
But I do exactly the same up here. We can't save in setting up here.

40
00:03:56.000 --> 00:04:04.000
But then I just go in and take my summary agent, run async, get the response back, get my messages,

41
00:04:04.000 --> 00:04:12.000
and then take my translation and take the output of the summary response, and then we're done.

42
00:04:12.000 --> 00:04:14.000
This is exactly the same.

43
00:04:14.000 --> 00:04:22.000
So, this is essentially the code I'm replacing with this code here.

44
00:04:22.000 --> 00:04:25.000
There, this couldn't appear.

45
00:04:25.000 --> 00:04:34.000
It is no objects at all. It's just pure strongly typed all the way.

46
00:04:34.000 --> 00:04:36.000
Very, very simple to understand.

47
00:04:36.000 --> 00:04:42.000
So, if I were to ever do sequential, I would do this.

48
00:04:42.000 --> 00:04:45.000
Let's look at concurrent.

49
00:04:45.000 --> 00:04:52.000
So, concurrent is nice sometimes if you have enough tokens to do it.

50
00:04:52.000 --> 00:04:58.000
But in this case, it was just, again, a legal text with a legal agent and a spelling error,

51
00:04:58.000 --> 00:05:00.000
which would probably not run concurrent anyway.

52
00:05:00.000 --> 00:05:08.000
But if they could run concurrent, I have very few times where things can run concurrent like that

53
00:05:08.000 --> 00:05:13.000
because they need each other when they are in a kind of workflow.

54
00:05:13.000 --> 00:05:18.000
But again, we can do some of the same, and we get these, again,

55
00:05:18.000 --> 00:05:23.000
the in-process execution and stuff like that.

56
00:05:23.000 --> 00:05:32.000
And if we look up in a version of that, we have, again, exactly the same start.

57
00:05:32.000 --> 00:05:33.000
We can't change that.

58
00:05:33.000 --> 00:05:38.000
But then I will just use a task when all started to agents,

59
00:05:38.000 --> 00:05:42.000
and then when I get both back, just write out my for each.

60
00:05:42.000 --> 00:05:50.000
Give exactly the same results, and these three, four lines of code

61
00:05:50.000 --> 00:06:01.000
takes away all this very hard to understand and debug as well.

62
00:06:01.000 --> 00:06:04.000
So, why not just these three lines of code?

63
00:06:04.000 --> 00:06:08.000
Why put in an entire workflow for such simple things?

64
00:06:08.000 --> 00:06:12.000
And I know it's simple scenarios here, but even if it's more advanced,

65
00:06:12.000 --> 00:06:22.000
I would just put it out in various classes and have them run it in a simple flow.

66
00:06:22.000 --> 00:06:28.000
And of same situation, we get some three different agents,

67
00:06:28.000 --> 00:06:31.000
an intent agent, and a movie agent, and a music agent,

68
00:06:31.000 --> 00:06:35.000
and we need to have the intent agent pass it on to

69
00:06:35.000 --> 00:06:38.000
or hand it off to someone, the others.

70
00:06:38.000 --> 00:06:43.000
There we begin to make these with hands-off that this one can send it

71
00:06:43.000 --> 00:06:48.000
to these ones, and these ones can send it back to this one, and such things.

72
00:06:48.000 --> 00:06:54.000
And then we make our workflow run where we need to send the events

73
00:06:54.000 --> 00:07:02.000
and find the right person talking, and all these kinds of things.

74
00:07:02.000 --> 00:07:07.000
So, if we do that, we can either do it by tools,

75
00:07:07.000 --> 00:07:11.000
so we can just set up the same agents, but instead the intent agent

76
00:07:11.000 --> 00:07:19.000
also get two tools, which are the two other agents,

77
00:07:19.000 --> 00:07:23.000
and then we just ask, and then we are basically done.

78
00:07:23.000 --> 00:07:27.000
If we want to see what agent it calls, it's not necessary.

79
00:07:27.000 --> 00:07:31.000
We put in a little function called middleware, but beyond that,

80
00:07:31.000 --> 00:07:40.000
we are down to these few lines of code compared to all this.

81
00:07:40.000 --> 00:07:44.000
And I simply don't understand why people want to sit and write things like this

82
00:07:44.000 --> 00:07:46.000
because there's no reuse.

83
00:07:46.000 --> 00:07:48.000
That was one of my things.

84
00:07:48.000 --> 00:07:52.000
I thought in the beginning that it couldn't make things be more reusable.

85
00:07:52.000 --> 00:07:54.000
I've not seen the scenario.

86
00:07:54.000 --> 00:07:59.000
I've simply not seen the scenario, and again, code is very reusable

87
00:07:59.000 --> 00:08:06.000
in general in C Sharp in general.

88
00:08:06.000 --> 00:08:10.000
But this is how we could do it with just tools,

89
00:08:10.000 --> 00:08:12.000
but we could also do it with structured output

90
00:08:12.000 --> 00:08:15.000
in a much more similar fashion.

91
00:08:15.000 --> 00:08:19.000
We just make our agents again, and then we just use structured output

92
00:08:19.000 --> 00:08:21.000
to get out the type of question.

93
00:08:21.000 --> 00:08:24.000
Is it a movie question or a music question?

94
00:08:24.000 --> 00:08:30.000
Then a switch case on that and write out with full control,

95
00:08:30.000 --> 00:08:34.000
with nothing making our run async for us

96
00:08:34.000 --> 00:08:38.000
so we can not control anything or anything.

97
00:08:38.000 --> 00:08:41.000
So very simple to do.

98
00:08:41.000 --> 00:08:45.000
Human little loop. Let's have a look.

99
00:08:45.000 --> 00:08:49.000
For the human little loop, we need to make some agents,

100
00:08:49.000 --> 00:08:52.000
find the animal to guess.

101
00:08:52.000 --> 00:08:54.000
This is a small guessing game.

102
00:08:54.000 --> 00:08:58.000
We find an animal to guess and give some hints,

103
00:08:58.000 --> 00:09:00.000
and then we make our request port

104
00:09:00.000 --> 00:09:05.000
so we can get human little loop interventions,

105
00:09:05.000 --> 00:09:09.000
and we need our executor down here

106
00:09:09.000 --> 00:09:13.000
where it takes the input, which is the guess.

107
00:09:13.000 --> 00:09:18.000
If it's not the right one, then give a new hint,

108
00:09:18.000 --> 00:09:22.000
else say the game is over.

109
00:09:22.000 --> 00:09:26.000
And up here we need to go start our event

110
00:09:26.000 --> 00:09:29.000
and listen for all these various things.

111
00:09:29.000 --> 00:09:32.000
So it's possible again,

112
00:09:32.000 --> 00:09:36.000
but if we look in just normal code,

113
00:09:36.000 --> 00:09:39.000
we do exactly the same up here.

114
00:09:39.000 --> 00:09:43.000
But then we just make a while loop in this case

115
00:09:43.000 --> 00:09:47.000
or however you want to have your GUI, of course,

116
00:09:47.000 --> 00:09:50.000
and then we just take our guess.

117
00:09:50.000 --> 00:09:54.000
If the answer is right, break the loop,

118
00:09:54.000 --> 00:09:57.000
else give a new hint.

119
00:09:59.000 --> 00:10:03.000
We're saving lines of code,

120
00:10:03.000 --> 00:10:06.000
and it's much more simple to understand this code,

121
00:10:06.000 --> 00:10:09.000
in my book at least.

122
00:10:11.000 --> 00:10:16.000
And the most strong example is the pizza example.

123
00:10:16.000 --> 00:10:20.000
So if we look at the pizza example down here

124
00:10:20.000 --> 00:10:24.000
where we use the executors.

125
00:10:24.000 --> 00:10:29.000
So if we go in here,

126
00:10:29.000 --> 00:10:32.000
then we need to make an order parser,

127
00:10:32.000 --> 00:10:35.000
and the order parser gets an AI

128
00:10:35.000 --> 00:10:39.000
to do structured output on that.

129
00:10:39.000 --> 00:10:43.000
So in here we just do this,

130
00:10:43.000 --> 00:10:46.000
but we need to have all this ceremony

131
00:10:46.000 --> 00:10:50.000
above and below for almost nothing.

132
00:10:50.000 --> 00:10:54.000
The stock taker is just checking through

133
00:10:54.000 --> 00:10:58.000
the various toppings of the order

134
00:10:58.000 --> 00:11:02.000
and check if the mushroom is out of stock sample here

135
00:11:02.000 --> 00:11:05.000
and put it into a warning.

136
00:11:05.000 --> 00:11:11.000
And the success executor then says the pizza is okay,

137
00:11:11.000 --> 00:11:16.000
and the other one will say it is not okay

138
00:11:16.000 --> 00:11:18.000
and send a mail to the customer.

139
00:11:18.000 --> 00:11:20.000
And then we need to build the workflow,

140
00:11:20.000 --> 00:11:22.000
we need to build the edges,

141
00:11:22.000 --> 00:11:24.000
and we need to build the switch

142
00:11:24.000 --> 00:11:27.000
so it switches between the end success

143
00:11:27.000 --> 00:11:30.000
or the warning part of it.

144
00:11:30.000 --> 00:11:32.000
Have the workflow run

145
00:11:32.000 --> 00:11:37.000
and react to the various events in it.

146
00:11:39.000 --> 00:11:42.000
We look at that without a workflow.

147
00:11:42.000 --> 00:11:47.000
We simply just go and say the input.

148
00:11:47.000 --> 00:11:51.000
We take our order agent and give us back an order.

149
00:11:51.000 --> 00:11:57.000
We immediately loop over that and make some warnings.

150
00:11:57.000 --> 00:11:59.000
We check if there's warnings.

151
00:11:59.000 --> 00:12:01.000
If not, it says okay,

152
00:12:01.000 --> 00:12:04.000
else the other is not okay.

153
00:12:04.000 --> 00:12:07.000
Up here I'm using the same objects down here,

154
00:12:07.000 --> 00:12:10.000
so we'll still need to have the objects

155
00:12:10.000 --> 00:12:13.000
and the creation of the agents,

156
00:12:13.000 --> 00:12:16.000
but the flow of this is so much simpler

157
00:12:16.000 --> 00:12:20.000
in my book to understand.

158
00:12:20.000 --> 00:12:24.000
So then some of you might argue,

159
00:12:24.000 --> 00:12:29.000
okay, what if you get a very, very complex workflow?

160
00:12:29.000 --> 00:12:32.000
Well, then I would probably use a workflow engine

161
00:12:32.000 --> 00:12:39.000
like N8n, Logic Apps, Make,

162
00:12:39.000 --> 00:12:41.000
all these that are actually good for that

163
00:12:41.000 --> 00:12:43.000
with very complex setups,

164
00:12:43.000 --> 00:12:48.000
and then I will build small entries into an API

165
00:12:48.000 --> 00:12:50.000
that could help with the scenarios

166
00:12:50.000 --> 00:12:53.000
that the workflow engine couldn't do by itself,

167
00:12:53.000 --> 00:12:56.000
because then I have that someone else takes care

168
00:12:56.000 --> 00:12:57.000
of running the workflow,

169
00:12:57.000 --> 00:12:59.000
saving all the workflow data and so on.

170
00:12:59.000 --> 00:13:02.000
I don't want to store all that

171
00:13:02.000 --> 00:13:05.000
because even now we can do workflows

172
00:13:05.000 --> 00:13:07.000
and we can save how they went and so on.

173
00:13:07.000 --> 00:13:10.000
We still would need to build something

174
00:13:10.000 --> 00:13:14.000
that could show these workflows executions and so on.

175
00:13:14.000 --> 00:13:17.000
So there I would outsource it

176
00:13:17.000 --> 00:13:21.000
to a real workflow engine system.

177
00:13:21.000 --> 00:13:25.000
And then if I have the need,

178
00:13:25.000 --> 00:13:29.000
but again, this is simple code.

179
00:13:29.000 --> 00:13:31.000
Yes, there are some if statements.

180
00:13:31.000 --> 00:13:34.000
Ooh, that's scary. That's wrong.

181
00:13:34.000 --> 00:13:37.000
Or yes, it can break in the middle.

182
00:13:37.000 --> 00:13:39.000
Yes, the others can also break in the middle,

183
00:13:39.000 --> 00:13:43.000
and yes, there is some robustness in there to build in,

184
00:13:43.000 --> 00:13:47.000
but in reality, I don't see them happening.

185
00:13:47.000 --> 00:13:52.000
But that's for the comments of this video.

186
00:13:52.000 --> 00:13:54.000
Tell me how I'm wrong.

187
00:13:54.000 --> 00:13:56.000
Tell me why I'm wrong.

188
00:13:56.000 --> 00:14:00.000
Tell me what you use your workflows for

189
00:14:00.000 --> 00:14:03.000
because there is a reason

190
00:14:03.000 --> 00:14:07.000
why this YouTube series has not shown workflows so much

191
00:14:07.000 --> 00:14:10.000
because, again, every time I try to find,

192
00:14:10.000 --> 00:14:13.000
oh, yes, now I have my bank statement,

193
00:14:13.000 --> 00:14:15.000
which I made a video on,

194
00:14:15.000 --> 00:14:18.000
on how to balance my banking book.

195
00:14:18.000 --> 00:14:22.000
Yes, then I could use concurrent

196
00:14:22.000 --> 00:14:27.000
to both check for the dividend company

197
00:14:27.000 --> 00:14:35.000
and match the output or the PDF.

198
00:14:35.000 --> 00:14:37.000
But then suddenly I couldn't do that

199
00:14:37.000 --> 00:14:40.000
because I needed something from the dividend

200
00:14:40.000 --> 00:14:44.000
before I could actually find the PDF.

201
00:14:44.000 --> 00:14:48.000
And just every time there's something

202
00:14:48.000 --> 00:14:53.000
that turns out to be, yes, yeah, this cannot be concurrent

203
00:14:53.000 --> 00:14:55.000
or, yes, I'm using so many tokens

204
00:14:55.000 --> 00:15:00.000
that concurrent would just lead to rate limits

205
00:15:00.000 --> 00:15:03.000
or, yeah, I could do this,

206
00:15:03.000 --> 00:15:06.000
but it would add me 50 lines extra of code

207
00:15:06.000 --> 00:15:08.000
or complexity to look at it.

208
00:15:08.000 --> 00:15:16.000
So I can't see why workflows need...

209
00:15:16.000 --> 00:15:18.000
I understand why they are there.

210
00:15:18.000 --> 00:15:20.000
I can live with them being there,

211
00:15:20.000 --> 00:15:25.000
but please, sometimes you just need to write good code

212
00:15:25.000 --> 00:15:28.000
instead of trying to fit it into a workflow

213
00:15:28.000 --> 00:15:30.000
just because they're there.

214
00:15:30.000 --> 00:15:32.000
So that's my message,

215
00:15:32.000 --> 00:15:35.000
but also my question to you.

216
00:15:35.000 --> 00:15:39.000
Tell me why I'm wrong with this video.

217
00:15:39.000 --> 00:15:43.000
I really, really want to know so I can see the light,

218
00:15:43.000 --> 00:15:47.000
but I can't see it at the moment.

219
00:15:47.000 --> 00:15:49.000
But, yeah, different video.

220
00:15:49.000 --> 00:15:51.000
Hope it still is beneficial.

221
00:15:51.000 --> 00:15:56.000
Hope it will spark some discussion down in the comments

222
00:15:56.000 --> 00:16:01.000
and help you also understand that you don't need if I'm right,

223
00:16:01.000 --> 00:16:06.000
and it's an if, it's not a because I'm right, if I'm right,

224
00:16:06.000 --> 00:16:10.000
that you don't spend your time writing code

225
00:16:10.000 --> 00:16:13.000
that looks like this down here

226
00:16:13.000 --> 00:16:17.000
where it is so difficult to actually understand

227
00:16:17.000 --> 00:16:20.000
six months from now.

228
00:16:20.000 --> 00:16:22.000
But that's everything for this video.

229
00:16:22.000 --> 00:16:24.000
See you in the next one.

