Agentes hospedados en Foundry

Agentes hospedados en el servicio de agentes Microsoft Foundry permiten implementar agentes de Agent Framework como aplicaciones en contenedores para infraestructura administrada por Microsoft. La plataforma controla el escalado, la persistencia del estado de sesión, la seguridad y la administración del ciclo de vida para que pueda centrarse en la lógica del agente. Microsoft Foundry Hosted Agents ya está disponible de forma general.

Con la integración de hospedaje del Agent Framework, puedes exponer un Agent, incluyendo un flujo de trabajo encapsulado con Workflow.as_agent(), a través del protocolo Foundry Responses o Invocations con muy poco código.

Cuándo usar agentes hospedados

Elija Agentes hospedados de Foundry cuando desee:

  • Infraestructura administrada : no es necesario configurar contenedores, servidores web ni reglas de escalado usted mismo.
  • Administración de sesiones integrada : la plataforma conserva y carga archivos en turnos y períodos $HOME de inactividad.
  • Identidad del agente dedicado — cada agente implementado obtiene su propia identidad Entra para el acceso seguro a modelos, herramientas y servicios posteriores.
  • Puntos de conexión compatibles con OpenAI : los clientes pueden interactuar con el agente mediante cualquier SDK compatible con OpenAI mediante el protocolo De respuestas.

Note

La integración de Python agent-framework-foundry-hosting se encuentra en versión preliminar. Agentes hospedados de Microsoft Foundry, el servicio de alojamiento administrado, ya está disponible de forma general.

Prerequisites

Para las pruebas locales, también necesita lo siguiente:

Instale el paquete NuGet de hospedaje:

dotnet add package Microsoft.Agents.AI.Foundry.Hosting --prerelease
dotnet add package Azure.AI.Projects --prerelease
  • Python 3.10 o posterior

Instale el paquete de hospedaje de versión preliminar, el cliente de Foundry y el paquete de autenticación de Azure:

pip install --pre agent-framework-foundry agent-framework-foundry-hosting azure-identity

En Foundry, la plataforma proporciona el contexto de usuario del autor de la llamada y el contexto de llamada; la infraestructura de hospedaje las usa para aislar el estado por usuario y reenviar el contexto de solicitud a los servicios Foundry. Las ejecuciones locales no reciben ese contexto de plataforma, por lo que las aplicaciones deben proporcionar sus propios controles de identidad y estado cuando sea necesario.

Protocolo de respuestas

El protocolo De respuestas es el punto de partida recomendado para la mayoría de los agentes. Expone un punto de conexión compatible con /responses OpenAI y la plataforma administra automáticamente el historial de conversaciones, el streaming y el ciclo de vida de la sesión.

using Azure.AI.AgentServer.Core;
using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.Foundry.Hosting;

var projectEndpoint = new Uri(Environment.GetEnvironmentVariable("FOUNDRY_PROJECT_ENDPOINT")
    ?? throw new InvalidOperationException("FOUNDRY_PROJECT_ENDPOINT is not set."));
var deployment = Environment.GetEnvironmentVariable("AZURE_AI_MODEL_DEPLOYMENT_NAME") ?? "gpt-4o";

AIAgent agent = new AIProjectClient(projectEndpoint, new DefaultAzureCredential())
    .AsAIAgent(
        model: deployment,
        instructions: "You are a helpful AI assistant.",
        name: "my-agent");

var builder = AgentHost.CreateBuilder(args);
builder.Services.AddFoundryResponses(agent);
builder.RegisterProtocol("responses", endpoints => endpoints.MapFoundryResponses());

var app = builder.Build();
app.Run();

AgentHost.CreateBuilder crea un host de aplicación preconfigurado para el entorno de hospedaje de Foundry. AddFoundryResponses registra el agente con el controlador de protocolo de respuestas y MapFoundryResponses asigna el /responses punto de conexión HTTP.

import os

