Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Este artigo mostra como gerenciar sessões para agentes hospedados no Serviço do Foundry Agent. Uma sessão é uma sandbox isolada com manutenção de estado, vinculada a uma única tarefa lógica (por exemplo, o chat de um usuário). A plataforma persiste o sistema de arquivos da sessão ($HOME e arquivos carregados) ao longo dos turnos e períodos de inatividade, para que o agente possa retomar de onde parou. As sessões persistem por até 30 dias, com um limite de inatividade de 15 minutos que desprovisiona a computação e salva o estado até que a sessão seja referenciada novamente. Para contexto, consulte agentes hospedados no Serviço de Agentes do Foundry.
Sessões versus conversas
Sessões e conversas são conceitos distintos no Serviço do Foundry Agent:
| Aspecto | Sessão | Conversa |
|---|---|---|
| O que ele representa | Computação em sandbox e sistema de arquivos persistente ($HOME, /files) |
Histórico de mensagens, chamadas de ferramenta e respostas |
| Identificador | agent_session_id |
previous_response_id ou conversation (somente protocolo de respostas) |
| Usado para | Uploads de arquivo, estado de trabalho entre turnos | Organização de threads em um chat |
| Gerenciado por | A plataforma, por meio da /sessions API |
A plataforma (respostas); seu código de contêiner (Invocações) |
A API /sessions neste artigo funciona da mesma maneira para agentes de protocolo de respostas e de protocolo de invocações. O que difere é como uma invocação por chamada se associa a uma sessão e se a plataforma armazena o histórico de conversas:
Protocolo de respostas. A continuidade da conversa provém de
previous_response_idou de umaconversationID, não da ID da sessão. Reutilizar o mesmoagent_session_idpor si só não reproduz as mensagens anteriores no modelo. Você tem duas maneiras de encadear as voltas de respostas:-
previous_response_id. Encadeia cada nova resposta à ID da resposta anterior. Sem estado no cliente. Cada chamada sem umagent_session_idexplícito cai em uma nova área restrita, portanto, incluaagent_session_idtambém quando você precisar reutilizar$HOMEestado ou arquivos carregados. -
conversation. Crie um objeto de conversa uma vez usandoPOST .../endpoint/protocols/openai/conversationse, em seguida, passe seuidem cada chamadaresponses.create. A plataforma armazena o histórico de mensagens sob esse ID de conversa, e um elemento estávelagent_session_idé automaticamente associado à conversa. As chamadas subsequentes reutilizam o mesmo sandbox sem que você precise acompanhar o ID da sessão.
-
Protocolo de invocações. A plataforma não armazena o histórico de conversas; o contêiner gerencia qualquer estado de que seu agente precisa ao longo das interações. As sessões ainda são úteis para a persistência de arquivos carregados e como um identificador estável que seu código pode usar para localizar seu próprio estado por sessão.
Dica
Enviar agent_session_id de volta em chamadas de acompanhamento as associa à mesma área restrita. Os endpoints de invocação não inferem a sessão apenas de previous_response_id. Você só precisa dessa vinculação quando os turnos posteriores devem ver os arquivos carregados por meio do ponto de extremidade da sessão /files ou do estado em que o agente escreveu $HOME. Para invocações sem estado puras, você pode permitir que cada chamada obtenha uma nova sessão.
Como cada protocolo associa uma invocação a uma sessão
Dois endpoints de invocação aceitam a ID da sessão em locais diferentes. Use o mecanismo mostrado para o protocolo que você está chamando.
| Protocolo | Ponto de Extremidade | Onde colocar agent_session_id |
|---|---|---|
| Respostas | POST .../endpoint/protocols/openai/responses |
Solicitar campo agent_session_id do corpo (ou usar o conversation campo, que associa automaticamente uma sessão) |
| Invocações | POST .../endpoint/protocols/invocations |
Parâmetro de cadeia de caracteres de consulta ?agent_session_id=<id> |
Para Invocações, a plataforma lê apenas o parâmetro de consulta. Campos nomeados agent_session_id ou session_id no corpo da solicitação e cabeçalhos como x-agent-session-id são passados para o contêiner sem alterações, mas não influenciam na escolha do sandbox para o qual a plataforma roteia.
Pré-requisitos
- Um agente hospedeiro implantado com uma
activeversão. Consulte Gerenciar agentes hospedados para saber como verificar o status da versão.
-
CLI do Azure versão 2.80 ou posterior, autenticada com
az login.
- Python SDK:
azure-ai-projects>=2.1.0eazure-identity.
Azure CLI do Desenvolvedor versão 1.23.0 ou posterior.
A extensão de agentes Foundry
azd ext install azure.ai.agents
Configurar variáveis
Os exemplos da API REST neste artigo usam az rest para chamar diretamente os endpoints Foundry Agent Service. Defina as seguintes variáveis antes de executar os comandos:
ACCOUNT_NAME="<your-foundry-account-name>"
PROJECT_NAME="<your-project-name>"
BASE_URL="https://${ACCOUNT_NAME}.services.ai.azure.com/api/projects/${PROJECT_NAME}"
API_VERSION="v1"
RESOURCE="https://ai.azure.com"
Importante
O parâmetro --resource é necessário para todas as chamadas az rest para endpoints do plano de dados do Serviço Foundry Agent. Sem ele, az rest não pode derivar o público-alvo Microsoft Entra correto da URL e a autenticação falha.
Nota
As operações de sessão são um recurso de visualização. Inclua o Foundry-Features: HostedAgents=V1Preview cabeçalho em cada solicitação REST.
Configurar o cliente
Todos os exemplos de Python neste artigo usam a seguinte configuração de cliente:
from azure.identity import DefaultAzureCredential
from azure.ai.projects import AIProjectClient
project = AIProjectClient(
endpoint="<your-project-endpoint>",
credential=DefaultAzureCredential(),
allow_preview=True,
)
Nota
As operações de sessão são expostas sob a project.beta.agents subcliente. As chamadas para project.beta.agents funcionam sem allow_preview=True, mas project.get_openai_client(agent_name=...)—usado neste artigo para invocar agentes de protocolo de resposta—exige allow_preview=True e gera ValueError sem ele.
Invocar um agente e permitir que a plataforma crie a sessão
Para a maioria dos agentes, você não precisa criar uma sessão com antecedência. Quando você invoca o agente sem um agent_session_id, o serviço cria um e o retorna na resposta. Capture um ID e passe-o em chamadas posteriores quando desejar que as invocações subsequentes compartilhem o mesmo estado de sandbox — por exemplo, arquivos carregados por meio do /files endpoint.
Nota
A continuidade da sessão não é a mesma que a continuidade da conversa. Para respostas, mantenha o histórico de mensagens entre as interações passando previous_response_id ou um ID conversation. Para Invocações, a plataforma não armazena o histórico— seu código de contêiner é responsável por acompanhar qualquer estado por sessão. Em ambos os casos, agent_session_id apenas vincula chamadas à mesma área restrita.
Protocolo de respostas
O endpoint Responses retorna um payload JSON único ou um fluxo SSE (Eventos Enviados pelo Servidor), dependendo do campo stream no corpo da solicitação. O padrão é false. Defina "stream": true para receber eventos incrementais.
AGENT_NAME="my-agent"
az rest --method POST \
--url "${BASE_URL}/agents/${AGENT_NAME}/endpoint/protocols/openai/responses?api-version=${API_VERSION}" \
--resource "${RESOURCE}" \
--headers "Foundry-Features=HostedAgents=V1Preview" \
--body '{
"input": "Find me hotels in Seattle under $200 per night",
"stream": false
}'
O conteúdo da resposta inclui a agent_session_id plataforma criada. Para continuar usando essa sessão em uma chamada posterior ao realizar threading com previous_response_id, inclua agent_session_id no corpo da solicitação.
az rest --method POST \
--url "${BASE_URL}/agents/${AGENT_NAME}/endpoint/protocols/openai/responses?api-version=${API_VERSION}" \
--resource "${RESOURCE}" \
--headers "Foundry-Features=HostedAgents=V1Preview" \
--body '{
"input": "Recommend one of those hotels",
"stream": false,
"agent_session_id": "<session-id-from-first-response>",
"previous_response_id": "<id-from-first-response>"
}'
Se você altera o thread para usar uma conversation ID, a plataforma roteia automaticamente cada chamada para a mesma agent_session_id conversa. Você não precisa passar agent_session_id por conta própria.
Quando você chama get_openai_client com um agent_name, o cliente OpenAI retornado é roteado para o ponto de extremidade do agente. A primeira chamada cria a sessão; a resposta carrega o novo agent_session_id em model_extra.
openai_client = project.get_openai_client(agent_name="my-agent")
response = openai_client.responses.create(
input="Find me hotels in Seattle under $200 per night",
)
session_id = response.model_extra.get("agent_session_id")
print(f"Session: {session_id}")
print(f"Response: {response.output_text}")
# Reuse the session and thread the conversation on a later turn.
follow_up = openai_client.responses.create(
input="Recommend one of those hotels",
previous_response_id=response.id,
extra_body={"agent_session_id": session_id},
)
print(follow_up.output_text)
Se o thread for girado com uma conversation ID em vez de previous_response_id, a plataforma roteia automaticamente cada chamada dessa conversa para a mesma agent_session_id— você pode omitir extra_body={"agent_session_id": ...}:
conversation = openai_client.conversations.create()
first = openai_client.responses.create(
input="Find me hotels in Seattle under $200 per night",
extra_body={"conversation": conversation.id},
)
follow_up = openai_client.responses.create(
input="Recommend one of those hotels",
extra_body={"conversation": conversation.id},
)
azd ai agent invoke --input "Find me hotels in Seattle under $200 per night"
Protocolo de invocações
Os agentes de invocações aceitam corpos de solicitação JSON arbitrários que correspondem ao esquema definido pelo contêiner. A plataforma roteia a chamada para uma sessão e encaminha o corpo da chamada para o seu contêiner; o formato de resposta é o que o contêiner emite. Agentes de exemplo e contêineres criados com o azure-ai-agentserver-invocations SDK retornam um fluxo SSE por padrão, com um evento terminal done que carrega o session_id (o mesmo valor que agent_session_id) e um invocation_id. Seu próprio contêiner pode retornar JSON, NDJSON, SSE ou qualquer outro tipo de conteúdo.
A primeira chamada sem um agent_session_id parâmetro de consulta cria uma nova sessão. Para reutilizar o sandbox em uma chamada posterior, passe o ID da sessão como o parâmetro de agent_session_id consulta.
AGENT_NAME="my-agent"
# First call — platform creates a new session.
az rest --method POST \
--url "${BASE_URL}/agents/${AGENT_NAME}/endpoint/protocols/invocations?api-version=${API_VERSION}" \
--resource "${RESOURCE}" \
--headers "Foundry-Features=HostedAgents=V1Preview" \
--body '{"input": "Hello"}'
Para um contêiner emissor de SSE, como os exemplos do Serviço do Agente, o evento final done carrega session_id e um invocation_id. Para reutilizar esse sandbox em uma chamada posterior, passe a ID da sessão como o parâmetro de agent_session_id consulta:
SESSION_ID="<session_id-from-first-response>"
az rest --method POST \
--url "${BASE_URL}/agents/${AGENT_NAME}/endpoint/protocols/invocations?api-version=${API_VERSION}&agent_session_id=${SESSION_ID}" \
--resource "${RESOURCE}" \
--headers "Foundry-Features=HostedAgents=V1Preview" \
--body '{"input": "Continue our previous discussion"}'
Importante
O endpoint Invocações lê o identificador da sessão da cadeia de caracteres de consulta. Campos nomeados agent_session_id ou session_id no corpo da solicitação e cabeçalhos como x-agent-session-id são encaminhados para o contêiner intocado, mas não alteram para qual área restrita a plataforma roteia.
O SDK do Python não fornece um cliente de invocações tipado. Chame o endpoint com requests (ou qualquer biblioteca HTTP) e autentique com um token bearer de azure-identity:
import json
import requests
from azure.identity import DefaultAzureCredential
credential = DefaultAzureCredential()
token = credential.get_token("https://ai.azure.com/.default").token
headers = {
"Authorization": f"Bearer {token}",
"Foundry-Features": "HostedAgents=V1Preview",
"Content-Type": "application/json",
}
base = "<your-project-endpoint>/agents/my-agent/endpoint/protocols/invocations?api-version=v1"
# First call — platform creates a new session.
response = requests.post(base, headers=headers, data=json.dumps({"input": "Hello"}))
for line in response.iter_lines(decode_unicode=True):
if line.startswith("data:"):
event = json.loads(line[len("data:"):].strip())
if event.get("type") == "done":
session_id = event["session_id"]
# Reuse the session on a later call.
requests.post(
f"{base}&agent_session_id={session_id}",
headers=headers,
data=json.dumps({"input": "Continue our previous discussion"}),
)
azd ai agent invoke --input '{"input": "Hello"}'
Chaves de isolamento
A chave de isolamento é um valor de escopo anexado a cada sessão. Cada sessão pertence a exatamente uma chave de isolamento e a plataforma roteia solicitações de sessão para que um chamador só veja e opere em sessões marcadas com a chave fornecida pela solicitação. A mesma chave se aplica consistentemente em todos os pontos de extremidade relacionados à sessão, independentemente de qual protocolo o agente usa:
POST/GET/DELETE .../endpoint/sessions[/{id}]-
POST .../endpoint/protocols/openai/responses(Agentes de respostas) -
POST .../endpoint/protocols/invocations(Agentes de invocações) PUT/GET/DELETE .../endpoint/sessions/{id}/files[/content]
A chave de isolamento é um valor de particionamento, não um mecanismo de autenticação ou autorização. O token Microsoft Entra na solicitação autentica o chamador e autoriza a chamada com base nas atribuições de função do projeto. A chave de isolamento limita apenas em quais sessões o chamador autenticado age. Aplique os controles de acesso do próprio aplicativo em uma camada acima do ponto de extremidade do agente quando você precisar decidir quais usuários podem agir em quais chaves.
Como a chave é definida depende do esquema de autorização do ponto de extremidade do agente, que você configura ao configurar o agente (consulte Configurar um agente):
-
Entra(padrão). A plataforma deriva a chave de isolamento do token Microsoft Entra do chamador. Ox-ms-user-isolation-keycabeçalho é aceito, mas ignorado. Cada chamador autenticado obtém automaticamente seu próprio escopo. -
Header. A plataforma lê a chave de isolamento dox-ms-user-isolation-keycabeçalho da requisição. Envie uma cadeia de caracteres estável para cada proprietário de sessão (por exemplo, um usuário final ou identificador de locatário) em cada solicitação de sessão, incluindo invocações e operações de arquivo. As solicitações sem o cabeçalho falham. A plataforma não valida o valor, portanto, seu cliente é responsável por escolher a chave certa para cada chamada.
Criar uma sessão explicitamente (avançado)
Crie uma sessão com antecedência somente quando precisar:
- Carregue arquivos no sandbox (
/files) antes da primeira vez de atuação do agente. - Pré-alocar uma sessão que pode ser referenciada no código do cliente antes da primeira invocação.
- Fixe a sessão em uma versão específica do agente com
version_indicator. Cada sessão é associada a uma única versão no momento da criação. Por padrão, a plataforma resolve a versão usando as regras de roteamento de tráfego do ponto de extremidade do agente (version_selector)— por exemplo,@latest. Passeversion_indicatorpara substituir isso e associe a sessão a uma versão concreta (como"2") para que, posteriormente, continue usando essa versão mesmo se você publicar uma versão mais recente. O valor deve ser um identificador de versão concreto retornado pela API de versões do agente; Aliases como@latestnão são aceitos aqui.
AGENT_NAME="my-agent"
az rest --method POST \
--url "${BASE_URL}/agents/${AGENT_NAME}/endpoint/sessions?api-version=${API_VERSION}" \
--resource "${RESOURCE}" \
--headers "x-ms-user-isolation-key=user-123" "Foundry-Features=HostedAgents=V1Preview" \
--body '{
"version_indicator": {
"type": "version_ref",
"agent_version": "2"
}
}'
Omita o corpo (ou envie {}) para permitir que a plataforma escolha a versão usando as regras de roteamento de tráfego do ponto de extremidade do agente.
session = project.beta.agents.create_session(
agent_name="my-agent",
body={},
isolation_key="user-123",
)
print(f"Session created (ID: {session.agent_session_id}, status: {session.status})")
O SDK requer a isolation_key palavra-chave e create_sessiondelete_session. O servidor aplica a configuração apenas quando o endpoint do agente está configurado para ler chaves dos cabeçalhos, conforme detalhado em chaves de isolamento.
Para fixar a sessão em uma versão específica do agente, inclua version_indicator no corpo:
session = project.beta.agents.create_session(
agent_name="my-agent",
body={
"version_indicator": {"type": "version_ref", "agent_version": "2"},
},
isolation_key="user-123",
)
As sessões são criadas automaticamente quando você invoca um agente por meio de azd. A criação manual de sessão não está disponível no momento como um comando autônomo.
Listar sessões
az rest --method GET \
--url "${BASE_URL}/agents/my-agent/endpoint/sessions?api-version=${API_VERSION}" \
--resource "${RESOURCE}" \
--headers "Foundry-Features=HostedAgents=V1Preview"
sessions = project.beta.agents.list_sessions(agent_name="my-agent")
for item in sessions:
print(f"Session: {item.agent_session_id} (status: {item.status})")
No momento, a listagem de sessão não está disponível como um comando autônomo. Use a API REST ou o SDK.
Obter detalhes da sessão
SESSION_ID="<session-id>"
az rest --method GET \
--url "${BASE_URL}/agents/my-agent/endpoint/sessions/${SESSION_ID}?api-version=${API_VERSION}" \
--resource "${RESOURCE}" \
--headers "Foundry-Features=HostedAgents=V1Preview"
session = project.beta.agents.get_session(
agent_name="my-agent",
session_id="<session-id>",
)
print(f"Session ID: {session.agent_session_id}, Status: {session.status}")
Atualmente, o gerenciamento de sessão não está disponível como um comando autônomo. Use a API REST ou o SDK.
Excluir uma sessão
A exclusão de uma sessão encerra o sandbox e libera seus recursos. Quando o endpoint do agente usa Header isolamento, a chave de isolamento deve corresponder ao valor usado na criação da sessão. Quando o ponto de extremidade usa Entra isolamento, a plataforma define o escopo da exclusão para a identidade de chamada.
SESSION_ID="<session-id>"
ISOLATION_KEY="user-123"
az rest --method DELETE \
--url "${BASE_URL}/agents/my-agent/endpoint/sessions/${SESSION_ID}?api-version=${API_VERSION}" \
--resource "${RESOURCE}" \
--headers "x-ms-user-isolation-key=${ISOLATION_KEY}" "Foundry-Features=HostedAgents=V1Preview"
project.beta.agents.delete_session(
agent_name="my-agent",
session_id="<session-id>",
isolation_key="user-123",
)
Atualmente, o gerenciamento de sessão não está disponível como um comando autônomo. Use a API REST ou o SDK.
Operações de arquivo de sessão
Carregue e baixe arquivos nas áreas restritas da sessão do agente. Cada arquivo tem o escopo de uma sessão específica. O tamanho máximo do arquivo para upload é de 50 MB.
Nota
O SDK do Python usa session_id como a palavra-chave para upload_session_file e agent_session_id para get_session_files, download_session_file e delete_session_file. Use o nome da palavra-chave mostrado em cada exemplo.
Carregar um arquivo
SESSION_ID="<session-id>"
az rest --method PUT \
--url "${BASE_URL}/agents/my-agent/endpoint/sessions/${SESSION_ID}/files/content?api-version=${API_VERSION}&path=data.csv" \
--resource "${RESOURCE}" \
--body @data.csv \
--headers "Content-Type=application/octet-stream" "Foundry-Features=HostedAgents=V1Preview"
project.beta.agents.upload_session_file(
agent_name="my-agent",
session_id="<session-id>",
content_or_file_path="./data.csv",
path="data.csv",
)
O content_or_file_path parâmetro aceita uma cadeia de caracteres de caminho de arquivo. O SDK lê e carrega o conteúdo do arquivo automaticamente.
azd ai agent files upload --file ./data.csv --target-path data.csv
Listar arquivos em uma sessão
SESSION_ID="<session-id>"
az rest --method GET \
--url "${BASE_URL}/agents/my-agent/endpoint/sessions/${SESSION_ID}/files?api-version=${API_VERSION}&path=." \
--resource "${RESOURCE}" \
--headers "Foundry-Features=HostedAgents=V1Preview"
files = project.beta.agents.get_session_files(
agent_name="my-agent",
agent_session_id="<session-id>",
path=".",
)
for entry in files.entries:
print(f" {entry['name']} (size: {entry['size']}, directory: {entry['is_directory']})")
azd ai agent files list .
Baixar um arquivo
SESSION_ID="<session-id>"
az rest --method GET \
--url "${BASE_URL}/agents/my-agent/endpoint/sessions/${SESSION_ID}/files/content?api-version=${API_VERSION}&path=data.csv" \
--resource "${RESOURCE}" \
--headers "Foundry-Features=HostedAgents=V1Preview" \
--output-file output.csv
content_bytes = b"".join(
project.beta.agents.download_session_file(
agent_name="my-agent",
agent_session_id="<session-id>",
path="data.csv",
)
)
with open("./output.csv", "wb") as f:
f.write(content_bytes)
azd ai agent files download --file data.csv --target-path ./output.csv
Excluir um arquivo
SESSION_ID="<session-id>"
az rest --method DELETE \
--url "${BASE_URL}/agents/my-agent/endpoint/sessions/${SESSION_ID}/files?api-version=${API_VERSION}&path=data.csv" \
--resource "${RESOURCE}" \
--headers "Foundry-Features=HostedAgents=V1Preview"
project.beta.agents.delete_session_file(
agent_name="my-agent",
agent_session_id="<session-id>",
path="data.csv",
)
azd ai agent files remove --file data.csv