Compartilhar via


Introdução ao AG-UI

Este tutorial demonstra como criar aplicativos cliente e servidor usando o protocolo AG-UI com .NET ou Python e Agent Framework. Você aprenderá a criar um servidor AG-UI que hospeda um agente de IA e um cliente que se conecta a ele para conversas interativas.

O que você construirá

Ao final deste tutorial, você terá:

  • Um servidor AG-UI que hospeda um agente de IA acessível via HTTP
  • Um aplicativo cliente que se conecta ao servidor e transmite respostas
  • Noções básicas de como o protocolo AG-UI funciona com o Agent Framework

Pré-requisitos

Antes de começar, verifique se você tem o seguinte:

Observação

Esses exemplos usam modelos do Azure OpenAI. Para obter mais informações, confira como implantar modelos do Azure OpenAI com o Azure AI Foundry.

Observação

Esses exemplos usam DefaultAzureCredential para autenticação. Verifique se você está autenticado com o Azure (por exemplo, via az login). Para obter mais informações, consulte a documentação da Identidade do Azure.

Aviso

O protocolo AG-UI ainda está em desenvolvimento e está sujeito a alterações. Manteremos essas amostras atualizadas à medida que o protocolo evoluir.

Etapa 1: Criando um servidor AG-UI

O servidor AG-UI hospeda seu agente de IA e o expõe por meio de pontos de extremidade HTTP usando ASP.NET Core.

Observação

O projeto do servidor requer o Microsoft.NET.Sdk.Web SDK. Se você estiver criando um novo projeto do zero, use dotnet new web ou verifique se o .csproj arquivo usa <Project Sdk="Microsoft.NET.Sdk.Web"> em vez de Microsoft.NET.Sdk.

Instalar pacotes necessários

Instale os pacotes necessários para o servidor:

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

Observação

O pacote Microsoft.Extensions.AI.OpenAI é necessário para o método de extensão AsIChatClient() que converte o ChatClient da OpenAI para a interface IChatClient esperada pelo Agent Framework.

Código do servidor

Crie um arquivo chamado 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();

Conceitos Principais

  • AddAGUI: registra os serviços AG-UI com o contêiner de injeção de dependência
  • MapAGUI: Método de extensão que registra o endpoint AG-UI com tratamento automático de solicitação/resposta e streaming de SSE.
  • ChatClient e AsIChatClient(): AzureOpenAIClient.GetChatClient() retorna o tipo de ChatClient da OpenAI. O método de extensão AsIChatClient() (de Microsoft.Extensions.AI.OpenAI) converte-o na interface IChatClient exigida pelo Agent Framework.
  • AsAIAgent: cria um agente do Agent Framework de um IChatClient
  • integração do ASP.NET Core: usa o suporte assíncrono nativo do ASP.NET Core para respostas de streaming
  • Instruções: O agente é criado com instruções padrão, que podem ser substituídas por mensagens de cliente
  • Configuração: AzureOpenAIClient com DefaultAzureCredential fornece autenticação segura

Configurar e executar o servidor

Defina as variáveis de ambiente necessárias:

export AZURE_OPENAI_ENDPOINT="https://your-resource.openai.azure.com/"
export AZURE_OPENAI_DEPLOYMENT_NAME="gpt-4o-mini"

Execute o servidor:

dotnet run --urls http://localhost:8888

O servidor começará a escutar em http://localhost:8888.

Observação

Mantenha esse servidor em execução enquanto você configura e executa o cliente na Etapa 2. O servidor e o cliente precisam ser executados simultaneamente para que o sistema completo funcione.

Etapa 2: Criando um cliente AG-UI

O cliente AG-UI se conecta ao servidor remoto e exibe respostas de streaming.

Importante

Antes de executar o cliente, verifique se o servidor de AG-UI da Etapa 1 está em execução.http://localhost:8888

Instalar pacotes necessários

Instale a biblioteca de clientes do AG-UI:

dotnet add package Microsoft.Agents.AI.AGUI --prerelease
dotnet add package Microsoft.Agents.AI --prerelease

Observação

O pacote Microsoft.Agents.AI fornece o método de extensão AsAIAgent().

Código do cliente

Crie um arquivo chamado 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}");
}

Conceitos Principais

  • Eventos Enviados pelo Servidor (SSE): o protocolo usa SSE para respostas de streaming
  • AGUIChatClient: Classe cliente que se conecta a servidores AG-UI e implementa IChatClient
  • AsAIAgent: método AGUIChatClient de extensão para criar um agente a partir do cliente
  • RunStreamingAsync: transmite respostas como AgentResponseUpdate objetos
  • AsChatResponseUpdate: método de extensão para acessar propriedades específicas do chat como ConversationId e ResponseId
  • Gerenciamento de Sessão: o sistema mantém o contexto da conversa entre solicitações
  • Tipos de conteúdo: as respostas incluem TextContent mensagens e ErrorContent para erros