from agent_framework import Agent
from agent_framework.foundry import FoundryChatClient
from agent_framework_foundry_hosting import ResponsesHostServer
from azure.identity import DefaultAzureCredential

client = FoundryChatClient(
    project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
    model=os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
    credential=DefaultAzureCredential(),
)

agent = Agent(
    client=client,
    instructions="You are a helpful AI assistant.",
)

server = ResponsesHostServer(agent)
server.run()

ResponsesHostServer envuelve tu agente y lo expone a través del protocolo Foundry Responses. Para un agente sin flujo de trabajo, la opción predeterminada history_source="agent_server" usa el proveedor de respuestas de Agent Server configurado como fuente del historial del modelo. El host impide que el servicio de modelo de bajada conserve una segunda copia cuando el cliente almacena el historial de forma predeterminada.

No combines la fuente de historial predeterminada con un HistoryProvider que tenga load_messages=True. Tampoco establezca las opciones de continuación de servicio posterior conversation_id, previous_response_id o conversation. El host rechaza estas configuraciones para evitar el historial duplicado.

Use ResponsesHostServer(agent, history_source="agent") cuando el proveedor de historial del agente o el servicio de modelo de nivel inferior deben administrar el historial de conversaciones. Este modo transmite únicamente la entrada de la solicitud actual desde Agent Server y mantiene el historial del agente y el funcionamiento del almacenamiento del servicio. Las implementaciones personalizadas SupportsAgentRun deben usar este modo. El store parámetro sigue siendo independiente: selecciona el proveedor de respuesta que conserva las entradas y salidas de la API de respuestas en ambos modos.

El host posee el agente proporcionado y podría agregar proveedores de contexto específicos del hospedaje. No reutilice el agente con otro host ni invoquelo directamente después de la construcción del host.

Conservar el estado y controlar las conversaciones de larga duración

ResponsesHostServer configura los almacenes respaldados por Foundry de forma predeterminada. Para los agentes que no pertenecen a un flujo de trabajo, AgentSessionStoreProvider proporciona un FoundryAgentSessionStore. En el caso de los agentes de flujo de trabajo, CheckpointStoreProvider proporciona un FoundryCheckpointStore. FunctionApprovalStoreProvider proporciona un FoundryFunctionApprovalStore para aprobaciones pendientes. Estos almacenes utilizan Foundry State Store cuando están hospedados y el estado del servidor del agente local cuando se ejecutan localmente.

Con history_source="agent", el almacén de sesión configurado conserva el estado del proveedor llevado por AgentSession, incluidos los mensajes de InMemoryHistoryProvider.

Para personalizar el almacenamiento, pase un StoreProvider a agent_session_store_provider o function_approval_store_provider. Pase ContextScopedStoreProvider a checkpoint_store_provider. Por ejemplo, implementar SessionStore y StoreProvider[SessionStore] para usar su propio almacén de sesiones de agentes ajeno a los flujos de trabajo.

Importe ResponsesServerOptions desde azure.ai.agentserver.responses, y páselo a ResponsesHostServer mediante el parámetro options. Las opciones de conversación de larga duración disponibles dependen del tipo de agente:

Capacidad Tipo de agente Requisitos y comportamiento
Respuestas en segundo plano resilientes Solo flujo de trabajo Establezca ResponsesServerOptions(resilient_background=True). Envíe la solicitud de respuestas con store=true y background=true. Después de un reinicio, el host reanuda el punto de control de flujo de trabajo duradero más reciente o reproduce la entrada original si no existe ningún punto de control. No configure el almacenamiento de puntos de control en el flujo de trabajo porque el host lo administra. Haga que los efectos secundarios externos sean idempotentes, porque el trabajo realizado después del último punto de control persistente podría repetirse.
Conversaciones orientables Solo para elementos que no sean de flujo de trabajo Establezca ResponsesServerOptions(steerable_conversations=True) y envíe solicitudes de respuestas con store=true. Mantén los turnos en una única cadena lineal reutilizando el mismo valor conversation. Como alternativa, envíe el previous_response_id inmediatamente anterior y conserve el agent_session_id resuelto. El host rechaza predecesores obsoletos que crearían una bifurcación.

