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.
Permite A2AAgent que a sua aplicação se ligue a agentes remotos expostos através do protocolo Agent-to-Agent (A2A). Envolve qualquer endpoint compatível com A2A como padrão AIAgent, para que possa usar métodos familiares como RunAsync e RunStreamingAsync interagir com agentes remotos, independentemente da estrutura ou tecnologia com que foram construídos.
Introdução
Adicione o pacote NuGet necessário ao seu projeto:
dotnet add package Microsoft.Agents.AI.A2A --prerelease
Descoberta de Agentes
Antes de comunicar com um agente A2A remoto, precisa de o descobrir e criar uma AIAgent instância. O protocolo A2A define três estratégias de descoberta, cada uma suportada pelo Agent Framework.
Well-Known URI
Os agentes A2A podem tornar o seu Cartão de Agente detetável num caminho padronizado: https://{domain}/.well-known/agent-card.json. Use o A2ACardResolver para buscar o cartão e criar um agente numa única chamada:
using A2A;
using Microsoft.Agents.AI;
// Initialize a resolver pointing at the remote agent's host.
A2ACardResolver resolver = new(new Uri("https://a2a-agent.example.com"));
// Resolve the agent card and create an AIAgent in one step.
AIAgent agent = await resolver.GetAIAgentAsync();
// Use the agent.
Console.WriteLine(await agent.RunAsync("Hello!"));
Sugestão
GetAIAgentAsync também aceita um parâmetro opcional A2AClientOptions para seleção do protocolo.
Catalog-Based Descoberta
Em ambientes empresariais ou mercados públicos, os Cartões de Agente são frequentemente geridos por um registo central. Se já tiver um AgentCard obtido de tal registo, converta-o diretamente para um AIAgent:
using A2A;
using Microsoft.Agents.AI;
// Assume agentCard was retrieved from a registry or catalog.
AgentCard agentCard = await GetAgentCardFromRegistryAsync("travel-planner");
AIAgent agent = agentCard.AsAIAgent();
Console.WriteLine(await agent.RunAsync("Plan a trip to Paris."));
Configuração Direta
Para sistemas fortemente acoplados ou cenários de desenvolvimento onde o endpoint do agente é conhecido antecipadamente, crie um A2AClient direto e converta-o para um AIAgent:
using A2A;
using Microsoft.Agents.AI;
// Create a client pointing at the known agent endpoint.
A2AClient a2aClient = new(new Uri("https://a2a-agent.example.com"));
AIAgent agent = a2aClient.AsAIAgent(name: "my-agent", description: "A helpful assistant.");
Console.WriteLine(await agent.RunAsync("What can you help me with?"));
Seleção de Protocolo
Os agentes A2A podem expor múltiplas ligações de protocolo, como HTTP+JSON e JSON-RPC. Por defeito, HTTP+JSON é preferido ao JSON-RPC. Use A2AClientOptions.PreferredBindings para controlar explicitamente qual a ligação de protocolo utilizada:
Note
O agente A2A remoto deve estar disponível num endpoint que suporte a ligação de protocolo selecionada.
using A2A;
using Microsoft.Agents.AI;
A2ACardResolver agentCardResolver = new(new Uri("https://a2a-agent.example.com"));
AgentCard agentCard = await agentCardResolver.GetAgentCardAsync();
// Prefer HTTP+JSON protocol binding. For JSON-RPC, set PreferredBindings = [ProtocolBindingNames.JsonRpc]
A2AClientOptions options = new()
{
PreferredBindings = [ProtocolBindingNames.HttpJson]
};
AIAgent agent = agentCard.AsAIAgent(options: options);
Console.WriteLine(await agent.RunAsync("Tell me a joke about a pirate."));
Streaming
O A2A suporta respostas em streaming através da Server-Sent Events. Use RunStreamingAsync para receber atualizações em tempo real enquanto o agente remoto processa o pedido:
using A2A;
using Microsoft.Agents.AI;
A2ACardResolver resolver = new(new Uri("https://a2a-agent.example.com"));
AIAgent agent = await resolver.GetAIAgentAsync();
await foreach (var update in agent.RunStreamingAsync("Write a short story about a robot."))
{
if (!string.IsNullOrEmpty(update.Text))
{
Console.Write(update.Text);
}
}
Respostas de Contexto
Os agentes A2A suportam respostas em segundo plano para lidar com operações de longa duração. Quando um agente A2A remoto devolve uma tarefa em vez de uma mensagem imediata, o Agent Framework fornece um token de continuação que pode usar para consultar resultados ou reconectar-se a fluxos interrompidos.
Sondagem para Conclusão de Tarefa
Para cenários que não são streaming, use AllowBackgroundResponses para receber um token de continuação e uma sondagem até que a tarefa seja concluída:
using A2A;
using Microsoft.Agents.AI;
A2ACardResolver resolver = new(new Uri("https://a2a-agent.example.com"));
AIAgent agent = await resolver.GetAIAgentAsync();
AgentSession session = await agent.CreateSessionAsync();
// AllowBackgroundResponses must be true so the server returns immediately with a continuation token
// instead of blocking until the task is complete.
AgentRunOptions options = new() { AllowBackgroundResponses = true };
// Start the initial run with a long-running task.
AgentResponse response = await agent.RunAsync(
"Conduct a comprehensive analysis of quantum computing applications in cryptography.",
session,
options: options);
// Poll until the response is complete.
while (response.ContinuationToken is { } token)
{
// Wait before polling again.
await Task.Delay(TimeSpan.FromSeconds(2));
// Continue with the token.
response = await agent.RunAsync(session, options: new AgentRunOptions { ContinuationToken = token });
}
Console.WriteLine(response);
Reconexão do Curso de Água
Em cenários de streaming, cada atualização pode incluir um token de continuação. Se o fluxo for interrompido, use o token para reconectar e obter o fluxo de resposta desde o início:
using A2A;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
A2ACardResolver resolver = new(new Uri("https://a2a-agent.example.com"));
AIAgent agent = await resolver.GetAIAgentAsync();
AgentSession session = await agent.CreateSessionAsync();
ResponseContinuationToken? continuationToken = null;
await foreach (var update in agent.RunStreamingAsync(
"Conduct a comprehensive analysis of quantum computing applications in cryptography.",
session))
{
// Save the continuation token to reconnect later if the stream is interrupted.
// Continuation tokens are only returned for long-running tasks. If the A2A agent
// returns a message instead of a task, the continuation token will not be initialized.
if (update.ContinuationToken is { } token)
{
continuationToken = token;
}
}
// If the stream was interrupted and a continuation token was captured,
// reconnect to the response stream using the saved continuation token.
if (continuationToken is not null)
{
await foreach (var update in agent.RunStreamingAsync(
session,
options: new() { ContinuationToken = continuationToken }))
{
if (!string.IsNullOrEmpty(update.Text))
{
Console.WriteLine(update.Text);
}
}
}
Note
Os agentes A2A suportam a reconexão do fluxo (obtendo o mesmo fluxo de resposta desde o início), não a retomada do fluxo a partir de um ponto específico do fluxo.
Tools
A2AAgent é um wrapper ao nível de transporte em torno de um agente A2A remoto. As ferramentas que o agente remoto usa estão do lado remoto e são invisíveis ao teu código. Os tipos de ferramentas do Agent Framework (ferramentas funcionais, interpretador de código, pesquisa de ficheiros, MCP alojado/local, etc.) não estão configurados A2AAgent diretamente — para estender as capacidades do agente remoto, alterar a configuração do agente remoto.
Introdução
Instale o pacote A2A:
pip install agent-framework-a2a --pre
Inicialização
A2AAgent Pode ser inicializado de três formas, dependendo do quanto sabe sobre o agente remoto antecipadamente.
URL direta
Para desenvolvimento ou sistemas fortemente acoplados onde o ponto final é conhecido:
from agent_framework.a2a import A2AAgent
async with A2AAgent(name="remote", url="https://a2a-agent.example.com") as agent:
response = await agent.run("Hello!")
print(response.messages[0].text)
Quando apenas uma URL é fornecida, A2AAgent cria-se internamente um cartão de agente mínimo e liga-se usando JSON-RPC.
Cartão de agente
Se tiveres um AgentCard registo ou catálogo, passa-o diretamente:
from agent_framework.a2a import A2AAgent
async with A2AAgent(agent_card=agent_card) as agent:
response = await agent.run("Plan a trip to Paris.")
print(response.messages[0].text)
Quando um AgentCard é fornecido, A2AAgent incumprimento name e description do cartão. Negocia o transporte usando os cartões supported_interfaces.
Well-Known URI (A2ACardResolver)
Use A2ACardResolver a partir do a2a-sdk para descobrir o agente remoto no caminho padrão bem conhecido (/.well-known/agent.json):
import httpx
from a2a.client import A2ACardResolver
from agent_framework.a2a import A2AAgent
async with httpx.AsyncClient(timeout=60.0) as http_client:
resolver = A2ACardResolver(httpx_client=http_client, base_url="https://a2a-agent.example.com")
agent_card = await resolver.get_agent_card()
async with A2AAgent(agent_card=agent_card) as agent:
response = await agent.run("What can you help me with?")
print(response.messages[0].text)
Streaming
Use stream=True para receber atualizações em tempo real enquanto o agente remoto processa o pedido:
from agent_framework.a2a import A2AAgent
async with A2AAgent(name="remote", url="https://a2a-agent.example.com") as agent:
async with agent.run("Write a short story about a robot.", 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))")
Tarefas de Longa Duração
Por defeito, A2AAgent espera que o agente remoto termine antes de regressar. Para tarefas de longa duração, defina background=True para mostrar um token de continuação que pode usar para inquirir ou subscrever mais tarde:
from agent_framework.a2a import A2AAgent
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)
Também pode subscrever novamente o fluxo SSE em vez de fazer polling:
# Resubscribe to the task's event stream
response = await agent.run(continuation_token=response.continuation_token)
Identidade de Conversa (context_id)
Quando chama A2AAgent.run() com um AgentSession, o agente determina automaticamente o A2A context_id de session.service_session_id se a mensagem que está a ser enviada ainda não incluir um. Isto permite-lhe manter a continuidade da conversa ao longo de várias chamadas A2A:
from agent_framework import AgentSession
from agent_framework.a2a import A2AAgent
async with A2AAgent(name="remote", url="https://a2a-agent.example.com") as agent:
session = AgentSession(service_session_id="my-conversation-1")
# context_id is automatically set to "my-conversation-1"
response = await agent.run("Hello!", session=session)
# Subsequent calls with the same session continue the conversation
response = await agent.run("Follow-up question", session=session)
Se uma mensagem tiver um valor explícito context_id no seu additional_properties, esse valor tem precedência sobre o valor padrão derivado da sessão.
Authentication
Use um AuthInterceptor para endpoints A2A seguros:
from a2a.client.auth.interceptor import AuthInterceptor
from agent_framework.a2a import A2AAgent
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!")
Configuração de Tempo Limite
A2AAgent aceita um timeout parâmetro para controlar os timeouts dos pedidos:
import httpx
from agent_framework.a2a import A2AAgent
# Simple timeout (applies to all components)
async with A2AAgent(name="remote", url="https://example.com", timeout=120.0) as agent:
...
# Fine-grained timeout
async with A2AAgent(
name="remote",
url="https://example.com",
timeout=httpx.Timeout(connect=10.0, read=120.0, write=10.0, pool=5.0),
) as agent:
...
Quando não é especificado o timeout, os valores predefinidos são: 10s conecta, 60s de leitura, 10s de escrita, 5s pool.
Tools
A2AAgent é um wrapper ao nível de transporte em torno de um agente A2A remoto. As ferramentas que o agente remoto usa estão do lado remoto e são invisíveis ao teu código. Os tipos de ferramentas do Agent Framework (ferramentas funcionais, interpretador de código, pesquisa de ficheiros, MCP alojado/local, etc.) não estão configurados A2AAgent diretamente — para estender as capacidades do agente remoto, alterar a configuração do agente remoto.
Se quiser que um agente da Foundry chame um agente A2A como ferramenta, consulte a get_a2a_tool fábrica em FoundryChatClient.