# Costruire un Assistente Chat con l'AI
Ricordi in Star Trek quando l'equipaggio parlava casualmente con il computer della nave, ponendo domande complesse e ricevendo risposte ponderate? Quello che sembrava pura fantascienza negli anni '60 è ora qualcosa che puoi costruire utilizzando tecnologie web che già conosci.
In questa lezione, creeremo un assistente chat AI utilizzando HTML, CSS, JavaScript e un po' di integrazione backend. Scoprirai come le stesse competenze che stai imparando possono connettersi a potenti servizi AI che comprendono il contesto e generano risposte significative.
Pensa all'AI come avere accesso a una vasta biblioteca che non solo trova informazioni, ma le sintetizza in risposte coerenti e personalizzate alle tue domande specifiche. Invece di cercare tra migliaia di pagine, ottieni risposte dirette e contestuali.
L'integrazione avviene attraverso tecnologie web familiari che lavorano insieme. HTML crea l'interfaccia della chat, CSS gestisce il design visivo, JavaScript gestisce le interazioni dell'utente e un'API backend collega tutto ai servizi AI. È simile a come le diverse sezioni di un'orchestra lavorano insieme per creare una sinfonia.
Stiamo essenzialmente costruendo un ponte tra la comunicazione umana naturale e l'elaborazione delle macchine. Imparerai sia l'implementazione tecnica dell'integrazione dei servizi AI sia i modelli di design che rendono le interazioni intuitive.
Alla fine di questa lezione, l'integrazione con l'AI sembrerà meno un processo misterioso e più un'altra API con cui puoi lavorare. Capirai i modelli fondamentali che alimentano applicazioni come ChatGPT e Claude, utilizzando gli stessi principi di sviluppo web che stai imparando.
Ecco come apparirà il tuo progetto finito:

## Comprendere l'AI: Dal Mistero alla Padronanza
Prima di immergerci nel codice, cerchiamo di capire con cosa stiamo lavorando. Se hai già utilizzato le API, conosci il modello di base: invia una richiesta, ricevi una risposta.
Le API AI seguono una struttura simile, ma invece di recuperare dati pre-memorizzati da un database, generano nuove risposte basate su modelli appresi da enormi quantità di testo. Pensalo come la differenza tra un sistema di catalogazione di una biblioteca e un bibliotecario esperto che può sintetizzare informazioni da più fonti.
### Cos'è davvero l'"AI Generativa"?
Considera come la Stele di Rosetta ha permesso agli studiosi di comprendere i geroglifici egizi trovando modelli tra lingue conosciute e sconosciute. I modelli AI funzionano in modo simile: trovano modelli in enormi quantità di testo per capire come funziona il linguaggio e poi usano quei modelli per generare risposte appropriate a nuove domande.
**Lascia che te lo spieghi con un semplice confronto:**
- **Database tradizionale**: Come chiedere il tuo certificato di nascita – ottieni sempre lo stesso documento
- **Motore di ricerca**: Come chiedere a un bibliotecario di trovare libri sui gatti – ti mostrano ciò che è disponibile
- **AI Generativa**: Come chiedere a un amico esperto di gatti – ti raccontano cose interessanti con parole proprie, adattate a ciò che vuoi sapere
```mermaid
graph LR
A[Your Question] --> B[AI Model]
B --> C[Pattern Recognition]
C --> D[Content Generation]
D --> E[Contextual Response]
F[Training Data
Books, Articles, Web] --> B
```
### Come i Modelli AI Imparano (Versione Semplice)
I modelli AI imparano attraverso l'esposizione a enormi dataset contenenti testi da libri, articoli e conversazioni. Attraverso questo processo, identificano modelli in:
- Come sono strutturati i pensieri nella comunicazione scritta
- Quali parole appaiono comunemente insieme
- Come fluiscono tipicamente le conversazioni
- Differenze contestuali tra comunicazione formale e informale
**È simile a come gli archeologi decifrano le lingue antiche**: analizzano migliaia di esempi per comprendere grammatica, vocabolario e contesto culturale, diventando infine capaci di interpretare nuovi testi utilizzando quei modelli appresi.
### Perché Modelli GitHub?
Stiamo utilizzando i Modelli GitHub per un motivo piuttosto pratico: ci dà accesso a un'AI di livello aziendale senza dover configurare la nostra infrastruttura AI (che, fidati, non vorresti fare in questo momento!). Pensalo come utilizzare un'API meteo invece di cercare di prevedere il meteo da solo installando stazioni meteorologiche ovunque.
È fondamentalmente "AI come Servizio", e la parte migliore? È gratuito per iniziare, quindi puoi sperimentare senza preoccuparti di accumulare un conto salato.
```mermaid
graph LR
A[Frontend Chat UI] --> B[Your Backend API]
B --> C[GitHub Models API]
C --> D[AI Model Processing]
D --> C
C --> B
B --> A
```
Utilizzeremo i Modelli GitHub per la nostra integrazione backend, che fornisce accesso a capacità AI di livello professionale attraverso un'interfaccia amichevole per gli sviluppatori. Il [GitHub Models Playground](https://github.com/marketplace/models/azure-openai/gpt-4o-mini/playground) funge da ambiente di test dove puoi sperimentare con diversi modelli AI e comprendere le loro capacità prima di implementarli nel codice.

**Ecco cosa rende il playground così utile:**
- **Prova** diversi modelli AI come GPT-4o-mini, Claude e altri (tutti gratuiti!)
- **Testa** le tue idee e i tuoi prompt prima di scrivere qualsiasi codice
- **Ottieni** frammenti di codice pronti all'uso nel tuo linguaggio di programmazione preferito
- **Modifica** impostazioni come livello di creatività e lunghezza della risposta per vedere come influenzano il risultato
Una volta che hai sperimentato un po', basta cliccare sulla scheda "Code" e scegliere il tuo linguaggio di programmazione per ottenere il codice di implementazione di cui hai bisogno.

