# Сесия 4: Създаване на продукционни чат приложения с Chainlit ## Преглед Тази сесия е посветена на изграждането на готови за продукция чат приложения с помощта на Chainlit и Microsoft Foundry Local. Ще научите как да създавате модерни уеб интерфейси за AI разговори, да внедрявате стрийминг отговори и да разгръщате стабилни чат приложения с подходящо управление на грешки и дизайн за потребителско изживяване. **Какво ще създадете:** - **Chainlit Chat App**: Модерен уеб интерфейс със стрийминг отговори - **WebGPU Демонстрация**: Инференция в браузъра за приложения с приоритет на поверителността - **Интеграция с Open WebUI**: Професионален чат интерфейс с Foundry Local - **Продукционни модели**: Управление на грешки, мониторинг и стратегии за разгръщане ## Цели на обучението - Създаване на готови за продукция чат приложения с Chainlit - Внедряване на стрийминг отговори за подобрено потребителско изживяване - Усвояване на модели за интеграция с Foundry Local SDK - Прилагане на подходящо управление на грешки и плавна деградация - Разгръщане и конфигуриране на чат приложения за различни среди - Разбиране на модерни уеб UI модели за разговорен AI ## Предварителни изисквания - **Foundry Local**: Инсталиран и работещ ([Ръководство за инсталация](https://learn.microsoft.com/azure/ai-foundry/foundry-local/)) - **Python**: Версия 3.10 или по-нова с възможност за виртуална среда - **Модел**: Зареден поне един модел (`foundry model run phi-4-mini`) - **Браузър**: Модерен уеб браузър с поддръжка на WebGPU (Chrome/Edge) - **Docker**: За интеграция с Open WebUI (по избор) ## Част 1: Разбиране на модерните чат приложения ### Преглед на архитектурата ``` User Browser ←→ Chainlit UI ←→ Python Backend ←→ Foundry Local ←→ AI Model ↓ ↓ ↓ ↓ ↓ Web UI Event Handlers OpenAI Client HTTP API Local GPU ``` ### Ключови технологии **Модели на Foundry Local SDK:** - `FoundryLocalManager(alias)`: Автоматично управление на услуги - `manager.endpoint` и `manager.api_key`: Детайли за връзка - `manager.get_model_info(alias).id`: Идентификация на модела **Chainlit Framework:** - `@cl.on_chat_start`: Инициализиране на чат сесии - `@cl.on_message`: Обработка на входящи съобщения от потребителя - `cl.Message().stream_token()`: Стрийминг в реално време - Автоматично генериране на UI и управление на WebSocket ## Част 2: Локална срещу облачна матрица за решения ### Характеристики на производителността | Аспект | Локално (Foundry) | Облак (Azure OpenAI) | |--------|-------------------|----------------------| | **Закъснение** | 🚀 50-200ms (без мрежа) | ⏱️ 200-2000ms (зависимо от мрежата) | | **Поверителност** | 🔒 Данните не напускат устройството | ⚠️ Данните се изпращат в облака | | **Цена** | 💰 Безплатно след хардуера | 💸 Плащане на токен | | **Офлайн** | ✅ Работи без интернет | ❌ Изисква интернет | | **Размер на модела** | ⚠️ Ограничен от хардуера | ✅ Достъп до най-големите модели | | **Скалируемост** | ⚠️ Зависима от хардуера | ✅ Неограничена скалируемост | ### Модели за хибридна стратегия **Локално първо с резервен вариант:** ```python async def hybrid_completion(prompt: str, complexity_threshold: int = 100): if len(prompt.split()) < complexity_threshold: return await local_completion(prompt) # Fast, private else: return await cloud_completion(prompt) # Complex reasoning ``` **Рутиране на базата на задачи:** ```python async def smart_routing(prompt: str, task_type: str): routing_rules = { "code_generation": "local", # Privacy-sensitive "creative_writing": "cloud", # Benefits from larger models "data_analysis": "local", # Fast iteration needed "research": "cloud" # Requires broad knowledge } if routing_rules.get(task_type) == "local": return await foundry_completion(prompt) else: return await azure_completion(prompt) ``` ## Част 3: Пример 04 - Chainlit Chat Application ### Бърз старт ```cmd # Navigate to Module08 directory cd Module08 # Start your preferred model foundry model run phi-4-mini # Run the Chainlit application (avoiding port conflicts) chainlit run samples\04\app.py -w --port 8080 ``` Приложението автоматично се отваря на `http://localhost:8080` с модерен чат интерфейс. ### Основна имплементация Приложението Sample 04 демонстрира готови за продукция модели: **Автоматично откриване на услуги:** ```python import chainlit as cl from openai import OpenAI from foundry_local import FoundryLocalManager # Global variables for client and model client = None model_name = None async def initialize_client(): global client, model_name alias = os.environ.get("MODEL", "phi-4-mini") try: # Use FoundryLocalManager for proper service management manager = FoundryLocalManager(alias) model_info = manager.get_model_info(alias) client = OpenAI( base_url=manager.endpoint, api_key=manager.api_key or "not-required" ) model_name = model_info.id if model_info else alias return True except Exception as e: # Fallback to manual configuration base_url = os.environ.get("BASE_URL", "http://localhost:51211") client = OpenAI(base_url=f"{base_url}/v1", api_key="not-required") model_name = alias return True ``` **Обработчик на стрийминг чат:** ```python @cl.on_message async def main(message: cl.Message): # Create streaming response msg = cl.Message(content="") await msg.send() stream = client.chat.completions.create( model=model_name, messages=[ {"role": "system", "content": "You are a helpful AI assistant."}, {"role": "user", "content": message.content} ], stream=True ) # Stream tokens in real-time for chunk in stream: if chunk.choices[0].delta.content: await msg.stream_token(chunk.choices[0].delta.content) await msg.update() ``` ### Опции за конфигурация **Променливи на средата:** | Променлива | Описание | По подразбиране | Пример | |------------|----------|-----------------|--------| | `MODEL` | Псевдоним на модела за използване | `phi-4-mini` | `qwen2.5-7b` | | `BASE_URL` | Endpoint на Foundry Local | Автоматично открит | `http://localhost:51211` | | `API_KEY` | API ключ (по избор за локално) | `""` | `your-api-key` | **Разширена употреба:** ```cmd # Use different model set MODEL=qwen2.5-7b chainlit run samples\04\app.py -w --port 8080 # Use different ports (avoid 51211 which is used by Foundry Local) chainlit run samples\04\app.py -w --port 3000 chainlit run samples\04\app.py -w --port 5000 ``` ## Част 4: Създаване и използване на Jupyter Notebooks ### Преглед на поддръжката на Notebook Примерът Sample 04 включва изчерпателен Jupyter notebook (`chainlit_app.ipynb`), който предоставя: - **📚 Образователно съдържание**: Стъпка по стъпка учебни материали - **🔬 Интерактивно изследване**: Стартиране и експериментиране с кодови клетки - **📊 Визуални демонстрации**: Графики, диаграми и визуализация на резултати - **🛠️ Инструменти за разработка**: Тестване и отстраняване на грешки ### Създаване на собствени Notebooks #### Стъпка 1: Настройка на Jupyter среда ```cmd # Ensure you're in the Module08 directory cd Module08 # Activate your virtual environment .venv\Scripts\activate # Install Jupyter and dependencies pip install jupyter notebook jupyterlab ipykernel pip install -r requirements.txt # Register the kernel for VS Code python -m ipykernel install --user --name=foundry-local --display-name="Foundry Local" ``` #### Стъпка 2: Създаване на нов Notebook **С помощта на VS Code:** 1. Отворете VS Code в директорията Module08 2. Създайте нов файл с разширение `.ipynb` 3. Изберете ядрото "Foundry Local", когато бъдете подканени 4. Започнете да добавяте клетки със съдържание **С помощта на Jupyter Lab:** ```cmd # Start Jupyter Lab jupyter lab # Navigate to samples/04/ and create new notebook # Choose Python 3 kernel ``` ### Най-добри практики за структура на Notebook #### Организация на клетките ```python # Cell 1: Imports and Setup import os import sys import chainlit as cl from openai import OpenAI from foundry_local import FoundryLocalManager print("✅ Libraries imported successfully") ``` ```python # Cell 2: Configuration and Client Setup class FoundryClientManager: def __init__(self, model_name="phi-4-mini"): self.model_name = model_name self.client = None def initialize_client(self): # Client initialization logic pass # Initialize and test client_manager = FoundryClientManager() result = client_manager.initialize_client() print(f"Client initialized: {result}") ``` ### Интерактивни примери и упражнения #### Упражнение 1: Тестване на конфигурацията на клиента ```python # Test different configuration methods configurations = [ {"method": "foundry_sdk", "model": "phi-4-mini"}, {"method": "manual", "base_url": "http://localhost:51211", "model": "qwen2.5-7b"}, ] for config in configurations: print(f"\n🧪 Testing {config['method']} configuration...") # Implementation here result = test_configuration(config) print(f"Result: {'✅ Success' if result['status'] == 'ok' else '❌ Failed'}") ``` #### Упражнение 2: Симулиране на стрийминг отговор ```python import asyncio async def simulate_streaming_response(text, delay=0.1): """Simulate how streaming works in Chainlit.""" print("🌊 Simulating streaming response...") for char in text: print(char, end='', flush=True) await asyncio.sleep(delay) print("\n✅ Streaming complete!") # Test the simulation sample_text = "This is how streaming responses work in Chainlit applications!" await simulate_streaming_response(sample_text) ``` ## Част 5: Демонстрация на WebGPU браузърна инференция ### Преглед WebGPU позволява изпълнение на AI модели директно в браузъра за максимална поверителност и без необходимост от инсталация. Този пример демонстрира ONNX Runtime Web с изпълнение чрез WebGPU. ### Стъпка 1: Проверка на поддръжката на WebGPU **Изисквания към браузъра:** - Chrome/Edge 113+ с активиран WebGPU - Проверка: `chrome://gpu` → потвърдете статус "WebGPU" - Програмна проверка: `if (!('gpu' in navigator)) { /* no WebGPU */ }` ### Стъпка 2: Създаване на WebGPU демонстрация Създайте директория: `samples/04/webgpu-demo/` **index.html:** ```html WebGPU + ONNX Runtime Demo

