🏗️ Архитектура веб-приложения: Аниме-персонаж для страницы 404
📋 Техническое задание
Цель:
Создать интерактивную страницу 404 с аниме-персонажем (девочка), который общается с пользователем через чат-интерфейс с поддержкой видео-анимаций и ИИ-ответов.
🎯 1. Архитектура системы
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ Frontend │ │ Backend API │ │ AI Service │
│ (React/Vue) │◄──►│ (Node.js) │◄──►│ (Hugging Face)│
└─────────────────┘ └──────────────────┘ └─────────────────┘
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ Video CDN │ │ Database │ │ Prompt Engine │
│ (Cloudinary) │ │ (MongoDB) │ │ (Custom) │
└─────────────────┘ └──────────────────┘ └─────────────────┘
🎨 2. Frontend компоненты
2.1 Основная структура (React)
jsx Скопировать
Закрыть блок
// components/AnimeChat404.jsx
import React, { useState, useEffect } from 'react';
import VideoPlayer from './VideoPlayer';
import ChatBubble from './ChatBubble';
import MessageInput from './MessageInput';
const AnimeChat404 = () => {
const [currentVideo, setCurrentVideo] = useState('idle');
const [messages, setMessages] = useState([]);
const [isTyping, setIsTyping] = useState(false);
return (
setCurrentVideo('idle')}
/>
<ChatBubble messages={messages} isTyping={isTyping} />
<MessageInput onSendMessage={handleSendMessage} />
);
};
2.2 Видео-плеер для анимаций
jsx Скопировать
Закрыть блок
// components/VideoPlayer.jsx
const VideoPlayer = ({ videoState, onVideoEnd }) => {
const videoMap = {
idle: '/videos/character/idle_loop.mp4',
talking: '/videos/character/talking.mp4',
thinking: '/videos/character/thinking.mp4',
happy: '/videos/character/happy_reaction.mp4',
flirty: '/videos/character/flirty_wink.mp4', // 18+ контент
embarrassed: '/videos/character/embarrassed.mp4'
};
return (
);
};
2.3 Чат-интерфейс
jsx Скопировать
Закрыть блок
// components/ChatBubble.jsx
const ChatBubble = ({ messages, isTyping }) => {
return (
{messages.map((msg, index) => (
{msg.text}
))}
{isTyping && <TypingIndicator />}
);
};
⚙️ 3. Backend API (Node.js + Express)
3.1 Основной сервер
javascript Скопировать
Закрыть блок
// server.js
const express = require('express');
const cors = require('cors');
const chatRoutes = require('./routes/chat');
const app = express();
app.use(cors());
app.use(express.json());
app.use('/api/chat', chatRoutes);
app.listen(3001, () => {
console.log('Anime Chat API running on port 3001');
});
3.2 Чат-контроллер
javascript Скопировать
Закрыть блок
// routes/chat.js
const express = require('express');
const { generateResponse } = require('../services/aiService');
const { analyzeMessage } = require('../services/promptAnalyzer');
const router = express.Router();
router.post('/message', async (req, res) => {
try {
const { message, userId } = req.body;
// Анализ сообщения для выбора анимации
const analysis = analyzeMessage(message);
// Генерация ответа через ИИ
const aiResponse = await generateResponse(message, analysis);
res.json({
response: aiResponse.text,
animation: aiResponse.animation,
mood: aiResponse.mood
});
} catch (error) {
res.status(500).json({ error: 'AI service unavailable' });
}
});
module.exports = router;
🤖 4. ИИ-сервис (бесплатные модели)
4.1 Hugging Face интеграция
javascript Скопировать
Закрыть блок
// services/aiService.js
const { HfInference } = require('@huggingface/inference');
const hf = new HfInference(process.env.HUGGINGFACE_TOKEN);
const generateResponse = async (userMessage, analysis) => {
// Системный промпт для аниме-персонажа
const systemPrompt = `
Ты - милая аниме девочка по имени Юки, которая помогает пользователям на странице 404.
Ты игривая, немного застенчивая, но можешь быть и кокетливой.
Отвечай в аниме-стиле с эмодзи. Можешь флиртовать и быть немного провокационной.
Контекст: пользователь попал на несуществующую страницу.
Сообщение пользователя: "${userMessage}"
`;
try {
// Используем бесплатную модель
const response = await hf.textGeneration({
model: 'microsoft/DialoGPT-medium',
inputs: systemPrompt,
parameters: {
max_new_tokens: 150,
temperature: 0.8,
do_sample: true
}
});
return {
text: response.generated_text,
animation: determineAnimation(analysis),
mood: analysis.mood
};
} catch (error) {
return {
text: "Ой, кажется я немного растерялась... 😅 Попробуй еще раз!",
animation: 'embarrassed',
mood: 'confused'
};
}
};
4.2 Альтернативные бесплатные ИИ
javascript Скопировать
Закрыть блок
// services/alternativeAI.js
// Вариант 1: Ollama (локально)
const ollamaGenerate = async (prompt) => {
const response = await fetch('http://localhost:11434/api/generate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
model: 'llama2',
prompt: prompt,
stream: false
})
});
return response.json();
};
// Вариант 2: OpenRouter (бесплатные модели)
const openRouterGenerate = async (prompt) => {
const response = await fetch('https://openrouter.ai/api/v1/chat/completions', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.OPENROUTER_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
model: 'nousresearch/nous-capybara-7b:free',
messages: [{ role: 'user', content: prompt }]
})
});
return response.json();
};
🎬 5. Система анимаций
5.1 Анализатор настроения
javascript Скопировать
Закрыть блок
// services/promptAnalyzer.js
const analyzeMessage = (message) => {
const lowerMsg = message.toLowerCase();
// Детекция 18+ контента
const flirtyKeywords = ['красивая', 'милая', 'сексуальная', 'привлекательная'];
const sadKeywords = ['грустно', 'плохо', 'ошибка', 'не работает'];
const happyKeywords = ['спасибо', 'круто', 'отлично', 'хорошо'];
if (flirtyKeywords.some(word => lowerMsg.includes(word))) {
return { mood: 'flirty', animation: 'flirty' };
}
if (sadKeywords.some(word => lowerMsg.includes(word))) {
return { mood: 'sympathetic', animation: 'thinking' };
}
if (happyKeywords.some(word => lowerMsg.includes(word))) {
return { mood: 'happy', animation: 'happy' };
}
return { mood: 'neutral', animation: 'talking' };
};
const determineAnimation = (analysis) => {
const animations = {
flirty: 'flirty',
happy: 'happy',
sympathetic: 'thinking',
neutral: 'talking'
};
return animations[analysis.mood] || 'talking';
};
🎨 6. Дизайн персонажа (техзадание для художника)
6.1 Описание персонажа
Имя: Юки (Yuki)
Возраст: 18-20 лет
Стиль: Современный аниме (похожий на Grok)
Внешность:
- Длинные серебристые/белые волосы с голубыми прядями
- Большие выразительные глаза (голубые/фиолетовые)
- Милое лицо с легким румянцем
- Стройная фигура
Одежда:
- Футуристический наряд (в стиле киберпанк)
- Короткая юбка или шорты
- Топ с открытыми плечами
- Технологические аксессуары (наушники, браслеты)
- Цветовая схема: белый, голубой, фиолетовый
18+ элементы:
- Слегка провокационная поза
- Кокетливые выражения лица
- Намеки на декольте (в рамках приличия)
6.2 Список необходимых анимаций
Видео-файлы (по 3-5 секунд каждый):
1. idle_loop.mp4 - базовая анимация (дыхание, моргание)
2. talking.mp4 - говорит (движение губ, жесты)
3. thinking.mp4 - задумчивость (палец у губ)
4. happy_reaction.mp4 - радость (улыбка, подпрыгивание)
5. flirty_wink.mp4 - кокетство (подмигивание, поцелуй)
6. embarrassed.mp4 - смущение (румянец, отвод взгляда)
7. greeting.mp4 - приветствие (машет рукой)
8. goodbye.mp4 - прощание (воздушный поцелуй)
💾 7. База данных (MongoDB)
7.1 Схема данных
javascript Скопировать
Закрыть блок
// models/ChatSession.js
const mongoose = require('mongoose');
const chatSessionSchema = new mongoose.Schema({
userId: String,
messages: [{
sender: { type: String, enum: ['user', 'yuki'] },
text: String,
timestamp: { type: Date, default: Date.now },
animation: String,
mood: String
}],
createdAt: { type: Date, default: Date.now },
lastActivity: { type: Date, default: Date.now }
});
module.exports = mongoose.model('ChatSession', chatSessionSchema);
🚀 8. Деплой и хостинг
8.1 Рекомендуемый стек
Frontend: Vercel (бесплатно)
Backend: Railway/Render (бесплатно)
Database: MongoDB Atlas (бесплатно)
CDN для видео: Cloudinary (бесплатно до 25GB)
AI API: Hugging Face (бесплатно с лимитами)
8.2 Environment переменные
bash Скопировать
Закрыть блок
# .env
HUGGINGFACE_TOKEN=your_token_here
MONGODB_URI=mongodb+srv://...
OPENROUTER_KEY=your_key_here
CLOUDINARY_URL=cloudinary://...
NODE_ENV=production
🎯 9. Примеры диалогов (18+ контент)
9.1 Флиртующие ответы
javascript Скопировать
Закрыть блок
const flirtyResponses = [
"Ой, ты такой милый! 😊💕 Может, вместо поиска страниц, поищем что-то интереснее? 😉",
"Хм, кажется ты заблудился... Но я не против составить тебе компанию! 💖✨",
"404? А я думала, ты специально пришел ко мне в гости! 😘💫",
"Эта страница исчезла, но я-то здесь... И мне немного скучно 😏💕"
];
9.2 Игривые реакции
javascript Скопировать
Закрыть блок
const playfulResponses = [
"Упс! Кажется, эта страница убежала от нас! 🏃♀️💨 Но не расстраивайся, я здесь!",
"404 - это как игра в прятки, только страница слишком хорошо спряталась! 😄🔍",
"Хочешь, я помогу найти то, что ты ищешь? Я знаю много интересных мест! 😊🗺️"
];
📱 10. Мобильная адаптация
10.1 Responsive дизайн
css Скопировать
Закрыть блок
/* styles/anime-chat.css */
.anime-404-container {
display: flex;
flex-direction: column;
height: 100vh;
max-width: 1200px;
margin: 0 auto;
Модель: Claude 4 Sonnet