Partilhar via


Construa um Agente OpenAI .NET usando um servidor MCP no Azure Container Apps

Este artigo mostra-lhe como construir um agente Model Context Protocol (MCP) usando .NET. Neste exemplo, o cliente MCP (escrito em C#/.NET) liga-se a um servidor MCP (escrito em TypeScript) para gerir uma lista de tarefas. O cliente encontra as ferramentas disponíveis no servidor e envia-as para um modelo Azure OpenAI. Os usuários podem então falar com o sistema todo usando a linguagem do dia a dia.

Ir para o código

Confira o modelo OpenAI MCP Agent Building Block AI. Este exemplo mostra como criar um agente OpenAI que usa um cliente MCP para consumir um servidor MCP existente.

Vá para a seção passo a passo do código para entender como esse exemplo funciona.

Visão geral da arquitetura

O seguinte diagrama mostra a arquitetura simples da aplicação de exemplo: Diagrama mostrando a arquitetura desde Visual Studio Code alojamento do agente e do cliente MCP até ao Servidor MCP.

  • Cliente MCP: Conecta-se ao servidor MCP e encontra as ferramentas disponíveis
  • Chat Client: Trabalha com Azure OpenAI para compreender linguagem natural
  • Blazor UI: Fornece uma interface web onde os usuários podem conversar
  • Camada de transporte: Usa Eventos Enviados pelo Servidor (SSE) para enviar mensagens em tempo real
  • Autenticação: usa tokens JWT para manter a conexão segura

O servidor MCP funciona como uma aplicação containerizada no Azure Container Apps (ACA). Ele usa um back-end TypeScript para fornecer ferramentas ao cliente MCP através do Model Context Protocol. Todas as ferramentas funcionam com um banco de dados SQLite back-end.

Observação

Visite Build a TypeScript MCP server usando Azure Container Apps para ver o guia de código do TypeScript MCP Server utilizado neste artigo.

Custo

Para manter os custos baixos, este exemplo usa níveis de preços básicos ou de consumo para a maioria dos recursos. Ajuste a camada conforme necessário e exclua recursos quando terminar para evitar cobranças.

Pré-requisitos

Um contêiner de desenvolvimento inclui todas as dependências necessárias para este artigo. Podes executá-lo no GitHub Codespaces (num navegador) ou localmente usando o Visual Studio Code.

Para seguir este artigo, certifique-se de que cumpre estes pré-requisitos:

Implementar um modelo Foundry gpt-5-mini usando a extensão Foundry VS Code

Implemente um modelo gpt-5-mini usando a Extensão Foundry em Visual Studio Code seguindo os seguintes passos:

Criar um projeto Foundry e implementar o modelo

Criar a cadeia de conexão do modelo OpenAI

  1. Depois de o gpt-5-mini modelo estar implementado, clique com o botão direito no modelo na extensão Foundry e selecione Copiar a chave API para copiar a chave API do modelo para a sua área de transferência.

  2. De seguida, clique com o botão direito no modelo implementado gpt-5-mini na extensão Foundry e selecione Copiar endpoint para copiar o endpoint do modelo para a sua prancheta, como mostrado na seguinte captura de ecrã:

    A screenshot mostra o menu de contexto do modelo implantado com as opções Copiar ponto final e Copiar chave API realçadas.

  3. Finalmente, crie um connection string para o modelo gpt-5-mini implementado usando o endpoint copiado e a chave API no seguinte formato: Endpoint=<AZURE_OPENAI_ENDPOINT>;Key=<AZURE_OPENAI_API_KEY>. Precisarás desta string de conexão mais tarde no artigo.

  • Uma subscrição Azure – Crie uma gratuitamente
  • Azure permissões da conta – A sua conta Azure deve ter permissões Microsoft.Authorization/roleAssignments/write, como Role Based Access Control Administrator, User Access Administrator ou Owner. Se você não tiver permissões no nível de assinatura, deverá receber RBAC para um grupo de recursos existente e implantar nesse grupo.
    • A tua conta Azure também precisa de permissões Microsoft.Resources/deployments/write ao nível da subscrição.
  • Conta GitHub

Ambiente de desenvolvimento aberto

Siga estas etapas para configurar um ambiente de desenvolvimento pré-configurado com todas as dependências necessárias.

GitHub Codespaces executa um contentor de desenvolvimento gerido pela GitHub com Visual Studio Code para a Web como interface. Use o GitHub Codespaces para a configuração mais simples, pois vem com as ferramentas e dependências necessárias pré-instaladas para este artigo.

Importante

Todas as contas do GitHub podem usar o Codespaces para até 60 horas gratuitas por mês com duas instâncias principais. Para mais informações, consulte armazenamento incluído mensalmente e horas fundamentais do GitHub Codespaces.

Siga os seguintes passos para criar um novo Codespace da GitHub no ramo main do repositório Azure-Samples/openai-mcp-agent-dotnet da GitHub.

  1. Clique com o botão direito do mouse no botão a seguir e selecione Abrir link na nova janela. Esta ação permite que você tenha o ambiente de desenvolvimento e a documentação abertos lado a lado.

    Open in GitHub Codespaces

  2. Na página Criar espaço de código , revise e selecione Criar novo espaço de código.

  3. Aguarde o início do codespace. Pode demorar alguns minutos.

  4. Verifique se o nome do modelo implantado é gpt-5-mini. Se o modelo implantado for diferente, atualize src/McpTodo.ClientApp/appsettings.json com o nome de implantação correto.

    {
      "OpenAI": {
        // Make sure this is the right deployment name.
        "DeploymentName": "gpt-5-mini"
      }
    }
    
  5. Inicie sessão no Azure com a CLI do Azure Developer no terminal na parte inferior do ecrã.

    azd auth login
    
  6. Copie o código do terminal e cole-o em um navegador. Siga as instruções para autenticar com a sua conta Azure.

Você executa o restante das tarefas neste contêiner de desenvolvimento.

Observação

Para executar o agente MCP localmente:

  1. Configure o seu ambiente conforme descrito na secção Começo no repositório de exemplos.
  2. Instale o seu MCP Server seguindo as instruções na secção Get MCP Server App no repositório de exemplos.
  3. Execute o agente MCP localmente seguindo as instruções na secção Run localmente no repositório de exemplos.
  4. Vá para a seção Usar o agente TODO MCP para continuar.

Implantar e executar

O repositório de exemplo contém todo o código e ficheiros de configuração para a implementação do agente MCP no Azure. Os passos seguintes guiam-no pelo exemplo de processo de implementação do agente MCP no Azure.

Publicar no Azure

Importante

Os recursos do Azure nesta secção começam a custar dinheiro imediatamente, mesmo que pares o comando antes de terminar.

Definir o token JWT

  • Defina o token JWT para o servidor MCP executando o seguinte comando no terminal na parte inferior da tela:

    # zsh/bash
    ./scripts/set-jwttoken.sh
    
    # PowerShell
    ./scripts/Set-JwtToken.ps1
    

Adicionar token JWT à configuração do ambiente azd

  1. Adicione o token JWT à configuração do ambiente azd executando o seguinte comando no terminal na parte inferior da tela:

    # zsh/bash
    env_dir=".azure/$(azd env get-value AZURE_ENV_NAME)"
    mkdir -p "$env_dir"
    cat ./src/McpTodo.ServerApp/.env >> "$env_dir/.env"
    
    # PowerShell
    $dotenv = Get-Content ./src/McpTodo.ServerApp/.env
    $dotenv | Add-Content -Path ./.azure/$(azd env get-value AZURE_ENV_NAME)/.env -Encoding utf8 -Force
    

    Observação

    Por padrão, o aplicativo cliente MCP é protegido pelo recurso de autenticação interno ACA. Você pode desativar esse recurso antes de executar azd up pela configuração:

    azd env set USE_LOGIN false
    
  2. Execute o seguinte comando Azure Developer CLI para o provisionamento de recursos do Azure e a implementação do código-fonte:

    azd up
    
  3. Use a tabela a seguir para responder aos prompts:

    Pronta Resposta
    Nome do ambiente Use um nome curto e minúsculo. Adicione o seu nome ou alias. Por exemplo, my-mcp-agent. O nome do ambiente torna-se parte do nome do grupo de recursos.
    Subscription Escolha a subscrição onde pretende criar recursos.
    Localização (para hospedagem) Escolha o local de implantação do modelo na lista.
    Cadeia de conexão OpenAI Cole a cadeia de ligação do modelo OpenAI que criou anteriormente na secção Criar o Modelo OpenAI cadeia de ligação.
  4. A implantação do aplicativo leva de 5 a 10 minutos.

  5. Após a conclusão da implantação, você pode acessar o agente MCP usando a URL na saída. O URL tem esta aparência:

    https://<env-name>.<container-id>.<region>.azurecontainerapps.io
    
  6. Abra a URL em um navegador da Web para usar o agente MCP.

Usar o agente TODO MCP

Depois que o agente MCP estiver em execução, você poderá usar as ferramentas que ele fornece no modo de agente. Para usar ferramentas MCP no modo de agente:

  1. Navegue até a URL do aplicativo cliente e entre no aplicativo.

    Observação

    Se definir o USE_LOGIN valor como false, poderá não lhe ser pedido para iniciar sessão.

  2. Digite um prompt como "Preciso enviar um e-mail para meu gerente na quarta-feira" na caixa de entrada do bate-papo e observe como as ferramentas são invocadas automaticamente conforme necessário.

  3. O agente MCP usa as ferramentas fornecidas pelo servidor MCP para atender à solicitação e retornar uma resposta na interface de chat.

  4. Experimente outros prompts como:

    Give me a list of to dos.
    Set "meeting at 1pm".
    Give me a list of to dos.
    Mark #1 as completed.
    Delete #1 from the to-do list.
    

Explore o código

O repositório de exemplo contém todo o código e ficheiros de configuração para a implementação do agente MCP no Azure. As seções a seguir orientam você pelos principais componentes do código do agente MCP.

Configuração e configuração do Cliente MCP

O aplicativo configura o cliente MCP no Program.cs. Essa configuração define como se conectar e quais opções usar. O código utiliza vários padrões avançados, incluindo integração com .NET Aspire e predefinidos de serviços:

builder.Services.AddSingleton<IMcpClient>(sp =>
{
    var config = sp.GetRequiredService<IConfiguration>();
    var loggerFactory = sp.GetRequiredService<ILoggerFactory>();

    var uri = new Uri(config["McpServers:TodoList"]!);

    var clientTransportOptions = new SseClientTransportOptions()
    {
        Endpoint = new Uri($"{uri.AbsoluteUri.TrimEnd('/')}/mcp"),
        AdditionalHeaders = new Dictionary<string, string>
        {
            { "Authorization", $"Bearer {config["McpServers:JWT:Token"]!}" }
        }
    };
    var clientTransport = new SseClientTransport(clientTransportOptions, loggerFactory);

    var clientOptions = new McpClientOptions()
    {
        ClientInfo = new Implementation()
        {
            Name = "MCP Todo Client",
            Version = "1.0.0",
        }
    };

    return McpClientFactory.CreateAsync(clientTransport, clientOptions, loggerFactory).GetAwaiter().GetResult();
});

Principais detalhes da implementação:

  • Configuração de Transporte: suporta eventos enviados pelo servidor (SSE) e transporte HTTP transmissível. O método de transporte depende da URL do ponto de extremidade - pontos de extremidade que terminam com /sse usam Server-Sent Events, enquanto os pontos de extremidade que terminam com /mcp usam HTTP transmissível. Essa abordagem permite a comunicação em tempo real entre cliente e servidor
  • Cabeçalhos de autenticação: os tokens JWT devem ser colocados no AdditionalHeaders para manter a comunicação segura do servidor
  • Informações do cliente: McpClientOptions informa ao servidor o nome e a versão do cliente
  • Padrão de fábrica: McpClientFactory.CreateAsync() conecta e completa o handshake de protocolo

.NET Aspire integração padrão do serviço

A aplicação utiliza o padrão de serviços predefinidos do .NET Aspire para questões transversais:

// McpTodo.ServiceDefaults/Extensions.cs
public static TBuilder AddServiceDefaults<TBuilder>(this TBuilder builder) where TBuilder : IHostApplicationBuilder
{
    builder.ConfigureOpenTelemetry();
    builder.AddDefaultHealthChecks();
    builder.Services.AddServiceDiscovery();
    
    builder.Services.ConfigureHttpClientDefaults(http =>
    {
        // Turn on resilience by default
        http.AddStandardResilienceHandler();
        // Turn on service discovery by default
        http.AddServiceDiscovery();
    });
    
    return builder;
}

Benefícios padrão do serviço:

  • Métodos de extensão componíveis: O sistema usa um padrão de construtor limpo para adicionar recursos compartilhados
  • Manipuladores de resiliência padrão: o sistema adiciona regras internas de repetição, disjuntor e tempo limite para você
  • Integração de descoberta de serviços: o sistema encontra serviços automaticamente em ambientes de contêiner
  • OpenTelemetry por padrão: O sistema recebe monitoramento completo sem qualquer trabalho de configuração

O diagrama a seguir mostra a relação entre preocupações transversais e serviços de aplicativos:

Diagrama mostrando a relação entre preocupações transversais e serviços de aplicativos.

Resolução da URL de Configuração

O exemplo inclui resolução de URL sofisticada para diferentes ambientes:

// AspireUrlParserExtensions.cs
public static Uri Resolve(this Uri uri, IConfiguration config)
{
    var absoluteUrl = uri.ToString();
    if (absoluteUrl.StartsWith("https+http://"))
    {
        var appname = absoluteUrl.Substring("https+http://".Length).Split('/')[0];
        var https = config[$"services:{appname}:https:0"]!;
        var http = config[$"services:{appname}:http:0"]!;
        
        return string.IsNullOrWhiteSpace(https) ? new Uri(http) : new Uri(https);
    }
    // Handle other URL formats...
}

Recursos de gerenciamento de configuração:

  • Abstração de descoberta de serviço: o sistema lida com URLs de desenvolvimento e produção de forma limpa
  • Negociação de protocolo: O sistema escolhe HTTPS primeiro, depois volta para HTTP
  • : O sistema utiliza padrões padrão de configuração de serviço .NET Aspire

Implementação de autenticação

Este exemplo usa a autenticação JWT (JSON Web Token) para proteger a conexão entre o cliente MCP e o servidor.

dotnet user-secrets --project ./src/McpTodo.ClientApp set McpServers:JWT:Token "$TOKEN"

Observação

Os scripts criavam automaticamente a variável $TOKEN quando executavas o script Bash (set-jwttoken.sh) ou PowerShell (Set-JwtToken.ps1) mais cedo na secção Deploy to Azure. Esses scripts executam as seguintes etapas:

  1. Executar npm run generate-token no aplicativo de servidor MCP para criar um token JWT
  2. Analise o arquivo gerado .env para extrair o valor JWT_TOKEN
  3. Armazene-o automaticamente em segredos de utilizador .NET para o MCPClient

O cliente MCP recupera o token JWT da configuração e o inclui nos cabeçalhos HTTP para autenticação ao se conectar ao servidor MCP:

AdditionalHeaders = new Dictionary<string, string>
{
    { "Authorization", $"Bearer {config["McpServers:JWT:Token"]!}" }
}

Esta abordagem garante:

  • Comunicação segura: O sistema só permite que clientes com tokens válidos se conectem ao servidor MCP
  • Autorização Baseada em Token: os tokens JWT permitem que o sistema verifique os utilizadores sem armazenar dados da sessão
  • Gerenciamento de configuração: O sistema armazena tokens confidenciais com segurança em segredos do usuário durante o desenvolvimento

Azure Container Apps Integração de Autenticação

A infraestrutura apresenta padrões avançados de autenticação utilizando funcionalidades de autenticação e autorização incorporadas Azure Container Apps ("Easy Auth"):

// containerapps-authconfigs.bicep
resource containerappAuthConfig 'Microsoft.App/containerApps/authConfigs@2024-10-02-preview' = {
  properties: {
    identityProviders: {
      azureActiveDirectory: {
        enabled: true
        registration: {
          clientId: clientId
          openIdIssuer: openIdIssuer
        }
      }
    }
    login: {
      tokenStore: {
        enabled: true
        azureBlobStorage: {
          blobContainerUri: '${storageAccount.properties.primaryEndpoints.blob}/token-store'
          managedIdentityResourceId: userAssignedIdentity.id
        }
      }
    }
  }
}

Recursos avançados de autenticação:

  • Zero-Code Authentication: Azure Container Apps fornece autenticação integrada
  • Identidade gerenciada para armazenamento: o sistema armazena tokens com segurança sem cadeias de conexão
  • Credenciais de identidade federada: o sistema ativa a identidade de carga de trabalho para autenticação ao estilo do Kubernetes

O diagrama a seguir mostra o processo de autenticação de segurança entre componentes.

Diagrama que mostra o aperto de mão de segurança entre componentes.

Descoberta e registro de ferramentas

O cliente MCP descobre as ferramentas disponíveis do servidor durante a inicialização do componente em Chat.razor:

protected override async Task OnInitializedAsync()
{
    messages.Add(new(ChatRole.System, SystemPrompt));
    tools = await McpClient.ListToolsAsync();
    chatOptions.Tools = [.. tools];
}

Como funciona a descoberta de ferramentas:

  1. Consulta ao servidor: McpClient.ListToolsAsync() envia uma solicitação ao servidor MCP para listar as ferramentas disponíveis
  2. Recuperação de esquema: o servidor envia de volta definições de ferramenta com nomes, descrições e esquemas de entrada
  3. Registro da ferramenta: O sistema registra as ferramentas com o ChatOptions objeto, disponibilizando-as para o cliente OpenAI
  4. Tipo de Segurança: A McpClientTool classe herda de AIFunction, proporcionando uma integração suave com Microsoft.Extensions.AI

O diagrama a seguir mostra como os esquemas de ferramentas são analisados e registrados:

Diagrama mostrando a descoberta da ferramenta e o fluxo de registro.

Integração OpenAI e invocação de funções

A configuração do cliente de chat demonstra como as ferramentas MCP se integram com o Azure OpenAI:

var chatClient = openAIClient.GetChatClient(config["OpenAI:DeploymentName"]).AsIChatClient();

builder.Services.AddChatClient(chatClient)
                .UseFunctionInvocation()
                .UseLogging();

Benefícios da integração:

  • Chamada de função automática: A .UseFunctionInvocation() extensão ativa a execução automática de ferramentas com base em decisões LLM
  • Easy Tool Access: As ferramentas MCP funcionam como funções integradas para o modelo OpenAI
  • Processamento de respostas: O sistema adiciona automaticamente os resultados da ferramenta ao fluxo de conversação

Implementação de chat em tempo real

A interface de bate-papo em Chat.razor demonstra respostas em fluxo contínuo e execução de ferramentas automatizadas com padrões Blazor avançados.

private async Task AddUserMessageAsync(ChatMessage userMessage)
{
    CancelAnyCurrentResponse();

    // Add the user message to the conversation
    messages.Add(userMessage);
    chatSuggestions?.Clear();
    await chatInput!.FocusAsync();

    // Stream and display a new response from the IChatClient
    var responseText = new TextContent("");
    currentResponseMessage = new ChatMessage(ChatRole.Assistant, [responseText]);
    currentResponseCancellation = new();
    await foreach (var update in ChatClient.GetStreamingResponseAsync([.. messages], chatOptions, currentResponseCancellation.Token))
    {
        messages.AddMessages(update, filter: c => c is not TextContent);
        responseText.Text += update.Text;
        ChatMessageItem.NotifyChanged(currentResponseMessage);
    }

    // Store the final response in the conversation, and begin getting suggestions
    messages.Add(currentResponseMessage!);
    currentResponseMessage = null;
    chatSuggestions?.Update(messages);
}

Recursos de implementação de streaming:

  • Real-Time Updates: GetStreamingResponseAsync() envia atualizações de resposta pouco a pouco
  • Execução da ferramenta: O sistema processa chamadas de função automaticamente durante o streaming
  • Capacidade de resposta da interface do usuário: ChatMessageItem.NotifyChanged() atualiza a interface do usuário em tempo real
  • Suporte a cancelamento: os usuários podem cancelar operações de longa duração

Padrões avançados de interface do usuário Blazor

A implementação usa padrões avançados de interface do usuário para atualizações em tempo real:

Manipulação de eventos segura de memória:

// ChatMessageItem.razor
private static readonly ConditionalWeakTable<ChatMessage, ChatMessageItem> SubscribersLookup = new();

public static void NotifyChanged(ChatMessage source)
{
    if (SubscribersLookup.TryGetValue(source, out var subscriber))
    {
        subscriber.StateHasChanged();
    }
}

Integração de componentes Web personalizados:

// ChatMessageList.razor.js
window.customElements.define('chat-messages', class ChatMessages extends HTMLElement {
    connectedCallback() {
        this._observer = new MutationObserver(mutations => this._scheduleAutoScroll(mutations));
        this._observer.observe(this, { childList: true, attributes: true });
    }
    
    _scheduleAutoScroll(mutations) {
        // Debounce the calls and handle smart auto-scrolling
        cancelAnimationFrame(this._nextAutoScroll);
        this._nextAutoScroll = requestAnimationFrame(() => {
            const addedUserMessage = mutations.some(m => 
                Array.from(m.addedNodes).some(n => 
                    n.parentElement === this && n.classList?.contains('user-message')));
            // Smart scrolling logic...
        });
    }
});

Gestão avançada do estado:

// Chat.razor
private void CancelAnyCurrentResponse()
{
    // If a response was cancelled while streaming, include it in the conversation so it's not lost
    if (currentResponseMessage is not null)
    {
        messages.Add(currentResponseMessage);
    }
    
    currentResponseCancellation?.Cancel();
    currentResponseMessage = null;
}

Benefícios da Blazor UI:

  • Componentes Web híbridos: O sistema combina Blazor Server com elementos personalizados para um melhor desempenho
  • Memory-Safe Event Handling: O sistema usa ConditionalWeakTable para evitar vazamentos de memória
  • Smart Auto-Scrolling: O sistema fornece um comportamento de bate-papo amigável com debouncing
  • Cancelamento gracioso: O sistema economiza trabalho parcial quando os usuários cancelam operações

Fluxo de solicitação/resposta

Veja como uma interação típica do usuário flui através do sistema:

  1. Entrada do usuário: O usuário digita uma mensagem como "Adicionar 'Comprar mantimentos' à minha lista de tarefas"
  2. Processamento de mensagens: o sistema adiciona a mensagem ao histórico de conversas
  3. LLM Analysis: Azure OpenAI analisa o pedido e decide que ferramentas utilizar
  4. Descoberta de ferramentas: o modelo encontra a ferramenta MCP certa (por exemplo, addTodo)
  5. Execução da ferramenta: O cliente MCP chama o servidor com os parâmetros necessários
  6. Processamento de resposta: O sistema adiciona a resposta do servidor à conversa
  7. UI Update: O sistema mostra o resultado para o usuário em tempo real

O diagrama a seguir mostra como as mensagens fluem da entrada do usuário através do OpenAI para a execução da ferramenta e de volta para a interface do usuário:

Diagrama mostrando o fluxo de solicitação/resposta.

Gestão de padrões assíncronos

O aplicativo demonstra padrões assíncronos sofisticados para operações em segundo plano:

// ChatSuggestions.razor
public void Update(IReadOnlyList<ChatMessage> messages)
{
    // Runs in the background and handles its own cancellation/errors
    _ = UpdateSuggestionsAsync(messages);
}

private async Task UpdateSuggestionsAsync(IReadOnlyList<ChatMessage> messages)
{
    cancellation?.Cancel();
    cancellation = new CancellationTokenSource();
    
    try
    {
        var response = await ChatClient.GetResponseAsync<string[]>(
            [.. ReduceMessages(messages), new(ChatRole.User, Prompt)],
            cancellationToken: cancellation.Token);
        // Handle response...
    }
    catch (Exception ex) when (ex is not OperationCanceledException)
    {
        await DispatchExceptionAsync(ex);
    }
}

Benefícios da tarefa em segundo plano:

  • Incêndio e Esqueça com Segurança: O sistema usa _ = padrão com manuseio adequado de exceções
  • Redução inteligente de contexto: o sistema limita o histórico de conversas para evitar a sobrecarga de tokens
  • Cancelamento inteligente: O sistema limpa adequadamente as operações concorrentes

Tratamento de erros e resiliência

A implementação inclui vários padrões de resiliência:

private void CancelAnyCurrentResponse()
{
    // If a response was cancelled while streaming, include it in the conversation so it's not lost
    if (currentResponseMessage is not null)
    {
        messages.Add(currentResponseMessage);
    }

    currentResponseCancellation?.Cancel();
    currentResponseMessage = null;
}

Características de resiliência:

  • Cancelamento normal: O sistema salva respostas em andamento quando os usuários as cancelam
  • Recuperação de conexão: O transporte SSE lida com quedas de conexão automaticamente
  • Gerenciamento de Estado: O estado da interface do usuário permanece consistente durante erros
  • Integração de registo: O sistema fornece registo completo para depuração e monitorização

Observabilidade e controlos sanitários

A aplicação inclui padrões de observabilidade sofisticados:

Configuração de verificação de integridade inteligente:

// Extensions.cs
public static WebApplication MapDefaultEndpoints(this WebApplication app)
{
    if (app.Environment.IsDevelopment())
    {
        // All health checks must pass for app to be considered ready
        app.MapHealthChecks(HealthEndpointPath);
        
        // Only health checks tagged with "live" must pass for app to be considered alive
        app.MapHealthChecks(AlivenessEndpointPath, new HealthCheckOptions
        {
            Predicate = r => r.Tags.Contains("live")
        });
    }
    return app;
}

OpenTelemetry com filtragem inteligente:

// Extensions.cs
.AddAspNetCoreInstrumentation(tracing =>
    // Exclude health check requests from tracing
    tracing.Filter = context =>
        !context.Request.Path.StartsWithSegments(HealthEndpointPath)
        && !context.Request.Path.StartsWithSegments(AlivenessEndpointPath)
)

Benefícios da observabilidade:

  • Terminais com Consciência do Ambiente: Exposição a verificações de integridade voltadas para a segurança
  • Liveness vs Readiness: padrões de verificação de saúde no estilo Kubernetes
  • Redução de ruído de telemetria: eliminando verificações de integridade de rotina dos rastros

Configuração e preparação do ambiente

A aplicação suporta vários ambientes através da configuração:

var openAIClient = Constants.GitHubModelEndpoints.Contains(endpoint.TrimEnd('/'))
                   ? new OpenAIClient(credential, openAIOptions)
                   : new AzureOpenAIClient(new Uri(endpoint), credential);

Opções de configuração:

  • Azure OpenAI: As implementações em produção normalmente utilizam Azure OpenAI Service
  • GitHub Modelos: Cenários de desenvolvimento podem usar GitHub Modelos
  • Desenvolvimento Local: Suporte para instâncias locais do servidor MCP
  • Container Deployment: Azure Container Apps para alojamento em produção

Limpeza de recursos

Depois de terminar de usar o agente MCP, limpe os recursos criados para evitar incorrer em custos desnecessários.

Para limpar recursos, siga estes passos:

  • Elimine os recursos Azure criados pela CLI do Azure Developer executando o seguinte comando no terminal na parte inferior do ecrã:

    azd down --purge --force
    

Limpar os Codespaces do GitHub

Elimina o ambiente do GitHub Codespaces para maximizar as suas horas gratuitas por núcleo.

Importante

Para mais informações sobre o armazenamento gratuito e as horas centrais da sua conta GitHub, consulte Armazenamento e horas centrais mensais incluídas no GitHub Codespaces.

  1. Inicie sessão no painel de GitHub Codespaces.

  2. Encontre os Codespaces ativos criados a partir do repositório Azure-Samples/openai-mcp-agent-dotnet GitHub.

  3. Abra o menu de contexto do espaço de código e selecione Excluir.

Obter ajuda

Regista o teu problema no Issues do repositório.