Dela via


A2A-integrering

A2A-protokollet (Agent-till-Agent) möjliggör standardiserad kommunikation mellan agenter, vilket gör det möjligt för agenter som skapats med olika ramverk och tekniker att kommunicera sömlöst.

Vad är A2A?

A2A är ett standardiserat protokoll som stöder:

  • Agentidentifiering via agentkort
  • Meddelandebaserad kommunikation mellan agenter
  • Långvariga agentprocesser genom uppgifter
  • Plattformsoberoende samverkan mellan olika agentramverk

Mer information finns i A2A-protokollspecifikationen.

Biblioteket Microsoft.Agents.AI.Hosting.A2A.AspNetCore tillhandahåller ASP.NET Core-integrering för att exponera dina agenter via A2A-protokollet.

NuGet-paket:

Example

Det här minimala exemplet visar hur du exponerar en agent via A2A. Exemplet innehåller OpenAPI- och Swagger-beroenden för att förenkla testningen.

1. Skapa ett ASP.NET Core Web API-projekt

Skapa ett nytt ASP.NET Core Web API-projekt eller använd ett befintligt.

2. Installera nödvändiga beroenden

Installera följande paket:

Kör följande kommandon i projektkatalogen för att installera nödvändiga NuGet-paket:

# Hosting.A2A.AspNetCore for A2A protocol integration
dotnet add package Microsoft.Agents.AI.Hosting.A2A.AspNetCore --prerelease

# Libraries to connect to Azure OpenAI
dotnet add package Azure.AI.OpenAI --prerelease
dotnet add package Azure.Identity
dotnet add package Microsoft.Extensions.AI
dotnet add package Microsoft.Extensions.AI.OpenAI --prerelease

# Swagger to test app
dotnet add package Microsoft.AspNetCore.OpenApi
dotnet add package Swashbuckle.AspNetCore

3. Konfigurera Azure OpenAI-anslutning

Programmet kräver en Azure OpenAI-anslutning. Konfigurera slutpunkten och distributionsnamnet med hjälp av dotnet user-secrets eller miljövariabler. Du kan också redigera appsettings.json, men det rekommenderas inte för de appar som distribueras i produktion eftersom vissa data kan anses vara hemliga.

dotnet user-secrets set "AZURE_OPENAI_ENDPOINT" "https://<your-openai-resource>.openai.azure.com/"
dotnet user-secrets set "AZURE_OPENAI_DEPLOYMENT_NAME" "gpt-4o-mini"

4. Lägg till koden i Program.cs

Ersätt innehållet i Program.cs med följande kod och kör programmet:

using A2A.AspNetCore;
using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI.Hosting;
using Microsoft.Extensions.AI;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddOpenApi();
builder.Services.AddSwaggerGen();

string endpoint = builder.Configuration["AZURE_OPENAI_ENDPOINT"]
    ?? throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT is not set.");
string deploymentName = builder.Configuration["AZURE_OPENAI_DEPLOYMENT_NAME"]
    ?? throw new InvalidOperationException("AZURE_OPENAI_DEPLOYMENT_NAME is not set.");

// Register the chat client
IChatClient chatClient = new AzureOpenAIClient(
        new Uri(endpoint),
        new DefaultAzureCredential())
    .GetChatClient(deploymentName)
    .AsIChatClient();
builder.Services.AddSingleton(chatClient);

// Register an agent
var pirateAgent = builder.AddAIAgent("pirate", instructions: "You are a pirate. Speak like a pirate.");

var app = builder.Build();

app.MapOpenApi();
app.UseSwagger();
app.UseSwaggerUI();

// Expose the agent via A2A protocol. You can also customize the agentCard
app.MapA2A(pirateAgent, path: "/a2a/pirate", agentCard: new()
{
    Name = "Pirate Agent",
    Description = "An agent that speaks like a pirate.",
    Version = "1.0"
});

app.Run();

Testa agenten

När programmet körs kan du testa A2A-agenten med hjälp av följande .http fil eller via Swagger-användargränssnittet.

Indataformatet uppfyller A2A-specifikationen. Du kan ange värden för:

  • messageId – En unik identifierare för det här specifika meddelandet. Du kan skapa ett eget ID (t.ex. ett GUID) eller ställa in det på så att null agenten genererar ett automatiskt.
  • contextId - Konversationsidentifieraren. Ange ditt eget ID för att starta en ny konversation eller fortsätta en befintlig genom att återanvända ett tidigare contextId. Agenten behåller konversationshistoriken för samma contextId. Agenten genererar även en åt dig, om ingen tillhandahålls.
# Send A2A request to the pirate agent
POST {{baseAddress}}/a2a/pirate/v1/message:stream
Content-Type: application/json
{
  "message": {
    "kind": "message",
    "role": "user",
    "parts": [
      {
        "kind": "text",
        "text": "Hey pirate! Tell me where have you been",
        "metadata": {}
      }
    ],
	"messageId": null,
    "contextId": "foo"
  }
}

