Zurück zum Blog

API & SDKAnleitung

Erste Anfrage in C# mit openai-dotnet: Endpunkt, Schlüssel, Antwort

Sende deine erste Chat-Completion aus einer C#-Konsolen-App: Setze den Endpoint in der offiziellen OpenAI-.NET-Bibliothek, lies den Schlüssel aus der Umgebungsvariable, gib die Antwort und den Finish-Grund aus.

Von CheapTokens TeamVeröffentlicht am 4 Min. Lesezeit

Cover: C# und die OpenAI-.NET-Bibliothek verbunden mit dem CheapTokens-Endpunkt
Auf dieser Seite
  1. Was du brauchst
  2. Die Konsolen-App bauen
  3. Der Code, Zeile für Zeile
  4. Was du sehen solltest
  5. Einen bestehenden Dienst umstellen
  6. Was eine Anfrage kostet
  7. Wenn es nicht funktioniert

Um eine Anfrage von C# an CheapTokens zu senden, behalte die offizielle OpenAI-Bibliothek für .NET bei und setze OpenAIClientOptions.Endpoint auf https://api.cheaptokens.dev/v1. Übergib die vollständige Modell-ID, zum Beispiel deepseek-ai/DeepSeek-V4-Flash-0731, und lies den Schlüssel aus einer Umgebungsvariable. Die Aufrufe ChatClient und CompleteChat bleiben genau wie in den OpenAI-Beispielen.

Angenommen, du hast bereits einen ASP.NET-Dienst, der mit OpenAI spricht, und möchtest einen anderen Endpunkt und ein anderes Modell ausprobieren, ohne den restlichen Code anzufassen. Bevor du irgendetwas darin verdrahtest, prüfe die drei Dinge, bei denen üblicherweise etwas schiefgeht (Schlüssel, Endpunkt, Modell-ID), in einer kleinen Konsolen-App. Genau das bauen wir hier. Die Details unten stammen aus der README der Bibliothek auf GitHub (openai/openai-dotnet, geprüft am 5. November 2026) und aus der CheapTokens-Dokumentation: die Dokumentationsseite hat dieselbe Basis-URL.

Was du brauchst#

Das Paket heißt OpenAI auf NuGet. Die neueste stabile Version am 5. November 2026 ist 2.15.0 (der Changelog-Eintrag ist vom 4. November). Es zielt auf .NET 8 und .NET Standard 2.0 ab, und laut README funktioniert es mit allen .NET Standard 2.0-Anwendungen, also ist auch ein älteres Projekt in Ordnung.

Drei Werte gehören in die App:

  • Basis-URL: https://api.cheaptokens.dev/v1 (kompatibel mit OpenAI Chat Completions);
  • Modell-ID: deepseek-ai/DeepSeek-V4-Flash-0731. Verwende die vollständige ID, der Kurzname aus einer Preistabelle wird nicht akzeptiert. DeepSeek-V4-Flash hat ein Kontextfenster von 380K und bis zu 32.768 Ausgabe-Tokens pro Antwort, ein Preis zu jeder Tageszeit;
  • einen API-Schlüssel aus deinem CheapTokens-Konto, aufbewahrt in einer Umgebungsvariable. Wenn du unsicher bist, wie du ihn speichern sollst, lies wie du einen API-Schlüssel sicher speicherst.

Die Konsolen-App bauen#

Schritt für Schritt

Erstelle das Projekt und führe es aus

Ein Konsolenprojekt erstellen

bash
dotnet new console -o FirstRequest
cd FirstRequest

Das Paket hinzufügen

bash
dotnet add package OpenAI

Den Schlüssel in eine Umgebungsvariable legen

In bash oder zsh:

bash
export CHEAPTOKENS_API_KEY=your-key

In Windows PowerShell:

powershell
$env:CHEAPTOKENS_API_KEY = "your-key"

Den Code einfügen und ausführen

Ersetze den Inhalt von Program.cs durch den Code aus dem nächsten Abschnitt und führe dann dotnet run aus.

Terminal mit den fünf Befehlen, die die Konsolen-App erstellen und ausführen
Die fünf Befehle: Projekt erstellen, in den Ordner wechseln, Paket hinzufügen, Schlüssel setzen, ausführen.

Der Code, Zeile für Zeile#

csharp
using System.ClientModel;
using OpenAI;
using OpenAI.Chat;

string? apiKey = Environment.GetEnvironmentVariable("CHEAPTOKENS_API_KEY");
if (string.IsNullOrEmpty(apiKey))
{
    Console.WriteLine("Set CHEAPTOKENS_API_KEY first.");
    return;
}

ChatClient client = new(
    model: "deepseek-ai/DeepSeek-V4-Flash-0731",
    credential: new ApiKeyCredential(apiKey),
    options: new OpenAIClientOptions
    {
        Endpoint = new Uri("https://api.cheaptokens.dev/v1")
    });

ChatCompletion completion = client.CompleteChat("Explain in two sentences what a token is.");

Console.WriteLine(completion.Content[0].Text);
Console.WriteLine($"finish_reason: {completion.FinishReason}");

