# Създаване на чат асистент с изкуствен интелект
Спомняте ли си в "Стар Трек", когато екипажът спокойно разговаряше с компютъра на кораба, задавайки му сложни въпроси и получавайки обмислени отговори? Това, което изглеждаше като чиста научна фантастика през 60-те години, сега е нещо, което можете да създадете, използвайки уеб технологии, които вече познавате.
В този урок ще създадем чат асистент с изкуствен интелект, използвайки HTML, CSS, JavaScript и малко бекенд интеграция. Ще откриете как същите умения, които сте усвоили, могат да се свържат с мощни AI услуги, които разбират контекста и генерират смислени отговори.
Помислете за изкуствения интелект като за достъп до огромна библиотека, която не само намира информация, но и я синтезира в последователни отговори, съобразени с вашите конкретни въпроси. Вместо да търсите сред хиляди страници, получавате директни, контекстуални отговори.
Интеграцията се осъществява чрез познати уеб технологии, които работят заедно. HTML създава интерфейса за чат, CSS се грижи за визуалния дизайн, JavaScript управлява взаимодействията с потребителя, а бекенд API свързва всичко с AI услугите. Това е подобно на начина, по който различните секции на оркестър работят заедно, за да създадат симфония.
На практика изграждаме мост между естествената човешка комуникация и машинната обработка. Ще научите както техническата реализация на интеграцията с AI услуги, така и дизайнерските модели, които правят взаимодействията интуитивни.
До края на този урок интеграцията с AI ще ви се стори по-малко мистериозен процес и повече като още един API, с който можете да работите. Ще разберете основните модели, които захранват приложения като ChatGPT и Claude, използвайки същите принципи на уеб разработката, които вече сте усвоили.
Ето как ще изглежда завършеният проект:

