WEBVTT

1
00:00:00.840 --> 00:00:03.780
Hi, and welcome to this AI in C# video

2
00:00:03.780 --> 00:00:05.580
on the Microsoft Agent Framework.

3
00:00:06.180 --> 00:00:08.760
Today we're going to look into the A2A

4
00:00:08.760 --> 00:00:12.020
protocol, which is something Google have made, where

5
00:00:12.020 --> 00:00:14.880
we have multiple agents talking to each other.

6
00:00:15.880 --> 00:00:18.320
Before we jump into the code, let's quickly

7
00:00:18.320 --> 00:00:20.500
talk a little about what this is.

8
00:00:22.060 --> 00:00:25.740
And if you are familiar with MCPs, they

9
00:00:25.740 --> 00:00:27.840
are very similar to...

10
00:00:27.840 --> 00:00:33.180
A2A is very similar to MCPs, but there

11
00:00:33.180 --> 00:00:35.820
is a bit more of intelligence in here.

12
00:00:37.220 --> 00:00:40.120
Also, if you have seen my video about

13
00:00:40.120 --> 00:00:43.300
an agent calling another agent as a tool,

14
00:00:43.520 --> 00:00:45.920
that would be beneficial in order to understand

15
00:00:45.920 --> 00:00:51.540
this, because that is essentially what's happening, but

16
00:00:51.540 --> 00:00:55.000
where the other agent is just remote.

17
00:00:55.800 --> 00:00:57.520
But what happens is you have a local

18
00:00:57.520 --> 00:01:00.900
app, and you know a URL for another

19
00:01:00.900 --> 00:01:01.620
agent.

20
00:01:03.060 --> 00:01:05.440
That is something called an agent card.

21
00:01:06.280 --> 00:01:09.680
So the remote agent have some kind of

22
00:01:09.680 --> 00:01:10.180
skills.

23
00:01:10.660 --> 00:01:12.860
It's normally tools, but it could also be

24
00:01:12.860 --> 00:01:15.920
that it's very good at something, or use

25
00:01:15.920 --> 00:01:18.360
a special model, or something like that.

26
00:01:19.460 --> 00:01:23.440
So it's just a normal agent, and it

27
00:01:23.440 --> 00:01:26.460
has these tools, and it shows it to,

28
00:01:26.880 --> 00:01:29.120
or exposes that to the local app as

29
00:01:29.120 --> 00:01:31.480
what is called an agent card, where it

30
00:01:31.480 --> 00:01:34.500
tells, I'm this, I'm good at this, you

31
00:01:34.500 --> 00:01:36.240
can use me for this, and so on.

32
00:01:36.900 --> 00:01:38.580
It's sort of like a business card.

33
00:01:39.100 --> 00:01:41.600
If you met a person where you could

34
00:01:41.600 --> 00:01:43.760
find information about what they can do, and

35
00:01:43.760 --> 00:01:46.180
how they can help, and what to talk

36
00:01:46.180 --> 00:01:46.520
with them.

37
00:01:47.120 --> 00:01:49.700
So a little like MCPs list tools.

38
00:01:51.740 --> 00:01:55.080
And then the local app can use these

39
00:01:55.080 --> 00:01:59.620
tools over here through this connection, as if

40
00:01:59.620 --> 00:02:02.810
they were connected directly to it itself.

41
00:02:04.100 --> 00:02:06.000
And what we're about to see in code

42
00:02:06.000 --> 00:02:08.300
is of course happening all on my machine,

43
00:02:08.720 --> 00:02:11.560
but the important thing to remember is that

44
00:02:11.560 --> 00:02:14.400
these two machines can be in different parts

45
00:02:14.400 --> 00:02:17.480
of the world, because they're just talking via

46
00:02:17.480 --> 00:02:18.240
a URL.

47
00:02:18.240 --> 00:02:21.840
So let's jump in and see it in

48
00:02:21.840 --> 00:02:22.140
action.

49
00:02:27.160 --> 00:02:30.740
So in the sample repo, we have agent

50
00:02:30.740 --> 00:02:32.640
to agent here, and we have a server

