中文字幕精品亚洲无线码二区,国产黄a三级三级三级看三级,亚洲七七久久桃花影院,丰满少妇被猛烈进入,国产小视频在线观看网站

多(duo)Agent協作入門:基于(yu)A2A協議的(de)Agent通信(下)

大家好,我是(shi)Edison。

上一篇,我們了解了A2A的三大角色和四大對象,還知道了A2A的基本工作流程。本篇就(jiu)來實踐(jian)一個典(dian)型的(de)A2A協議(yi)案例:Travel Planner。

Travel Planner介紹

本篇我們(men)要開發的一個(ge)小助手暫且叫它為“Travel Planner”,顧名思義,旅(lv)行(xing)規劃助手。它的場景(jing)工作流(liu)程如下圖所示:

image

讓我們通過上一篇的知識,區分一下他們的角色:

  • User 角色:用戶
  • Client 角色:主助手
  • Remoet Agent 角色:航班智(zhi)能體、酒店(dian)智(zhi)能體、旅游智(zhi)能體

在(zai)這(zhe)個流程中(zhong),主(zhu)助手Client負(fu)責(ze)接收用戶(hu)發來的請求,并通過(guo)A2A協議從遠(yuan)端(duan)Agent獲取必要的信(xin)息,最后整合這(zhe)些信(xin)息發給大模型整理輸(shu)出一個完整友好的旅游(you)規劃方案返(fan)回給用戶(hu)。

那么(me),這也就意味(wei)著我們需(xu)要創建(jian)四(si)個.NET項目,其中:

  • 1個.NET控制臺項目(mu):主(zhu)助手

  • 3個ASP.NET Web項(xiang)目(mu):航班智能(neng)體、酒店智能(neng)體、旅(lv)游(you)智能(neng)體

在VS解(jie)決方(fang)案中它們(men)是這樣子的:

image

那么(me),接下來(lai)我們就來(lai)一一實現,上干貨!

注意:為了示例Code簡單易懂,本案例并未涉及Task狀態的相關設置。關于Task狀態機相關案例,可以參考A2A .NET SDK的GitHub中的示例代碼。

航班Agent實現(xian)

添(tian)加NuGet包,后續不再(zai)贅(zhui)述:

A2A.AspNetCore "0.3.1-preview"

創建一個FlightAgent類,定義其能力(li) 和(he) AgentCard:

public class FlightAgent
{
    public void Attach(ITaskManager taskManager)
    {
        taskManager.OnMessageReceived = QueryFlightsAsync;
        taskManager.OnAgentCardQuery = GetAgentCardAsync;
    }
    private Task<A2AResponse> QueryFlightsAsync(MessageSendParams messageSendParams, CancellationToken cancellationToken)
    {
        if (cancellationToken.IsCancellationRequested)
        {
            return Task.FromCanceled<A2AResponse>(cancellationToken);
        }
        // Process the message
        var messageText = messageSendParams.Message.Parts.OfType<TextPart>().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 = $"Available Flilghts: CZ6250 - RMB380, MF1952 - RMB 390, GJ3156 - RMB410"
            }]
        };
        return Task.FromResult<A2AResponse>(message);
    }
    private Task<AgentCard> GetAgentCardAsync(string agentUrl, CancellationToken cancellationToken)
    {
        if (cancellationToken.IsCancellationRequested)
        {
            return Task.FromCanceled<AgentCard>(cancellationToken);
        }
        var capabilities = new AgentCapabilities()
        {
            Streaming = true,
            PushNotifications = false,
        };
        return Task.FromResult(new AgentCard()
        {
            Name = "Flight Agent",
            Description = "Agent which will query and return available flights to user.",
            Url = agentUrl,
            Version = "1.0.0",
            DefaultInputModes = ["text"],
            DefaultOutputModes = ["text"],
            Capabilities = capabilities,
            Skills = [],
        });
    }
}

這里說明一下(xia),我這里為了方便(bian)是(shi)直接返回了一個固定的輸出內容,但在實際應用中往(wang)往(wang)需要進行(xing)具(ju)體(ti)的業(ye)務邏(luo)輯處(chu)理 或 調用大模(mo)型進行(xing)處(chu)理。下(xia)面的幾個Agent也是(shi)類似(si)的情況,就不再贅(zhui)述。

然后,在Program.cs中進(jin)行注冊:

using A2A;
using A2A.AspNetCore;
using FlightAgentServer;
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
var taskManager = new TaskManager();
var agent = new FlightAgent();
agent.Attach(taskManager);
// Add JSON-RPC endpoint for A2A
app.MapA2A(taskManager, "/flights");
// Add well-known agent card endpoint for A2A
app.MapWellKnownAgentCard(taskManager, "/flights");
// Add HTTP endpoint for A2A
app.MapHttpA2A(taskManager, "/flights");

app.Run();

這里需要注意的是:為了能夠讓Client端能夠發現該Agent Card,請務必使用 MapWellKnownAgentCard 擴展方法進行注冊

