Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Il protocollo da agente a agente (A2A) consente la comunicazione standardizzata tra gli agenti, consentendo agli agenti compilati con framework e tecnologie diversi di comunicare senza problemi.
Che cos'è A2A?
A2A è un protocollo standardizzato che supporta:
- Individuazione agente tramite schede agente
- Comunicazione basata su messaggi tra agenti
- Processi agentici a lunga durata tramite attività
- Interoperabilità multipiattaforma tra diversi framework agente
Per altre informazioni, vedere la specifica del protocollo A2A.
La libreria Microsoft.Agents.AI.Hosting.A2A.AspNetCore fornisce l'integrazione di ASP.NET Core per esporre gli agenti tramite il protocollo A2A.
Pacchetti NuGet:
Example
Questo esempio minimo illustra come esporre un agente tramite A2A. L'esempio include dipendenze OpenAPI e Swagger per semplificare il test.
1. Creare un progetto API Web di base ASP.NET
Creare un nuovo progetto api Web core ASP.NET o usarne uno esistente.
2. Installare le dipendenze necessarie
Installare i pacchetti seguenti:
Eseguire i comandi seguenti nella directory del progetto per installare i pacchetti NuGet necessari:
# 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. Configurare la connessione OpenAI di Azure
L'applicazione richiede una connessione OpenAI di Azure. Configurare l'endpoint e il nome della distribuzione usando dotnet user-secrets o le variabili di ambiente.
È anche possibile modificare semplicemente , appsettings.jsonma non è consigliabile per le app distribuite nell'ambiente di produzione perché alcuni dei dati possono essere considerati segreti.
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. Aggiungere il codice a Program.cs
Sostituire il contenuto di Program.cs con il codice seguente ed eseguire l'applicazione:
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();
Test dell'agente
Dopo aver eseguito l'applicazione, è possibile testare l'agente A2A usando il file seguente .http o tramite l'interfaccia utente di Swagger.
Il formato di input è conforme alla specifica A2A. È possibile specificare i valori per:
-
messageId- Identificatore univoco per questo messaggio specifico. È possibile creare il proprio ID (ad esempio, un GUID) o impostarlo sunullper consentire all'agente di generarne uno automaticamente. -
contextId- Identificatore della conversazione. Specificare il proprio ID per avviare una nuova conversazione o continuare una esistente riutilizzando un oggetto precedentecontextId. L'agente manterrà la cronologia delle conversazioni per lo stessocontextId. Agent genererà anche uno per l'utente, se non ne viene fornito alcuno.
# 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"
}
}
Nota: sostituire {{baseAddress}} con l'endpoint server.
Questa richiesta restituisce la risposta JSON seguente:
{
"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 risposta include ( contextId identificatore della conversazione), messageId (identificatore del messaggio) e il contenuto effettivo dell'agente pirata.
Configurazione di AgentCard
AgentCard fornisce metadati sull'agente per l'individuazione e l'integrazione:
app.MapA2A(agent, "/a2a/my-agent", agentCard: new()
{
Name = "My Agent",
Description = "A helpful agent that assists with tasks.",
Version = "1.0",
});
È possibile accedere alla scheda agente inviando questa richiesta:
# Send A2A request to the pirate agent
GET {{baseAddress}}/a2a/pirate/v1/card
Nota: sostituire {{baseAddress}} con l'endpoint server.
Proprietà AgentCard
- Nome: nome visualizzato dell'agente
- Descrizione: breve descrizione dell'agente
- Versione: stringa di versione per l'agente
- URL: URL endpoint (assegnato automaticamente se non specificato)
- Funzionalità: metadati facoltativi relativi a streaming, notifiche push e altre funzionalità
Esposizione di più agenti
È possibile esporre più agenti in una singola applicazione, purché gli endpoint non si sovrappongano. Ecco un esempio:
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");
Il agent-framework-a2a pacchetto consente di connettersi e comunicare con agenti esterni conformi a A2A.
pip install agent-framework-a2a --pre
Connessione a un agente A2A
Usare A2AAgent per eseguire il wrapping di qualsiasi endpoint A2A remoto. L'agente risolve le funzionalità dell'agente remoto tramite AgentCard e gestisce tutti i dettagli del protocollo.
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())
Risposte in streaming
A2A supporta naturalmente lo streaming tramite eventi di Server-Sent: gli aggiornamenti arrivano in tempo reale man mano che funziona l'agente remoto:
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))")
Attività a lungo termine
Per impostazione predefinita, A2AAgent attende che l'agente remoto termini prima di restituire. Per le attività a esecuzione prolungata, impostare background=True per ottenere un token di continuazione che è possibile usare per eseguire il polling o ripetere la sottoscrizione in un secondo momento:
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
Usare un AuthInterceptor per gli endpoint A2A protetti:
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!")
Vedere anche
- Panoramica delle integrazioni
- Integrazione OpenAI
- Specifica del protocollo A2A
- Individuazione agenti