Die README zeigt dieses Muster für "einen Proxy oder ein selbst gehostetes OpenAI-kompatibles LLM": der Endpunkt kommt in OpenAIClientOptions, der Schlüssel in ein ApiKeyCredential (es lebt in System.ClientModel, daher das erste using). Die Prüfung am Anfang ist unsere: Sie gibt eine klare Meldung aus, wenn die Variable nicht gesetzt ist.

CompleteChat mit einem einfachen String sendet eine Benutzernachricht und wartet auf die vollständige Antwort. Der Antworttext steht in completion.Content[0].Text. Der Finish-Grund steht in completion.FinishReason.

Ablauf: Schlüssel aus der Umgebungsvariable, ChatClient mit Endpoint, CompleteChat, Text und FinishReason
Was im Programm vom Schlüssel bis zur ausgegebenen Antwort passiert.

Was du sehen solltest#

Du solltest eine kurze Erklärung zu Tokens und eine Zeile mit dem Finish-Grund erhalten; nach einem normalen Ende ist er Stop (die README vergleicht FinishReason mit ChatFinishReason.Stop). Der Wortlaut der Antwort ändert sich von Lauf zu Lauf.

Die zweite Zeile ist die, die es zu lesen lohnt. Die README vergleicht FinishReason mit ChatFinishReason.Stop (das Modell ist von selbst fertig geworden) und ChatFinishReason.ToolCalls (das Modell möchte ein Tool aufrufen). Alles andere als Stop in einem einfachen Chat bedeutet, dass die Antwort aus einem anderen Grund geendet hat, und der übliche Verdächtige ist ein Längenlimit. Wenn du eine Antwort siehst, die mitten im Satz abbricht, erklärt dieser Artikel finish_reason und max_tokens.

Einen bestehenden Dienst umstellen#

Wenn dein Dienst bereits einen ChatClient für OpenAI erstellt, änderst du zwei Dinge: den Modell-String und die Optionen. Der Rest der Aufrufe funktioniert weiterhin.

Vergleichen

Derselbe Client, zwei geänderte Zeilen

Vorher

csharp
ChatClient client = new(
    model: "your-current-model",
    credential: new ApiKeyCredential(apiKey));

Nachher

csharp
ChatClient client = new(
    model: "deepseek-ai/DeepSeek-V4-Flash-0731",
    credential: new ApiKeyCredential(apiKey),
    options: new OpenAIClientOptions
    {
        Endpoint = new Uri("https://api.cheaptokens.dev/v1")
    });

Für kurze Anfragen gibt es eine zweite Option: zai-org/GLM-5.3-Flash (390K Kontext, bis zu 8.192 Ausgabe-Tokens). Du änderst nur den String model. Eine Liste der IDs, die dein Schlüssel verwenden kann, ist nur eine Anfrage entfernt, siehe Modelle mit GET /v1/models auflisten.

Was eine Anfrage kostet#

Angenommen, ein Dienst bearbeitet 1.000 Anfragen pro Tag, jede mit etwa 300 Tokens Eingabe und 400 Tokens Ausgabe. Eine solche Anfrage kostet $0.000045 bei DeepSeek-V4-Flash. Die Tabelle unten zeigt dieselben 1.000 Anfragen bei allen drei Modellen neben OpenRouter. Insgesamt, mit Eingabe und Ausgabe zusammengerechnet, ist DeepSeek-V4-Flash günstiger als OpenRouter. Aktuelle Preise stehen auf der Preisseite, und die DeepSeek-Seite listet, was das Modell bietet.

Modell Pro Anfrage 1.000 Anfragen OpenRouter, 1.000 Anfragen
GLM-5.3-Flash $0.000022 $0.022 $0.0433
DeepSeek-V4-Flash $0.000045 $0.0445 $0.077
MiniMax-M2.7 $0.000075 $0.075 $0.90

300 Input- und 400 Output-Tokens pro Anfrage. Die Preise pro 1 Mio. Tokens sind aktuell und ändern sich zusammen mit unseren Tarifen; die OpenRouter-Spalte zeigt Referenzpreise für dieselbe Arbeitslast.

Wenn es nicht funktioniert#

  • 401. Der Schlüssel fehlt oder ist falsch. Gib aus, ob die Variable gesetzt ist (die Prüfung im Code macht das), und stelle sicher, dass dotnet run im selben Terminal gestartet wurde, in dem du export (oder $env:) ausgeführt hast: Die Variable lebt nur in dieser Sitzung.
  • 404. Meistens die Modell-ID: ein Kurzname statt der vollständigen deepseek-ai/DeepSeek-V4-Flash-0731 oder ein Endpunkt ohne /v1 (prüfe auch, dass OpenAIClientOptions wirklich an ChatClient übergeben wird). Details stehen in API 401 oder 404: falscher Schlüssel, Basis-URL oder Modell-ID.
  • error CS0246: The type or namespace name 'ApiKeyCredential' could not be found. Die Zeile using System.ClientModel; fehlt oben in Program.cs.

Dieselbe Idee in einer anderen Sprache: die Go-Version mit openai-go.