## Configurare l'Integrazione Backend con Python
Ora implementiamo l'integrazione AI utilizzando Python. Python è eccellente per le applicazioni AI grazie alla sua sintassi semplice e alle sue potenti librerie. Partiremo dal codice del playground dei Modelli GitHub e lo riorganizzeremo in una funzione riutilizzabile e pronta per la produzione.
### Comprendere l'Implementazione Base
Quando prendi il codice Python dal playground, otterrai qualcosa che assomiglia a questo. Non preoccuparti se sembra tanto all'inizio: analizziamolo pezzo per pezzo.
```python
"""Run this model in Python
> pip install openai
"""
import os
from openai import OpenAI
# To authenticate with the model you will need to generate a personal access token (PAT) in your GitHub settings.
# Create your PAT token by following instructions here: 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"],
)
```python
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)
```
**Ecco cosa sta succedendo in questo codice:**
- **Importiamo** gli strumenti necessari: `os` per leggere le variabili d'ambiente e `OpenAI` per comunicare con l'AI
- **Configuriamo** il client OpenAI per puntare ai server AI di GitHub invece che direttamente a OpenAI
- **Autentichiamo** utilizzando un token speciale di GitHub (ne parleremo tra poco!)
- **Strutturiamo** la nostra conversazione con diversi "ruoli" – pensalo come impostare la scena per uno spettacolo
- **Inviamo** la nostra richiesta all'AI con alcuni parametri di fine-tuning
- **Estraiamo** il testo della risposta effettiva da tutti i dati che tornano
### Comprendere i Ruoli dei Messaggi: Il Framework di Conversazione AI
Le conversazioni AI utilizzano una struttura specifica con diversi "ruoli" che servono a scopi distinti:
```python
messages=[
{
"role": "system",
"content": "You are a helpful assistant who explains things simply."
},
{
"role": "user",
"content": "What is machine learning?"
}
]
```
**Pensalo come dirigere uno spettacolo:**
- **Ruolo del sistema**: Come le indicazioni di scena per un attore – dice all'AI come comportarsi, quale personalità avere e come rispondere
- **Ruolo dell'utente**: La domanda o il messaggio effettivo della persona che utilizza la tua applicazione
- **Ruolo dell'assistente**: La risposta dell'AI (non lo invii, ma appare nella cronologia della conversazione)
**Analogia nel mondo reale**: Immagina di presentare un amico a qualcuno a una festa:
- **Messaggio del sistema**: "Questa è la mia amica Sarah, è una dottoressa che spiega concetti medici in modo semplice"
- **Messaggio dell'utente**: "Puoi spiegare come funzionano i vaccini?"
- **Risposta dell'assistente**: Sarah risponde come una dottoressa amichevole, non come un avvocato o uno chef
### Comprendere i Parametri AI: Fine-Tuning del Comportamento delle Risposte
I parametri numerici nelle chiamate API AI controllano come il modello genera risposte. Queste impostazioni ti permettono di regolare il comportamento dell'AI per diversi casi d'uso:
#### Temperatura (0.0 a 2.0): La Manopola della Creatività
**Cosa fa**: Controlla quanto creative o prevedibili saranno le risposte dell'AI.
**Pensalo come il livello di improvvisazione di un musicista jazz:**
- **Temperatura = 0.1**: Suona esattamente la stessa melodia ogni volta (altamente prevedibile)
- **Temperatura = 0.7**: Aggiunge alcune variazioni di buon gusto rimanendo riconoscibile (creatività bilanciata)
- **Temperatura = 1.5**: Jazz sperimentale completo con svolte inaspettate (altamente imprevedibile)
```python
# Very predictable responses (good for factual questions)
response = client.chat.completions.create(
messages=[{"role": "user", "content": "What is 2+2?"}],
temperature=0.1 # Will almost always say "4"
)
# Creative responses (good for brainstorming)
response = client.chat.completions.create(
messages=[{"role": "user", "content": "Write a creative story opening"}],
temperature=1.2 # Will generate unique, unexpected stories
)
```
#### Max Tokens (1 a 4096+): Il Controllore della Lunghezza della Risposta
**Cosa fa**: Imposta un limite sulla lunghezza della risposta dell'AI.
**Pensalo come se i token fossero approssimativamente equivalenti alle parole** (circa 1 token = 0.75 parole in inglese):
- **max_tokens=50**: Breve e conciso (come un messaggio di testo)
- **max_tokens=500**: Un bel paragrafo o due
- **max_tokens=2000**: Una spiegazione dettagliata con esempi
```python
# Short, concise answers
response = client.chat.completions.create(
messages=[{"role": "user", "content": "Explain JavaScript"}],
max_tokens=100 # Forces a brief explanation
)
# Detailed, comprehensive answers
response = client.chat.completions.create(
messages=[{"role": "user", "content": "Explain JavaScript"}],
max_tokens=1500 # Allows for detailed explanations with examples
)
```
#### Top_p (0.0 a 1.0): Il Parametro di Focalizzazione
**Cosa fa**: Controlla quanto l'AI si concentra sulle risposte più probabili.
**Immagina l'AI con un enorme vocabolario, classificato per probabilità di ogni parola:**
- **top_p=0.1**: Considera solo il 10% delle parole più probabili (molto focalizzato)
- **top_p=0.9**: Considera il 90% delle parole possibili (più creativo)
- **top_p=1.0**: Considera tutto (massima varietà)
**Ad esempio**: Se chiedi "Il cielo è solitamente..."
- **Top_p basso**: Dirà quasi sicuramente "blu"
- **Top_p alto**: Potrebbe dire "blu", "nuvoloso", "vasto", "mutevole", "bello", ecc.
### Mettere Tutto Insieme: Combinazioni di Parametri per Diversi Casi d'Uso
```python
# For factual, consistent answers (like a documentation bot)
factual_params = {
"temperature": 0.2,
"max_tokens": 300,
"top_p": 0.3
}
# For creative writing assistance
creative_params = {
"temperature": 1.1,
"max_tokens": 1000,
"top_p": 0.9
}
# For conversational, helpful responses (balanced)
conversational_params = {
"temperature": 0.7,
"max_tokens": 500,
"top_p": 0.8
}
```
**Comprendere perché questi parametri sono importanti**: Diverse applicazioni necessitano di diversi tipi di risposte. Un bot di assistenza clienti dovrebbe essere coerente e fattuale (bassa temperatura), mentre un assistente alla scrittura creativa dovrebbe essere immaginativo e vario (alta temperatura). Comprendere questi parametri ti dà il controllo sulla personalità e sullo stile di risposta dell'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))
```
**Comprendere questa funzione migliorata:**
- **Accetta** due parametri: il prompt dell'utente e un messaggio di sistema opzionale
- **Fornisce** un messaggio di sistema predefinito per un comportamento generale dell'assistente
- **Utilizza** suggerimenti di tipo Python appropriati per una migliore documentazione del codice
- **Include** una docstring dettagliata che spiega lo scopo e i parametri della funzione
- **Restituisce** solo il contenuto della risposta, rendendolo facile da usare nella nostra API web
- **Mantiene** gli stessi parametri del modello per un comportamento AI coerente
### La Magia dei Prompt di Sistema: Programmare la Personalità dell'AI
Se i parametri controllano come pensa l'AI, i prompt di sistema controllano chi l'AI pensa di essere. Questa è onestamente una delle parti più interessanti del lavoro con l'AI: stai essenzialmente dando all'AI una personalità completa, un livello di competenza e uno stile di comunicazione.
**Pensalo come scegliere diversi attori per diversi ruoli**: Invece di avere un assistente generico, puoi creare esperti specializzati per diverse situazioni. Hai bisogno di un insegnante paziente? Un partner creativo per brainstorming? Un consulente aziendale diretto? Basta cambiare il prompt di sistema!
#### Perché i Prompt di Sistema Sono Così Potenti
Ecco la parte affascinante: i modelli AI sono stati addestrati su innumerevoli conversazioni in cui le persone adottano diversi ruoli e livelli di competenza. Quando dai all'AI un ruolo specifico, è come premere un interruttore che attiva tutti quei modelli appresi.
**È come il metodo di recitazione per l'AI**: Dì a un attore "sei un professore anziano e saggio" e guarda come regolano automaticamente postura, vocabolario e modi. L'AI fa qualcosa di sorprendentemente simile con i modelli linguistici.
#### Creare Prompt di Sistema Efficaci: L'Arte e la Scienza
**L'anatomia di un ottimo prompt di sistema:**
1. **Ruolo/Identità**: Chi è l'AI?
2. **Competenza**: Cosa sa?
3. **Stile di comunicazione**: Come parla?
4. **Istruzioni specifiche**: Su cosa dovrebbe concentrarsi?
```python
# ❌ Vague system prompt
"You are helpful."
# ✅ Detailed, effective system prompt
"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."
```
#### Esempi di Prompt di Sistema con Contesto
Vediamo come diversi prompt di sistema creano personalità AI completamente diverse:
```python
# Example 1: The Patient Teacher
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.
"""
# Example 2: The Creative Collaborator
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.
"""
# Example 3: The Strategic Business Advisor
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.
"""
```
#### Vedere i Prompt di Sistema in Azione
Testiamo la stessa domanda con diversi prompt di sistema per vedere le differenze drammatiche:
**Domanda**: "Come gestisco l'autenticazione degli utenti nella mia app web?"
```python
# With teacher prompt:
teacher_response = call_llm(
"How do I handle user authentication in my web app?",
teacher_prompt
)
# Typical response: "Great question! Let's break authentication down into simple steps.
# Think of it like a nightclub bouncer checking IDs..."
# With business prompt:
business_response = call_llm(
"How do I handle user authentication in my web app?",
business_prompt
)
# Typical response: "From a strategic perspective, authentication is crucial for user
# trust and regulatory compliance. Let me outline a framework considering security,
# user experience, and scalability..."
```
#### Tecniche Avanzate per i Prompt di Sistema
**1. Impostazione del Contesto**: Fornisci all'AI informazioni di background
```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. Formattazione dell'Output**: Dì all'AI come strutturare le risposte
```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. Impostazione dei Vincoli**: Definisci cosa l'AI NON dovrebbe fare
```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.
"""
```
#### Perché Questo È Importante per il Tuo Assistente Chat
Comprendere i prompt di sistema ti dà un potere incredibile per creare assistenti AI specializzati:
- **Bot di assistenza clienti**: Utile, paziente, consapevole delle politiche
- **Tutor di apprendimento**: Incoraggiante, passo dopo passo, verifica la comprensione
- **Partner creativo**: Immaginativo, costruisce sulle idee, chiede "e se?"
- **Esperto tecnico**: Preciso, dettagliato, attento alla sicurezza
**L'intuizione chiave**: Non stai solo chiamando un'API AI – stai creando una personalità AI personalizzata che serve il tuo caso d'uso specifico. Questo è ciò che rende le applicazioni AI moderne utili e personalizzate piuttosto che generiche.
## Costruire l'API Web con FastAPI: Il Tuo Hub di Comunicazione AI ad Alte Prestazioni
Ora costruiamo il backend che collega il tuo frontend ai servizi AI. Utilizzeremo FastAPI, un framework Python moderno che eccelle nella costruzione di API per applicazioni AI.
FastAPI offre diversi vantaggi per questo tipo di progetto: supporto asincrono integrato per gestire richieste concorrenti, generazione automatica della documentazione API e prestazioni eccellenti. Il tuo server FastAPI funge da intermediario che riceve richieste dal frontend, comunica con i servizi AI e restituisce risposte formattate.
### Perché FastAPI per le Applicazioni AI?
Potresti chiederti: "Non posso semplicemente chiamare l'AI direttamente dal mio JavaScript frontend?" o "Perché FastAPI invece di Flask o Django?" Ottime domande!
**Ecco perché FastAPI è perfetto per ciò che stiamo costruendo:**
- **Async di default**: Può gestire più richieste AI contemporaneamente senza bloccarsi
- **Documentazione automatica**: Visita `/docs` e ottieni una pagina di documentazione API interattiva e ben strutturata gratuitamente
- **Validazione integrata**: Intercetta gli errori prima che causino problemi
- **Velocità fulminea**: Uno dei framework Python più veloci in circolazione
- **Python moderno**: Utilizza tutte le funzionalità più recenti e avanzate di Python
**Ed ecco perché abbiamo bisogno di un backend:**
**Sicurezza**: La tua chiave API per l'AI è come una password – se la metti nel JavaScript del frontend, chiunque visualizzi il codice sorgente del tuo sito web potrebbe rubarla e utilizzare i tuoi crediti AI. Il backend mantiene le credenziali sensibili al sicuro.
**Limitazione delle richieste e controllo**: Il backend ti permette di controllare la frequenza con cui gli utenti possono fare richieste, implementare l'autenticazione degli utenti e aggiungere il logging per monitorare l'utilizzo.
**Elaborazione dei dati**: Potresti voler salvare le conversazioni, filtrare contenuti inappropriati o combinare più servizi AI. La logica per queste operazioni risiede nel backend.
**L'architettura somiglia a un modello client-server:**
- **Frontend**: Livello di interfaccia utente per l'interazione
- **Backend API**: Livello di elaborazione e instradamento delle richieste
- **Servizio AI**: Computazione esterna e generazione delle risposte
- **Variabili d'ambiente**: Configurazione sicura e archiviazione delle credenziali
### Comprendere il flusso richiesta-risposta
Vediamo cosa succede quando un utente invia un messaggio:
```mermaid
sequenceDiagram
participant User as 👤 User
participant Frontend as 🌐 Frontend
participant API as 🔧 FastAPI Server
participant AI as 🤖 AI Service
User->>Frontend: Types "Hello AI!"
Frontend->>API: POST /hello {"message": "Hello AI!"}
Note over API: Validates request
Adds system prompt
API->>AI: Sends formatted request
AI->>API: Returns AI response
Note over API: Processes response
Logs conversation
API->>Frontend: {"response": "Hello! How can I help?"}
Frontend->>User: Displays AI message
```
**Comprendere ogni passaggio:**
1. **Interazione dell'utente**: La persona digita nell'interfaccia della chat
2. **Elaborazione del frontend**: JavaScript cattura l'input e lo formatta come JSON
3. **Validazione API**: FastAPI valida automaticamente la richiesta utilizzando i modelli Pydantic
4. **Integrazione AI**: Il backend aggiunge il contesto (prompt di sistema) e chiama il servizio AI
5. **Gestione della risposta**: L'API riceve la risposta dell'AI e può modificarla se necessario
6. **Visualizzazione nel frontend**: JavaScript mostra la risposta nell'interfaccia della chat
### Comprendere l'architettura API
```mermaid
sequenceDiagram
participant Frontend
participant FastAPI
participant AI Function
participant GitHub Models
Frontend->>FastAPI: POST /hello {"message": "Hello AI!"}
FastAPI->>AI Function: call_llm(message, system_prompt)
AI Function->>GitHub Models: API request
GitHub Models->>AI Function: AI response
AI Function->>FastAPI: response text
FastAPI->>Frontend: {"response": "Hello! How can I help?"}
```
### Creare l'applicazione FastAPI
Costruiamo la nostra API passo dopo passo. Crea un file chiamato `api.py` con il seguente codice 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
# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# Create FastAPI application
app = FastAPI(
title="AI Chat API",
description="A high-performance API for AI-powered chat applications",
version="1.0.0"
)
# Configure CORS
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # Configure appropriately for production
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# Pydantic models for request/response validation
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:
# Extract and validate message
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]}...")
# Call AI service (note: call_llm should be made async for better performance)
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)
```
**Comprendere l'implementazione di FastAPI:**
- **Importa** FastAPI per le funzionalità di framework web moderno e Pydantic per la validazione dei dati
- **Crea** documentazione API automatica (disponibile su `/docs` quando il server è in esecuzione)
- **Abilita** il middleware CORS per consentire richieste frontend da origini diverse
- **Definisce** modelli Pydantic per la validazione automatica delle richieste/risposte e la documentazione
- **Utilizza** endpoint asincroni per migliori prestazioni con richieste concorrenti
- **Implementa** codici di stato HTTP appropriati e gestione degli errori con HTTPException
- **Include** logging strutturato per monitoraggio e debug
- **Fornisce** un endpoint di controllo dello stato per monitorare lo stato del servizio
**Vantaggi principali di FastAPI rispetto ai framework tradizionali:**
- **Validazione automatica**: I modelli Pydantic garantiscono l'integrità dei dati prima dell'elaborazione
- **Documentazione interattiva**: Visita `/docs` per una documentazione API generata automaticamente e testabile
- **Sicurezza dei tipi**: Gli hint di tipo in Python prevengono errori di runtime e migliorano la qualità del codice
- **Supporto async**: Gestisce più richieste AI simultaneamente senza blocchi
- **Prestazioni**: Elaborazione delle richieste significativamente più veloce per applicazioni in tempo reale
### Comprendere CORS: La guardia di sicurezza del web
CORS (Cross-Origin Resource Sharing) è come una guardia di sicurezza in un edificio che controlla se i visitatori sono autorizzati a entrare. Vediamo perché è importante e come influisce sulla tua applicazione.
#### Cos'è CORS e perché esiste?
**Il problema**: Immagina se qualsiasi sito web potesse inviare richieste al sito della tua banca per tuo conto senza il tuo permesso. Sarebbe un incubo per la sicurezza! I browser lo impediscono di default attraverso la "Same-Origin Policy".
**Same-Origin Policy**: I browser consentono alle pagine web di inviare richieste solo al dominio, alla porta e al protocollo da cui sono state caricate.
**Analogia con la vita reale**: È come la sicurezza di un condominio – solo i residenti (stessa origine) possono accedere all'edificio di default. Se vuoi far visitare un amico (origine diversa), devi dirlo esplicitamente alla sicurezza.
#### CORS nel tuo ambiente di sviluppo
Durante lo sviluppo, il tuo frontend e backend funzionano su porte diverse:
- Frontend: `http://localhost:3000` (o file:// se apri direttamente l'HTML)
- Backend: `http://localhost:5000`
Questi sono considerati "origini diverse" anche se sono sullo stesso computer!
```python
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI(__name__)
CORS(app) # This tells browsers: "It's okay for other origins to make requests to this API"
```
**Cosa fa la configurazione CORS in pratica:**
- **Aggiunge** intestazioni HTTP speciali alle risposte API che dicono ai browser "questa richiesta cross-origin è consentita"
- **Gestisce** richieste "preflight" (i browser a volte controllano i permessi prima di inviare la richiesta effettiva)
- **Previene** il temuto errore "bloccato dalla politica CORS" nella console del browser
#### Sicurezza CORS: Sviluppo vs Produzione
```python
# 🚨 Development: Allows ALL origins (convenient but insecure)
CORS(app)
# ✅ Production: Only allow your specific frontend domain
CORS(app, origins=["https://yourdomain.com", "https://www.yourdomain.com"])
# 🔒 Advanced: Different origins for different environments
if app.debug: # Development mode
CORS(app, origins=["http://localhost:3000", "http://127.0.0.1:3000"])
else: # Production mode
CORS(app, origins=["https://yourdomain.com"])
```
**Perché è importante**: Durante lo sviluppo, `CORS(app)` è come lasciare la porta di casa aperta – comodo ma non sicuro. In produzione, vuoi specificare esattamente quali siti web possono comunicare con la tua API.
#### Scenari comuni CORS e soluzioni
| Scenario | Problema | Soluzione |
|----------|---------|----------|
| **Sviluppo locale** | Il frontend non riesce a raggiungere il backend | Aggiungi CORSMiddleware a FastAPI |
| **GitHub Pages + Heroku** | Il frontend distribuito non riesce a raggiungere l'API | Aggiungi l'URL di GitHub Pages alle origini CORS |
| **Dominio personalizzato** | Errori CORS in produzione | Aggiorna le origini CORS per corrispondere al tuo dominio |
| **App mobile** | L'app non riesce a raggiungere l'API web | Aggiungi il dominio della tua app o usa `*` con cautela |
**Consiglio utile**: Puoi controllare le intestazioni CORS negli strumenti per sviluppatori del browser sotto la scheda Network. Cerca intestazioni come `Access-Control-Allow-Origin` nella risposta.
### Gestione degli errori e validazione
Nota come la nostra API include una gestione degli errori adeguata:
```python
# Validate that we received a message
if not message:
return jsonify({"error": "Message field is required"}), 400
```
**Principi chiave di validazione:**
- **Controlla** i campi richiesti prima di elaborare le richieste
- **Restituisce** messaggi di errore significativi in formato JSON
- **Utilizza** codici di stato HTTP appropriati (400 per richieste errate)
- **Fornisce** feedback chiari per aiutare gli sviluppatori frontend a risolvere i problemi
## Configurazione e avvio del backend
Ora che abbiamo la nostra integrazione AI e il server FastAPI pronto, mettiamo tutto in funzione. Il processo di configurazione prevede l'installazione delle dipendenze Python, la configurazione delle variabili d'ambiente e l'avvio del server di sviluppo.
### Configurazione dell'ambiente Python
Configuriamo il tuo ambiente di sviluppo Python. Gli ambienti virtuali sono come l'approccio compartimentato del Progetto Manhattan – ogni progetto ha il proprio spazio isolato con strumenti e dipendenze specifici, evitando conflitti tra progetti diversi.
```bash
# Navigate to your backend directory
cd backend
# Create a virtual environment (like creating a clean room for your project)
python -m venv venv
# Activate it (Linux/Mac)
source ./venv/bin/activate
# On Windows, use:
# venv\Scripts\activate
# Install the good stuff
pip install openai fastapi uvicorn python-dotenv
```
**Cosa abbiamo appena fatto:**
- **Creato** una bolla Python personale dove possiamo installare pacchetti senza influenzare nient'altro
- **Attivato** l'ambiente in modo che il terminale sappia di utilizzare questo ambiente specifico
- **Installato** gli elementi essenziali: OpenAI per la magia AI, FastAPI per la nostra API web, Uvicorn per eseguirla e python-dotenv per la gestione sicura dei segreti
**Dipendenze chiave spiegate:**
- **FastAPI**: Framework web moderno e veloce con documentazione API automatica
- **Uvicorn**: Server ASGI ultra veloce che esegue applicazioni FastAPI
- **OpenAI**: Libreria ufficiale per l'integrazione con i modelli GitHub e l'API OpenAI
- **python-dotenv**: Caricamento sicuro delle variabili d'ambiente dai file .env
### Configurazione dell'ambiente: mantenere i segreti al sicuro
Prima di avviare la nostra API, dobbiamo parlare di una delle lezioni più importanti nello sviluppo web: come mantenere i tuoi segreti davvero segreti. Le variabili d'ambiente sono come una cassaforte sicura che solo la tua applicazione può accedere.
#### Cosa sono le variabili d'ambiente?
**Pensa alle variabili d'ambiente come a una cassetta di sicurezza** – metti le tue cose preziose lì dentro e solo tu (e la tua app) hai la chiave per accedervi. Invece di scrivere informazioni sensibili direttamente nel codice (dove chiunque può vederle), le conservi in modo sicuro nell'ambiente.
**Ecco la differenza:**
- **Il modo sbagliato**: Scrivere la tua password su un post-it e metterlo sul monitor
- **Il modo giusto**: Conservare la tua password in un gestore di password sicuro che solo tu puoi accedere
#### Perché le variabili d'ambiente sono importanti
```python
# 🚨 NEVER DO THIS - API key visible to everyone
client = OpenAI(
api_key="ghp_1234567890abcdef...", # Anyone can steal this!
base_url="https://models.github.ai/inference"
)
# ✅ DO THIS - API key stored securely
client = OpenAI(
api_key=os.environ["GITHUB_TOKEN"], # Only your app can access this
base_url="https://models.github.ai/inference"
)
```
**Cosa succede quando codifichi i segreti nel codice:**
1. **Esposizione nel controllo di versione**: Chiunque abbia accesso al tuo repository Git vede la tua chiave API
2. **Repository pubblici**: Se pubblichi su GitHub, la tua chiave è visibile a tutto il mondo
3. **Condivisione con il team**: Altri sviluppatori che lavorano sul tuo progetto ottengono accesso alla tua chiave API personale
4. **Violazioni di sicurezza**: Se qualcuno ruba la tua chiave API, può utilizzare i tuoi crediti AI
#### Creazione del file di ambiente
Crea un file `.env` nella directory del tuo backend. Questo file conserva i tuoi segreti localmente:
```bash
# .env file - This should NEVER be committed to Git
GITHUB_TOKEN=your_github_personal_access_token_here
FASTAPI_DEBUG=True
ENVIRONMENT=development
```
**Comprendere il file .env:**
- **Un segreto per riga** nel formato `KEY=value`
- **Nessuno spazio** intorno al segno di uguale
- **Nessuna necessità di virgolette** intorno ai valori (di solito)
- **Commenti** iniziano con `#`
#### Creazione del token di accesso personale GitHub
Il tuo token GitHub è come una password speciale che dà alla tua applicazione il permesso di utilizzare i servizi AI di GitHub:
**Passaggi per creare il token:**
1. **Vai su Impostazioni GitHub** → Impostazioni sviluppatore → Token di accesso personale → Token (classico)
2. **Clicca su "Genera nuovo token (classico)"**
3. **Imposta la scadenza** (30 giorni per test, più lunga per produzione)
4. **Seleziona gli ambiti**: Spunta "repo" e qualsiasi altra autorizzazione necessaria
5. **Genera il token** e copialo immediatamente (non puoi vederlo di nuovo!)
6. **Incollalo nel tuo file .env**
```bash
# Example of what your token looks like (this is fake!)
GITHUB_TOKEN=ghp_1A2B3C4D5E6F7G8H9I0J1K2L3M4N5O6P7Q8R
```
#### Caricamento delle variabili d'ambiente in Python
```python
import os
from dotenv import load_dotenv
# Load environment variables from .env file
load_dotenv()
# Now you can access them securely
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"
)
```
**Cosa fa questo codice:**
- **Carica** il file .env e rende le variabili disponibili in Python
- **Controlla** se il token richiesto esiste (buona gestione degli errori!)
- **Genera** un errore chiaro se il token manca
- **Utilizza** il token in modo sicuro senza esporlo nel codice
#### Sicurezza Git: Il file .gitignore
Il tuo file `.gitignore` dice a Git quali file non tracciare o caricare mai:
```bash
# .gitignore - Add these lines
.env
*.env
.env.local
.env.production
__pycache__/
venv/
.vscode/
```
**Perché è cruciale**: Una volta aggiunto `.env` a `.gitignore`, Git ignorerà il tuo file di ambiente, impedendoti di caricare accidentalmente i tuoi segreti su GitHub.
#### Ambienti diversi, segreti diversi
Le applicazioni professionali utilizzano chiavi API diverse per ambienti diversi:
```bash
# .env.development
GITHUB_TOKEN=your_development_token
DEBUG=True
# .env.production
GITHUB_TOKEN=your_production_token
DEBUG=False
```
**Perché è importante**: Non vuoi che i tuoi esperimenti di sviluppo influenzino la tua quota di utilizzo AI in produzione, e vuoi livelli di sicurezza diversi per ambienti diversi.
### Avvio del server di sviluppo: dare vita al tuo FastAPI
Ora arriva il momento emozionante – avviare il server di sviluppo FastAPI e vedere la tua integrazione AI prendere vita! FastAPI utilizza Uvicorn, un server ASGI ultra veloce progettato specificamente per applicazioni Python asincrone.
#### Comprendere il processo di avvio del server FastAPI
```bash
# Method 1: Direct Python execution (includes auto-reload)
python api.py
# Method 2: Using Uvicorn directly (more control)
uvicorn api:app --host 0.0.0.0 --port 5000 --reload
```
Quando esegui questo comando, ecco cosa succede dietro le quinte:
**1. Python carica la tua applicazione FastAPI**:
- Importa tutte le librerie necessarie (FastAPI, Pydantic, OpenAI, ecc.)
- Carica le variabili d'ambiente dal tuo file `.env`
- Crea l'istanza dell'applicazione FastAPI con documentazione automatica
**2. Uvicorn configura il server ASGI**:
- Si collega alla porta 5000 con capacità di gestione delle richieste asincrone
- Configura l'instradamento delle richieste con validazione automatica
- Abilita il ricaricamento automatico per lo sviluppo (riavvio in caso di modifiche ai file)
- Genera documentazione API interattiva
**3. Il server inizia ad ascoltare**:
- Il tuo terminale mostra: `INFO: Uvicorn running on http://0.0.0.0:5000`
- Il server può gestire più richieste AI concorrenti
- La tua API è pronta con documentazione automatica su `http://localhost:5000/docs`
#### Cosa dovresti vedere quando tutto funziona
```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.
```
**Comprendere l'output di FastAPI:**
- **Osserva le modifiche**: Ricaricamento automatico abilitato per lo sviluppo
- **Uvicorn in esecuzione**: Il server ASGI ad alte prestazioni è attivo
- **Processo di ricaricamento avviato**: Osservatore di file per riavvii automatici
- **Avvio dell'applicazione completato**: App FastAPI inizializzata con successo
- **Documentazione interattiva disponibile**: Visita `/docs` per la documentazione API automatica
#### Testare il tuo FastAPI: Approcci potenti e multipli
FastAPI offre diversi modi convenienti per testare la tua API, inclusa la documentazione interattiva automatica:
**Metodo 1: Documentazione API interattiva (consigliato)**
1. Apri il browser e vai su `http://localhost:5000/docs`
2. Vedrai Swagger UI con tutti i tuoi endpoint documentati
3. Clicca su `/hello` → "Prova" → Inserisci un messaggio di test → "Esegui"
4. Visualizza la risposta direttamente nel browser con formattazione corretta
**Metodo 2: Test di base nel browser**
1. Vai su `http://localhost:5000` per l'endpoint root
2. Vai su `http://localhost:5000/health` per controllare lo stato del server
3. Questo conferma che il tuo server FastAPI è in esecuzione correttamente
**Metodo 2: Test da riga di comando (avanzato)**
```bash
# Test with curl (if available)
curl -X POST http://localhost:5000/hello \
-H "Content-Type: application/json" \
-d '{"message": "Hello AI!"}'
# Expected response:
# {"response": "Hello! I'm your AI assistant. How can I help you today?"}
```
**Metodo 3: Script di test Python**
#### Risoluzione dei problemi comuni all'avvio
| Messaggio di errore | Cosa significa | Come risolverlo |
|---------------------|----------------|-----------------|
| `ModuleNotFoundError: No module named 'fastapi'` | FastAPI non è installato | Esegui `pip install fastapi uvicorn` nel tuo ambiente virtuale |
| `ModuleNotFoundError: No module named 'uvicorn'` | Server ASGI non installato | Esegui `pip install uvicorn` nel tuo ambiente virtuale |
| `KeyError: 'GITHUB_TOKEN'` | Variabile d'ambiente non trovata | Controlla il file `.env` e la chiamata a `load_dotenv()` |
| `Address already in use` | La porta 5000 è occupata | Termina altri processi che utilizzano la porta 5000 o cambia porta |
| `ValidationError` | I dati della richiesta non corrispondono al modello Pydantic | Controlla che il formato della richiesta corrisponda allo schema previsto |
| `HTTPException 422` | Entità non elaborabile | La validazione della richiesta è fallita, controlla `/docs` per il formato corretto |
| `OpenAI API error` | Autenticazione del servizio AI fallita | Verifica che il tuo token GitHub sia corretto e abbia i permessi adeguati |
#### Migliori pratiche di sviluppo
**Ricaricamento automatico**: FastAPI con Uvicorn offre il ricaricamento automatico quando salvi le modifiche ai file Python. Questo significa che puoi modificare il codice e testarlo immediatamente senza dover riavviare manualmente.
**Logging per lo sviluppo**: Aggiungi il logging per capire cosa sta succedendo:
**Perché il logging aiuta**: Durante lo sviluppo, puoi vedere esattamente quali richieste arrivano, cosa risponde l'AI e dove si verificano gli errori. Questo rende il debug molto più veloce.
### Configurazione per GitHub Codespaces: sviluppo cloud semplificato
GitHub Codespaces è come avere un potente computer di sviluppo nel cloud, accessibile da qualsiasi browser. Se stai lavorando in Codespaces, ci sono alcuni passaggi aggiuntivi per rendere il tuo backend accessibile al frontend.
#### Comprendere il networking di Codespaces
In un ambiente di sviluppo locale, tutto gira sullo stesso computer:
- Backend: `http://localhost:5000`
- Frontend: `http://localhost:3000` (o file://)
In Codespaces, il tuo ambiente di sviluppo gira sui server di GitHub, quindi "localhost" ha un significato diverso. GitHub crea automaticamente URL pubblici per i tuoi servizi, ma devi configurarli correttamente.
#### Configurazione passo-passo di Codespaces
**1. Avvia il server backend**:
Vedrai il familiare messaggio di avvio di FastAPI/Uvicorn, ma noterai che sta girando all'interno dell'ambiente Codespace.
**2. Configura la visibilità della porta**:
- Cerca la scheda "Ports" nel pannello inferiore di VS Code
- Trova la porta 5000 nella lista
- Clicca con il tasto destro sulla porta 5000
- Seleziona "Port Visibility" → "Public"
**Perché renderla pubblica?** Di default, le porte di Codespace sono private (accessibili solo a te). Renderle pubbliche permette al frontend (che gira nel browser) di comunicare con il backend.
**3. Ottieni il tuo URL pubblico**:
Dopo aver reso la porta pubblica, vedrai un URL simile a:
**4. Aggiorna la configurazione del frontend**:
#### Comprendere gli URL di Codespace
Gli URL di Codespace seguono un pattern prevedibile:
**Analisi di questo pattern:**
- `codespace-name`: Un identificatore unico per il tuo Codespace (di solito include il tuo nome utente)
- `port`: Il numero di porta su cui il tuo servizio sta girando (5000 per la nostra app FastAPI)
- `app.github.dev`: Dominio di GitHub per le applicazioni Codespace
#### Testare la configurazione di Codespace
**1. Testa direttamente il backend**:
Apri il tuo URL pubblico in una nuova scheda del browser. Dovresti vedere:
**2. Testa con gli strumenti per sviluppatori del browser**:
#### Codespaces vs Sviluppo Locale
| Aspetto | Sviluppo Locale | GitHub Codespaces |
|---------|-----------------|-------------------|
| **Tempo di configurazione** | Più lungo (installazione di Python, dipendenze) | Istantaneo (ambiente preconfigurato) |
| **Accesso URL** | `http://localhost:5000` | `https://xyz-5000.app.github.dev` |
| **Configurazione porta** | Automatica | Manuale (rendere le porte pubbliche) |
| **Persistenza file** | Macchina locale | Repository GitHub |
| **Collaborazione** | Difficile condividere l'ambiente | Facile condividere il link del Codespace |
| **Dipendenza da Internet** | Solo per chiamate API AI | Necessaria per tutto |
#### Consigli per lo sviluppo in Codespaces
**Variabili d'ambiente in Codespaces**:
Il tuo file `.env` funziona allo stesso modo in Codespaces, ma puoi anche impostare variabili d'ambiente direttamente nel Codespace.
**Gestione delle porte**:
- Codespaces rileva automaticamente quando la tua applicazione inizia ad ascoltare su una porta
- Puoi inoltrare più porte contemporaneamente (utile se aggiungi un database in seguito)
- Le porte rimangono accessibili finché il tuo Codespace è attivo
**Workflow di sviluppo**:
1. Apporta modifiche al codice in VS Code
2. FastAPI si ricarica automaticamente (grazie alla modalità di ricaricamento di Uvicorn)
3. Testa immediatamente le modifiche tramite l'URL pubblico
4. Effettua il commit e il push quando sei pronto
> 💡 **Consiglio Pro**: Salva nei preferiti l'URL del backend del tuo Codespace durante lo sviluppo. Poiché i nomi dei Codespace sono stabili, l'URL non cambierà finché utilizzi lo stesso Codespace.
## Creare l'interfaccia chat del frontend: dove gli utenti incontrano l'AI
Ora costruiremo l'interfaccia utente – la parte che determina come le persone interagiscono con il tuo assistente AI. Come il design dell'interfaccia originale dell'iPhone, ci concentreremo su come rendere la tecnologia complessa intuitiva e naturale da usare.
### Comprendere l'architettura moderna del frontend
La nostra interfaccia chat sarà ciò che chiamiamo un'applicazione "Single Page Application" o SPA. Invece dell'approccio tradizionale in cui ogni clic carica una nuova pagina, la nostra app si aggiorna in modo fluido e istantaneo:
**Vecchi siti web**: Come leggere un libro fisico – sfogli completamente nuove pagine
**La nostra app chat**: Come usare il tuo telefono – tutto scorre e si aggiorna senza interruzioni
### I tre pilastri dello sviluppo frontend
Ogni applicazione frontend – dai siti web semplici alle app complesse come Discord o Slack – si basa su tre tecnologie fondamentali. Pensale come la base di tutto ciò che vedi e con cui interagisci sul web:
**HTML (Struttura)**: Questa è la tua base
- Decide quali elementi esistono (pulsanti, aree di testo, contenitori)
- Dà significato ai contenuti (questo è un'intestazione, questo è un modulo, ecc.)
- Crea la struttura di base su cui tutto il resto si costruisce
**CSS (Presentazione)**: Questo è il tuo designer d'interni
- Fa sembrare tutto bello (colori, font, layout)
- Gestisce le diverse dimensioni dello schermo (telefono vs laptop vs tablet)
- Crea animazioni fluide e feedback visivi
**JavaScript (Comportamento)**: Questo è il tuo cervello
- Risponde a ciò che fanno gli utenti (clic, digitazione, scorrimento)
- Comunica con il backend e aggiorna la pagina
- Rende tutto interattivo e dinamico
**Pensalo come un progetto architettonico:**
- **HTML**: Il progetto strutturale (definizione degli spazi e delle relazioni)
- **CSS**: Il design estetico e ambientale (stile visivo e esperienza utente)
- **JavaScript**: I sistemi meccanici (funzionalità e interattività)
### Perché l'architettura moderna di JavaScript è importante
La nostra applicazione chat utilizzerà modelli di JavaScript moderni che vedrai nelle applicazioni professionali. Comprendere questi concetti ti aiuterà a crescere come sviluppatore:
**Architettura basata su classi**: Organizzeremo il nostro codice in classi, che è come creare progetti per oggetti
**Async/Await**: Metodo moderno per gestire operazioni che richiedono tempo (come le chiamate API)
**Programmazione basata su eventi**: La nostra app risponde alle azioni degli utenti (clic, pressione di tasti) invece di girare in un ciclo
**Manipolazione del DOM**: Aggiornamento dinamico del contenuto della pagina web in base alle interazioni degli utenti e alle risposte delle API
### Configurazione della struttura del progetto
Crea una directory frontend con questa struttura organizzata:
**Comprendere l'architettura:**
- **Separa** le preoccupazioni tra struttura (HTML), comportamento (JavaScript) e presentazione (CSS)
- **Mantiene** una struttura di file semplice e facile da navigare e modificare
- **Segue** le migliori pratiche di sviluppo web per organizzazione e manutenibilità
### Costruire la base HTML: struttura semantica per l'accessibilità
Iniziamo con la struttura HTML. Lo sviluppo web moderno enfatizza l'uso di "HTML semantico" – utilizzare elementi HTML che descrivano chiaramente il loro scopo, non solo il loro aspetto. Questo rende la tua applicazione accessibile ai lettori di schermo, ai motori di ricerca e ad altri strumenti.
**Perché l'HTML semantico è importante**: Immagina di descrivere la tua app chat a qualcuno al telefono. Diresti "c'è un'intestazione con il titolo, un'area principale dove appaiono le conversazioni e un modulo in basso per digitare i messaggi". L'HTML semantico utilizza elementi che corrispondono a questa descrizione naturale.
Crea `index.html` con questo markup strutturato in modo ponderato:
**Comprendere ogni elemento HTML e il suo scopo:**
#### Struttura del documento
- **``**: Indica al browser che si tratta di HTML5 moderno
- **``**: Specifica la lingua della pagina per i lettori di schermo e gli strumenti di traduzione
- **``**: Garantisce la corretta codifica dei caratteri per il testo internazionale
- **``**: Rende la pagina mobile-responsive controllando lo zoom e la scala
#### Elementi semantici
- **``**: Identifica chiaramente la sezione superiore con titolo e descrizione
- **``**: Designa l'area di contenuto principale (dove avvengono le conversazioni)
- **`