Obs! Ersätt {{baseAddress}} med serverslutpunkten.

Den här begäran returnerar följande JSON-svar:

{
	"kind": "message",
	"role": "agent",
	"parts": [
		{
			"kind": "text",
			"text": "Arrr, ye scallywag! Ye’ll have to tell me what yer after, or be I walkin’ the plank? 🏴‍☠️"
		}
	],
	"messageId": "chatcmpl-CXtJbisgIJCg36Z44U16etngjAKRk",
	"contextId": "foo"
}

Svaret innehåller (konversationsidentifierare contextId ), messageId (meddelandeidentifierare) och det faktiska innehållet från piratagenten.

AgentCard-konfiguration

AgentCard Innehåller metadata om din agent för identifiering och integrering:

app.MapA2A(agent, "/a2a/my-agent", agentCard: new()
{
    Name = "My Agent",
    Description = "A helpful agent that assists with tasks.",
    Version = "1.0",
});

Du kan komma åt agentkortet genom att skicka den här begäran:

# Send A2A request to the pirate agent
GET {{baseAddress}}/a2a/pirate/v1/card

Obs! Ersätt {{baseAddress}} med serverslutpunkten.

Egenskaper för AgentCard

  • Namn: Agentens visningsnamn
  • Beskrivning: Kort beskrivning av agenten
  • Version: Versionssträng för agenten
  • Url: Slutpunkts-URL (tilldelas automatiskt om den inte anges)
  • Funktioner: Valfria metadata om strömning, push-meddelanden och andra funktioner

Exponera flera agenter

Du kan exponera flera agenter i ett enda program, så länge deras slutpunkter inte kolliderar. Här är ett exempel:

var mathAgent = builder.AddAIAgent("math", instructions: "You are a math expert.");
var scienceAgent = builder.AddAIAgent("science", instructions: "You are a science expert.");

app.MapA2A(mathAgent, "/a2a/math");
app.MapA2A(scienceAgent, "/a2a/science");

Med agent-framework-a2a paketet kan du ansluta till och kommunicera med externa A2A-kompatibla agenter.

pip install agent-framework-a2a --pre

Ansluta till en A2A-agent

Använd A2AAgent för att omsluta en fjärransluten A2A-slutpunkt. Agenten löser fjärragentens funktioner via agentkortet och hanterar all protokollinformation.

import asyncio
import httpx
from a2a.client import A2ACardResolver
from agent_framework.a2a import A2AAgent

async def main():
    a2a_host = "https://your-a2a-agent.example.com"

    # 1. Discover the remote agent's capabilities
    async with httpx.AsyncClient(timeout=60.0) as http_client:
        resolver = A2ACardResolver(httpx_client=http_client, base_url=a2a_host)
        agent_card = await resolver.get_agent_card()
        print(f"Found agent: {agent_card.name}")

    # 2. Create an A2AAgent and send a message
    async with A2AAgent(
        name=agent_card.name,
        agent_card=agent_card,
        url=a2a_host,
    ) as agent:
        response = await agent.run("What are your capabilities?")
        for message in response.messages:
            print(message.text)

asyncio.run(main())

Direktuppspelningssvar

A2A stöder naturligtvis strömning via Server-Sent-händelser – uppdateringar kommer i realtid när fjärragenten fungerar:

async with A2AAgent(name="remote", url="https://a2a-agent.example.com") as agent:
    async with agent.run("Tell me about yourself", stream=True) as stream:
        async for update in stream:
            for content in update.contents:
                if content.text:
                    print(content.text, end="", flush=True)

        final = await stream.get_final_response()
        print(f"\n({len(final.messages)} message(s))")

Långvariga uppgifter

Som standard väntar A2AAgent på att fjärragenten ska slutföra innan det returneras. För långvariga uppgifter anger du background=True för att hämta en fortsättningstoken som du kan använda för att avsöka eller prenumerera igen senare:

async with A2AAgent(name="worker", url="https://a2a-agent.example.com") as agent:
    # Start a long-running task
    response = await agent.run("Process this large dataset", background=True)

    if response.continuation_token:
        # Poll for completion later
        result = await agent.poll_task(response.continuation_token)
        print(result)

Authentication

Använd en AuthInterceptor för skyddade A2A-slutpunkter:

from a2a.client.auth.interceptor import AuthInterceptor

class BearerAuth(AuthInterceptor):
    def __init__(self, token: str):
        self.token = token

    async def intercept(self, request):
        request.headers["Authorization"] = f"Bearer {self.token}"
        return request

async with A2AAgent(
    name="secure-agent",
    url="https://secure-a2a-agent.example.com",
    auth_interceptor=BearerAuth("your-token"),
) as agent:
    response = await agent.run("Hello!")

Se även

Nästa steg