Habilitar A2A entrante en un agente de Foundry (versión preliminar)

Importante

Los elementos marcados (versión preliminar) de este artículo se encuentran actualmente en versión preliminar pública. Esta versión preliminar se proporciona sin un contrato de nivel de servicio y no se recomienda para cargas de trabajo de producción. Es posible que algunas características no se admitan o que tengan funcionalidades restringidas. Para obtener más información, vea Supplemental Terms of Use for Microsoft Azure Previews.

Puede exponer el agente del Foundry Agent Service como un punto de conexión de agente a agente (A2A) para que otros agentes puedan detectarlo y llamarlo a través del protocolo A2A. Cuando se habilita el A2A entrante, Foundry publica una ficha tarjeta de agente para el agente y acepta solicitudes A2A entrantes de eventos de llamada externos.

Foundry Agent Service admite la versión 1.0 del protocolo A2A y la versión 0.3. Las nuevas integraciones deben tener como destino la versión 1.0. Para obtener más información sobre cómo los clientes seleccionan una versión, consulte Versiones del protocolo A2A.

Tipos de agente admitidos

Para el A2A entrante se necesita el protocolo de respuestas. Los agentes de prompts admiten el protocolo de respuestas de forma predeterminada, y puedes exponerlos como puntos de conexión A2A.

Sugerencia

En este artículo se explica cómo exponer el agente como un punto de conexión A2A al que pueden llamar otros agentes. Si desea que el agente llame a un punto de conexión A2A remoto, consulte Conectar con un punto de conexión de agente A2A desde el Servicio Foundry Agent.

Requisitos previos

  • Una suscripción Azure con un proyecto de Foundry activo.

  • Un agente de prompts desplegado en Foundry Agent Service.

  • Rol Azure obligatorio: Foundry User o superior en el proyecto Foundry.

    Importante

    Recientemente se cambió el nombre de los roles RBAC de Foundry. Foundry User, Foundry Owner, Foundry Account Owner y Foundry Project Manager se llamaban anteriormente Usuario de Azure AI, Propietario de Azure AI, Propietario de la cuenta de Azure AI y Administrador de proyectos de Azure AI. Es posible que siga viendo los nombres anteriores en algunos lugares mientras se implementa el cambio de nombre. El cambio de nombre no modifica los identificadores de rol y los permisos principales.

Activar A2A entrante

La habilitación de A2A entrante requiere dos cosas: una tarjeta de agente que describe las funcionalidades del agente y el protocolo A2A habilitado en el punto de conexión del agente. Puede establecer ambos en una sola llamada PATCH. Esta característica aún no está disponible en el portal de Foundry: use la API REST o el SDK de Python.

La habilitación de A2A entrante aún no se puede configurar en el portal de Foundry. Use la API REST o el SDK de Python.

Versiones del protocolo A2A

Foundry sirve ambas versiones del protocolo A2A en la misma ruta de acceso base (…/endpoint/protocols/a2a). Los agentes de llamada seleccionan una versión de una de estas tres maneras:

  • Descubrimiento de la tarjeta del agente (recomendado)—Obtén la tarjeta del agente correspondiente a la versión. Foundry publica la tarjeta v1.0 en …/agentCard/v1.0 y la tarjeta v0.3 en …/agentCard/v0.3. Cada tarjeta declara su protocolVersion, y la mayoría de los SDK de cliente de A2A usan ese campo para negociar automáticamente la versión para solicitudes posteriores.
  • Encabezado HTTP: establezca A2A-Version: 1.0 (o A2A-Version: 0.3) en la solicitud.
  • Cadena de consulta: anexe ?a2a-version=1.0 (o ?a2a-version=0.3) a la dirección URL de la solicitud.

Si proporciona una versión tanto en el encabezado A2A-Version como en la cadena de consulta a2a-version, los valores deben coincidir. Si los valores difieren, Foundry devuelve HTTP 400 con el version-ambiguous tipo de problema o el JSON-RPC VERSION_AMBIGUOUS motivo. Quite un selector de versión o haga que los valores sean idénticos.

Importante

Si una solicitud no especifica una versión a través del encabezado A2A-Version o de la cadena de consulta a2a-version, Foundry ofrece A2A v0.3 de forma predeterminada, de acuerdo con la especificación A2A. Para usar v1.0, establezca el encabezado, establezca la cadena de consulta o haga que el cliente capture la tarjeta del agente v1.0 para que el SDK negocia automáticamente la versión 1.0.

En la tabla siguiente se resumen las versiones admitidas:

Versión Situación Recomendado para
1.0 Soportado Nuevas integraciones
0.3 Soportado Integraciones existentes que ya tienen como destino v0.3

