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.
Ce tutoriel montre comment générer à la fois des applications serveur et client à l’aide du protocole AG-UI avec .NET ou Python et Agent Framework. Vous allez apprendre à créer un serveur AG-UI qui héberge un agent IA et un client qui s’y connecte pour des conversations interactives.
Ce que vous allez construire
À la fin de ce tutoriel, vous disposez des points suivants :
- Un serveur AG-UI hébergeant un agent IA accessible via HTTP
- Application cliente qui se connecte au serveur et diffuse des réponses
- Compréhension du fonctionnement du protocole AG-UI avec Agent Framework
Prerequisites
Avant de commencer, vérifiez que vous disposez des éléments suivants :
- .NET 8.0 ou version ultérieure
- Point de terminaison et déploiement du service Azure OpenAI configurés
- Azure CLI installé et authentifié
- L’utilisateur a le
Cognitive Services OpenAI Contributorrôle pour la ressource Azure OpenAI
Note
Ces exemples utilisent des modèles Azure OpenAI. Pour plus d’informations, consultez comment déployer des modèles Azure OpenAI avec Azure AI Foundry.
Note
Ces exemples utilisent DefaultAzureCredential pour l’authentification. Vérifiez que vous êtes authentifié auprès d’Azure (par exemple, via az login). Pour plus d’informations, consultez la documentation d’Azure Identity.
Avertissement
Le protocole AG-UI est toujours en cours de développement et peut être modifié. Nous allons conserver ces exemples mis à jour à mesure que le protocole évolue.
Étape 1 : Création d’un serveur AG-UI
Le serveur AG-UI héberge votre agent IA et l’expose via des points de terminaison HTTP à l’aide de ASP.NET Core.
Note
Le projet de serveur nécessite le Microsoft.NET.Sdk.Web Kit de développement logiciel (SDK). Si vous créez un projet à partir de zéro, utilisez dotnet new web ou vérifiez que votre .csproj fichier utilise <Project Sdk="Microsoft.NET.Sdk.Web"> au lieu de Microsoft.NET.Sdk.
Installer les packages requis
Installez les packages nécessaires pour le serveur :
dotnet add package Microsoft.Agents.AI.Hosting.AGUI.AspNetCore --prerelease
dotnet add package Azure.AI.OpenAI --prerelease
dotnet add package Azure.Identity
dotnet add package Microsoft.Extensions.AI.OpenAI --prerelease
Note
Le Microsoft.Extensions.AI.OpenAI package est requis pour la méthode d'extension AsIChatClient() qui convertit ChatClient d'OpenAI en l'interface IChatClient attendue par Agent Framework.
Code du serveur
Créez un fichier nommé Program.cs:
// Copyright (c) Microsoft. All rights reserved.
using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI.Hosting.AGUI.AspNetCore;
using Microsoft.Extensions.AI;
using OpenAI.Chat;
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpClient().AddLogging();
builder.Services.AddAGUI();
WebApplication app = builder.Build();
string endpoint = builder.Configuration["AZURE_OPENAI_ENDPOINT"]
?? throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT is not set.");
string deploymentName = builder.Configuration["AZURE_OPENAI_DEPLOYMENT_NAME"]
?? throw new InvalidOperationException("AZURE_OPENAI_DEPLOYMENT_NAME is not set.");
// Create the AI agent
ChatClient chatClient = new AzureOpenAIClient(
new Uri(endpoint),
new DefaultAzureCredential())
.GetChatClient(deploymentName);
AIAgent agent = chatClient.AsIChatClient().AsAIAgent(
name: "AGUIAssistant",
instructions: "You are a helpful assistant.");
// Map the AG-UI agent endpoint
app.MapAGUI("/", agent);
await app.RunAsync();
Concepts clés
-
AddAGUI: enregistre les services AG-UI auprès du conteneur d’injection de dépendances -
MapAGUI: méthode d'extension qui enregistre l'endpoint AG-UI avec la gestion automatique des requêtes/réponses et les événements émis par le serveur (SSE) en continu -
ChatClientetAsIChatClient():AzureOpenAIClient.GetChatClient()retourne le type d’OpenAIChatClient. LaAsIChatClient()méthode d’extension (deMicrosoft.Extensions.AI.OpenAI) la convertit en interfaceIChatClientrequise par Agent Framework -
AsAIAgent: crée un agent Agent Framework à partir d’unIChatClient - intégration ASP.NET Core : utilise la prise en charge asynchrone native d'ASP.NET Core pour les réponses en flux
- Instructions : l’agent est créé avec des instructions par défaut, qui peuvent être remplacées par des messages clients
-
Configuration :
AzureOpenAIClientavecDefaultAzureCredentialfournit une authentification sécurisée
Configurer et exécuter le serveur
Définissez les variables d’environnement requises :
export AZURE_OPENAI_ENDPOINT="https://your-resource.openai.azure.com/"
export AZURE_OPENAI_DEPLOYMENT_NAME="gpt-4o-mini"
Exécutez le serveur :
dotnet run --urls http://localhost:8888
Le serveur va commencer à écouter http://localhost:8888.
Note
Maintenez ce serveur en cours d’exécution pendant la configuration et l’exécution du client à l’étape 2. Le serveur et le client doivent s’exécuter simultanément pour que le système complet fonctionne.
Étape 2 : Création d’un client AG-UI
Le client AG-UI se connecte au serveur distant et affiche les réponses en streaming.
Important
Avant d’exécuter le client, vérifiez que le serveur AG-UI de l’étape 1 est en cours d’exécution à http://localhost:8888.
Installer les packages requis
Installez la bibliothèque de client AG-UI :
dotnet add package Microsoft.Agents.AI.AGUI --prerelease
dotnet add package Microsoft.Agents.AI --prerelease
Note
Le Microsoft.Agents.AI package fournit la méthode d’extension AsAIAgent() .
Client Code
Créez un fichier nommé Program.cs:
// Copyright (c) Microsoft. All rights reserved.
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.AGUI;
using Microsoft.Extensions.AI;
string serverUrl = Environment.GetEnvironmentVariable("AGUI_SERVER_URL") ?? "http://localhost:8888";
Console.WriteLine($"Connecting to AG-UI server at: {serverUrl}\n");
// Create the AG-UI client agent
using HttpClient httpClient = new()
{
Timeout = TimeSpan.FromSeconds(60)
};
AGUIChatClient chatClient = new(httpClient, serverUrl);
AIAgent agent = chatClient.AsAIAgent(
name: "agui-client",
description: "AG-UI Client Agent");
AgentSession session = await agent.CreateSessionAsync();
List<ChatMessage> messages =
[
new(ChatRole.System, "You are a helpful assistant.")
];
try
{
while (true)
{
// Get user input
Console.Write("\nUser (:q or quit to exit): ");
string? message = Console.ReadLine();
if (string.IsNullOrWhiteSpace(message))
{
Console.WriteLine("Request cannot be empty.");
continue;
}
if (message is ":q" or "quit")
{
break;
}
messages.Add(new ChatMessage(ChatRole.User, message));
// Stream the response
bool isFirstUpdate = true;
string? threadId = null;
await foreach (AgentResponseUpdate update in agent.RunStreamingAsync(messages, session))
{
ChatResponseUpdate chatUpdate = update.AsChatResponseUpdate();
// First update indicates run started
if (isFirstUpdate)
{
threadId = chatUpdate.ConversationId;
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine($"\n[Run Started - Thread: {chatUpdate.ConversationId}, Run: {chatUpdate.ResponseId}]");
Console.ResetColor();
isFirstUpdate = false;
}
// Display streaming text content
foreach (AIContent content in update.Contents)
{
if (content is TextContent textContent)
{
Console.ForegroundColor = ConsoleColor.Cyan;
Console.Write(textContent.Text);
Console.ResetColor();
}
else if (content is ErrorContent errorContent)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine($"\n[Error: {errorContent.Message}]");
Console.ResetColor();
}
}
}
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine($"\n[Run Finished - Thread: {threadId}]");
Console.ResetColor();
}
}
catch (Exception ex)
{
Console.WriteLine($"\nAn error occurred: {ex.Message}");
}
Concepts clés
- Server-Sent Events (SSE) : le protocole utilise SSE pour les réponses de diffusion en continu
-
AGUIChatClient : classe cliente qui se connecte aux serveurs AG-UI et implémente
IChatClient -
AsAIAgent: Méthode d'extension sur
AGUIChatClientpour créer un agent à partir du client -
RunStreamingAsync : Diffuse des réponses en tant qu’objets
AgentResponseUpdate -
AsChatResponseUpdate : méthode d’extension pour accéder aux propriétés spécifiques à la conversation telles que
ConversationIdetResponseId -
Gestion des sessions : le
AgentSessionmaintient le contexte de conversation à travers les requêtes -
Types de contenu : les réponses incluent
TextContentles messages etErrorContentles erreurs
Configurer et exécuter le client
Définissez éventuellement une URL de serveur personnalisée :
export AGUI_SERVER_URL="http://localhost:8888"
Exécutez le client dans un terminal distinct (vérifiez que le serveur de l’étape 1 est en cours d’exécution) :
dotnet run
Étape 3 : Tester le système complet
Avec le serveur et le client en cours d’exécution, vous pouvez maintenant tester le système complet.
Sortie attendue
$ dotnet run
Connecting to AG-UI server at: http://localhost:8888
User (:q or quit to exit): What is 2 + 2?
[Run Started - Thread: thread_abc123, Run: run_xyz789]
2 + 2 equals 4.
[Run Finished - Thread: thread_abc123]
User (:q or quit to exit): Tell me a fun fact about space
[Run Started - Thread: thread_abc123, Run: run_def456]
Here's a fun fact: A day on Venus is longer than its year! Venus takes
about 243 Earth days to rotate once on its axis, but only about 225 Earth
days to orbit the Sun.
[Run Finished - Thread: thread_abc123]
User (:q or quit to exit): :q
Sortie Codée par Couleur
Le client affiche différents types de contenu avec des couleurs distinctes :
- Jaune : Exécuter les notifications démarrées
- Cyan : Réponses de texte de l’agent (diffusées en temps réel)
- Vert : Notifications d’exécution
- Rouge : Messages d’erreur
Fonctionnement
flux du côté serveur
- Le client envoie une requête HTTP POST avec des messages
- Le point de terminaison ASP.NET Core reçoit la demande via
MapAGUI - Agent traite les messages à l’aide d’Agent Framework
- Les réponses sont converties en événements AG-UI
- Les événements sont transmis en continu en tant que Server-Sent Events (SSE)
- La connexion se ferme une fois l’exécution terminée
Flux Côté Client
-
AGUIChatClientenvoie une requête HTTP POST au point de terminaison du serveur - Le serveur répond avec le flux SSE
- Le client analyse les événements entrants en
AgentResponseUpdateobjets - Chaque mise à jour s’affiche en fonction de son type de contenu
-
ConversationIdest capturé pour la continuité des conversations - Le flux se termine lorsque l'exécution se termine
Détails du protocole
Le protocole AG-UI utilise :
- HTTP POST pour l’envoi de requêtes
- Événements émis par le serveur (SSE) pour les réponses en streaming
- JSON pour la sérialisation d’événements
- ID de thread (en tant que
ConversationId) pour la maintenance du contexte de conversation - ID d'exécution (en tant que
ResponseId) pour le suivi des exécutions individuelles
Étapes suivantes
Maintenant que vous comprenez les principes de base de l'AG-UI, vous pouvez :
- Ajouter des outils back-end : créer des outils de fonction personnalisés pour votre domaine
Ressources additionnelles
Prerequisites
Avant de commencer, vérifiez que vous disposez des éléments suivants :
- Python 3.10 ou version ultérieure
- Point de terminaison et déploiement du service Azure OpenAI configurés
- Azure CLI installé et authentifié
- L’utilisateur a le
Cognitive Services OpenAI Contributorrôle pour la ressource Azure OpenAI
Note
Ces exemples utilisent des modèles Azure OpenAI. Pour plus d’informations, consultez comment déployer des modèles Azure OpenAI avec Azure AI Foundry.
Note
Ces exemples utilisent DefaultAzureCredential pour l’authentification. Vérifiez que vous êtes authentifié auprès d’Azure (par exemple, via az login). Pour plus d’informations, consultez la documentation d’Azure Identity.
Avertissement
Le protocole AG-UI est toujours en cours de développement et peut être modifié. Nous allons conserver ces exemples mis à jour à mesure que le protocole évolue.
Étape 1 : Création d’un serveur AG-UI
Le serveur AG-UI héberge votre agent IA et l’expose via des points de terminaison HTTP à l’aide de FastAPI.
Installer les packages requis
Installez les packages nécessaires pour le serveur :
pip install agent-framework-ag-ui --pre
Ou en utilisant UV :
uv pip install agent-framework-ag-ui --prerelease=allow
Cela installe agent-framework-coreautomatiquement , fastapiet uvicorn en tant que dépendances.
Code du serveur
Créez un fichier nommé server.py:
"""AG-UI server example."""
import os
from agent_framework import Agent
from agent_framework.azure import AzureOpenAIChatClient
from agent_framework_ag_ui import add_agent_framework_fastapi_endpoint
from azure.identity import AzureCliCredential
from fastapi import FastAPI
# Read required configuration
endpoint = os.environ.get("AZURE_OPENAI_ENDPOINT")
deployment_name = os.environ.get("AZURE_OPENAI_DEPLOYMENT_NAME")
if not endpoint:
raise ValueError("AZURE_OPENAI_ENDPOINT environment variable is required")
if not deployment_name:
raise ValueError("AZURE_OPENAI_DEPLOYMENT_NAME environment variable is required")
chat_client = AzureOpenAIChatClient(
credential=AzureCliCredential(),
endpoint=endpoint,
deployment_name=deployment_name,
)
# Create the AI agent
agent = Agent(
name="AGUIAssistant",
instructions="You are a helpful assistant.",
chat_client=chat_client,
)
# Create FastAPI app
app = FastAPI(title="AG-UI Server")
# Register the AG-UI endpoint
add_agent_framework_fastapi_endpoint(app, agent, "/")
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="127.0.0.1", port=8888)
Concepts clés
-
add_agent_framework_fastapi_endpoint: enregistre le point de terminaison AG-UI incluant la gestion automatique des demandes/réponses et la diffusion en continu SSE -
Agent: Agent Framework qui gère les demandes entrantes - Intégration de FastAPI : utilise la prise en charge asynchrone native de FastAPI pour les réponses de streaming
- Instructions : l’agent est créé avec des instructions par défaut, qui peuvent être remplacées par des messages clients
-
Configuration :
AzureOpenAIChatClientlit à partir de variables d’environnement ou accepte directement les paramètres
Configurer et exécuter le serveur
Définissez les variables d’environnement requises :
export AZURE_OPENAI_ENDPOINT="https://your-resource.openai.azure.com/"
export AZURE_OPENAI_DEPLOYMENT_NAME="gpt-4o-mini"
Exécutez le serveur :
python server.py
Ou en utilisant directement uvicorn :
uvicorn server:app --host 127.0.0.1 --port 8888
Le serveur va commencer à écouter http://127.0.0.1:8888.
Étape 2 : Création d’un client AG-UI
Le client AG-UI se connecte au serveur distant et affiche les réponses en streaming.
Installer les packages requis
Le package AG-UI est déjà installé, ce qui inclut les AGUIChatClientéléments suivants :
# Already installed with agent-framework-ag-ui
pip install agent-framework-ag-ui --pre
Client Code
Créez un fichier nommé client.py:
"""AG-UI client example."""
import asyncio
import os
from agent_framework import Agent
from agent_framework_ag_ui import AGUIChatClient
async def main():
"""Main client loop."""
# Get server URL from environment or use default
server_url = os.environ.get("AGUI_SERVER_URL", "http://127.0.0.1:8888/")
print(f"Connecting to AG-UI server at: {server_url}\n")
# Create AG-UI chat client
chat_client = AGUIChatClient(server_url=server_url)
# Create agent with the chat client
agent = Agent(
name="ClientAgent",
chat_client=chat_client,
instructions="You are a helpful assistant.",
)
# Get a thread for conversation continuity
thread = agent.create_session()
try:
while True:
# Get user input
message = input("\nUser (:q or quit to exit): ")
if not message.strip():
print("Request cannot be empty.")
continue
if message.lower() in (":q", "quit"):
break
# Stream the agent response
print("\nAssistant: ", end="", flush=True)
async for update in agent.run(message, session=thread, stream=True):
# Print text content as it streams
if update.text:
print(f"\033[96m{update.text}\033[0m", end="", flush=True)
print("\n")
except KeyboardInterrupt:
print("\n\nExiting...")
except Exception as e:
print(f"\n\033[91mAn error occurred: {e}\033[0m")
if __name__ == "__main__":
asyncio.run(main())
Concepts clés
-
Server-Sent Events (SSE) : le protocole utilise le format SSE (
data: {json}\n\n) -
Types d’événements : différents événements fournissent des métadonnées et du contenu (MAJUSCULES soulignées) :
-
RUN_STARTED: l’agent a démarré le traitement -
TEXT_MESSAGE_START: Début d’un message texte de l’agent -
TEXT_MESSAGE_CONTENT: texte incrémentiel diffusé par l'agent (avec le champdelta) -
TEXT_MESSAGE_END: Fin d’un sms -
RUN_FINISHED:Achèvement réussi -
RUN_ERROR: Informations sur l’erreur
-
-
Nommage de champ : les champs d’événement utilisent camelCase (par exemple,
threadId,runId,messageId) -
Gestion des threads : le
threadIdcontextualise le contexte de conversation entre les demandes - Client-Side Instructions : les messages système sont envoyés à partir du client
Configurer et exécuter le client
Définissez éventuellement une URL de serveur personnalisée :
export AGUI_SERVER_URL="http://127.0.0.1:8888/"
Exécutez le client (dans un terminal distinct) :
python client.py
Étape 3 : Tester le système complet
Avec le serveur et le client en cours d’exécution, vous pouvez maintenant tester le système complet.
Sortie attendue
$ python client.py
Connecting to AG-UI server at: http://127.0.0.1:8888/
User (:q or quit to exit): What is 2 + 2?
[Run Started - Thread: abc123, Run: xyz789]
2 + 2 equals 4.
[Run Finished - Thread: abc123, Run: xyz789]
User (:q or quit to exit): Tell me a fun fact about space
[Run Started - Thread: abc123, Run: def456]
Here's a fun fact: A day on Venus is longer than its year! Venus takes
about 243 Earth days to rotate once on its axis, but only about 225 Earth
days to orbit the Sun.
[Run Finished - Thread: abc123, Run: def456]
User (:q or quit to exit): :q
Sortie Codée par Couleur
Le client affiche différents types de contenu avec des couleurs distinctes :
- Jaune : Exécuter les notifications démarrées
- Cyan : Réponses de texte de l’agent (diffusées en temps réel)
- Vert : Notifications d’exécution
- Rouge : Messages d’erreur
Test avec curl (facultatif)
Avant d’exécuter le client, vous pouvez tester le serveur manuellement à l’aide de curl :
curl -N http://127.0.0.1:8888/ \
-H "Content-Type: application/json" \
-H "Accept: text/event-stream" \
-d '{
"messages": [
{"role": "user", "content": "What is 2 + 2?"}
]
}'
Vous devriez voir le flux des Server-Sent Events :
data: {"type":"RUN_STARTED","threadId":"...","runId":"..."}
data: {"type":"TEXT_MESSAGE_START","messageId":"...","role":"assistant"}
data: {"type":"TEXT_MESSAGE_CONTENT","messageId":"...","delta":"The"}
data: {"type":"TEXT_MESSAGE_CONTENT","messageId":"...","delta":" answer"}
...
data: {"type":"TEXT_MESSAGE_END","messageId":"..."}
data: {"type":"RUN_FINISHED","threadId":"...","runId":"..."}
Fonctionnement
flux du côté serveur
- Le client envoie une requête HTTP POST avec des messages
- Le point de terminaison FastAPI reçoit la requête
-
AgentFrameworkAgentun wrapper orchestre l’exécution - Agent traite les messages à l’aide d’Agent Framework
-
AgentFrameworkEventBridgeconvertit les mises à jour de l’agent en événements AG-UI - Les réponses sont diffusées en flux continu sous forme d'événements émis par le serveur (SSE)
- La connexion se ferme une fois l’exécution terminée
Flux Côté Client
- Le client envoie une requête HTTP POST au point de terminaison du serveur
- Le serveur répond avec le flux SSE
- Le client analyse les lignes entrantes
data:en tant qu’événements JSON - Chaque événement est affiché en fonction de son type
-
threadIdest capturé pour la continuité des conversations - Le flux se termine lorsque l'événement
RUN_FINISHEDarrive.
Détails du protocole
Le protocole AG-UI utilise :
- HTTP POST pour l’envoi de requêtes
- Événements émis par le serveur (SSE) pour les réponses en streaming
- JSON pour la sérialisation d’événements
- ID de thread pour la maintenance du contexte de conversation
- Identifiants d'exécution pour le suivi des exécutions individuelles
- Nommage de type d’événement : UPPERCASE avec traits de soulignement (par exemple,
RUN_STARTED,TEXT_MESSAGE_CONTENT) - Nommage de champ : camelCase (par exemple,
threadId,runId,messageId)
Modèles courants
Configuration de serveur personnalisée
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
# Add CORS for web clients
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
add_agent_framework_fastapi_endpoint(app, agent, "/agent")
Agents multiples
app = FastAPI()
weather_agent = Agent(name="weather", ...)
finance_agent = Agent(name="finance", ...)
add_agent_framework_fastapi_endpoint(app, weather_agent, "/weather")
add_agent_framework_fastapi_endpoint(app, finance_agent, "/finance")
Gestion des erreurs
try:
async for event in client.send_message(message):
if event.get("type") == "RUN_ERROR":
error_msg = event.get("message", "Unknown error")
print(f"Error: {error_msg}")
# Handle error appropriately
except httpx.HTTPError as e:
print(f"HTTP error: {e}")
except Exception as e:
print(f"Unexpected error: {e}")
Résolution des problèmes
Connexion refusée
Vérifiez que le serveur est en cours d’exécution avant de démarrer le client :
# Terminal 1
python server.py
# Terminal 2 (after server starts)
python client.py
Erreurs d’authentification
Vérifiez que vous êtes authentifié auprès d’Azure :
az login
Vérifiez que vous disposez de l’attribution de rôle correcte sur la ressource Azure OpenAI.
Streaming non opérationnel
Vérifiez que le temps d'attente pour votre client est suffisant.
httpx.AsyncClient(timeout=60.0) # 60 seconds should be enough
Pour les agents fonctionnant sur de longues périodes, ajustez le délai d'attente en conséquence.
Contexte de thread perdu
Le client gère automatiquement la continuité des threads. Si le contexte est perdu :
- Vérifiez que
threadIdsoit capturé à partir des événementsRUN_STARTED - Vérifiez que la même instance cliente est utilisée entre les messages
- Vérifiez que le serveur reçoit le
thread_iddans les demandes suivantes
Étapes suivantes
Maintenant que vous comprenez les principes de base de l'AG-UI, vous pouvez :
- Ajouter des outils back-end : créer des outils de fonction personnalisés pour votre domaine