Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
In diesem Artikel erfahren Sie, wie Sie einen MCP-Agent (Model Context Protocol) mit .NET erstellen. In diesem Beispiel stellt der MCP-Client (geschrieben in C#/.NET) eine Verbindung mit einem MCP-Server (geschrieben in TypeScript) zum Verwalten einer Aufgabenliste bereit. Der Client findet verfügbare Tools vom Server und sendet sie an ein Azure OpenAI-Modell. Benutzer können dann mit dem Todo-System sprechen, indem sie die alltagssprachliche Sprache verwenden.
Zum Code gelangen
Schauen Sie sich die OpenAI MCP Agent Building Block AI-Vorlage an. In diesem Beispiel wird gezeigt, wie Sie einen OpenAI-Agent erstellen, der einen MCP-Client verwendet, um einen vorhandenen MCP-Server zu nutzen.
Wechseln Sie zum Code-Durchgang Abschnitt, um zu verstehen, wie dieses Beispiel funktioniert.
Architekturübersicht
Das folgende Diagramm zeigt die einfache Architektur der Beispiel-App:
- MCP-Client: Stellt eine Verbindung mit dem MCP-Server bereit und findet verfügbare Tools.
- Chat Client: Arbeitet mit Azure OpenAI, um natürliche Sprache zu verstehen
- Blazor UI: Stellt eine Weboberfläche bereit, über die Benutzer chatten können
- Transportschicht: Nutzt Server-Sent Events (SSE) zum Senden von Nachrichten in Echtzeit.
- Authentifizierung: Verwendet JWT-Token, um die Verbindung sicher zu halten
Der MCP-Server wird als containerisierte App auf Azure Container Apps (ACA) ausgeführt. Es verwendet ein TypeScript-Back-End, um Tools für den MCP-Client über das Model Context Protocol bereitzustellen. Alle Tools arbeiten mit einer Back-End SQLite-Datenbank.
Hinweis
Besuchen Sie Erstellen Sie einen TypeScript MCP-Server mit Azure Container Apps, um die Code-Demonstration des im Artikel verwendeten TypeScript MCP-Servers zu sehen.
Kosten
Um die Kosten niedrig zu halten, verwendet dieses Beispiel grundlegende preisniveaus oder Verbrauchsniveaus für die meisten Ressourcen. Passen Sie die Ebene nach Bedarf an, und löschen Sie Ressourcen, wenn Sie damit fertig sind, um Gebühren zu vermeiden.
Voraussetzungen
- Visual Studio Code – Neueste Version zur Unterstützung der MCP Server-Entwicklung.
- .NET 9 SDK
- C#Dev Kit für Visual Studio Code Visual Studio Code Erweiterung
- GitHub Copilot Visual Studio Code Erweiterung
- GitHub Copilot Chat Visual Studio Code Erweiterung
- Azure Developer CLI (azd)
- Microsoft Foundry für Visual Studio Code Erweiterung
- Ein bereitgestelltes Foundry GPT-5-Mini-Modell
Ein Entwicklungscontainer enthält alle Abhängigkeiten, die Sie für diesen Artikel benötigen. Sie können sie in GitHub Codespaces (in einem Browser) oder lokal mit Visual Studio Code ausführen.
Um diesem Artikel zu folgen, stellen Sie sicher, dass Sie diese Voraussetzungen erfüllen:
Bereitstellen eines Foundry gpt-5-mini-Modells mithilfe der Foundry VS Code Extension
Stellen Sie ein gpt-5-mini-Modell mithilfe der Foundry Extension in Visual Studio Code mithilfe der folgenden Schritte bereit:
Erstellen eines Foundry-Projekts und Bereitstellen des Modells
- Um ein Foundry-Projekt zu erstellen und ein
gpt-5-mini-Modell bereitzustellen, befolgen Sie die Get Started-Anweisungen im Artikel Work with the Microsoft Foundry for Visual Studio Code extension (Preview).
Erstellen Sie die Verbindungzeichenfolge des OpenAI-Modells
Nachdem das
gpt-5-miniModell bereitgestellt wurde, klicken Sie mit der rechten Maustaste auf das Modell in der Foundry-Erweiterung, und wählen Sie "API-Schlüssel kopieren " aus, um den API-Schlüssel des Modells in die Zwischenablage zu kopieren.Klicken Sie als Nächstes mit der rechten Maustaste auf das bereitgestellte
gpt-5-miniModell in der Foundry-Erweiterung, und wählen Sie "Endpunkt kopieren" aus, um den Endpunkt des Modells in die Zwischenablage zu kopieren, wie im folgenden Screenshot gezeigt:Erstellen Sie schließlich eine connection string für das bereitgestellte
gpt-5-mini-Modell mit dem kopierten Endpunkt- und API-Schlüssel im folgenden Format:Endpoint=<AZURE_OPENAI_ENDPOINT>;Key=<AZURE_OPENAI_API_KEY>. Sie benötigen diese connection string weiter unten im Artikel.
- Ein Azure-Abonnement – Create one for free
- Azure Kontoberechtigungen – Ihr Azure Konto muss über
Microsoft.Authorization/roleAssignments/writeBerechtigungen verfügen, z. B. Role Based Access Control Administrator, Benutzerzugriffsadministrator oder Owner. Wenn Sie nicht über Berechtigungen auf Abonnementebene verfügen, müssen Sie RBAC für eine vorhandene Ressourcengruppe erhalten und für diese Gruppe bereitstellen.- Ihr Azure Konto benötigt auch
Microsoft.Resources/deployments/writeBerechtigungen auf Abonnementebene.
- Ihr Azure Konto benötigt auch
- GitHub Konto
Offene Entwicklungsumgebung
Führen Sie die folgenden Schritte aus, um eine vorkonfigurierte Entwicklungsumgebung mit allen erforderlichen Abhängigkeiten einzurichten.
GitHub Codespaces führt einen Entwicklungscontainer aus, der von GitHub mit Visual Studio Code für das Web verwaltet wird als Schnittstelle. Verwenden Sie GitHub Codespaces für die einfachste Einrichtung, da sie die erforderlichen Tools und Abhängigkeiten enthält, die für diesen Artikel vorinstalliert sind.
Von Bedeutung
Alle GitHub-Konten können Codespaces für bis zu 60 Stunden kostenlos jeden Monat mit zwei Kerninstanzen verwenden. Weitere Informationen finden Sie unter GitHub Codespaces monatlich enthaltene Speicher- und Kernstunden.
Führen Sie die folgenden Schritte aus, um einen neuen GitHub Codespace im main Branch des Repositorys Azure-Samples/openai-mcp-agent-dotnet GitHub zu erstellen.
Klicken Sie mit der rechten Maustaste auf die folgende Schaltfläche, und wählen Sie im neuen Fenster "Link öffnen" aus. Mit dieser Aktion können Sie die Entwicklungsumgebung und die Dokumentation nebeneinander öffnen.
Überprüfen Sie auf der Seite Codespace erstellen die Informationen und wählen Sie dann Neuen Codespace erstellen.
Warten Sie, bis der Codespace gestartet wird. Es kann einige Minuten dauern.
Stellen Sie sicher, dass der Name
gpt-5-minides bereitgestellten Modells lautet. Wenn Ihr bereitgestelltes Modell anders ist, aktualisieren Siesrc/McpTodo.ClientApp/appsettings.jsonmit dem richtigen Bereitstellungsnamen.{ "OpenAI": { // Make sure this is the right deployment name. "DeploymentName": "gpt-5-mini" } }Melden Sie sich mit der Azure Developer CLI am unteren Bildschirmrand bei Azure an.
azd auth loginKopieren Sie den Code vom Terminal, und fügen Sie ihn dann in einen Browser ein. Folgen Sie den Anweisungen, um sich bei Ihrem Azure Konto zu authentifizieren.
Sie führen die restlichen Aufgaben in diesem Entwicklungscontainer aus.
Hinweis
So führen Sie den MCP-Agent lokal aus:
- Richten Sie Ihre Umgebung ein, wie im Abschnitt Getting started im Beispiel-Repository beschrieben.
- Installieren Sie Ihren MCP-Server, indem Sie die Anweisungen im Abschnitt Get MCP Server App im Beispiel-Repository befolgen.
- Führen Sie den MCP-Agent lokal aus, indem Sie den Anweisungen im Abschnitt Run lokal im Beispiel-Repository folgen.
- Fahren Sie mit dem Abschnitt Verwendung des TODO MCP-Agents fort.
Bereitstellen und Ausführen
Das Beispiel-Repository enthält alle Code- und Konfigurationsdateien für die Bereitstellung des MCP-Agenten auf Azure. Die folgenden Schritte führen Sie durch den Bereitstellungsprozess des Azure-MCP-Beispielagenten.
Bereitstellen auf Azure
Von Bedeutung
Azure-Ressourcen in diesem Bereich beginnen sofort, Kosten zu verursachen, auch wenn Sie den Befehl beenden, bevor er abgeschlossen ist.
Festlegen des JWT-Tokens
Legen Sie das JWT-Token für den MCP-Server fest, indem Sie den folgenden Befehl im Terminal am unteren Rand des Bildschirms ausführen:
# zsh/bash ./scripts/set-jwttoken.sh# PowerShell ./scripts/Set-JwtToken.ps1
Hinzufügen eines JWT-Tokens zur Azd-Umgebungskonfiguration
Fügen Sie das JWT-Token zur Azd-Umgebungskonfiguration hinzu, indem Sie den folgenden Befehl am unteren Rand des Bildschirms im Terminal ausführen:
# 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 -ForceHinweis
Standardmäßig ist die MCP-Client-App durch das integrierte ACA-Authentifizierungsfeature geschützt. Sie können dieses Feature vor der Ausführung
azd updeaktivieren, indem Sie Folgendes festlegen:azd env set USE_LOGIN falseFühren Sie den folgenden Azure Developer CLI-Befehl für Azure Ressourcenbereitstellung und Quellcodebereitstellung aus:
azd upVerwenden Sie die folgende Tabelle, um die Eingabeaufforderungen zu beantworten:
Prompt Antwort Umgebungsname Verwenden Sie einen kurzen, kleingeschriebenen Namen. Fügen Sie Ihren Namen oder Alias hinzu. Beispiel: my-mcp-agent. Der Umgebungsname wird Teil des Ressourcengruppennamens.Subscription Wählen Sie das Abonnement aus, in dem Sie Ressourcen erstellen möchten. Standort (für Hosting) Wählen Sie den Installationsort des Modells aus der Liste aus. OpenAI-Verbindungszeichenfolge Fügen Sie die Verbindungszeichenfolge für das OpenAI-Modell, das Sie zuvor erstellt haben, im Abschnitt Create the OpenAI Model connection string ein. Die App-Bereitstellung dauert 5 bis 10 Minuten.
Nach Abschluss der Bereitstellung können Sie mithilfe der URL in der Ausgabe auf den MCP-Agent zugreifen. Die URL sieht wie folgt aus:
https://<env-name>.<container-id>.<region>.azurecontainerapps.ioÖffnen Sie die URL in einem Webbrowser, um den MCP-Agent zu verwenden.
Verwenden des TODO MCP-Agents
Nachdem der MCP-Agent ausgeführt wurde, können Sie die tools verwenden, die er im Agentmodus bereitstellt. So verwenden Sie MCP-Tools im Agentmodus:
Navigieren Sie zur Client-App-URL, und melden Sie sich bei der App an.
Hinweis
Wenn Sie den
USE_LOGINWert auf "false" festlegen, werden Sie möglicherweise nicht aufgefordert, sich anzumelden.Geben Sie eine Eingabeaufforderung wie "Ich muss am Mittwoch eine E-Mail an meinen Vorgesetzten senden" im Chateingabefeld ein, und beachten Sie, wie Tools bei Bedarf automatisch aufgerufen werden.
Der MCP-Agent verwendet die vom MCP-Server bereitgestellten Tools, um die Anforderung zu erfüllen und eine Antwort in der Chatschnittstelle zurückzugeben.
Experimentieren Sie mit anderen Eingabeaufforderungen wie:
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.
Untersuchen des Codes
Das Beispiel-Repository enthält alle Code- und Konfigurationsdateien für die Bereitstellung des MCP-Agenten auf Azure. In den folgenden Abschnitten werden Sie durch die wichtigsten Komponenten des MCP-Agent-Codes geführt.
MCP-Clientkonfiguration und -einrichtung
Die Anwendung richtet den MCP-Client in Program.csein. Diese Konfiguration definiert, wie eine Verbindung hergestellt und welche Optionen verwendet werden sollen. Der Code verwendet verschiedene erweiterte Muster, einschließlich .NET Aspire Integrations- und Dienststandardeinstellungen:
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();
});
Wichtige Implementierungsdetails:
-
Transportkonfiguration:
SseClientTransportOptionsunterstützt sowohl Server-Sent-Ereignisse (SSE) als auch streambaren HTTP-Transport. Die Transportmethode hängt von der Endpunkt-URL ab – Endpunkte, die mit/sseenden, verwenden Server-Sent Events, während Endpunkte, die mit/mcpenden, streambares HTTP nutzen. Dieser Ansatz ermöglicht die Echtzeitkommunikation zwischen Client und Server. -
Authentifizierungsheader: JWT-Token werden in
AdditionalHeadersaufgenommen, um die Serverkommunikation sicher zu halten -
Clientinformationen: teilt dem Server den Namen und die Version des Clients mit.
McpClientOptions -
Factory Pattern:
McpClientFactory.CreateAsync()verbindet und schließt den Protokoll-Handshake ab.
.NET Aspire Service-Standardeinstellungen Integration
Die Anwendung verwendet das Standarddienstmuster von .NET Aspire für Querschnittsbelange.
// 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;
}
Standardmäßige Vorteile des Diensts:
- Komponierbare Erweiterungsmethoden: Das System verwendet ein klares Builder-Muster, um gemeinsame Funktionen hinzuzufügen.
- Standardresilienzhandler: Das System fügt integrierte Wiederholungs-, Schaltkreisbrecher- und Timeoutregeln für Sie hinzu.
- Service Discovery Integration: Das System findet Dienste automatisch in Containerumgebungen.
- OpenTelemetry standardmäßig: Das System erhält vollständiges Monitoring ohne jeglichen Einrichtungsaufwand.
Das folgende Diagramm zeigt die Beziehung zwischen querschneidenden Bedenken und Anwendungsdiensten:
Konfigurations-URL-Auflösung
Das Beispiel enthält eine anspruchsvolle URL-Auflösung für verschiedene Umgebungen:
// 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...
}
Funktionen der Konfigurationsverwaltung:
- Service Discovery Abstraction: Das System verarbeitet Entwicklungs- und Produktions-URLs sauber
- Protokollverhandlung: Das System wählt zuerst HTTPS und greift dann auf HTTP zurück.
- Configuration Convention: Das System verwendet Standardmäßige .NET Aspire Dienstsetupmuster.
Authentifizierungsimplementierung
In diesem Beispiel wird die JWT-Authentifizierung (JSON Web Token) verwendet, um die Verbindung zwischen dem MCP-Client und dem Server zu sichern.
dotnet user-secrets --project ./src/McpTodo.ClientApp set McpServers:JWT:Token "$TOKEN"
Hinweis
Die Skripts haben die Variable $TOKEN automatisch erstellt, wenn Sie entweder das Skript Bash (set-jwttoken.sh) oder powerShell-Skript (Set-JwtToken.ps1) weiter oben im Abschnitt Deploy to Azure ausgeführt haben.
Diese Skripts führen die folgenden Schritte aus:
- Ausführen
npm run generate-tokenin der MCP-Server-App zum Erstellen eines JWT-Tokens - Analysieren der generierten
.envDatei zum Extrahieren des JWT_TOKEN Werts - Automatisches Speichern in den .NET User Secrets für den MCPClient
Der MCP-Client ruft das JWT-Token aus der Konfiguration ab und schließt es in die HTTP-Header für die Authentifizierung ein, wenn eine Verbindung mit dem MCP-Server hergestellt wird:
AdditionalHeaders = new Dictionary<string, string>
{
{ "Authorization", $"Bearer {config["McpServers:JWT:Token"]!}" }
}
Dieser Ansatz stellt Folgendes sicher:
- Sichere Kommunikation: Das System ermöglicht Clients nur mit gültigen Token, eine Verbindung mit dem MCP-Server herzustellen.
- Token-Based Autorisierung: JWT-Token ermöglichen es dem System, Benutzer zu überprüfen, ohne Sitzungsdaten zu speichern.
- Konfigurationsverwaltung: Das System speichert vertrauliche Token während der Entwicklung sicher in geheimen Benutzerschlüsseln.
Azure Container Apps Authentifizierungsintegration
Die Infrastruktur zeigt erweiterte Authentifizierungsmuster mit Azure Container Apps integrierten Authentifizierungs- und Autorisierungsfeatures ("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
}
}
}
}
}
Erweiterte Authentifizierungsfeatures:
- Zero-Code Authentication: Azure Container Apps bietet integrierte Authentifizierung
- Verwaltete Identität für Speicher: Das System speichert Token ohne Verbindungszeichenfolgen sicher
- Verbundidentitätsanmeldeinformationen: Das System ermöglicht die Workload-Identität für die Authentifizierung im Stil von Kubernetes
Das folgende Diagramm zeigt den Sicherheitshandshake zwischen Komponenten.
Toolermittlung und -registrierung
Der MCP-Client erkennt verfügbare Tools vom Server während der Komponenteninitialisierung in Chat.razor:
protected override async Task OnInitializedAsync()
{
messages.Add(new(ChatRole.System, SystemPrompt));
tools = await McpClient.ListToolsAsync();
chatOptions.Tools = [.. tools];
}
Wie die Tool-Ermittlung funktioniert:
-
Serverabfrage:
McpClient.ListToolsAsync()sendet eine Anforderung an den MCP-Server, um verfügbare Tools auflisten zu können. - Schemaabruf: Der Server sendet Tooldefinitionen mit Namen, Beschreibungen und Eingabeschemas zurück.
-
Toolregistrierung: Das System registriert Tools mit dem
ChatOptionsObjekt und stellt sie dem OpenAI-Client zur Verfügung. -
Typsicherheit: Die
McpClientToolKlasse erbt vonAIFunction, was eine reibungslose Integration mit Microsoft.Extensions.AI ermöglicht.
Das folgende Diagramm zeigt, wie Toolschemas analysiert und registriert werden:
OpenAI-Integration und Funktionsaufruf
Die Konfiguration des Chatclients veranschaulicht, wie MCP-Tools in Azure OpenAI integriert werden:
var chatClient = openAIClient.GetChatClient(config["OpenAI:DeploymentName"]).AsIChatClient();
builder.Services.AddChatClient(chatClient)
.UseFunctionInvocation()
.UseLogging();
Integrationsvorteile:
-
Automatische Funktionsaufrufe: Die
.UseFunctionInvocation()Erweiterung aktiviert die automatische Toolausführung basierend auf LLM-Entscheidungen - Einfacher Toolzugriff: MCP-Tools funktionieren als integrierte Funktionen für das OpenAI-Modell
- Antwortverarbeitung: Das System fügt dem Unterhaltungsfluss automatisch Toolergebnisse hinzu.
Real-Time Chatimplementierung
Die Chatoberfläche in Chat.razor zeigt Streaming-Antworten und die Ausführung von Tools mit erweiterten Blazor-Mustern:
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);
}
Features der Streamingimplementierung:
-
Real-Time Updates:
GetStreamingResponseAsync()Sendet Antwort-Updates bitweise - Toolausführung: Das System verarbeitet Funktionsaufrufe während des Streamings automatisch
-
Reaktionsfähigkeit der Benutzeroberfläche:
ChatMessageItem.NotifyChanged()Aktualisiert die Benutzeroberfläche in Echtzeit. - Abbruchsupport: Benutzer können lange ausgeführte Vorgänge abbrechen
Erweiterte Blazor-UI-Muster
Die Implementierung verwendet erweiterte Benutzeroberflächenmuster für Echtzeitupdates:
Memory-Safe Ereignisbehandlung:
// 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();
}
}
Integration benutzerdefinierter Webkomponenten:
// 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...
});
}
});
Erweiterte Zustandsverwaltung:
// 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;
}
Vorteile der Blazor-Benutzeroberfläche:
- Hybridwebkomponenten: Das System kombiniert Blazor Server mit benutzerdefinierten Elementen für eine bessere Leistung
- Memory-Safe Ereignisbehandlung: Das System verwendet ConditionalWeakTable zur Vermeidung von Speicherverlusten.
- Intelligentes Automatisches Scrollen: Das System bietet benutzerfreundliches Chatverhalten mit Entprellen
- Ordnungsgemäßer Abbruch: Das System speichert teilweise Arbeit, wenn Benutzer Vorgänge abbrechen
Anforderungs-/Antwortfluss
So fließt eine typische Benutzerinteraktion über das System:
- Benutzereingabe: Der Benutzer gibt eine Meldung wie "Lebensmittel kaufen" zu meiner Aufgabenliste hinzufügen" ein.
- Nachrichtenverarbeitung: Das System fügt die Nachricht dem Unterhaltungsverlauf hinzu.
- LLM Analysis: Azure OpenAI analysiert die Anforderung und entscheidet, welche Tools verwendet werden sollen.
-
ToolErmittlung: Das Modell findet das richtige MCP-Tool (z. B
addTodo. ) - Toolausführung: Der MCP-Client ruft den Server mit den erforderlichen Parametern auf.
- Antwortverarbeitung: Das System fügt der Unterhaltung die Serverantwort hinzu.
- Benutzeroberflächenaktualisierung: Das System zeigt dem Benutzer das Ergebnis in Echtzeit an.
Das folgende Diagramm zeigt, wie Nachrichten von der Benutzereingabe über OpenAI zur Toolausführung und zurück zur Benutzeroberfläche fließen:
Asynchrone Musterverwaltung
Die Anwendung veranschaulicht komplexe asynchrone Muster für Hintergrundvorgänge:
// 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);
}
}
Vorteile von Hintergrundaufgaben:
-
Feuer-und-Vergessen mit Sicherheit: Das System verwendet
_ =Muster mit korrekter Ausnahmebehandlung. - Intelligente Kontextreduzierung: Das System begrenzt den Unterhaltungsverlauf, um einen Token-Überlauf zu verhindern.
- Intelligente Stornierung: Das System bereinigt konkurrierende Vorgänge ordnungsgemäß
Fehlerbehandlung und Resilienz
Die Implementierung umfasst mehrere Resilienzmuster:
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;
}
Resilienzfunktionen:
- Eleganter Abbruch: Das System speichert fortlaufende Antworten, wenn Benutzer sie abbrechen.
- Verbindungswiederherstellung: Der SSE-Transport verwaltet Verbindungsabbrüche automatisch.
- Zustandsverwaltung: Der UI-Zustand bleibt während Fehlern konsistent.
- Protokollierungsintegration: Das System bietet vollständige Protokollierung zum Debuggen und Überwachen.
Überwachbarkeit und Integritätsprüfungen
Die Anwendung umfasst komplexe Observability-Muster:
Konfiguration der Intelligenten Gesundheitsprüfung:
// 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 mit intelligenter Filterung:
// Extensions.cs
.AddAspNetCoreInstrumentation(tracing =>
// Exclude health check requests from tracing
tracing.Filter = context =>
!context.Request.Path.StartsWithSegments(HealthEndpointPath)
&& !context.Request.Path.StartsWithSegments(AlivenessEndpointPath)
)
Vorteile der Beobachtbarkeit:
- Environment-Aware Endpunkte: Sicherheitsbewusste Gesundheitsüberprüfung
- Liveness vs Readiness: Muster für Gesundheitsprüfungen im Kubernetes-Stil
- Telemetrie-Rauschreduzierung: Filtern von Routine-Gesundheitschecks aus Ablaufverfolgungen
Konfiguration und Umgebungseinrichtung
Die Anwendung unterstützt mehrere Umgebungen durch Konfiguration:
var openAIClient = Constants.GitHubModelEndpoints.Contains(endpoint.TrimEnd('/'))
? new OpenAIClient(credential, openAIOptions)
: new AzureOpenAIClient(new Uri(endpoint), credential);
Konfigurationsoptionen:
- Azure OpenAI: Produktionsbereitstellungen verwenden in der Regel Azure OpenAI Service
- GitHub Modelle: Entwicklungsszenarien können GitHub Modelle verwenden.
- Lokale Entwicklung: Unterstützung für lokale MCP-Serverinstanzen
- Container-Bereitstellung: Azure Container Apps für Produktionshosting
Bereinigen von Ressourcen
Nach Abschluss der Verwendung des MCP-Agents bereinigen Sie die von Ihnen erstellten Ressourcen, um unnötige Kosten zu vermeiden.
Führen Sie die folgenden Schritte aus, um Ressourcen zu bereinigen:
Löschen Sie die Azure Ressourcen, die von der Azure Developer CLI erstellt wurden, indem Sie den folgenden Befehl im Terminal am unteren Rand des Bildschirms ausführen:
azd down --purge --force
Bereinigen GitHub Codespaces
Löschen Sie die GitHub Codespaces-Umgebung, um Ihre kostenlosen Stunden pro Kern zu maximieren.
Von Bedeutung
Weitere Informationen zu den kostenlosen Speicher- und Kernstunden Ihres GitHub Kontos finden Sie unter GitHub Codespaces monatlich enthaltene Speicher- und Kernstunden.
Melden Sie sich beim GitHub Codespaces-Dashboard an.
Suchen Sie Ihre aktiven Codespaces, die aus dem GitHub-Repository
Azure-Samples/openai-mcp-agent-dotneterstellt wurden.Öffnen Sie das Kontextmenü für den Codespace und wählen Sie Löschenaus.
Hier erhalten Sie Hilfe
Erfassen Sie Ihr Problem im Issues-Bereich des Repositorys.