Contrato de execução de agente hospedado

Um agente alojado é um contentor que cumpre um contrato de execução específico com a plataforma Microsoft Foundry. Esta referência descreve o que a plataforma espera do seu contentor e como os pacotes adaptadores SDK o ajudam a cumprir esses requisitos.

Os pacotes adaptadores SDK implementam todo o contrato por ti. Se usares azure-ai-agentserver-responses ou azure-ai-agentserver-invocations, implementas apenas a lógica do teu handler.

Se usar um agente de programação como o GitHub Copilot para implementar ou rever um contentor de agente alojado, o Microsoft Foundry Skill pode ajudar a verificar o contrato de execução, o uso do adaptador e as suposições de implementação.

Requisitos contratuais

O seu recipiente deve:

Requisito Detail
Ouça na porta 8088 HTTP/1.1, HTTP simples. A plataforma termina o TLS.
Entregar uma insonda de saúde Regresso 200 OK de GET /readiness.
Implementar um endpoint de protocolo Sirva pelo menos um de POST /responses ou POST /invocations.
Consumir variáveis do ambiente da plataforma Leia as variáveis que a plataforma insere no arranque.
Desliga com elegância Escritas de flush e fechar ligações em SIGTERM.

Pontos finais de protocolo

Um protocolo define o contrato HTTP entre o Foundry e o seu contentor de agente. O teu contentor implementa pelo menos um endpoint de protocolo.

Protocolo de Respostas

O protocolo de respostas implementa a API OpenAI Responses. A plataforma envia pedidos para POST /responses e espera uma resposta JSON ou um fluxo de Server-Sent Eventos (SSE).

Aspect Detail
Endpoint POST /responses
Entrada Pedido da API OpenAI Responses (input, model, stream, e assim sucessivamente)
Output Objeto de resposta JSON ou fluxo SSE de eventos de resposta
Histórico da conversa Hidratado automaticamente pelo adaptador SDK quando conversation.id está presente
Streaming SSE com o tipo de text/event-stream conteúdo

Use o protocolo de respostas como escolha padrão. É compatível com o ecossistema da API OpenAI.

Protocolo de invocações

O protocolo de invocações é um protocolo de passagem mínima. Defines a estrutura da carga útil, e a plataforma passa-a sem interpretação.

Aspect Detail
Endpoint POST /invocations
Entrada Qualquer carga JSON que o teu handler espere
Output Qualquer resposta JSON ou fluxo SSE
Histórico da conversa Não conseguiu. O teu código trata do estado, se necessário.
Streaming Opcional, através da SSE

Use o protocolo de invocações quando precisar de controlo total sobre as cargas úteis de pedido e resposta.

Pacotes adaptadores SDK

Os pacotes adaptadores são específicos de protocolo e independentes do framework. Funcionam com qualquer framework de agentes, incluindo Microsoft Agent Framework, LangGraph e código personalizado.

Protocolo Pacote Python Pacote .NET
Responses azure-ai-agentserver-responses Azure.AI.AgentServer.Responses
Invocações azure-ai-agentserver-invocations Azure.AI.AgentServer.Invocations

O adaptador trata das seguintes partes do contrato por si:

  • Configuração do servidor HTTP na porta 8088.
  • O endpoint da sonda de saúde (GET /readiness).
  • Análise sintética de pedidos específica do protocolo e formatação de respostas.
  • Histórico de conversa, hidratação (protocolo de respostas).
  • Infraestrutura de streaming SSE.
  • Instrumentação OpenTelemetry.
  • Desligamento gracioso em SIGTERM.
  • Ambiente da plataforma, consumo variável.

Implementas uma função handler que recebe pedidos analisados e devolve respostas.

Execução de longa duração e resiliente (pré-visualização)

Os adaptadores de protocolo compõem com a tarefa resiliente e primitivas de streaming na sua dependência AgentServer Core. Utilize estas primitivas quando o trabalho tiver de sobreviver a uma interrupção de processo ou quando os clientes têm de se reconectar à saída reproduzida.

O adaptador de Respostas pode gerir a execução resiliente para respostas em segundo plano armazenadas. O teu servidor opta por um processamento resiliente em segundo plano, e o teu handler ou reexecuta em segurança ou retoma a partir de um checkpoint durável. As respostas em primeiro plano não são reativadas depois de o processo terminar.

O adaptador Invocations não prescreve um estado ou contrato de sondagem. Regista tarefas resilientes para execução duradoura e depois define os endpoints de resposta, polling ou stream que expõem o progresso aos teus clientes.

Para o modelo de execução, estratégias de checkpoint e comportamento de replay do cliente, veja Resiliência para agentes alojados de longa duração.

Exemplos de manipuladores

As amostras completas para trazer as suas próprias amostras para ambos os protocolos e ambas as linguagens encontram-se no repositório foundry-samples .