Comprobación de la tarjeta del agente

Después de habilitar A2A entrante, el agente expone las siguientes URL que utilizan los agentes de llamada:

  • Ruta de acceso base de A2A: la dirección URL raíz de las interacciones del protocolo A2A con el agente:

    https://{account}.services.ai.azure.com/api/projects/{project}/agents/{agent}/endpoint/protocols/a2a

  • URL de tarjeta del agente (v1.0, recomendada): punto de conexión de detección que utilizan los agentes de llamada para recuperar la tarjeta v1.0 del agente:

    https://{account}.services.ai.azure.com/api/projects/{project}/agents/{agent}/endpoint/protocols/a2a/agentCard/v1.0

  • URL de tarjeta del agente (v0.3): punto de conexión de detección de la tarjeta v0.3. Use esta dirección URL para los clientes que tienen como destino A2A v0.3:

    https://{account}.services.ai.azure.com/api/projects/{project}/agents/{agent}/endpoint/protocols/a2a/agentCard/v0.3

Redactas la tarjeta del agente una sola vez (en el cuerpo de PATCH agent_card mostrado anteriormente), y Foundry refleja el mismo contenido en ambos formatos de tarjeta, v1.0 y v0.3.

Importante

Todas las direcciones URL de A2A requieren autenticación Microsoft Entra ID. No se admite el acceso anónimo a la tarjeta del agente. La identidad que realiza la llamada debe tener el rol Foundry Agent Consumer u otro rol de Foundry que conceda acceso al punto de conexión en el proyecto o agente de Foundry.

Para confirmar que la tarjeta del agente está configurada correctamente, capture la tarjeta v1.0 directamente:

curl -X GET "$BASE_URL/agents/$AGENT_NAME/endpoint/protocols/a2a/agentCard/v1.0" \
  -H "Authorization: Bearer $TOKEN"

La respuesta contiene la tarjeta del agente con la descripción y las habilidades que configuró. Compruebe que los campos coinciden con las capacidades previstas y confirme que el campo protocolVersion de la tarjeta coincide con la ruta de versión que solicitó.

Configuración de la autenticación para las solicitudes entrantes

Las solicitudes A2A entrantes requieren Microsoft Entra ID autenticación. No se admite la autenticación basada en claves ni el acceso no autenticado. El agente de llamada debe presentar un token de Microsoft Entra válido. La identidad detrás de ese token debe tener el rol Foundry Agent Consumer u otro rol de Foundry que conceda acceso al punto de conexión en el proyecto o agente de Foundry de destino.

Se admiten dos patrones de autenticación:

En nombre del usuario final (OBO)

El agente de llamada transmite la identidad del usuario final. El agente recibe un token que representa al usuario real, por lo que puede limitar las acciones a los permisos de ese usuario. Este patrón es adecuado cuando el agente necesita aplicar el control de acceso por usuario.

Identidad de servicio (identidad del agente, entidad de servicio o identidad administrada)

El agente de llamada se autentica con su propia identidad, ya sea la identidad del agente asignado a la plataforma, una entidad de servicio o una identidad administrada. El agente ve la identidad del servicio de llamada, no un usuario individual. Este patrón es adecuado para los flujos de trabajo de agente a agente de back-end en los que no se requiere el contexto de usuario individual.

Conceder acceso al extremo A2A

Asigna el rol Foundry Agent Consumer a la identidad que envía las solicitudes A2A. Este rol proporciona acceso con privilegios mínimos a los puntos de conexión del agente sin conceder permiso para crear o modificar agentes.

Elija el ámbito de asignación de roles en función del acceso que necesita el autor de la llamada:

  • Asigna el rol en el ámbito del proyecto de Foundry de destino para permitir que la identidad llame a todos los puntos de conexión de agente del proyecto.
  • Asigne el rol en el ámbito del agente de destino para permitir que la identidad llame únicamente a ese punto de conexión del agente.

Use la identidad representada por el token de acceso:

  • Para las solicitudes de OBO, conceda acceso al usuario final o a un grupo que contenga al usuario.
  • Para las solicitudes de servicio a servicio, conceda acceso a la identidad del agente que realiza la llamada, al principal de servicio o a la identidad administrada.
  • Para un agente de Foundry del nuevo modelo, utilice la identidad especificada por el instance_identity del agente. El agente tiene esta identidad única a partir de la creación y la publicación no la cambia.
  • Para un llamante de la aplicación de agente heredada, utilice la identidad compartida del proyecto antes de la publicación y la identidad distinta de la aplicación de agente después de la publicación.

