|
|
1 month ago | |
|---|---|---|
| .. | ||
| solution | 4 months ago | |
| README.md | 1 month ago | |
README.md
Byg en Chat-assistent med AI
Kan du huske i Star Trek, da besætningen afslappet talte med skibets computer, stillede den komplekse spørgsmål og fik gennemførte svar? Hvad der virkede som ren science fiction i 1960’erne, er nu noget, du kan bygge ved hjælp af webteknologier, du allerede kender.
I denne lektion skaber vi en AI-chatassistent ved hjælp af HTML, CSS, JavaScript og en backend-integration. Du vil opdage, hvordan de samme færdigheder, du har lært, kan forbinde til kraftfulde AI-tjenester, som kan forstå kontekst og generere meningsfulde svar.
Tænk på AI som adgang til et enormt bibliotek, der ikke blot kan finde information, men også syntetisere det til sammenhængende svar, der er skræddersyet til dine specifikke spørgsmål. I stedet for at gennemgå tusindvis af sider får du direkte, kontekstuelle svar.
Integrationen sker gennem velkendte webteknologier, der arbejder sammen. HTML skaber chatgrænsefladen, CSS håndterer det visuelle design, JavaScript styrer brugerinteraktioner, og en backend-API forbinder det hele til AI-tjenester. Det ligner, hvordan forskellige sektioner i et orkester samarbejder for at skabe en symfoni.
Vi bygger i bund og grund en bro mellem naturlig menneskelig kommunikation og maskinbehandling. Du lærer både den tekniske implementering af AI-tjenesteintegration og designmønstrene, der gør interaktioner intuitive.
Ved slutningen af denne lektion vil AI-integration føles mindre som en mystisk proces og mere som en hvilken som helst anden API, du kan arbejde med. Du vil forstå de grundlæggende mønstre, der driver applikationer som ChatGPT og Claude, ved at bruge de samme webudviklingsprincipper, du allerede har lært.
⚡ Hvad Du Kan Nå på de Næste 5 Minutter
Hurtig Startvej for Travle Udviklere
flowchart LR
A[⚡ 5 minutter] --> B[Få GitHub-token]
B --> C[Test AI legeplads]
C --> D[Kopiér Python-kode]
D --> E[Se AI-svar]
- Minut 1: Besøg GitHub Models Playground og opret en personlig adgangstoken
- Minut 2: Test AI-interaktioner direkte i playground-grænsefladen
- Minut 3: Klik på fanen "Code" og kopier Python-koden
- Minut 4: Kør koden lokalt med din token:
GITHUB_TOKEN=your_token python test.py - Minut 5: Se dit første AI-svar genereres fra din egen kode
Hurtig Testkode:
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)
Hvorfor det betyder noget: På 5 minutter vil du opleve magien ved programmeret AI-interaktion. Dette repræsenterer grundstenen, der driver alle AI-applikationer, du bruger.
Sådan vil dit færdige projekt se ud:
🗺️ Din Læringsrejse Gennem AI-applikationsudvikling
journey
title Fra Webudvikling til AI-Integration
section Forståelse af AI-Grundlag
Opdag generative AI-koncepter: 4: You
Udforsk GitHub Models platform: 6: You
Mestre AI-parametre og prompts: 8: You
section Backend Integration
Byg Python API-server: 5: You
Implementer AI-funktionskald: 7: You
Håndter asynkrone operationer: 8: You
section Frontend Udvikling
Skab moderne chatgrænseflade: 6: You
Mestre realtidsinteraktioner: 8: You
Byg responsiv brugeroplevelse: 9: You
section Professionel Anvendelse
Udrul komplet AI-system: 7: You
Optimer ydelsesmønstre: 8: You
Skab produktionsklar app: 9: You
Dit Mål for Rejsen: Ved lektionens afslutning har du bygget en komplet AI-drevet applikation med de samme teknologier og mønstre, der driver moderne AI-assistenter som ChatGPT, Claude og Google Bard.
Forstå AI: Fra Mystik til Mestring
Før vi dykker ned i koden, lad os forstå, hvad vi arbejder med. Hvis du har brugt API’er før, kender du det grundlæggende mønster: sende en anmodning, modtage et svar.
AI-API’er følger en lignende struktur, men i stedet for at hente forudlagrede data fra en database genererer de nye svar baseret på mønstre lært fra enorme mængder tekst. Tænk på det som forskellen mellem et bibliotekskatalog og en kyndig bibliotekar, der kan syntetisere information fra flere kilder.
Hvad er "Generativ AI" Egentlig?
Tænk på, hvordan Rosetta-stenen gjorde det muligt for forskere at forstå egyptiske hieroglyffer ved at finde mønstre mellem kendte og ukendte sprog. AI-modeller arbejder på samme måde – de finder mønstre i enorme tekstmængder for at forstå, hvordan sprog fungerer, og bruger derefter disse mønstre til at generere passende svar på nye spørgsmål.
Lad mig forklare det med en simpel sammenligning:
- Traditionel database: Som at bede om din fødselsattest – du får det samme dokument hver gang
- Søgemaskine: Som at bede en bibliotekar finde bøger om katte – de viser dig, hvad der er tilgængeligt
- Generativ AI: Som at spørge en vidende ven om katte – de fortæller dig interessante ting med deres egne ord, tilpasset det, du vil vide
graph LR
A[Dit Spørgsmål] --> B[AI Model]
B --> C[Mønster Genkendelse]
C --> D[Indholds Generering]
D --> E[Kontekstuel Respons]
F[Træningsdata<br/>Bøger, Artikler, Web] --> B
Hvordan AI-modeller Lærer (Den Enkle Version)
AI-modeller lærer gennem eksponering for enorme datasæt indeholdende tekst fra bøger, artikler og samtaler. Gennem denne proces identificerer de mønstre i:
- Hvordan tanker struktureres i skriftlig kommunikation
- Hvilke ord der ofte optræder sammen
- Hvordan samtaler typisk flyder
- Kontekstuelle forskelle mellem formel og uformel kommunikation
Det svarer til, hvordan arkæologer afkoder gamle sprog: de analyserer tusinder af eksempler for at forstå grammatik, ordforråd og kulturel kontekst, og bliver til sidst i stand til at tolke nye tekster ved hjælp af disse lærte mønstre.
Hvorfor GitHub Models?
Vi bruger GitHub Models af en praktisk årsag – det giver os adgang til AI på virksomhedsniveau uden at skulle opsætte vores egen AI-infrastruktur (hvilket du for resten ikke har lyst til lige nu!). Tænk på det som at bruge en vejr-API i stedet for selv at oprette vejrstationer overalt.
Det er i bund og grund "AI-som-en-Service", og det bedste? Det er gratis at komme i gang med, så du kan eksperimentere uden bekymring om store regninger.
graph LR
A[Frontend Chat UI] --> B[Din Backend API]
B --> C[GitHub Models API]
C --> D[AI Modelbehandling]
D --> C
C --> B
B --> A
Vi bruger GitHub Models til vores backend-integration, som giver adgang til professionelle AI-kapaciteter gennem en udviklervenlig grænseflade. GitHub Models Playground fungerer som et testmiljø, hvor du kan prøve forskellige AI-modeller og forstå deres egenskaber, før du implementerer dem i kode.
🧠 AI-applikationsudviklingsøkosystem
mindmap
root((AI Udvikling))
Forståelse af AI
Generative Modeller
Mønster Genkendelse
Indhold Generering
Kontekst Forståelse
Svar Syntese
AI Parametre
Temperatur Kontrol
Token Grænser
Top-p Filtrering
System Prompter
Backend Arkitektur
API Integration
GitHub Modeller
Autentificering
Forespørgsels Håndtering
Fejl Håndtering
Python Infrastruktur
FastAPI Framework
Async Operationer
Miljø Sikkerhed
CORS Konfiguration
Frontend Oplevelse
Chat Interface
Real-time Opdateringer
Besked Historik
Bruger Feedback
Indlæsnings Tilstande
Moderne Web Teknologi
ES6 Klasser
Async/Await
DOM Manipulation
Event Håndtering
Professionelle Mønstre
Sikkerheds Bedste Praksis
Token Håndtering
Input Validering
XSS Forebyggelse
Fejlgrænser
Produktionsberedskab
Ydelsesoptimering
Responsivt Design
Tilgængelighed
Test Strategier
Kerneprincip: AI-applikationsudvikling kombinerer traditionelle webudviklingsfærdigheder med AI-tjenesteintegration for at skabe intelligente applikationer, der føles naturlige og responsive for brugerne.
Det der gør playground så nyttig:
- Prøv forskellige AI-modeller som GPT-4o-mini, Claude og andre (alle gratis!)
- Test dine idéer og prompts inden du skriver kode
- Få klar-til-brug kodeeksempler i dit foretrukne programmeringssprog
- Juster indstillinger som kreativitet og svarlængde for at se, hvordan de påvirker output
Når du har prøvet lidt, klik bare på fanen "Code" og vælg dit programmersprog for at få den nødvendige implementeringskode.
Opsætning af Python Backend Integration
Lad os nu implementere AI-integrationen med Python. Python er fremragende til AI-applikationer pga. sin simple syntaks og kraftfulde biblioteker. Vi starter med koden fra GitHub Models playground og refaktorerer den derefter til en genanvendelig, produktionsklar funktion.
Forstå den Grundlæggende Implementering
Når du henter Python-koden fra playground, får du noget, der ligner dette. Bare rolig, hvis det virker meget til at starte med – lad os gennemgå det stykke for stykke:
"""Run this model in Python
> pip install openai
"""
import os
from openai import OpenAI
# For at godkende med modellen skal du generere et personligt adgangstoken (PAT) i dine GitHub-indstillinger.
# Opret dit PAT-token ved at følge instruktionerne her: 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)
Det der sker i denne kode:
- Vi importerer de nødvendige værktøjer:
ostil at læse miljøvariabler ogOpenAItil at kommunikere med AI - Vi opsætter OpenAI-klienten til at pege på GitHubs AI-servere i stedet for direkte OpenAI
- Vi autentificerer med en særlig GitHub-token (mere om det om lidt!)
- Vi strukturerer vores samtale med forskellige "roller" – tænk på det som at sætte scenen for et skuespil
- Vi sender vores anmodning til AI med nogle finjusteringsparametre
- Vi udtrækker det faktiske svartekst fra al den data, der kommer tilbage
Forståelse af Beskedsroller: AI-samtalens Rammeværk
AI-samtaler bruger en specifik struktur med forskellige "roller", der tjener forskellige formål:
messages=[
{
"role": "system",
"content": "You are a helpful assistant who explains things simply."
},
{
"role": "user",
"content": "What is machine learning?"
}
]
Tænk på det som at instruere et skuespil:
- System-rollen: Som scenemanuskript for en skuespiller – den fortæller AI, hvordan den skal opføre sig, hvilken personlighed den skal have og hvordan den skal svare
- Bruger-rollen: Det egentlige spørgsmål eller besked fra den, der bruger din applikation
- Assistent-rollen: AIs svar (det sender du ikke, men det vises i samtalehistorikken)
Virkelighedsfaglig analogi: Forestil dig, at du præsenterer en ven for en anden til en fest:
- Systembesked: "Det her er min ven Sarah, hun er læge og er rigtig god til at forklare medicinske begreber i enkle termer"
- Brugerbesked: "Kan du forklare, hvordan vacciner virker?"
- Assistentbesked: Sarah svarer som en venlig læge, ikke som advokat eller kok
Forstå AI-parametre: Finjustering af Svaradfærd
De numeriske parametre i AI-API-kald kontrollerer, hvordan modellen genererer svar. Disse indstillinger giver dig mulighed for at justere AIs adfærd til forskellige formål:
Temperatur (0,0 til 2,0): Kreativitetsdrejeknappen
Hvad den gør: Styrer, hvor kreativ eller forudsigelig AIs svar bliver.
Tænk på det som en jazzmusikers improvisationsniveau:
- Temperatur = 0,1: Spiller den nøjagtige samme melodi hver gang (meget forudsigelig)
- Temperatur = 0,7: Tilføjer nogle smagfulde variationer, mens det stadig er genkendeligt (balanceret kreativitet)
- Temperatur = 1,5: Fuld eksperimentel jazz med uventede drejninger (meget uforudsigeligt)
# Meget forudsigelige svar (godt til faktuelle spørgsmål)
response = client.chat.completions.create(
messages=[{"role": "user", "content": "What is 2+2?"}],
temperature=0.1 # Vil næsten altid sige "4"
)
# Kreative svar (godt til brainstorm)
response = client.chat.completions.create(
messages=[{"role": "user", "content": "Write a creative story opening"}],
temperature=1.2 # Vil generere unikke, uventede historier
)
Max Tokens (1 til 4096+): Kontrol af Svarets Længde
Hvad den gør: Sætter en grænse for, hvor langt AIs svar kan være.
Tænk på tokens som omtrent svarende til ord (ca. 1 token = 0,75 ord på engelsk):
- max_tokens=50: Kort og godt (som en sms)
- max_tokens=500: Et pænt afsnit eller to
- max_tokens=2000: En detaljeret forklaring med eksempler
# Korte, præcise svar
response = client.chat.completions.create(
messages=[{"role": "user", "content": "Explain JavaScript"}],
max_tokens=100 # Tvinger en kort forklaring
)
# Detaljerede, omfattende svar
response = client.chat.completions.create(
messages=[{"role": "user", "content": "Explain JavaScript"}],
max_tokens=1500 # Muliggør detaljerede forklaringer med eksempler
)
Top_p (0,0 til 1,0): Fokusparameteren
Hvad den gør: Kontrollerer, hvor fokuseret AI er på de mest sandsynlige svar.
Forestil dig at AI har et kæmpe ordforråd, rangeret efter sandsynlighed:
- top_p=0,1: Overvejer kun de 10 % mest sandsynlige ord (meget fokuseret)
- top_p=0,9: Overvejer 90 % af mulige ord (mere kreativ)
- top_p=1,0: Overvejer alt (maksimal variation)
For eksempel: Hvis du spørger "Himmelen er normalt..."
- Lav top_p: Siger næsten altid "blå"
- Høj top_p: Kan sige "blå", "skyet", "uendelig", "foranderlig", "smuk" osv.
Sætte Det Hele Sammen: Parameterkombinationer til Forskellige Brug
# For faktuelle, konsistente svar (som en dokumentationsbot)
factual_params = {
"temperature": 0.2,
"max_tokens": 300,
"top_p": 0.3
}
# Til kreativ skrivehjælp
creative_params = {
"temperature": 1.1,
"max_tokens": 1000,
"top_p": 0.9
}
# Til samtaleorienterede, hjælpsomme svar (afbalanceret)
conversational_params = {
"temperature": 0.7,
"max_tokens": 500,
"top_p": 0.8
}
quadrantChart
title AI Parameteroptimeringsmatrix
x-axis Lav Kreativitet --> Høj Kreativitet
y-axis Kort Respons --> Lang Respons
quadrant-1 Kreativt Indhold
quadrant-2 Detaljeret Analyse
quadrant-3 Hurtige Fakta
quadrant-4 Samtale-AI
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]
Hvorfor disse parametre er vigtige: Forskellige applikationer har brug for forskellige typer svar. En kundeservicebot bør være konsekvent og faktuel (lav temperatur), mens en kreativ skriveassistent skal være fantasifuld og varieret (høj temperatur). At forstå disse parametre giver dig kontrol over din AIs personlighed og svarstil.
**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))
Forstå denne forbedrede funktion:
- Accepterer to parametre: brugerens prompt og en valgfri systembesked
- Tilbyder en standard systembesked for generel assistentadfærd
- Bruger korrekte Python typeangivelser til bedre kodetekst
- Inkluderer en detaljeret docstring, der forklarer funktionens formål og parametre
- Returnerer kun svarindholdet, så det er nemt at bruge i vores web-API
- Vedligeholder de samme modelparametre for konsistent AI-adfærd
Magien ved Systemprompter: Programmering af AI-personlighed
Hvis parametre styrer, hvordan AI tænker, styrer systemprompter, hvem AI tror, den er. Dette er ærligt talt en af de fedeste dele ved at arbejde med AI – du giver AI en komplet personlighed, fagligt niveau og kommunikationsstil.
Tænk på systemprompter som at caste forskellige skuespillere til forskellige roller: I stedet for én generisk assistent kan du skabe specialiserede eksperter til forskellige situationer. Brug for en tålmodig lærer? En kreativ brainstormingpartner? En seriøs forretningsrådgiver? Bare skift systemprompten!
Hvorfor Systemprompter Er Så Kraftfulde
Her er det fascinerende: AI-modeller er trænet på utallige samtaler, hvor folk påtager sig forskellige roller og ekspertiseniveauer. Når du giver AI en specifik rolle, er det som at trykke på en kontakt, der aktiverer alle de lærte mønstre.
Det svarer til metode-skuespil for AI: Sig til en skuespiller "du er en klog, gammel professor" og se, hvordan de automatisk tilpasser kropsholdning, ordvalg og manerer. AI gør noget bemærkelsesværdigt lignende med sprog.
Skabelse af Effektive Systemprompter: Kunsten og Videnskaben
Anatomien af en god systemprompt:
- Rolle/Identitet: Hvem er AI?
- Ekspertise: Hvad ved den?
- Kommunikationsstil: Hvordan taler den?
- Specifikke instruktioner: Hvad skal den fokusere på?
# ❌ Uklar systemprompt
"You are helpful."
# ✅ Detaljeret, effektiv systemprompt
"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."
Systemprompt-eksempler med kontekst
Lad os se, hvordan forskellige systemprompter skaber helt forskellige AI-personligheder:
# Eksempel 1: Den tålmodige lærer
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.
"""
# Eksempel 2: Den kreative samarbejdspartner
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.
"""
# Eksempel 3: Den strategiske forretningsrådgiver
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.
"""
Se Systemprompter i Aktion
Lad os teste det samme spørgsmål med forskellige systemprompter for at se de dramatiske forskelle:
Spørgsmål: "Hvordan håndterer jeg brugerautentifikation i min webapp?"
# Med lærer-prompt:
teacher_response = call_llm(
"How do I handle user authentication in my web app?",
teacher_prompt
)
# Typisk svar: "Godt spørgsmål! Lad os opdele autentificering i simple trin.
# Tænk på det som en natklub dørmand, der tjekker ID'er..."
# Med forretningsprompt:
business_response = call_llm(
"How do I handle user authentication in my web app?",
business_prompt
)
# Typisk svar: "Set fra et strategisk perspektiv er autentificering afgørende for bruger
# tillid og overholdelse af regler. Lad mig skitsere en ramme, der tager højde for sikkerhed,
# brugeroplevelse og skalerbarhed..."
Avancerede Systemprompt-teknikker
1. Kontekstopsætning: Giv AI baggrundsinformation
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. Outputformatering: Fortæl AI'en, hvordan svar skal struktureres
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. Begrænsningsindstilling: Definer, hvad AI'en IKKE skal gøre
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.
"""
Hvorfor dette er vigtigt for din chatassistent
Forståelse af systemprompter giver dig utrolig magt til at skabe specialiserede AI-assistenter:
- Kundeservicebot: Hjælpsom, tålmodig, politik-kyndig
- Læringsvejleder: Opmuntrende, trin-for-trin, tjekker forståelse
- Kreativ partner: Fantasifuld, bygger videre på ideer, spørger "hvad nu hvis?"
- Teknisk ekspert: Præcis, detaljeret, sikkerhedsbevidst
Den centrale indsigt: Du kalder ikke bare en AI API – du skaber en brugerdefineret AI-personlighed, der tjener dit specifikke brugsscenarie. Det er det, der gør moderne AI-applikationer skræddersyede og nyttige i stedet for generiske.
🎯 Pædagogisk tjek-in: AI-personlighedsprogrammering
Pause og reflekter: Du har netop lært at programmere AI-personligheder via systemprompter. Dette er en grundlæggende færdighed i moderne AI-applikationsudvikling.
Hurtig selvvurdering:
- Kan du forklare, hvordan systemprompter adskiller sig fra almindelige brugermeddelelser?
- Hvad er forskellen på temperatur- og top_p-parametre?
- Hvordan ville du skabe en systemprompt for et specifikt brugsscenarie (f.eks. en kodevejleder)?
Virkelighedsnær forbindelse: De systemprompt-teknikker, du har lært, bruges i alle større AI-applikationer – fra GitHub Copilots kodeassistance til ChatGPT's samtalegrænseflade. Du mestrer de samme mønstre, som AI-produktteams bruger hos store tech-virksomheder.
Udfordrende spørgsmål: Hvordan kunne du designe forskellige AI-personligheder til forskellige brugertyper (begynder vs ekspert)? Overvej, hvordan det samme underliggende AI-model kunne betjene forskellige målgrupper via prompt-engineering.
Byg Web API'en med FastAPI: Dit Højtydende AI-kommunikationsknudepunkt
Lad os nu bygge backend'en, der forbinder din frontend med AI-tjenester. Vi vil bruge FastAPI, et moderne Python-framework, som er fremragende til at bygge API’er til AI-applikationer.
FastAPI tilbyder flere fordele for denne type projekt: indbygget asynkron støtte til håndtering af samtidige forespørgsler, automatisk API-dokumentationsgenerering og fremragende ydeevne. Din FastAPI-server fungerer som en mellemliggende del, der modtager forespørgsler fra frontend, kommunikerer med AI-tjenesterne og returnerer formaterede svar.
Hvorfor FastAPI til AI-applikationer?
Du tænker måske: "Kan jeg ikke bare kalde AI direkte fra min frontend JavaScript?" eller "Hvorfor FastAPI frem for Flask eller Django?" Gode spørgsmål!
Her er hvorfor FastAPI er perfekt til det, vi bygger:
- Async som standard: Kan jonglere flere AI-forespørgsler samtidig uden at hænge fast
- Automatisk dokumentation: Besøg
/docsog få en flot, interaktiv API-dokumentationsside gratis - Indbygget validering: Fanger fejl, før de skaber problemer
- Lynhurtig: Et af de hurtigste Python-frameworks overhovedet
- Moderne Python: Bruger alle de nyeste og bedste Python-funktioner
Og her er hvorfor vi overhovedet har brug for en backend:
Sikkerhed: Dit AI API-nøgle er som en adgangskode – hvis du lægger den i frontend JavaScript, kan alle, der ser din hjemmesides kildekode, stjæle den og bruge dine AI-kreditter. Backend'en holder følsomme legitimationsoplysninger sikre.
Ratebegrænsning & kontrol: Backend'en lader dig styre, hvor ofte brugere kan sende forespørgsler, implementere brugerautentifikation og tilføje logning for at spore brug.
Databehandling: Du vil måske gemme samtaler, filtrere upassende indhold eller kombinere flere AI-tjenester. Backend'en er stedet, hvor denne logik hører hjemme.
Arkitekturen minder om en klient-server-model:
- Frontend: Brugergrænsefladelag til interaktion
- Backend API: Forespørgselsbehandling og routering
- AI-tjeneste: Ekstern udregning og svargenerering
- Miljøvariabler: Sikker konfigurations- og legitimationslagring
Forståelse af forespørgsels- og svarflowet
Lad os følge, hvad der sker, når en bruger sender en besked:
sequenceDiagram
participant User as 👤 Bruger
participant Frontend as 🌐 Frontend
participant API as 🔧 FastAPI Server
participant AI as 🤖 AI Service
User->>Frontend: Taster "Hej AI!"
Frontend->>API: POST /hello {"message": "Hej AI!"}
Note over API: Validerer forespørgsel<br/>Tilføjer systemprompt
API->>AI: Sender formateret forespørgsel
AI->>API: Returnerer AI svar
Note over API: Behandler svar<br/>Logger samtale
API->>Frontend: {"response": "Hej! Hvordan kan jeg hjælpe?"}
Frontend->>User: Viser AI besked
Forstå hvert trin:
- Brugerinteraktion: Personen skriver i chatgrænsefladen
- Frontend-behandling: JavaScript fanger input og formaterer det som JSON
- API-validering: FastAPI validerer automatisk forespørgslen vha. Pydantic-modeller
- AI-integration: Backend tilføjer kontekst (systemprompt) og kalder AI-tjenesten
- Svarhåndtering: API modtager AI-svar og kan ændre det efter behov
- Frontend-visning: JavaScript viser svaret i chatgrænsefladen
Forståelse af API-arkitekturen
sequenceDiagram
participant Frontend
participant FastAPI
participant AI Function
participant GitHub Models
Frontend->>FastAPI: POST /hello {"message": "Hej AI!"}
FastAPI->>AI Function: call_llm(message, system_prompt)
AI Function->>GitHub Models: API forespørgsel
GitHub Models->>AI Function: AI svar
AI Function->>FastAPI: svar tekst
FastAPI->>Frontend: {"response": "Hej! Hvordan kan jeg hjælpe?"}
flowchart TD
A[Brugerinput] --> B[Frontend Validering]
B --> C[HTTP POST Anmodning]
C --> D[FastAPI Router]
D --> E[Pydantic Validering]
E --> F[AI Funktionskald]
F --> G[GitHub Models API]
G --> H[Svarbehandling]
H --> I[JSON Svar]
I --> J[Frontend Opdatering]
subgraph "Sikkerhedslag"
K[CORS Middleware]
L[Miljøvariabler]
M[Fejlhåndtering]
end
D --> K
F --> L
H --> M
Oprettelse af FastAPI-applikationen
Lad os bygge vores API trin for trin. Opret en fil med navnet api.py med følgende FastAPI-kode:
# api.py
from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
from llm import call_llm
import logging
# Konfigurer logning
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# Opret FastAPI-applikation
app = FastAPI(
title="AI Chat API",
description="A high-performance API for AI-powered chat applications",
version="1.0.0"
)
# Konfigurer CORS
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # Konfigurer passende til produktion
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# Pydantic-modeller til anmodnings-/responsvalidering
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:
# Udtræk og valider besked
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]}...")
# Kald AI-service (bemærk: call_llm bør laves asynkron for bedre ydeevne)
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)
Forståelse af FastAPI-implementeringen:
- Importer FastAPI for moderne webframework-funktionalitet og Pydantic for datavalidering
- Opretter automatisk API-dokumentation (tilgængelig på
/docs, når serveren kører) - Aktiverer CORS-middleware for at tillade frontend-forespørgsler fra forskellige oprindelser
- Definerer Pydantic-modeller til automatisk validering af forespørgsler/svar og dokumentation
- Bruger asynkrone endpoints for bedre ydeevne ved samtidige forespørgsler
- Implementerer korrekte HTTP-statuskoder og fejlhåndtering med HTTPException
- Inkluderer struktureret logning til overvågning og fejlfinding
- Tilbyder et health check-endpoint til overvågning af servicestatus
Nøglefordele ved FastAPI over traditionelle frameworks:
- Automatisk validering: Pydantic-modeller sikrer data-integritet før behandling
- Interaktive docs: Besøg
/docsfor automatisk genereret, testbar API-dokumentation - Typsikkerhed: Python type hints forebygger runtime-fejl og forbedrer kodekvalitet
- Async support: Håndter flere AI-forespørgsler samtidigt uden blokering
- Ydeevne: Markant hurtigere forespørgselsbehandling til realtidsapplikationer
Forståelse af CORS: Webens sikkerhedsvagt
CORS (Cross-Origin Resource Sharing) er som en sikkerhedsvagt ved en bygning, der tjekker, om besøgende må komme ind. Lad os forstå, hvorfor det betyder noget, og hvordan det påvirker din applikation.
Hvad er CORS, og hvorfor findes det?
Problemet: Forestil dig, at enhver hjemmeside kunne sende forespørgsler til din banks hjemmeside på dine vegne uden din tilladelse. Det ville være et sikkerhedsmareridt! Browsere forhindrer dette som standard gennem "Same-Origin Policy."
Same-Origin Policy: Browsere tillader kun, at websider sender forespørgsler til samme domæne, port og protokol, som de blev indlæst fra.
Virkelighedslignelse: Det er som sikkerheden i en lejlighedsbygning – kun beboere (samme oprindelse) kan som standard komme ind. Vil du lade en ven (anden oprindelse) besøge, skal du eksplicit fortælle sikkerhedsvagten, at det er i orden.
CORS i dit udviklingsmiljø
Under udvikling kører din frontend og backend på forskellige porte:
- Frontend:
http://localhost:3000(eller file:// hvis HTML åbnes direkte) - Backend:
http://localhost:5000
Disse betragtes som "forskellige oprindelser," selvom de kører på samme computer!
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI(__name__)
CORS(app) # Dette fortæller browsere: "Det er i orden, at andre oprindelser foretager forespørgsler til dette API"
Hvad CORS-konfiguration gør i praksis:
- Tilføjer særlige HTTP-headere til API-svar, der fortæller browsere "denne cross-origin-forespørgsel er tilladt"
- Håndterer "preflight" forespørgsler (browsere tjekker nogle gange tilladelser, før den egentlige forespørgsel sendes)
- Forhindrer den frygtede fejlkode "blokeret af CORS-politik" i din browserkonsol
CORS-sikkerhed: Udvikling vs produktion
# 🚨 Udvikling: Tillader ALLE oprindelser (praktisk men usikkert)
CORS(app)
# ✅ Produktion: Tillad kun dit specifikke frontend-domæne
CORS(app, origins=["https://yourdomain.com", "https://www.yourdomain.com"])
# 🔒 Avanceret: Forskellige oprindelser for forskellige miljøer
if app.debug: # Udviklingstilstand
CORS(app, origins=["http://localhost:3000", "http://127.0.0.1:3000"])
else: # Produktionstilstand
CORS(app, origins=["https://yourdomain.com"])
Hvorfor det betyder noget: I udvikling er CORS(app) som at lade din hoveddør stå ulåst – bekvemt, men ikke sikkert. I produktion vil du specificere præcis hvilke hjemmesider, der må tale med din API.
Almindelige CORS-scenarier og løsninger
| Scenario | Problem | Løsning |
|---|---|---|
| Lokal udvikling | Frontend kan ikke nå backend | Tilføj CORSMiddleware til FastAPI |
| GitHub Pages + Heroku | Udrullet frontend kan ikke nå API | Tilføj din GitHub Pages URL til CORS oprindelser |
| Custom domæne | CORS-fejl i produktion | Opdater CORS oprindelser til at matche dit domæne |
| Mobilapp | App kan ikke nå web-API | Tilføj dit apps domæne eller brug * med omhu |
Pro tip: Du kan tjekke CORS-headere i browserens udviklerværktøjer under fanen Netværk. Kig efter headere som Access-Control-Allow-Origin i svaret.
Fejlhåndtering og validering
Bemærk, hvordan vores API inkluderer korrekt fejlhåndtering:
# Bekræft, at vi har modtaget en besked
if not message:
return jsonify({"error": "Message field is required"}), 400
Nøgleprincipper for validering:
- Tjekker for påkrævede felter før behandling af forespørgsler
- Returnerer meningsfulde fejlbeskeder i JSON-format
- Bruger passende HTTP-statuskoder (400 for dårlige forespørgsler)
- Giver klar feedback, der hjælper frontend-udviklere med at debugge problemer
Opsætning og kørsel af din backend
Nu hvor vi har AI-integration og FastAPI-server klar, lad os få det hele til at køre. Opsætningsprocessen involverer installation af Python-afhængigheder, konfiguration af miljøvariabler og start af din udviklingsserver.
Python-miljøopsætning
Lad os opsætte dit Python-udviklingsmiljø. Virtuelle miljøer er som Manhattan-projektets afdelte tilgang – hvert projekt får sin egen isolerede plads med specifikke værktøjer og afhængigheder, som forhindrer konflikter mellem projekter.
# Gå til din backend-mappe
cd backend
# Opret et virtuelt miljø (som at oprette et rengøringsrum til dit projekt)
python -m venv venv
# Aktivér det (Linux/Mac)
source ./venv/bin/activate
# På Windows, brug:
# venv\Scripts\activate
# Installer det gode stuff
pip install openai fastapi uvicorn python-dotenv
Hvad vi lige gjorde:
- Oprettede vores egen lille Python-boble, hvor vi kan installere pakker uden at påvirke andet
- Aktiverede den, så terminalen ved at bruge dette specifikke miljø
- Installerede det væsentlige: OpenAI til AI-magi, FastAPI til vores web-API, Uvicorn til faktisk at køre den, og python-dotenv til sikker håndtering af hemmeligheder
Nøgletillæg forklaret:
- FastAPI: Moderne, hurtigt web-framework med automatisk API-dokumentation
- Uvicorn: Lynhurtig ASGI-server, der kører FastAPI-applikationer
- OpenAI: Officiel bibliotek til GitHub Models og OpenAI API-integration
- python-dotenv: Sikker indlæsning af miljøvariabler fra .env-filer
Miljøkonfiguration: Hold hemmeligheder sikre
Før vi starter API'en, skal vi tale om en af de vigtigste lektioner i webudvikling: hvordan man faktisk holder sine hemmeligheder hemmelige. Miljøvariabler er som et sikkert pengeskab, som kun din applikation har adgang til.
Hvad er miljøvariabler?
Tænk på miljøvariabler som en sikkerhedsboks – du lægger dine værdifulde ting deri, og kun du (og din app) har nøglen til at få dem ud. I stedet for at skrive følsomme oplysninger direkte i koden (hvor bogstaveligt talt alle kan se dem), opbevarer du dem sikkert i miljøet.
Her er forskellen:
- Den forkerte måde: Skrive din adgangskode på en seddel og sætte den på din skærm
- Den rigtige måde: Holde din adgangskode i en sikker adgangskodehåndtering, som kun du kan tilgå
Hvorfor miljøvariabler betyder noget
# 🚨 GØR ALDRIG DETTE - API-nøgle synlig for alle
client = OpenAI(
api_key="ghp_1234567890abcdef...", # Alle kan stjæle denne!
base_url="https://models.github.ai/inference"
)
# ✅ GØR DETTE - API-nøgle gemt sikkert
client = OpenAI(
api_key=os.environ["GITHUB_TOKEN"], # Kun din app kan få adgang til denne
base_url="https://models.github.ai/inference"
)
Hvad der sker, når du hardcoder hemmeligheder:
- Versionskontrol-eksponering: Alle med adgang til dit Git-repository ser din API-nøgle
- Offentlige repositories: Hvis du pusher til GitHub, er din nøgle synlig for hele internettet
- Teamdeling: Andre udviklere på projektet får adgang til din personlige API-nøgle
- Sikkerhedsbrud: Hvis nogen stjæler din API-nøgle, kan de bruge dine AI-kreditter
Opsætning af din miljøfil
Opret en .env-fil i din backend-mappe. Denne fil gemmer dine hemmeligheder lokalt:
# .env fil - Denne bør ALDRIG committes til Git
GITHUB_TOKEN=your_github_personal_access_token_here
FASTAPI_DEBUG=True
ENVIRONMENT=development
Forståelse af .env-filen:
- Én hemmelighed per linje i formatet
KEY=value - Ingen mellemrum omkring lighedstegnet
- Ingen citationstegn nødvendigt omkring værdier (som regel)
- Kommentarer starter med
#
Oprettelse af dit GitHub Personlige Adgangstoken
Dit GitHub-token er som en særlig adgangskode, der giver din applikation tilladelse til at bruge GitHubs AI-tjenester:
Trin-for-trin tokenoprettelse:
- Gå til GitHub Settings → Developer settings → Personal access tokens → Tokens (classic)
- Klik på "Generate new token (classic)"
- Sæt udløbsdato (30 dage til test, længere til produktion)
- Vælg scopes: Marker "repo" og eventuelle andre nødvendige tilladelser
- Generer token og kopier det med det samme (det kan ikke ses igen!)
- Indsæt i din .env-fil
# Eksempel på hvordan dit token ser ud (dette er falsk!)
GITHUB_TOKEN=ghp_1A2B3C4D5E6F7G8H9I0J1K2L3M4N5O6P7Q8R
Indlæsning af miljøvariabler i Python
import os
from dotenv import load_dotenv
# Indlæs miljøvariabler fra .env-fil
load_dotenv()
# Nu kan du få adgang til dem sikkert
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"
)
Hvad denne kode gør:
- Indlæser din .env-fil og gør variabler tilgængelige i Python
- Tjekker om det nødvendige token findes (god fejlhåndtering!)
- Kaster en klar fejl, hvis token mangler
- Bruger token sikkert uden at eksponere det i koden
Git-sikkerhed: .gitignore-filen
Din .gitignore-fil fortæller Git, hvilke filer der aldrig skal trackes eller uploades:
# .gitignore - Tilføj disse linjer
.env
*.env
.env.local
.env.production
__pycache__/
venv/
.vscode/
Hvorfor det er afgørende: Når du tilføjer .env til .gitignore, ignorerer Git din miljøfil og forhindrer, at du utilsigtet uploader dine hemmeligheder til GitHub.
Forskellige miljøer, forskellige hemmeligheder
Professionelle applikationer bruger forskellige API-nøgler til forskellige miljøer:
# .env.udvikling
GITHUB_TOKEN=your_development_token
DEBUG=True
# .env.produktion
GITHUB_TOKEN=your_production_token
DEBUG=False
Hvorfor det betyder noget: Du vil undgå, at dine udviklingseksperimenter påvirker din produktions AI-brugsgrænse, og du ønsker forskellige sikkerhedsniveauer for forskellige miljøer.
Start af din udviklingsserver: Giv liv til din FastAPI
Nu kommer det spændende øjeblik – at starte din FastAPI-udviklingsserver og se din AI-integration blive levende! FastAPI bruger Uvicorn, en lynhurtig ASGI-server, der er specielt designet til asynkrone Python-applikationer.
Forståelse af FastAPI-serverens opstartsproces
# Metode 1: Direkte Python-udførelse (inkluderer automatisk genindlæsning)
python api.py
# Metode 2: Brug af Uvicorn direkte (mere kontrol)
uvicorn api:app --host 0.0.0.0 --port 5000 --reload
Når du kører denne kommando, sker følgende bag kulisserne:
1. Python loader din FastAPI-applikation:
- Importerer alle nødvendige biblioteker (FastAPI, Pydantic, OpenAI osv.)
- Loader miljøvariabler fra din
.env-fil - Opretter FastAPI-applikationsinstansen med automatisk dokumentation
2. Uvicorn konfigurerer ASGI-serveren:
- Binder til port 5000 med asynkron anmodningshåndtering
- Sætter anmodningsrouting op med automatisk validering
- Aktiverer hot reload til udvikling (genstarter ved filændringer)
- Genererer interaktiv API-dokumentation
3. Serveren begynder at lytte:
- Din terminal viser:
INFO: Uvicorn running on http://0.0.0.0:5000 - Serveren kan håndtere flere samtidige AI-forespørgsler
- Din API er klar med automatisk dokumentation på
http://localhost:5000/docs
Hvad du bør se, når alt fungerer
$ 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.
Forståelse af FastAPI-uddata:
- Vil overvåge ændringer: Auto-reload aktiveret til udvikling
- Uvicorn kører: Højtydende ASGI-server er aktiv
- Starter genloader-processen: Filovervågning til automatisk genstart
- Applikationsstart fuldført: FastAPI-app initialiseret med succes
- Interaktive docs tilgængelige: Besøg
/docsfor automatisk API-dokumentation
Test af din FastAPI: Flere kraftfulde tilgange
FastAPI tilbyder flere praktiske måder at teste din API på, inklusiv automatisk interaktiv dokumentation:
Metode 1: Interaktiv API-dokumentation (Anbefalet)
- Åbn din browser og gå til
http://localhost:5000/docs - Du vil se Swagger UI med alle dine endpoints dokumenteret
- Klik på
/hello→ "Try it out" → Indtast en testbesked → "Execute" - Se svaret direkte i browseren med korrekt formatering
Metode 2: Grundlæggende browser-test
- Gå til
http://localhost:5000for roden af endpoint - Gå til
http://localhost:5000/healthfor at tjekke serverens helbred - Dette bekræfter, at din FastAPI-server kører korrekt
Metode 2: Kommandolinjetest (Avanceret)
# Test med curl (hvis tilgængelig)
curl -X POST http://localhost:5000/hello \
-H "Content-Type: application/json" \
-d '{"message": "Hello AI!"}'
# Forventet svar:
# {"response": "Hej! Jeg er din AI-assistent. Hvordan kan jeg hjælpe dig i dag?"}
Metode 3: Python-testscripts
# test_api.py - Opret denne fil for at teste din API
import requests
import json
# Test API-endpointet
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)
Fejlfinding af almindelige opstartsproblemer
| Fejlmeddelelse | Hvad det betyder | Hvordan du løser det |
|---|---|---|
ModuleNotFoundError: No module named 'fastapi' |
FastAPI ikke installeret | Kør pip install fastapi uvicorn i dit virtuelle miljø |
ModuleNotFoundError: No module named 'uvicorn' |
ASGI-server ikke installeret | Kør pip install uvicorn i dit virtuelle miljø |
KeyError: 'GITHUB_TOKEN' |
Miljøvariabel ikke fundet | Tjek din .env-fil og load_dotenv()-opkald |
Address already in use |
Port 5000 er optaget | Stop andre processer, der bruger port 5000, eller skift port |
ValidationError |
Anmodningsdata matcher ikke Pydantic-modellen | Tjek at din anmodning matcher den forventede skema |
HTTPException 422 |
Ubehandlingsbar enhed | Anmodningsvalidering fejlede, tjek /docs for korrekt format |
OpenAI API error |
AI-serviceens autentificering fejlede | Bekræft at din GitHub-token er korrekt og har rette tilladelser |
Udviklingsbest practices
Hot Reloading: FastAPI med Uvicorn tilbyder automatisk genindlæsning, når du gemmer ændringer i dine Python-filer. Det betyder, at du kan ændre din kode og teste med det samme uden manuelt at genstarte.
# Aktivér hot reloading eksplicit
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000, debug=True) # debug=True aktiverer hot reload
Logging til udvikling: Tilføj logging for at forstå, hvad der sker:
import logging
# Opsæt logning
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
Hvorfor logging hjælper: Under udvikling kan du se præcis hvilke forespørgsler, der kommer ind, hvad AI’en svarer med, og hvor fejl opstår. Det gør fejlfinding meget hurtigere.
Konfiguration til GitHub Codespaces: Skyudvikling gjort nemt
GitHub Codespaces er som en kraftfuld udviklingscomputer i skyen, som du kan tilgå fra enhver browser. Hvis du arbejder i Codespaces, er der et par ekstra trin for at gøre din backend tilgængelig for dit frontend.
Forståelse af netværket i Codespaces
I et lokalt udviklingsmiljø kører alt på samme computer:
- Backend:
http://localhost:5000 - Frontend:
http://localhost:3000(eller file://)
I Codespaces kører dit udviklingsmiljø på GitHubs servere, så "localhost" har en anden betydning. GitHub opretter automatisk offentlige URL’er til dine tjenester, men du skal konfigurere dem korrekt.
Trin-for-trin Codespaces-konfiguration
1. Start din backend-server:
cd backend
python api.py
Du vil se den velkendte FastAPI/Uvicorn opstartsmeddelelse, men bemærk, at den kører inde i Codespace-miljøet.
2. Konfigurer port-synlighed:
- Kig efter fanen "Ports" i nederste panel i VS Code
- Find port 5000 på listen
- Højreklik på port 5000
- Vælg "Port Visibility" → "Public"
Hvorfor gøre den offentlig? Som standard er Codespace-porte private (kun tilgængelige for dig). At gøre den offentlig tillader, at dit frontend (som kører i browseren) kan kommunikere med din backend.
3. Få din offentlige URL: Efter at have gjort porten offentlig, vil du se en URL som:
https://your-codespace-name-5000.app.github.dev
4. Opdater din frontend-konfiguration:
// I din frontend app.js, opdater BASE_URL:
this.BASE_URL = "https://your-codespace-name-5000.app.github.dev";
Forståelse af Codespace-URL’er
Codespace-URL’er følger et forudsigeligt mønster:
https://[codespace-name]-[port].app.github.dev
Nedbrudt i dele:
codespace-name: En unik identifikator for din Codespace (ofte inkluderer dit brugernavn)port: Portnummer, som din service kører på (5000 for vores FastAPI-app)app.github.dev: GitHubs domæne for Codespace-applikationer
Test af din Codespace-opsætning
1. Test backenden direkte: Åbn din offentlige URL i en ny browsertab. Du bør se:
Welcome to the AI Chat API. Send POST requests to /hello with JSON payload containing 'message' field.
2. Test med browserens udviklerværktøjer:
// Åbn browserkonsollen og test din 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 Lokal udvikling
| Aspekt | Lokal udvikling | GitHub Codespaces |
|---|---|---|
| Opsætningstid | Længere (installer Python, afhængigheder) | Øjeblikkelig (forudkonfigureret miljø) |
| URL-adgang | http://localhost:5000 |
https://xyz-5000.app.github.dev |
| Portkonfiguration | Automatisk | Manuel (gør porte offentlige) |
| Filpersistens | Lokal maskine | GitHub repository |
| Samarbejde | Vanskeligt at dele miljø | Let at dele Codespace-link |
| Internetafhængighed | Kun til AI API-kald | Krævet til alt |
Tips til udvikling i Codespace
Miljøvariabler i Codespaces:
Din .env-fil fungerer på samme måde i Codespaces, men du kan også sætte miljøvariabler direkte i Codespace:
# Indstil miljøvariabel for den aktuelle session
export GITHUB_TOKEN="your_token_here"
# Eller tilføj til din .bashrc for vedvarende effekt
echo 'export GITHUB_TOKEN="your_token_here"' >> ~/.bashrc
Portstyring:
- Codespaces registrerer automatisk, når din applikation begynder at lytte på en port
- Du kan videresende flere porte samtidigt (nyttigt, hvis du senere tilføjer en database)
- Porte forbliver tilgængelige, så længe din Codespace kører
Udviklingsworkflow:
- Foretag kodeændringer i VS Code
- FastAPI genindlæses automatisk (takket være Uvicorns reload-tilstand)
- Test ændringer øjeblikkeligt via den offentlige URL
- Commit og push, når du er klar
💡 Pro tip: Bogmærk din Codespace backend-URL under udvikling. Da Codespace-navne er stabile, vil URL’en ikke ændre sig, så længe du bruger samme Codespace.
Opret frontend chat-interface: Hvor mennesker møder AI
Nu bygger vi brugergrænsefladen – den del, der bestemmer, hvordan folk interagerer med din AI-assistent. Ligesom designet af den oprindelige iPhone-grænseflade fokuserer vi på at gøre kompleks teknologi intuitiv og naturlig at bruge.
Forståelse af moderne frontend-arkitektur
Vores chat-interface bliver det, vi kalder en “Single Page Application” eller SPA. I stedet for den gammeldags tilgang, hvor hvert klik indlæser en ny side, opdaterer vores app glat og øjeblikkeligt:
Gamle hjemmesider: Som at læse en fysisk bog – du bladre til helt nye sider
Vores chat-app: Som at bruge din telefon – alt flyder og opdateres gnidningsfrit
graph TD
A[Bruger skriver besked] --> B[JavaScript fanger input]
B --> C[Valider og formater data]
C --> D[Send til backend API]
D --> E[Vis indlæsningsstatus]
E --> F[Modtag AI-svar]
F --> G[Opdater chatgrænseflade]
G --> H[Klar til næste besked]
classDiagram
class ChatApp {
+beskeder: HTMLElement
+formular: HTMLElement
+input: HTMLElement
+sendKnap: HTMLElement
+BASE_URL: string
+API_ENDPOINT: string
+constructor()
+initialiserEventLyttere()
+håndterIndsendelse(event)
+kaldAPI(besked)
+tilføjBesked(tekst, rolle)
+escapeHtml(tekst)
+rulTilBund()
+sætIndlæsning(erIndlæser)
}
ChatApp --> DOM : manipulerer
ChatApp --> FastAPI : sender forespørgsler
De tre søjler i frontend-udvikling
Enhver frontend-applikation – fra simple websites til komplekse apps som Discord eller Slack – er bygget på tre kerne-teknologier. Tænk på dem som fundamentet for alt, du ser og interagerer med på webben:
HTML (Struktur): Dette er dit fundament
- Bestemmer, hvilke elementer der findes (knapper, tekstområder, containere)
- Giver mening til indholdet (dette er en overskrift, dette er en formular osv.)
- Skaber den grundlæggende struktur, som alt andet bygger på
CSS (Præsentation): Dette er din indretningsarkitekt
- Får alt til at se smukt ud (farver, skrifttyper, layout)
- Håndterer forskellige skærmstørrelser (mobil, laptop, tablet)
- Skaber bløde animationer og visuel feedback
JavaScript (Adfærd): Dette er din hjerne
- Reagerer på brugerhandlinger (klik, skrivning, scroll)
- Kommunikerer med din backend og opdaterer siden
- Gør alting interaktivt og dynamisk
Tænk på det som arkitektonisk design:
- HTML: Det strukturelle blueprint (definerer rum og forhold)
- CSS: Det æstetiske og miljømæssige design (visuel stil og brugeroplevelse)
- JavaScript: De mekaniske systemer (funktionalitet og interaktivitet)
Hvorfor moderne JavaScript-arkitektur er vigtigt
Vores chat-applikation vil bruge moderne JavaScript-mønstre, som du vil se i professionelle applikationer. At forstå disse koncepter hjælper dig som udvikler:
Klasselignende arkitektur: Vi organiserer vores kode i klasser, som at lave blueprints til objekter
Async/Await: Moderne måde at håndtere operationer, der tager tid (f.eks. API-kald)
Event-drevet programmering: Vores app reagerer på brugerhandlinger (klik, tastetryk) fremfor at køre i en løkke
DOM-manipulation: Dynamisk opdatering af websides indhold baseret på brugerinteraktioner og API-respons
Projektstrukturopsætning
Opret en frontend-mappe med denne organiserede struktur:
frontend/
├── index.html # Main HTML structure
├── app.js # JavaScript functionality
└── styles.css # Visual styling
Forstå arkitekturen:
- Adskiller bekymringer mellem struktur (HTML), adfærd (JavaScript) og præsentation (CSS)
- Bevarer en enkel filstruktur, som er let at navigere og ændre
- Følger bedste webudviklingspraksis for organisering og vedligeholdelse
Opbygning af HTML-fundamentet: Semantisk struktur for tilgængelighed
Lad os starte med HTML-strukturen. Moderne webudvikling fremhæver “semantisk HTML” – brugen af HTML-elementer, der klart beskriver deres formål, ikke kun deres udseende. Det gør din applikation tilgængelig for skærmlæsere, søgemaskiner og andre værktøjer.
Hvorfor semantisk HTML er vigtigt: Forestil dig, at du skulle beskrive din chat-app til en person over telefonen. Du ville sige “der er en header med titlen, et hovedområde hvor samtaler vises, og en formular nederst til at skrive beskeder.” Semantisk HTML bruger elementer, der matcher denne naturlige beskrivelse.
Opret index.html med denne gennemtænkte markup:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AI Chat Assistant</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="chat-container">
<header class="chat-header">
<h1>AI Chat Assistant</h1>
<p>Ask me anything!</p>
</header>
<main class="chat-messages" id="messages" role="log" aria-live="polite">
<!-- Messages will be dynamically added here -->
</main>
<form class="chat-form" id="chatForm">
<div class="input-group">
<input
type="text"
id="messageInput"
placeholder="Type your message here..."
required
aria-label="Chat message input"
>
<button type="submit" id="sendBtn" aria-label="Send message">
Send
</button>
</div>
</form>
</div>
<script src="app.js"></script>
</body>
</html>
Forståelse af hvert HTML-element og dets formål:
Dokumentstruktur
<!DOCTYPE html>: Fortæller browseren, at dette er moderne HTML5<html lang="en">: Angiver sidens sprog for skærmlæsere og oversættelsesværktøjer<meta charset="UTF-8">: Sikrer korrekt tegnkodning til international tekst<meta name="viewport"...>: Gør siden mobilresponsiv ved at styre zoom og skala
Semantiske elementer
<header>: Klart definerer topsektionen med titel og beskrivelse<main>: Angiver hovedindholdsområdet (hvor samtaler foregår)<form>: Semantisk korrekt til brugerinput, muliggør ordentlig tastaturnavigation
Tilgængelighedsfunktioner
role="log": Fortæller skærmlæsere at dette område indeholder en kronologisk log af beskederaria-live="polite": Annoncerer nye beskeder til skærmlæsere uden at afbrydearia-label: Giver beskrivende labels til formularstyringerrequired: Browser validerer, at brugerne indtaster en besked før afsendelse
CSS- og JavaScript-integration
class-attributter: Tilbyder styling-kroge til CSS (f.eks.chat-container,input-group)id-attributter: Gør det muligt for JavaScript at finde og manipulere specifikke elementer- Script-placering: JavaScript-fil indlæses til sidst, så HTML først kan loades
Hvorfor denne struktur virker:
- Logisk flow: Header → Hovedindhold → Indtastningsformular matcher naturlig læseretning
- Tastaturnavigerbar: Brugere kan tabbe igennem alle interaktive elementer
- Skærmlæservenlig: Klare pejlemærker og beskrivelser til brugere med synshandicap
- Mobilresponsiv: Viewport-meta-tag muliggør responsivt design
- Progressiv forbedring: Fungerer selvom CSS eller JavaScript ikke loader
Tilføj interaktiv JavaScript: Moderne webapplikationslogik
Nu bygger vi JavaScript, som bringer vores chatgrænseflade til live. Vi vil bruge moderne JavaScript-mønstre, som du vil møde i professionel webudvikling, inklusive ES6-klasser, async/await og event-drevet programmering.
Forståelse af Moderne JavaScript-arkitektur
I stedet for at skrive procedurekode (en række funktioner, der kører i rækkefølge), vil vi skabe en klassebaseret arkitektur. Tænk på en klasse som en blåkopi til at skabe objekter – ligesom en arkitekts plantegning kan bruges til at bygge flere huse.
Hvorfor bruge klasser til webapplikationer?
- Organisation: Al relateret funktionalitet er samlet
- Genanvendelighed: Du kan oprette flere chatinstanser på samme side
- Vedligeholdelse: Nemmere at debugge og ændre specifikke funktioner
- Professionel standard: Dette mønster bruges i frameworks som React, Vue og Angular
Opret app.js med dette moderne, velstrukturerede JavaScript:
// app.js - Moderne chatapplikationslogik
class ChatApp {
constructor() {
// Få referencer til DOM-elementer, vi skal manipulere med
this.messages = document.getElementById("messages");
this.form = document.getElementById("chatForm");
this.input = document.getElementById("messageInput");
this.sendButton = document.getElementById("sendBtn");
// Konfigurer din backend-URL her
this.BASE_URL = "http://localhost:5000"; // Opdater dette til dit miljø
this.API_ENDPOINT = `${this.BASE_URL}/hello`;
// Opsæt event-lyttere, når chat-appen oprettes
this.initializeEventListeners();
}
initializeEventListeners() {
// Lyt efter formularindsendelse (når brugeren klikker Send eller trykker Enter)
this.form.addEventListener("submit", (e) => this.handleSubmit(e));
// Lyt også efter Enter-tasten i inputfeltet (bedre brugeroplevelse)
this.input.addEventListener("keypress", (e) => {
if (e.key === "Enter" && !e.shiftKey) {
e.preventDefault();
this.handleSubmit(e);
}
});
}
async handleSubmit(event) {
event.preventDefault(); // Forhindre at formularen opdaterer siden
const messageText = this.input.value.trim();
if (!messageText) return; // Send ikke tomme beskeder
// Giv brugeren feedback om, at noget sker
this.setLoading(true);
// Tilføj brugerbesked til chatten med det samme (optimistisk UI)
this.appendMessage(messageText, "user");
// Ryd inputfeltet, så brugeren kan skrive næste besked
this.input.value = '';
try {
// Kald AI API'et og vent på svar
const reply = await this.callAPI(messageText);
// Tilføj AI-svar til chatten
this.appendMessage(reply, "assistant");
} catch (error) {
console.error('API Error:', error);
this.appendMessage("Sorry, I'm having trouble connecting right now. Please try again.", "error");
} finally {
// Aktivér interfacet igen uanset succes eller fejl
this.setLoading(false);
}
}
async callAPI(message) {
const response = await fetch(this.API_ENDPOINT, {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({ message })
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
return data.response;
}
appendMessage(text, role) {
const messageElement = document.createElement("div");
messageElement.className = `message ${role}`;
messageElement.innerHTML = `
<div class="message-content">
<span class="message-text">${this.escapeHtml(text)}</span>
<span class="message-time">${new Date().toLocaleTimeString()}</span>
</div>
`;
this.messages.appendChild(messageElement);
this.scrollToBottom();
}
escapeHtml(text) {
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
scrollToBottom() {
this.messages.scrollTop = this.messages.scrollHeight;
}
setLoading(isLoading) {
this.sendButton.disabled = isLoading;
this.input.disabled = isLoading;
this.sendButton.textContent = isLoading ? "Sending..." : "Send";
}
}
// Initialiser chatapplikationen, når siden indlæses
document.addEventListener("DOMContentLoaded", () => {
new ChatApp();
});
Forståelse af hvert JavaScript-koncept
ES6 Klasse Struktur:
class ChatApp {
constructor() {
// Dette kører, når du opretter en ny ChatApp instans
// Det er som "setup" funktionen for din chat
}
methodName() {
// Metoder er funktioner, der tilhører klassen
// De kan få adgang til klasseegenskaber ved hjælp af "this"
}
}
Async/Await Mønster:
// Gammel måde (callback-helvede):
fetch(url)
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error));
// Moderne måde (async/await):
try {
const response = await fetch(url);
const data = await response.json();
console.log(data);
} catch (error) {
console.error(error);
}
Event-drevet Programmering: I stedet for konstant at tjekke om noget skete, "lytter" vi efter events:
// Når formularen indsendes, kør handleSubmit
this.form.addEventListener("submit", (e) => this.handleSubmit(e));
// Når Enter-tasten trykkes, kør også handleSubmit
this.input.addEventListener("keypress", (e) => { /* ... */ });
DOM-manipulation:
// Opret nye elementer
const messageElement = document.createElement("div");
// Ændr deres egenskaber
messageElement.className = "message user";
messageElement.innerHTML = "Hello world!";
// Tilføj til siden
this.messages.appendChild(messageElement);
Sikkerhed og Bedste Praksis
XSS Forebyggelse:
escapeHtml(text) {
const div = document.createElement('div');
div.textContent = text; // Dette undslipper automatisk HTML
return div.innerHTML;
}
Hvorfor det er vigtigt: Hvis en bruger skriver <script>alert('hack')</script>, sikrer denne funktion, at det vises som tekst og ikke kører som kode.
Fejlhåndtering:
try {
const reply = await this.callAPI(messageText);
this.appendMessage(reply, "assistant");
} catch (error) {
// Vis en brugervenlig fejl i stedet for at få appen til at gå ned
this.appendMessage("Sorry, I'm having trouble...", "error");
}
Brugeroplevelses-Overvejelser:
- Optimistisk UI: Tilføj brugerbesked med det samme, vent ikke på serversvar
- Indlæsningsstatus: Deaktiver knapper og vis "Sender..." mens der ventes
- Auto-scroll: Hold de nyeste beskeder synlige
- Inputvalidering: Send ikke tomme beskeder
- Genvejstaster: Enter-tast sender beskeder (som i rigtige chat-apps)
Forståelse af Applikationsflowet
- Siden loader →
DOMContentLoadedevent affyres →new ChatApp()oprettes - Konstruktør kører → Henter DOM-elementreferencer → Sætter event-lyttere op
- Bruger skriver besked → Trykker Enter eller klikker Send →
handleSubmitkører - handleSubmit → Validerer input → Viser indlæsningsstatus → Kalder API
- API svarer → Tilføjer AI-besked til chat → Genaktiverer interface
- Klar til næste besked → Brugeren kan fortsætte med at chatte
Denne arkitektur er skalerbar – du kan nemt tilføje funktioner som beskedredigering, filuploads eller flere samtaletråde uden at omskrive kerne-strukturen.
🎯 Pædagogisk Tjek-ind: Moderne Frontend Arkitektur
Forståelse af Arkitekturen: Du har implementeret en komplet single-page applikation med moderne JavaScript-mønstre. Dette repræsenterer professionelt frontend-udviklingsniveau.
Nøglekoncepter Mestret:
- ES6 Klassearkitektur: Organiseret, vedligeholdelsesvenlig kodestruktur
- Async/Await Mønstre: Moderne asynkron programmering
- Event-drevet Programmering: Responsivt brugergrænsefladedesign
- Sikkerheds bedste praksis: XSS-forebyggelse og inputvalidering
Brancheforbindelse: Mønstrene du har lært (klassebaseret arkitektur, async-operationer, DOM-manipulation) er fundamentet for moderne frameworks som React, Vue og Angular. Du bygger med samme arkitektoniske tankegang som i produktionsapplikationer.
Refleksionsspørgsmål: Hvordan ville du udvide denne chatapplikation til at håndtere flere samtaler eller brugerautentifikation? Overvej de nødvendige arkitektoniske ændringer og hvordan klassestrukturen ville udvikle sig.
Style Din Chatgrænseflade
Lad os nu skabe en moderne, visuelt tiltalende chatgrænseflade med CSS. God styling får din applikation til at føles professionel og forbedrer den samlede brugeroplevelse. Vi bruger moderne CSS-funktioner som Flexbox, CSS Grid og brugerdefinerede egenskaber for et responsivt, tilgængeligt design.
Opret styles.css med disse omfattende styles:
/* styles.css - Modern chat interface styling */
:root {
--primary-color: #2563eb;
--secondary-color: #f1f5f9;
--user-color: #3b82f6;
--assistant-color: #6b7280;
--error-color: #ef4444;
--text-primary: #1e293b;
--text-secondary: #64748b;
--border-radius: 12px;
--shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 20px;
}
.chat-container {
width: 100%;
max-width: 800px;
height: 600px;
background: white;
border-radius: var(--border-radius);
box-shadow: var(--shadow);
display: flex;
flex-direction: column;
overflow: hidden;
}
.chat-header {
background: var(--primary-color);
color: white;
padding: 20px;
text-align: center;
}
.chat-header h1 {
font-size: 1.5rem;
margin-bottom: 5px;
}
.chat-header p {
opacity: 0.9;
font-size: 0.9rem;
}
.chat-messages {
flex: 1;
padding: 20px;
overflow-y: auto;
display: flex;
flex-direction: column;
gap: 15px;
background: var(--secondary-color);
}
.message {
display: flex;
max-width: 80%;
animation: slideIn 0.3s ease-out;
}
.message.user {
align-self: flex-end;
}
.message.user .message-content {
background: var(--user-color);
color: white;
border-radius: var(--border-radius) var(--border-radius) 4px var(--border-radius);
}
.message.assistant {
align-self: flex-start;
}
.message.assistant .message-content {
background: white;
color: var(--text-primary);
border-radius: var(--border-radius) var(--border-radius) var(--border-radius) 4px;
border: 1px solid #e2e8f0;
}
.message.error .message-content {
background: var(--error-color);
color: white;
border-radius: var(--border-radius);
}
.message-content {
padding: 12px 16px;
box-shadow: var(--shadow);
position: relative;
}
.message-text {
display: block;
line-height: 1.5;
word-wrap: break-word;
}
.message-time {
display: block;
font-size: 0.75rem;
opacity: 0.7;
margin-top: 5px;
}
.chat-form {
padding: 20px;
border-top: 1px solid #e2e8f0;
background: white;
}
.input-group {
display: flex;
gap: 10px;
align-items: center;
}
#messageInput {
flex: 1;
padding: 12px 16px;
border: 2px solid #e2e8f0;
border-radius: var(--border-radius);
font-size: 1rem;
outline: none;
transition: border-color 0.2s ease;
}
#messageInput:focus {
border-color: var(--primary-color);
}
#messageInput:disabled {
background: #f8fafc;
opacity: 0.6;
cursor: not-allowed;
}
#sendBtn {
padding: 12px 24px;
background: var(--primary-color);
color: white;
border: none;
border-radius: var(--border-radius);
font-size: 1rem;
font-weight: 600;
cursor: pointer;
transition: background-color 0.2s ease;
min-width: 80px;
}
#sendBtn:hover:not(:disabled) {
background: #1d4ed8;
}
#sendBtn:disabled {
background: #94a3b8;
cursor: not-allowed;
}
@keyframes slideIn {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* Responsive design for mobile devices */
@media (max-width: 768px) {
body {
padding: 10px;
}
.chat-container {
height: calc(100vh - 20px);
border-radius: 8px;
}
.message {
max-width: 90%;
}
.input-group {
flex-direction: column;
gap: 10px;
}
#messageInput {
width: 100%;
}
#sendBtn {
width: 100%;
}
}
/* Accessibility improvements */
@media (prefers-reduced-motion: reduce) {
.message {
animation: none;
}
* {
transition: none !important;
}
}
/* Dark mode support */
@media (prefers-color-scheme: dark) {
.chat-container {
background: #1e293b;
color: #f1f5f9;
}
.chat-messages {
background: #0f172a;
}
.message.assistant .message-content {
background: #334155;
color: #f1f5f9;
border-color: #475569;
}
.chat-form {
background: #1e293b;
border-color: #475569;
}
#messageInput {
background: #334155;
color: #f1f5f9;
border-color: #475569;
}
}
Forståelse af CSS-arkitekturen:
- Bruger CSS-variabler (custom properties) for konsistent tema og nem vedligeholdelse
- Implementerer Flexbox-layout for responsivt design og korrekt justering
- Inkluderer glatte animationer for besked-udseende uden at være forstyrrende
- Giver visuel adskillelse mellem brugerbeskeder, AI-svar og fejltilstande
- Understøtter responsivt design der virker på både desktop og mobil
- Tager højde for tilgængelighed med nedsat bevægelses-præferencer og ordentlige kontrastforhold
- Tilbyder mørk tilstand baseret på brugerens systempræferencer
Konfiguration af Din Backend URL
Det sidste skridt er at opdatere BASE_URL i dit JavaScript, så det matcher din backend-server:
// Til lokal udvikling
this.BASE_URL = "http://localhost:5000";
// Til GitHub Codespaces (erstat med din faktiske URL)
this.BASE_URL = "https://your-codespace-name-5000.app.github.dev";
Bestemmelse af din backend URL:
- Lokal udvikling: Brug
http://localhost:5000, hvis frontend og backend kører lokalt - Codespaces: Find din backend-URL i Ports-fanen efter du har gjort port 5000 offentlig
- Produktion: Erstat med dit faktiske domæne, når du deployer til en hostingtjeneste
💡 Test-tip: Du kan teste din backend direkte ved at besøge rod-URL'en i din browser. Du bør se velkomstbeskeden fra din FastAPI-server.
Test og Deployering
Nu hvor du har både frontend- og backend-komponenter, lad os teste, at alt virker sammen og udforske deployeringsmuligheder for at dele din chatassistent med andre.
Lokal Test Workflow
Følg disse trin for at teste din komplette applikation:
graph TD
A[Start Backend Server] --> B[Konfigurer Miljøvariabler]
B --> C[Test API Endpoints]
C --> D[Åbn Frontend i Browser]
D --> E[Test Chatfunktionalitet]
E --> F[Fejlret Eventuelle Problemer]
Trin-for-trin testproces:
-
Start din backend-server:
cd backend source venv/bin/activate # eller venv\Scripts\activate på Windows python api.py -
Tjek at API’en virker:
- Åbn
http://localhost:5000i din browser - Du skulle gerne se velkomstbeskeden fra din FastAPI-server
- Åbn
-
Åbn din frontend:
- Gå til din frontend-mappe
- Åbn
index.htmli din webbrowser - Eller brug VS Codes Live Server-udvidelse for bedre udviklingsoplevelse
-
Test chat-funktionaliteten:
- Skriv en besked i inputfeltet
- Klik på "Send" eller tryk Enter
- Tjek at AI svarer relevant
- Se browserkonsollen efter eventuelle JavaScript-fejl
Fejlretning af Almindelige Problemer
| Problem | Symptomer | Løsning |
|---|---|---|
| CORS-fejl | Frontend kan ikke nå backend | Sørg for at FastAPIs CORSMiddleware er korrekt konfigureret |
| API-nøglefejl | 401 Unauthorized svar | Tjek din GITHUB_TOKEN miljøvariabel |
| Connection Refused | Netværksfejl i frontend | Bekræft backend-URL og at Flask-serveren kører |
| Ingen AI-respons | Tomme eller fejlsvar | Tjek backend-log for API-kvote- eller autentifikationsproblemer |
Almindelige fejlfindingstrin:
- Tjekker browserens Developer Tools Console for JavaScript-fejl
- Verificerer at Netværksfanen viser succesfulde API-forespørgsler og svar
- Gennemgår backend-terminalens output for Python-fejl eller API-problemer
- Bekræfter at miljøvariabler er korrekt indlæst og tilgængelige
📈 Din AI Applikationsudviklings Mastery Tidslinje
timeline
title Fuldstændig Udviklingsrejse for AI-applikationer
section AI Grundlag
Forstå Generativ AI
: Forstå mønstergenkendelseskoncepter
: Mestre AI parameterkontrol
: Lær prompt engineering teknikker
Integration af GitHub Modeller
: Naviger AI serviceplatforme
: Håndter autentificering sikkert
: Optimer modelparametre
section Backend Udvikling
Python API Arkitektur
: Byg FastAPI applikationer
: Implementer asynkrone operationer
: Skab sikre endpoints
AI Service Integration
: Forbind til eksterne AI API'er
: Håndter rate limiting
: Implementer fejlgraenser
section Frontend Mestring
Moderne JavaScript Mønstre
: Mestre ES6 klassearkitektur
: Implementer async/await flows
: Byg responsive brugerflader
Realtids Brugeroplevelse
: Skab dynamiske chatflader
: Håndter loading tilstande
: Optimer brugerinteraktioner
section Produktion-Klarhed
Sikkerhed & Ydeevne
: Implementer sikker tokenhåndtering
: Forhindr XSS sårbarheder
: Optimer API ydeevne
Professionel Udrulning
: Byg skalerbare arkitekturer
: Skab vedligeholdelsesvenlig kode
: Dokumenter udviklingsprocesser
🎓 Graduationsmilepæl: Du har med succes bygget en komplet AI-drevet applikation ved hjælp af de samme teknologier og arkitektoniske mønstre, der driver moderne AI-assistenter. Disse færdigheder repræsenterer skæringspunktet mellem traditionel webudvikling og banebrydende AI-integration.
🔄 Næste niveau kapaciteter:
- Parat til at udforske avancerede AI-frameworks (LangChain, LangGraph)
- Klædt på til at bygge multimodale AI-applikationer (tekst, billede, stemme)
- Udstyret til at implementere vektordatabaser og søgesystemer
- Fundament lagt for maskinlæring og AI-model finjustering
GitHub Copilot Agent Udfordring 🚀
Brug Agent-tilstand til at løse følgende udfordring:
Beskrivelse: Forbedr chatassistenten ved at tilføje samtalehistorik og beskedvedholdelse. Denne udfordring hjælper dig med at forstå, hvordan man håndterer state i chatapplikationer og implementerer datalagring for bedre brugeroplevelse.
Prompt: Ændr chatapplikationen, så den inkluderer samtalehistorik, der bevares mellem sessioner. Tilføj funktionalitet til at gemme chatbeskeder i local storage, vise samtalehistorik når siden loades, og inkluder en "Ryd Historik"-knap. Implementer også skriveindikatorer og tidsstempler på beskeder for at gøre chatoplevelsen mere realistisk.
Lær mere om agent-tilstand her.
Opgave: Byg Din Personlige AI Assistent
Nu skal du skabe din egen AI-assistent-implementering. I stedet for blot at kopiere tutorial-koden, er dette en mulighed for at anvende koncepterne, mens du bygger noget, der afspejler dine egne interesser og brugssager.
Projektkrav
Lad os sætte dit projekt op med en ren, organiseret struktur:
my-ai-assistant/
├── backend/
│ ├── api.py # Your FastAPI server
│ ├── llm.py # AI integration functions
│ ├── .env # Your secrets (keep this safe!)
│ └── requirements.txt # Python dependencies
├── frontend/
│ ├── index.html # Your chat interface
│ ├── app.js # The JavaScript magic
│ └── styles.css # Make it look amazing
└── README.md # Tell the world about your creation
Kerneimplementeringsopgaver
Backend Udvikling:
- Tag vores FastAPI-kode og gør den til din egen
- Skab en unik AI-personlighed – måske en hjælpsom madlavningsassistent, en kreativ skrivepartner eller en studiekompis?
- Tilføj solid fejlhåndtering, så din app ikke går ned, når der opstår fejl
- Skriv klar dokumentation for alle, der vil forstå hvordan din API virker
Frontend Udvikling:
- Byg en chatgrænseflade der føles intuitiv og imødekommende
- Skriv ren, moderne JavaScript, som du kan være stolt af at vise andre udviklere
- Design skræddersyet styling, der afspejler din AIs personlighed – sjov og farverig? Ren og minimalistisk? Det er op til dig!
- Sørg for at det virker godt på både telefoner og computere
Personliggørelseskrav:
- Vælg et unikt navn og personlighed til din AI-assistent – måske noget, der afspejler dine interesser eller de problemer, du vil løse
- Tilpas det visuelle design, så det matcher din assistents vibe
- Skriv en fængende velkomstbesked, der får folk til at ville starte en samtale
- Test din assistent med forskellige slags spørgsmål og se, hvordan den reagerer
Forslagsidéer til Udvidelser (Valgfrit)
Vil du tage dit projekt til næste niveau? Her er nogle sjove idéer at udforske:
| Funktion | Beskrivelse | Færdigheder du øver |
|---|---|---|
| Beskedhistorik | Husk samtaler selv efter sideopdatering | Arbejde med localStorage, JSON-håndtering |
| Skriveindikatorer | Vis "AI skriver..." mens der ventes på svar | CSS-animationer, async-programmering |
| Beskedtidsstempler | Vis hvornår hver besked blev sendt | Dato/tidsformatering, UX-design |
| Eksportér Chat | Lad brugere downloade deres samtale | Filhåndtering, dataeksport |
| Tema-skift | Skift mellem lys og mørk tilstand | CSS-variabler, brugerpræferencer |
| Stemmeinput | Tilføj tale-til-tekst funktionalitet | Web-API’er, tilgængelighed |
Test og Dokumentation
Kvalitetssikring:
- Test din applikation med forskellige inputtyper og edge cases
- Bekræft at det responsive design virker på forskellige skærmstørrelser
- Tjek tilgængelighed med tastaturnavigation og skærmlæsere
- Valider HTML og CSS for standardoverholdelse
Dokumentationskrav:
- Skriv en README.md, der forklarer dit projekt og hvordan man kører det
- Inkluder screenshots af din chatgrænseflade i brug
- Dokumenter unikke funktioner eller tilpasninger du har tilføjet
- Giv klare opsætningsinstruktioner til andre udviklere
Indsendelsesretningslinjer
Projektleverancer:
- Komplett projektmappe med al kildekode
- README.md med projektbeskrivelse og opsætningsinstruktioner
- Screenshots, der demonstrerer din chatassistent i funktion
- Kort refleksion over hvad du lærte og hvilke udfordringer du stod overfor
Evalueringskriterier:
- Funktionalitet: Virker chatassistenten som forventet?
- Kodekvalitet: Er koden velorganiseret, kommenteret og vedligeholdbar?
- Design: Er interface visuelt tiltalende og brugervenligt?
- Kreativitet: Hvor unik og personlig er din implementering?
- Dokumentation: Er opsætningsinstruktioner klare og fyldestgørende?
💡 Sukcesstip: Start med basis-kravene først, og tilføj så udvidelser, når alt virker. Fokuser på at lave en poleret kerneoplevelse før avancerede features.
Løsning
Bonusudfordringer
Klar til at tage din AI-assistent til næste niveau? Prøv disse avancerede udfordringer, der vil uddybe din forståelse af AI-integration og webudvikling.
Personligheds Tilpasning
Den virkelige magi sker, når du giver din AI-assistent en unik personlighed. Eksperimenter med forskellige systemprompter for at skabe specialiserede assistenter:
Professionel Assistent Eksempel:
call_llm(message, "You are a professional business consultant with 20 years of experience. Provide structured, actionable advice with specific steps and considerations.")
Kreativ Skrivningshjælper Eksempel:
call_llm(message, "You are an enthusiastic creative writing coach. Help users develop their storytelling skills with imaginative prompts and constructive feedback.")
Teknisk Mentor Eksempel:
call_llm(message, "You are a patient senior developer who explains complex programming concepts using simple analogies and practical examples.")
Frontend Forbedringer
Transformer din chatgrænseflade med disse visuelle og funktionelle forbedringer:
Avancerede CSS-funktioner:
- Implementer glatte besked-animationer og overgange
- Tilføj custom chatbobledesign med CSS-former og gradienter
- Skab en skriveindikator-animation til når AI "tænker"
- Design emoji-reaktioner eller beskedbedømmelsessystem
JavaScript-Forbedringer:
- Tilføj tastaturgenveje (Ctrl+Enter for send, Escape for ryd input)
- Implementer søge- og filtreringsfunktionalitet for beskeder
- Skab eksportfunktion for samtaler (download som tekst eller JSON)
- Tilføj autosave til localStorage for at forhindre beskedtab
Avanceret AI-Integration
Flere AI-personligheder:
- Lav en dropdown til at skifte imellem forskellige AI-personligheder
- Gem brugerens foretrukne personlighed i localStorage
- Implementer kontekstskift, der bevarer samtaleflowet
Smartsvar-funktioner:
- Tilføj samtalekontekst-awareness (AI husker tidligere beskeder)
- Implementer smarte forslag baseret på samtaleemne
- Opret hurtige svar-knapper til almindelige spørgsmål
🎯 Læringsmål: Disse bonusudfordringer hjælper dig med at forstå avancerede webudviklingsmønstre og AI-integrationsmetoder, som anvendes i produktionsapplikationer.
Resume og Næste Skridt
Tillykke! Du har med succes bygget en komplet AI-drevet chatassistent fra bunden. Dette projekt har givet dig praksiserfaring med moderne webudviklingsteknologier og AI-integration – færdigheder, der bliver stadig mere værdifulde i dagens teknologilandskab.
Det, Du Har Opnået
I løbet af denne lektion har du mestret flere nøgle-teknologier og koncepter:
Backend-udvikling:
- Integreret med GitHub Models API for AI-funktionalitet
- Bygget en RESTful API ved hjælp af Flask med korrekt fejlhåndtering
- Implementeret sikker autentificering ved brug af miljøvariabler
- Konfigureret CORS for kryds-oprindelses-forespørgsler mellem frontend og backend
Frontend-udvikling:
- Oprettet et responsivt chatinterface med semantisk HTML
- Implementeret moderne JavaScript med async/await og klassebaseret arkitektur
- Designet en engagerende brugerflade med CSS Grid, Flexbox og animationer
- Tilføjet tilgængelighedsfunktioner og principper for responsivt design
Full-Stack Integration:
- Forbundet frontend og backend gennem HTTP API-kald
- Håndteret realtime brugerinteraktioner og asynkron dataflow
- Implementeret fejlhåndtering og brugerfeedback gennem hele applikationen
- Testet den komplette applikationsarbejdsgang fra brugerinput til AI-svar
Væsentlige Læringsudbytter
mindmap
root((AI Chat App Færdigheder))
API Integration
Autentificering
Fejlhåndtering
Asynkron Programmering
Webudvikling
HTML5 Semantik
Moderne CSS
ES6+ JavaScript
Brugeroplevelse
Responsivt Design
Tilgængelighed
Realtidsinteraktion
AI Forståelse
Prompt Ingeniørarbejde
Modelparametre
Samtale Flow
Dette projekt har introduceret dig til grundlæggende principper for at opbygge AI-drevne applikationer, som repræsenterer fremtiden for webudvikling. Du forstår nu, hvordan man integrerer AI-muligheder i traditionelle webapplikationer og skaber engagerende brugeroplevelser, der føles intelligente og responsivrige.
Professionelle Anvendelser
De færdigheder, du har udviklet i denne lektion, er direkte anvendelige i moderne softwareudviklingskarrierer:
- Full-stack webudvikling med moderne frameworks og API’er
- AI-integration i webapplikationer og mobilapps
- API-design og -udvikling til mikrotjenestearkitekturer
- Brugergrænsefladeudvikling med fokus på tilgængelighed og responsivt design
- DevOps-praksis inklusive miljøkonfiguration og deployment
Fortsæt Din AI-udviklingsrejse
Næste Læringsskridt:
- Udforsk mere avancerede AI-modeller og API’er (GPT-4, Claude, Gemini)
- Lær om prompt engineering-teknikker for bedre AI-svar
- Studer samtaledesign og chatbot-brugeroplevelsesprincipper
- Undersøg AI-sikkerhed, etik og ansvarlig AI-udviklingspraksis
- Byg mere komplekse applikationer med samtalememory og kontekstbevidsthed
Avancerede Projektideer:
- Multi-bruger chatrum med AI-moderation
- AI-drevne kundeservice-chatbots
- Uddannelsesvejledere med personlig læring
- Kreative skrivepartnere med forskellige AI-personligheder
- Tekniske dokumentationsassistenter for udviklere
Kom Godt I Gang med GitHub Codespaces
Vil du prøve dette projekt i et cloud-udviklingsmiljø? GitHub Codespaces leverer en komplet udviklingsopsætning i din browser, perfekt til at eksperimentere med AI-applikationer uden lokale installationskrav.
Opsætning af Dit Udviklingsmiljø
Trin 1: Opret fra skabelon
- Naviger til Web Dev For Beginners repository
- Klik på "Use this template" i øverste højre hjørne (sørg for at være logget ind på GitHub)
Trin 2: Start Codespaces
- Åbn dit nyoprettede repository
- Klik på den grønne "Code" knap, og vælg "Codespaces"
- Vælg "Create codespace on main" for at starte dit udviklingsmiljø
Trin 3: Miljøkonfiguration
Når din Codespace indlæses, får du adgang til:
- Forudinstalleret Python, Node.js og alle nødvendige udviklingsværktøjer
- VS Code-interface med udvidelser til webudvikling
- Terminaladgang til at køre backend- og frontend-servere
- Port forwarding til at teste dine applikationer
Hvad Codespaces tilbyder:
- Fjerner problemer med lokal miljøopsætning og konfiguration
- Giver et konsistent udviklingsmiljø på tværs af forskellige enheder
- Indeholder forudkonfigurerede værktøjer og udvidelser til webudvikling
- Tilbyder sømløs integration med GitHub til versionsstyring og samarbejde
🚀 Pro Tip: Codespaces er perfekt til at lære og prototype AI-applikationer, da det håndterer al kompleks miljøopsætning automatisk, så du kan fokusere på at bygge og lære fremfor problemer med konfiguration.
Ansvarsfraskrivelse: Dette dokument er blevet oversat ved hjælp af AI-oversættelsestjenesten Co-op Translator. Selvom vi bestræber os på nøjagtighed, skal du være opmærksom på, at automatiserede oversættelser kan indeholde fejl eller unøjagtigheder. Det oprindelige dokument på dets modersmål skal betragtes som den autoritative kilde. For kritisk information anbefales professionel, menneskelig oversættelse. Vi påtager os intet ansvar for misforståelser eller fejltolkninger, der opstår som følge af brugen af denne oversættelse.