酒店Agent實現

創建一個(ge)HotelAgent類,定義其能力(li) 和 AgentCard:

public class HotelAgent
{
    public void Attach(ITaskManager taskManager)
    {
        taskManager.OnMessageReceived = QueryHotelsAsync;
        taskManager.OnAgentCardQuery = GetAgentCardAsync;
    }
    private Task<A2AResponse> QueryHotelsAsync(MessageSendParams messageSendParams, CancellationToken cancellationToken)
    {
        if (cancellationToken.IsCancellationRequested)
        {
            return Task.FromCanceled<A2AResponse>(cancellationToken);
        }
        // Process the message
        var messageText = messageSendParams.Message.Parts.OfType<TextPart>().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 = $"Available Hotels: JI Hotel - RMB350, Holiday In - RMB 320, Hilton - RMB610"
            }]
        };
        return Task.FromResult<A2AResponse>(message);
    }
    private Task<AgentCard> GetAgentCardAsync(string agentUrl, CancellationToken cancellationToken)
    {
        if (cancellationToken.IsCancellationRequested)
        {
            return Task.FromCanceled<AgentCard>(cancellationToken);
        }
        var capabilities = new AgentCapabilities()
        {
            Streaming = true,
            PushNotifications = false,
        };
        return Task.FromResult(new AgentCard()
        {
            Name = "Hotel Agent",
            Description = "Agent which will query and return available hotels to user.",
            Url = agentUrl,
            Version = "1.0.0",
            DefaultInputModes = ["text"],
            DefaultOutputModes = ["text"],
            Capabilities = capabilities,
            Skills = [],
        });
    }
}

同樣,請參考航(hang)班Agent完成(cheng)Program.cs中的注冊。

規劃Agent實(shi)現(xian)

創建(jian)一個PlanAgent類,定義其能(neng)力 和 AgentCard:

public class PlanAgent
{
    public void Attach(ITaskManager taskManager)
    {
        taskManager.OnMessageReceived = QueryPlansAsync;
        taskManager.OnAgentCardQuery = GetAgentCardAsync;
    }
    private Task<A2AResponse> QueryPlansAsync(MessageSendParams messageSendParams, CancellationToken cancellationToken)
    {
        if (cancellationToken.IsCancellationRequested)
        {
            return Task.FromCanceled<A2AResponse>(cancellationToken);
        }
        // Process the message
        var messageText = messageSendParams.Message.Parts.OfType<TextPart>().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 = $"Available Plans: The Muslim Quarter - 2 Hours, The Terracotta Warriors - 3 Hours, The Huaqing Palace - 2 Hours"
            }]
        };
        return Task.FromResult<A2AResponse>(message);
    }
    private Task<AgentCard> GetAgentCardAsync(string agentUrl, CancellationToken cancellationToken)
    {
        if (cancellationToken.IsCancellationRequested)
        {
            return Task.FromCanceled<AgentCard>(cancellationToken);
        }
        var capabilities = new AgentCapabilities()
        {
            Streaming = true,
            PushNotifications = false,
        };
        return Task.FromResult(new AgentCard()
        {
            Name = "Plan Agent",
            Description = "Agent which will query and return travel plans to user.",
            Url = agentUrl,
            Version = "1.0.0",
            DefaultInputModes = ["text"],
            DefaultOutputModes = ["text"],
            Capabilities = capabilities,
            Skills = [],
        });
    }
}

主助手實現

這里(li)我(wo)們暫且(qie)命名為(wei)TravelPlannerClient,在該項(xiang)目(mu)中(zhong)我(wo)們需要用(yong)到Semantic Kernel進行與大(da)模型API的集成,因此(ci)我(wo)們先安裝一下相關NuGet包:

A2A 0.3.1-preivew
Microsoft.SemanticKernel.Agents.Core 1.65.0
Microsoft.SemanticKernel.Agents.OpenAI 1.65.0-preview

然后,假設我們有一個(ge)配置文件appsettings.json定義了大模型供應商的(de)信息:

{
  "LLM": {
    "BASE_URL": "//api.siliconflow.cn",
    "API_KEY": "******************************",
    "MODEL_ID": "Qwen/Qwen2.5-32B-Instruct"
  }
}

這里我們使用SiliconCloud提供的 Qwen2.5-32B-Instruct 模型,你可以(yi)通過這(zhe)個URL注(zhu)冊賬號: 獲取大量(liang)免費的Token來進行本次實驗。

最后,就是完整的Client端代碼實現,這里我分了(le)幾(ji)個主要的步(bu)驟寫在注釋(shi)中,方便(bian)你(ni)理解每個步(bu)驟是干什(shen)么的:

using A2A;
using Microsoft.Extensions.Configuration;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;
using TravelPlannerClient.Infrastructure;

Console.WriteLine("[Step1] Now loading the configuration...");
var config = new ConfigurationBuilder()
    .AddJsonFile($"appsettings.json", optional: false, reloadOnChange: true)
    .Build();