Configurar e executar o cliente

Opcionalmente, defina uma URL de servidor personalizada:

export AGUI_SERVER_URL="http://localhost:8888"

Execute o cliente em um terminal separado (verifique se o servidor da Etapa 1 está em execução):

dotnet run

Etapa 3: Testando o sistema completo

Com o servidor e o cliente em execução, agora você pode testar o sistema completo.

Saída esperada

$ 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

Saída Codificada por Cores

O cliente exibe diferentes tipos de conteúdo com cores distintas:

  • Amarelo: executar notificações iniciadas
  • Ciano: Respostas de texto do agente (transmitidas em tempo real)
  • Verde: executar notificações de conclusão
  • Vermelho: Mensagens de erro

Como funciona

Fluxo do Lado do Servidor

  1. Cliente envia solicitação HTTP POST com mensagens
  2. O endpoint ASP.NET Core recebe a solicitação por meio de MapAGUI
  3. O agente processa as mensagens usando o Agent Framework
  4. As respostas são convertidas em eventos de AG-UI
  5. Os eventos são transmitidos de volta como eventos enviados pelo servidor (SSE)
  6. A conexão é fechada quando a execução é concluída

Fluxo de Client-Side

  1. AGUIChatClient envia solicitação HTTP POST para o endpoint do servidor
  2. O servidor responde com o fluxo SSE
  3. O cliente analisa eventos de entrada em AgentResponseUpdate objetos
  4. Cada atualização é exibida com base em seu tipo de conteúdo
  5. ConversationId é capturado para continuidade da conversa
  6. O fluxo é finalizado quando a execução termina

Detalhes do protocolo

O protocolo AG-UI usa:

  • HTTP POST para enviar solicitações
  • Server-Sent Events (SSE) para respostas de streaming
  • JSON para serialização de eventos
  • IDs de thread (como ConversationId) para manter o contexto de conversa
  • IDs de execução (como ResponseId) para rastrear execuções individuais

Próximas etapas

Agora que você entende as noções básicas do AG-UI, você pode:

Recursos adicionais

Pré-requisitos

Antes de começar, verifique se você tem o seguinte:

Observação

Esses exemplos usam modelos do Azure OpenAI. Para obter mais informações, confira como implantar modelos do Azure OpenAI com o Azure AI Foundry.

Observação

Esses exemplos usam DefaultAzureCredential para autenticação. Verifique se você está autenticado com o Azure (por exemplo, via az login). Para obter mais informações, consulte a documentação da Identidade do Azure.

Aviso

O protocolo AG-UI ainda está em desenvolvimento e está sujeito a alterações. Manteremos essas amostras atualizadas à medida que o protocolo evoluir.

Etapa 1: Criando um servidor AG-UI

O servidor AG-UI hospeda seu agente de IA e o disponibiliza através de endpoints HTTP usando FastAPI.

Instalar pacotes necessários

Instale os pacotes necessários para o servidor:

pip install agent-framework-ag-ui --pre

Ou usando uv:

uv pip install agent-framework-ag-ui --prerelease=allow

Isso instalará agent-framework-coreautomaticamente, fastapie uvicorn como dependências.

Código do servidor

Crie um arquivo chamado 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)

Conceitos Principais

  • add_agent_framework_fastapi_endpoint: registra o endpoint AG-UI com gerenciamento automático de solicitações/respostas e streaming de SSE
  • Agent: o agente do Agent Framework que lidará com solicitações de entrada
  • Integração do FastAPI: usa o suporte assíncrono nativo do FastAPI para respostas de streaming
  • Instruções: O agente é criado com instruções padrão, que podem ser substituídas por mensagens de cliente
  • Configuração: AzureOpenAIChatClient lê de variáveis de ambiente ou aceita parâmetros diretamente

Configurar e executar o servidor

Defina as variáveis de ambiente necessárias:

export AZURE_OPENAI_ENDPOINT="https://your-resource.openai.azure.com/"
export AZURE_OPENAI_DEPLOYMENT_NAME="gpt-4o-mini"

Execute o servidor:

python server.py

Ou usando o uvicorn diretamente:

uvicorn server:app --host 127.0.0.1 --port 8888

O servidor começará a escutar em http://127.0.0.1:8888.

Etapa 2: Criando um cliente AG-UI

O cliente AG-UI se conecta ao servidor remoto e exibe respostas de streaming.

Instalar pacotes necessários

