Powrót do bloga

API i SDKPrzewodnik

Pierwsze żądanie w C# z openai-dotnet: endpoint, klucz, odpowiedź

Wyślij pierwsze uzupełnienie czatu z aplikacji konsolowej C#: ustaw Endpoint w oficjalnej bibliotece OpenAI .NET, odczytaj klucz ze zmiennej środowiskowej, wypisz odpowiedź i powód zakończenia.

Autor: CheapTokens TeamOpublikowano 4 min czytania

Okładka: C# i biblioteka OpenAI .NET połączone z endpointem CheapTokens
Na tej stronie
  1. Czego potrzebujesz
  2. Zbuduj aplikację konsolową
  3. Kod, linia po linii
  4. Co powinieneś zobaczyć
  5. Przełączanie istniejącej usługi
  6. Ile kosztuje jedno żądanie
  7. Jeśli nie działa

Aby wysłać żądanie z C# do CheapTokens, zachowaj oficjalną bibliotekę OpenAI dla .NET i ustaw OpenAIClientOptions.Endpoint na https://api.cheaptokens.dev/v1. Podaj pełny identyfikator modelu, na przykład deepseek-ai/DeepSeek-V4-Flash-0731, a klucz odczytaj ze zmiennej środowiskowej. Wywołania ChatClient i CompleteChat pozostają dokładnie takie, jak w przykładach OpenAI.

Załóżmy, że masz już usługę ASP.NET, która komunikuje się z OpenAI, i chcesz wypróbować inny endpoint i model bez ruszania reszty kodu. Zanim cokolwiek do niej podłączysz, sprawdź w małej aplikacji konsolowej trzy rzeczy, które zwykle idą nie tak (klucz, endpoint, identyfikator modelu). To właśnie budujemy tutaj. Poniższe szczegóły pochodzą z README biblioteki na GitHubie (openai/openai-dotnet, sprawdzone 5 listopada 2026) oraz z dokumentacji CheapTokens: strona dokumentacji podaje ten sam bazowy URL.

Czego potrzebujesz#

Pakiet nazywa się OpenAI w NuGet. Najnowsza stabilna wersja na 5 listopada 2026 to 2.15.0 (wpis w changelogu jest datowany na 4 listopada). Obsługuje .NET 8 i .NET Standard 2.0, a README mówi, że działa ze wszystkimi aplikacjami .NET Standard 2.0, więc starszy projekt też jest w porządku.

Do aplikacji trafiają trzy wartości:

  • bazowy URL: https://api.cheaptokens.dev/v1 (zgodny z OpenAI Chat Completions);
  • identyfikator modelu: deepseek-ai/DeepSeek-V4-Flash-0731. Używaj pełnego identyfikatora, krótka nazwa z tabeli cen nie jest akceptowana. DeepSeek-V4-Flash ma okno kontekstu 380K i do 32 768 tokenów wyjściowych na odpowiedź, jedna cena o każdej porze dnia;
  • klucz API z Twojego konta CheapTokens, trzymany w zmiennej środowiskowej. Jeśli nie wiesz, jak go przechowywać, przeczytaj jak bezpiecznie przechowywać klucz API.

Zbuduj aplikację konsolową#

Krok po kroku

Utwórz projekt i uruchom go

Utwórz projekt konsolowy

bash
dotnet new console -o FirstRequest
cd FirstRequest

Dodaj pakiet

bash
dotnet add package OpenAI

Umieść klucz w zmiennej środowiskowej

W bashu lub zsh:

bash
export CHEAPTOKENS_API_KEY=your-key

W Windows PowerShell:

powershell
$env:CHEAPTOKENS_API_KEY = "your-key"

Wklej kod i uruchom

Zastąp zawartość Program.cs kodem z następnej sekcji, a następnie uruchom dotnet run.

Terminal z pięcioma poleceniami, które tworzą i uruchamiają aplikację konsolową
Pięć poleceń: utwórz projekt, wejdź do folderu, dodaj pakiet, ustaw klucz, uruchom.

Kod, linia po linii#

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