51
00:02:32.640 --> 00:02:33.540
and a client.

52
00:02:35.500 --> 00:02:38.600
And first I will just show it run,

53
00:02:38.980 --> 00:02:40.580
and then we will go through the code.

54
00:02:41.220 --> 00:02:42.940
And in order to run it, I need

55
00:02:42.940 --> 00:02:45.560
to run both systems, and for that reason

56
00:02:45.560 --> 00:02:48.680
I went into the setup configuration here, and

57
00:02:48.680 --> 00:02:51.900
set up that these two start at the

58
00:02:51.900 --> 00:02:52.460
same time.

59
00:02:55.140 --> 00:02:58.540
So if I run it, and arrange a

60
00:02:58.540 --> 00:03:00.420
bunch of screens here so we can see

61
00:03:00.420 --> 00:03:07.960
it, then we have the server here, and

62
00:03:07.960 --> 00:03:09.340
here we have the client.

63
00:03:11.260 --> 00:03:14.360
And if I ask it, in this case

64
00:03:14.360 --> 00:03:16.820
it knows about some files on my machine.

65
00:03:17.660 --> 00:03:21.160
So if we find the files up here,

66
00:03:21.820 --> 00:03:23.580
you can see there's 10 files in this

67
00:03:23.580 --> 00:03:28.140
folder, so I can ask how many files.

68
00:03:29.560 --> 00:03:32.700
These files are the same as you saw

69
00:03:32.700 --> 00:03:35.580
in my function calling scenario, and it can

70
00:03:35.580 --> 00:03:38.260
see there's 10 files.

71
00:03:38.260 --> 00:03:40.260
And we can go in and say delete

72
00:03:40.260 --> 00:03:49.570
the orange.txt file.

73
00:03:53.040 --> 00:03:54.960
If we do that, it removes it over

74
00:03:54.960 --> 00:03:55.240
here.

75
00:03:55.560 --> 00:03:58.280
So we are about to get information, but

76
00:03:58.280 --> 00:03:59.260
also actions.

77
00:04:00.160 --> 00:04:03.740
And over here, things are happening on behalf

78
00:04:03.740 --> 00:04:05.820
of this, and had this just been one

79
00:04:05.820 --> 00:04:10.520
agent with the skills, meaning had it been

80
00:04:12.210 --> 00:04:16.010
down here in features, our normal function calling,

81
00:04:16.810 --> 00:04:19.450
it would just have been a tool that

82
00:04:19.450 --> 00:04:22.930
we gave to a system, and that would

83
00:04:22.930 --> 00:04:23.370
be it.

84
00:04:24.250 --> 00:04:27.810
But now it's happening over a URL, and

85
00:04:27.810 --> 00:04:30.670
again, the important part is to think the

86
00:04:30.670 --> 00:04:33.830
server here could be in a completely different

87
00:04:33.830 --> 00:04:35.750
part of the world while the client would

88
00:04:35.750 --> 00:04:36.570
be on my machine.

89
00:04:37.340 --> 00:04:39.330
But let's see how it's implemented.

90
00:04:42.850 --> 00:04:45.590
So let's first look at the server, because

91
00:04:45.590 --> 00:04:48.110
without the server, we can't call the client.

92
00:04:51.300 --> 00:04:53.960
So first up, we are using a new

93
00:04:53.960 --> 00:04:57.620
NuGet packet we haven't used before, and we're

94
00:04:57.620 --> 00:05:00.760
using AI hosting A2A ASP.NET Core.

95
00:05:01.960 --> 00:05:03.920
And since this is a console app, we're

96
00:05:03.920 --> 00:05:07.220
still making it work as ASP.NET Core,

97
00:05:07.340 --> 00:05:09.740
so we are actually exposing a URL.

98
00:05:10.460 --> 00:05:15.540
So when I run it and show you

99
00:05:15.540 --> 00:05:17.880
the server, you can see we get this

100
00:05:17.880 --> 00:05:20.320
URL up here, just like if it had

101
00:05:20.320 --> 00:05:23.120
been a web API or whatever.