O pacote AG-UI já está instalado, o que inclui :AGUIChatClient

# Already installed with agent-framework-ag-ui
pip install agent-framework-ag-ui --pre

Código do cliente

Crie um arquivo chamado 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())

Conceitos Principais

  • Server-Sent Events (SSE): o protocolo usa o formato SSE (data: {json}\n\n)
  • Tipos de evento: eventos diferentes fornecem metadados e conteúdo (UPPERCASE com sublinhados):
    • RUN_STARTED: o agente iniciou o processamento
    • TEXT_MESSAGE_START: início de uma mensagem de texto do agente
    • TEXT_MESSAGE_CONTENT: texto incremental transmitido do agente (com o campo delta)
    • TEXT_MESSAGE_END: fim de uma mensagem de texto
    • RUN_FINISHED: conclusão bem-sucedida
    • RUN_ERROR: informações de erro
  • Nomenclatura de campo: os campos de evento usam camelCase (por exemplo, , threadId, runId, messageId)
  • Gerenciamento de threads: o threadId mantém o contexto da conversa entre solicitações
  • Instruções do lado do cliente: as mensagens do sistema são enviadas do cliente

Configurar e executar o cliente

Opcionalmente, defina uma URL de servidor personalizada:

export AGUI_SERVER_URL="http://127.0.0.1:8888/"

Execute o cliente (em um terminal separado):

python client.py

Etapa 3: Testando o sistema completo

Com o servidor e o cliente em execução, agora você pode testar o sistema completo.

Saída esperada

$ 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

Saída Codificada por Cores

O cliente exibe diferentes tipos de conteúdo com cores distintas:

  • Amarelo: executar notificações iniciadas
  • Ciano: Respostas de texto do agente (transmitidas em tempo real)
  • Verde: executar notificações de conclusão
  • Vermelho: Mensagens de erro

Testando com curl (opcional)

Antes de executar o cliente, você pode testar o servidor manualmente usando 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?"}
    ]
  }'

Você vai ver Server-Sent Events sendo transmitidos de volta.

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":"..."}

Como funciona

Fluxo do Lado do Servidor

  1. Cliente envia solicitação HTTP POST com mensagens
  2. O endpoint do FastAPI recebe a solicitação
  3. AgentFrameworkAgent wrapper orquestra a execução
  4. O agente processa as mensagens usando o Agent Framework
  5. AgentFrameworkEventBridge converte atualizações de agente em eventos de AG-UI
  6. As respostas são transmitidas como Eventos Enviados pelo Servidor (SSE)
  7. A conexão é fechada quando a execução é concluída

Fluxo de Client-Side

  1. O cliente envia solicitação HTTP POST para o ponto de extremidade do servidor
  2. O servidor responde com o fluxo SSE
  3. O cliente analisa as linhas de entrada data: como eventos JSON
  4. Cada evento é exibido com base em seu tipo
  5. threadId é capturado para continuidade da conversa
  6. O fluxo é concluído quando o evento RUN_FINISHED chega

Detalhes do protocolo

O protocolo AG-UI usa:

  • HTTP POST para enviar solicitações
  • Server-Sent Events (SSE) para respostas de streaming
  • JSON para serialização de eventos
  • IDs de thread para manter o contexto de conversação
  • Executar IDs para acompanhar execuções individuais
  • Nomenclatura de tipo de evento: UPPERCASE com sublinhados (por exemplo, RUN_STARTED, TEXT_MESSAGE_CONTENT)
  • Nomenclatura de campo: camelCase (por exemplo, threadId, runId, messageId)

Padrões comuns

Configuração do servidor personalizado

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")

Vários agentes

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")

Tratamento de erros

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}")

Resolução de problemas

Conexão recusada

Verifique se o servidor está em execução antes de iniciar o cliente:

# Terminal 1
python server.py

# Terminal 2 (after server starts)
python client.py

Erros de autenticação

Verifique se você está autenticado com o Azure:

az login

Verifique se você tem a atribuição de função correta no recurso do Azure OpenAI.

Streaming não funcionando

Verifique se o tempo limite configurado para o cliente é adequado.

httpx.AsyncClient(timeout=60.0)  # 60 seconds should be enough

Para agentes de longa execução, aumente o tempo limite correspondentemente.

Contexto de thread perdido

O cliente gerencia automaticamente a continuidade do thread. Se o contexto for perdido:

  1. Verifique se threadId está sendo capturado de RUN_STARTED eventos
  2. Verifique se a mesma instância do cliente é usada entre mensagens
  3. Verifique se o servidor está recebendo o thread_id em solicitações subsequentes

Próximas etapas

Agora que você entende as noções básicas do AG-UI, você pode:

Recursos adicionais