🚀 WebGPU + Foundry Local Integration

Initializing...

    


```

**main.js:**
```javascript
const statusEl = document.getElementById('status');
const outputEl = document.getElementById('output');

function log(msg) {
    outputEl.textContent += `${msg}\n`;
    console.log(msg);
}

(async () => {
    try {
        if (!('gpu' in navigator)) {
            statusEl.textContent = '❌ WebGPU not available';
            return;
        }
        
        statusEl.textContent = '🔍 WebGPU detected. Loading model...';
        
        // Use a small ONNX model for demo
        const modelUrl = 'https://huggingface.co/onnx/models/resolve/main/vision/classification/mnist-12/mnist-12.onnx';
        
        const session = await ort.InferenceSession.create(modelUrl, {
            executionProviders: ['webgpu']
        });
        
        log('✅ ONNX Runtime session created with WebGPU');
        log(`📊 Input names: ${session.inputNames.join(', ')}`);
        log(`📊 Output names: ${session.outputNames.join(', ')}`);
        
        // Create dummy input (MNIST expects 1x1x28x28)
        const inputData = new Float32Array(1 * 1 * 28 * 28).fill(0.1);
        const input = new ort.Tensor('float32', inputData, [1, 1, 28, 28]);
        
        const feeds = {};
        feeds[session.inputNames[0]] = input;
        
        const results = await session.run(feeds);
        const output = results[session.outputNames[0]];
        
        // Find prediction (argmax)
        let maxIdx = 0;
        for (let i = 1; i < output.data.length; i++) {
            if (output.data[i] > output.data[maxIdx]) maxIdx = i;
        }
        
        statusEl.textContent = '✅ WebGPU inference complete!';
        log(`🎯 Predicted class: ${maxIdx}`);
        log(`📈 Confidence scores: [${Array.from(output.data).map(x => x.toFixed(3)).join(', ')}]`);
        
    } catch (error) {
        statusEl.textContent = `❌ Error: ${error.message}`;
        log(`Error: ${error.message}`);
        console.error(error);
    }
})();
```

### Стъпка 3: Стартиране на демонстрацията

```cmd
# Create demo directory
mkdir samples\04\webgpu-demo
cd samples\04\webgpu-demo

