Chatboty oparte o sztuczną inteligencję (takie jak słynny ChatGPT) zdobyły ogromną popularność. Wyobraź sobie możliwość zadawania pytań programowi, który rozumie język naturalny i odpowiada niczym człowiek, to właśnie umożliwiają modele GPT. W tym artykule pokaże Ci, jak stworzyć prostego chatbota w C#, wykorzystując GPT-4 poprzez jego API. Przejdziemy przez cały proces krok po kroku: od uzyskania klucza API, przez napisanie kodu, aż po uruchomienie aplikacji. Nie obawiaj się, integracja GPT-4 z .NET jest dziś całkiem prosta, a kilka linijek kodu wystarczy, by zbudować własnego asystenta konwersacyjnego.
Krok 1: Zdobycie klucza API OpenAI (GPT-4)
Aby Twój chatbot mógł korzystać z GPT-4, potrzebujesz klucza API OpenAI. Jeśli nie masz jeszcze konta, zarejestruj się na platformie OpenAI i wygeneruj nowy sekretny klucz w sekcji API Keys. Po zalogowaniu przejdź do zakładki API Keys, kliknij Create new secret key, nadaj mu nazwę i skopiuj wygenerowany klucz w bezpieczne miejsce (np. do notatnika). Pamiętaj, że dostęp do API GPT-4 jest płatny. OpenAI poprosi Cię o podanie danych karty i zasilenie konta. Na szczęście koszty dla testowego bota będą niewielkie (kilka centów za krótkie rozmowy), ale warto mieć to na uwadze.
Uwaga: Traktuj swój klucz API jak hasło – nie publikuj go nigdzie publicznie. Każdy, kto wejdzie w posiadanie tego klucza, mógłby korzystać z Twojego limitu API (a Ty poniesiesz koszty). Za chwilę pokaże Ci, jak bezpiecznie przechowywać klucz w kodzie.
Krok 2: Utworzenie projektu C# (.NET)
Kolejnym krokiem jest stworzenie projektu aplikacji, w której zaimplementujemy chatbota. Stwórz nowy projekt, może to być prosta aplikacja konsolowa o nazwie np. ChatbotGPT.
Możesz otworzyć ten projekt w swoim ulubionym edytorze (Visual Studio, VS Code itp.) i uruchomić go, aby upewnić się, że wszystko działa – domyślnie zobaczysz w konsoli klasyczny komunikat "Hello, World!".
Teraz pora dodać narzędzia potrzebne do integracji z API OpenAI. Skorzystamy z oficjalnej biblioteki OpenAI .NET SDK, która ułatwi wywoływanie API GPT. Zainstaluj przez nugeta pakiet: OpenAI.
Pakiet OpenAI dostarcza gotowe klasy do komunikacji z API OpenAI z poziomu C#. Po zainstalowaniu biblioteki możemy przystąpić do napisania kodu chatbota.
Krok 3: Konfiguracja klucza API w aplikacji
Zanim napiszemy logikę rozmowy, musimy przekazać do aplikacji klucz API pobrany z panelu OpenAI. Nigdy nie wpisujemy klucza na sztywno w kodzie, to zła praktyka ze względów bezpieczeństwa. Zamiast tego przechowamy go w zmiennej środowiskowej lub pliku konfiguracyjnym, a nasz program odczyta stamtąd wartość.
Najprostszym podejściem jest utworzenie pliku tekstowego .env w folderze projektu (lub dodanie zmiennej środowiskowej w systemie) z zawartością:
OPENAI_API_KEY=twój_klucz_apiTaki plik .env możesz potem wczytać w aplikacji albo skorzystać z mechanizmu User Secrets .NET. Na potrzeby tego prostego projektu, w kodzie odczytamy zmienną środowiskową. Upewnij się, że przed uruchomieniem aplikacji zmienna OPENAI_API_KEY jest ustawiona (np. za pomocą pliku .env lub ręcznie w systemie). Dzięki temu w kodzie będziemy mogli pobrać klucz przez Environment.GetEnvironmentVariable() zamiast trzymać go na stałe w kodzie źródłowym.
Tip: Jeśli używasz systemu kontroli wersji (git), dodaj plik z kluczem API do .gitignore, aby nie został przypadkiem opublikowany w repozytorium. Przechowywanie sekretów w kodzie źródłowym jest bardzo ryzykowne.
Krok 4: Połączenie z GPT-4 – wysyłanie zapytań (prompt)
Mając projekt i skonfigurowany klucz, możemy napisać kod, który połączy się z modelem GPT-4 i wyśle do niego pytanie od użytkownika. W pliku Program.cs zaimplementujemy prostą pętlę: program będzie czytał linijki tekstu z konsoli (pytania użytkownika) i wysyłał je do API GPT, a następnie wypisywał odpowiedź modelu.
Najpierw zainicjujmy klienta OpenAI w naszym kodzie C#. Możemy to zrobić używając klasy ChatClient z biblioteki OpenAI:
using OpenAI.Chat;
string? apiKey = Environment.GetEnvironmentVariable("OPENAI_API_KEY");
var chatClient = new ChatClient(model: "gpt-4", apiKey: apiKey);W powyższym fragmencie tworzymy obiekt ChatClient, wskazując nazwę modelu ("gpt-4") oraz nasz klucz API. Gdybyś nie miał dostępu do GPT-4 lub chciał zaoszczędzić, możesz tu podać model gpt-3.5-turbo, reszta kodu będzie działać identycznie, tylko odpowiedzi mogą być nieco mniej rozbudowane. Ważne, aby zmienna apiKey zawierała nasz sekret (pobrany ze zmiennych środowiskowych).
Teraz przygotujemy strukturę do przechowywania historii czatu. Model GPT za każdym razem, gdy dostaje zapytanie, nie pamięta poprzednich interakcji, o ile sami mu ich nie prześlemy. Innymi słowy – musimy wysyłać w żądaniu także kontekst poprzedniej rozmowy, jeśli chcemy, by model "pamiętał" co już zostało powiedziane. Rozwiążemy to utrzymując listę wiadomości (obiektów typu ChatMessage), którą będziemy aktualizować przy każdej iteracji konwersacji.
Dodajmy następujący kod inicjujący rozmowę:
var messages = new List<ChatMessage>();
/* Dodaj opcjonalną wiadomość systemową lub powitalną asystenta na start: */
messages.Add(new SystemChatMessage("Jesteś pomocnym asystentem AI."));
Console.WriteLine("Chatbot: Cześć! W czym mogę pomóc?"); Powyżej utworzyliśmy listę messages i opcjonalnie dodaliśmy wiadomość systemową definiującą rolę AI (np. że jest pomocnym asystentem) oraz symulowaliśmy powitanie od chatbota. Wiadomości systemowe mogą służyć do ustawienia tonu lub kontekstu rozmowy (np. "Jesteś asystentem do spraw programowania..."), choć nie są one obowiązkowe. Można też na początku dodać wiadomość asystenta z gotowym powitaniem, aby użytkownik od razu coś zobaczył.
Teraz kluczowa część, pętla wczytująca pytania użytkownika i odsyłająca je do modelu:
while (true)
{
Console.ForegroundColor = ConsoleColor.Cyan;
string userInput = Console.ReadLine();
Console.ResetColor();
if (string.IsNullOrWhiteSpace(userInput) || userInput.ToLower() == "exit") break;
/* Dodaj pytanie użytkownika do historii wiadomości */
messages.Add(new UserChatMessage(userInput));
/* Wyślij całą historię czatu do modelu i uzyskaj odpowiedź */
ChatCompletion result = await chatClient.CompleteChatAsync(messages);
string assistantReply = result.Content[0].Text;
/* Dodaj odpowiedź asystenta do historii i wyświetl ją */
messages.Add(new AssistantChatMessage(assistantReply));
Console.WriteLine($"Chatbot: {assistantReply}");
}W pętli powyżej dzieje się kilka rzeczy:
1. Czytamy pytanie wpisane przez użytkownika z konsoli (Console.ReadLine()), a jeśli użytkownik wpisze "exit" lub pustą linię – kończymy konwersację i wychodzimy z pętli.
2. Dodajemy pytanie użytkownika jako nową wiadomość typu UserChatMessage do listy messages.
3. Wysyłamy zapytanie do API za pomocą chatClient.CompleteChatAsync(messages). Zwracamy uwagę, że przekazujemy całą historię messages (wraz z poprzednimi wiadomościami) – dzięki temu GPT-4 otrzymuje kontekst rozmowy i może nawiązać do wcześniejszych pytań/odpowiedzi. Metoda zwraca obiekt ChatCompletion zawierający odpowiedź wygenerowaną przez AI.
4. Wydobywamy tekst odpowiedzi (assistantReply) i dodajemy go jako AssistantChatMessage do naszej listy messages (aby ta odpowiedź również stała się częścią kontekstu w kolejnych iteracjach).
5. Wyświetlamy odpowiedź na ekranie poprzedzając ją etykietą "Chatbot:".
I to właściwie jest cały mechanizm. Nasz program w kółko pobiera pytanie i zwraca odpowiedź, aż użytkownik zakończy rozmowę.
Krok 5: Uruchomienie i testowanie chatbota
Możemy teraz uruchomić aplikację. Jeśli wszystko skonfigurowałeś poprawnie, zobaczysz powitanie chatbota i będziesz mógł wpisać własne pytanie. Model GPT-4 wygeneruje odpowiedź i nasz program wypisze ją w konsoli.
Jak widać, chatbot odpowiada całkiem naturalnie na zadane pytania. Dzięki temu, że w każdym żądaniu do API wysyłamy pełną historię czatu, model pamięta kontekst – np. gdy użytkownik poprosi "opowiedz dowcip o programistach" a potem doprecyzuje "teraz o psach", GPT-4 rozumie, że chodzi o kolejny dowcip, tym razem w innej tematyce, ponieważ ma historię rozmowy dostępną podczas generowania odpowiedzi.
Warto zauważyć, że korzystamy z asynchronicznej metody CompleteChatAsync, więc nasz program nie "zamraża się" w oczekiwaniu na odpowiedź i mógłby być łatwo rozbudowany np. o równoległe działania. Samo użycie biblioteki OpenAI SDK bardzo upraszcza kod – właściwie wszystko, co musimy zrobić, to wywołać metodę CompleteChat na liście wiadomości i odebrać wynik. Gdybyśmy chcieli, taki sam efekt moglibyśmy osiągnąć wysyłając zapytania HTTP do endpointu OpenAI /v1/chat/completions samodzielnie, ale wtedy musielibyśmy ręcznie przygotowywać JSON z wiadomościami i analizować odpowiedź. Skorzystanie z gotowej biblioteki oszczędza nam tych niskopoziomowych detali.
Podsumowanie
W kilku krokach zbudowaliśmy prostego chatbota AI w C#, wykorzystując model GPT-4 poprzez API OpenAI. Podsumujmy, co udało się osiągnąć: posiadamy klucz API (przechowywany bezpiecznie poza kodem), mamy aplikację konsolową .NET, która wysyła zapytania do modelu i wyświetla odpowiedzi, a co najważniejsze – potrafimy utrzymać konwersację, przekazując historię dialogu przy kolejnych pytaniach, dzięki czemu nasz chatbot sprawia wrażenie, jakby pamiętał poprzednie wypowiedzi. Oczywiście to dopiero początek możliwości. Taki program można rozbudować o interfejs graficzny, obsługę różnych poleceń, czy integrację z innymi usługami.
Jeśli fascynuje Cię tworzenie aplikacji z AI i chcesz wejść na wyższy poziom, rozważ dołączenie do mojego szkolenia online Szkoła AI w C#/.NET. W ramach tego szkolenia uczymy od podstaw, jak budować rozwiązania oparte o sztuczną inteligencję i uczenie maszynowe w ekosystemie .NET, od integracji modeli GPT po trenowanie własnych modeli ML. To świetna okazja, by poszerzyć swoje umiejętności i stworzyć jeszcze bardziej zaawansowane projekty z AI.