Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
En este artículo se muestra cómo administrar sesiones para agentes hospedados en el servicio de agente Foundry. Una sesión es un espacio aislado con estado asociado a una sola carga de trabajo lógica (por ejemplo, el chat de un usuario). La plataforma conserva el sistema de archivos de la sesión ($HOME y los archivos cargados) entre turnos y períodos inactivos, por lo que el agente puede reanudar dónde se dejó. Las sesiones se conservan durante un máximo de 30 días, con un tiempo de espera de inactividad de 15 minutos que desaprovisiona el cómputo y guarda el estado hasta que se vuelva a referenciar la sesión. Para obtener más información, consulte Agentes hospedados en el servicio de agente Foundry.
Sesiones versus conversaciones
Las sesiones y las conversaciones son conceptos distintos en el servicio Foundry Agent.
| Aspecto | Sesión | Conversación |
|---|---|---|
| Lo que representa | Computación de espacio aislado y sistema de archivos persistente ($HOME, /files) |
Historial de mensajes, llamadas a herramientas y respuestas |
| Identificador | agent_session_id |
previous_response_id o conversation (solo protocolo de respuestas) |
| Se utiliza para | Cargas de archivos, estado de trabajo entre turnos | Integración de los turnos de chat |
| Administrado por | La plataforma, a través de la /sessions API |
La plataforma (Respuestas); el código de contenedor (invocaciones) |
La /sessions API de este artículo funciona de la misma manera para los agentes de protocolo de respuestas y protocolo de invocaciones. Lo que difiere es cómo se enlaza una invocación por llamada a una sesión y si la plataforma almacena el historial de conversaciones:
Protocolo de respuestas. La continuidad de la conversación no procede del identificador de sesión, sino de
previous_response_ido de un ID deconversation. Reutilizar el mismoagent_session_idno reproduce automáticamente los mensajes previos al modelo. Tiene dos formas de encadenar las respuestas por turnos:-
previous_response_id. Encadene cada nueva respuesta al identificador de la respuesta anterior. Sin estado en el cliente. Cada llamada sin unagent_session_idexplícito cae en un nuevo espacio aislado, así que incluyaagent_session_idtambién cuando necesite reutilizar los archivos cargados o el estado$HOME. -
conversation. Cree un objeto de conversación una vez a través dePOST .../endpoint/protocols/openai/conversations, y a continuación, pase suiden cada llamadaresponses.create. La plataforma almacena el historial de mensajes bajo ese identificador de conversación, y unagent_session_idpersistente se asocia automáticamente a la conversación. Las llamadas posteriores reutilizan el mismo espacio aislado sin tener que realizar un seguimiento del identificador de sesión.
-
Protocolo de invocaciones. La plataforma no almacena el historial de conversaciones; el contenedor administra cualquier estado que el agente necesite durante las interacciones. Las sesiones siguen siendo útiles para la persistencia de /uploaded-file y como un identificador estable que el código puede usar para buscar su propio estado por sesión.
Propina
El reenvío de agent_session_id en las llamadas de seguimiento los vincula al mismo espacio aislado. Los puntos de conexión de invocación no deducen la sesión solo de previous_response_id. Solo necesita ese enlace cuando, en etapas posteriores, deba ver los archivos cargados a través del punto de conexión de la sesión /files o el estado al que escribió el agente $HOME. En el caso de invocaciones completamente sin estado, puede dejar que cada llamada reciba una sesión nueva.
Cómo enlaza cada protocolo una invocación a una sesión
Los dos puntos finales de invocación aceptan el ID de sesión en ubicaciones diferentes. Utilice el mecanismo que se muestra para el protocolo que está utilizando.
| Protocolo | Punto de conexión | Dónde colocar agent_session_id |
|---|---|---|
| Respuestas | POST .../endpoint/protocols/openai/responses |
Campo de cuerpo agent_session_id de la solicitud (o use el campo conversation, que se une automáticamente a una sesión) |
| Invocaciones | POST .../endpoint/protocols/invocations |
Parámetro de cadena de consulta ?agent_session_id=<id> |
En Invocaciones, la plataforma solo lee el parámetro de consulta. Los campos denominados agent_session_id o session_id en el cuerpo de la solicitud y los encabezados como x-agent-session-id se pasan al contenedor sin modificar, pero no influyen en el espacio aislado al que se enruta la plataforma.
Requisitos previos
- Un agente hospedado implementado con una
activeversión. Consulte Administración de agentes hospedados para comprobar el estado de la versión.
-
CLI de Azure versión 2.80 o posterior, autenticado con
az login.
- SDK de Python:
azure-ai-projects>=2.1.0yazure-identity.
Azure CLI para desarrolladores versión 1.23.0 o posterior.
La extensión de Foundry para agentes:
azd ext install azure.ai.agents
Configurar variables
En los ejemplos de la API REST de este artículo se usa az rest para llamar directamente a los puntos de conexión del Servicio de Agente Foundry. Establezca las siguientes variables antes de ejecutar los 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
El --resource parámetro es necesario para todas las llamadas a los az rest puntos de conexión del plano de datos del servicio Foundry Agent. Sin ella, az rest no puede derivar la audiencia de Microsoft Entra correcta de la dirección URL y se produce un error en la autenticación.
Nota
Las operaciones de sesión son una característica en versión preliminar. Incluya el Foundry-Features: HostedAgents=V1Preview encabezado en cada solicitud REST.
Configuración del cliente
Todos los ejemplos de Python de este artículo usan la siguiente configuración 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
Las operaciones de sesión se exponen en el project.beta.agents subclient. Las llamadas a project.beta.agents funcionan sin allow_preview=True, pero project.get_openai_client(agent_name=...), que se usan en este artículo para invocar agentes de protocolo de respuestas, requiere allow_preview=True y genera ValueError sin él.
Invoque un agente y permita que la plataforma cree la sesión
Para la mayoría de los agentes, no es necesario crear una sesión de antemano. Cuando se invoca al agente sin agent_session_id, el servicio crea uno y lo devuelve en la respuesta. Capture ese identificador y páselo en llamadas posteriores cuando desee que las invocaciones posteriores compartan el mismo estado de espacio aislado; por ejemplo, los archivos que cargue a través del /files punto de conexión.
Nota
La continuidad de la sesión no es la misma que la continuidad de la conversación. En Respuestas, conserve el historial de mensajes a través de turnos pasando previous_response_id o un conversation identificador. Para las invocaciones, la plataforma no almacena el historial, así que el código del contenedor es responsable de realizar el seguimiento de cualquier estado por sesión. En ambos casos, agent_session_id solo vincula las llamadas al mismo sandbox.
Protocolo de respuestas
El punto de conexión de Respuestas devuelve una sola carga útil JSON o una secuencia de eventos Server-Sent Events (SSE), en función del campo stream del cuerpo de la solicitud. El valor predeterminado es false. Configúrelo "stream": true para recibir eventos incrementales.
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
}'
La carga de respuesta incluye la agent_session_id plataforma creada. Para seguir usando esa sesión en una llamada posterior cuando se manejen subprocesos con previous_response_id, incluya agent_session_id en el cuerpo de la solicitud.
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>"
}'
Si convierte el hilo en un identificador conversation en su lugar, la plataforma enruta automáticamente cada llamada de esa conversación a la misma agent_session_id. No necesitas pasar agent_session_id tú mismo.
Cuando llamas a get_openai_client con un agent_name, el cliente de OpenAI devuelto se enruta al punto de conexión del agente. La primera llamada crea la sesión; la respuesta incluye el nuevo agent_session_id en 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)
Si el subproceso gira con un conversation identificador en lugar de previous_response_id, la plataforma enruta automáticamente cada llamada de esa conversación a la misma agent_session_id, puede 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 invocaciones
Los agentes de invocaciones aceptan cuerpos de solicitud JSON arbitrarios que coinciden con el esquema que define el contenedor. La plataforma enruta la llamada a una sesión y reenvía el contenido a tu contenedor; el formato de respuesta se corresponde con lo que emite el contenedor. Los agentes de ejemplo y los contenedores creados con el azure-ai-agentserver-invocations SDK devuelven una secuencia SSE por defecto, con un evento terminal done que lleva el session_id (el mismo valor que agent_session_id) y un invocation_id. Su propio contenedor puede devolver JSON, NDJSON, SSE o cualquier otro tipo de contenido.
La primera llamada sin un agent_session_id parámetro de consulta crea una nueva sesión. Para reutilizar el sandbox en una llamada posterior, pase el identificador de sesión como parámetro de consulta agent_session_id.
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"}'
En el caso de un contenedor emisor de SSE como los ejemplos de Agent Service, el evento final done lleva session_id y invocation_id. Para reutilizar ese espacio aislado en una llamada posterior, pase el identificador de sesión como el parámetro de consulta agent_session_id:
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
El punto de conexión Invocations lee el identificador de sesión de la cadena de consulta. Los campos denominados agent_session_id o session_id en el cuerpo de la solicitud y los encabezados, como x-agent-session-id, se reenvían al contenedor sin modificaciones, pero no cambian a qué espacio aislado se enruta la plataforma.
El SDK de Python no proporciona un cliente de invocaciones tipado. Llame al punto de conexión con requests (o cualquier biblioteca HTTP) y autentíquese con un token de portador desde 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"}'
Claves de aislamiento
La clave de aislamiento es un valor de delimitación asociado a cada sesión. Cada sesión pertenece exactamente a una clave de aislamiento y la plataforma enruta las solicitudes de sesión para que un llamante solo vea y opere en sesiones etiquetadas con la clave que proporciona la solicitud. La misma clave se aplica de forma coherente en todos los puntos de conexión relacionados con la sesión, independientemente del protocolo que use el agente:
POST/GET/DELETE .../endpoint/sessions[/{id}]-
POST .../endpoint/protocols/openai/responses(Agentes de respuesta) -
POST .../endpoint/protocols/invocations(Agentes de invocaciones) PUT/GET/DELETE .../endpoint/sessions/{id}/files[/content]
La clave de aislamiento es un valor de creación de particiones, no un mecanismo de autenticación o autorización. El token de Microsoft Entra en la solicitud autentica al llamante y autoriza la llamada según las asignaciones de roles del proyecto. La clave de aislamiento solo limita las sesiones en las que actúa el llamante autenticado. Aplique los propios controles de acceso de la aplicación en una capa superior al punto de conexión del agente cuando necesite decidir qué usuarios pueden actuar en qué claves.
La forma en que se establece la clave depende del esquema de autorización del punto de conexión del agente, que se configura al configurar el agente (consulte Configuración de un agente):
-
Entra(valor predeterminado). La plataforma deriva la clave de aislamiento desde el token de Microsoft Entra del emisor de la llamada. Elx-ms-user-isolation-keyencabezado se acepta pero se omite. Cada llamador autenticado obtiene automáticamente su propio ámbito. -
Header. La plataforma lee la clave de aislamiento del encabezado de solicitudx-ms-user-isolation-key. Envíe una cadena estable por propietario de sesión (por ejemplo, un identificador de usuario final o de inquilino) en cada solicitud de sesión, incluidas las invocaciones y las operaciones de archivo. Se produce un error en las solicitudes sin el encabezado. La plataforma no valida el valor, por lo que el cliente es responsable de elegir la clave adecuada para cada llamada.
Crear una sesión explícitamente (avanzada)
Cree una sesión de antemano solo cuando necesite:
- Suba los archivos a la caja de arena (
/files) antes de la primera intervención del agente. - Asignar previamente una sesión a la que puede hacer referencia desde el código de cliente antes de la primera invocación.
- Fije la sesión a una versión específica del agente con
version_indicator. Cada sesión está enlazada a una sola versión en el momento de la creación. De forma predeterminada, la plataforma resuelve la versión mediante las reglas de enrutamiento de tráfico del punto de conexión del agente—por ejemplo,version_selector@latest. Paseversion_indicatorpara invalidar eso y enlazar la sesión a una versión concreta (como"2") para que más adelante siga usando esa versión incluso si publica una más reciente. El valor debe ser un identificador de versión concreto devuelto por la API de versiones del agente; los alias como@latestno se aceptan aquí.
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 el cuerpo (o envíe {}) para permitir que la plataforma seleccione la versión utilizando las reglas de enrutamiento de tráfico del punto de conexión del 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})")
El SDK requiere la isolation_key palabra clave en create_session y delete_session. El servidor solo lo aplica cuando el punto de conexión del agente está configurado para leer las claves de los encabezados; consulte Claves de aislamiento.
Para anclar la sesión a una versión específica del agente, incluya version_indicator en el cuerpo:
session = project.beta.agents.create_session(
agent_name="my-agent",
body={
"version_indicator": {"type": "version_ref", "agent_version": "2"},
},
isolation_key="user-123",
)
Las sesiones se crean automáticamente al invocar un agente a través de azd. La creación manual de sesiones no está disponible actualmente como comando independiente.
Enumerar sesiones
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})")
La lista de sesiones no está disponible actualmente como comando independiente. Use la API REST o el SDK.
Obtención de los detalles de la sesión
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}")
La administración de sesiones no está disponible actualmente como comando independiente. Use la API REST o el SDK.
Eliminación de una sesión
Al eliminar una sesión, se finaliza el espacio aislado y se liberan sus recursos. Cuando el punto de conexión del agente usa Header aislamiento, la clave de aislamiento debe coincidir con el valor usado cuando se creó la sesión. Cuando el punto de conexión usa Entra aislamiento, la plataforma limita la eliminación a la identidad que realiza la llamada.
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",
)
La administración de sesiones no está disponible actualmente como comando independiente. Use la API REST o el SDK.
Operaciones de archivos de sesión
Cargue y descargue archivos en espacios aislados de sesión del agente. Cada archivo está asignado a una sesión específica. El tamaño máximo de archivo para la carga es de 50 MB.
Nota
El SDK de Python usa session_id como palabra clave para upload_session_file y agent_session_id para get_session_files, download_session_file y delete_session_file. Use el nombre de palabra clave que se muestra en cada ejemplo.
Carga de un archivo
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",
)
El content_or_file_path parámetro acepta una cadena de ruta de acceso de archivo. El SDK lee y carga automáticamente el contenido del archivo.
azd ai agent files upload --file ./data.csv --target-path data.csv
Enumerar archivos en una sesión
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 .
Descargar un archivo
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
Eliminar un archivo
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