Kommentar
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Protokollet Agent-till-Agent (A2A) möjliggör standardiserad kommunikation mellan agenter som skapats med olika ramverk och tekniker. Den här sidan beskriver hur du exponerar Agent Framework-agenter som A2A-servrar.
Information om hur du identifierar och anropar en fjärransluten A2A-agent finns i A2A-agenttjänsten.
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 Microsoft Foundry
dotnet add package Azure.AI.Projects --prerelease
dotnet add package Azure.Identity
dotnet add package Microsoft.Agents.AI.Foundry --prerelease
# Swagger to test app
dotnet add package Microsoft.AspNetCore.OpenApi
dotnet add package Swashbuckle.AspNetCore
3. Konfigurera Microsoft Foundry-anslutning
Programmet kräver en Microsoft Foundry-projektanslutning. 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.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;
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 AIProjectClient(
new Uri(endpoint),
new DefaultAzureCredential())
.GetProjectOpenAIClient()
.GetProjectResponsesClient()
.AsIChatClient(deploymentName);
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();
Varning
DefaultAzureCredential är praktiskt för utveckling men kräver noggrant övervägande i produktion. I produktion bör du överväga att använda en specifik autentiseringsuppgift (t.ex. ManagedIdentityCredential) för att undvika problem med svarstid, oavsiktlig avsökning av autentiseringsuppgifter och potentiella säkerhetsrisker från reservmekanismer.
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å attnullagenten 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 tidigarecontextId. Agenten behåller konversationshistoriken för sammacontextId. 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");
Paketet agent-framework-a2a exponerar en Agent Framework-agent över A2A-protokollet.
pip install agent-framework-a2a --pre
Testa en säker slutpunkt
Använd en AuthInterceptor i en testklient för att verifiera en säker A2A-slutpunkt:
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!")
Exponera en Agent Framework-agent över A2A
Paketet agent-framework-a2a tillhandahåller en fördefinierad A2AExecutor som anpassar valfri Agent Framework-agent till A2A-serversidesprotokollet. Den kör agenten, mappar utdatainnehåll som stöds till A2A-händelser och artefakter och hanterar uppdateringar av aktivitetsstatus via den officiella a2a-sdk.
Din applikation sätter samman den omkringliggande A2A SDK-servern: agentkortet, DefaultRequestHandler, uppgiftslagret, rutter eller applikationsbyggaren, autentisering och driftsättning. En jämförelse med appägda adaptrar och fristående konverteringshjälpare i agent-framework-hosting-a2a, se Självhosta A2A-agenter.
import uvicorn
from a2a.server.request_handlers import DefaultRequestHandler
from a2a.server.routes import create_agent_card_routes, create_jsonrpc_routes
from a2a.server.tasks import InMemoryTaskStore
from a2a.types import AgentCapabilities, AgentCard, AgentInterface, AgentSkill
from agent_framework import Agent
from agent_framework.a2a import A2AExecutor
from agent_framework.openai import OpenAIChatClient
from starlette.applications import Starlette
flight_skill = AgentSkill(
id="Flight_Booking",
name="Flight Booking",
description="Search and book flights across Europe.",
tags=["flights", "travel", "europe"],
examples=[],
)
public_agent_card = AgentCard(
name="Europe Travel Agent",
description="Helps users search and book flights and hotels across Europe.",
version="1.0.0",
default_input_modes=["text"],
default_output_modes=["text"],
capabilities=AgentCapabilities(streaming=True),
supported_interfaces=[
AgentInterface(url="http://localhost:9999/", protocol_binding="JSONRPC"),
],
skills=[flight_skill],
)
agent = Agent(
client=OpenAIChatClient(),
name="Europe Travel Agent",
instructions="You are a helpful Europe Travel Agent.",
)
request_handler = DefaultRequestHandler(
agent_executor=A2AExecutor(agent, stream=True),
task_store=InMemoryTaskStore(),
agent_card=public_agent_card,
)
server = Starlette(
routes=[
*create_agent_card_routes(public_agent_card),
*create_jsonrpc_routes(request_handler, "/"),
]
)
uvicorn.run(server, host="0.0.0.0", port=9999)
A2AExecutor strömmar agentuppdateringar som A2A-artefakter när den underliggande agenten stöder strömning och vidarebefordrar A2A context_id som agentsessionens session_id. Du kan underklassera A2AExecutor och åsidosätta handle_events metoden för att implementera anpassade transformeringar från agentens utdataformat till A2A-protokollhändelser.
A2A-protokoll
Go Agent Framework stöder värdtjänster för Agent Framework-agenter via A2A-protokollet (Agent-till-Agent) med provider/a2aprovider paketet och de officiella A2A Go-serverhantarna.
Installera Agent Framework- och A2A-paketen i din Go-modul:
go get github.com/microsoft/agent-framework-go
go get github.com/a2aproject/a2a-go/v2
Var värd för en agent via A2A
Skapa eller återanvända en Agent Framework-agent, beskriv den med ett A2A-agentkort och exponera den via en av A2A-transportbindningarna. I det här exemplet kan hostAgent vara valfritt Agent Framework *agent.Agent; servern har en JSON-RPC-slutpunkt vid / och tillhandahåller agentkortet på den välkända A2A-sökvägen.
import (
"fmt"
"net/http"
"github.com/a2aproject/a2a-go/v2/a2a"
"github.com/a2aproject/a2a-go/v2/a2asrv"
"github.com/microsoft/agent-framework-go/provider/a2aprovider"
)
url := "http://localhost:5000"
card := &a2a.AgentCard{
Name: "InvoiceAgent",
Description: "Handles requests relating to invoices.",
Version: "1.0.0",
DefaultInputModes: []string{"text"},
DefaultOutputModes: []string{"text"},
Capabilities: a2a.AgentCapabilities{
Streaming: false,
},
SupportedInterfaces: []*a2a.AgentInterface{
a2a.NewAgentInterface(url, a2a.TransportProtocolJSONRPC),
},
}
mux := http.NewServeMux()
requestHandler := a2asrv.NewHandler(
a2aprovider.NewExecutor(hostAgent, a2aprovider.ExecutorConfig{}),
a2asrv.WithExtendedAgentCard(card),
)
mux.Handle("/", a2asrv.NewJSONRPCHandler(requestHandler))
mux.Handle(a2asrv.WellKnownAgentCardPath, a2asrv.NewStaticAgentCardHandler(card))
if err := http.ListenAndServe(":5000", mux); err != nil {
panic(fmt.Errorf("A2A server failed: %w", err))
}
Omslut samma begärandehanterare med a2asrv.NewRESTHandler när du vill exponera HTTP+JSON-transportbindningen. Ange ExecutorConfig.AllowBackgroundResponses till true om den värdbaserade agenten ska tillåtas att returnera A2A-uppgifter för långvarigt arbete.
Se även
- Översikt över integreringar
- A2A-agenttjänst
- OpenAI-integrering
- A2A-protokollspecifikation
- Agentupptäckt