# Bygg en Chat Assistent med AI Husker du i Star Trek når besetningen tilfeldig pratet med skipscomputeren, stilte komplekse spørsmål og fikk gjennomtenkte svar? Det som virket som ren science fiction på 1960-tallet, er nå noe du kan bygge ved hjelp av webteknologier du allerede kan. I denne leksjonen skal vi lage en AI-chatassistent ved hjelp av HTML, CSS, JavaScript og litt backend-integrasjon. Du vil oppdage hvordan de samme ferdighetene du har lært kan koble til kraftige AI-tjenester som kan forstå kontekst og generere meningsfulle svar. Tenk på AI som å ha tilgang til et enormt bibliotek som ikke bare kan finne informasjon, men også syntetisere det til sammenhengende svar tilpasset dine spesifikke spørsmål. I stedet for å søke gjennom tusenvis av sider, får du direkte, kontekstuelle svar. Integrasjonen skjer gjennom velkjente webteknologier som jobber sammen. HTML lager chat-grensesnittet, CSS tar seg av det visuelle designet, JavaScript håndterer brukerinteraksjoner, og en backend-API kobler alt til AI-tjenester. Det er som hvordan forskjellige seksjoner i et orkester spiller sammen for å skape en symfoni. Vi bygger egentlig en bro mellom naturlig menneskelig kommunikasjon og maskinbehandling. Du vil lære både den tekniske implementeringen av AI-tjenesteintegrasjon og designmønstrene som gjør interaksjoner intuitive. På slutten av denne leksjonen vil AI-integrasjon føles mindre som en mystisk prosess og mer som en annen API du kan jobbe med. Du vil forstå grunnleggende mønstre som driver applikasjoner som ChatGPT og Claude, ved å bruke de samme prinsippene for webutvikling du allerede har lært. ## ⚡ Hva Du Kan Gjøre i de Neste 5 Minuttene **Rask Start for Travle Utviklere** ```mermaid flowchart LR A[⚡ 5 minutter] --> B[Få GitHub-token] B --> C[Test AI-lekeplass] C --> D[Kopier Python-kode] D --> E[Se AI-svar] ``` - **Minutt 1**: Besøk [GitHub Models Playground](https://github.com/marketplace/models/azure-openai/gpt-4o-mini/playground) og lag et personlig tilgangstoken - **Minutt 2**: Test AI-interaksjoner direkte i playground-grensesnittet - **Minutt 3**: Klikk på "Code" fanen og kopier Python-koden - **Minutt 4**: Kjør koden lokalt med tokenet ditt: `GITHUB_TOKEN=your_token python test.py` - **Minutt 5**: Se ditt første AI-svar genereres fra din egen kode **Rask Testkode**: ```python import os from openai import OpenAI client = OpenAI( base_url="https://models.github.ai/inference", api_key="your_token_here" ) response = client.chat.completions.create( messages=[{"role": "user", "content": "Hello AI!"}], model="openai/gpt-4o-mini" ) print(response.choices[0].message.content) ``` **Hvorfor dette er viktig**: På 5 minutter vil du oppleve magien ved programmatisk AI-interaksjon. Dette er grunnmuren som driver hver AI-applikasjon du bruker. Slik vil ditt ferdige prosjekt se ut: ![Chat app interface showing conversation between user and AI assistant](../../../translated_images/no/screenshot.0a1ee0d123df681b.webp) ## 🗺️ Din Læringsreise Gjennom AI Applikasjonsutvikling ```mermaid journey title Fra netutvikling til AI-integrasjon section Forstå AI-grunnlag Oppdag generative AI-konsepter: 4: You Utforsk GitHub Models-plattformen: 6: You Mestre AI-parametere og oppfordringer: 8: You section Backend-integrasjon Bygg Python API-server: 5: You Implementer AI-funksjonskall: 7: You Håndter asynkrone operasjoner: 8: You section Frontend-utvikling Lag moderne chattegrensesnitt: 6: You Mestre sanntidsinteraksjoner: 8: You Bygg responsiv brukeropplevelse: 9: You section Profesjonell anvendelse Distribuer komplett AI-system: 7: You Optimaliser ytelsesmønstre: 8: You Lag produksjonsklar app: 9: You ``` **Din reisemål**: På slutten av denne leksjonen vil du ha bygget en komplett AI-drevet applikasjon ved å bruke de samme teknologiene og mønstrene som driver moderne AI-assistenter som ChatGPT, Claude og Google Bard. ## Forstå AI: Fra Mysterium til Mestring Før vi dykker ned i koden, la oss forstå hva vi jobber med. Hvis du har brukt API-er før, kjenner du det grunnleggende mønsteret: send en forespørsel, motta et svar. AI-API-er følger en lignende struktur, men i stedet for å hente forhåndslagrede data fra en database, genererer de nye svar basert på mønstre lært fra enorme mengder tekst. Tenk på det som forskjellen mellom et bibliotekskatalogsystem og en kunnskapsrik bibliotekar som kan syntetisere informasjon fra flere kilder. ### Hva er egentlig "Generativ AI"? Tenk på hvordan Rosettasteinen lot forskere forstå egyptiske hieroglyfer ved å finne mønstre mellom kjente og ukjente språk. AI-modeller fungerer på samme måte – de finner mønstre i enorme mengder tekst for å forstå hvordan språk fungerer, og bruker deretter disse mønstrene til å generere passende svar på nye spørsmål. **La meg forklare det med en enkel sammenligning:** - **Tradisjonell database**: Som å spørre om din fødselsattest – du får det samme dokumentet hver gang - **Søkemotor**: Som å spørre en bibliotekar om bøker om katter – de viser deg hva som er tilgjengelig - **Generativ AI**: Som å spørre en kunnskapsrik venn om katter – de forteller deg interessante ting med egne ord, tilpasset det du vil vite ```mermaid graph LR A[Ditt Spørsmål] --> B[AI-modell] B --> C[Mønster-gjenkjenning] C --> D[Innholdsgenerering] D --> E[Kontekstuell Respons] F[Treningsdata
Bøker, Artikler, Nett] --> B ``` ### Hvordan AI-modeller lærer (Den enkle versjonen) AI-modeller lærer ved eksponering for enorme datasett som inneholder tekst fra bøker, artikler og samtaler. Gjennom denne prosessen identifiserer de mønstre i: - Hvordan tanker struktureres i skriftlig kommunikasjon - Hvilke ord som ofte forekommer sammen - Hvordan samtaler vanligvis flyter - Kontekstuelle forskjeller mellom formell og uformell kommunikasjon **Det er som arkeologer som avkoder gamle språk**: de analyserer tusenvis av eksempler for å forstå grammatikk, vokabular og kulturell kontekst, og blir til slutt i stand til å tolke nye tekster basert på de lærte mønstrene. ### Hvorfor GitHub Models? Vi bruker GitHub Models av en ganske praktisk grunn – det gir oss tilgang til AI på bedriftsnivå uten at vi må sette opp vår egen AI-infrastruktur (og tro meg, det vil du ikke gjøre akkurat nå!). Tenk på det som å bruke en vær-API i stedet for å prøve å forutsi været selv ved å sette opp værstasjoner overalt. Det er egentlig "AI-som-en-Tjeneste", og det beste? Det er gratis å komme i gang, slik at du kan eksperimentere uten å bekymre deg for høye kostnader. ```mermaid graph LR A[Frontend Chat UI] --> B[Din Backend-API] B --> C[GitHub Modeller API] C --> D[AI Modellbehandling] D --> C C --> B B --> A ``` Vi bruker GitHub Models for backend-integrasjonen, som gir tilgang til AI-kapasiteter på profesjonelt nivå gjennom et utviklervennlig grensesnitt. [GitHub Models Playground](https://github.com/marketplace/models/azure-openai/gpt-4o-mini/playground) fungerer som et testmiljø hvor du kan eksperimentere med forskjellige AI-modeller og forstå deres evner før du implementerer dem i kode. ## 🧠 AI Applikasjonsutviklings Økosystem ```mermaid mindmap root((AI Development)) Understanding AI Generative Models Pattern Recognition Content Generation Context Understanding Response Synthesis AI Parameters Temperature Control Token Limits Top-p Filtering System Prompts Backend Architecture API Integration GitHub Models Authentication Request Handling Error Management Python Infrastructure FastAPI Framework Async Operations Environment Security CORS Configuration Frontend Experience Chat Interface Real-time Updates Message History User Feedback Loading States Modern Web Tech ES6 Classes Async/Await DOM Manipulation Event Handling Professional Patterns Security Best Practices Token Management Input Validation XSS Prevention Error Boundaries Production Readiness Performance Optimization Responsive Design Accessibility Testing Strategies ``` **Kjerneprinsipp**: AI-applikasjonsutvikling kombinerer tradisjonelle webutviklingsferdigheter med AI-tjenesteintegrasjon, og skaper intelligente applikasjoner som føles naturlige og responsive for brukerne. ![GitHub Models AI Playground interface with model selection and testing area](../../../translated_images/no/playground.d2b927122224ff8f.webp) **Dette gjør playground så nyttig:** - **Prøv ut** forskjellige AI-modeller som GPT-4o-mini, Claude, og flere (alle gratis!) - **Test** ideene og promptene dine før du skriver kode - **Få** ferdige kode-snutter i ditt favoritt programmeringsspråk - **Justér** innstillinger som kreativitet og svarlengde for å se hvordan det påvirker resultatet Når du har lekt deg litt, klikk bare på "Code"-fanen og velg programmeringsspråk for å få implementasjonskoden du trenger. ![Playground choice showing code generation options for different programming languages](../../../translated_images/no/playground-choice.1d23ba7d407f4758.webp) ## Sette Opp Python Backend-integrasjon Nå skal vi implementere AI-integrasjonen ved hjelp av Python. Python er utmerket for AI-applikasjoner på grunn av sin enkle syntaks og kraftige biblioteker. Vi starter med koden fra GitHub Models playground, og refaktorerer den så til en gjenbrukbar, produksjonsklar funksjon. ### Forstå grunnleggende implementering Når du henter Python-koden fra playground, får du noe som ser slik ut. Ikke bekymre deg om det virker mye i starten – la oss gå gjennom det bit for bit: ```python """Run this model in Python > pip install openai """ import os from openai import OpenAI # For å autentisere med modellen må du generere en personlig tilgangstoken (PAT) i GitHub-innstillingene dine. # Opprett din PAT-token ved å følge instruksjonene 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) ``` **Dette skjer i koden:** - **Vi importerer** verktøyene vi trenger: `os` for å lese miljøvariabler og `OpenAI` for å kommunisere med AI - **Vi setter opp** OpenAI-klienten til å peke på GitHub sine AI-servere i stedet for OpenAI direkte - **Vi autentiserer** med et spesielt GitHub-token (mer om det om et øyeblikk!) - **Vi strukturerer** samtalen med forskjellige "roller" – tenk på det som å sette scenen for et skuespill - **Vi sender** forespørselen til AI med noen fininnstillingsparametere - **Vi henter ut** det faktiske svarteksten fra all dataen som kommer tilbake ### Forstå Meldingsroller: AI Samtale-rammeverket AI-samtaler bruker en bestemt struktur med ulike "roller" som har forskjellige formål: ```python messages=[ { "role": "system", "content": "You are a helpful assistant who explains things simply." }, { "role": "user", "content": "What is machine learning?" } ] ``` **Tenk på det som å regissere et skuespill:** - **System-rolle**: Som scenedirektiv for en skuespiller – forteller AI hvordan den skal oppføre seg, hvilken personlighet den skal ha og hvordan den skal svare - **Bruker-rolle**: Det faktiske spørsmålet eller meldingen fra personen som bruker applikasjonen - **Assistent-rolle**: AI sitt svar (dette sender du ikke, men det vises i samtalehistorikken) **Virkelighetsanalog**: Forestill deg at du introduserer en venn på en fest: - **System-melding**: "Dette er vennen min Sarah, hun er lege og flink til å forklare medisinske konsepter på en enkel måte" - **Bruker-melding**: "Kan du forklare hvordan vaksiner fungerer?" - **Assistent-svar**: Sarah svarer som en vennlig lege, ikke som en advokat eller kokk ### Forstå AI-parametere: Fininnstilling av svaradferd De numeriske parameterne i AI-API-kallene styrer hvordan modellen genererer svar. Disse innstillingene lar deg justere AI-ens oppførsel for ulike bruksområder: #### Temperature (0.0 til 2.0): Kreativitetskontrollen **Hva den gjør**: Styrer hvor kreative eller forutsigbare AI-svarene vil være. **Tenk på det som improvisasjonsnivået til en jazzmusiker:** - **Temperature = 0.1**: Spiller samme melodi hver gang (svært forutsigbar) - **Temperature = 0.7**: Legger til noen smakfulle variasjoner mens melodien er gjenkjennelig (balansert kreativitet) - **Temperature = 1.5**: Full eksperimentell jazz med uventede vendinger (svært uforutsigbar) ```python # Veldig forutsigbare svar (bra for faktaspørsmål) response = client.chat.completions.create( messages=[{"role": "user", "content": "What is 2+2?"}], temperature=0.1 # Vil nesten alltid si "4" ) # Kreative svar (bra for idémyldring) response = client.chat.completions.create( messages=[{"role": "user", "content": "Write a creative story opening"}], temperature=1.2 # Vil generere unike, uventede historier ) ``` #### Max Tokens (1 til 4096+): Kontrollerer svarlengde **Hva den gjør**: Setter en øvre grense for hvor langt AI-svaret kan bli. **Tenk på tokens som omtrent det samme som ord** (omtrent 1 token = 0,75 ord på engelsk): - **max_tokens=50**: Kort og konsist (som en SMS) - **max_tokens=500**: Et hyggelig avsnitt eller to - **max_tokens=2000**: En detaljert forklaring med eksempler ```python # Korte, konsise svar response = client.chat.completions.create( messages=[{"role": "user", "content": "Explain JavaScript"}], max_tokens=100 # Tvinger frem en kort forklaring ) # Detaljerte, omfattende svar response = client.chat.completions.create( messages=[{"role": "user", "content": "Explain JavaScript"}], max_tokens=1500 # Tillater detaljerte forklaringer med eksempler ) ``` #### Top_p (0.0 til 1.0): Fokusparameteren **Hva den gjør**: Styrer hvor fokusert AI er på de mest sannsynlige svarene. **Se for deg at AI har et enormt vokabular rangert etter sannsynlighet for hvert ord:** - **top_p=0.1**: Vurderer kun de topp 10 % mest sannsynlige ordene (svært fokusert) - **top_p=0.9**: Vurderer 90 % av mulige ord (mer kreativ) - **top_p=1.0**: Vurderer alt (maksimal variasjon) **For eksempel**: Hvis du spør "Himmelen er vanligvis..." - **Lav top_p**: Sier nesten alltid "blå" - **Høy top_p**: Kan si "blå", "overskyet", "vid", "foranderlig", "vakker", osv. ### Sette Alt Sammen: Parameterkombinasjoner for Ulike Bruksområder ```python # For faktiske, konsistente svar (som en dokumentasjonsbot) factual_params = { "temperature": 0.2, "max_tokens": 300, "top_p": 0.3 } # For kreativ skrivehjelp creative_params = { "temperature": 1.1, "max_tokens": 1000, "top_p": 0.9 } # For samtalebaserte, hjelpsomme svar (balansert) conversational_params = { "temperature": 0.7, "max_tokens": 500, "top_p": 0.8 } ``` ```mermaid quadrantChart title AI Parameteroptimaliseringsmatrise x-axis Lav kreativitet --> Høy kreativitet y-axis Kort respons --> Lang respons quadrant-1 Kreativt innhold quadrant-2 Detaljert analyse quadrant-3 Rask fakta quadrant-4 Konversasjons-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 parameterne betyr noe**: Ulike applikasjoner trenger ulike typer svar. En kundeservicebot bør være konsistent og faktabasert (lav temperature), mens en kreativ skriveassistent bør være fantasifull og variert (høy temperature). Å forstå disse parameterne gir deg kontroll over AI-ens personlighet 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 funksjonen:** - **Aksepterer** to parametere: brukerens prompt og en valgfri systemmelding - **Gir** en standard systemmelding for generell assistentadferd - **Bruker** riktige Python type hints for bedre kodedokumentasjon - **Inneholder** en detaljert docstring som forklarer funksjonens hensikt og parametere - **Returnerer** kun svarinnholdet, noe som gjør det enkelt å bruke i web-API-en vår - **Opprettholder** de samme modellparameterne for konsistent AI-adferd ### Magien med Systemprompter: Programmer AI’s Personlighet Hvis parametere kontrollerer hvordan AI tenker, styrer systemprompter hvem AI tror den er. Dette er virkelig en av de kuleste delene av å jobbe med AI – du gir AI en komplett personlighet, ekspertisenivå og kommunikasjonsstil. **Tenk på systemprompter som å kaste forskjellige skuespillere i ulike roller**: I stedet for en generisk assistent kan du skape spesialiserte eksperter for ulike situasjoner. Trenger du en tålmodig lærer? En kreativ brainstorming-partner? En seriøs forretningsrådgiver? Bare endre systemprompten! #### Hvorfor systemprompter er så kraftfulle Her er det fascinerende: AI-modeller er trent på utallige samtaler der folk inntar forskjellige roller og ekspertisenivåer. Når du gir AI en spesifikk rolle, er det som å slå en bryter som aktiverer alle disse lærte mønstrene. **Det er som metode-teater for AI**: Si til en skuespiller "du er en klok, gammel professor" og se hvordan de automatisk justerer holdning, vokabular og væremåte. AI gjør noe bemerkelsesverdig likt med språk. #### Lage Effektive Systemprompter: Kunst og Vitenskap **Anatomien til en god systemprompt:** 1. **Rolle/Identitet**: Hvem er AI? 2. **Ekspertise**: Hva kan den? 3. **Kommunikasjonsstil**: Hvordan snakker den? 4. **Spesifikke instruksjoner**: Hva skal den fokusere på? ```python # ❌ Vag systeminstruks "You are helpful." # ✅ Detaljert, effektiv systeminstruks "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." ``` #### Eksempler på systemprompter med kontekst La oss se hvordan ulike systemprompter lager helt forskjellige AI-personligheter: ```python # Eksempel 1: Den tålmodige læreren 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 samarbeidspartneren 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ådgiveren 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 praksis La oss teste det samme spørsmålet med forskjellige systemprompter for å se de dramatiske forskjellene: **Spørsmål**: "Hvordan håndterer jeg brukerautentisering i webappen min?" ```python # Med lærerpåminnelse: teacher_response = call_llm( "How do I handle user authentication in my web app?", teacher_prompt ) # Typisk svar: "Flott spørsmål! La oss dele autentisering opp i enkle trinn. # Tenk på det som en dørvakt på en nattklubb som sjekker ID..." # Med forretningspåminnelse: business_response = call_llm( "How do I handle user authentication in my web app?", business_prompt ) # Typisk svar: "Fra et strategisk perspektiv er autentisering avgjørende for bruker # tillit og regulatorisk samsvar. La meg skissere en ramme som tar hensyn til sikkerhet, # brukeropplevelse og skalerbarhet..." ``` #### Avanserte teknikker for systemprompter **1. Kontekstsetting**: Gi AI bakgrunnsinformasjon ```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. Output Formatting**: Fortell AI hvordan svar skal struktureres ```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. Constraint Setting**: Definer hva AI IKKE skal gjøre ```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. """ ``` #### Hvorfor dette er viktig for din chatassistent Å forstå systemprompter gir deg utrolig makt til å lage spesialiserte AI-assistenter: - **Kundeservicebot**: Hjelpsom, tålmodig, policy-bevisst - **Læringsveileder**: Oppmuntrende, steg-for-steg, sjekker forståelse - **Kreativ partner**: Fantasifull, bygger videre på ideer, spør "hva om?" - **Teknisk ekspert**: Presis, detaljert, sikkerhetsbevisst **Nøkkelforståelsen**: Du bare ringer ikke et AI-API – du skaper en tilpasset AI-personlighet som tjener ditt spesifikke brukstilfelle. Dette er det som gjør moderne AI-applikasjoner føles skreddersydde og nyttige i stedet for generiske. ### 🎯 Pedagogisk sjekkpunkt: Programmering av AI-personlighet **Pause og reflekter**: Du har nettopp lært å programmere AI-personligheter gjennom systemprompter. Dette er en grunnleggende ferdighet i moderne AI-applikasjonsutvikling. **Rask egenvurdering**: - Kan du forklare hvordan systemprompter skiller seg fra vanlige brukermeldinger? - Hva er forskjellen på temperature- og top_p-parametrene? - Hvordan ville du lage en systemprompt for et spesifikt brukstilfelle (som en kodeveileder)? **Virkelighetsforbindelse**: Systemprompt-teknikkene du har lært brukes i alle større AI-applikasjoner – fra GitHub Copilot sin kodehjelp til ChatGPTs samtalegrensesnitt. Du mestrer de samme mønstrene som AI-produktteam i store teknologiselskaper bruker. **Utfordringsspørsmål**: Hvordan kunne du designe forskjellige AI-personligheter for ulike brukertyper (nybegynner vs ekspert)? Vurder hvordan samme underliggende AI-modell kan tjene ulike målgrupper gjennom prompt-teknikker. ## Bygge Web API med FastAPI: Ditt høyytelses AI-kommunikasjonsnav La oss nå bygge backend som kobler frontend til AI-tjenester. Vi bruker FastAPI, et moderne Python-rammeverk som er glimrende egnet for å bygge APIer for AI-applikasjoner. FastAPI tilbyr flere fordeler for denne typen prosjekter: innebygd async-støtte for håndtering av samtidige forespørsler, automatisk generering av API-dokumentasjon og utmerket ytelse. Din FastAPI-server fungerer som en mellomstasjon som mottar forespørsler fra frontend, kommuniserer med AI-tjenester og returnerer formaterte svar. ### Hvorfor FastAPI for AI-applikasjoner? Du lurer kanskje på: "Kan jeg ikke bare kalle AI direkte fra frontend JavaScript?" eller "Hvorfor FastAPI i stedet for Flask eller Django?" Gode spørsmål! **Her er hvorfor FastAPI er perfekt for det vi bygger:** - **Async som standard**: Kan håndtere flere AI-forespørsler samtidig uten å låse seg - **Automatisk dokumentasjon**: Besøk `/docs` og få en vakker, interaktiv API-dokumentasjon gratis - **Innebygd validering**: Fanger opp feil før de skaper problemer - **Lynrask**: Et av de raskeste Python-rammeverkene der ute - **Moderne Python**: Bruker alle de nyeste og beste Python-funksjonene **Og hvorfor vi trenger en backend i det hele tatt:** **Sikkerhet**: Din AI-API-nøkkel er som et passord – legger du det i frontend JavaScript kan hvem som helst som ser nettsidens kildekode stjele det og bruke AI-kredittene dine. Backend holder sensitive legitimasjoner trygge. **Ratebegrensning og kontroll**: Backend lar deg kontrollere hvor ofte brukere kan sende forespørsler, implementere brukerautentisering, og legge til logging for å spore bruk. **Databehandling**: Du vil kanskje lagre samtaler, filtrere upassende innhold eller kombinere flere AI-tjenester. Backend er stedet for denne logikken. **Arkitekturen ligner en klient-server-modell:** - **Frontend**: Brukergrensesnittlaget for interaksjon - **Backend-API**: Forespørselsbehandling og ruting - **AI-tjeneste**: Ekstern beregning og svarproduksjon - **Miljøvariabler**: Sikker konfigurasjon og lagring av legitimasjon ### Forstå Request-Response-flyten La oss spore hva som skjer når en bruker sender en melding: ```mermaid sequenceDiagram participant User as 👤 Bruker participant Frontend as 🌐 Frontend participant API as 🔧 FastAPI Server participant AI as 🤖 AI-tjeneste User->>Frontend: Skriver "Hei AI!" Frontend->>API: POST /hello {"message": "Hei AI!"} Note over API: Validerer forespørsel
Legger til systemprompt API->>AI: Sender formatert forespørsel AI->>API: Returnerer AI-svar Note over API: Behandler svar
Logger samtale API->>Frontend: {"response": "Hei! Hvordan kan jeg hjelpe?"} Frontend->>User: Viser AI-melding ``` **Forstå hvert steg:** 1. **Brukerinteraksjon**: Person skriver i chat-grensesnittet 2. **Frontend behandling**: JavaScript fanger opp input og formaterer som JSON 3. **API-validering**: FastAPI validerer automatisk forespørselen ved hjelp av Pydantic-modeller 4. **AI-integrasjon**: Backend legger på kontekst (systemprompt) og kaller AI-tjenesten 5. **Responsbehandling**: API mottar AI-respons og kan justere den om nødvendig 6. **Frontend visning**: JavaScript viser svaret i chattegrensesnittet ### Forstå API-arkitektur ```mermaid sequenceDiagram participant Frontend participant FastAPI participant AI Function participant GitHub Models Frontend->>FastAPI: POST /hello {"message": "Hei AI!"} FastAPI->>AI Function: call_llm(message, system_prompt) AI Function->>GitHub Models: API request GitHub Models->>AI Function: AI svar AI Function->>FastAPI: svar tekst FastAPI->>Frontend: {"response": "Hei! Hvordan kan jeg hjelpe?"} ``` ```mermaid flowchart TD A[Brukerinndata] --> B[Frontend validering] B --> C[HTTP POST-forespørsel] C --> D[FastAPI-ruter] D --> E[Pydantic-validering] E --> F[AI-funksjonskall] F --> G[GitHub Modeller API] G --> H[Responsbehandling] H --> I[JSON-respons] I --> J[Frontend oppdatering] subgraph "Sikkerhetslag" K[CORS-mellomvare] L[Miljøvariabler] M[Feilhåndtering] end D --> K F --> L H --> M ``` ### Lage FastAPI-applikasjonen La oss bygge API-et vårt steg for steg. Lag en fil som heter `api.py` med følgende FastAPI-kode: ```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 # Konfigurer logging logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) # Opprett FastAPI-applikasjon 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 hensiktsmessig for produksjon allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # Pydantic-modeller for forespørsels-/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: # Ekstraher og valider melding 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]}...") # Kall AI-tjeneste (merk: call_llm bør gjøres asynkron for bedre ytelse) 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å FastAPI-implementasjonen:** - **Importer** FastAPI for moderne web-rammeverksfunksjonalitet og Pydantic for datavalidering - **Oppretter** automatisk API-dokumentasjon (tilgjengelig på `/docs` når server kjører) - **Aktiverer** CORS-middleware for å tillate forespørsler fra frontend på forskjellige domener - **Definerer** Pydantic-modeller for automatisk validering av forespørsler/svar og dokumentasjon - **Bruker** asynkrone endepunkter for bedre ytelse med samtidige forespørsler - **Implementerer** riktig HTTP-statuskoder og feilhåndtering med HTTPException - **Inkluderer** strukturert logging for overvåking og debugging - **Leverer** health check-endepunkt for overvåking av tjenestestatus **Viktige FastAPI-fordeler over tradisjonelle rammeverk:** - **Automatisk validering**: Pydantic-modeller sikrer dataintegritet før behandling - **Interaktive dokumenter**: Besøk `/docs` for auto-generert, testbar API-dokumentasjon - **Typesikkerhet**: Python-typehinting forhindrer runtime-feil og forbedrer kodekvalitet - **Async-støtte**: Håndter flere AI-forespørsler samtidig uten blokkering - **Ytelse**: Betydelig raskere forespørselsbehandling for sanntidsapplikasjoner ### Forstå CORS: Nettets sikkerhetsvakt CORS (Cross-Origin Resource Sharing) er som en sikkerhetsvakt i en bygning som sjekker om besøkende har lov til å komme inn. La oss forstå hvorfor dette er viktig og hvordan det påvirker applikasjonen din. #### Hva er CORS og hvorfor finnes det? **Problemet**: Tenk deg at hvilken som helst nettside kunne sende forespørsler til banken din på dine vegne uten din tillatelse. Det hadde vært et sikkerhetsmareritt! Nettlesere hindrer dette som standard via "Same-Origin Policy." **Same-Origin Policy**: Nettlesere tillater kun websider å sende forespørsler til samme domene, port og protokoll som siden ble lastet fra. **Virkelighetsanalogien**: Det er som leilighetsbyggsikkerhet – kun beboere (samme opprinnelse) kan som standard komme inn i bygget. Vil du slippe inn en venn (annen opprinnelse) må du uttrykkelig informere sikkerheten om at det er greit. #### CORS i ditt utviklingsmiljø Under utvikling kjører frontend og backend på ulike porter: - Frontend: `http://localhost:3000` (eller file:// om du åpner HTML direkte) - Backend: `http://localhost:5000` Disse regnes som "forskjellige opprinnelser" selv om de er på samme maskin! ```python from fastapi.middleware.cors import CORSMiddleware app = FastAPI(__name__) CORS(app) # Dette forteller nettlesere: "Det er greit for andre opprinnelser å sende forespørsler til dette API-et" ``` **Hva CORS-konfigurasjon gjør i praksis:** - **Legger til** spesielle HTTP-headere i API-respons som forteller nettlesere "denne cross-origin-forespørselen er tillatt" - **Håndterer** "preflight"-forespørsler (nettlesere sjekker av og til tillatelser før de sender den faktiske forespørselen) - **Forhindrer** den fryktede "blokkert av CORS-policy"-feilen i nettleserkonsollen #### CORS-sikkerhet: Utvikling vs produksjon ```python # 🚨 Utvikling: Tillater ALLE opprinnelser (praktisk men usikkert) CORS(app) # ✅ Produksjon: Tillat kun ditt spesifikke frontend-domene CORS(app, origins=["https://yourdomain.com", "https://www.yourdomain.com"]) # 🔒 Avansert: Ulike opprinnelser for forskjellige miljøer if app.debug: # Utviklingsmodus CORS(app, origins=["http://localhost:3000", "http://127.0.0.1:3000"]) else: # Produksjonsmodus CORS(app, origins=["https://yourdomain.com"]) ``` **Hvorfor dette betyr noe**: I utvikling er `CORS(app)` som å la inngangsdøren stå ulåst – praktisk, men ikke sikkert. I produksjon bør du spesifisere nøyaktig hvilke nettsteder som kan kommunisere med API-et ditt. #### Vanlige CORS-scenarier og løsninger | Scenario | Problem | Løsning | |-----------------------|------------------------------|-----------------------------| | **Lokal utvikling** | Frontend når ikke backend | Legg til CORSMiddleware i FastAPI | | **GitHub Pages + Heroku** | Distribuert frontend når ikke API | Legg til GitHub Pages-URL i CORS-origins | | **Egendefinert domene** | CORS-feil i produksjon | Oppdater CORS-origins til ditt domene | | **Mobilapp** | App når ikke nett-API | Legg til appens domene eller bruk `*` forsiktig | **Proftips**: Du kan sjekke CORS-headere i nettleserens utviklerverktøy under Nettverk-fanen. Se etter headere som `Access-Control-Allow-Origin` i responsene. ### Feilhåndtering og validering Legg merke til hvordan API-et vårt inkluderer god feilhåndtering: ```python # Bekreft at vi mottok en melding if not message: return jsonify({"error": "Message field is required"}), 400 ``` **Viktige valideringsprinsipper:** - **Sjekker** påkrevd felt før behandling av forespørsel - **Returnerer** meningsfulle feilmeldinger i JSON-format - **Bruker** riktige HTTP-statuskoder (400 for dårlige forespørsler) - **Gir** klare tilbakemeldinger som hjelper frontend-utviklere å feilsøke ## Sette opp og kjøre backend Nå som vi har AI-integrasjon og FastAPI-server klar, la oss få alt til å kjøre. Oppsettprosessen omfatter installering av Python-avhengigheter, konfigurering av miljøvariabler og oppstart av utviklingsserveren. ### Python miljøoppsett La oss sette opp ditt Python utviklingsmiljø. Virtuelle miljøer er som Manhattanprosjektets oppdelte tilnærming – hvert prosjekt får sitt eget isolerte rom med spesifikke verktøy og avhengigheter, slik at man unngår konflikt mellom prosjekter. ```bash # Naviger til backend-katalogen din cd backend # Opprett et virtuelt miljø (som å lage et rent rom for prosjektet ditt) python -m venv venv # Aktiver det (Linux/Mac) source ./venv/bin/activate # På Windows, bruk: # venv\Scripts\activate # Installer de gode tingene pip install openai fastapi uvicorn python-dotenv ``` **Hva vi nettopp gjorde:** - **Opprettet** vår egen lille Python-boble hvor vi kan installere pakker uten å påvirke andre prosjekter - **Aktivert** denne slik at terminalen vet å bruke akkurat dette miljøet - **Installert** det essensielle: OpenAI for AI-magi, FastAPI for vårt web-API, Uvicorn for å faktisk kjøre det, og python-dotenv for sikker håndtering av hemmeligheter **Viktige avhengigheter forklart:** - **FastAPI**: Moderne, raskt web-rammeverk med automatisk API-dokumentasjon - **Uvicorn**: Lynrask ASGI-server som kjører FastAPI-applikasjoner - **OpenAI**: Offisiell bibliotek for GitHub-modeller og OpenAI API-integrasjon - **python-dotenv**: Laster miljøvariabler sikkert fra .env-filer ### Miljøkonfigurasjon: Holde hemmeligheter trygge Før vi starter API-et må vi snakke om en av de viktigste leksjonene i webutvikling: hvordan man faktisk holder hemmelighetene sine hemmelige. Miljøvariabler er som et sikkert hvelv som bare applikasjonen din kan åpne. #### Hva er miljøvariabler? **Tenk på miljøvariabler som et sikkerhetsskap** – du legger verdifulle ting der, og bare du (og appen din) har nøkkelen til å hente dem ut. I stedet for å skrive sensitiv info direkte i koden (der bokstavelig talt hvem som helst kan se det), lagrer du det trygt i miljøet. **Her er forskjellen:** - **Feil metode**: Skrive passordet ditt på en lapp og henge det på skjermen - **Riktig metode**: Holde passordet i en sikker passordhåndterer som bare du har tilgang til #### Hvorfor miljøvariabler er viktige ```python # 🚨 ALDRI GJØR DETTE - API-nøkkel synlig for alle client = OpenAI( api_key="ghp_1234567890abcdef...", # Alle kan stjele dette! base_url="https://models.github.ai/inference" ) # ✅ GJØR DETTE - API-nøkkel lagret sikkert client = OpenAI( api_key=os.environ["GITHUB_TOKEN"], # Bare appen din kan få tilgang til dette base_url="https://models.github.ai/inference" ) ``` **Hva som skjer med hardkodede hemmeligheter:** 1. **Eksponering i versjonskontroll**: Alle som har tilgang til Git-repositoriet ditt ser API-nøkkelen 2. **Offentlige repoer**: Skrur du til GitHub blir nøkkelen synlig for hele internett 3. **Delt med teamet**: Andre utviklere får tilgang til din personlige API-nøkkel 4. **Sikkerhetsbrudd**: Hvis noen stjeler nøkkelen, kan de bruke dine AI-kreditter #### Sette opp din miljøfil Lag en `.env`-fil i backend-katalogen. Denne filen lagrer hemmelighetene dine lokalt: ```bash # .env-fil - Denne bør ALDRI legges til i Git GITHUB_TOKEN=your_github_personal_access_token_here FASTAPI_DEBUG=True ENVIRONMENT=development ``` **Forstå .env-filen:** - **Én hemmelighet per linje** i `KEY=value`-format - **Ingen mellomrom** rundt likhetstegnet - **Ingen anførselstegn** rundt verdier (vanligvis) - **Kommentarer** starter med `#` #### Lage ditt personlige GitHub Access Token Din GitHub-token er som et spesielt passord som gir applikasjonen din tillatelse til å bruke GitHubs AI-tjenester: **Steg-for-steg tokenopprettelse:** 1. **Gå til GitHub Settings** → Developer settings → Personal access tokens → Tokens (classic) 2. **Klikk "Generate new token (classic)"** 3. **Sett utløpstid** (30 dager for testing, lengre for produksjon) 4. **Velg scopes**: Kryss av for "repo" og andre nødvendige tillatelser 5. **Generer token** og kopier det med en gang (du kan ikke se det igjen!) 6. **Lim det inn i .env-filen** ```bash # Eksempel på hvordan tokenet ditt ser ut (dette er falskt!) GITHUB_TOKEN=ghp_1A2B3C4D5E6F7G8H9I0J1K2L3M4N5O6P7Q8R ``` #### Laste miljøvariabler i Python ```python import os from dotenv import load_dotenv # Last miljøvariabler fra .env-fil load_dotenv() # Nå kan du få tilgang 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" ) ``` **Hva denne koden gjør:** - **Laster** .env-filen din og gjør variablene tilgjengelige for Python - **Sjekker** om nødvendig token finnes (god feilhåndtering!) - **Kaster** en tydelig feil hvis token mangler - **Bruker** token sikkert uten å eksponere i kode #### Git-sikkerhet: .gitignore-filen Din `.gitignore`-fil forteller Git hvilke filer den aldri skal spore eller laste opp: ```bash # .gitignore - Legg til disse linjene .env *.env .env.local .env.production __pycache__/ venv/ .vscode/ ``` **Hvorfor dette er avgjørende**: Når du legger `.env` i `.gitignore` vil Git ignorere miljøfilen, og du unngår å ved et uhell laste opp hemmeligheter til GitHub. #### Ulike miljøer, forskjellige hemmeligheter Profesjonelle applikasjoner bruker ulike API-nøkler for ulike miljøer: ```bash # .env.utmikling GITHUB_TOKEN=your_development_token DEBUG=True # .env.produksjon GITHUB_TOKEN=your_production_token DEBUG=False ``` **Hvorfor dette er viktig**: Du vil ikke at utviklingseksperimenter skal påvirke din produksjons AI-brukskvote, og du ønsker ulike sikkerhetsnivåer for ulike miljøer. ### Starte din utviklingsserver: La FastAPIen din leve videre Nå kommer det spennende øyeblikket – å starte din FastAPI-utviklingsserver og se AI-integrasjonen komme til liv! FastAPI bruker Uvicorn, en lynrask ASGI-server som er spesielt designet for asynkrone Python-applikasjoner. #### Forstå FastAPI serveroppstart-prosessen ```bash # Metode 1: Direkte Python-eksekvering (inkluderer automatisk opplasting) python api.py # Metode 2: Bruke Uvicorn direkte (mer kontroll) uvicorn api:app --host 0.0.0.0 --port 5000 --reload ``` Når du kjører denne kommandoen, skjer følgende bak kulissene: **1. Python laster FastAPI-applikasjonen din**: - Importerer alle nødvendige biblioteker (FastAPI, Pydantic, OpenAI osv.) - Laster miljøvariabler fra `.env`-filen din - Oppretter FastAPI-applikasjonsinstansen med automatisk dokumentasjon **2. Uvicorn konfigurerer ASGI-serveren**: - Binder til port 5000 med asynkron forespørselsbehandling - Setter opp ruting for forespørsler med automatisk validering - Aktiverer hot reload for utvikling (starter på nytt ved filendringer) - Genererer interaktiv API-dokumentasjon **3. Serveren begynner å lytte**: - Terminalen din viser: `INFO: Uvicorn running on http://0.0.0.0:5000` - Serveren kan håndtere flere samtidige AI-forespørsler - API-en din er klar med automatisk dokumentasjon på `http://localhost:5000/docs` #### Hva du bør se når alt fungerer ```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. ``` **Forstå FastAPI-utdataene:** - **Vil overvåke endringer**: Auto-reload aktivert for utvikling - **Uvicorn kjører**: Høyytelses ASGI-server er aktiv - **Startet reloader-prosess**: Filovervåker for automatisk omstart - **Applikasjonen er ferdig oppstartet**: FastAPI-app initialisert suksessfullt - **Interaktiv dokumentasjon tilgjengelig**: Besøk `/docs` for automatisk API-dokumentasjon #### Testing av FastAPI: Flere kraftfulle tilnærminger FastAPI tilbyr flere praktiske måter å teste API-et ditt på, inkludert automatisk interaktiv dokumentasjon: **Metode 1: Interaktiv API-dokumentasjon (anbefalt)** 1. Åpne nettleseren og gå til `http://localhost:5000/docs` 2. Du vil se Swagger UI med alle dine endepunkter dokumentert 3. Klikk på `/hello` → "Try it out" → Skriv inn en testmelding → "Execute" 4. Se svaret direkte i nettleseren med korrekt formatering **Metode 2: Enkel nettlesertest** 1. Gå til `http://localhost:5000` for rotendepunktet 2. Gå til `http://localhost:5000/health` for å sjekke serverhelse 3. Dette bekrefter at FastAPI-serveren kjører riktig **Metode 2: Kommandolinjetest (avansert)** ```bash # Test med curl (hvis tilgjengelig) curl -X POST http://localhost:5000/hello \ -H "Content-Type: application/json" \ -d '{"message": "Hello AI!"}' # Forventet svar: # {"response": "Hei! Jeg er din AI-assistent. Hvordan kan jeg hjelpe deg i dag?"} ``` **Metode 3: Python-testskript** ```python # test_api.py - Opprett denne filen for å teste API-en din import requests import json # Test API-endepunktet 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) ``` #### Feilsøking av vanlige oppstartsproblemer | Feilmelding | Hva det betyr | Hvordan fikse | |-------------|---------------|--------------| | `ModuleNotFoundError: No module named 'fastapi'` | FastAPI er ikke installert | Kjør `pip install fastapi uvicorn` i ditt virtuelle miljø | | `ModuleNotFoundError: No module named 'uvicorn'` | ASGI-serveren er ikke installert | Kjør `pip install uvicorn` i ditt virtuelle miljø | | `KeyError: 'GITHUB_TOKEN'` | Miljøvariabel ikke funnet | Sjekk `.env`-filen din og `load_dotenv()`-kallet | | `Address already in use` | Port 5000 er i bruk | Avslutt andre prosesser som bruker port 5000 eller endre porten | | `ValidationError` | Forespørselsdata samsvarer ikke med Pydantic-modellen | Sjekk at forespørselsformatet samsvarer med forventet skjema | | `HTTPException 422` | Ubehandlingsbar enhet | Forespørselsvalidering feilet, sjekk `/docs` for riktig format | | `OpenAI API error` | Autentisering for AI-tjenesten feilet | Verifiser at GitHub-tokenet ditt er korrekt og har nødvendige tillatelser | #### Beste praksis for utvikling **Hot Reloading**: FastAPI med Uvicorn tilbyr automatisk omlasting når du lagrer endringer i Python-filene dine. Det betyr at du kan modifisere koden og teste umiddelbart uten å måtte starte serveren manuelt på nytt. ```python # Aktiver hot reloading eksplisitt if __name__ == "__main__": app.run(host="0.0.0.0", port=5000, debug=True) # debug=True aktiverer hot reload ``` **Logging for utvikling**: Legg til logging for å forstå hva som skjer: ```python import logging # Sett opp logging 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 hjelper**: Under utvikling kan du se nøyaktig hvilke forespørsler som kommer inn, hva AI svarer med, og hvor feil oppstår. Dette gjør feilsøking mye raskere. ### Konfigurere for GitHub Codespaces: Skyutvikling gjort enkelt GitHub Codespaces er som å ha en kraftig utviklingsmaskin i skyen som du kan nå fra hvilken som helst nettleser. Hvis du jobber i Codespaces, er det noen ekstra trinn for å gjøre backend tilgjengelig for frontend. #### Forstå Codespaces nettverksbruk I et lokalt utviklingsmiljø kjører alt på samme maskin: - Backend: `http://localhost:5000` - Frontend: `http://localhost:3000` (eller file://) I Codespaces kjører utviklingsmiljøet på GitHubs servere, så "localhost" har en annen betydning. GitHub lager automatisk offentlige URLer for tjenestene dine, men du må konfigurere dem riktig. #### Steg-for-steg Codespaces-konfigurasjon **1. Start backend-serveren din**: ```bash cd backend python api.py ``` Du vil se den kjente FastAPI/Uvicorn oppstarts-meldingen, men merk at det kjører inne i Codespace-miljøet. **2. Konfigurer port-synlighet**: - Se etter "Ports"-fanen i bunnpanelet i VS Code - Finn port 5000 i listen - Høyreklikk på port 5000 - Velg "Port Visibility" → "Public" **Hvorfor gjøre den offentlig?** Som standard er Codespace-porter private (bare tilgjengelig for deg). Å gjøre den offentlig tillater at frontend (kjører i nettleseren) kan kommunisere med backend. **3. Få din offentlige URL**: Etter at porten er gjort offentlig, vil du se en URL som: ``` https://your-codespace-name-5000.app.github.dev ``` **4. Oppdater frontend-konfigurasjonen din**: ```javascript // I din frontend app.js, oppdater BASE_URL: this.BASE_URL = "https://your-codespace-name-5000.app.github.dev"; ``` #### Forstå Codespace-URLer Codespace-URLer følger et forutsigbart mønster: ``` https://[codespace-name]-[port].app.github.dev ``` **Dette innebærer:** - `codespace-name`: En unik identifikator for Codespacen din (vanligvis inkluderer brukernavn) - `port`: Portnummeret tjenesten kjører på (5000 for vår FastAPI-app) - `app.github.dev`: GitHubs domene for Codespace-applikasjoner #### Testing av Codespace-oppsettet ditt **1. Test backend direkte**: Åpne den offentlige URLen i en ny nettleserfane. Du skal se: ``` Welcome to the AI Chat API. Send POST requests to /hello with JSON payload containing 'message' field. ``` **2. Test med nettleserens utviklerverktøy**: ```javascript // Åpne nettleserkonsollen og test API-en din 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 utvikling | Aspekt | Lokal utvikling | GitHub Codespaces | |--------|-----------------|-------------------| | **Oppsettstid** | Lang (installer Python, avhengigheter) | Umiddelbar (forhåndskonfigurert miljø) | | **URL-tilgang** | `http://localhost:5000` | `https://xyz-5000.app.github.dev` | | **Portkonfigurasjon** | Automatisk | Manuell (gjør porter offentlige) | | **Filpersistens** | Lokal maskin | GitHub-repositorium | | **Samarbeid** | Vanskelig å dele miljø | Enkel deling av Codespace-lenke | | **Internettavhengighet** | Bare for AI API-kall | Nødvendig for alt | #### Tips for utvikling i Codespace **Miljøvariabler i Codespaces**: Din `.env`-fil fungerer på samme måte i Codespaces, men du kan også sette miljøvariabler direkte i Codespace: ```bash # Sett miljøvariabel for den gjeldende økten export GITHUB_TOKEN="your_token_here" # Eller legg til i din .bashrc for varighet echo 'export GITHUB_TOKEN="your_token_here"' >> ~/.bashrc ``` **Porthåndtering**: - Codespaces oppdager automatisk når applikasjonen begynner å lytte på en port - Du kan videresende flere porter samtidig (nyttig hvis du senere legger til database) - Portene forblir tilgjengelige så lenge Codespace kjører **Utviklingsarbeidsflyt**: 1. Gjør kodeendringer i VS Code 2. FastAPI gjør auto-reload (takket være Uvicorns reload-modus) 3. Test endringene umiddelbart via den offentlige URLen 4. Commit og push når du er klar > 💡 **Pro tips**: Bokmerk backend-URLen for Codespace under utvikling. Siden Codespace-navn er stabile, vil ikke URLen endres så lenge du bruker samme Codespace. ## Lage frontend chatgrensesnitt: Der mennesker møter AI Nå skal vi bygge brukergrensesnittet – delen som bestemmer hvordan folk interagerer med AI-assistenten din. Som designet til den originale iPhonens grensesnitt, fokuserer vi på å gjøre kompleks teknologi intuitiv og naturlig å bruke. ### Forstå moderne frontend-arkitektur Chatgrensesnittet vårt vil være det vi kaller en "Single Page Application" eller SPA. I stedet for gammeldags tilnærming der hvert klikk laster en ny side, oppdaterer appen vår smidig og umiddelbart: **Gammeldagse nettsteder**: Som å lese en fysisk bok – du blar til helt nye sider **Vår chat-app**: Som å bruke telefonen – alt flyter og oppdateres sømløst ```mermaid graph TD A[Bruker skriver melding] --> B[JavaScript fanger opp input] B --> C[Valider og formater data] C --> D[Send til backend-API] D --> E[Vis lastingstilstand] E --> F[Motta AI-respons] F --> G[Oppdater chatgrensesnitt] G --> H[Klar for neste melding] ``` ```mermaid classDiagram class ChatApp { +messages: HTMLElement +form: HTMLElement +input: HTMLElement +sendButton: HTMLElement +BASE_URL: string +API_ENDPOINT: string +constructor() +initializeEventListeners() +handleSubmit(event) +callAPI(message) +appendMessage(tekst, rolle) +escapeHtml(tekst) +scrollToBottom() +setLoading(erLaster) } ChatApp --> DOM : manipulerer ChatApp --> FastAPI : sender forespørsler ``` ### De tre søylene i frontend-utvikling Hver frontend-applikasjon – fra enkle nettsider til komplekse apper som Discord eller Slack – er bygget på tre kjerne-teknologier. Tenk på dem som fundamentet for alt du ser og interagerer med på nettet: **HTML (Struktur)**: Dette er fundamentet ditt - Bestemmer hvilke elementer som finnes (knapper, tekstfelt, containere) - Gir mening til innhold (dette er en overskrift, dette er et skjema osv.) - Lager grunnstrukturen som alt annet bygger på **CSS (Presentasjon)**: Dette er interiørdesigneren din - Gjør alt vakkert (farger, fonter, layout) - Håndterer forskjellige skjermstørrelser (mobil, laptop, nettbrett) - Lager jevne animasjoner og visuell respons **JavaScript (Adferd)**: Dette er hjernen din - Responderer på brukerhandlinger (klikk, skriving, scrolling) - Kommuniserer med backend og oppdaterer siden - Gjør alt interaktivt og dynamisk **Tenk på det som arkitekturdesign:** - **HTML**: Den strukturelle planen (definere rom og sammenhenger) - **CSS**: Den estetiske og miljømessige designen (visuell stil og brukeropplevelse) - **JavaScript**: De mekaniske systemene (funksjonalitet og interaktivitet) ### Hvorfor moderne JavaScript-arkitektur betyr noe Chat-applikasjonen vår bruker moderne JavaScript-mønstre som du vil se i profesjonelle applikasjoner. Å forstå disse konseptene hjelper deg når du vokser som utvikler: **Klassebasert arkitektur**: Vi organiserer koden i klasser, som er som blåkopier for objekter **Async/Await**: Moderne måte å håndtere operasjoner som tar tid (som API-kall) **Hendelsesdrevet programmering**: Appen reagerer på brukerhandlinger (klikk, tastepress) i stedet for å kjøre i loop **DOM-manipulasjon**: Dynamisk oppdatering av nettsideinnhold basert på brukerhandlinger og API-svar ### Oppsett av prosjektstruktur Lag en frontend-mappe med denne organiserte strukturen: ```text frontend/ ├── index.html # Main HTML structure ├── app.js # JavaScript functionality └── styles.css # Visual styling ``` **Forstå arkitekturen:** - **Separasjon** av bekymringer mellom struktur (HTML), adferd (JavaScript) og presentasjon (CSS) - **Opprettholder** en enkel mappestruktur som er lett å navigere og endre - **Følger** beste praksis innen webutvikling for organisasjon og vedlikehold ### Bygge HTML-fundamentet: Semantisk struktur for tilgjengelighet La oss begynne med HTML-strukturen. Moderne webutvikling legger vekt på "semantisk HTML" – altså å bruke HTML-elementer som tydelig beskriver formålet sitt, ikke bare utseendet. Dette gjør appen din tilgjengelig for skjermlesere, søkemotorer og andre verktøy. **Hvorfor semantisk HTML er viktig**: Tenk deg at du skal beskrive chat-appen din til noen på telefon. Du ville sagt "det er en toppseksjon med tittel, et hovedområde hvor samtaler vises, og et skjema nederst for å skrive meldinger." Semantisk HTML bruker elementer som passer denne naturlige beskrivelsen. Lag `index.html` med denne gjennomtenkte, strukturerte markupen: ```html AI Chat Assistant