# Save HTML and JS files, then serve
python -m http.server 5173

# Open browser to http://localhost:5173
```

## Част 6: Интеграция с Open WebUI

### Преглед

Open WebUI предоставя професионален интерфейс, подобен на ChatGPT, който се свързва с OpenAI-съвместимия API на Foundry Local.

### Стъпка 1: Предварителни изисквания

```cmd
# Verify Foundry Local is running
foundry service status

# Start a model
foundry model run phi-4-mini

# Confirm API endpoint is accessible
curl http://localhost:51211/v1/models
```

### Стъпка 2: Настройка с Docker (Препоръчително)

```cmd
# Pull Open WebUI image
docker pull ghcr.io/open-webui/open-webui:main

# Run with Foundry Local connection
docker run -d --name open-webui -p 3000:8080 ^
  -e OPENAI_API_BASE_URL=http://host.docker.internal:51211/v1 ^
  -e OPENAI_API_KEY=foundry-local-key ^
  -v open-webui-data:/app/backend/data ^
  ghcr.io/open-webui/open-webui:main
```

**Забележка:** `host.docker.internal` позволява на Docker контейнери да достъпват хост машината в Windows.

### Стъпка 3: Конфигурация

1. **Отворете браузър:** Навигирайте до `http://localhost:3000`
2. **Първоначална настройка:** Създайте администраторски акаунт
3. **Конфигурация на модела:**
   - Настройки → Модели → OpenAI API  
   - Базов URL: `http://host.docker.internal:51211/v1`
   - API ключ: `foundry-local-key` (всяка стойност работи)