Exemplo de protocolo de respostas

Este handler mínimo encaminha a entrada do utilizador para um modelo do catálogo de modelos Foundry através da API Responses. O adaptador SDK hidrata automaticamente o histórico de conversas através de context.get_history() (Python) ou context.GetHistoryAsync() (C#), para que o agente mantenha o contexto entre turnos.

De bring-your-own/responses/hello-world/main.py:

import asyncio
import os

from azure.ai.agentserver.responses import (
    CreateResponse,
    ResponseContext,
    ResponsesAgentServerHost,
    ResponsesServerOptions,
    TextResponse,
)
from azure.ai.projects import AIProjectClient
from azure.identity import DefaultAzureCredential

# FOUNDRY_PROJECT_ENDPOINT is auto-injected in hosted Foundry containers and
# set by 'azd ai agent run' for local development.
_endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"]
_model = os.environ["FOUNDRY_MODEL_NAME"]

_project_client = AIProjectClient(
    endpoint=_endpoint, credential=DefaultAzureCredential()
)
_responses_client = _project_client.get_openai_client().responses

app = ResponsesAgentServerHost(
    options=ResponsesServerOptions(default_fetch_history_count=20),
)


@app.response_handler
async def handler(
    request: CreateResponse,
    context: ResponseContext,
    _cancellation_signal: asyncio.Event,
):
    user_input = await context.get_input_text() or "Hello!"
    history = await context.get_history()

    # Build the model input from prior conversation turns + the current message.
    input_items = []
    for item in history:
        # Map history items to {"role": ..., "content": ...} dicts; see the
        # full sample for the unpacking helper.
        ...
    input_items.append({"role": "user", "content": user_input})

    response = await asyncio.get_running_loop().run_in_executor(
        None,
        lambda: _responses_client.create(
            model=_model,
            instructions="You are a helpful AI assistant.",
            input=input_items,
            store=False,  # platform manages history; don't store at model level
        ),
    )

    return TextResponse(context, request, text=response.output_text)


app.run()

Reference: ResponsesAgentServerHost, AIProjectClient, DefaultAzureCredential

Exemplo de protocolo de invocações

Com o protocolo de invocações, o teu handler recebe o JSON que o chamador publica e devolve o JSON que o teu código escolher. Não há histórico de conversas incorporado.

Padrão de:bring-your-own/invocations/hello-world

from starlette.requests import Request
from starlette.responses import JSONResponse, Response
from azure.ai.agentserver.invocations import InvocationAgentServerHost

app = InvocationAgentServerHost()


@app.invoke_handler
async def handle_invoke(request: Request) -> Response:
    data = await request.json()
    message = data.get("message", "Hello!")
    return JSONResponse({"echo": message})


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

Os exemplos completos incluem também hidratação do histórico de conversas, tratamento de erros, telemetria, integração com a caixa de ferramentas e configuração do Dockerfile azure.yaml .

Sonda de saúde

A plataforma envia GET /readiness para determinar se o seu contentor está pronto para servir o tráfego. Retorne 200 OK quando o contentor estiver pronto, ou um estado não 200 para sinalizar que a plataforma deve reiniciar a instância. Os adaptadores SDK registam automaticamente este endpoint.

Rede e transportes

Property Valor
Protocolo HTTP/1.1
Porta padrão 8088 (sobrescrever com a PORT variável de ambiente)
Endereço de ligação 0.0.0.0 (todas as interfaces)
TLS Terminado pela plataforma. O teu recipiente serve HTTP simples.

Desligamento gracioso

Quando a plataforma envia SIGTERM, o seu contentor deixa de aceitar novos pedidos, termina pedidos em andamento, limpa as escritas pendentes ( $HOME o sistema de ficheiros da sessão) e sai limpamente. Os adaptadores SDK tratam esta sequência automaticamente.

Variáveis do ambiente da plataforma

A plataforma injeta variáveis de ambiente no seu contentor no arranque. O seu código pode ler as seguintes variáveis chave:

Variável Purpose
FOUNDRY_PROJECT_ENDPOINT Endpoint do projeto Foundry para chamadas API
FOUNDRY_AGENT_ID O identificador de estabilidade (GUID) do agente. Use-o para encaminhamento por agente, telemetria ou particionamento de armazenamento.
FOUNDRY_AGENT_NAME O nome do agente
FOUNDRY_AGENT_VERSION A versão do agente
FOUNDRY_AGENT_SESSION_ID O ID da sessão atual

Cabeçalhos de pedido de plataforma (protocolo de contentores 2.0.0)

Estes cabeçalhos aplicam-se apenas a agentes alojados no protocolo container versão 2.0.0. No protocolo 2.0.0, a plataforma injeta-os em todos os pedidos para os endpoints do protocolo, tanto para os protocolos de Respostas como de Invocações. Eles não são enviados para endpoints de infraestrutura, como a sonda de saúde. Trata os seus valores como opacos e lê, mas não os sobreponhas.

Cabeçalho Purpose
x-agent-user-id Identificador global, por utilizador, para o chamador atual. Use-o como chave de partição principal para os dados por utilizador que o seu contentor armazena; É para uso do teu contentor e não é encaminhado para saída. O mesmo utilizador gera o mesmo valor entre agentes.
x-agent-foundry-call-id Identificador por pedido. Encaminhá-lo inalterado nas chamadas de saída para os serviços da Foundry (Armazenamento, Toolbox e outros agentes); A plataforma resolve a identidade do chamador a partir dela. Os adaptadores SDK oficiais encaminham-no automaticamente quando ligas para esses serviços através dos seus clientes.

Ambos os cabeçalhos são fiáveis – a plataforma gera-os a partir da identidade verificada – e nenhum é garantido quando executa localmente, por isso gere os valores em falta com elegância.

O SDK AgentServer expõe estas como constantes em PlatformHeaders e lê-as por ti – em FoundryAgentRequestContext.Current .NET ou get_request_context() em Python. Para a lista completa de cabeçalhos da plataforma, incluindo cabeçalhos de resposta, as somas em tempo de execução como x-agent-session-id, x-platform-server, e x-platform-error-source, consulte a referência da biblioteca Azure AI Agent Server Core.

Para saber como o protocolo 2.0.0 altera a propagação da identidade, veja Migrar agentes alojados.

Exemplo: particionar dados armazenados por sessão

Quando o seu contentor persiste em dados pertencentes ao utilizador, escreva-os pela sessão (e, para sessões partilhadas, pelo utilizador) para que um chamador não consiga ler os dados de outro. O exemplo de agente de tomada de notas faz isto derivando um caminho de ficheiro por sessão sob $HOME, onde os ficheiros também são acessíveis através da API de Ficheiros de Sessão:

# note_store.py - one JSONL file per session, stored under $HOME.
def _get_file_path(session_id: str) -> str:
    safe_id = "".join(c if c.isalnum() or c in "-_" else "_" for c in session_id)
    base_dir = os.environ.get("HOME", os.getcwd())
    return os.path.join(base_dir, f"notes_{safe_id}.jsonl")

Quando mais do que um utilizador pode partilhar uma sessão, adicione x-agent-user-id à chave. Veja : Multiplexar múltiplos utilizadores numa sessão de agente alojada.

Encaminhe cabeçalhos de pedidos personalizados para o seu contentor

A secção anterior cobre os cabeçalhos que a plataforma insere. Separadamente, o gateway encaminha apenas um conjunto fixo de cabeçalhos de pedido fornecidos pelo chamador para o seu contentor. Qualquer cabeçalho de chamador fora desse conjunto é descartado no gateway antes do pedido chegar ao teu contentor, o que mantém as credenciais e cabeçalhos internos fora do teu contentor por defeito.

Para passar os seus próprios dados contextuais para o seu contentor, use o prefixo do cabeçalho do cliente pass-through, x-client-. A plataforma encaminha todos os cabeçalhos que começam por x-client- inalterados, por isso podes enviar valores como um ID de tenant ou uma feature flag sem alterar o corpo do pedido, e depois lê-los no teu handler como qualquer outro cabeçalho de pedido. O SDK AgentServer define este prefixo como PlatformHeaders.ClientHeaderPrefix; para a lista completa de cabeçalhos da plataforma, consulte a referência da biblioteca Azure AI Agent Server Core.

O gateway encaminha estes cabeçalhos de chamadas para os endpoints do protocolo Respostas e Invocações:

Cabeçalho ou prefixo Purpose
x-client-* Qualquer cabeçalho personalizado que prefixes com x-client-. Use este prefixo para passar os seus próprios valores contextuais – como tenant, feature flags ou tokens de correlação – para o seu contentor.
accept, accept-encoding, accept-language, content-type, content-length, content-encoding Era necessário o padrão de negociação de conteúdo e cabeçalhos do corpo para analisar o pedido.
traceparent, tracestate, baggage, x-ms-client-request-id, x-request-idrequest-id, correlation-context, request-context, ms-cv IDs de rastreamento distribuído e correlação, para que os registos do seu contentor estejam ligados ao pedido de origem.
user-agent Identifica o SDK ou cliente que chama, para diagnóstico.

O gateway nunca encaminha cabeçalhos de credenciais como Authorization, ou Host, Cookie, e x-forwarded-*. Qualquer cabeçalho que não corresponda à lista de permissões é eliminado, por isso não confie em cabeçalhos personalizados fora do x-client-* prefixo que cheguem ao seu contentor.