102
00:05:23.920 --> 00:05:26.000
And as well, we also get something called

103
00:05:26.000 --> 00:05:29.100
well-known agent card JSON.

104
00:05:31.610 --> 00:05:35.670
And the way it works is we go

105
00:05:35.670 --> 00:05:38.710
to our server, and we do the normal

106
00:05:38.710 --> 00:05:42.250
business part as we do with any agents

107
00:05:42.250 --> 00:05:43.150
we have done so far.

108
00:05:43.150 --> 00:05:45.470
We take the Azure OpenAI client.

109
00:05:46.130 --> 00:05:48.850
In this case, we are grabbing the different

110
00:05:48.850 --> 00:05:49.330
tools.

111
00:05:49.550 --> 00:05:51.630
Again, exactly the same as we did down

112
00:05:51.630 --> 00:05:54.110
here in the tool calling advanced, which there's

113
00:05:54.110 --> 00:05:55.070
a separate video on.

114
00:05:55.790 --> 00:05:58.230
And then we're just making an agent just

115
00:05:58.230 --> 00:06:02.530
like we do, and we give them these

116
00:06:02.530 --> 00:06:04.890
tools, and we set up a little function

117
00:06:04.890 --> 00:06:07.170
calling middleware so we can see that the

118
00:06:07.170 --> 00:06:08.570
tools are being called.

119
00:06:09.310 --> 00:06:11.810
You don't technically need tools here.

120
00:06:11.810 --> 00:06:13.490
It could be that it was very good

121
00:06:13.490 --> 00:06:15.470
at understanding something.

122
00:06:15.710 --> 00:06:17.810
It was hooked up to a vector store.

123
00:06:18.010 --> 00:06:21.570
It could be something that you would like

124
00:06:21.570 --> 00:06:24.410
to expose to the world through something more

125
00:06:24.410 --> 00:06:27.930
intelligent than just bringing raw data back.

126
00:06:30.620 --> 00:06:32.140
But then we begin with the agent part,

127
00:06:32.540 --> 00:06:35.180
and the agent part not really here.

128
00:06:35.340 --> 00:06:38.460
We're just setting up that ASP.NET Core

129
00:06:38.460 --> 00:06:40.300
can have a URL.

130
00:06:40.980 --> 00:06:43.360
And then we're building something called an agent

131
00:06:43.360 --> 00:06:43.720
card.

132
00:06:44.040 --> 00:06:45.740
Again, the agent's business card.

133
00:06:46.200 --> 00:06:48.500
So this is what is being exchanged between

134
00:06:48.500 --> 00:06:50.180
the two, the client and the server.

135
00:06:50.980 --> 00:06:54.320
So we tell, hey, I'm an agent.

136
00:06:54.540 --> 00:06:55.680
I'm called files agent.

137
00:06:55.940 --> 00:06:58.080
I can handle requests related to files.

138
00:06:58.860 --> 00:07:03.720
I'm version 1.0. My input modes are

139
00:07:03.720 --> 00:07:05.820
text, and my output modes are text.

140
00:07:06.820 --> 00:07:09.940
Again, this protocol has lots and lots of

141
00:07:09.940 --> 00:07:12.740
other features, authentication and so on, but we're

142
00:07:12.740 --> 00:07:14.920
just diving into the basics here.

143
00:07:15.360 --> 00:07:16.320
We're not streaming.

144
00:07:16.680 --> 00:07:19.500
We're just giving data fullback, and we're not

145
00:07:19.500 --> 00:07:23.540
sending any notifications because something can also be

146
00:07:23.540 --> 00:07:25.560
long running and such things like that.

147
00:07:26.880 --> 00:07:29.500
But we have one skill, which we call

148
00:07:29.500 --> 00:07:32.940
an agent skill, which is just that we

149
00:07:32.940 --> 00:07:37.940
are file experts, and we can do the

150
00:07:37.940 --> 00:07:39.020
questions about the files.

151
00:07:40.060 --> 00:07:44.120
We can give some tags so different agent

152
00:07:44.120 --> 00:07:46.840
cards can be categorised and stuff, and we