README pokazuje ten wzorzec dla "proxiego lub samodzielnie hostowanego LLM zgodnego z OpenAI": endpoint trafia do OpenAIClientOptions, klucz do ApiKeyCredential (znajduje się w System.ClientModel, stąd pierwszy using). Sprawdzenie na górze jest nasze: daje jasny komunikat, jeśli zmienna nie jest ustawiona.

CompleteChat ze zwykłym stringiem wysyła jedną wiadomość użytkownika i czeka na całą odpowiedź. Tekst odpowiedzi jest w completion.Content[0].Text. Powód zakończenia jest w completion.FinishReason.

Przepływ: klucz ze zmiennej środowiskowej, ChatClient z Endpoint, CompleteChat, tekst i FinishReason
Co dzieje się w programie od klucza do wypisanej odpowiedzi.

Co powinieneś zobaczyć#

Powinieneś otrzymać krótkie wyjaśnienie tokenów i linię z powodem zakończenia; po normalnym zakończeniu to Stop (README porównuje FinishReason z ChatFinishReason.Stop). Treść odpowiedzi zmienia się z każdym uruchomieniem.

Druga linia jest tą, którą warto przeczytać. README porównuje FinishReason z ChatFinishReason.Stop (model zakończył samodzielnie) i ChatFinishReason.ToolCalls (model chce wywołać narzędzie). Cokolwiek innego niż Stop w zwykłym czacie oznacza, że odpowiedź zakończyła się z innego powodu, a zwykłym podejrzanym jest limit długości. Jeśli widzisz odpowiedź, która urywa się w połowie zdania, ten artykuł wyjaśnia finish_reason i max_tokens.

Przełączanie istniejącej usługi#

Jeśli Twoja usługa już tworzy ChatClient dla OpenAI, zmieniasz dwie rzeczy: string modelu i opcje. Reszta wywołań działa dalej.

Porównaj

Ten sam klient, dwie zmienione linie

Przed

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

Po

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

Dla krótkich żądań jest druga opcja: zai-org/GLM-5.3-Flash (kontekst 390K, do 8 192 tokenów wyjściowych). Zmieniasz tylko string model. Lista identyfikatorów, których może użyć Twój klucz, jest o jedno żądanie stąd, zobacz Lista modeli z GET /v1/models.

Ile kosztuje jedno żądanie#

Załóżmy, że usługa obsługuje 1000 żądań dziennie, każde około 300 tokenów na wejściu i 400 tokenów na wyjściu. Jedno takie żądanie kosztuje $0.000045 na DeepSeek-V4-Flash. Poniższa tabela pokazuje te same 1000 żądań na wszystkich trzech modelach obok OpenRouter. W sumie, licząc wejście i wyjście razem, DeepSeek-V4-Flash jest tańszy niż OpenRouter. Aktualne ceny są na stronie cen, a strona DeepSeek wymienia, co oferuje model.

Model Za żądanie 1000 żądań OpenRouter, 1000 żądań
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 tokenów wejściowych i 400 tokenów wyjściowych na żądanie. Ceny za 1 mln tokenów są aktualne i zmieniają się wraz z naszymi taryfami; kolumna OpenRouter pokazuje ceny referencyjne dla tego samego obciążenia.

Jeśli nie działa#

  • 401. Brakuje klucza lub jest błędny. Wypisz, czy zmienna jest ustawiona (sprawdzenie w kodzie to robi) i upewnij się, że dotnet run jest uruchomiony w tym samym terminalu, w którym uruchomiłeś export (lub $env:): zmienna żyje tylko w tej sesji.
  • 404. Najczęściej identyfikator modelu: krótka nazwa zamiast pełnego deepseek-ai/DeepSeek-V4-Flash-0731 albo endpoint bez /v1 (sprawdź też, czy OpenAIClientOptions jest naprawdę przekazywany do ChatClient). Szczegóły są w API 401 lub 404: zły klucz, bazowy URL lub identyfikator modelu.
  • error CS0246: The type or namespace name 'ApiKeyCredential' could not be found. Brakuje linii using System.ClientModel; na górze Program.cs.

Ten sam pomysł w innym języku: wersja w Go z openai-go.