找回密码
 立即注册
首页 业界区 业界 MAF快速入门(14)快速集成A2A Agent

MAF快速入门(14)快速集成A2A Agent

懵径 2026-2-4 23:20:03
大家好,我是Edison。
最近我一直在跟着圣杰的《.NET+AI智能体开发进阶》课程学习MAF开发多智能体工作流,我强烈推荐你也上车跟我一起出发!
上一篇,我们学习了MAF中常见的多智能体编排模式。本篇,我们来了解下在MAF中如何快速集成A2A (Agent to Agent)。
1 A2A协议介绍

在之前的系列文章中我们其实已经介绍过A2A协议了,这里我们快速温习一下。A2A 即 Agent-to-Agent,翻译过来就是“智能代理之间的协议”,我们可以理解为它就是一个大模型Agent们用来“聊天”的“通用语言”。
1.png

A2A定义了一套清晰、标准的沟通方式,让Agent们可以顺畅地交流,让不同平台和框架下的Agent都能够说“同一种话”,实现无障碍的信息交换和协作。
更多关于A2A协议的内容:

  • 多Agent协作入门:基于A2A协议的Agent通信(上)
  • 多Agent协作入门:基于A2A协议的Agent通信(中)
2 将A2A Agent封装为Tool

在MAF集成A2A Agent,最主要的操作就是:将A2A Agent封装为一个Tool,这个Tool对应到MAF中就是一个AIFunction对象。
前面我们提到可以将MCP服务也封装为一个Tool(AIFunction)让Agent调用,这里A2A Agent也是一样的道理。
这样做的好处是:让MAF中的Agent像调用本地函数一样调用远程A2A Agent 或 MCP Server
下面的代码展示了在MAF中将A2A Card转换为Agent,然后再将Agent转换为AIFunction:
  1. ......
  2. var functionTools = new List();
  3. foreach (var endpoint in agentEndpoints)
  4. {
  5.     var resolver = new A2ACardResolver(new Uri(endpoint));
  6.     var card = await resolver.GetAgentCardAsync();
  7.     var agent = card.AsAIAgent(); // Convert A2A Agent to AIAgent instance
  8.     functionTools.AddRange(AgentFunctionHelper.CreateFunctionTools(agent, card));
  9. }
  10. ......
复制代码
下面是AgentFunctionHelper类的代码实现:
  1. public class AgentFunctionHelper
  2. {
  3.     public static IEnumerable CreateFunctionTools(AIAgent a2aAgent, AgentCard agentCard)
  4.     {
  5.         foreach (var skill in agentCard.Skills)
  6.         {
  7.             AIFunctionFactoryOptions options = new()
  8.             {
  9.                 Name = Sanitize(skill.Id),
  10.                 Description = $$"""
  11.                 {
  12.                     "description": "{{skill.Description}}",
  13.                     "tags": "[{{string.Join(", ", skill.Tags ?? [])}}]",
  14.                     "examples": "[{{string.Join(", ", skill.Examples ?? [])}}]",
  15.                     "inputModes": "[{{string.Join(", ", skill.InputModes ?? [])}}]",
  16.                     "outputModes": "[{{string.Join(", ", skill.OutputModes ?? [])}}]"
  17.                 }
  18.                 """,
  19.             };
  20.             yield return AIFunctionFactory.Create(RunAgentAsync, options);
  21.         }
  22.         async Task<string> RunAgentAsync(string input, CancellationToken cancellationToken)
  23.         {
  24.             var response = await a2aAgent.RunAsync(input, cancellationToken: cancellationToken).ConfigureAwait(false);
  25.             return response.Text;
  26.         }
  27.     }
  28.     private static readonly Regex InvalidNameCharsRegex = new Regex("[^0-9A-Za-z]+", RegexOptions.Compiled);
  29.     public staticstringSanitize(string name)
  30.     {
  31.         return InvalidNameCharsRegex.Replace(name, "_");
  32.     }
  33. }
复制代码
其中的CreateFunctionTools方法实现了将A2A Agent的所有公开技能转换为AIFunction工具。
而Sanitize方法则实现了函数名称的规范化,因为AIFunction的名称必须符合一定规范(仅限字母、数字和下划线),因此需要主动对技能名称进行规范化。
3 完整集成示例

这次我们还是使用上次文章中的案例,即一个旅游助手,它可以通过A2A协议调用多个Agent的技能。
2.png

我们需要创建四个.NET项目,其中:

  • 1个.NET控制台项目:主助手
  • 3个ASP.NET Web项目:天气智能体、酒店智能体、路线智能体
在VS中的项目结构如下:
3.png

本次案例我们希望实现主助手可以回答用户关于不同主题(景点,酒店,天气)的问题,它可以根据问题自主选择需要调用一个或多个Agent去获取必要的信息后进行整合优化后再回复用户。
3.1 天气Agent

添加NuGet包,后续A2A Agent项目都需要安装此包,不再赘述:
  1. A2A.AspNetCore
复制代码
创建一个 WeatherAgent类,定义其能力 和 AgentCard,这里我们需要公开一个AgentSkill即天气查询的能力:
[code]public class WeatherAgent{    public void Attach(ITaskManager taskManager)    {        taskManager.OnMessageReceived = QueryWeatherAsync;        taskManager.OnAgentCardQuery = GetAgentCardAsync;    }    private Task QueryWeatherAsync(MessageSendParams messageSendParams, CancellationToken cancellationToken)    {        if (cancellationToken.IsCancellationRequested)        {            return Task.FromCanceled(cancellationToken);        }        // Process the message        var messageText = messageSendParams.Message.Parts.OfType().First().Text;        // Create and return an artifact        var message = new AgentMessage()        {            Role = MessageRole.Agent,            MessageId = Guid.NewGuid().ToString(),            ContextId = messageSendParams.Message.ContextId,            Parts = [new TextPart() {                Text = $"""                    
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

2026-2-8 14:14:39

举报

懂技术并乐意极积无私分享的人越来越少。珍惜
7 天前

举报

懂技术并乐意极积无私分享的人越来越少。珍惜
您需要登录后才可以回帖 登录 | 立即注册