ResponsesHostServer genera RuntimeError si se habilitan las respuestas en segundo plano resilientes para un agente que no sea de flujo de trabajo o las conversaciones orientables para un agente de flujo de trabajo. Para obtener implementaciones completas, consulte el almacenamiento personalizado, el flujo de trabajo resistente de larga duración y ejemplos de agentes de larga duración direccionables .

Cuando una herramienta de MCP hospedada en Foundry requiere el consentimiento del usuario, ResponsesHostServer devuelve una respuesta incompleta con un oauth_consent_request elemento de salida. Presente su consent_link al usuario y, a continuación, continúe con el ID de la respuesta incompleta como previous_response_id después de que el usuario otorgue su consentimiento. El host conserva la sesión del agente para este reintento y expone solo los vínculos de consentimiento HTTPS absolutos.

Protocolo de invocaciones

El protocolo Invocaciones proporciona control total sobre la solicitud y la respuesta HTTP. Úselo cuando necesite cargas personalizadas, procesamiento no conversacional o protocolos de streaming que no sean compatibles con OpenAI.

Con el protocolo de Invocaciones en C#, se implementa una implementación personalizada de InvocationHandler para procesar las solicitudes entrantes.

using Azure.AI.AgentServer.Core;
using Azure.AI.AgentServer.Invocations;
using Microsoft.Agents.AI;

var builder = AgentHost.CreateBuilder(args);

builder.Services.AddSingleton<AIAgent, MyAgent>();
builder.Services.AddInvocationsServer();
builder.Services.AddScoped<InvocationHandler, MyInvocationHandler>();

builder.RegisterProtocol("invocations", endpoints => endpoints.MapInvocationsServer());

var app = builder.Build();
app.Run();

El AddInvocationsServer método registra los servicios del protocolo de invocaciones. Implemente InvocationHandler para definir cómo procesa el agente cada solicitud.

Para una configuración ligera, use InvocationsHostServer del paquete agent_framework_foundry_hosting. Envuelve tu agente de forma similar a ResponsesHostServer y administra automáticamente las sesiones:

import os

from agent_framework import Agent
from agent_framework.foundry import FoundryChatClient
from agent_framework_foundry_hosting import InvocationsHostServer
from azure.identity import DefaultAzureCredential

client = FoundryChatClient(
    project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
    model=os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
    credential=DefaultAzureCredential(),
)

agent = Agent(
    client=client,
    instructions="You are a friendly assistant. Keep your answers brief.",
    default_options={"store": False},
)

server = InvocationsHostServer(agent)
server.run()

Para un control total sobre el control de solicitudes, use InvocationAgentServerHost directamente desde el azure.ai.agentserver.invocations paquete e implemente su propio controlador de invocación:

import os
from collections.abc import AsyncGenerator

from agent_framework import Agent, AgentSession
from agent_framework.foundry import FoundryChatClient
from azure.ai.agentserver.invocations import InvocationAgentServerHost
from azure.identity import DefaultAzureCredential
from starlette.requests import Request
from starlette.responses import JSONResponse, Response, StreamingResponse

_sessions: dict[str, AgentSession] = {}

client = FoundryChatClient(
    project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
    model=os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
    credential=DefaultAzureCredential(),
)

agent = Agent(
    client=client,
    instructions="You are a friendly assistant. Keep your answers brief.",
    default_options={"store": False},
)

app = InvocationAgentServerHost()