4. **Тестване на връзката:** Моделите трябва да се появят в падащото меню

### Отстраняване на проблеми

**Чести проблеми:**

1. **Отказ на връзката:**
   ```cmd
   # Check Foundry Local status
   foundry service ps
   netstat -ano | findstr :51211
   ```

2. **Моделите не се появяват:**
   - Проверете дали моделът е зареден: `foundry model list`
   - Проверете API отговора: `curl http://localhost:51211/v1/models`
   - Рестартирайте Open WebUI контейнера

## Част 7: Съображения за продукционно разгръщане

### Конфигурация на средата

**Настройка за разработка:**
```cmd
# Development with auto-reload and debugging
chainlit run samples\04\app.py -w --port 8080 --debug
```

**Продукционно разгръщане:**
```cmd
# Production mode with optimizations
chainlit run samples\04\app.py --host 0.0.0.0 --port 8080 --no-cache
```

### Чести проблеми с портове и решения

**Предотвратяване на конфликт с порт 51211:**
```cmd
# Check what's using Foundry Local port
netstat -ano | findstr :51211

# Use different port for Chainlit
chainlit run samples\04\app.py -w --port 8080
```

### Мониторинг на производителността

**Имплементация на проверка на здравето:**
```python
@cl.on_chat_start
async def health_check():
    try:
        # Test model availability
        response = client.chat.completions.create(
            model=model_name,
            messages=[{"role": "user", "content": "test"}],
            max_tokens=1
        )
        return {"status": "healthy", "model": model_name}
    except Exception as e:
        return {"status": "unhealthy", "error": str(e)}
```

## Обобщение

Сесия 4 обхвана създаването на готови за продукция Chainlit приложения за разговорен AI. Научихте за:

- ✅ **Chainlit Framework**: Модерен UI и поддръжка на стрийминг за чат приложения
- ✅ **Интеграция с Foundry Local**: Използване на SDK и модели за конфигурация  
- ✅ **WebGPU Инференция**: AI в браузъра за максимална поверителност
- ✅ **Настройка на Open WebUI**: Разгръщане на професионален чат интерфейс
- ✅ **Продукционни модели**: Управление на грешки, мониторинг и скалируемост

Приложението Sample 04 демонстрира най-добрите практики за създаване на стабилни чат интерфейси, които използват локални AI модели чрез Microsoft Foundry Local, като същевременно осигуряват отлично потребителско изживяване.

## Референции

- **[Sample 04: Chainlit Application](samples/04/README.md)**: Пълно приложение с документация
- **[Chainlit Educational Notebook](samples/04/chainlit_app.ipynb)**: Интерактивни учебни материали
- **[Foundry Local Documentation](https://learn.microsoft.com/azure/ai-foundry/foundry-local/)**: Пълна документация на платформата
- **[Chainlit Documentation](https://docs.chainlit.io/)**: Официална документация на фреймуърка
- **[Open WebUI Integration Guide](https://github.com/microsoft/foundry-local/blob/main/docs/tutorials/chat-application-with-open-web-ui.md)**: Официален урок

---

**Отказ от отговорност**:  
Този документ е преведен с помощта на AI услуга за превод [Co-op Translator](https://github.com/Azure/co-op-translator). Въпреки че се стремим към точност, моля, имайте предвид, че автоматизираните преводи може да съдържат грешки или неточности. Оригиналният документ на неговия роден език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален човешки превод. Не носим отговорност за недоразумения или погрешни интерпретации, произтичащи от използването на този превод.