Agentes Alojados da Foundry

Agentes alojados no Microsoft Foundry Agent Service permitem-lhe implementar aplicações agentes containerizadas para a infraestrutura gerida pela Microsoft. A plataforma gere escalabilidade, persistência do estado da sessão, segurança e gestão do ciclo de vida para que possa focar-se na lógica do seu agente. O Microsoft Foundry Hosted Agents está geralmente disponível e suporta agentes construídos com o seu próprio código ou um framework de agentes preferido. Este artigo aborda especificamente a integração de alojamento do Agent Framework.

Com a integração de hospedagem do Agent Framework, pode expor um Agent, incluindo um fluxo de trabalho encapsulado com Workflow.as_agent(), através do protocolo Foundry Responses ou Invocations com um mínimo de código.

Observação

Também pode implementar código de agente construído com outros frameworks para agentes alojados no Foundry usando fluxos de trabalho do Azure Developer CLI (azd). Para conceitos independentes do framework e orientações de implementação, veja O que são agentes alojados? O resto deste artigo foca-se na integração do Agent Framework.

Quando usar agentes hospedados

Escolha agentes alojados na Foundry quando quiser:

  • Infraestrutura gerida — não precisa de configurar containers, servidores web ou regras de escalabilidade por si próprio.
  • Gestão de sessões incorporada — a plataforma persiste $HOME e carrega ficheiros ao longo de turnos e períodos de inatividade.
  • Identidade dedicada de agente — cada agente implementado recebe a sua própria identidade Entra para acesso seguro a modelos, ferramentas e serviços subsequentes.
  • Endpoints compatíveis com OpenAI — os clientes podem interagir com o seu agente usando qualquer SDK compatível com OpenAI através do protocolo Responses.
  • Para agentes de áudio em tempo real, utilize agentes alojados com Azure Speech no Foundry Tools (Voice Live) para deteção de atividade de voz do lado do servidor, cancelamento de eco e redução de ruído. Para obter mais detalhes, consulte Utilizar o Voice Live com agentes alojados.

Observação

A integração com Python agent-framework-foundry-hosting está em pré-lançamento. O Microsoft Foundry Hosted Agents, o serviço de alojamento gerido, está geralmente disponível.

Pré-requisitos

Para testes locais, também precisa de:

Instale o pacote NuGet de alojamento:

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

Instale o pacote de alojamento pré-lançamento, o cliente Foundry e o pacote de autenticação Azure:

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

No Foundry, a plataforma fornece o contexto de utilizador do chamador e o contexto da chamada; a infraestrutura de alojamento utiliza-os para isolar o estado por utilizador e encaminhar o contexto do pedido para os serviços do Foundry. As execuções locais não recebem esse contexto de plataforma, pelo que as aplicações têm de fornecer os seus próprios controlos de identidade e estado quando necessário.

Protocolo de Respostas

O protocolo Respostas é o ponto de partida recomendado para a maioria dos agentes. Expõe um endpoint compatível /responses com OpenAI, e a plataforma gere automaticamente o histórico de conversas, o streaming e o ciclo de vida das sessões.

Para agentes Python alojados, uma resposta que termina prematuramente tem um estado incomplete. Os clientes de streaming recebem um evento final response.incomplete, enquanto os clientes sem streaming recebem status definido como incomplete. Um motivo de conclusão content_filter corresponde a incomplete_details.reason definido como content_filter, e length corresponde a max_output_tokens. Qualquer conteúdo gerado ou conteúdo de recusa permanece disponível na resposta.

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();

O AgentHost.CreateBuilder cria um anfitrião de aplicação pré-configurado para o ambiente de alojamento da Foundry. AddFoundryResponses regista o seu agente com o handler do protocolo Responses e MapFoundryResponses mapeia o /responses endpoint 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()

Encapsula ResponsesHostServer o seu agente, expondo-o através do protocolo Foundry Responses. Para um agente sem fluxo de trabalho, o history_source="agent_server" predefinido utiliza o fornecedor de respostas configurado do Agent Server como fonte do histórico do modelo. O host impede que o serviço de modelo downstream retenha uma segunda cópia quando o cliente guarda o histórico por predefinição.

Não combine a fonte de histórico padrão com um HistoryProvider que tenha load_messages=True. Também não definas as opções de continuação do serviço conversation_id, previous_response_id ou conversation a jusante. O anfitrião rejeita estas configurações para evitar histórico duplicado.