Utilice el ID del objeto de Microsoft Entra (entidad principal) de la identidad para la asignación de roles, no su ID de aplicación (cliente).

Para obtener más información sobre los dos modelos de identidad, consulte Migración de aplicaciones de agente al nuevo punto de conexión de agente y a la nueva experiencia de publicación.

Los formatos de ámbito del proyecto y del agente son:

/subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.CognitiveServices/accounts/<account>/projects/<project>

/subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.CognitiveServices/accounts/<account>/projects/<project>/agents/<agent>

Asigne el rol mediante su identificador de definición de rol:

PRINCIPAL_TYPE="ServicePrincipal"

az role assignment create \
  --assignee-object-id "<calling-principal-object-id>" \
  --assignee-principal-type "$PRINCIPAL_TYPE" \
  --role "eed3b665-ab3a-47b6-8f48-c9382fb1dad6" \
  --scope "<target-project-or-agent-scope>"

Establezca PRINCIPAL_TYPE en User, Groupo ServicePrincipal en función de la identidad de llamada. Las identidades de agente y las identidades administradas usan ServicePrincipal.

Cuando la persona que llama obtiene un token directamente, solicita el ámbito https://ai.azure.com/.default. Para obtener más información sobre las asignaciones de roles, consulte Control de acceso basado en roles para Microsoft Foundry.

Transportes de A2A admitidos

La compatibilidad con el transporte depende de la versión del protocolo A2A:

Transporte v0.3 v1.0
HTTP+JSON ✔️
JSONRPC ✔️ ✔️
gRPC

A2A v1.0 solo admite JSON-RPC en el endpoint de entrada de Foundry. Los clientes que requieren HTTP+JSON deben usar v0.3 o cambiar a JSONRPC para v1.0.

Conexión a un agente de Foundry A2A con el SDK de Python A2A

En el siguiente ejemplo se muestra cómo usar el SDK de Python A2A de código abierto para conectarse a un agente Foundry que tiene A2A entrante habilitado. El SDK lee el campo protocolVersion de la tarjeta de agente y negocia la versión coincidente del protocolo para las solicitudes posteriores, por lo que hacer que el resolutor apunte a agentCard/v1.0 hace que el cliente use A2A v1.0 de un extremo a otro.

Dado que la tarjeta del agente Foundry requiere autenticación y utiliza una ruta de acceso personalizada (agentCard/v1.0 en lugar de la predeterminada .well-known/agent-card.json), se configura el cliente httpx con un token de portador y se pasa la ruta de acceso personalizada de la tarjeta del agente al solucionador.

Instale los paquetes necesarios:

pip install a2a-sdk==1.0.2 azure-identity==1.25.3 httpx==0.28.1
import asyncio

import httpx

from azure.identity import DefaultAzureCredential
from a2a.client import A2ACardResolver, ClientConfig, create_client
from a2a.helpers import new_text_message
from a2a.types.a2a_pb2 import (
    Role,
    SendMessageRequest,
)

# Your Foundry agent's A2A base path
A2A_BASE_URL = (
    "https://{account}.services.ai.azure.com/api/projects"
    "/{project}/agents/{agent}/endpoint/protocols/a2a"
)
# Agent card path, relative to the A2A base URL.
AGENT_CARD_PATH = "agentCard/v1.0"


async def main():
    # Get a Microsoft Entra token
    credential = DefaultAzureCredential()
    token = credential.get_token("https://ai.azure.com/.default").token

    async with httpx.AsyncClient(
        headers={"Authorization": f"Bearer {token}"},
        timeout=httpx.Timeout(120.0),
    ) as httpx_client:
        # Resolve the agent card from the custom path
        resolver = A2ACardResolver(
            httpx_client=httpx_client,
            base_url=A2A_BASE_URL,
            agent_card_path=AGENT_CARD_PATH,
        )
        agent_card = await resolver.get_agent_card()

        # Create a non-streaming A2A client
        config = ClientConfig(
            streaming=False,
            httpx_client=httpx_client,
        )
        client = await create_client(
            agent=agent_card, client_config=config
        )

        # Send a message to the Foundry agent
        message = new_text_message(
            "Hello, what can you do?", role=Role.ROLE_USER
        )
        request = SendMessageRequest(message=message)

        async for response in client.send_message(request):
            print(response)

        await client.close()


if __name__ == "__main__":
    asyncio.run(main())

Reemplace {account}, {project}y {agent} por el nombre del recurso Foundry, el nombre del proyecto y el nombre del agente. La función de resolución genera la URL completa de la ficha de agente añadiendo la ruta relativa AGENT_CARD_PATH a A2A_BASE_URL.

