Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Utilisez le package langchain_azure_ai.agents.hosting pour exposer un graphique LangGraph compilé via les protocoles de Microsoft Foundry agents hébergés. Le package d’hébergement vous permet de conserver la logique de votre agent LangChain et LangGraph dans le code tandis que Foundry gère le runtime hébergé, les sessions, la mise à l’échelle, l’identité et les points de terminaison de protocole.
Dans cet article, vous allez créer un agent LangGraph minimal, l’exposer via le protocole Réponses ou Appels, le tester via HTTP et le déployer sur Foundry avec l’interface CLI développeur Azure ou l’extension Foundry Toolkit Visual Studio Code.
Vous allez également apprendre à migrer un projet LangGraph existant sans modifier son code ou sa configuration.
Prerequisites
- Un abonnement Azure. Créez-en un gratuitement.
- Un projet Foundry.
- Un modèle de conversation déployé, tel que
gpt-4.1ougpt-5-mini. - Python 3.10 ou version ultérieure.
- Azure CLI connecté (
az login) afin queDefaultAzureCredentialpuisse s’authentifier.
Installer le package
Installez langchain-azure-ai la version 1.2.9 ou ultérieure avec l’hébergement supplémentaire :
pip install -U "langchain-azure-ai[hosting]>=1.2.9" azure-identity
L’élément hosting supplémentaire installe les bibliothèques de protocole Foundry utilisées par les serveurs hôtes :
-
azure-ai-agentserver-responsespour l’endpoint compatible OpenAI/responses. -
azure-ai-agentserver-invocationspour le point de terminaison générique/invocations.
Choisir un protocole d’hébergement
Les agents hébergés peuvent exposer un ou plusieurs protocoles. Commencez par Responses pour la majorité des agents conversationnels.
| Protocol | Classe d’hôte | Point de terminaison | À utiliser lorsque |
|---|---|---|---|
| Responses | ResponsesHostServer |
/responses |
Vous souhaitez une conversation compatible OpenAI, la diffusion en continu, l’historique des réponses et le thread de conversation. |
| Appels | InvocationsHostServer |
/invocations |
Vous souhaitez une forme JSON personnalisée, un point de terminaison de style webhook ou un traitement non conversationnel. |
Pour plus d’informations sur le comportement et les sessions de protocole, consultez Agents hébergés et Gérer les sessions d’agent hébergé.
Configurer des variables d’environnement
Définissez le point de terminaison du projet et le nom de déploiement de modèle pour le développement local :
export FOUNDRY_PROJECT_ENDPOINT="https://<resource>.services.ai.azure.com/api/projects/<project>"
export FOUNDRY_MODEL_NAME="gpt-4.1"
Lorsque le même code s’exécute en tant qu’agent hébergé dans Foundry, la plateforme injecte FOUNDRY_PROJECT_ENDPOINT. Si vous utilisez azd ai agent init avec un exemple azure.yaml, le projet généré utilise également FOUNDRY_MODEL_NAME pour le déploiement du modèle sélectionné.
Protocole des réponses
Utilisez le protocole Responses lorsque vous souhaitez un point de terminaison de chat compatible OpenAI avec la diffusion en continu, l’historique des réponses et les fils de conversation.
Créer un hôte de réponses
Créez un fichier nommé main.py avec un agent LangGraph minimal qui utilise un modèle Foundry. Ce schéma correspond à l’exemple de base de Responses dans le dépôt source langchain-azure-ai.
import os
from azure.ai.projects import AIProjectClient
from azure.identity import DefaultAzureCredential, get_bearer_token_provider
from langchain.agents import create_agent
from langchain_openai import ChatOpenAI
from langchain_azure_ai.agents.hosting import ResponsesHostServer
_AZURE_AI_SCOPE = "https://ai.azure.com/.default"
def build_chat_model() -> ChatOpenAI:
project_endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"].rstrip("/")
deployment = os.environ.get("FOUNDRY_MODEL_NAME", "gpt-4.1")
credential = DefaultAzureCredential()
project = AIProjectClient(endpoint=project_endpoint, credential=credential)
openai_client = project.get_openai_client()
token_provider = get_bearer_token_provider(credential, _AZURE_AI_SCOPE)
return ChatOpenAI(
model=deployment,
base_url=str(openai_client.base_url),
api_key=token_provider,
)
def main() -> None:
graph = create_agent(build_chat_model(), tools=[])
port = int(os.environ.get("PORT", "8088"))
ResponsesHostServer(graph).run(port=port)
if __name__ == "__main__":
main()
Ce que fait cet extrait de code : Crée un agent LangGraph avec LangChain, create_agentle connecte au point de terminaison de modèle compatible OpenAI du projet Foundry et transmet le graphique compilé à ResponsesHostServer. L’hôte démarre un serveur HTTP et expose le graphique via POST /responses. Par défaut, le serveur est lié au port 8088ou à la valeur de la PORT variable d’environnement lorsqu’un port est défini.
Note
Les agents profonds sont hébergés de la même façon que les autres agents LangGraph. Passez l’agent directement à ResponsesHostServer.
agent = create_deep_agent(...)
ResponsesHostServer(agent).run(port=port)
Exécutez l’application localement :
python main.py
Testez le point de terminaison Responses
Envoyez une demande de réponses sans diffusion en continu au serveur local.
Bash:
curl -sS -H "Content-Type: application/json" \
-X POST http://localhost:8088/responses \
-d '{"input":"Give me one practical tip for testing hosted agents.","stream":false}'
PowerShell :
$body = @{
input = "Give me one practical tip for testing hosted agents."
stream = $false
} | ConvertTo-Json
Invoke-RestMethod `
-Uri http://localhost:8088/responses `
-Method Post `
-Body $body `
-ContentType "application/json"
Pour les réponses diffusées en continu, définissez stream sur true. L’hôte émet des événements envoyés par le serveur d’API Réponses, tels que response.created, response.output_text.deltaet response.completed.
Conversations
ResponsesHostServer prend en charge deux modèles d’état de conversation. Le modèle qu’il utilise dépend du fait que votre graphique compilé possède un point de contrôle LangGraph.
| Configuration du graphe | Source de conversation | Ce que l’hôte envoie au graphe lors des tours suivants |
|---|---|---|
| Graph sans point de contrôle | Historique des réponses à partir du runtime du protocole | Historique des réponses antérieures plus l’entrée de requête actuelle |
| Graph compilé avec un point de contrôle | État de point de contrôle LangGraph associé à la conversation ou au fil de réponse | Entrée de requête actuelle uniquement |
Utilisez un point de contrôle lorsque votre graphique a besoin de l’état d’exécution LangGraph, des interruptions ou de l’état local du nœud entre les tours. Pour les tests locaux, vous pouvez utiliser un point de contrôle en mémoire :
from langgraph.checkpoint.memory import MemorySaver
graph = create_agent(
build_chat_model(),
tools=[],
checkpointer=MemorySaver(),
)
Pour les assistants hébergés en production, utilisez un point de contrôle durable au lieu d’un point de contrôle en mémoire afin que l’état du graphique survive aux redémarrages de conteneur.
Les clients poursuivent une conversation Responses en transmettant previous_response_id ou un identifiant conversation. Pour les tests locaux, chaînez l’ID de réponse précédent dans la requête suivante :
POST http://localhost:8088/responses
Content-Type: application/json
{
"input": "Can you make that more concise?",
"previous_response_id": "<previous-response-id>",
"stream": false
}
Lorsque l’assistant s’exécute dans Foundry, le même schéma fonctionne via le point de terminaison Responses de l’assistant hébergé. Si les tours suivants nécessitent également le même système de fichiers du bac à sable hébergé, incluez agent_session_id ou utilisez un identifiant conversation. Pour plus d’informations, consultez Gérer les sessions de l’agent hébergé.
Intervention humaine
Si votre graphique utilise des appels LangGraph interrupt() , ResponsesHostServer affiche les interruptions en attente via les éléments de sortie de l’API Réponses standard :
- Élément
function_callnommé__hosted_agent_adapter_interrupt__. - Élément
mcp_approval_requestavecserver_labeldéfini surlanggraph.
Les clients peuvent reprendre le graphe en envoyant soit un élément function_call_output dont le call_id correspond à l’ID d’interruption, soit un élément mcp_approval_response dont le approval_request_id correspond à l’ID d’interruption. Utilisez function_call_output lorsque vous devez envoyer une charge utile LangGraph Command riche comportant des champs resume, update ou goto. Utiliser mcp_approval_response pour un flux d’approbation ou de rejet simple.
Protocole d'invocation
Utilisez InvocationsHostServer quand vos appelants ne peuvent pas utiliser la forme de requête de l’API Réponses ou lorsque votre scénario n’est pas une conversation de conversation. L’hôte Invocations par défaut accepte une chaîne message et un indicateur optionnel stream.
Créer un hôte d’invocation
Utilisez la même fonction de génération de modèle à partir de l’exemple Réponses, mais commencez InvocationsHostServer au lieu de ResponsesHostServer.
import os
from langchain.agents import create_agent
from langgraph.checkpoint.memory import MemorySaver
from langchain_azure_ai.agents.hosting import InvocationsHostServer
def main() -> None:
graph = create_agent(
build_chat_model(),
tools=[],
checkpointer=MemorySaver(),
)
port = int(os.environ.get("PORT", "8088"))
InvocationsHostServer(graph).run(port=port)
if __name__ == "__main__":
main()
Ce que fait cet extrait de code : Héberge l’agent LangGraph via POST /invocations. Le point de contrôle MemorySaver offre une continuité multitour locale pour un ID de session donné. En production, utilisez un point de contrôle persistant pour que l’état soit conservé lors des redémarrages du conteneur.
Note
Les agents profonds sont hébergés de la même façon que les autres agents LangGraph. Passez l’agent directement à InvocationsHostServer.
agent = create_deep_agent(...)
InvocationsHostServer(agent).run(port=port)
Tester le point de terminaison des appels
Envoyez une demande de non-diffusion en continu :
curl -i -X POST http://localhost:8088/invocations \
-H "Content-Type: application/json" \
-d '{"message":"My name is Alice.","stream":false}'
Les demandes de non diffusion en continu retournent JSON sous cette forme :
{
"response": "Assistant text"
}
Pour les conversations à plusieurs échanges, réutilisez l’en-tête de réponse x-agent-session-id comme paramètre de requête agent_session_id dans la requête suivante :
curl -X POST "http://localhost:8088/invocations?agent_session_id=<session-id>" \
-H "Content-Type: application/json" \
-d '{"message":"What is my name?"}'
Les requêtes de streaming renvoient des événements text/event-stream avec des charges utiles de token :
curl -N -X POST http://localhost:8088/invocations \
-H "Content-Type: application/json" \
-d '{"message":"Count to 5.","stream":true}'
Le flux contient des événements de jeton suivis d’un événement terminal done :
data: {"token": "..."}
event: done
data: {}
Personnaliser le schéma de requête
Pour personnaliser le corps de la requête, créez une sous-classe de InvocationsHostServer et redéfinissez parse_request. Vous pouvez également remplacer build_input pour mapper les données analysées à un état de graphe personnalisé.
from starlette.requests import Request
from langchain_azure_ai.agents.hosting import InvocationsHostServer
class TicketHostServer(InvocationsHostServer):
async def parse_request(self, request: Request) -> tuple[str, bool]:
data = await request.json()
ticket_id = data["ticket_id"]
description = data["description"]
stream = bool(data.get("stream", False))
return f"Summarize ticket {ticket_id}: {description}", stream
if __name__ == "__main__":
TicketHostServer(graph).run()
Ce que fait cet extrait de code : Accepte une charge utile de ticket personnalisée et la convertit en message utilisateur unique avant que l’hôte appelle le graphique. Pour obtenir un état de graphique plus complexe, remplacez build_input au lieu d’aplatir la requête en texte.
Déployer
Vous pouvez déployer à l’aide de l’interface CLI Azure développeur ou de l’extension Foundry Toolkit Visual Studio Code. Le flux de travail de l’interface Azure Developer CLI utilise des fichiers azure.yaml d’exemple et Docker. Le flux d’extension offre une expérience de déploiement guidée dans Visual Studio Code.
Le déploiement d’un agent hébergé nécessite le rôle Foundry Project Manager dans le projet. Pour plus d’informations, consultez Déployer un agent hébergé.
Déployer avec Azure Developer CLI
Le langchain-azure-ai référentiel source inclut des exemples d’agents hébergés que vous pouvez exécuter et déployer à l’aide de l’interface CLI Azure développeur. Le flux utilise les azure.yaml, Dockerfile et main.py de chaque échantillon. Pour plus d’informations sur la configuration de l’agent hébergé, azure.yamlconsultez Author azure.yaml pour les agents hébergés.
Installez l’extension de l’agent AI et connectez-vous avant d’initialiser un exemple :
azd ext install azure.ai.agents
azd auth login
Docker doit s’exécuter localement, car azd ai agent run génère l’image conteneur déclarée dans le fichier Dockerfile de l’exemple. Pour plus de détails sur la commande, consultez la documentation de référence de Azure Developer CLI.
Initialiser à partir d’un exemple azure.yaml
Créez un dossier et initialisez-le à partir d’un exemple azure.yaml. Remplacez l’URL par l’exemple azure.yaml que vous souhaitez utiliser.
mkdir my-langchain-agent
cd my-langchain-agent
azd ai agent init -m https://github.com/langchain-ai/langchain-azure/blob/main/samples/hosting/langgraph-hosted-agents/responses/01_basic/azure.yaml
Suivez les instructions affichées par azd ai agent init. Si vous n’avez pas encore de déploiement de projet et de modèle Foundry, le flux d’initialisation peut vous guider tout au long de leur création.
Exécutez localement le conteneur
Exécutez l’hôte de l’agent localement via azd:
azd ai agent run
L’hôte fonctionne sur http://127.0.0.1:8088. Dans un autre terminal, appelez directement le point de terminaison de protocole local :
curl -X POST http://127.0.0.1:8088/responses \
-H "Content-Type: application/json" \
-d '{"input": "Hello!"}'
Équivalent PowerShell :
(Invoke-WebRequest -Uri http://127.0.0.1:8088/responses `
-Method POST -ContentType 'application/json' `
-Body '{"input": "Hello!"}').Content
Vous pouvez également appeler l’agent local via azd:
azd ai agent invoke --local "Hello!"
Déployer sur Foundry
Si le projet initialisé utilise un nouveau projet foundry et un déploiement de modèle, approvisionnez d’abord les ressources Azure :
azd provision
Déployez l’agent :
azd deploy
Le déploiement place l’assistant dans une image de conteneur, publie cette image dans le registre de conteneurs provisionné et la déploie dans l’environnement d’exécution de l’assistant hébergé de Foundry.
L’infrastructure d’hébergement Foundry injecte des variables d’environnement runtime dans l’agent, notamment :
-
FOUNDRY_PROJECT_ENDPOINT: URL du point de terminaison du projet Foundry où l’agent est déployé. -
FOUNDRY_MODEL_NAME: nom de déploiement du modèle sélectionné pendantazd ai agent init. -
APPLICATIONINSIGHTS_CONNECTION_STRING: chaîne de connexion de l'instance Application Insights du projet.
Pour obtenir des concepts de déploiement complets, des autorisations et des détails de gestion, consultez Déployer un agent hébergé et gérer le cycle de vie de l’agent hébergé.
Déployer avec l’extension Foundry Toolkit pour Visual Studio Code
Pour le déploiement basé sur l’extension, consultez Démarrage rapide : Déployer votre premier agent hébergé.
Héberger un agent existant
Si votre application fonctionne déjà avec LangSmith ou l’interface CLI LangGraph, utilisez le langchain_azure_ai.agents.hosting.run module pour héberger en toute transparence l’agent sur Foundry sans modifier son code ou sa configuration.
À partir de la racine du projet, démarrez un hôte Réponses :
python -m langchain_azure_ai.agents.hosting.run --protocol responses
Pour exposer le même graphe via le protocole Invocations, définissez --protocol sur invocations. Si langgraph.json définit plusieurs graphes, passez le nom du graphe en premier argument. Utilisez --config <path> si le fichier de configuration n’est pas au chemin d’accès par défaut langgraph.json . Par exemple:
python -m langchain_azure_ai.agents.hosting.run agent --protocol invocations
Utilisez la même commande de module que le point d’entrée du conteneur lorsque vous déployez l’application existante sur Foundry.
Par exemple, configurez la commande dans azure.yaml.
Le paramètre principal est le point d’entrée.
services:
my-agent:
host: azure.ai.agent
kind: hosted
codeConfiguration:
runtime: python_3_13
entryPoint: '-m langchain_azure_ai.agents.hosting.run --protocol responses'
...
...
Résolution des problèmes
Utilisez cette liste de contrôle pour diagnostiquer les problèmes courants lors du développement d’agents hébergés avec langchain_azure_ai.agents.hosting.
Échec de la validation du schéma graph
Les hôtes par défaut s’attendent à un graphique LangGraph compilé dont l’état a un messages champ, tel que MessagesState. Si votre graphique utilise un schéma d’état personnalisé, sous-classez l’hôte et remplacez build_input. Pour les réponses, remplacez handle_create quand vous avez besoin d’un contrôle total sur l’analyse des requêtes, l’exécution de graphiques et les événements Réponses émis.
L’état de la conversation ne se poursuit pas
Pour le protocole Responses, transmettez previous_response_id ou un ID conversation lors des tours suivants. Si votre graphique utilise un point de contrôle, vérifiez que le point de contrôle est configuré et durable pour l’environnement dans lequel l’agent s’exécute.
Pour le protocole Invocations, la plateforme ne stocke pas l’historique des conversations.
Utilisez un paramètre de requête agent_session_id pour acheminer les appels ultérieurs vers le même bac à sable hébergé, et utilisez votre propre magasin d’état ou le point de contrôle LangGraph pour gérer l’état de la conversation.
Impossible d’atteindre le modèle dans le conteneur hébergé
Vérifiez que la version de l’agent hébergé inclut FOUNDRY_MODEL_NAMEet que l’identité de l’agent est autorisée à appeler le projet Foundry. La plateforme définit FOUNDRY_PROJECT_ENDPOINT ; votre code doit lire cette variable lors de son exécution dans Foundry.