153
00:07:46.840 --> 00:07:50.920
give a small example on how we work.

154
00:07:52.040 --> 00:07:53.840
And then we give the URL that we

155
00:07:53.840 --> 00:07:54.840
need to be.

156
00:07:55.860 --> 00:07:59.060
And the tools themselves are fairly simple.

157
00:07:59.200 --> 00:08:02.980
It's just create folder, delete folder, just normal

158
00:08:02.980 --> 00:08:04.260
C-sharp code.

159
00:08:04.520 --> 00:08:06.840
And again, if you want to know about

160
00:08:06.840 --> 00:08:09.940
this, see the tool calling advanced for full

161
00:08:09.940 --> 00:08:10.340
details.

162
00:08:11.460 --> 00:08:13.460
The final thing we do is just like

163
00:08:13.460 --> 00:08:16.260
a map get, map post in a minimal

164
00:08:16.260 --> 00:08:16.700
API.

165
00:08:16.900 --> 00:08:19.240
We do a map A to A, and

166
00:08:19.240 --> 00:08:21.640
we tell this is the agent we are

167
00:08:21.640 --> 00:08:22.140
exposing.

168
00:08:22.740 --> 00:08:26.280
Here's the part we are exposing it, meaning

169
00:08:26.280 --> 00:08:27.060
just the root.

170
00:08:27.920 --> 00:08:31.100
Here is the agent card, and here is

171
00:08:31.100 --> 00:08:35.600
the well-known agent card, so it knows

172
00:08:35.600 --> 00:08:39.400
this information when it needs to work.

173
00:08:40.320 --> 00:08:42.299
And then we are just running, meaning we

174
00:08:42.299 --> 00:08:44.560
are starting the little mini web server in

175
00:08:44.560 --> 00:08:45.940
our console app here.

176
00:08:48.420 --> 00:08:53.120
On the client side, it is fairly simple.

177
00:08:54.220 --> 00:08:56.800
In here, we instead use the A to

178
00:08:56.800 --> 00:08:58.740
A instead of hosting A2A, because

179
00:08:58.740 --> 00:08:59.740
we are the consumer.

180
00:09:01.050 --> 00:09:05.470
And we are going to start, because I'm

181
00:09:05.470 --> 00:09:08.210
starting at the same time, I'm just waiting

182
00:09:08.210 --> 00:09:10.190
one second just to be sure that the

183
00:09:10.190 --> 00:09:14.070
server is ready to begin to be consumed

184
00:09:14.070 --> 00:09:14.750
by the client.

185
00:09:16.610 --> 00:09:19.370
Then we do something called an A to

186
00:09:19.370 --> 00:09:22.090
A card resolver where we take the URL.

187
00:09:22.610 --> 00:09:24.090
Again, this could be a remote URL.

188
00:09:25.270 --> 00:09:29.690
And we get that, and the agent framework

189
00:09:29.690 --> 00:09:32.350
just gives us and give me that as

190
00:09:32.350 --> 00:09:34.210
an AI agent, and we're done.

191
00:09:34.790 --> 00:09:36.550
Because then we have an AI agent, we

192
00:09:36.550 --> 00:09:40.210
could begin to use that as such.

193
00:09:40.830 --> 00:09:45.570
But what we are doing is we're giving

194
00:09:45.570 --> 00:09:48.290
it as a tool to an agent that

195
00:09:48.290 --> 00:09:50.010
we control over on our side.

196
00:09:51.070 --> 00:09:53.530
That agent is just like normal.

197
00:09:53.530 --> 00:10:00.610
We give it instructions like normal, and we

198
00:10:00.610 --> 00:10:02.010
just make a chat loop.

199
00:10:02.330 --> 00:10:05.690
So nothing over here is different other than

200
00:10:05.690 --> 00:10:09.210
this, which we then give as a tool.

201
00:10:09.790 --> 00:10:13.310
Beyond that, it's just normal agent framework like

202
00:10:13.310 --> 00:10:14.150
we normally do.

203
00:10:16.090 --> 00:10:18.010
So there's not much to this.