Conectar desde otro agente de Foundry

Puede llamar a un agente Foundry A2A desde otro agente de Foundry mediante la herramienta A2A. En esta sección se explica la configuración completa: crear una conexión al agente de destino y, a continuación, crear un agente de llamada que use esa conexión.

Paso 1: Creación de una conexión A2A al agente de destino

La conexión almacena la dirección URL del punto de conexión A2A del agente de destino y los detalles de autenticación. Para un destino de agente de Foundry, no establezcas una ruta de tarjeta de agente. Foundry resuelve automáticamente la ruta de acceso predeterminada de la tarjeta del agente y negocia por usted la versión del protocolo A2A.

Configurar variables:

SUBSCRIPTION_ID="your-subscription-id"
RESOURCE_GROUP="your-resource-group"
FOUNDRY_ACCOUNT="your-foundry-account"
PROJECT_NAME="your-project"
CONNECTION_NAME="my-a2a-target"
TARGET_A2A_URL="https://{account}.services.ai.azure.com/api/projects/{project}/agents/{agent}/endpoint/protocols/a2a"
TOKEN=$(az account get-access-token \
  --scope https://management.azure.com/.default \
  --query accessToken -o tsv)

Cree la conexión:

curl --request PUT \
  --url "https://management.azure.com/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.CognitiveServices/accounts/$FOUNDRY_ACCOUNT/projects/$PROJECT_NAME/connections/$CONNECTION_NAME?api-version=2025-04-01-preview" \
  --header "Authorization: Bearer $TOKEN" \
  --header "Content-Type: application/json" \
  --data '{
    "properties": {
      "authType": "AgenticIdentityToken",
      "category": "RemoteA2A",
      "target": "'"$TARGET_A2A_URL"'",
      "audience": "https://ai.azure.com",
      "Credentials": {},
      "metadata": {}
    }
  }'

Para ver otras opciones de autenticación (basada en claves, OAuth, identidad administrada), consulte Creación de una conexión A2A mediante la API REST.

Paso 2: Creación del agente de llamada con la herramienta A2A

Una vez que exista la conexión, cree un agente que use A2APreviewTool para llamar al agente de destino:

from azure.identity import DefaultAzureCredential
from azure.ai.projects import AIProjectClient
from azure.ai.projects.models import (
    PromptAgentDefinition,
    A2APreviewTool,
)

PROJECT_ENDPOINT = "your_project_endpoint"
A2A_CONNECTION_NAME = "my-a2a-target"
AGENT_NAME = "my-calling-agent"

project = AIProjectClient(
    endpoint=PROJECT_ENDPOINT,
    credential=DefaultAzureCredential(),
)
openai = project.get_openai_client()

a2a_connection = project.connections.get(A2A_CONNECTION_NAME)

tool = A2APreviewTool(
    project_connection_id=a2a_connection.id,
)

agent = project.agents.create_version(
    agent_name=AGENT_NAME,
    definition=PromptAgentDefinition(
        model="gpt-4.1-mini",
        instructions=(
            "You are a helpful assistant. Use the A2A tool "
            "to delegate tasks to the target agent."
        ),
        tools=[tool],
    ),
)

# Send a message and stream the response
stream_response = openai.responses.create(
    stream=True,
    input="Ask the target agent what it can do.",
    extra_body={
        "agent_reference": {
            "name": agent.name,
            "type": "agent_reference",
        }
    },
)

for event in stream_response:
    if event.type == "response.output_text.delta":
        print(event.delta, end="")
    elif event.type == "response.completed":
        print(f"\n\nCompleted: {event.response.output_text}")

# Clean up
project.agents.delete_version(
    agent_name=agent.name, agent_version=agent.version
)

Para obtener más ejemplos de lenguaje (C#, JavaScript, Java, REST), consulte Connect to an A2A agent endpoint from Foundry Agent Service.

Limitaciones

  • Se admiten las versiones 1.0 y 0.3 del protocolo A2A. No se admiten otras versiones.
  • Para A2A v1.0, solo se admite el transporte JSONRPC. HTTP+JSON y gRPC no se admiten para v1.0. Consulte los transportes compatibles con A2A.
  • Solo se admite la modalidad de texto . No se admiten datos de archivo ni otras modalidades de no texto.
  • No se admiten las respuestas de streaming (eventos enviados por el servidor).
  • Para el A2A entrante se necesita el protocolo de respuestas. Los agentes que no usan el protocolo de respuestas no se pueden exponer como puntos de conexión A2A.
  • Esta característica está en versión preliminar y no se recomienda para cargas de trabajo de producción.