## Разбиране на изкуствения интелект: От мистерия към майсторство
Преди да се потопим в кода, нека разберем с какво работим. Ако сте използвали API-та преди, знаете основния модел: изпращате заявка, получавате отговор.
AI API-тата следват подобна структура, но вместо да извличат предварително съхранени данни от база данни, те генерират нови отговори въз основа на модели, научени от огромни количества текст. Помислете за това като за разликата между библиотечна картотека и знаещ библиотекар, който може да синтезира информация от множество източници.
### Какво всъщност е "Генеративен изкуствен интелект"?
Помислете как Розетският камък е позволил на учените да разберат египетските йероглифи, като са открили модели между известни и неизвестни езици. Моделите на изкуствения интелект работят по подобен начин – те откриват модели в огромни количества текст, за да разберат как работи езикът, а след това използват тези модели, за да генерират подходящи отговори на нови въпроси.
**Нека го обясня с прост пример:**
- **Традиционна база данни**: Като да поискате акта си за раждане – получавате един и същ документ всеки път.
- **Търсачка**: Като да помолите библиотекар да намери книги за котки – той ви показва какво е налично.
- **Генеративен изкуствен интелект**: Като да попитате знаещ приятел за котки – той ви разказва интересни неща със свои думи, съобразени с това, което искате да знаете.
```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
)
```
#### Max Tokens (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.
"""
```
#### Виждане на системните подсказки в действие
Нека тестваме един и същ въпрос с различни системни подсказки, за да видим драматичните разлики:
**Въпрос**: "Как да се справя с удостоверяването на потребителите в моето уеб приложение?"
```python
# With teacher prompt:
teacher_response = call_llm(
"How do I handle user authentication in my web app?",
teacher_prompt
)
# Typical response: "Great question! Let's break authentication down into simple steps.
# Think of it like a nightclub bouncer checking IDs..."
# With business prompt:
business_response = call_llm(
"How do I handle user authentication in my web app?",
business_prompt
)
# Typical response: "From a strategic perspective, authentication is crucial for user
# trust and regulatory compliance. Let me outline a framework considering security,
# user experience, and scalability..."
```
#### Разширени техники за системни подсказки
**1. Настройка на контекста**: Дайте на AI основна информация
```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. Форматиране на изхода**: Кажете на AI как да структурира отговорите
```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. Задаване на ограничения**: Определете какво AI не трябва да прави
```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.
"""
```
#### Защо
**Ето защо 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, които казват на браузърите "тази заявка от различен произход е разрешена"
- **Обработва** "предварителни" заявки (браузърите понякога проверяват разрешенията преди да изпратят действителната заявка)
- **Предотвратява** страховитата грешка "блокирано от CORS политика" в конзолата на браузъра
#### Сигурност на 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 заглавията в Инструментите за разработчици на браузъра под раздела 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, трябва да поговорим за един от най-важните уроци в уеб разработката: как да пазим тайните си наистина тайни. Променливите на средата са като сигурен сейф, до който само вашето приложение има достъп.
#### Какво представляват променливите на средата?
**Мислете за променливите на средата като за сейф за ценности** – поставяте ценните си неща там и само вие (и вашето приложение) имате ключа за достъп. Вместо да пишете чувствителна информация директно в кода си (където буквално всеки може да я види), я съхранявате безопасно в средата.
**Ето разликата:**
- **Грешен начин**: Да напишете паролата си на лепяща бележка и да я залепите на монитора
- **Правилен начин**: Да съхранявате паролата си в сигурен мениджър на пароли, до който само вие имате достъп
#### Защо променливите на средата са важни
```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` в директорията на вашия бекенд. Този файл съхранява вашите тайни локално:
```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 токен е като специална парола, която дава на вашето приложение разрешение да използва AI услугите на GitHub:
**Стъпка по стъпка за създаване на токен:**
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
```
#### Зареждане на променливи на средата в 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 и др.)
- Зарежда променливите на средата от вашия `.env` файл
- Създава инстанция на FastAPI приложението с автоматична документация
**2. Uvicorn конфигурира ASGI сървъра**:
- Свързва се към порт 5000 с възможности за асинхронна обработка на заявки
- Настройва маршрутизация на заявки с автоматична валидация
- Активира автоматично презареждане за разработка (рестартира при промени в файловете)
- Генерира интерактивна API документация
**3. Сървърът започва да слуша**:
- Вашият терминал показва: `INFO: Uvicorn running on http://0.0.0.0:5000`
- Сървърът може да обработва множество конкурентни AI заявки
- Вашето API е готово с автоматична документация на `http://localhost:5000/docs`
#### Как
```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";
```
#### Разбиране на URL адресите на Codespace
URL адресите на Codespace следват предвидим модел:
```
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 срещу локална разработка
| Аспект | Локална разработка | GitHub Codespaces |
|--------|--------------------|-------------------|
| **Време за настройка** | По-дълго (инсталиране на Python, зависимости) | Моментално (предварително конфигурирана среда) |
| **Достъп до URL** | `http://localhost:5000` | `https://xyz-5000.app.github.dev` |
| **Конфигурация на портовете** | Автоматична | Ръчна (направете портовете публични) |
| **Запазване на файлове** | Локална машина | Репозитория на GitHub |
| **Сътрудничество** | Трудно за споделяне на среда | Лесно за споделяне на линк към Codespace |
| **Интернет зависимост** | Само за AI API заявки | Необходимо за всичко |
#### Съвети за разработка в Codespaces
**Променливи на средата в Codespaces**:
Вашият `.env` файл работи по същия начин в Codespaces, но можете също да зададете променливи на средата директно в 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. Комитнете и качете, когато сте готови
> 💡 **Съвет**: Запазете вашия URL адрес на бекенда в Codespace по време на разработката. Тъй като имената на Codespace са стабилни, URL адресът няма да се промени, докато използвате същия Codespace.
## Създаване на интерфейс за чат: Където хората срещат AI
Сега ще изградим потребителския интерфейс – частта, която определя как хората взаимодействат с вашия AI асистент. Както при дизайна на оригиналния интерфейс на iPhone, ще се фокусираме върху това сложната технология да изглежда интуитивна и лесна за използване.
### Разбиране на съвременната архитектура на фронтенда
Нашият чат интерфейс ще бъде това, което наричаме "Single Page Application" или 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!