204
00:10:18.250 --> 00:10:21.550
It's just this exchange between the two that

205
00:10:21.550 --> 00:10:26.690
this running in one process can get an

206
00:10:26.690 --> 00:10:28.970
agent that can be used as skills in

207
00:10:28.970 --> 00:10:29.710
another process.

208
00:10:33.060 --> 00:10:35.500
So when we again look at it here,

209
00:10:35.940 --> 00:10:41.800
and the server, let me try to get

210
00:10:41.800 --> 00:10:44.480
them a little more side-by-side here,

211
00:10:47.640 --> 00:10:56.200
this and the files, then we could, for

212
00:10:56.200 --> 00:11:04.540
example, say group the files into folders

213
00:11:06.430 --> 00:11:12.060
based on their colour.

214
00:11:16.520 --> 00:11:18.160
So now it begins to work over here.

215
00:11:18.540 --> 00:11:20.460
It found the root folder.

216
00:11:21.180 --> 00:11:25.910
It found the content of each file and

217
00:11:25.910 --> 00:11:30.210
so on, and it wants us to confirm.

218
00:11:33.040 --> 00:11:34.020
We want to proceed.

219
00:11:34.020 --> 00:11:35.640
But that is just AI.

220
00:11:36.220 --> 00:11:38.280
Had it been in the same root, then

221
00:11:38.280 --> 00:11:39.940
the same thing would have happened.

222
00:11:40.780 --> 00:11:43.260
But right now, it's doing its work and

223
00:11:43.260 --> 00:11:47.420
putting in banana and lemon and pear into

224
00:11:47.420 --> 00:11:49.060
the yellow and so on.

225
00:11:49.400 --> 00:11:52.140
So it's just AI, and again, it's just

226
00:11:52.140 --> 00:11:56.320
as if we had one agent without two,

227
00:11:57.020 --> 00:11:59.140
but the cool thing is, of course, that

228
00:12:00.450 --> 00:12:03.990
these are in two different locations in the

229
00:12:03.990 --> 00:12:04.230
world.

230
00:12:04.230 --> 00:12:06.690
In my case, it's two different processes that

231
00:12:06.690 --> 00:12:08.930
talk with each other, but it could have

232
00:12:08.930 --> 00:12:12.190
been two different servers, one sitting in US

233
00:12:12.190 --> 00:12:14.410
and one sitting in Europe, talking to each

234
00:12:14.410 --> 00:12:14.690
other.

235
00:12:16.330 --> 00:12:19.630
And again, this sounds very much like MCP,

236
00:12:20.330 --> 00:12:22.430
but you have more.

237
00:12:23.690 --> 00:12:26.250
You could technically just make a tool called

238
00:12:26.250 --> 00:12:31.150
files tool in MCP and have an AI

239
00:12:31.150 --> 00:12:34.290
work behind the scenes, but it's not really

240
00:12:34.290 --> 00:12:35.150
meant for that.

241
00:12:35.350 --> 00:12:36.770
This is more meant for that.

242
00:12:37.030 --> 00:12:38.030
It's bigger things.

243
00:12:38.230 --> 00:12:41.230
It's more advanced things that are happening.

244
00:12:42.110 --> 00:12:43.950
So if you're using one or the other,

245
00:12:44.210 --> 00:12:49.110
I will probably use MCP more than A2A,

246
00:12:49.230 --> 00:12:51.730
but I can't see a world where A2A

247
00:12:51.730 --> 00:12:52.950
makes sense.

248
00:12:54.750 --> 00:12:56.390
So that is everything.

249
00:12:56.590 --> 00:12:57.770
Very simple to do.

250
00:12:58.650 --> 00:13:02.170
A little complex topic, but behind the scenes

251
00:13:02.170 --> 00:13:06.110
it's actually very simple that it's just these

252
00:13:06.110 --> 00:13:07.790
two lines of code that give us an

253
00:13:07.790 --> 00:13:09.210
agent that we can use as a tool.

254
00:13:10.270 --> 00:13:10.850
That's it.

255
00:13:11.230 --> 00:13:12.050
Thank you for attending.
