# Zbuduj Asystenta Czatu z AI
Pamiętasz w Star Treku, kiedy załoga swobodnie rozmawiała z komputerem statku, zadając mu skomplikowane pytania i otrzymując przemyślane odpowiedzi? To, co w latach 60. XX wieku wydawało się czystą fantastyką naukową, dziś możesz zbudować, używając znanych Ci technologii webowych.
W tej lekcji stworzymy asystenta czatu AI, korzystając z HTML, CSS, JavaScript oraz integracji backendowej. Odkryjesz, jak te same umiejętności, które zdobywasz, mogą połączyć się z potężnymi usługami AI, które rozumieją kontekst i generują sensowne odpowiedzi.
Pomyśl o AI jak o dostępie do ogromnej biblioteki, która nie tylko potrafi znaleźć informacje, ale także syntetyzuje je w spójne odpowiedzi dostosowane do Twoich konkretnych pytań. Zamiast przeszukiwać tysiące stron, otrzymujesz bezpośrednie, kontekstowe odpowiedzi.
Integracja odbywa się poprzez znane technologie webowe, które ze sobą współpracują. HTML tworzy interfejs czatu, CSS zajmuje się projektem wizualnym, JavaScript obsługuje interakcje użytkownika, a API backendowe łączy to wszystko z usługami AI. To podobne do współpracy różnych sekcji orkiestry, tworzących symfonię.
Budujemy zasadniczo most między naturalną komunikacją ludzką a przetwarzaniem maszynowym. Nauczysz się zarówno technicznej realizacji integracji z usługą AI, jak i wzorców projektowych, które sprawiają, że interakcje wydają się intuicyjne.
Pod koniec tej lekcji integracja z AI będzie mniej tajemniczym procesem, a bardziej kolejnym API, z którym możesz pracować. Zrozumiesz podstawowe wzorce, które napędzają aplikacje takie jak ChatGPT i Claude, korzystając z tych samych zasad tworzenia stron internetowych, które poznajesz.
## ⚡ Co możesz zrobić w następnych 5 minutach
**Szybka droga startowa dla zapracowanych programistów**
```mermaid
flowchart LR
A[⚡ 5 minut] --> B[Uzyskaj token GitHub]
B --> C[Przetestuj AI playground]
C --> D[Skopiuj kod Pythona]
D --> E[Zobacz odpowiedzi AI]
```
- **Minuta 1**: Odwiedź [GitHub Models Playground](https://github.com/marketplace/models/azure-openai/gpt-4o-mini/playground) i utwórz token dostępu osobistego
- **Minuta 2**: Przetestuj interakcje z AI bezpośrednio w interfejsie playground
- **Minuta 3**: Kliknij zakładkę „Code” i skopiuj fragment kodu w Pythonie
- **Minuta 4**: Uruchom kod lokalnie ze swoim tokenem: `GITHUB_TOKEN=your_token python test.py`
- **Minuta 5**: Obserwuj pierwszą wygenerowaną odpowiedź AI z własnego kodu
**Szybki testowy kod**:
```python
import os
from openai import OpenAI
client = OpenAI(
base_url="https://models.github.ai/inference",
api_key="your_token_here"
)
response = client.chat.completions.create(
messages=[{"role": "user", "content": "Hello AI!"}],
model="openai/gpt-4o-mini"
)
print(response.choices[0].message.content)
```
**Dlaczego to ważne**: W ciągu 5 minut doświadczysz magii programistycznej interakcji z AI. To fundamentalny budulec każdego zastosowania AI, którego używasz.
Oto jak będzie wyglądał Twój ukończony projekt:

## 🗺️ Twoja podróż edukacyjna przez rozwój aplikacji AI
```mermaid
journey
title Od rozwoju sieci do integracji AI
section Zrozumienie podstaw AI
Odkryj koncepcje generatywnej AI: 4: You
Poznaj platformę modeli GitHub: 6: You
Opanuj parametry i zapytania AI: 8: You
section Integracja backendu
Zbuduj serwer API w Pythonie: 5: You
Wdróż wywołania funkcji AI: 7: You
Obsłuż operacje asynchroniczne: 8: You
section Rozwój frontend
Stwórz nowoczesny interfejs czatu: 6: You
Opanuj interakcje w czasie rzeczywistym: 8: You
Zbuduj responsywne doświadczenie użytkownika: 9: You
section Profesjonalna aplikacja
Wdróż kompletny system AI: 7: You
Optymalizuj wzorce wydajności: 8: You
Stwórz aplikację gotową do produkcji: 9: You
```
**Cel twojej podróży**: Pod koniec tej lekcji zbudujesz kompletną aplikację zasilaną AI, korzystając z tych samych technologii i wzorców, które napędzają nowoczesnych asystentów AI, takich jak ChatGPT, Claude i Google Bard.
## Zrozumienie AI: od tajemnicy do mistrzostwa
Zanim zanurzymy się w kod, zrozummy, z czym mamy do czynienia. Jeśli wcześniej korzystałeś z API, znasz podstawowy schemat: wysyłasz zapytanie, otrzymujesz odpowiedź.
API AI działają podobnie, ale zamiast pobierać wstępnie zapisane dane z bazy, generują nowe odpowiedzi na podstawie wzorców nauczonych z ogromnych zbiorów tekstów. Pomyśl o tym jak o różnicy między katalogiem bibliotecznym a znającym się bibliotekarzem, który potrafi syntetyzować informacje z wielu źródeł.
### Czym naprawdę jest „Generatywna AI”?
Pomyśl, jak Kamień z Rosetty pozwolił uczonym zrozumieć egipskie hieroglify, znajdując wzorce między znanymi i nieznanymi językami. Modele AI działają podobnie – odnajdują wzorce w ogromnych ilościach tekstu, aby zrozumieć, jak działa język, a następnie wykorzystują te wzorce do generowania odpowiednich odpowiedzi na nowe pytania.
**Wyjaśnię to prostym porównaniem:**
- **Tradycyjna baza danych**: jak proszenie o akt urodzenia – dostajesz dokładnie ten sam dokument za każdym razem
- **Wyszukiwarka**: jak proszenie bibliotekarza o znalezienie książek o kotach – pokazuje, co jest dostępne
- **Generatywna AI**: jak pytanie mądrego przyjaciela o koty – opowiada ciekawe rzeczy własnymi słowami, dostosowane do tego, co chcesz wiedzieć
```mermaid
graph LR
A[Twoje pytanie] --> B[Model AI]
B --> C[Rozpoznawanie wzorców]
C --> D[Generowanie treści]
D --> E[Kontextowa odpowiedź]
F[Dane treningowe
Książki, Artykuły, Sieć] --> B
```
### Jak uczą się modele AI (wersja uproszczona)
Modele AI uczą się, mając dostęp do ogromnych zbiorów danych zawierających teksty z książek, artykułów i rozmów. W trakcie tego procesu identyfikują wzorce w:
- Sposobie, w jaki strukturyzowane są myśli w komunikacji pisemnej
- Jakie słowa często występują razem
- Jak przebiegają typowe rozmowy
- Różnice kontekstowe między komunikacją formalną i nieformalną
**To podobne do metod archeologów rozszyfrowujących starożytne języki**: analizują tysiące przykładów, aby poznać gramatykę, słownictwo i kontekst kulturowy, aż w końcu potrafią interpretować nowe teksty, bazując na poznanych wzorcach.
### Dlaczego GitHub Models?
Korzystamy z GitHub Models z bardzo praktycznego powodu – daje nam dostęp do AI na poziomie korporacyjnym, bez konieczności zakładania własnej infrastruktury AI (uwierz mi, nie chcesz tego robić teraz!). To tak, jak korzystanie z API pogodowego zamiast prób przewidywania pogody samodzielnie, zakładając stacje meteorologiczne wszędzie.
To zasadniczo „AI jako usługa” i najlepsze jest to, że możesz zacząć za darmo, eksperymentując bez obawy o ogromne koszty.
```mermaid
graph LR
A[Interfejs czatu frontend] --> B[Twój backend API]
B --> C[GitHub Models API]
C --> D[Przetwarzanie modelu AI]
D --> C
C --> B
B --> A
```
Użyjemy GitHub Models do integracji backendowej, która zapewnia dostęp do profesjonalnych możliwości AI przez przyjazny dla programisty interfejs. [GitHub Models Playground](https://github.com/marketplace/models/azure-openai/gpt-4o-mini/playground) służy jako środowisko testowe, gdzie możesz eksperymentować z różnymi modelami AI i zrozumieć ich możliwości przed implementacją w kodzie.
## 🧠 Ekosystem rozwoju aplikacji AI
```mermaid
mindmap
root((Rozwój AI))
Understanding AI
Generative Models
Rozpoznawanie wzorców
Generowanie treści
Zrozumienie kontekstu
Synteza odpowiedzi
AI Parameters
Kontrola temperatury
Limity tokenów
Filtrowanie Top-p
Systemowe podpowiedzi
Backend Architecture
API Integration
Modele GitHub
Uwierzytelnianie
Obsługa żądań
Zarządzanie błędami
Python Infrastructure
Framework FastAPI
Operacje asynchroniczne
Bezpieczeństwo środowiska
Konfiguracja CORS
Frontend Experience
Chat Interface
Aktualizacje w czasie rzeczywistym
Historia wiadomości
Opinie użytkowników
Stany ładowania
Modern Web Tech
Klasy ES6
Async/Await
Manipulacja DOM
Obsługa zdarzeń
Professional Patterns
Security Best Practices
Zarządzanie tokenami
Walidacja danych wejściowych
Zapobieganie XSS
Granice błędów
Production Readiness
Optymalizacja wydajności
Responsywny design
Dostępność
Strategie testowania
```
**Główna zasada**: rozwój aplikacji AI łączy tradycyjne umiejętności tworzenia stron internetowych z integracją usług AI, tworząc inteligentne aplikacje, które są naturalne i responsywne dla użytkowników.

**Co sprawia, że playground jest tak przydatny:**
- **Wypróbuj** różne modele AI, takie jak GPT-4o-mini, Claude i inne (wszystkie darmowe!)
- **Przetestuj** swoje pomysły i zapytania przed napisaniem kodu
- **Uzyskaj** gotowe fragmenty kodu w preferowanym języku programowania
- **Dostosuj** ustawienia, takie jak poziom kreatywności i długość odpowiedzi, aby zobaczyć, jak wpływają na wynik
Po zabawie po prostu kliknij zakładkę „Code” i wybierz język programowania, aby otrzymać potrzebny kod implementacyjny.

## Konfiguracja integracji backendowej w Pythonie
Teraz zaimplementujmy integrację AI przy użyciu Pythona. Python jest doskonały do aplikacji AI ze względu na prostą składnię i potężne biblioteki. Zaczniemy od kodu z GitHub Models playground, a potem przebudujemy go na funkcję wielokrotnego użytku, gotową do produkcji.
### Zrozumienie podstawowej implementacji
Gdy pobierzesz kod Pythona z playground, otrzymasz coś takiego. Nie martw się, jeśli na początku wydaje się skomplikowane – przejdziemy przez to krok po kroku:
```python
"""Run this model in Python
> pip install openai
"""
import os
from openai import OpenAI
# Aby uwierzytelnić się w modelu, musisz wygenerować osobisty token dostępu (PAT) w ustawieniach GitHub.
# Utwórz swój token PAT, postępując zgodnie z instrukcjami tutaj: https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens
client = OpenAI(
base_url="https://models.github.ai/inference",
api_key=os.environ["GITHUB_TOKEN"],
)
response = client.chat.completions.create(
messages=[
{
"role": "system",
"content": "",
},
{
"role": "user",
"content": "What is the capital of France?",
}
],
model="openai/gpt-4o-mini",
temperature=1,
max_tokens=4096,
top_p=1
)
print(response.choices[0].message.content)
```
**Co się dzieje w tym kodzie:**
- **Importujemy** niezbędne narzędzia: `os` do odczytu zmiennych środowiskowych oraz `OpenAI` do komunikacji z AI
- **Konfigurujemy** klienta OpenAI tak, aby łączył się z serwerami AI GitHub, a nie bezpośrednio z OpenAI
- **Uwierzytelniamy** się za pomocą specjalnego tokenu GitHub (więcej o tym za chwilę!)
- **Strukturyzujemy** naszą rozmowę z różnymi „rolami” – to jak ustawianie sceny do przedstawienia
- **Wysyłamy** zapytanie do AI z pewnymi parametrami dostrajania
- **Wyciągamy** faktyczny tekst odpowiedzi z całych danych zwróconych przez AI
### Zrozumienie ról wiadomości: ramy rozmowy z AI
Rozmowy z AI mają określoną strukturę z różnymi „rolami”, które pełnią różne funkcje:
```python
messages=[
{
"role": "system",
"content": "You are a helpful assistant who explains things simply."
},
{
"role": "user",
"content": "What is machine learning?"
}
]
```
**Pomyśl o tym jak o reżyserii przedstawienia:**
- **Rola systemu**: jak wskazówki sceniczne dla aktora – mówi AI, jak się zachowywać, jaką mieć osobowość i jak odpowiadać
- **Rola użytkownika**: faktyczne pytanie lub wiadomość od osoby korzystającej z aplikacji
- **Rola asystenta**: odpowiedź AI (nie wysyłasz jej, ale pojawia się w historii rozmowy)
**Analogicznie w realnym świecie**: wyobraź sobie, że przedstawiasz przyjaciela na imprezie:
- **Wiadomość systemowa**: „To jest moja przyjaciółka Sarah, jest lekarzem i świetnie tłumaczy medyczne kwestie prostym językiem”
- **Wiadomość użytkownika**: „Czy możesz wyjaśnić, jak działają szczepionki?”
- **Odpowiedź asystenta**: Sarah odpowiada jako przyjazny lekarz, a nie prawnik czy kucharz
### Zrozumienie parametrów AI: dostrajanie zachowania odpowiedzi
Parametry numeryczne w wywołaniach API AI kontrolują, jak model generuje odpowiedzi. Ustawienia te pozwalają dostosować zachowanie AI do różnych zastosowań:
#### Temperature (0.0 do 2.0): pokrętło kreatywności
**Co robi**: Kontroluje, jak kreatywne lub przewidywalne będą odpowiedzi AI.
**Pomyśl o tym jak o poziomie improwizacji muzyka jazzowego:**
- **Temperature = 0.1**: Gra tę samą melodię za każdym razem (bardzo przewidywalne)
- **Temperature = 0.7**: Dodaje subtelne wariacje, pozostając rozpoznawalnym (zrównoważona kreatywność)
- **Temperature = 1.5**: Pełna, eksperymentalna improwizacja jazzowa z niespodziewanymi zwrotami (bardzo nieprzewidywalne)
```python
# Bardzo przewidywalne odpowiedzi (dobre dla pytań faktualnych)
response = client.chat.completions.create(
messages=[{"role": "user", "content": "What is 2+2?"}],
temperature=0.1 # Prawie zawsze powie „4”
)
# Kreatywne odpowiedzi (dobre do burzy mózgów)
response = client.chat.completions.create(
messages=[{"role": "user", "content": "Write a creative story opening"}],
temperature=1.2 # Wygeneruje unikalne, nieoczekiwane historie
)
```
#### Max Tokens (1 do 4096+): kontrola długości odpowiedzi
**Co robi**: Ustawia limit długości odpowiedzi AI.
**Pomyśl o tokenach jak o mniej więcej równoważnych słowach** (około 1 token ≈ 0,75 słowa po angielsku):
- **max_tokens=50**: Krótka i zwięzła odpowiedź (jak SMS)
- **max_tokens=500**: Fajny akapit lub dwa
- **max_tokens=2000**: Szczegółowe wyjaśnienie z przykładami
```python
# Krótkie, zwięzłe odpowiedzi
response = client.chat.completions.create(
messages=[{"role": "user", "content": "Explain JavaScript"}],
max_tokens=100 # Wymusza krótkie wyjaśnienie
)
# Szczegółowe, obszerne odpowiedzi
response = client.chat.completions.create(
messages=[{"role": "user", "content": "Explain JavaScript"}],
max_tokens=1500 # Pozwala na szczegółowe wyjaśnienia z przykładami
)
```
#### Top_p (0.0 do 1.0): parametr skupienia
**Co robi**: Kontroluje, jak bardzo AI skupia się na najbardziej prawdopodobnych odpowiedziach.
**Wyobraź sobie, że AI ma ogromne słownictwo, uporządkowane według prawdopodobieństwa słów:**
- **top_p=0.1**: Biera pod uwagę jedynie 10% najbardziej prawdopodobnych słów (bardzo skoncentrowane)
- **top_p=0.9**: Biera pod uwagę 90% możliwych słów (bardziej kreatywne)
- **top_p=1.0**: Uwzględnia wszystko (maksymalna różnorodność)
**Na przykład**: gdy pytasz „Niebo zazwyczaj jest...”
- **Niskie top_p**: prawie na pewno odpowie „niebieskie”
- **Wysokie top_p**: może powiedzieć „niebieskie”, „pochmurne”, „rozległe”, „zmienne”, „piękne” itd.
### Skomponowanie wszystkiego razem: kombinacje parametrów dla różnych zastosowań
```python
# Dla merytorycznych, spójnych odpowiedzi (jak bot dokumentacyjny)
factual_params = {
"temperature": 0.2,
"max_tokens": 300,
"top_p": 0.3
}
# Dla pomocy w twórczym pisaniu
creative_params = {
"temperature": 1.1,
"max_tokens": 1000,
"top_p": 0.9
}
# Dla rozmownych, pomocnych odpowiedzi (zrównoważonych)
conversational_params = {
"temperature": 0.7,
"max_tokens": 500,
"top_p": 0.8
}
```
```mermaid
quadrantChart
title Macierz optymalizacji parametrów SI
x-axis Niska kreatywność --> Wysoka kreatywność
y-axis Krótka odpowiedź --> Długa odpowiedź
quadrant-1 Kreatywne treści
quadrant-2 Szczegółowa analiza
quadrant-3 Szybkie fakty
quadrant-4 Konwersacyjne SI
Documentation Bot: [0.2, 0.3]
Customer Service: [0.4, 0.4]
General Assistant: [0.7, 0.5]
Creative Writer: [0.9, 0.9]
Brainstorming Tool: [0.8, 0.8]
```
**Dlaczego te parametry są ważne**: różne aplikacje potrzebują różnych rodzajów odpowiedzi. Bot obsługi klienta powinien być spójny i faktualny (niskie temperature), podczas gdy kreatywny asystent pisarski powinien być pomysłowy i zróżnicowany (wysokie temperature). Zrozumienie tych parametrów daje Ci kontrolę nad osobowością i stylem odpowiedzi AI.
```
**Here's what's happening in this code:**
- **We import** the tools we need: `os` for reading environment variables and `OpenAI` for talking to the AI
- **We set up** the OpenAI client to point to GitHub's AI servers instead of OpenAI directly
- **We authenticate** using a special GitHub token (more on that in a minute!)
- **We structure** our conversation with different "roles" – think of it like setting the scene for a play
- **We send** our request to the AI with some fine-tuning parameters
- **We extract** the actual response text from all the data that comes back
> 🔐 **Security Note**: Never hardcode API keys in your source code! Always use environment variables to store sensitive credentials like your `GITHUB_TOKEN`.
### Creating a Reusable AI Function
Let's refactor this code into a clean, reusable function that we can easily integrate into our web application:
```python
import asyncio
from openai import AsyncOpenAI
# Use AsyncOpenAI for better performance
client = AsyncOpenAI(
base_url="https://models.github.ai/inference",
api_key=os.environ["GITHUB_TOKEN"],
)
async def call_llm_async(prompt: str, system_message: str = "You are a helpful assistant."):
"""
Sends a prompt to the AI model asynchronously and returns the response.
Args:
prompt: The user's question or message
system_message: Instructions that define the AI's behavior and personality
Returns:
str: The AI's response to the prompt
"""
try:
response = await client.chat.completions.create(
messages=[
{
"role": "system",
"content": system_message,
},
{
"role": "user",
"content": prompt,
}
],
model="openai/gpt-4o-mini",
temperature=1,
max_tokens=4096,
top_p=1
)
return response.choices[0].message.content
except Exception as e:
logger.error(f"AI API error: {str(e)}")
return "I'm sorry, I'm having trouble processing your request right now."
# Backward compatibility function for synchronous calls
def call_llm(prompt: str, system_message: str = "You are a helpful assistant."):
"""Synchronous wrapper for async AI calls."""
return asyncio.run(call_llm_async(prompt, system_message))
```
**Zrozumienie tej ulepszonej funkcji:**
- **Przyjmuje** dwa parametry: zapytanie użytkownika i opcjonalną wiadomość systemową
- **Zapewnia** domyślną wiadomość systemową dla ogólnego zachowania asystenta
- **Używa** prawidłowych podpowiedzi typów Pythona dla lepszej dokumentacji kodu
- **Zawiera** szczegółowy docstring wyjaśniający cel i parametry funkcji
- **Zwraca** tylko treść odpowiedzi, co ułatwia jej użycie w naszej webowej API
- **Utrzymuje** te same parametry modelu dla spójnego zachowania AI
### Magia promptów systemowych: programowanie osobowości AI
Jeśli parametry kontrolują, jak AI myśli, prompt systemowy kontroluje, kim AI myśli, że jest. To naprawdę jedna z najfajniejszych części pracy z AI – zasadniczo dajesz AI pełną osobowość, poziom wiedzy i styl komunikacji.
**Pomyśl o promptach systemowych jak o obsadzaniu różnych aktorów do różnych ról**: zamiast jednego uniwersalnego asystenta, możesz stworzyć specjalistycznych ekspertów do różnych sytuacji. Potrzebujesz cierpliwego nauczyciela? Kreatywnego partnera do burzy mózgów? Dobrego doradcy biznesowego? Wystarczy zmienić prompt systemowy!
#### Dlaczego prompt systemowy jest tak potężny
Oto fascynująca część: modele AI były trenowane na niezliczonych rozmowach, w których ludzie przyjmowali różne role i poziomy wiedzy. Gdy dasz AI konkretną rolę, to jak przełączenie przełącznika aktywującego wszystkie te wyuczone wzorce.
**To jak metoda aktorska dla AI**: powiedz aktorowi „jesteś mądrym, starym profesorem” i obserwuj, jak automatycznie dostosowuje postawę, słownictwo i maniery. AI robi coś niezwykle podobnego z wzorcami językowymi.
#### Tworzenie efektywnych promptów systemowych: sztuka i nauka
**Anatomia świetnego promptu systemowego:**
1. **Rola/Tożsamość**: Kim jest AI?
2. **Ekspertyza**: Co wie?
3. **Styl komunikacji**: Jak mówi?
4. **Konkretne instrukcje**: Na czym ma się skupić?
```python
# ❌ Niejasna podpowiedź systemowa
"You are helpful."
# ✅ Szczegółowa, skuteczna podpowiedź systemowa
"You are Dr. Sarah Chen, a senior software engineer with 15 years of experience at major tech companies. You explain programming concepts using real-world analogies and always provide practical examples. You're patient with beginners and enthusiastic about helping them understand complex topics."
```
#### Przykłady promptów systemowych z kontekstem
Zobaczmy, jak różne prompt systemowy tworzą całkowicie odmienne osobowości AI:
```python
# Przykład 1: Cierpliwy nauczyciel
teacher_prompt = """
You are an experienced programming instructor who has taught thousands of students.
You break down complex concepts into simple steps, use analogies from everyday life,
and always check if the student understands before moving on. You're encouraging
and never make students feel bad for not knowing something.
"""
# Przykład 2: Kreatywny współpracownik
creative_prompt = """
You are a creative writing partner who loves brainstorming wild ideas. You're
enthusiastic, imaginative, and always build on the user's ideas rather than
replacing them. You ask thought-provoking questions to spark creativity and
offer unexpected perspectives that make stories more interesting.
"""
# Przykład 3: Strategiczny doradca biznesowy
business_prompt = """
You are a strategic business consultant with an MBA and 20 years of experience
helping startups scale. You think in frameworks, provide structured advice,
and always consider both short-term tactics and long-term strategy. You ask
probing questions to understand the full business context before giving advice.
"""
```
#### Widok promptów systemowych w praktyce
Przetestujmy to samo pytanie, używając różnych promptów systemowych, aby zobaczyć znaczące różnice:
**Pytanie**: „Jak obsługiwać uwierzytelnianie użytkownika w mojej aplikacji webowej?”
```python
# Z poleceniem nauczyciela:
teacher_response = call_llm(
"How do I handle user authentication in my web app?",
teacher_prompt
)
# Typowa odpowiedź: „Świetne pytanie! Rozbijmy uwierzytelnianie na proste kroki.
# Pomyśl o tym jak o ochroniarzu w klubie nocnym sprawdzającym dowody tożsamości...”
# Z poleceniem biznesowym:
business_response = call_llm(
"How do I handle user authentication in my web app?",
business_prompt
)
# Typowa odpowiedź: „Z strategicznego punktu widzenia uwierzytelnianie jest kluczowe dla zaufania użytkowników
# oraz zgodności z przepisami. Pozwól, że przedstawię ramy uwzględniające bezpieczeństwo,
# doświadczenie użytkownika i skalowalność...”
```
#### Zaawansowane techniki promptów systemowych
**1. Ustawianie kontekstu**: daj AI informacje w tle
```python
system_prompt = """
You are helping a junior developer who just started their first job at a startup.
They know basic HTML/CSS/JavaScript but are new to backend development and databases.
Be encouraging and explain things step-by-step without being condescending.
"""
```
**2. Formatowanie wyjścia**: Powiedz AI, jak organizować odpowiedzi
```python
system_prompt = """
You are a technical mentor. Always structure your responses as:
1. Quick Answer (1-2 sentences)
2. Detailed Explanation
3. Code Example
4. Common Pitfalls to Avoid
5. Next Steps for Learning
"""
```
**3. Ustalanie ograniczeń**: Określ, czego AI NIE powinno robić
```python
system_prompt = """
You are a coding tutor focused on teaching best practices. Never write complete
solutions for the user - instead, guide them with hints and questions so they
learn by doing. Always explain the 'why' behind coding decisions.
"""
```
#### Dlaczego to jest ważne dla Twojego asystenta czatu
Zrozumienie poleceń systemowych daje Ci niesamowitą moc tworzenia wyspecjalizowanych asystentów AI:
- **Bot obsługi klienta**: pomocny, cierpliwy, świadomy polityk
- **Nauczyciel**: zachęcający, krok po kroku, sprawdzający zrozumienie
- **Partner kreatywny**: pomysłowy, rozwijający idee, zadający pytanie "a co jeśli?"
- **Ekspert techniczny**: precyzyjny, szczegółowy, dbający o bezpieczeństwo
**Kluczowa wskazówka**: Nie wywołujesz tylko interfejsu API AI – tworzysz spersonalizowaną osobowość AI, odpowiadającą na Twój konkretny przypadek użycia. To właśnie sprawia, że nowoczesne aplikacje AI wydają się dostosowane i użyteczne, a nie ogólne.
### 🎯 Pedagogiczna kontrola: Programowanie osobowości AI
**Zatrzymaj się i przemyśl**: Właśnie nauczyłeś się programować osobowości AI za pomocą poleceń systemowych. To podstawowa umiejętność w nowoczesnym rozwoju aplikacji AI.
**Szybka samoocena**:
- Czy potrafisz wyjaśnić, czym polecenia systemowe różnią się od zwykłych wiadomości użytkownika?
- Jaka jest różnica pomiędzy parametrami temperature a top_p?
- Jak stworzyłbyś polecenie systemowe dla konkretnego zastosowania (np. nauczyciel kodowania)?
**Połączenie z rzeczywistością**: Techniki poleceń systemowych, których się nauczyłeś, są używane w każdej większej aplikacji AI – od asystenta kodowania GitHub Copilot po interfejs konwersacyjny ChatGPT. Opanowujesz te same wzorce, które wykorzystują zespoły produktowe AI w dużych firmach technologicznych.
**Pytanie wyzwania**: Jak zaprojektowałbyś różne osobowości AI dla różnych typów użytkowników (początkujący vs ekspert)? Rozważ, jak ten sam podstawowy model AI mógłby obsługiwać różne grupy odbiorców dzięki inżynierii promptów.
## Budowanie Web API za pomocą FastAPI: Twoje wydajne centrum komunikacji AI
Zbudujmy teraz backend, który połączy frontend z usługami AI. Użyjemy FastAPI, nowoczesnego frameworka Pythona, który doskonale sprawdza się w tworzeniu API dla aplikacji AI.
FastAPI oferuje kilka zalet dla tego typu projektów: wbudowane wsparcie async do obsługi współbieżnych zapytań, automatyczne generowanie dokumentacji API oraz świetną wydajność. Serwer FastAPI będzie pośrednikiem, który odbiera żądania z frontendu, komunikuje się z usługami AI i zwraca sformatowane odpowiedzi.
### Dlaczego FastAPI do aplikacji AI?
Możesz się zastanawiać: „Czy nie można po prostu wywołać AI bezpośrednio z frontendowego JavaScriptu?” albo „Dlaczego FastAPI zamiast Flask lub Django?” Świetne pytania!
**Oto dlaczego FastAPI jest idealny do tego, co budujemy:**
- **Domyślnie async**: Może obsługiwać wiele żądań AI jednocześnie bez zacięć
- **Automatyczna dokumentacja**: Odwiedź `/docs`, aby zobaczyć piękną, interaktywną dokumentację API za darmo
- **Wbudowana walidacja**: Wykrywa błędy zanim wywołają problemy
- **Błyskawiczna wydajność**: Jeden z najszybszych frameworków Python
- **Nowoczesny Python**: Korzysta z najnowszych i najlepszych funkcji Pythona
**A oto dlaczego w ogóle potrzebujemy backendu:**
**Bezpieczeństwo**: Twój klucz API do AI jest jak hasło – jeśli umieścisz go w frontendowym JavaScript, każdy, kto zobaczy kod źródłowy Twojej strony, może go ukraść i wykorzystać Twoje kredyty AI. Backend trzyma poufne dane w bezpiecznym miejscu.
**Ograniczanie częstotliwości i kontrola**: Backend pozwala kontrolować, jak często użytkownicy mogą robić zapytania, implementować uwierzytelnianie użytkowników i dodawać logi do śledzenia użycia.
**Przetwarzanie danych**: Możesz chcieć zapisywać rozmowy, filtrować nieodpowiednie treści lub łączyć wiele usług AI. Logika ta żyje właśnie w backendzie.
**Architektura przypomina model klient-serwer:**
- **Frontend**: warstwa interfejsu użytkownika do interakcji
- **Backend API**: warstwa przetwarzania i kierowania żądań
- **Usługa AI**: zewnętrzne przetwarzanie i generowanie odpowiedzi
- **Zmienne środowiskowe**: bezpieczna konfiguracja i przechowywanie danych uwierzytelniających
### Zrozumienie przepływu żądanie-odpowiedź
Prześledźmy, co się dzieje, gdy użytkownik wysyła wiadomość:
```mermaid
sequenceDiagram
participant User as 👤 Użytkownik
participant Frontend as 🌐 Frontend
participant API as 🔧 Serwer FastAPI
participant AI as 🤖 Usługa AI
User->>Frontend: Wpisuje "Cześć AI!"
Frontend->>API: POST /hello {"message": "Cześć AI!"}
Note over API: Weryfikuje żądanie
Dodaje prompt systemowy
API->>AI: Wysyła sformatowane żądanie
AI->>API: Zwraca odpowiedź AI
Note over API: Przetwarza odpowiedź
Rejestruje rozmowę
API->>Frontend: {"response": "Cześć! W czym mogę pomóc?"}
Frontend->>User: Wyświetla wiadomość AI
```
**Zrozumienie każdego kroku:**
1. **Interakcja użytkownika**: Osoba wpisuje wiadomość w interfejsie czatu
2. **Przetwarzanie frontendu**: JavaScript przechwytuje wejście i formatuje je jako JSON
3. **Walidacja API**: FastAPI automatycznie weryfikuje żądanie przy pomocy modeli Pydantic
4. **Integracja AI**: Backend dodaje kontekst (polecenie systemowe) i wywołuje usługę AI
5. **Obsługa odpowiedzi**: API odbiera odpowiedź AI i może ją zmodyfikować
6. **Wyświetlanie frontendu**: JavaScript pokazuje odpowiedź w interfejsie czatu
### Zrozumienie architektury API
```mermaid
sequenceDiagram
participant Frontend
participant FastAPI
participant AI Function
participant GitHub Models
Frontend->>FastAPI: POST /hello {"message": "Witaj AI!"}
FastAPI->>AI Function: call_llm(wiadomość, system_prompt)
AI Function->>GitHub Models: zapytanie API
GitHub Models->>AI Function: odpowiedź AI
AI Function->>FastAPI: tekst odpowiedzi
FastAPI->>Frontend: {"response": "Cześć! Jak mogę pomóc?"}
```
```mermaid
flowchart TD
A[Wprowadzanie danych przez użytkownika] --> B[Weryfikacja na froncie]
B --> C[Żądanie HTTP POST]
C --> D[Router FastAPI]
D --> E[Walidacja Pydantic]
E --> F[Wywołanie funkcji AI]
F --> G[API modeli GitHub]
G --> H[Przetwarzanie odpowiedzi]
H --> I[Odpowiedź JSON]
I --> J[Aktualizacja frontendu]
subgraph "Warstwa bezpieczeństwa"
K[Middleware CORS]
L[Zmienne środowiskowe]
M[Obsługa błędów]
end
D --> K
F --> L
H --> M
```
### Tworzenie aplikacji FastAPI
Zbudujmy nasze API krok po kroku. Utwórz plik o nazwie `api.py` z następującym kodem FastAPI:
```python
# api.py
from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
from llm import call_llm
import logging
# Konfiguracja logowania
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# Utwórz aplikację FastAPI
app = FastAPI(
title="AI Chat API",
description="A high-performance API for AI-powered chat applications",
version="1.0.0"
)
# Konfiguracja CORS
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # Skonfiguruj odpowiednio dla produkcji
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# Modele Pydantic do walidacji żądań/odpowiedzi
class ChatMessage(BaseModel):
message: str
class ChatResponse(BaseModel):
response: str
@app.get("/")
async def root():
"""Root endpoint providing API information."""
return {
"message": "Welcome to the AI Chat API",
"docs": "/docs",
"health": "/health"
}
@app.get("/health")
async def health_check():
"""Health check endpoint."""
return {"status": "healthy", "service": "ai-chat-api"}
@app.post("/hello", response_model=ChatResponse)
async def chat_endpoint(chat_message: ChatMessage):
"""Main chat endpoint that processes messages and returns AI responses."""
try:
# Wyodrębnij i zwaliduj wiadomość
message = chat_message.message.strip()
if not message:
raise HTTPException(status_code=400, detail="Message cannot be empty")
logger.info(f"Processing message: {message[:50]}...")
# Wywołaj usługę AI (uwaga: call_llm powinno być asynchroniczne dla lepszej wydajności)
ai_response = await call_llm_async(message, "You are a helpful and friendly assistant.")
logger.info("AI response generated successfully")
return ChatResponse(response=ai_response)
except HTTPException:
raise
except Exception as e:
logger.error(f"Error processing chat message: {str(e)}")
raise HTTPException(status_code=500, detail="Internal server error")
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=5000, reload=True)
```
**Zrozumienie implementacji FastAPI:**
- **Importuje** FastAPI dla nowoczesnej funkcjonalności web frameworka oraz Pydantic do walidacji danych
- **Tworzy** automatyczną dokumentację API (dostępną pod `/docs` podczas działania serwera)
- **Włącza** middleware CORS, by pozwolić zapytaniom frontendu z różnych źródeł
- **Definiuje** modele Pydantic do automatycznej walidacji i dokumentacji zapytań/odpowiedzi
- **Używa** endpointów async dla lepszej wydajności przy współbieżnych zapytaniach
- **Wprowadza** odpowiednie kody statusu HTTP i obsługę błędów z HTTPException
- **Zawiera** strukturalne logowanie do monitoringu i debugowania
- **Zapewnia** endpoint "health check" do monitorowania statusu usługi
**Kluczowe zalety FastAPI w porównaniu do tradycyjnych frameworków:**
- **Automatyczna walidacja**: modele Pydantic gwarantują integralność danych przed przetworzeniem
- **Interaktywna dokumentacja**: odwiedź `/docs` po automatycznie wygenerowaną, testowalną dokumentację API
- **Bezpieczeństwo typów**: wskazówki typów Pythona zapobiegają błędom w czasie działania i poprawiają jakość kodu
- **Wsparcie async**: obsługuje wiele zapytań AI równocześnie bez blokowania
- **Wydajność**: znacznie szybsze przetwarzanie żądań dla aplikacji czasu rzeczywistego
### Zrozumienie CORS: Strażnik bezpieczeństwa sieci
CORS (Cross-Origin Resource Sharing) to jak strażnik bezpieczeństwa w budynku, który sprawdza, czy odwiedzający mają pozwolenie na wejście. Zrozummy, dlaczego to jest ważne i jak wpływa na Twoją aplikację.
#### Czym jest CORS i dlaczego istnieje?
**Problem**: Wyobraź sobie, że każda strona mogłaby wysyłać zapytania do Twojego banku w Twoim imieniu bez Twojej zgody. To byłaby katastrofa bezpieczeństwa! Przeglądarki domyślnie tego zabraniają poprzez "politykę tego samego źródła".
**Polityka tego samego źródła**: Przeglądarki pozwalają wykonywać zapytania tylko do tej samej domeny, portu i protokołu, z których został załadowany dokument.
**Analogicznie do rzeczywistości**: To jak ochrona budynku mieszkalnego – domyślnie tylko mieszkańcy (to samo źródło) mają dostęp. Jeśli chcesz wpuścić przyjaciela (inne źródło), musisz wyraźnie powiedzieć ochronie, że jest zaproszony.
#### CORS w Twoim środowisku programistycznym
Podczas developmentu frontend i backend działają na różnych portach:
- Frontend: `http://localhost:3000` (lub file:// jeśli otwierasz HTML bez serwera)
- Backend: `http://localhost:5000`
Są to uważane za „inne źródła”, mimo że działają na tym samym komputerze!
```python
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI(__name__)
CORS(app) # To mówi przeglądarkom: „Inne źródła mogą wykonywać żądania do tego API”
```
**Co robi konfiguracja CORS w praktyce:**
- **Dodaje** specjalne nagłówki HTTP do odpowiedzi API, które mówią przeglądarce „to żądanie z innego pochodzenia jest dozwolone”
- **Obsługuje** zapytania „preflight” (przeglądarki czasem sprawdzają uprawnienia zanim wyślą właściwe zapytanie)
- **Zapobiega** błędowi „blocked by CORS policy” w konsoli Twojej przeglądarki
#### Bezpieczeństwo CORS: Development kontra produkcja
```python
# 🚨 Rozwój: Zezwala na WSZYSTKIE pochodzenia (wygodne, ale niebezpieczne)
CORS(app)
# ✅ Produkcja: Zezwalaj tylko na konkretną domenę frontendu
CORS(app, origins=["https://yourdomain.com", "https://www.yourdomain.com"])
# 🔒 Zaawansowane: Różne pochodzenia dla różnych środowisk
if app.debug: # Tryb rozwoju
CORS(app, origins=["http://localhost:3000", "http://127.0.0.1:3000"])
else: # Tryb produkcji
CORS(app, origins=["https://yourdomain.com"])
```
**Dlaczego to ważne**: W trakcie tworzenia `CORS(app)` jest jak zostawienie otwartych drzwi – wygodne, ale niebezpieczne. W produkcji chcesz precyzyjnie określić, które strony mogą się łączyć z Twoim API.
#### Typowe scenariusze i rozwiązania CORS
| Scenariusz | Problem | Rozwiązanie |
|------------|----------|-------------|
| **Lokalny rozwój** | Frontend nie może dotrzeć do backendu | Dodaj CORSMiddleware do FastAPI |
| **GitHub Pages + Heroku** | Wdrożony frontend nie może połączyć się z API | Dodaj adres GitHub Pages do pochodzeń CORS |
| **Własna domena** | Błędy CORS w produkcji | Zaktualizuj pochodzenia CORS, aby odpowiadały Twojej domenie |
| **Aplikacja mobilna** | Aplikacja nie może połączyć się z API webowym | Dodaj domenę aplikacji lub ostrożnie użyj `*` |
**Wskazówka**: Możesz sprawdzić nagłówki CORS w narzędziach developerskich przeglądarki, w zakładce Sieć. Szukaj nagłówków typu `Access-Control-Allow-Origin` w odpowiedzi.
### Obsługa błędów i walidacja
Zauważ, że nasze API zawiera odpowiednią obsługę błędów:
```python
# Sprawdź, czy otrzymaliśmy wiadomość
if not message:
return jsonify({"error": "Message field is required"}), 400
```
**Kluczowe zasady walidacji:**
- **Sprawdza** wymagane pola przed przetworzeniem żądań
- **Zwraca** znaczące komunikaty o błędach w formacie JSON
- **Używa** odpowiednich kodów statusu HTTP (400 dla złych żądań)
- **Daje** jasną informację zwrotną, która pomaga frontendowym deweloperom debugować problemy
## Konfiguracja i uruchamianie backendu
Teraz, gdy mamy integrację AI i serwer FastAPI, uruchommy wszystko. Proces konfiguracji obejmuje instalację zależności Pythona, ustawienie zmiennych środowiskowych i uruchomienie serwera w trybie deweloperskim.
### Konfiguracja środowiska Python
Ustawmy środowisko programistyczne w Pythonie. Wirtualne środowiska są jak podejście projektu Manhattan – każdy projekt ma własną, odizolowaną przestrzeń z konkretnymi narzędziami i zależnościami, zapobiegając konfliktom między projektami.
```bash
# Przejdź do katalogu backendu
cd backend
# Utwórz wirtualne środowisko (jak stworzenie czystego pokoju dla Twojego projektu)
python -m venv venv
# Aktywuj je (Linux/Mac)
source ./venv/bin/activate
# Na Windows użyj:
# venv\Scripts\activate
# Zainstaluj dobre rzeczy
pip install openai fastapi uvicorn python-dotenv
```
**Co właśnie zrobiliśmy:**
- **Utworzyliśmy** naszą własną bańkę Pythona, w której możemy instalować pakiety bez wpływu na inne projekty
- **Aktywowaliśmy** ją, dzięki czemu terminal wie, aby używać tego konkretnego środowiska
- **Zainstalowaliśmy** podstawowe pakiety: OpenAI dla magii AI, FastAPI do API webowego, Uvicorn do uruchomienia serwera oraz python-dotenv do bezpiecznego zarządzania sekretami
**Wyjaśnienie kluczowych zależności:**
- **FastAPI**: nowoczesny, szybki framework webowy z automatyczną dokumentacją API
- **Uvicorn**: błyskawiczny serwer ASGI, który uruchamia aplikacje FastAPI
- **OpenAI**: oficjalna biblioteka do GitHub Models i integracji z API OpenAI
- **python-dotenv**: bezpieczne ładowanie zmiennych środowiskowych z plików .env
### Konfiguracja środowiska: jak zachować bezpieczeństwo sekretów
Zanim uruchomimy API, porozmawiajmy o jednej z najważniejszych lekcji w tworzeniu aplikacji webowych: jak naprawdę utrzymać swoje sekrety w tajemnicy. Zmienne środowiskowe to jak sejf, do którego ma dostęp tylko Twoja aplikacja.
#### Czym są zmienne środowiskowe?
**Pomyśl o zmiennych środowiskowych jak o skrytce bankowej** – wkładasz tam cenne rzeczy, a klucz do niej masz tylko Ty (i Twoja aplikacja). Zamiast pisać poufne dane bezpośrednio w kodzie (gdzie każdy może je zobaczyć), trzymasz je bezpiecznie w środowisku.
**Oto różnica:**
- **Zły sposób**: Pisać hasło na karteczce i przykleić do monitora
- **Dobry sposób**: Przechowywać hasło w menedżerze haseł, do którego masz tylko Ty dostęp
#### Dlaczego zmienne środowiskowe są ważne
```python
# 🚨 NIGDY TEGO NIE RÓB - klucz API widoczny dla wszystkich
client = OpenAI(
api_key="ghp_1234567890abcdef...", # Każdy może go ukraść!
base_url="https://models.github.ai/inference"
)
# ✅ RÓB TO - klucz API przechowywany bezpiecznie
client = OpenAI(
api_key=os.environ["GITHUB_TOKEN"], # Tylko twoja aplikacja ma do tego dostęp
base_url="https://models.github.ai/inference"
)
```
**Co się dzieje, gdy wkleisz sekrety na sztywno:**
1. **Dostęp w kontroli wersji**: Każdy, kto ma dostęp do repozytorium Git, widzi Twój klucz API
2. **Repozytoria publiczne**: Jeśli wypchniesz kod na GitHub, Twój klucz jest widoczny dla całego internetu
3. **Współpraca zespołowa**: Inni programiści pracujący nad projektem mają dostęp do Twojego osobistego klucza API
4. **Naruszenia bezpieczeństwa**: Jeśli ktoś ukradnie Twój klucz API, może korzystać z Twoich kredytów AI
#### Ustawianie pliku środowiskowego
Utwórz plik `.env` w katalogu backendu. Ten plik przechowuje Twoje sekrety lokalnie:
```bash
# plik .env - Ten plik NIGDY nie powinien być zatwierdzany do Git
GITHUB_TOKEN=your_github_personal_access_token_here
FASTAPI_DEBUG=True
ENVIRONMENT=development
```
**Zrozumienie pliku .env:**
- **Jeden sekret na linię** w formacie `KLUCZ=wartość`
- **Brak spacji** wokół znaku równości
- **Brak konieczności cudzysłowów** wokół wartości (zwykle)
- **Komentarze** zaczynają się od `#`
#### Tworzenie osobistego tokenu dostępu do GitHub
Twój token GitHub to specjalne hasło, które daje Twojej aplikacji uprawnienia do korzystania z usług AI GitHub:
**Krok po kroku tworzenie tokenu:**
1. **Wejdź do ustawień GitHub** → Developer settings → Personal access tokens → Tokens (classic)
2. **Kliknij „Generate new token (classic)”**
3. **Ustaw datę wygaśnięcia** (30 dni do testowania, dłużej do produkcji)
4. **Wybierz zakresy**: zaznacz „repo” i inne potrzebne uprawnienia
5. **Wygeneruj token** i natychmiast go skopiuj (nie zobaczysz go ponownie!)
6. **Wklej do pliku .env**
```bash
# Przykład, jak wygląda Twój token (to jest fałszywe!)
GITHUB_TOKEN=ghp_1A2B3C4D5E6F7G8H9I0J1K2L3M4N5O6P7Q8R
```
#### Ładowanie zmiennych środowiskowych w Pythonie
```python
import os
from dotenv import load_dotenv
# Załaduj zmienne środowiskowe z pliku .env
load_dotenv()
# Teraz możesz bezpiecznie uzyskać do nich dostęp
api_key = os.environ.get("GITHUB_TOKEN")
if not api_key:
raise ValueError("GITHUB_TOKEN not found in environment variables!")
client = OpenAI(
api_key=api_key,
base_url="https://models.github.ai/inference"
)
```
**Co robi ten kod:**
- **Ładuje** Twój plik .env i udostępnia zmienne dla Pythona
- **Sprawdza**, czy wymagany token istnieje (dobra obsługa błędów!)
- **Zwraca jasny błąd**, jeśli token jest brakujący
- **Używa** tokenu bezpiecznie, bez ujawniania go w kodzie
#### Bezpieczeństwo Gita: plik .gitignore
Twój plik `.gitignore` mówi Gitowi, których plików nigdy nie śledzić ani nie wysyłać:
```bash
# .gitignore - Dodaj te linie
.env
*.env
.env.local
.env.production
__pycache__/
venv/
.vscode/
```
**Dlaczego to istotne**: Po dodaniu `.env` do `.gitignore`, Git będzie ignorować ten plik, zapobiegając przypadkowemu wysłaniu tajemnic na GitHub.
#### Różne środowiska, różne sekrety
Profesjonalne aplikacje używają różnych kluczy API dla różnych środowisk:
```bash
# .env.development
GITHUB_TOKEN=your_development_token
DEBUG=True
# .env.production
GITHUB_TOKEN=your_production_token
DEBUG=False
```
**Dlaczego to ważne**: Nie chcesz, aby Twoje eksperymenty w dewelopmencie wpływały na produkcyjny limit użycia AI, i chcesz mieć różny poziom bezpieczeństwa w różnych środowiskach.
### Uruchamianie serwera deweloperskiego: ożywienie FastAPI
Teraz nadchodzi ekscytujący moment – uruchomienie serwera deweloperskiego FastAPI i zobaczenie, jak integracja AI ożywa! FastAPI używa Uvicorna, błyskawicznego serwera ASGI, zaprojektowanego specjalnie do asynchronicznych aplikacji w Pythonie.
#### Zrozumienie procesu uruchamiania serwera FastAPI
```bash
# Metoda 1: Bezpośrednie uruchomienie Pythona (z automatycznym przeładowaniem)
python api.py
# Metoda 2: Bezpośrednie użycie Uvicorn (więcej kontroli)
uvicorn api:app --host 0.0.0.0 --port 5000 --reload
```
Kiedy uruchamiasz to polecenie, dzieje się za kulisami:
**1. Python ładuje Twoją aplikację FastAPI**:
- Importuje wszystkie wymagane biblioteki (FastAPI, Pydantic, OpenAI itd.)
- Wczytuje zmienne środowiskowe z pliku `.env`
- Tworzy instancję aplikacji FastAPI z automatyczną dokumentacją
**2. Uvicorn konfiguruje serwer ASGI**:
- Wiąże się z portem 5000 z obsługą asynchronicznych zapytań
- Ustawia routing z automatyczną walidacją
- Włącza hot reload do celów deweloperskich (restart przy zmianach plików)
- Generuje interaktywną dokumentację API
**3. Serwer zaczyna nasłuchiwać**:
- W terminalu pojawia się: `INFO: Uvicorn running on http://0.0.0.0:5000`
- Serwer może obsługiwać wiele współbieżnych zapytań AI
- Twoje API jest gotowe z automatyczną dokumentacją pod `http://localhost:5000/docs`
#### Co powinieneś zobaczyć, gdy wszystko działa
```bash
$ python api.py
INFO: Will watch for changes in these directories: ['/your/project/path']
INFO: Uvicorn running on http://0.0.0.0:5000 (Press CTRL+C to quit)
INFO: Started reloader process [12345] using WatchFiles
INFO: Started server process [12346]
INFO: Waiting for application startup.
INFO: Application startup complete.
```
**Zrozumienie wyjścia FastAPI:**
- **Will watch for changes**: Włączony auto-reload do pracy deweloperskiej
- **Uvicorn running**: Aktywny szybki serwer ASGI
- **Started reloader process**: Monitor plików do automatycznych restartów
- **Application startup complete**: Aplikacja FastAPI pomyślnie zainicjalizowana
- **Interactive docs available**: Odwiedź `/docs` aby zobaczyć automatyczną dokumentację API
#### Testowanie FastAPI: Wielorakie potężne metody
FastAPI oferuje kilka wygodnych sposobów testowania API, w tym automatyczną interaktywną dokumentację:
**Metoda 1: Interaktywna dokumentacja API (zalecana)**
1. Otwórz przeglądarkę i przejdź do `http://localhost:5000/docs`
2. Zobaczysz interfejs Swagger UI z dokumentacją wszystkich endpointów
3. Kliknij na `/hello` → „Try it out” → wpisz testową wiadomość → „Execute”
4. Zobacz odpowiedź bezpośrednio w przeglądarce w odpowiednim formacie
**Metoda 2: Podstawowy test w przeglądarce**
1. Wejdź na `http://localhost:5000` (endpoint root)
2. Wejdź na `http://localhost:5000/health` aby sprawdzić stan serwera
3. To potwierdzi, że Twój serwer FastAPI działa poprawnie
**Metoda 2: Test z linii poleceń (zaawansowany)**
```bash
# Test za pomocą curl (jeśli dostępne)
curl -X POST http://localhost:5000/hello \
-H "Content-Type: application/json" \
-d '{"message": "Hello AI!"}'
# Oczekiwana odpowiedź:
# {"response": "Cześć! Jestem twoim asystentem AI. Jak mogę ci dzisiaj pomóc?"}
```
**Metoda 3: Skrypt testowy w Pythonie**
```python
# test_api.py - Utwórz ten plik, aby przetestować swoje API
import requests
import json
# Przetestuj punkt końcowy API
url = "http://localhost:5000/hello"
data = {"message": "Tell me a joke about programming"}
response = requests.post(url, json=data)
if response.status_code == 200:
result = response.json()
print("AI Response:", result['response'])
else:
print("Error:", response.status_code, response.text)
```
#### Rozwiązywanie typowych problemów podczas startu
| Komunikat błędu | Co oznacza | Jak naprawić |
|-----------------|------------|--------------|
| `ModuleNotFoundError: No module named 'fastapi'` | FastAPI nie jest zainstalowane | Uruchom `pip install fastapi uvicorn` w swoim virtualenv |
| `ModuleNotFoundError: No module named 'uvicorn'` | Serwer ASGI nie jest zainstalowany | Uruchom `pip install uvicorn` w swoim virtualenv |
| `KeyError: 'GITHUB_TOKEN'` | Zmienna środowiskowa nie znaleziona | Sprawdź plik `.env` i wywołanie `load_dotenv()` |
| `Address already in use` | Port 5000 jest zajęty | Zakończ inne procesy korzystające z portu 5000 lub zmień port |
| `ValidationError` | Dane zapytania nie zgadzają się z modelem Pydantic | Sprawdź format zapytania, zgodny ze schematem |
| `HTTPException 422` | Niemożliwy do przetworzenia byt | Walidacja zapytania nie powiodła się, sprawdź `/docs` dla poprawnego formatu |
| `OpenAI API error` | Błąd uwierzytelniania usługi AI | Zweryfikuj, czy token GitHub jest poprawny i ma odpowiednie uprawnienia |
#### Najlepsze praktyki w dewelopmencie
**Hot Reloading**: FastAPI z Uvicornem zapewnia automatyczne przeładowanie przy zapisie zmian w plikach Python. Możesz modyfikować kod i natychmiast testować bez ręcznego restartowania.
```python
# Wyraźnie włącz hot reloading
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000, debug=True) # debug=True włącza hot reload
```
**Logowanie w trakcie dewelopmentu**: Dodaj logowanie, aby rozumieć, co się dzieje:
```python
import logging
# Skonfiguruj logowanie
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
@app.route("/hello", methods=["POST"])
def hello():
data = request.get_json()
message = data.get("message", "")
logger.info(f"Received message: {message}")
if not message:
logger.warning("Empty message received")
return jsonify({"error": "Message field is required"}), 400
try:
response = call_llm(message, "You are a helpful and friendly assistant.")
logger.info(f"AI response generated successfully")
return jsonify({"response": response})
except Exception as e:
logger.error(f"AI API error: {str(e)}")
return jsonify({"error": "AI service temporarily unavailable"}), 500
```
**Dlaczego logowanie pomaga**: Podczas developmentu widzisz, jakie zapytania przychodzą, jak AI na nie odpowiada i gdzie pojawiają się błędy. To znacznie przyspiesza debugowanie.
### Konfiguracja dla GitHub Codespaces: łatwy rozwój w chmurze
GitHub Codespaces to jak posiadanie potężnego komputera programistycznego w chmurze, do którego masz dostęp z każdej przeglądarki. Pracując w Codespaces, należy wykonać kilka dodatkowych kroków, aby backend był dostępny dla frontend.
#### Zrozumienie sieci w Codespaces
W lokalnym środowisku deweloperskim wszystko działa na tym samym komputerze:
- Backend: `http://localhost:5000`
- Frontend: `http://localhost:3000` (lub file://)
W Codespaces środowisko działa na serwerach GitHub, więc „localhost” ma inne znaczenie. GitHub automatycznie tworzy publiczne adresy URL dla Twoich usług, ale trzeba je odpowiednio skonfigurować.
#### Krok po kroku: konfiguracja Codespaces
**1. Uruchom serwer backend**:
```bash
cd backend
python api.py
```
Zobaczysz znany komunikat startu FastAPI/Uvicorn, ale działa on wewnątrz środowiska Codespace.
**2. Skonfiguruj widoczność portu**:
- Znajdź zakładkę „Ports” w dolnym panelu w VS Code
- Znajdź port 5000 na liście
- Kliknij prawym przyciskiem myszy na port 5000
- Wybierz „Port Visibility” → „Public”
**Dlaczego udostępnić publicznie?** Domyślnie porty Codespace są prywatne (dostępne tylko dla Ciebie). Udostępnienie publiczne pozwala, aby frontend (działający w przeglądarce) komunikował się z backendem.
**3. Pobierz swój publiczny URL**:
Po udostępnieniu portu otrzymasz URL w formie:
```
https://your-codespace-name-5000.app.github.dev
```
**4. Zaktualizuj konfigurację frontendu**:
```javascript
// W swoim frontendowym pliku app.js zaktualizuj BASE_URL:
this.BASE_URL = "https://your-codespace-name-5000.app.github.dev";
```
#### Zrozumienie adresów Codespace
Adresy Codespace mają przewidywalny wzorzec:
```
https://[codespace-name]-[port].app.github.dev
```
**Rozbijając na części:**
- `codespace-name`: Unikalny identyfikator Twojego Codespace (zazwyczaj zawiera nazwę użytkownika)
- `port`: Numer portu, na którym działa usługa (5000 dla naszej aplikacji FastAPI)
- `app.github.dev`: domena GitHub dla aplikacji Codespace
#### Testowanie konfiguracji Codespace
**1. Testuj backend bezpośrednio**:
Otwórz swój publiczny URL w nowej karcie przeglądarki. Powinieneś zobaczyć:
```
Welcome to the AI Chat API. Send POST requests to /hello with JSON payload containing 'message' field.
```
**2. Testuj przy pomocy narzędzi developerskich przeglądarki**:
```javascript
// Otwórz konsolę przeglądarki i przetestuj swoje API
fetch('https://your-codespace-name-5000.app.github.dev/hello', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({message: 'Hello from Codespaces!'})
})
.then(response => response.json())
.then(data => console.log(data));
```
#### Codespaces vs dewelopment lokalny
| Aspekt | Dewelopment lokalny | GitHub Codespaces |
|--------|---------------------|-------------------|
| **Czas konfiguracji** | Dłuższy (instalacja Pythona, zależności) | Natychmiastowy (środowisko wstępnie skonfigurowane) |
| **Dostęp do URL** | `http://localhost:5000` | `https://xyz-5000.app.github.dev` |
| **Konfiguracja portu** | Automatyczna | Ręczna (udostępnienie portów) |
| **Przechowywanie plików** | Maszyna lokalna | Repozytorium GitHub |
| **Współpraca** | Trudne do udostępniania środowiska | Łatwe udostępnienie linku do Codespace |
| **Zależność od internetu** | Tylko do wywołań API AI | Wymagana dla wszystkiego |
#### Wskazówki do pracy w Codespaces
**Zmienne środowiskowe w Codespaces**:
Twój plik `.env` działa identycznie w Codespaces, ale można również ustawiać zmienne bezpośrednio w Codespace:
```bash
# Ustaw zmienną środowiskową dla bieżącej sesji
export GITHUB_TOKEN="your_token_here"
# Lub dodaj do swojego .bashrc, aby była trwała
echo 'export GITHUB_TOKEN="your_token_here"' >> ~/.bashrc
```
**Zarządzanie portami**:
- Codespaces automatycznie wykrywa, gdy aplikacja zaczyna nasłuchiwać na porcie
- Możesz przekazywać wiele portów jednocześnie (przydatne np. przy dodaniu bazy danych)
- Porty pozostają dostępne tak długo, jak Codespace działa
**Workflow developmentu**:
1. Wprowadzaj zmiany w kodzie w VS Code
2. FastAPI przeładuje się automatycznie (dzięki trybowi reload Uvicorna)
3. Testuj zmiany natychmiast przez publiczny URL
4. Zatwierdź i wypchnij zmiany, gdy będziesz gotowy
> 💡 **Przydatna wskazówka**: Zapisz w zakładkach swój backendowy URL Codespace podczas developmentu. Nazwy Codespace są stabilne, więc URL nie zmieni się dopóki korzystasz z tego samego Codespace.
## Tworzenie interfejsu czatu frontendowego: gdzie człowiek spotyka AI
Teraz zbudujemy interfejs użytkownika – część, która określa, jak ludzie będą wchodzić w interakcję z Twoim asystentem AI. Tak jak design oryginalnego iPhone’a, skupiamy się na tym, by złożona technologia była intuicyjna i naturalna w użyciu.
### Zrozumienie nowoczesnej architektury frontendu
Nasz interfejs czatu będzie tym, co nazywamy „aplikacją jednostronicową” lub SPA. Zamiast tradycyjnego podejścia, gdzie każdy klik powoduje załadowanie nowej strony, nasza aplikacja aktualizuje się płynnie i natychmiastowo:
**Stare strony**: jak czytanie papierowej książki – przewracasz nową stronę
**Nasza aplikacja czatu**: jak używanie telefonu – wszystko płynie i aktualizuje się bez zakłóceń
```mermaid
graph TD
A[Użytkownik Pisze Wiadomość] --> B[JavaScript Przechwytuje Wejście]
B --> C[Waliduj i Formatuj Dane]
C --> D[Wyślij do Backend API]
D --> E[Wyświetl Stan Ładowania]
E --> F[Odbierz Odpowiedź AI]
F --> G[Aktualizuj Interfejs Czatu]
G --> H[Gotowe na Następną Wiadomość]
```
```mermaid
classDiagram
class ChatApp {
+messages: HTMLElement
+form: HTMLElement
+input: HTMLElement
+sendButton: HTMLElement
+BASE_URL: string
+API_ENDPOINT: string
+constructor()
+initializeEventListeners()
+handleSubmit(event)
+callAPI(message)
+appendMessage(text, role)
+escapeHtml(text)
+scrollToBottom()
+setLoading(isLoading)
}
ChatApp --> DOM : manipuluje
ChatApp --> FastAPI : wysyła żądania
```
### Trzy filary tworzenia frontendu
Każda aplikacja frontendowa – od prostych stron po skomplikowane aplikacje typu Discord czy Slack – opiera się na trzech podstawowych technologiach. Można je traktować jako fundament wszystkiego, co widzisz i z czym wchodzisz w interakcję w sieci:
**HTML (Struktura)**: to Twój fundament
- Określa, jakie elementy istnieją (przyciski, pola tekstowe, kontenery)
- Nadaje znaczenie treści (np. to jest nagłówek, to jest formularz)
- Tworzy podstawową strukturę, na której buduje się wszystko inne
**CSS (Prezentacja)**: to twój projektant wnętrz
- Sprawia, że wszystko wygląda pięknie (kolory, czcionki, układy)
- Obsługuje różne rozmiary ekranów (telefon, laptop, tablet)
- Tworzy płynne animacje i wizualne informacje zwrotne
**JavaScript (Zachowanie)**: to twój mózg
- Reaguje na działania użytkownika (kliknięcia, pisanie, przewijanie)
- Komunikuje się z backendem i aktualizuje stronę
- Sprawia, że wszystko jest interaktywne i dynamiczne
**Pomysł architektoniczny:**
- **HTML**: plan konstrukcyjny (definiujący przestrzenie i relacje)
- **CSS**: estetyka i projekt środowiska (wygląd i doświadczenie użytkownika)
- **JavaScript**: systemy mechaniczne (funkcjonalność i interaktywność)
### Dlaczego nowoczesna architektura JavaScript jest ważna
Nasza aplikacja czatu będzie używać nowoczesnych wzorców JavaScript, które zobaczysz w profesjonalnych aplikacjach. Zrozumienie tych pojęć pomoże ci rozwijać się jako programista:
**Architektura oparta na klasach**: zorganizujemy kod w klasy, które są jak szablony obiektów
**Async/Await**: nowoczesny sposób obsługi operacji zajmujących czas (np. wywołania API)
**Programowanie zdarzeniowe**: aplikacja reaguje na akcje użytkownika (kliknięcia, wciśnięcia klawiszy), a nie działa w pętli
**Manipulacja DOM**: dynamiczna aktualizacja zawartości strony na podstawie interakcji i odpowiedzi API
### Struktura projektu
Utwórz katalog frontend z taką uporządkowaną strukturą:
```text
frontend/
├── index.html # Main HTML structure
├── app.js # JavaScript functionality
└── styles.css # Visual styling
```
**Zrozumienie architektury:**
- **Oddziela** strukturę (HTML), zachowanie (JavaScript) i prezentację (CSS)
- **Utrzymuje** prostą strukturę plików, łatwą do nawigacji i modyfikacji
- **Podąża** za najlepszymi praktykami webdevu w zakresie organizacji i utrzymywalności
### Budowa fundamentu HTML: struktura semantyczna dla dostępności
Zacznijmy od struktury HTML. Nowoczesny rozwój stron podkreśla „semantyczny HTML” – używanie elementów, które jasno opisują swój cel, a nie tylko wygląd. Dzięki temu aplikacja jest dostępna dla czytników ekranu, wyszukiwarek i innych narzędzi.
**Dlaczego semantyczny HTML jest ważny**: wyobraź sobie, że opisujesz swoją aplikację czatu komuś przez telefon. Powiedziałbyś „jest nagłówek z tytułem, główna część z rozmowami, oraz formularz u dołu do pisania wiadomości”. Semantyczny HTML używa elementów odpowiadających temu naturalnemu opisowi.
Utwórz plik `index.html` z taką przemyślaną strukturą:
```html
Ask me anything!