AI Chat Assistant

Ask me anything!

``` **Forstå hvert HTML-element og dets formål:** #### Dokumentstruktur - **``**: Forteller nettleseren at dette er moderne HTML5 - **``**: Angir sidens språk for skjermlesere og oversettelsesverktøy - **``**: Sikrer korrekt tegnkoding for internasjonal tekst - **``**: Gjør siden mobilvennlig ved å kontrollere zoom og skalering #### Semantiske elementer - **`
`**: Klart definerer toppseksjon med tittel og beskrivelse - **`
`**: Angir hovedinnholdsområdet (der samtalene vises) - **`
`**: Semantisk korrekt for brukerinput, muliggjør god tastaturnavigasjon #### Tilgjengelighetsfunksjoner - **`role="log"`**: Forteller skjermlesere at dette området inneholder en kronologisk logg over meldinger - **`aria-live="polite"`**: Annonserer nye meldinger til skjermlesere uten å forstyrre - **`aria-label`**: Gir beskrivende etiketter for formkontroller - **`required`**: Nettleseren validerer at brukere skriver inn en melding før sending #### CSS- og JavaScript-integrasjon - **`class` attributter**: Gir styling-kroker for CSS (f.eks. `chat-container`, `input-group`) - **`id` attributter**: Lar JavaScript finne og manipulere spesifikke elementer - **Script-plassering**: JavaScript-fil lastes inn til slutt slik at HTML laster først **Hvorfor denne strukturen fungerer:** - **Logisk flyt**: Header → Hovedinnhold → Inntastingsskjema samsvarer med naturlig lese-rekkefølge - **Tastaturvennlig**: Brukere kan navigere med tabulatortasten gjennom alle interaktive elementer - **Skjermleservennlig**: Klare landemerker og beskrivelser for synshemmede brukere - **Mobilresponsiv**: Viewport meta-tag muliggjør responsivt design - **Progressiv forbedring**: Fungerer selv om CSS eller JavaScript svikter å laste ### Legge til interaktiv JavaScript: Moderne webapplikasjonslogikk Nå skal vi bygge JavaScript som gir vår chattegrensesnitt liv. Vi bruker moderne JavaScript-mønstre som du vil møte i profesjonell webutvikling, inkludert ES6-klasser, async/await og hendelsesbasert programmering. #### Forstå Moderne JavaScript-arkitektur I stedet for å skrive prosedyrekode (en serie funksjoner som kjører i rekkefølge), lager vi en **klassebasert arkitektur**. Tenk på en klasse som en blåkopi for å lage objekter – slik en arkitekts tegninger kan brukes til å bygge flere hus. **Hvorfor bruke klasser for webapplikasjoner?** - **Organisering**: All relatert funksjonalitet er samlet - **Gjenbrukbarhet**: Du kan lage flere chatte-instans på samme side - **Vedlikeholdbarhet**: Enklere å feilsøke og endre spesifikke funksjoner - **Profesjonell standard**: Dette mønsteret brukes i rammeverk som React, Vue og Angular Lag `app.js` med denne moderne, godt strukturerte JavaScript: ```javascript // app.js - Moderne chat-applikasjonslogikk class ChatApp { constructor() { // Få referanser til DOM-elementer vi trenger å manipulere this.messages = document.getElementById("messages"); this.form = document.getElementById("chatForm"); this.input = document.getElementById("messageInput"); this.sendButton = document.getElementById("sendBtn"); // Konfigurer backend-URLen din her this.BASE_URL = "http://localhost:5000"; // Oppdater dette for ditt miljø this.API_ENDPOINT = `${this.BASE_URL}/hello`; // Sett opp event-lyttere når chat-appen opprettes this.initializeEventListeners(); } initializeEventListeners() { // Lytt etter innsending av skjema (når bruker klikker Send eller trykker Enter) this.form.addEventListener("submit", (e) => this.handleSubmit(e)); // Lytt også etter Enter-tasten i inndatafeltet (bedre brukeropplevelse) this.input.addEventListener("keypress", (e) => { if (e.key === "Enter" && !e.shiftKey) { e.preventDefault(); this.handleSubmit(e); } }); } async handleSubmit(event) { event.preventDefault(); // Forhindre at skjemaet oppdaterer siden const messageText = this.input.value.trim(); if (!messageText) return; // Ikke send tomme meldinger // Gi brukeren tilbakemelding om at noe skjer this.setLoading(true); // Legg til brukermelding i chatten umiddelbart (optimistisk UI) this.appendMessage(messageText, "user"); // Tøm inndatafeltet slik at brukeren kan skrive neste melding this.input.value = ''; try { // Kall AI-APIet og vent på svar const reply = await this.callAPI(messageText); // Legg til AI-respons i 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 { // Aktiver grensesnittet igjen uavhengig av suksess eller feil 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 = `
${this.escapeHtml(text)} ${new Date().toLocaleTimeString()}
`; 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 chatteapplikasjonen når siden lastes inn document.addEventListener("DOMContentLoaded", () => { new ChatApp(); }); ``` #### Forstå Hvert JavaScript-konsept **ES6 Klassestruktur**: ```javascript class ChatApp { constructor() { // Dette kjører når du oppretter en ny ChatApp-instans // Det er som "oppsett"-funksjonen for chatten din } methodName() { // Metoder er funksjoner som tilhører klassen // De kan få tilgang til klasseegenskaper ved å bruke "this" } } ``` **Async/Await-mønster**: ```javascript // Gammel måte (callback-helvete): fetch(url) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error(error)); // Moderne måte (async/await): try { const response = await fetch(url); const data = await response.json(); console.log(data); } catch (error) { console.error(error); } ``` **Hendelsesdrevet Programmering**: I stedet for konstant å sjekke om noe har skjedd, "lytter" vi etter hendelser: ```javascript // Når skjemaet sendes inn, kjør handleSubmit this.form.addEventListener("submit", (e) => this.handleSubmit(e)); // Når Enter-tasten trykkes, kjør også handleSubmit this.input.addEventListener("keypress", (e) => { /* ... */ }); ``` **DOM-manipulasjon**: ```javascript // Opprett nye elementer const messageElement = document.createElement("div"); // Endre deres egenskaper messageElement.className = "message user"; messageElement.innerHTML = "Hello world!"; // Legg til på siden this.messages.appendChild(messageElement); ``` #### Sikkerhet og Beste Praksis **XSS-forebygging**: ```javascript escapeHtml(text) { const div = document.createElement('div'); div.textContent = text; // Dette unngår HTML automatisk return div.innerHTML; } ``` **Hvorfor dette er viktig**: Hvis en bruker skriver ``, sørger denne funksjonen for at det vises som tekst i stedet for å kjøre som kode. **Feilhåndtering**: ```javascript try { const reply = await this.callAPI(messageText); this.appendMessage(reply, "assistant"); } catch (error) { // Vis brukervennlig feil i stedet for å krasje appen this.appendMessage("Sorry, I'm having trouble...", "error"); } ``` **Brukeropplevelsehensyn**: - **Optimistisk UI**: Legg til brukermelding umiddelbart, ikke vent på serverrespons - **Lastetilstander**: Deaktiver knapper og vis "Sender..." mens du venter - **Autoscroll**: Hold nyeste meldinger synlige - **Input-validering**: Ikke send tomme meldinger - **Snarveier på tastatur**: Enter-tast sender meldinger (som i ekte chatteapper) #### Forstå Applikasjonsflyten 1. **Side lastes inn** → `DOMContentLoaded`-hendelsen trigges → `new ChatApp()` opprettes 2. **Konstruktør kjører** → Henter DOM-elementreferanser → Setter opp hendelseslyttere 3. **Bruker skriver melding** → Trykker Enter eller klikker Send → `handleSubmit` kjører 4. **handleSubmit** → Validerer input → Viser lastetilstand → Kaller API 5. **API svarer** → Legger til AI-melding i chat → Aktiverer grensesnitt på nytt 6. **Klar for neste melding** → Bruker kan fortsette å chatte Denne arkitekturen er skalerbar – du kan enkelt legge til funksjoner som meldingsredigering, filopplastinger eller flere samtaletråder uten å omskrive kjerneoppsettet. ### 🎯 Pedagogisk Sjekkpunkt: Moderne Frontend-arkitektur **Forståelse av arkitektur**: Du har implementert en komplett enkelt-sides applikasjon med moderne JavaScript-mønstre. Dette representerer profesjonell frontend-utvikling på høyeste nivå. **Nøkkelkonsepter mestret**: - **ES6 Klassearkitektur**: Organisert, vedlikeholdbar kode - **Async/Await-mønstre**: Moderne asynkron programmering - **Hendelsesdrevet Programmering**: Responsivt brukergrensesnitt - **Beste praksis for sikkerhet**: XSS-forebygging og input-validering **Bransjetilknytning**: Mønstrene du har lært (klassebasert arkitektur, asynkrone operasjoner, DOM-manipulasjon) er grunnlaget for moderne rammeverk som React, Vue og Angular. Du bygger med samme arkitektoniske tankegang som i produksjonsapplikasjoner. **Refleksjonsspørsmål**: Hvordan ville du utvidet denne chatteapplikasjonen for å håndtere flere samtaler eller brukerautentisering? Tenk på hvilke arkitektoniske endringer som trengs og hvordan klassestrukturen ville utvikle seg. ### Style ditt chattegrensesnitt Nå lager vi et moderne, visuelt tiltalende chattegrensesnitt med CSS. God styling gjør applikasjonen din profesjonell og forbedrer brukeropplevelsen. Vi bruker moderne CSS-funksjoner som Flexbox, CSS Grid og tilpassede egenskaper for et responsivt og tilgjengelig design. Lag `styles.css` med denne omfattende stilen: ```css /* 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å CSS-arkitekturen:** - **Bruker** CSS-tilpassede egenskaper (variabler) for konsistent tema og lett vedlikehold - **Implementerer** Flexbox-layout for responsivt design og riktig justering - **Inkluderer** jevne animasjoner ved meldingsvisning uten å være distraherende - **Gir** visuell forskjell mellom brukermeldinger, AI-responser og feiltilstander - **Støtter** responsivt design som fungerer på både desktop og mobil - **Tar hensyn til** tilgjengelighet med redusert bevegelse og riktig kontrast - **Tilbyr** mørk modus basert på brukerens systempreferanser ### Konfigurere backend-URLen din Det siste steget er å oppdatere `BASE_URL` i JavaScript til din backend-server: ```javascript // For lokal utvikling this.BASE_URL = "http://localhost:5000"; // For GitHub Codespaces (erstatt med din faktiske URL) this.BASE_URL = "https://your-codespace-name-5000.app.github.dev"; ``` **Bestemme backend-URL:** - **Lokal utvikling**: Bruk `http://localhost:5000` hvis både frontend og backend kjører lokalt - **Codespaces**: Finn backend-URL i Ports-fanen etter å ha gjort port 5000 offentlig - **Produksjon**: Bytt ut med ditt faktiske domene når du distribuerer til en hosting-tjeneste > 💡 **Testtips**: Du kan teste backend direkte ved å besøke rot-URL i nettleseren. Du bør se velkomstmeldingen fra FastAPI-serveren din. ## Testing og Distribusjon Nå som du har både frontend- og backend-komponentene klare, la oss teste at alt fungerer sammen og se på distribusjonsmuligheter for å dele chat-assistenten med andre. ### Lokal testingsprosess Følg disse trinnene for å teste den komplette applikasjonen: ```mermaid graph TD A[Start Backend-server] --> B[Konfigurer miljøvariabler] B --> C[Test API-endepunkter] C --> D[Åpne frontend i nettleser] D --> E[Test chatfunksjonalitet] E --> F[Feilsøk eventuelle problemer] ``` **Steg-for-steg testing:** 1. **Start backend-serveren din**: ```bash cd backend source venv/bin/activate # eller venv\Scripts\activate på Windows python api.py ``` 2. **Verifiser at API fungerer**: - Åpne `http://localhost:5000` i nettleseren - Du skal se velkomstmeldingen fra FastAPI-serveren 3. **Åpne frontend**: - Naviger til frontend-katalogen din - Åpne `index.html` i nettleseren - Eller bruk VS Code Live Server-utvidelsen for bedre utviklingsopplevelse 4. **Test chattefunksjonaliteten**: - Skriv en melding i inputfeltet - Klikk "Send" eller trykk Enter - Sjekk at AI svarer korrekt - Kontroller nettleserkonsollen for eventuelle JavaScript-feil ### Vanlige problemer og løsninger | Problem | Symptomer | Løsning | |---------|----------|----------| | **CORS-feil** | Frontend får ikke kontakt med backend | Sørg for at FastAPI CORSMiddleware er korrekt konfigurert | | **API-nøkkelfeil** | 401 Unauthorized-svar | Sjekk `GITHUB_TOKEN` miljøvariabelen din | | **Connection Refused** | Nettverksfeil i frontend | Verifiser backend-URL og at Flask-serveren kjører | | **Ingen AI-svar** | Tomme eller feilsvar | Se gjennom backend-logger for API-kvote eller autentiseringsproblemer | **Vanlige feilsøkingstrinn:** - **Sjekk** nettleserens Utviklerverktøy-konsoll for JavaScript-feil - **Bekreft** at Nettverk-fanen viser vellykkede API-forespørsler og svar - **Gjennomgå** backend-terminal for Python-feil eller API-problemer - **Sjekk** at miljøvariabler er lastet og tilgjengelige ## 📈 Din Tidslinje for AI-applikasjonsutvikling ```mermaid timeline title Fullstendig AI-applikasjonsutviklingsreise section AI-grunnlag Forstå generativ AI : Forstå mønstergjenkjenningskonsepter : Mestre AI parameterkontroll : Lær prompt engineering teknikker GitHub-modellintegrasjon : Naviger AI tjenesteplattformer : Håndter autentisering sikkert : Optimaliser modellparametre section Backend-utvikling Python API-arkitektur : Bygg FastAPI-applikasjoner : Implementer asynkrone operasjoner : Lag sikre endepunkter AI-tjenesteintegrasjon : Koble til eksterne AI-APIer : Håndter rate limiting : Implementer feilsonegrenser section Frontend-mestring Moderne JavaScript-mønstre : Mestre ES6 klassearkitektur : Implementer async/await flyt : Bygg responsive grensesnitt Sanntids brukeropplevelse : Lag dynamiske chattegrensesnitt : Håndter lastetilstander : Optimaliser brukerinteraksjoner section Produksjonsberedskap Sikkerhet & ytelse : Implementer sikker tokenhåndtering : Forhindre XSS-sårbarheter : Optimaliser API-ytelse Profesjonell distribusjon : Bygg skalerbare arkitekturer : Lag vedlikeholdbar kode : Dokumenter utviklingsprosesser ``` **🎓 Avslutningsmilepæl**: Du har bygget en komplett AI-drevet applikasjon med de samme teknologiene og arkitekturprinsippene som driver moderne AI-assistenter. Disse ferdighetene representerer skjæringspunktet mellom tradisjonell webutvikling og banebrytende AI-integrasjon. **🔄 Neste nivå kapasiteter**: - Klar for å utforske avanserte AI-rammeverk (LangChain, LangGraph) - Forberedt på å bygge multimodale AI-applikasjoner (tekst, bilde, stemme) - Utstyrt til å implementere vektordatabaser og gjenfinningssystemer - Grunnlag lagt for maskinlæring og AI-modellfinjustering ## GitHub Copilot Agent Challenge 🚀 Bruk agentmodus til å fullføre følgende utfordring: **Beskrivelse:** Forbedre chat-assistenten ved å legge til samtalehistorikk og meldinglagring. Denne utfordringen hjelper deg å forstå hvordan du håndterer tilstand i chat-applikasjoner og implementerer datalagring for bedre brukeropplevelse. **Oppgave:** Endre chatteapplikasjonen slik at samtalehistorikk bevares mellom økter. Legg til funksjonalitet for å lagre chatmeldinger i lokal lagring, vis samtalehistorikk ved sideinnlasting, og inkluder en "Tøm Historikk"-knapp. Implementer også skriveindikatorer og tidsstempel på meldinger for en mer realistisk chatteopplevelse. Les mer om [agent mode](https://code.visualstudio.com/blogs/2025/02/24/introducing-copilot-agent-mode) her. ## Oppgave: Bygg Din Personlige AI-assistent Nå skal du lage din egen AI-assistent. I stedet for bare å kopiere kode fra denne veiledningen, er dette en mulighet til å bruke kunnskapen mens du bygger noe som reflekterer dine interesser og brukstilfeller. ### Prosjektkrav La oss sette opp prosjektet ditt med en ryddig, organisert struktur: ```text 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 ``` ### Kjerneoppgaver for implementering **Backend-utvikling:** - **Ta** vår FastAPI-kode og gjør den til din egen - **Lag** en unik AI-personlighet – kanskje en hjelpsom matlagingsassistent, kreativ skrivepartner eller studiekamerat? - **Legg til** solid feilhåndtering slik at appen ikke krasjer ved problemer - **Skriv** tydelig dokumentasjon for alle som ønsker å forstå API-en din **Frontend-utvikling:** - **Bygg** et chattegrensesnitt som føles intuitivt og innbydende - **Skriv** ren, moderne JavaScript som du kan være stolt av å vise andre utviklere - **Design** spesialtilpasset stil som gjenspeiler AI-personligheten din – morsom og fargerik? Ren og minimalistisk? Bare fantasien setter grenser! - **Sørg for** at det fungerer godt på både mobil og desktop **Personalisering:** - **Velg** et unikt navn og personlighet for AI-assistenten – noe som reflekterer dine interesser eller problemstillinger du vil løse - **Tilpass** det visuelle designet til assistentens stil - **Skriv** en engasjerende velkomstmelding som gjør at folk vil begynne å chatte - **Test** assistenten med ulike spørsmål for å se responsen ### Forbedringsideer (valgfritt) Vil du ta prosjektet til neste nivå? Her er morsomme ideer å utforske: | Funksjon | Beskrivelse | Ferdigheter du øver på | |---------|-------------|------------------------| | **Meldingshistorikk** | Husk samtaler selv etter sideoppdatering | Arbeide med localStorage, JSON | | **Skriveindikatorer** | Vis "AI skriver..." mens det venter på svar | CSS-animasjoner, asynkron programmering | | **Meldingers tidsstempel** | Vis når hver melding ble sendt | Dato-/tidsformatering, UX-design | | **Eksportere chat** | La brukere laste ned samtalen sin | Filhåndtering, dataeksport | | **Temabytting** | Lys/mørk modusbryter | CSS-variabler, brukerpreferanser | | **Talestyring** | Legg til tale-til-tekst-funksjonalitet | Web-APIer, tilgjengelighet | ### Testing og dokumentasjon **Kvalitetssikring:** - **Test** applikasjonen med ulike inputtyper og ekstreme tilfeller - **Bekreft** at responsivt design fungerer på ulike skjermstørrelser - **Sjekk** tilgjengelighet med tastaturnavigasjon og skjermlesere - **Valider** HTML og CSS for standardkompatibilitet **Dokumentasjonskrav:** - **Skriv** en README.md som forklarer prosjektet og hvordan det kjøres - **Inkluder** skjermbilder av chattegrensesnittet i bruk - **Dokumenter** eventuelle unike funksjoner eller tilpasninger - **Gi** klare installasjonsinstruksjoner for andre utviklere ### Innleveringskrav **Prosjektleveranser:** 1. Fullstendig prosjektmappe med all kildekode 2. README.md med prosjektbeskrivelse og installasjonsveiledning 3. Skjermbilder som viser chat-assistenten i bruk 4. Kort refleksjon om hva du lærte og hvilke utfordringer du møtte **Evalueringskriterier:** - **Funksjonalitet**: Fungerer chat-assistenten som forventet? - **Kodekvalitet**: Er koden godt organisert, kommentert og vedlikeholdbar? - **Design**: Er grensesnittet visuelt tiltalende og brukervennlig? - **Kreativitet**: Hvor unik og personlig er implementasjonen? - **Dokumentasjon**: Er installasjonsinstruksjoner tydelige og fullstendige? > 💡 **Suksesstips**: Start med grunnleggende krav først, legg til forbedringer etter at alt fungerer. Fokuser på å skape en polert kjerneopplevelse før avanserte funksjoner legges til. ## Løsning [Løsning](./solution/README.md) ## Bonusutfordringer Klar for å ta AI-assistenten din til neste nivå? Prøv disse avanserte utfordringene som utdyper AI-integrasjon og webutvikling. ### Personlig tilpasning Den virkelige magien skjer når du gir AI-assistenten din en unik personlighet. Eksperimenter med forskjellige systemprompter for å lage spesialiserte assistenter: **Profesjonell assistent-eksempel:** ```python call_llm(message, "You are a professional business consultant with 20 years of experience. Provide structured, actionable advice with specific steps and considerations.") ``` **Kreativ skrivehjelper-eksempel:** ```python 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:** ```python call_llm(message, "You are a patient senior developer who explains complex programming concepts using simple analogies and practical examples.") ``` ### Frontend-forbedringer Forvandle chattegrensesnittet ditt med disse visuelle og funksjonelle oppgraderingene: **Avanserte CSS-funksjoner:** - **Implementer** jevne melding animasjoner og overganger - **Legg til** spesialdesignede chatbobler med CSS-former og gradienter - **Lag** en skriveindikator-animasjon som viser når AI "tenker" - **Design** emoji-reaksjoner eller meldingsvurderingssystem **JavaScript-forbedringer:** - **Legg til** tastatursnarveier (Ctrl+Enter for send, Escape for å tømme input) - **Implementer** meldingssøk og filtreringsfunksjonalitet - **Lag** samtaleeksportfunksjon (last ned som tekst eller JSON) - **Legg til** automatisk lagring i localStorage for å unngå meldings-tap ### Avansert AI-integrasjon **Flere AI-personligheter:** - **Lag** en nedtrekksmeny for å bytte mellom AI-personligheter - **Lagre** brukerens foretrukne personlighet i localStorage - **Implementer** kontekstskifting som opprettholder samtaleflyt **Smartsvar-funksjoner:** - **Legg til** samtalekontekstkunnskap (AI husker tidligere meldinger) - **Implementer** smarte forslag basert på samtaletema - **Opprett** raske svar-knapper for vanlige spørsmål > 🎯 **Læringsmål**: Disse bonusutfordringene hjelper deg med å forstå avanserte webutviklingsmønstre og AI-integrasjonsteknikker som brukes i produksjonsapplikasjoner. ## Oppsummering og neste steg Gratulerer! Du har med suksess bygget en komplett AI-drevet chatassistent fra bunnen av. Dette prosjektet har gitt deg praktisk erfaring med moderne webutviklingsteknologier og AI-integrasjon – ferdigheter som blir stadig mer verdifulle i dagens teknologilandskap. ### Hva du har oppnådd Gjennom denne leksjonen har du mestret flere viktige teknologier og konsepter: **Backend-utvikling:** - **Integrert** med GitHub Models API for AI-funksjonalitet - **Bygget** et RESTful API med Flask med riktig feilhåndtering - **Implementert** sikker autentisering ved bruk av miljøvariabler - **Konfigurert** CORS for tverr-opprinnelse forespørsler mellom frontend og backend **Frontend-utvikling:** - **Opprettet** et responsivt chattegrensesnitt med semantisk HTML - **Implementert** moderne JavaScript med async/await og klassebasert arkitektur - **Designet** en engasjerende brukergrensesnitt med CSS Grid, Flexbox og animasjoner - **Lagt til** tilgjengelighetsfunksjoner og responsive designprinsipper **Full-stack integrasjon:** - **Koblet** frontend og backend gjennom HTTP API-kall - **Håndtert** sanntidsbrukerinteraksjoner og asynkron dataflyt - **Implementert** feilhåndtering og brukerfeedback gjennom applikasjonen - **Testet** hele applikasjonsflyten fra brukerinput til AI-svar ### Viktige læringsutbytter ```mermaid mindmap root((AI Chat App Ferdigheter)) API Integration Authentication Error Handling Async Programming Web Development HTML5 Semantics Modern CSS ES6+ JavaScript User Experience Responsive Design Accessibility Real-time Interaction AI Understanding Prompt Engineering Model Parameters Conversation Flow ``` Dette prosjektet har introdusert deg for grunnleggende prinsipper for å bygge AI-drevne applikasjoner, som representerer fremtiden for webutvikling. Du forstår nå hvordan du kan integrere AI-funksjonalitet i tradisjonelle webapplikasjoner, og skape engasjerende brukeropplevelser som føles intelligente og responsive. ### Profesjonelle anvendelser Ferdighetene du har utviklet i denne leksjonen er direkte anvendelige i moderne programvareutviklingskarrierer: - **Full-stack webutvikling** med moderne rammeverk og APIer - **AI-integrasjon** i webapplikasjoner og mobilapper - **API-design og utvikling** for mikrotjenestearkitekturer - **Utvikling av brukergrensesnitt** med fokus på tilgjengelighet og responsivt design - **DevOps-praksis** inkludert miljøkonfigurasjon og distribusjon ### Fortsett din AI-utviklingsreise **Neste læringstrinn:** - **Utforsk** mer avanserte AI-modeller og APIer (GPT-4, Claude, Gemini) - **Lær** om prompt engineering-teknikker for bedre AI-responser - **Studer** samtaledesign og prinsipper for chatbot-brukeropplevelse - **Undersøk** AI-sikkerhet, etikk og ansvarlig AI-utvikling - **Bygg** mer komplekse applikasjoner med samtaleminne og kontekstbevissthet **Avanserte prosjektideer:** - Flersbruker chatrom med AI-moderasjon - AI-drevne kundeservice-chatboter - Utdanningsassistenter med personlig læring - Kreative skrive-samarbeidspartnere med ulike AI-personligheter - Teknisk dokumentasjonsassistenter for utviklere ## Kom i gang med GitHub Codespaces Vil du prøve dette prosjektet i et skybasert utviklingsmiljø? GitHub Codespaces tilbyr en komplett utviklingsoppsett i nettleseren, perfekt for å eksperimentere med AI-applikasjoner uten lokale oppsettskrav. ### Oppsett av ditt utviklingsmiljø **Steg 1: Opprett fra mal** - **Naviger** til [Web Dev For Beginners repository](https://github.com/microsoft/Web-Dev-For-Beginners) - **Klikk** på "Use this template" øverst til høyre (sørg for at du er logget inn på GitHub) ![Create from template interface showing the green "Use this template" button](../../../translated_images/no/template.67ad477109d29a2b.webp) **Steg 2: Start Codespaces** - **Åpne** ditt nylig opprettede repository - **Klikk** på den grønne "Code"-knappen og velg "Codespaces" - **Velg** "Create codespace on main" for å starte utviklingsmiljøet ditt ![Create codespace interface with options for launching cloud development environment](../../../translated_images/no/codespace.bcecbdf5d2747d3d.webp) **Steg 3: Miljøkonfigurasjon** Når Codespace lastes inn, får du tilgang til: - **Forhåndsinstallert** Python, Node.js og alle nødvendige utviklingsverktøy - **VS Code-grensesnitt** med utvidelser for webutvikling - **Terminaltilgang** for å kjøre backend- og frontend-servere - **Port forwarding** for testing av applikasjonene dine **Hva Codespaces tilbyr:** - **Eliminerer** problemer med lokal miljøoppsett og konfigurasjon - **Gir** konsekvent utviklingsmiljø på tvers av ulike enheter - **inkluderer** forhåndskonfigurerte verktøy og utvidelser for webutvikling - **Tilbyr** sømløs integrasjon med GitHub for versjonskontroll og samarbeid > 🚀 **Profftips**: Codespaces er perfekt for læring og prototyping av AI-applikasjoner siden det håndterer all kompleks miljøoppsett automatisk, slik at du kan fokusere på bygging og læring i stedet for feilsøking av konfigurering. --- **Ansvarsfraskrivelse**: Dette dokumentet er oversatt ved hjelp av AI-oversettelsestjenesten [Co-op Translator](https://github.com/Azure/co-op-translator). Selv om vi streber etter nøyaktighet, vennligst vær oppmerksom på at automatiske oversettelser kan inneholde feil eller unøyaktigheter. Det opprinnelige dokumentet på originalspråket skal anses som den autoritative kilden. For kritisk informasjon anbefales profesjonell menneskelig oversettelse. Vi er ikke ansvarlige for misforståelser eller feiltolkninger som følge av bruk av denne oversettelsen.