Use ResponsesHostServer(agent, history_source="agent") quando o fornecedor de histórico do agente ou o serviço de modelos a jusante tiver de gerir o histórico das conversas. Este modo transmite apenas os dados de entrada do pedido atual provenientes do Agent Server e preserva o histórico do agente e o comportamento de armazenamento do serviço. Implementações personalizadas SupportsAgentRun devem usar este modo. O store parâmetro permanece separado: seleciona o fornecedor de resposta que persiste as entradas e saídas da API de Respostas em ambos os modos.

O host é proprietário do agente fornecido e pode adicionar fornecedores de contexto específicos para o alojamento. Não reutilize o agente com outro host nem o invoque diretamente após a construção do host.

Escolha uma instância de agente ou fábrica

Tanto ResponsesHostServer como InvocationsHostServer aceitam, através do parâmetro agent, quer uma instância de agente quer um invocável síncrono ou assíncrono sem argumentos. O hospedeiro reutiliza uma instância ao longo de todo o seu ciclo de vida. Uma função invocável é executada uma vez por pedido, e o agente devolvido pertence a esse pedido.

Use uma função invocável quando o agente mantém um estado mutável fora de AgentSession. Em particular, crie um WorkflowAgent a partir de uma fábrica que cria um novo fluxo de trabalho, executores e agentes encapsulados:

def create_workflow_agent():
    return build_workflow().as_agent(name="support-workflow")


server = ResponsesHostServer(agent=create_workflow_agent)

Mantenha o nome do fluxo de trabalho e os IDs dos executores estáveis para que os pedidos de Resposta posteriores possam localizar os checkpoints guardados. ResponsesHostServer continua o estado suportado através dos seus armazenamentos de sessão, checkpoint e aprovação de funções; não persiste campos arbitrários num agente com escopo de pedido. Veja o fluxo de trabalho e exemplos de workflow resilientes e de longa duração .

Persistir o estado e lidar com conversas de longa duração

ResponsesHostServer configura, por predefinição, repositórios suportados pelo Foundry. Para agentes sem fluxo de trabalho, AgentSessionStoreProvider fornece um FoundryAgentSessionStore. Para agentes de workflow, CheckpointStoreProvider fornece um FoundryCheckpointStore. FunctionApprovalStoreProvider disponibiliza uma FoundryFunctionApprovalStore para aprovações pendentes. Estes armazenamentos usam o Foundry State Store quando estão hospedados e o estado local do Agent Server quando executa localmente.

Com history_source="agent", o armazenamento de sessões configurado persiste o estado do fornecedor transportado por AgentSession, incluindo as mensagens de InMemoryHistoryProvider.

Para personalizar o armazenamento, passe um StoreProvider para agent_session_store_provider ou function_approval_store_provider. Passe a ContextScopedStoreProvider para checkpoint_store_provider. Por exemplo, implementa SessionStore e StoreProvider[SessionStore] para usar o teu próprio armazenamento de sessões do agente fora do workflow.

Importa ResponsesServerOptions de azure.ai.agentserver.responses, e passa para ResponsesHostServer através do options parâmetro. As opções de conversa de longa duração disponíveis dependem do tipo de agente:

Capacidade Tipo de agente Requisitos e comportamento
Respostas resilientes em segundo plano Apenas fluxo de trabalho Defina ResponsesServerOptions(resilient_background=True). Envie o pedido de Respostas com store=true e background=true. Após um reinício, o host retoma o ponto de verificação mais recente do fluxo de trabalho durável ou reprocessa a entrada original se não existir nenhum ponto de verificação. Não configure o armazenamento de pontos de verificação no fluxo de trabalho, porque a respetiva gestão é feita pelo anfitrião. Torna os efeitos laterais externos idempotentes, porque o trabalho após o último ponto de verificação persistente pode ser repetido.
Conversas orientáveis Apenas para casos sem fluxo de trabalho Defina ResponsesServerOptions(steerable_conversations=True) e envie pedidos de resposta com store=true. Mantém turnos numa cadeia linear reutilizando o mesmo conversation valor. Em alternativa, envie o previous_response_id imediatamente anterior e preserve o agent_session_id já resolvido. O anfitrião rejeita predecessores desatualizados que criariam uma bifurcação.

ResponsesHostServer gera RuntimeError se ativares respostas resilientes em segundo plano para um agente que não seja de workflow ou conversas direcionáveis para um agente de workflow. Para implementações completas, consulte os samples de armazenamento personalizado, fluxo de trabalho resiliente e de longa duração e agentes de longa duração orientáveis .