Console.WriteLine(
"[Step2] Now loading the chat client..."); var chattingApiConfiguration = new OpenAiConfiguration( config.GetSection("LLM:MODEL_ID").Value, config.GetSection("LLM:BASE_URL").Value, config.GetSection("LLM:API_KEY").Value); var openAiChattingClient = new HttpClient(new OpenAiHttpHandler(chattingApiConfiguration.EndPoint)); var kernel = Kernel.CreateBuilder() .AddOpenAIChatCompletion(chattingApiConfiguration.ModelId, chattingApiConfiguration.ApiKey, httpClient: openAiChattingClient) .Build();
Console.WriteLine(
"[Step3] Now loading the remote agent clients..."); // Remote Agent 1 : Flight Agent var cardResolver = new A2ACardResolver(new Uri("//localhost:7011/")); var agentCard = await cardResolver.GetAgentCardAsync(); var flightAgentClient = new A2AClient(new Uri(agentCard.Url)); // Remote Agent 2 : Hotel Agent cardResolver = new A2ACardResolver(new Uri("//localhost:7021/")); agentCard = await cardResolver.GetAgentCardAsync(); var hotelAgentClient = new A2AClient(new Uri(agentCard.Url)); // Remote Agent 3 : Plan Agent cardResolver = new A2ACardResolver(new Uri("//localhost:7031/")); agentCard = await cardResolver.GetAgentCardAsync(); var planAgentClient = new A2AClient(new Uri(agentCard.Url));
Console.WriteLine(
"[Step4] Welcome to use Travel Planner!\n"); var task = "Hello, I'd like to have a travelling in Xian, please give me one travel plan."; Console.WriteLine($"# User Message: \n{task}\n"); var userMessage = new AgentMessage { Role = MessageRole.User, Parts = [new TextPart { Text = task }] };
Console.WriteLine(
"[Step5] Now getting A2A Response from Remote Agents..."); var agentResponse = (AgentMessage)await flightAgentClient.SendMessageAsync(new MessageSendParams { Message = userMessage }); var flightOptions = ((TextPart)agentResponse.Parts[0]).Text; Console.WriteLine($"Flight-Agent Response: {flightOptions}"); agentResponse = (AgentMessage)await hotelAgentClient.SendMessageAsync(new MessageSendParams { Message = userMessage }); var hotelOptions = ((TextPart)agentResponse.Parts[0]).Text; Console.WriteLine($"Hotel-Agent Response: {hotelOptions}"); agentResponse = (AgentMessage)await planAgentClient.SendMessageAsync(new MessageSendParams { Message = userMessage }); var planOptions = ((TextPart)agentResponse.Parts[0]).Text; Console.WriteLine($"Plan-Agent Response: {planOptions}\n");
Console.WriteLine(
"[Step6] Now sumarizing the final response to user..."); var prompt = $""" You are a travel planner assistant. You have received the flight options, hotel options and travel plan from different agents. You need to summarize the information and give a final travel plan to user. Flight Options: {flightOptions} Hotel Options: {hotelOptions} Travel Plan: {planOptions} Please provide a concise and clear travel plan to the user. """; var chatCompletionService = kernel.GetRequiredService<IChatCompletionService>(); var response = await chatCompletionService.GetChatMessageContentAsync(prompt); Console.WriteLine($"Your Plan: {response.Content}");
Console.ReadKey();

在(zai)代碼(ma)中(zhong),我(wo)直接給出了用戶的請(qing)求:“I'd like to have a travelling in Xian, please give me one travel plan.”,即(ji)我(wo)想去(qu)西安旅游,給我(wo)一個旅游規劃。

最終的(de)執行結果如(ru)下所示,圖(tu)中用紅色(se)矩形框標注的(de)就是最終返回給用戶的(de)旅游規(gui)劃(hua):

image

可以看到,主助(zhu)手通過A2A協(xie)議分別從多(duo)個遠端Agent獲取了(le)(le)部分信(xin)息(xi),然后交由(you)大模(mo)型進行了(le)(le)整合優化,一個用戶(hu)友好的旅(lv)游規劃方(fang)案(an)就生(sheng)成好了(le)(le)。

小結

本文介紹了一個(ge)典型(xing)的A2A應用(yong)案例 - Travel Planner 旅游規劃助(zhu)手(shou),涉及(ji)一個(ge)Client 和 3個(ge)Remote Agent,是(shi)一個(ge)拿來練手(shou)增強理(li)解(jie)的好案例,希(xi)望對你有(you)所幫助(zhu)!

示例源碼

Github: 

參考資(zi)料(liao)

sing1ee,2025年完整指南:A2A協議 - AI智能體協作的新標準

黃佳,《

圣杰:《》(推薦學習!!!)

posted @ 2025-10-11 08:00  EdisonZhou  閱讀(317)  評論(1)    收藏  舉報