# Изградите асистента за ћаскање уз помоћ вештачке интелигенције
Сећате ли се у серији Звездане стазе када је посада опуштено разговарала са рачунаром брода, постављала му сложена питања и добијала промишљене одговоре? Оно што је изгледало као чиста научна фантастика 1960-их, сада је нешто што можете сами да направите користећи веб технологије које већ познајете.
У овом упутству ћемо направити асистента за ћаскање са вештачком интелигенцијом користећи HTML, CSS, JavaScript и неку позадинску интеграцију. Открићете како исте вештине које сте до сада учили могу да се повежу са моћним AI сервисима који разумеју контекст и генеришу смислене одговоре.
Замислите AI као приступ огромној библиотеци која не само да може да пронађе информације, већ и да их синтетизује у кохерентне одговоре прилагођене вашим специфичним питањима. Уместо да претражујете хиљаде страница, добијате директне, контекстуалне одговоре.
Интеграција се дешава кроз познате веб технологије које раде заједно. HTML креира интерфејс за ћаскање, CSS се брине о визуелном дизајну, JavaScript управља интеракцијама корисника, а позадински API повезује све са AI сервисима. То је слично као када различити делови оркестра раде заједно да би створили симфонију.
У суштини, градимо мост између природне људске комуникације и машинске обраде. Научићете како да технички имплементирате интеграцију AI сервиса и дизајнерске обрасце који чине интеракције интуитивним.
До краја овог упутства, интеграција AI-а ће вам изгледати мање као мистериозан процес, а више као још један API са којим можете радити. Разумећете основне обрасце који покрећу апликације попут ChatGPT-а и Claude-а, користећи исте принципе веб развоја које сте већ учили.
Ево како ће изгледати ваш завршени пројекат:

## Разумевање AI-а: Од мистерије до мајсторства
Пре него што се упустимо у код, хајде да разумемо са чим радимо. Ако сте раније користили API-је, знате основни образац: пошаљите захтев, примите одговор.
AI API-ји следе сличну структуру, али уместо да преузимају унапред сачуване податке из базе, они генеришу нове одговоре на основу образаца научених из огромних количина текста. Замислите то као разлику између библиотечког каталога и знајућег библиотекара који може синтетизовати информације из више извора.
### Шта је заправо "Генеративна вештачка интелигенција"?
Размислите како је Розетски камен омогућио научницима да разумеју египатске хијероглифе проналазећи обрасце између познатих и непознатих језика. AI модели раде на сличан начин – проналазе обрасце у огромним количинама текста како би разумели како језик функционише, а затим користе те обрасце за генерисање одговарајућих одговора на нова питања.
**Да вам то објасним једноставним поређењем:**
- **Традиционална база података**: Као да тражите извод из матичне књиге рођених – увек добијате исти документ
- **Претраживач**: Као да питате библиотекара да пронађе књиге о мачкама – он вам показује шта је доступно
- **Генеративна AI**: Као да питате знајућег пријатеља о мачкама – он вам прича занимљиве ствари својим речима, прилагођене ономе што желите да знате
```mermaid
graph LR
A[Your Question] --> B[AI Model]
B --> C[Pattern Recognition]
C --> D[Content Generation]
D --> E[Contextual Response]
F[Training Data
Books, Articles, Web] --> B
```
### Како AI модели уче (једноставна верзија)
AI модели уче кроз излагање огромним скуповима података који садрже текст из књига, чланака и разговора. Кроз овај процес, они идентификују обрасце у:
- Како су мисли структурисане у писаној комуникацији
- Које речи се обично појављују заједно
- Како разговори обично теку
- Контекстуалне разлике између формалне и неформалне комуникације
**То је слично начину на који археолози дешифрују древне језике**: анализирају хиљаде примера како би разумели граматику, вокабулар и културни контекст, и на крају постају способни да тумаче нове текстове користећи те научене обрасце.
### Зашто GitHub Models?
Користимо GitHub Models из веома практичног разлога – пружа нам приступ AI-у на нивоу предузећа без потребе да постављамо сопствену AI инфраструктуру (што, верујте ми, тренутно не желите да радите!). Замислите то као коришћење API-ја за временску прогнозу уместо да сами покушавате да предвидите време постављањем метеоролошких станица свуда.
То је у суштини "AI као услуга", а најбољи део? Бесплатно је за почетак, тако да можете експериментисати без бриге о великим трошковима.
```mermaid
graph LR
A[Frontend Chat UI] --> B[Your Backend API]
B --> C[GitHub Models API]
C --> D[AI Model Processing]
D --> C
C --> B
B --> A
```
Користићемо GitHub Models за нашу позадинску интеграцију, која пружа приступ професионалним AI могућностима кроз интерфејс прилагођен програмерима. [GitHub Models Playground](https://github.com/marketplace/models/azure-openai/gpt-4o-mini/playground) служи као тестно окружење где можете експериментисати са различитим AI моделима и разумети њихове могућности пре него што их имплементирате у код.

**Ево шта чини овај playground тако корисним:**
- **Испробајте** различите AI моделе као што су GPT-4o-mini, Claude и други (све бесплатно!)
- **Тестирајте** своје идеје и упите пре него што напишете било какав код
- **Добијте** готове кодне исечке на вашем омиљеном програмском језику
- **Прилагодите** поставке као што су ниво креативности и дужина одговора да видите како утичу на резултате
Када се мало поиграте, само кликните на картицу "Code" и изаберите свој програмски језик да бисте добили код за имплементацију који вам је потребан.

## Постављање Python позадинске интеграције
Сада ћемо имплементирати AI интеграцију користећи Python. Python је одличан за AI апликације због своје једноставне синтаксе и моћних библиотека. Почећемо са кодом из GitHub Models playground-а, а затим га прерадити у функцију која се може поново користити и која је спремна за производњу.
### Разумевање основне имплементације
Када преузмете Python код из playground-а, добићете нешто што изгледа овако. Не брините ако вам се на први поглед чини компликовано – хајде да га разложимо део по део:
```python
"""Run this model in Python
> pip install openai
"""
import os
from openai import OpenAI
# To authenticate with the model you will need to generate a personal access token (PAT) in your GitHub settings.
# Create your PAT token by following instructions here: https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens
client = OpenAI(
base_url="https://models.github.ai/inference",
api_key=os.environ["GITHUB_TOKEN"],
)
```python
response = client.chat.completions.create(
messages=[
{
"role": "system",
"content": "",
},
{
"role": "user",
"content": "What is the capital of France?",
}
],
model="openai/gpt-4o-mini",
temperature=1,
max_tokens=4096,
top_p=1
)
print(response.choices[0].message.content)
```
**Ево шта се дешава у овом коду:**
- **Увозимо** алатке које су нам потребне: `os` за читање променљивих окружења и `OpenAI` за комуникацију са AI-јем
- **Постављамо** OpenAI клијента да се повеже са GitHub-овим AI серверима уместо директно са OpenAI-јем
- **Аутентификујемо се** користећи посебан GitHub токен (о томе више касније!)
- **Структуришемо** наш разговор са различитим "улогама" – замислите то као постављање сцене за представу
- **Шаљемо** наш захтев AI-ју са неким параметрима за фино подешавање
- **Извлачимо** стварни текст одговора из свих података који се враћају
### Разумевање улога порука: Оквир за AI разговоре
AI разговори користе специфичну структуру са различитим "улогама" које имају одређене сврхе:
```python
messages=[
{
"role": "system",
"content": "You are a helpful assistant who explains things simply."
},
{
"role": "user",
"content": "What is machine learning?"
}
]
```
**Замислите то као режирање представе:**
- **Улога система**: Као сценска упутства за глумца – говори AI-ју како да се понаша, коју личност да има и како да одговара
- **Улога корисника**: Стварно питање или порука од особе која користи вашу апликацију
- **Улога асистента**: Одговор AI-ја (не шаљете ово, али се појављује у историји разговора)
**Аналогија из стварног живота**: Замислите да представљате пријатеља некоме на забави:
- **Порука система**: "Ово је моја пријатељица Сара, она је докторка која одлично објашњава медицинске концепте на једноставан начин"
- **Порука корисника**: "Можете ли ми објаснити како функционишу вакцине?"
- **Одговор асистента**: Сара одговара као љубазна докторка, а не као адвокат или кувар
### Разумевање AI параметара: Фино подешавање понашања одговора
Нумерички параметри у AI API позивима контролишу како ће модел генерисати одговоре. Ова подешавања вам омогућавају да прилагодите понашање AI-ја за различите намене:
#### Температура (0.0 до 2.0): Дугме за креативност
**Шта ради**: Контролише колико ће креативни или предвидљиви бити одговори AI-ја.
**Замислите то као ниво импровизације џез музичара:**
- **Температура = 0.1**: Свирање исте мелодије сваки пут (веома предвидљиво)
- **Температура = 0.7**: Додавање неких лепих варијација уз задржавање препознатљивости (уравнотежена креативност)
- **Температура = 1.5**: Потпуно експериментални џез са неочекиваним обртима (веома непредвидљиво)
```python
# Very predictable responses (good for factual questions)
response = client.chat.completions.create(
messages=[{"role": "user", "content": "What is 2+2?"}],
temperature=0.1 # Will almost always say "4"
)
# Creative responses (good for brainstorming)
response = client.chat.completions.create(
messages=[{"role": "user", "content": "Write a creative story opening"}],
temperature=1.2 # Will generate unique, unexpected stories
)
```
#### Максимални број токена (1 до 4096+): Контролор дужине одговора
**Шта ради**: Поставља ограничење на то колико дугачак одговор AI може бити.
**Замислите токене као приближно еквивалентне речима** (отприлике 1 токен = 0.75 речи на енглеском):
- **max_tokens=50**: Кратко и јасно (као текстуална порука)
- **max_tokens=500**: Леп параграф или два
- **max_tokens=2000**: Детаљно објашњење са примерима
```python
# Short, concise answers
response = client.chat.completions.create(
messages=[{"role": "user", "content": "Explain JavaScript"}],
max_tokens=100 # Forces a brief explanation
)
# Detailed, comprehensive answers
response = client.chat.completions.create(
messages=[{"role": "user", "content": "Explain JavaScript"}],
max_tokens=1500 # Allows for detailed explanations with examples
)
```
#### Top_p (0.0 до 1.0): Параметар фокуса
**Шта ради**: Контролише колико се AI фокусира на највероватније одговоре.
**Замислите AI са огромним речником, рангираним по томе колико је вероватна свака реч:**
- **top_p=0.1**: Узима у обзир само највероватнијих 10% речи (веома фокусирано)
- **top_p=0.9**: Узима у обзир 90% могућих речи (креативније)
- **top_p=1.0**: Узима у обзир све (максимална разноврсност)
**На пример**: Ако питате "Небо је обично..."
- **Низак top_p**: Скоро сигурно каже "плаво"
- **Висок top_p**: Може рећи "плаво", "облачно", "пространо", "променљиво", "прелепо" итд.
### Спајање свега: Комбинације параметара за различите намене
```python
# For factual, consistent answers (like a documentation bot)
factual_params = {
"temperature": 0.2,
"max_tokens": 300,
"top_p": 0.3
}
# For creative writing assistance
creative_params = {
"temperature": 1.1,
"max_tokens": 1000,
"top_p": 0.9
}
# For conversational, helpful responses (balanced)
conversational_params = {
"temperature": 0.7,
"max_tokens": 500,
"top_p": 0.8
}
```
**Разумевање зашто су ови параметри важни**: Различите апликације захтевају различите типове одговора. Бот за корисничку подршку треба да буде конзистентан и чињеничан (ниска температура), док асистент за креативно писање треба да буде маштовит и разноврстан (висока температура). Разумевање ових параметара вам даје контролу над личношћу и стилом одговора вашег AI-ја.
```
**Here's what's happening in this code:**
- **We import** the tools we need: `os` for reading environment variables and `OpenAI` for talking to the AI
- **We set up** the OpenAI client to point to GitHub's AI servers instead of OpenAI directly
- **We authenticate** using a special GitHub token (more on that in a minute!)
- **We structure** our conversation with different "roles" – think of it like setting the scene for a play
- **We send** our request to the AI with some fine-tuning parameters
- **We extract** the actual response text from all the data that comes back
> 🔐 **Security Note**: Never hardcode API keys in your source code! Always use environment variables to store sensitive credentials like your `GITHUB_TOKEN`.
### Creating a Reusable AI Function
Let's refactor this code into a clean, reusable function that we can easily integrate into our web application:
```python
import asyncio
from openai import AsyncOpenAI
# Use AsyncOpenAI for better performance
client = AsyncOpenAI(
base_url="https://models.github.ai/inference",
api_key=os.environ["GITHUB_TOKEN"],
)
async def call_llm_async(prompt: str, system_message: str = "You are a helpful assistant."):
"""
Sends a prompt to the AI model asynchronously and returns the response.
Args:
prompt: The user's question or message
system_message: Instructions that define the AI's behavior and personality
Returns:
str: The AI's response to the prompt
"""
try:
response = await client.chat.completions.create(
messages=[
{
"role": "system",
"content": system_message,
},
{
"role": "user",
"content": prompt,
}
],
model="openai/gpt-4o-mini",
temperature=1,
max_tokens=4096,
top_p=1
)
return response.choices[0].message.content
except Exception as e:
logger.error(f"AI API error: {str(e)}")
return "I'm sorry, I'm having trouble processing your request right now."
# Backward compatibility function for synchronous calls
def call_llm(prompt: str, system_message: str = "You are a helpful assistant."):
"""Synchronous wrapper for async AI calls."""
return asyncio.run(call_llm_async(prompt, system_message))
```
**Разумевање ове побољшане функције:**
- **Прихвата** два параметра: упит корисника и опционалну поруку система
- **Пружа** подразумевану поруку система за опште понашање асистента
- **Користи** исправне Python типске наговештаје за бољу документацију кода
- **Враћа** само садржај одговора, што га чини лако употребљивим у нашем веб API-ју
- **Одржава** исте параметре модела за конзистентно понашање AI-ја
### Магија системских упита: Програмирање личности AI-ја
Ако параметри контролишу како AI размишља, системски упити контролишу ко AI мисли да јесте. Ово је заиста један од најзанимљивијих аспеката рада са AI-јем – у суштини, дајете AI-ју комплетну личност, ниво експертизе и стил комуникације.
**Замислите системске упите као одабир различитих глумаца за различите улоге**: Уместо да имате једног генеричког асистента, можете креирати специјализоване стручњаке за различите ситуације. Потребан вам је стрпљив учитељ? Креативни партнер за размишљање? Озбиљан пословни саветник? Само промените системски упит!
#### Зашто су системски упити тако моћни
Ево фасцинантног дела: AI модели су обучени на безброј разговора у којима људи усвајају различите улоге и нивое експертизе. Када AI-ју дате одређену улогу, то је као да укључите прекидач који активира све те научене обрасце.
**То је као методска глума за AI**: Реците глумцу "ти си мудри стари професор" и гледајте како аутоматски прилагођава свој став, вокабулар и манире. AI ради нешто изузетно слично са језичким обрасцима.
#### Креирање ефективних системских упита: Уметност и наука
**Анатомија одличног системског упита:**
1. **Улога/идентитет**: Ко је AI?
2. **Експертиза**: Шта зна?
3. **Стил комуникације**: Како говори?
4. **Специфична упутства**: На шта треба да се фокусира?
```python
# ❌ Vague system prompt
"You are helpful."
# ✅ Detailed, effective system prompt
"You are Dr. Sarah Chen, a senior software engineer with 15 years of experience at major tech companies. You explain programming concepts using real-world analogies and always provide practical examples. You're patient with beginners and enthusiastic about helping them understand complex topics."
```
#### Примери системских упита са контекстом
Хајде да видимо како различити системски упити стварају потпуно различите личности AI-ја:
```python
# Example 1: The Patient Teacher
teacher_prompt = """
You are an experienced programming instructor who has taught thousands of students.
You break down complex concepts into simple steps, use analogies from everyday life,
and always check if the student understands before moving on. You're encouraging
and never make students feel bad for not knowing something.
"""
# Example 2: The Creative Collaborator
creative_prompt = """
You are a creative writing partner who loves brainstorming wild ideas. You're
enthusiastic, imaginative, and always build on the user's ideas rather than
replacing them. You ask thought-provoking questions to spark creativity and
offer unexpected perspectives that make stories more interesting.
"""
# Example 3: The Strategic Business Advisor
business_prompt = """
You are a strategic business consultant with an MBA and 20 years of experience
helping startups scale. You think in frameworks, provide structured advice,
and always consider both short-term tactics and long-term strategy. You ask
probing questions to understand the full business context before giving advice.
"""
```
#### Гледање системских упита
**Ево зашто је FastAPI савршен за оно што градимо:**
- **Асинхрони рад по подразумеваном подешавању**: Може истовремено обрађивати више AI захтева без застоја
- **Аутоматска документација**: Посетите `/docs` и добијате лепу, интерактивну страницу са документацијом API-ја бесплатно
- **Уграђена валидација**: Проналази грешке пре него што изазову проблеме
- **Изузетно брз**: Један од најбржих Python оквира
- **Модеран Python**: Користи најновије и најбоље функције Python-а
**И ево зашто нам је уопште потребан бекенд:**
**Безбедност**: Ваш AI API кључ је као лозинка – ако га ставите у JavaScript на фронтенду, свако ко погледа изворни код вашег сајта може га украсти и користити ваше AI кредите. Бекенд чува осетљиве акредитиве безбедним.
**Ограничење брзине и контрола**: Бекенд вам омогућава да контролишете колико често корисници могу слати захтеве, имплементирате аутентификацију корисника и додате логовање за праћење употребе.
**Обрада података**: Можда ћете желети да сачувате разговоре, филтрирате непримерен садржај или комбинујете више AI услуга. Бекенд је место где се ова логика одвија.
**Архитектура подсећа на модел клијент-сервер:**
- **Фронтенд**: Слој корисничког интерфејса за интеракцију
- **Бекенд API**: Слој за обраду захтева и рутирање
- **AI услуга**: Спољашња обрада и генерисање одговора
- **Енвиронмент променљиве**: Сигурно складиштење конфигурације и акредитива
### Разумевање тока захтева и одговора
Пратимо шта се дешава када корисник пошаље поруку:
```mermaid
sequenceDiagram
participant User as 👤 User
participant Frontend as 🌐 Frontend
participant API as 🔧 FastAPI Server
participant AI as 🤖 AI Service
User->>Frontend: Types "Hello AI!"
Frontend->>API: POST /hello {"message": "Hello AI!"}
Note over API: Validates request
Adds system prompt
API->>AI: Sends formatted request
AI->>API: Returns AI response
Note over API: Processes response
Logs conversation
API->>Frontend: {"response": "Hello! How can I help?"}
Frontend->>User: Displays AI message
```
**Разумевање сваког корака:**
1. **Интеракција корисника**: Особа куца у интерфејсу за ћаскање
2. **Обрада на фронтенду**: JavaScript хвата унос и форматира га као JSON
3. **Валидација API-ја**: FastAPI аутоматски валидара захтев користећи Pydantic моделе
4. **Интеграција AI-а**: Бекенд додаје контекст (системски упит) и позива AI услугу
5. **Обрада одговора**: API прима одговор AI-а и може га модификовати ако је потребно
6. **Приказ на фронтенду**: JavaScript приказује одговор у интерфејсу за ћаскање
### Разумевање архитектуре API-ја
```mermaid
sequenceDiagram
participant Frontend
participant FastAPI
participant AI Function
participant GitHub Models
Frontend->>FastAPI: POST /hello {"message": "Hello AI!"}
FastAPI->>AI Function: call_llm(message, system_prompt)
AI Function->>GitHub Models: API request
GitHub Models->>AI Function: AI response
AI Function->>FastAPI: response text
FastAPI->>Frontend: {"response": "Hello! How can I help?"}
```
### Креирање FastAPI апликације
Хајде да корак по корак изградимо наш API. Направите датотеку под називом `api.py` са следећим FastAPI кодом:
```python
# api.py
from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
from llm import call_llm
import logging
# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# Create FastAPI application
app = FastAPI(
title="AI Chat API",
description="A high-performance API for AI-powered chat applications",
version="1.0.0"
)
# Configure CORS
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # Configure appropriately for production
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# Pydantic models for request/response validation
class ChatMessage(BaseModel):
message: str
class ChatResponse(BaseModel):
response: str
@app.get("/")
async def root():
"""Root endpoint providing API information."""
return {
"message": "Welcome to the AI Chat API",
"docs": "/docs",
"health": "/health"
}
@app.get("/health")
async def health_check():
"""Health check endpoint."""
return {"status": "healthy", "service": "ai-chat-api"}
@app.post("/hello", response_model=ChatResponse)
async def chat_endpoint(chat_message: ChatMessage):
"""Main chat endpoint that processes messages and returns AI responses."""
try:
# Extract and validate message
message = chat_message.message.strip()
if not message:
raise HTTPException(status_code=400, detail="Message cannot be empty")
logger.info(f"Processing message: {message[:50]}...")
# Call AI service (note: call_llm should be made async for better performance)
ai_response = await call_llm_async(message, "You are a helpful and friendly assistant.")
logger.info("AI response generated successfully")
return ChatResponse(response=ai_response)
except HTTPException:
raise
except Exception as e:
logger.error(f"Error processing chat message: {str(e)}")
raise HTTPException(status_code=500, detail="Internal server error")
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=5000, reload=True)
```
**Разумевање имплементације FastAPI-ја:**
- **Увоз** FastAPI за функционалност модерног веб оквира и Pydantic за валидацију података
- **Креирање** аутоматске документације API-ја (доступно на `/docs` када сервер ради)
- **Омогућавање** CORS middleware-а за омогућавање захтева са фронтенда са различитих порекла
- **Дефинисање** Pydantic модела за аутоматску валидацију захтева/одговора и документацију
- **Коришћење** асинхроних крајњих тачака за боље перформансе са истовременим захтевима
- **Имплементација** одговарајућих HTTP статус кодова и руковање грешкама са HTTPException
- **Укључивање** структурисаног логовања за праћење и отклањање грешака
- **Обезбеђивање** крајње тачке за проверу здравља сервиса
**Кључне предности FastAPI-ја у односу на традиционалне оквире:**
- **Аутоматска валидација**: Pydantic модели обезбеђују интегритет података пре обраде
- **Интерактивна документација**: Посетите `/docs` за аутоматски генерисану, тестабилну документацију API-ја
- **Типска сигурност**: Python типске назнаке спречавају грешке у раду и побољшавају квалитет кода
- **Подршка за асинхрони рад**: Обрада више AI захтева истовремено без блокирања
- **Перформансе**: Значајно бржа обрада захтева за апликације у реалном времену
### Разумевање CORS-а: Чувар безбедности веба
CORS (Cross-Origin Resource Sharing) је као чувар безбедности у згради који проверава да ли је посетиоцима дозвољен улаз. Хајде да разумемо зашто је то важно и како утиче на вашу апликацију.
#### Шта је CORS и зашто постоји?
**Проблем**: Замислите да било који сајт може слати захтеве вашем банкарском сајту у ваше име без ваше дозволе. То би био безбедносни кошмар! Прегледачи то спречавају подразумевано кроз "Политику истог порекла".
**Политика истог порекла**: Прегледачи дозвољавају веб страницама да шаљу захтеве само ка истом домену, порту и протоколу са којег су учитани.
**Аналогија из стварног живота**: То је као безбедност у стамбеној згради – само станари (исто порекло) могу приступити згради по подразумеваном подешавању. Ако желите да ваш пријатељ (друго порекло) посети, морате експлицитно рећи обезбеђењу да је то у реду.
#### CORS у вашем развојном окружењу
Током развоја, ваш фронтенд и бекенд раде на различитим портовима:
- Фронтенд: `http://localhost:3000` (или file:// ако директно отварате HTML)
- Бекенд: `http://localhost:5000`
Ово се сматра "различитим пореклима" иако су на истом рачунару!
```python
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI(__name__)
CORS(app) # This tells browsers: "It's okay for other origins to make requests to this API"
```
**Шта CORS конфигурација ради у пракси:**
- **Додаје** посебне HTTP заглавља у одговоре API-ја која говоре прегледачима "овај захтев са различитим пореклом је дозвољен"
- **Рукује** "preflight" захтевима (прегледачи понекад проверавају дозволе пре слања стварног захтева)
- **Спречава** страшну грешку "blocked by CORS policy" у конзоли вашег прегледача
#### CORS безбедност: Развој наспрам продукције
```python
# 🚨 Development: Allows ALL origins (convenient but insecure)
CORS(app)
# ✅ Production: Only allow your specific frontend domain
CORS(app, origins=["https://yourdomain.com", "https://www.yourdomain.com"])
# 🔒 Advanced: Different origins for different environments
if app.debug: # Development mode
CORS(app, origins=["http://localhost:3000", "http://127.0.0.1:3000"])
else: # Production mode
CORS(app, origins=["https://yourdomain.com"])
```
**Зашто је ово важно**: У развоју, `CORS(app)` је као да оставите врата отворена – згодно, али небезбедно. У продукцији, желите да прецизно наведете који сајтови могу комуницирати са вашим API-јем.
#### Уобичајени сценарији CORS-а и решења
| Сценарио | Проблем | Решење |
|----------|---------|----------|
| **Локални развој** | Фронтенд не може да приступи бекенду | Додајте CORSMiddleware у FastAPI |
| **GitHub Pages + Heroku** | Деплојовани фронтенд не може да приступи API-ју | Додајте URL вашег GitHub Pages-а у CORS порекла |
| **Прилагођени домен** | CORS грешке у продукцији | Ажурирајте CORS порекла да одговарају вашем домену |
| **Мобилна апликација** | Апликација не може да приступи веб API-ју | Додајте домен ваше апликације или пажљиво користите `*` |
**Савет**: Можете проверити CORS заглавља у Developer Tools вашег прегледача под картицом Network. Потражите заглавља као што је `Access-Control-Allow-Origin` у одговору.
### Руковање грешкама и валидација
Приметите како наш API укључује правилно руковање грешкама:
```python
# Validate that we received a message
if not message:
return jsonify({"error": "Message field is required"}), 400
```
**Кључни принципи валидације:**
- **Проверава** обавезна поља пре обраде захтева
- **Враћа** смислене поруке о грешкама у JSON формату
- **Користи** одговарајуће HTTP статус кодове (400 за лоше захтеве)
- **Обезбеђује** јасне повратне информације за помоћ фронтенд програмерима у отклањању грешака
## Постављање и покретање вашег бекенда
Сада када имамо нашу AI интеграцију и FastAPI сервер спреман, хајде да све покренемо. Процес постављања укључује инсталирање Python зависности, конфигурисање енвиронмент променљивих и покретање вашег развојног сервера.
### Постављање Python окружења
Хајде да поставимо ваше Python развојно окружење. Виртуелна окружења су као приступ Манхатн пројекта – сваки пројекат добија свој изоловани простор са специфичним алатима и зависностима, спречавајући конфликте између различитих пројеката.
```bash
# Navigate to your backend directory
cd backend
# Create a virtual environment (like creating a clean room for your project)
python -m venv venv
# Activate it (Linux/Mac)
source ./venv/bin/activate
# On Windows, use:
# venv\Scripts\activate
# Install the good stuff
pip install openai fastapi uvicorn python-dotenv
```
**Шта смо управо урадили:**
- **Креирали** свој мали Python балон где можемо инсталирати пакете без утицаја на било шта друго
- **Активирали** га тако да наш терминал зна да користи ово специфично окружење
- **Инсталирали** основне ствари: OpenAI за AI магију, FastAPI за наш веб API, Uvicorn за његово покретање и python-dotenv за сигурно управљање тајнама
**Кључне зависности објашњене:**
- **FastAPI**: Модеран, брз веб оквир са аутоматском документацијом API-ја
- **Uvicorn**: Изузетно брз ASGI сервер који покреће FastAPI апликације
- **OpenAI**: Званична библиотека за GitHub моделе и OpenAI API интеграцију
- **python-dotenv**: Сигурно учитавање енвиронмент променљивих из .env датотека
### Конфигурација окружења: Чување тајни безбедним
Пре него што покренемо наш API, морамо разговарати о једној од најважнијих лекција у веб развоју: како заиста чувати своје тајне. Енвиронмент променљиве су као сигурни трезор који само ваша апликација може приступити.
#### Шта су енвиронмент променљиве?
**Замислите енвиронмент променљиве као сигурну кутију за депоновање** – стављате своје вредне ствари унутра, и само ви (и ваша апликација) имате кључ да их извадите. Уместо да пишете осетљиве информације директно у свој код (где их буквално свако може видети), чувате их безбедно у окружењу.
**Ево разлике:**
- **Погрешан начин**: Писање ваше лозинке на лепљивој белешци и стављање на монитор
- **Прави начин**: Чување ваше лозинке у сигурном менаџеру лозинки који само ви можете приступити
#### Зашто су енвирonment променљиве важне
```python
# 🚨 NEVER DO THIS - API key visible to everyone
client = OpenAI(
api_key="ghp_1234567890abcdef...", # Anyone can steal this!
base_url="https://models.github.ai/inference"
)
# ✅ DO THIS - API key stored securely
client = OpenAI(
api_key=os.environ["GITHUB_TOKEN"], # Only your app can access this
base_url="https://models.github.ai/inference"
)
```
**Шта се дешава када директно унесете тајне:**
1. **Излагање верзионисању**: Свако ко има приступ вашем Git репозиторијуму види ваш API кључ
2. **Јавни репозиторијуми**: Ако га поставите на GitHub, ваш кључ је видљив целом интернету
3. **Дељење са тимом**: Други програмери који раде на вашем пројекту добијају приступ вашем личном API кључу
4. **Безбедносни пропусти**: Ако неко украде ваш API кључ, може користити ваше AI кредите
#### Постављање ваше .env датотеке
Креирајте `.env` датотеку у вашем бекенд директоријуму. Ова датотека локално чува ваше тајне:
```bash
# .env file - This should NEVER be committed to Git
GITHUB_TOKEN=your_github_personal_access_token_here
FASTAPI_DEBUG=True
ENVIRONMENT=development
```
**Разумевање .env датотеке:**
- **Једна тајна по линији** у формату `KEY=value`
- **Без размака** око знака једнакости
- **Без наводника** око вредности (обично)
- **Коментари** почињу са `#`
#### Креирање вашег GitHub личног приступног токена
Ваш GitHub токен је као посебна лозинка која даје вашој апликацији дозволу да користи GitHub AI услуге:
**Корак-по-корак креирање токена:**
1. **Идите на GitHub Settings** → Developer settings → Personal access tokens → Tokens (classic)
2. **Кликните "Generate new token (classic)"**
3. **Поставите истек** (30 дана за тестирање, дуже за продукцију)
4. **Изаберите опсеге**: Означите "repo" и било које друге дозволе које су вам потребне
5. **Генеришите токен** и одмах га копирајте (не можете га поново видети!)
6. **Залепите у вашу .env датотеку**
```bash
# Example of what your token looks like (this is fake!)
GITHUB_TOKEN=ghp_1A2B3C4D5E6F7G8H9I0J1K2L3M4N5O6P7Q8R
```
#### Учитавање енвирonment променљивих у Python-у
```python
import os
from dotenv import load_dotenv
# Load environment variables from .env file
load_dotenv()
# Now you can access them securely
api_key = os.environ.get("GITHUB_TOKEN")
if not api_key:
raise ValueError("GITHUB_TOKEN not found in environment variables!")
client = OpenAI(
api_key=api_key,
base_url="https://models.github.ai/inference"
)
```
**Шта овај код ради:**
- **Учитава** вашу .env датотеку и чини променљиве доступним Python-у
- **Проверава** да ли постоји потребан токен (добро руковање грешкама!)
- **Подиже** јасну грешку ако токен недостаје
- **Користи** токен безбедно без излагања у коду
#### Git безбедност: .gitignore датотека
Ваша `.gitignore` датотека говори Git-у које датотеке никада не треба пратити или отпремати:
```bash
# .gitignore - Add these lines
.env
*.env
.env.local
.env.production
__pycache__/
venv/
.vscode/
```
**Зашто је ово кључно**: Када додате `.env` у `.gitignore`, Git ће игнорисати вашу датотеку окружења, спречавајући вас да случајно отпремите своје тајне на GitHub.
#### Различита окружења, различите тајне
Професионалне апликације користе различите API кључеве за различита окружења:
```bash
# .env.development
GITHUB_TOKEN=your_development_token
DEBUG=True
# .env.production
GITHUB_TOKEN=your_production_token
DEBUG=False
```
**Зашто је ово важно**: Не желите да ваши експерименти у развоју утичу на вашу продукцијску AI квоту, и желите различите нивое безбедности за различита окружења.
### Покретање вашег развојног сервера: Оживљавање вашег FastAPI-ја
Сада долази узбудљив тренутак – покретање вашег FastAPI развојног сервера и гледање како ваша AI интеграција оживљава! FastAPI користи Uvicorn, изузетно брз ASGI сервер који је посебно дизајниран за асинхрони Python апликације.
#### Разумевање процеса покретања FastAPI сервера
```bash
# Method 1: Direct Python execution (includes auto-reload)
python api.py
# Method 2: Using Uvicorn directly (more control)
uvicorn api:app --host 0.0.0.0 --port 5000 --reload
```
Када покренете ову команду, ево шта се дешава иза сцене:
**1. Python учитава вашу FastAPI апликацију**:
- Увоз свих потребних библиотека (FastAPI, Pydantic, OpenAI, итд.)
- Учитавање енвиронment променљивих из ваше `.env` датотеке
- Креирање FastAPI инстанце апликације са аутоматском документацијом
**2. Uvicorn конфигурише ASGI сервер**:
-
```python
# test_api.py - Create this file to test your API
import requests
import json
# Test the API endpoint
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)
```
#### Решавање уобичајених проблема при покретању
| Порука о грешци | Шта значи | Како поправити |
|-----------------|-----------|----------------|
| `ModuleNotFoundError: No module named 'fastapi'` | FastAPI није инсталиран | Покрените `pip install fastapi uvicorn` у вашем виртуелном окружењу |
| `ModuleNotFoundError: No module named 'uvicorn'` | ASGI сервер није инсталиран | Покрените `pip install uvicorn` у вашем виртуелном окружењу |
| `KeyError: 'GITHUB_TOKEN'` | Променљива окружења није пронађена | Проверите ваш `.env` фајл и позив `load_dotenv()` |
| `Address already in use` | Порт 5000 је заузет | Затворите друге процесе који користе порт 5000 или промените порт |
| `ValidationError` | Подаци захтева не одговарају Pydantic моделу | Проверите да ли формат вашег захтева одговара очекиваној шеми |
| `HTTPException 422` | Необрађени ентитет | Валидација захтева није успела, проверите `/docs` за исправан формат |
| `OpenAI API error` | Аутентификација AI услуге није успела | Проверите да ли је ваш GitHub токен исправан и да ли има одговарајуће дозволе |
#### Најбоље праксе за развој
**Аутоматско поновно учитавање**: FastAPI са Uvicorn-ом омогућава аутоматско поновно учитавање када сачувате измене у вашим Python фајловима. То значи да можете одмах тестирати измене без ручног поновног покретања.
```python
# Enable hot reloading explicitly
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000, debug=True) # debug=True enables hot reload
```
**Логовање за развој**: Додајте логовање да бисте разумели шта се дешава:
```python
import logging
# Set up 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
```
**Зашто логовање помаже**: Током развоја, можете видети тачно који захтеви стижу, како AI одговара и где се јављају грешке. Ово значајно убрзава процес отклањања грешака.
### Конфигурисање за GitHub Codespaces: Развој у облаку на једноставан начин
GitHub Codespaces је као да имате моћан рачунар за развој у облаку који можете да приступите из било ког претраживача. Ако радите у Codespaces-у, постоји неколико додатних корака како би ваш бекенд био доступан фронтенду.
#### Разумевање мрежне конфигурације Codespaces-а
У локалном развојном окружењу, све ради на истом рачунару:
- Бекенд: `http://localhost:5000`
- Фронтенд: `http://localhost:3000` (или file://)
У Codespaces-у, ваше развојно окружење ради на серверима GitHub-а, па "localhost" има другачије значење. GitHub аутоматски креира јавне URL-ове за ваше услуге, али их морате правилно конфигурисати.
#### Кораци за конфигурисање Codespaces-а
**1. Покрените ваш бекенд сервер**:
```bash
cd backend
python api.py
```
Видећете познату FastAPI/Uvicorn поруку о покретању, али приметићете да ради унутар Codespace окружења.
**2. Конфигуришите видљивост порта**:
- Потражите картицу "Ports" у доњем панелу VS Code-а
- Пронађите порт 5000 на листи
- Кликните десним тастером миша на порт 5000
- Изаберите "Port Visibility" → "Public"
**Зашто га учинити јавним?** Подразумевано, портови у Codespace-у су приватни (доступни само вама). Учинивши га јавним, омогућавате вашем фронтенду (који ради у претраживачу) да комуницира са вашим бекендом.
**3. Добијте ваш јавни URL**:
Након што учините порт јавним, видећете URL као:
```
https://your-codespace-name-5000.app.github.dev
```
**4. Ажурирајте конфигурацију фронтенда**:
```javascript
// In your frontend app.js, update the BASE_URL:
this.BASE_URL = "https://your-codespace-name-5000.app.github.dev";
```
#### Разумевање Codespace URL-ова
Codespace URL-ови следе предвидив образац:
```
https://[codespace-name]-[port].app.github.dev
```
**Објашњење:**
- `codespace-name`: Јединствени идентификатор за ваш Codespace (обично укључује ваше корисничко име)
- `port`: Број порта на коме ваша услуга ради (5000 за нашу FastAPI апликацију)
- `app.github.dev`: Домен GitHub-а за апликације у Codespace-у
#### Тестирање вашег Codespace подешавања
**1. Тестирајте директно бекенд**:
Отворите ваш јавни URL у новом прозору претраживача. Требало би да видите:
```
Welcome to the AI Chat API. Send POST requests to /hello with JSON payload containing 'message' field.
```
**2. Тестирајте помоћу алатки за развој у претраживачу**:
```javascript
// Open browser console and test your 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 локални развој
| Аспект | Локални развој | GitHub Codespaces |
|--------|----------------|-------------------|
| **Време подешавања** | Дуже (инсталација Python-а, зависности) | Тренутно (унапред конфигурисано окружење) |
| **Приступ URL-у** | `http://localhost:5000` | `https://xyz-5000.app.github.dev` |
| **Конфигурација порта** | Аутоматска | Ручна (учинити портове јавним) |
| **Перзистенција фајлова** | Локални рачунар | GitHub репозиторијум |
| **Колаборација** | Тешко делити окружење | Лако делити линк Codespace-а |
| **Зависност од интернета** | Само за AI API позиве | Потребно за све |
#### Савети за развој у Codespace-у
**Променљиве окружења у Codespace-у**:
Ваш `.env` фајл ради исто у Codespace-у, али можете директно поставити променљиве окружења у Codespace-у:
```bash
# Set environment variable for the current session
export GITHUB_TOKEN="your_token_here"
# Or add to your .bashrc for persistence
echo 'export GITHUB_TOKEN="your_token_here"' >> ~/.bashrc
```
**Управљање портовима**:
- Codespaces аутоматски детектује када ваша апликација почне да слуша на порту
- Можете истовремено проследити више портова (корисно ако касније додате базу података)
- Портови остају доступни све док ваш Codespace ради
**Радни ток развоја**:
1. Измените код у VS Code-у
2. FastAPI се аутоматски поново учитава (захваљујући Uvicorn-овом режиму поновног учитавања)
3. Одмах тестирајте измене преко јавног URL-а
4. Направите commit и push када будете спремни
> 💡 **Савет**: Сачувајте ваш Codespace бекенд URL током развоја. Пошто су имена Codespace-а стабилна, URL се неће мењати све док користите исти Codespace.
## Креирање фронтенд интерфејса за ћаскање: Где се људи сусрећу са AI
Сада ћемо изградити кориснички интерфејс – део који одређује како људи комуницирају са вашим AI асистентом. Као што је дизајн оригиналног интерфејса iPhone-а, фокусираћемо се на то да сложену технологију учинимо интуитивном и природном за коришћење.
### Разумевање модерне архитектуре фронтенда
Наш интерфејс за ћаскање биће оно што називамо "апликација са једном страницом" или SPA. Уместо старомодног приступа где сваки клик учитава нову страницу, наша апликација се ажурира глатко и тренутно:
**Старе веб странице**: Као читање физичке књиге – окрећете потпуно нове странице
**Наша апликација за ћаскање**: Као коришћење телефона – све тече и ажурира се беспрекорно
```mermaid
graph TD
A[User Types Message] --> B[JavaScript Captures Input]
B --> C[Validate & Format Data]
C --> D[Send to Backend API]
D --> E[Display Loading State]
E --> F[Receive AI Response]
F --> G[Update Chat Interface]
G --> H[Ready for Next Message]
```
### Три стуба фронтенд развоја
Свака фронтенд апликација – од једноставних веб страница до сложених апликација као што су Discord или Slack – изграђена је на три основне технологије. Замислите их као темељ свега што видите и са чим комуницирате на вебу:
**HTML (Структура)**: Ово је ваш темељ
- Одређује који елементи постоје (дугмад, текстуални оквири, контејнери)
- Додаје значење садржају (ово је наслов, ово је форма, итд.)
- Креира основну структуру на којој се све остало гради
**CSS (Презентација)**: Ово је ваш дизајнер ентеријера
- Чини све лепим (боје, фонтови, распореди)
- Прилагођава различите величине екрана (телефон, лаптоп, таблет)
- Креира глатке анимације и визуелне повратне информације
**JavaScript (Понашање)**: Ово је ваш мозак
- Реагује на оно што корисници раде (кликови, куцање, скроловање)
- Комуницира са вашим бекендом и ажурира страницу
- Чини све интерактивним и динамичним
**Замислите то као архитектонски дизајн:**
- **HTML**: Структурни план (дефинисање простора и односа)
- **CSS**: Естетски и дизајн окружења (визуелни стил и корисничко искуство)
- **JavaScript**: Механички системи (функционалност и интерактивност)
### Зашто је важна модерна архитектура JavaScript-а
Наша апликација за ћаскање користиће модерне JavaScript шаблоне које ћете видети у професионалним апликацијама. Разумевање ових концепата помоћи ће вам да напредујете као програмер:
**Архитектура заснована на класама**: Организоваћемо наш код у класе, што је као креирање планова за објекте
**Async/Await**: Модеран начин за обраду операција које трају (као што су API позиви)
**Програмирање засновано на догађајима**: Наша апликација реагује на акције корисника (кликови, притисци на тастере) уместо да ради у петљи
**Манипулација DOM-ом**: Динамично ажурирање садржаја веб странице на основу интеракција корисника и одговора API-ја
### Подешавање структуре пројекта
Креирајте директоријум за фронтенд са овако организованом структуром:
```text
frontend/
├── index.html # Main HTML structure
├── app.js # JavaScript functionality
└── styles.css # Visual styling
```
**Разумевање архитектуре:**
- **Одвајање** између структуре (HTML), понашања (JavaScript) и презентације (CSS)
- **Одржавање** једноставне структуре фајлова која је лако прегледна и модификована
- **Праћење** најбољих пракси веб развоја за организацију и одрживост
### Изградња HTML основе: Семантичка структура за приступачност
Почнимо са HTML структуром. Модеран веб развој наглашава "семантички HTML" – коришћење HTML елемената који јасно описују своју сврху, а не само свој изглед. Ово чини вашу апликацију приступачном читачима екрана, претраживачима и другим алатима.
**Зашто је семантички HTML важан**: Замислите да описујете вашу апликацију за ћаскање некоме преко телефона. Рекли бисте "постоји заглавље са насловом, главни део где се појављују разговори и форма на дну за куцање порука." Семантички HTML користи елементе који одговарају овом природном опису.
Креирајте `index.html` са овако промишљено структурираним маркапом:
```html
Ask me anything!