Quando uma ferramenta MCP alojada no Foundry requer consentimento do utilizador, ResponsesHostServer devolve uma resposta incompleta com um oauth_consent_request item de saída. Apresente-o ao utilizador consent_link e, em seguida, continue com o ID da resposta incompleta como previous_response_id depois de o utilizador dar o seu consentimento. O anfitrião mantém a sessão do agente para esta nova tentativa e disponibiliza apenas hiperligações de consentimento HTTPS absolutas.

Protocolo de invocações

O protocolo Invocations dá-lhe controlo total sobre o pedido HTTP e a resposta. Use-o quando precisar de payloads personalizados, processamento não conversacional ou protocolos de streaming que não sejam compatíveis com OpenAI.

Com o protocolo Invocations em C#, implementa-se um personalizado InvocationHandler para processar os pedidos recebidos.

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();

O AddInvocationsServer método regista os serviços do protocolo Invocations. Implementa InvocationHandler para definir como o seu agente processa cada pedido.

Para uma configuração leve, use InvocationsHostServer do pacote agent_framework_foundry_hosting. Envolve o seu agente de forma semelhante ao ResponsesHostServer e gere as sessões automaticamente:

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()

InvocationsHostServer aceita a mesma instância ou as formas de fábrica com âmbito de pedido descritas para o host Responses. As suas sessões incorporadas são armazenadas em memória durante o tempo de vida do host e não persistem após um reinício. O protocolo Invocations não retoma execuções de workflow pendentes ou interrompidas. Use o padrão de manipulador personalizado na secção seguinte com armazenamento durável da aplicação quando necessitar de um comportamento de continuação diferente.

Para controlo total sobre o tratamento dos pedidos, use InvocationAgentServerHost diretamente do azure.ai.agentserver.invocations pacote e implemente o seu próprio handler de invocação:

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

O armazenamento de sessão em memória no exemplo do handler personalizado perde-se ao reiniciar. Use armazenamento durável (por exemplo, Cosmos DB) em produção.

Para uma implementação completa do Invocations, consulte o exemplo do Telegram hospedado pela Foundry. Coloca a API Management à frente do webhook do agente hospedado e utiliza identidades geridas, Key Vault e Cosmos DB para um histórico duradouro de conversas.

Observação

O suporte para Go em agentes alojados no Foundry estará disponível em breve. Consulte o repositório Agent Framework Go para o estado mais recente.

Tip

Consulte os exemplos Python ou os exemplos C# para exemplos de um projeto de agente hospedado. Ou usar o comando azd ai agent init para estruturar um novo projeto de agente hospedado do início. Consulte este guia de início rápido para instruções passo a passo.

Executando localmente

A Azure Developer CLI (azd) oferece a forma mais fácil de executar e testar o seu agente hospedado localmente.

Inicializar um projeto

Crie uma nova pasta e inicialize a partir de um manifesto de exemplo:

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

Tip

O manifesto pode ser um caminho para um ficheiro YAML local ou uma URL para um manifesto remoto.

Definir variáveis de ambiente

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

Executa o agente host

azd ai agent run

O host do agente começa em http://localhost:8088.

Invocar o agente

azd ai agent invoke --local "Hello!"

Ou usar curl:

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

Ou no PowerShell:

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

Implantação no Foundry

Depois de verificares o teu agente localmente, implementa-o no Microsoft Foundry:

  1. Fornecer recursos (se ainda não tiver um projeto Foundry):

    azd provision
    

    Isto cria um grupo de recursos com uma instância Foundry, projeto, implementação de modelos, Application Insights e um registo de contentores.

  2. Implementar o agente:

    azd deploy
    

    Isto empacota o seu agente como uma imagem de contentor, envia-o para o Azure Container Registry e implementa-o no Foundry Agent Service.

A infraestrutura de alojamento do Foundry injeta automaticamente as seguintes variáveis de ambiente no seu contentor de agentes em tempo de execução:

Variável Descrição
FOUNDRY_PROJECT_ENDPOINT O URL do endpoint para o projeto Foundry.
AZURE_AI_MODEL_DEPLOYMENT_NAME O nome da implementação do modelo (configurado durante azd ai agent init).
APPLICATIONINSIGHTS_CONNECTION_STRING A cadeia de ligação "Application Insights" para telemetria.

Uma vez implementado, o seu agente está acessível através do seu endpoint dedicado da Foundry e também pode ser testado no portal da Foundry.

Passos seguintes