Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
O protocolo Agente-para-Agente (A2A) permite a comunicação padronizada entre agentes construídos com diferentes estruturas e tecnologias. Esta página aborda a exposição de agentes do Agent Framework como servidores A2A.
Para descobrir e invocar um agente A2A remoto, consulte o serviço de agente A2A.
O que é A2A?
O A2A é um protocolo padronizado que suporta:
- Descoberta de agentes através de cartões de agente
- Comunicação baseada em mensagens entre agentes
- Processos agentivos de longa duração através de tarefas
- Interoperabilidade entre plataformas entre diferentes frameworks de agentes
Para mais informações, consulte a especificação do protocolo A2A.
A Microsoft.Agents.AI.Hosting.A2A.AspNetCore biblioteca fornece integração com o ASP.NET Core para expor agentes através do protocolo A2A.
Pacotes NuGet:
Example
Este exemplo mínimo mostra como expor um agente através de A2A. O exemplo inclui dependências do OpenAPI e do Swagger para simplificar os testes.
1. Criar um projeto ASP.NET Core Web API
Crie um novo projeto ASP.NET Core Web API ou use um já existente.
2. Instalar as dependências necessárias
Instale os seguintes pacotes:
Execute os seguintes comandos no diretório do seu projeto para instalar os pacotes NuGet necessários:
# 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. Configurar a ligação Microsoft Foundry
A aplicação requer uma ligação ao projeto Microsoft Foundry. Configura o endpoint e o nome da implementação usando dotnet user-secrets ou variáveis de ambiente.
Também podes simplesmente editar o appsettings.json, mas isso não é recomendado para as aplicações implementadas em produção, pois alguns dados podem ser considerados secretos.
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. Adicionar o código à Program.cs
Substitua o conteúdo de Program.cs pelo seguinte código e execute a aplicação:
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 é conveniente para o desenvolvimento, mas requer uma consideração cuidadosa na produção. Em produção, considere usar uma credencial específica (por exemplo, ManagedIdentityCredential) para evitar problemas de latência, sondagens não intencionais de credenciais e potenciais riscos de segurança provenientes de mecanismos de recurso.
Testar o Agente
Depois de a aplicação estar a correr, pode testar o agente A2A usando o ficheiro seguinte .http ou através da interface Swagger.
O formato de entrada cumpre a especificação A2A. Pode fornecer valores para:
-
messageId- Um identificador único para esta mensagem específica. Podes criar o teu próprio ID (por exemplo, um GUID) ou defini-lo paranullque o agente gere um automaticamente. -
contextId- O identificador da conversa. Forneça o seu próprio ID para iniciar uma nova conversa ou continue uma existente reutilizando uma anteriorcontextId. O agente irá manter o histórico de conversas para o mesmocontextId. O agente também gerará um para si, se não for fornecido nenhum.
# 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: Substitua {{baseAddress}} pelo endpoint do seu servidor.
Este pedido devolve a seguinte resposta JSON:
{
"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"
}
A resposta inclui o contextId (identificador da conversa), messageId (identificador da mensagem) e o conteúdo real do agente pirata.
Configuração do AgentCard
O AgentCard fornece metadados sobre o seu agente para descoberta e integração.
app.MapA2A(agent, "/a2a/my-agent", agentCard: new()
{
Name = "My Agent",
Description = "A helpful agent that assists with tasks.",
Version = "1.0",
});
Pode aceder ao cartão de agente enviando este pedido:
# Send A2A request to the pirate agent
GET {{baseAddress}}/a2a/pirate/v1/card
Nota: Substitua {{baseAddress}} pelo endpoint do seu servidor.
Propriedades AgentCard
- Nome: Nome de exibição do agente
- Descrição: Breve descrição do agente
- Versão: String de versão para o agente
- URL: URL do endpoint (atribuído automaticamente se não especificado)
- Capacidades: Metadados opcionais sobre streaming, notificações push e outras funcionalidades
Exposição de Múltiplos Agentes
Podes expor vários agentes numa única aplicação, desde que os seus endpoints não colidam. Eis um exemplo:
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");
O agent-framework-a2a pacote expõe um agente Agent Framework através do protocolo A2A.
pip install agent-framework-a2a --pre
Testar um endpoint seguro
Use um AuthInterceptor cliente dentro de um cliente de teste para verificar um endpoint A2A seguro:
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!")
Disponibilizar um agente do Agent Framework através de A2A
O pacote agent-framework-a2a fornece uma implementação predefinida A2AExecutor que adapta qualquer agente do Agent Framework ao protocolo A2A no lado do servidor. Executa o agente, mapeia o conteúdo de saída suportado para eventos e artefactos A2A e gere as atualizações do estado das tarefas através do a2a-sdk oficial.
A sua aplicação compõe o servidor A2A SDK subjacente: o cartão do agente, DefaultRequestHandler o repositório de tarefas, as rotas ou o construtor de aplicações, a autenticação e a disponibilização. Para comparar os adaptadores da própria aplicação e os auxiliares autónomos de conversão em agent-framework-hosting-a2a, veja Agentes A2A autoalojados.
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 transmite atualizações do agente como artefactos A2A quando o agente subjacente suporta transmissão em fluxo e propaga o context_id A2A como o session_id da sessão do agente. Pode criar uma subclasse de A2AExecutor e substituir o método handle_events para implementar transformações personalizadas do formato de saída do seu agente em eventos do protocolo A2A.
Protocolo A2A
O Go Agent Framework suporta o alojamento de agentes do Agent Framework através do protocolo Agent-to-Agent (A2A) com o provider/a2aprovider pacote e os gestores oficiais de servidores A2A Go.
Instala o Agent Framework e os pacotes A2A no teu módulo Go:
go get github.com/microsoft/agent-framework-go
go get github.com/a2aproject/a2a-go/v2
Alojar um agente via A2A
Crie ou reutilize um agente do Agent Framework, descreva-o com um cartão de agente A2A e exponha-o através de uma das ligações de transporte A2A. Neste exemplo, hostAgent é qualquer Agent Framework *agent.Agent; o servidor hospeda um endpoint JSON-RPC em / e serve a carta agente no conhecido caminho A2A.
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))
}
Envolve o mesmo processador de pedidos com a2asrv.NewRESTHandler quando quiseres expor a associação de transporte HTTP+JSON. Defina ExecutorConfig.AllowBackgroundResponses como true caso o agente hospedado deva poder retornar tarefas A2A para trabalho de longa duração.
Ver também
- Visão Geral das Integrações
- Serviço de agente A2A
- Integração OpenAI
- Especificação do Protocolo A2A
- Descoberta de Agentes