@app.invoke_handler
async def handle_invoke(request: Request):
    """Handle streaming multi-turn chat."""
    data = await request.json()
    session_id = request.state.session_id
    stream = data.get("stream", False)
    user_message = data.get("message", None)

    if user_message is None:
        return Response(content="Missing 'message' in request", status_code=400)

    session = _sessions.setdefault(session_id, AgentSession(session_id=session_id))

    if stream:

        async def stream_response() -> AsyncGenerator[str]:
            async for update in agent.run(user_message, session=session, stream=True):
                yield update.text

        return StreamingResponse(
            stream_response(),
            media_type="text/event-stream",
            headers={"Cache-Control": "no-cache", "Connection": "keep-alive"},
        )

    response = await agent.run([user_message], session=session, stream=stream)
    return JSONResponse({"response": response.text})


if __name__ == "__main__":
    app.run()

Warning

El almacén de sesión en memoria del ejemplo del controlador personalizado se pierde al reiniciar. Use almacenamiento duradero (por ejemplo, Cosmos DB) en producción.

Para obtener una implementación completa de invocaciones, consulte el ejemplo de Telegram hospedado por Foundry. Coloca API Management delante del webhook del agente alojado y usa identidades administradas, Key Vault y Cosmos DB para un historial de conversaciones duradero.

Note

La compatibilidad de Go con los agentes hospedados en Foundry estará disponible próximamente. Consulte el repositorio de Agent Framework Go para obtener el estado más reciente.

Tip

Consulte los ejemplos de Python o los ejemplos de C# para obtener ejemplos de un proyecto de agente hospedado. O bien, use el comando azd ai agent init para generar la estructura de un nuevo proyecto de agente hospedado desde cero. Consulte esta guía de inicio rápido para obtener instrucciones paso a paso.

Ejecución local

La CLI de Azure Developer (azd) proporciona la manera más fácil de ejecutar y probar el agente hospedado localmente.

Inicialización de un proyecto

Cree una nueva carpeta e inicialice a partir de un manifiesto de ejemplo:

mkdir my-hosted-agent && cd my-hosted-agent
azd ai agent init -m <path-to-agent.manifest.yaml>

Tip

El manifiesto puede ser una ruta de acceso a un archivo YAML local o una dirección URL a un manifiesto remoto.

Establecimiento de variables de entorno

export FOUNDRY_PROJECT_ENDPOINT="https://<account>.services.ai.azure.com/api/projects/<project>"
export AZURE_AI_MODEL_DEPLOYMENT_NAME="<your-model-deployment>"

Ejecuta el host del agente

azd ai agent run

El host del agente se inicia en http://localhost:8088.

Invoque al agente

azd ai agent invoke --local "Hello!"

O bien, use curl:

curl -X POST http://localhost:8088/responses \
  -H "Content-Type: application/json" \
  -d '{"input": "Hello!"}'

O en PowerShell:

(Invoke-WebRequest -Uri http://localhost:8088/responses -Method POST -ContentType "application/json" -Body '{"input": "Hello!"}').Content

Implementación en Foundry

Una vez que haya comprobado el agente localmente, impleméntelo en Microsoft Foundry:

  1. Aprovisione recursos (si aún no tiene un proyecto Foundry):

    azd provision
    

    Esto crea un grupo de recursos con una instancia de Foundry, un proyecto, una implementación de modelos, Application Insights y un registro de contenedor.

  2. Implemente el agente:

    azd deploy
    

    Esto empaqueta al agente como una imagen de contenedor, lo inserta en Azure Container Registry e lo implementa en el servicio Foundry Agent.

La infraestructura de hospedaje de Foundry inserta automáticamente las siguientes variables de entorno en el contenedor del agente en tiempo de ejecución:

Variable Description
FOUNDRY_PROJECT_ENDPOINT Dirección URL del punto de conexión del proyecto Foundry.
AZURE_AI_MODEL_DEPLOYMENT_NAME Nombre de implementación del modelo (configurado durante azd ai agent init).
APPLICATIONINSIGHTS_CONNECTION_STRING La cadena de conexión de Application Insights para la telemetría.

Una vez desplegado, el agente es accesible mediante su endpoint dedicado de Foundry y también se puede probar desde el portal de Foundry.

Pasos siguientes