Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Le protocole Agent-to-Agent (A2A) permet une communication standardisée entre les agents créés avec différentes infrastructures et technologies. Cette page décrit l’exposition des agents Agent Framework en tant que serveurs A2A.
Pour découvrir et appeler un agent A2A distant, consultez le service de l’agent A2A.
Qu’est-ce qu’A2A ?
A2A est un protocole standardisé qui prend en charge :
- Découverte de l’agent par le biais de cartes d’agent
- Communication basée sur les messages entre les agents
- Processus agentiques de longue durée via des tâches
- Interopérabilité multiplateforme entre différents frameworks d’agent
Pour plus d’informations, consultez la spécification du protocole A2A.
La Microsoft.Agents.AI.Hosting.A2A.AspNetCore bibliothèque fournit une intégration d'ASP.NET Core pour exposer vos agents via le protocole A2A.
Packages NuGet :
Example
Cet exemple minimal montre comment exposer un agent via A2A. L’exemple inclut les dépendances OpenAPI et Swagger pour simplifier les tests.
1. Créer un projet d’API web core ASP.NET
Créez un projet d’API web core ASP.NET ou utilisez-en un existant.
2. Installer les dépendances requises
Installez les packages suivants :
Exécutez les commandes suivantes dans votre répertoire de projet pour installer les packages NuGet requis :
# 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. Configurer la connexion Microsoft Foundry
L’application nécessite une connexion de projet Microsoft Foundry. Configurez le point de terminaison et le nom du déploiement à l'aide de dotnet user-secrets ou de variables d'environnement.
Vous pouvez également simplement modifier le appsettings.json, mais ce n’est pas recommandé pour les applications déployées en production, car certaines données peuvent être considérées comme secrètes.
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. Ajoutez le code à Program.cs
Remplacez le contenu du Program.cs code suivant et exécutez l’application :
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();
Warning
DefaultAzureCredential est pratique pour le développement, mais nécessite une considération minutieuse en production. En production, envisagez d’utiliser des informations d’identification spécifiques (par exemple ManagedIdentityCredential) pour éviter les problèmes de latence, la détection involontaire des informations d’identification et les risques de sécurité potentiels liés aux mécanismes de secours.
Test de l’agent
Une fois l’application en cours d’exécution, vous pouvez tester l’agent A2A à l’aide du fichier suivant .http ou via l’interface utilisateur Swagger.
Le format d’entrée est conforme à la spécification A2A. Vous pouvez fournir des valeurs pour :
-
messageId- Identificateur unique pour ce message spécifique. Vous pouvez créer votre propre ID (par exemple, un GUID) ou le définir surnullpour permettre à l’agent d’en générer un automatiquement. -
contextId- Identificateur de conversation. Fournissez votre propre ID pour démarrer une nouvelle conversation ou poursuivre une conversation existante en réutilisant un précédentcontextId. L'agent conservera l'historique de conversation pour le mêmecontextId. L’agent en génère également un pour vous, si aucun n’est fourni.
# 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"
}
}
Remarque : Remplacez {{baseAddress}} par votre point de terminaison de serveur.
Cette requête retourne la réponse JSON suivante :
{
"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"
}
La réponse inclut l' contextId (identificateur de conversation), messageId l’identificateur de message et le contenu réel de l’agent pirate.
Configuration d’AgentCard
Les AgentCard fournissent des métadonnées sur votre agent pour la découverte et l'intégration.
app.MapA2A(agent, "/a2a/my-agent", agentCard: new()
{
Name = "My Agent",
Description = "A helpful agent that assists with tasks.",
Version = "1.0",
});
Vous pouvez accéder à la carte de l’agent en envoyant cette requête :
# Send A2A request to the pirate agent
GET {{baseAddress}}/a2a/pirate/v1/card
Remarque : Remplacez {{baseAddress}} par votre point de terminaison de serveur.
Propriétés AgentCard
- Nom affiché de l’agent
- Description : brève description de l’agent
- Version : chaîne de version pour l’agent
- URL : URL du point de terminaison (automatiquement attribuée si elle n’est pas spécifiée)
- Fonctionnalités : métadonnées facultatives sur la diffusion en continu, les notifications Push et d’autres fonctionnalités
Exposition de plusieurs agents
Vous pouvez exposer plusieurs agents dans une seule application, tant que leurs points de terminaison ne sont pas en collision. Prenons un exemple :
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");
Le agent-framework-a2a package expose un agent Agent Framework sur le protocole A2A.
pip install agent-framework-a2a --pre
Tester un point de terminaison sécurisé
Utilisez un AuthInterceptor client de test pour vérifier un point de terminaison A2A sécurisé :
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!")
Exposition d’un agent Agent Framework sur A2A
Le agent-framework-a2a package fournit une implémentation A2AExecutor préconfigurée qui adapte tout agent du framework Agent Framework au protocole A2A côté serveur. Il exécute l’agent, associe les contenus de sortie pris en charge aux événements et artefacts A2A, et gère les mises à jour de l’état des tâches via le a2a-sdk officiel.
Votre application assemble le serveur sdk A2A environnant : la carte de l’agent, le DefaultRequestHandlermagasin de tâches, les itinéraires ou le générateur d’applications, l’authentification et le déploiement. Pour une comparaison avec les adaptateurs propres à l’application et les utilitaires de conversion autonomes dans agent-framework-hosting-a2a, consultez les agents A2A auto-hébergés.
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 transmet les mises à jour de l’agent sous forme d’artefacts A2A lorsque l’agent sous-jacent prend en charge la diffusion en continu et propage le context_id A2A en tant que session_id de la session d’agent. Vous pouvez sous-classer A2AExecutor et remplacer la handle_events méthode pour implémenter des transformations personnalisées du format de sortie de votre agent vers les événements de protocole A2A.
Protocole A2A
Go Agent Framework prend en charge l’hébergement d’agents Agent Framework via le protocole Agent-to-Agent (A2A) avec le provider/a2aprovider package et les gestionnaires de serveurs A2A Go officiels.
Installez les packages Agent Framework et A2A dans votre module Go :
go get github.com/microsoft/agent-framework-go
go get github.com/a2aproject/a2a-go/v2
Héberger un agent via A2A
Créez ou réutilisez un agent Agent Framework, décrivez-le avec une carte d’agent A2A et exposez-le via l’une des liaisons de transport A2A. Dans cet exemple, hostAgent est n’importe quel framework *agent.Agentd’agent ; le serveur héberge un point de terminaison JSON-RPC sur / et sert la carte de l’agent sur le chemin A2A connu.
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))
}
Encapsulez le même gestionnaire de requêtes avec a2asrv.NewRESTHandler lorsque vous souhaitez exposer la liaison de transport HTTP+JSON. Défini ExecutorConfig.AllowBackgroundResponses sur la valeur true si l’agent hébergé doit être autorisé à retourner des tâches A2A pour un travail de longue durée.
Voir aussi
- Vue d’ensemble des intégrations
- Service de l’agent A2A
- Intégration d’OpenAI
- Spécification du protocole A2A
- Découverte de l’agent