Почему чат-бот на сайте - это не роскошь, а необходимость
Вечер пятницы, 23:00. Человек сидит на вашем сайте и думает: "Сколько стоит разработка интернет-магазина?". Он готов оставить заявку. Но менеджер уже спит, форма обратной связи обещает ответ "в течение 24 часов", а до понедельника человек найдёт другую компанию.
Знакомая ситуация? Именно так бизнес теряет клиентов каждый день. По статистике, 55% посетителей сайта уходят, если не получают ответ в первые 5 минут.
AI чат-бот решает эту проблему. Это виртуальный сотрудник, который работает 24 часа в сутки, 7 дней в неделю, мгновенно отвечает на вопросы и собирает контакты тех, кому нужно связаться с менеджером. И стоит он $3-30 в месяц - дешевле, чем одна чашка кофе в день.
В этой статье мы покажем, как создать такого бота за один день. Пошагово, с подробными объяснениями каждой строки кода.
Два типа чат-ботов: кнопки vs искусственный интеллект
Кнопочный бот (rule-based) - это бот с заранее прописанными сценариями. "Нажмите 1, чтобы узнать цены. Нажмите 2 для техподдержки." Простой и предсказуемый, но ограниченный: если вопрос не предусмотрен в сценарии - бот разводит руками.
Представьте телефонный автоответчик: "Для русского языка нажмите 1, for English press 2". Вы можете только выбирать из предложенных вариантов.
AI-бот (на основе нейросети) - это бот, который понимает обычный человеческий язык. Пользователь пишет своими словами: "А вы делаете мобильные приложения? И сколько это примерно стоит?" - и бот понимает суть вопроса и отвечает на основе базы знаний вашей компании.
Это как живой менеджер: вы говорите свободно, а он понимает и отвечает по делу. Именно такого бота мы будем строить.
Архитектура: три простых компонента
Наш чат-бот состоит из трёх частей:
- Виджет - это то, что видит пользователь: кнопка в углу экрана и окно чата. Делается на HTML, CSS и JavaScript
- Сервер (backend) - программа, которая принимает сообщения от виджета, отправляет их нейросети и возвращает ответы. Делается на Node.js
- База знаний - информация о вашей компании: услуги, цены, FAQ. Нейросеть использует её для ответов
Аналогия: виджет - это окошко на почте, сервер - почтальон, база знаний - справочник, по которому почтальон ищет ответы.
Шаг 1: Виджет чата (то, что видит пользователь)
Виджет - это плавающая кнопка в правом нижнем углу сайта. При нажатии открывается окно чата. Весь виджет - один JavaScript-файл, который можно подключить к любому сайту одной строкой кода.
// chatbot-widget.js - виджет чата для сайта
// Подключается одной строкой в HTML:
// <script src="/chatbot-widget.js"></script>
// Всё оборачиваем в IIFE (Immediately Invoked Function Expression)
// Это значит: функция создаётся и сразу выполняется
// Зачем? Чтобы наши переменные не конфликтовали с другим кодом на сайте
(function() {
// Создаём HTML-элемент, который будет содержать весь виджет
const container = document.createElement('div')
container.id = 'chatbot-widget'
// innerHTML - содержимое элемента в формате HTML
// Здесь мы создаём: стили (CSS), кнопку и окно чата
container.innerHTML = `
<style>
/* Стили виджета */
#chatbot-widget { font-family: -apple-system, sans-serif; }
/* Круглая кнопка в правом нижнем углу */
.cb-button {
position: fixed; /* Фиксированная позиция - не сдвигается при прокрутке */
bottom: 24px; /* 24px от нижнего края */
right: 24px; /* 24px от правого края */
z-index: 9999; /* Поверх всех остальных элементов */
width: 56px;
height: 56px;
border-radius: 50%; /* Круглая форма */
background: #00ff88; /* Зелёный цвет */
border: none;
cursor: pointer; /* Указатель при наведении */
box-shadow: 0 4px 20px rgba(0,255,136,0.3); /* Тень */
display: flex;
align-items: center;
justify-content: center;
transition: transform 0.2s; /* Плавная анимация */
}
.cb-button:hover { transform: scale(1.1); } /* Увеличение при наведении */
.cb-button svg { width: 24px; height: 24px; fill: #000; }
/* Окно чата */
.cb-window {
position: fixed;
bottom: 96px; /* Чуть выше кнопки */
right: 24px;
z-index: 9999;
width: 380px;
height: 520px;
border-radius: 16px; /* Скруглённые углы */
background: #fff;
box-shadow: 0 8px 40px rgba(0,0,0,0.15);
display: none; /* По умолчанию скрыто */
flex-direction: column;
overflow: hidden;
}
.cb-window.open { display: flex; } /* Показываем при открытии */
/* Шапка окна чата */
.cb-header {
padding: 16px;
background: #111;
color: #fff;
display: flex;
align-items: center;
gap: 12px;
}
/* Зелёная точка "онлайн" */
.cb-header .status {
width: 8px; height: 8px;
border-radius: 50%;
background: #00ff88;
}
/* Область сообщений */
.cb-messages {
flex: 1; /* Занимает всё свободное пространство */
overflow-y: auto; /* Прокрутка, если сообщений много */
padding: 16px;
display: flex;
flex-direction: column;
gap: 8px;
}
/* Одно сообщение */
.cb-msg {
max-width: 80%;
padding: 10px 14px;
border-radius: 12px;
font-size: 14px;
line-height: 1.5;
}
/* Сообщение от бота - слева, серый фон */
.cb-msg.bot {
background: #f0f0f0;
align-self: flex-start;
}
/* Сообщение от пользователя - справа, тёмный фон */
.cb-msg.user {
background: #111;
color: #fff;
align-self: flex-end;
}
/* Область ввода сообщения */
.cb-input-area {
padding: 12px;
border-top: 1px solid #eee;
display: flex;
gap: 8px;
}
.cb-input {
flex: 1;
border: 1px solid #ddd;
border-radius: 8px;
padding: 10px 14px;
font-size: 14px;
outline: none;
}
.cb-input:focus { border-color: #00ff88; }
.cb-send {
background: #111;
color: #fff;
border: none;
border-radius: 8px;
padding: 10px 16px;
cursor: pointer;
}
/* Адаптация для мобильных устройств */
@media (max-width: 480px) {
.cb-window {
width: calc(100% - 32px); /* Почти на всю ширину экрана */
height: 70vh; /* 70% высоты экрана */
right: 16px;
bottom: 80px;
}
}
</style>
<!-- Кнопка открытия чата (иконка сообщения) -->
<button class="cb-button" onclick="toggleChat()">
<svg viewBox="0 0 24 24">
<path d="M20 2H4c-1.1 0-2 .9-2 2v18l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2z"/>
</svg>
</button>
<!-- Окно чата -->
<div class="cb-window" id="cb-window">
<div class="cb-header">
<div class="status"></div>
<div>
<div style="font-weight:600">AI-Ассистент</div>
<div style="font-size:12px;opacity:0.7">Отвечаю мгновенно, 24/7</div>
</div>
</div>
<div class="cb-messages" id="cb-messages">
<div class="cb-msg bot">Здравствуйте! Я AI-ассистент. Задайте вопрос о наших услугах, ценах или сроках - отвечу мгновенно.</div>
</div>
<div class="cb-input-area">
<input class="cb-input" id="cb-input"
placeholder="Напишите сообщение..."
onkeydown="if(event.key==='Enter')sendMessage()" />
<button class="cb-send" onclick="sendMessage()">Отправить</button>
</div>
</div>
`
// Добавляем виджет на страницу
document.body.appendChild(container)
// history - массив для хранения истории переписки
// Отправляется на сервер при каждом сообщении,
// чтобы бот помнил контекст разговора
const history = []
// Функция открытия/закрытия окна чата
window.toggleChat = function() {
document.getElementById('cb-window').classList.toggle('open')
}
// Функция добавления сообщения в окно чата
function addMessage(text, role) {
const messages = document.getElementById('cb-messages')
const msg = document.createElement('div')
msg.className = `cb-msg ${role}` // 'bot' или 'user'
msg.textContent = text
messages.appendChild(msg)
messages.scrollTop = messages.scrollHeight // Прокрутка вниз
return msg
}
// Функция отправки сообщения
window.sendMessage = async function() {
const input = document.getElementById('cb-input')
const text = input.value.trim() // Убираем пробелы в начале и конце
if (!text) return // Не отправляем пустые сообщения
input.value = '' // Очищаем поле ввода
addMessage(text, 'user') // Показываем сообщение пользователя
history.push({ role: 'user', content: text }) // Добавляем в историю
// Показываем индикатор "бот думает..."
const typing = addMessage('Думаю...', 'bot')
try {
// Отправляем историю переписки на наш сервер
const response = await fetch('/api/chatbot', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ messages: history }),
})
const data = await response.json()
// Заменяем "Думаю..." на реальный ответ
typing.remove()
addMessage(data.reply, 'bot')
history.push({ role: 'assistant', content: data.reply })
} catch {
typing.remove()
addMessage('Извините, произошла ошибка. Попробуйте позже.', 'bot')
}
}
})()
Шаг 2: Сервер - соединяем виджет с нейросетью
Сервер - это "посредник" между виджетом и нейросетью Claude. Он получает сообщение от виджета, добавляет информацию о компании (системный промпт) и отправляет всё в Claude API. Claude формирует ответ, сервер передаёт его обратно виджету.
// chatbot-api.ts - серверная часть чат-бота
// Устанавливаем: npm install express @anthropic-ai/sdk express-rate-limit
import express from 'express'
import Anthropic from '@anthropic-ai/sdk'
import rateLimit from 'express-rate-limit'
const app = express()
app.use(express.json()) // Чтобы сервер понимал JSON
// Создаём клиент Claude API
const anthropic = new Anthropic()
// Rate limiting - защита от спама
// Не больше 20 запросов в минуту с одного IP-адреса
// Без этого злоумышленник может отправить тысячи запросов и разорить вас на API
const limiter = rateLimit({
windowMs: 60 * 1000, // Окно: 1 минута
max: 20, // Максимум 20 запросов
message: { error: 'Слишком много запросов, подождите минуту' },
})
// Системный промпт - "мозг" вашего чат-бота
// Здесь вы описываете ВСЮ информацию о компании
// Чем подробнее - тем точнее будут ответы
const SYSTEM_PROMPT = `Ты - AI-ассистент компании [Название вашей компании].
Отвечаешь на вопросы посетителей сайта о компании, услугах, ценах и сроках.
ИНФОРМАЦИЯ О КОМПАНИИ:
- Направление: веб-разработка и мобильные приложения
- Услуги: разработка сайтов, интернет-магазинов, CRM-систем, мобильных приложений, AI-интеграции
- Стек технологий: React, Next.js, Node.js, TypeScript, PostgreSQL, React Native
- Сроки: лендинг 1-2 недели, корпоративный сайт 3-4 недели, интернет-магазин 4-8 недель, CRM 8-16 недель
- Цены: лендинг от 80 000 руб, корпоративный сайт от 150 000 руб, интернет-магазин от 300 000 руб
ПРАВИЛА ПОВЕДЕНИЯ:
- Отвечай кратко и по делу (2-4 предложения)
- Будь дружелюбным и профессиональным
- Если не знаешь точный ответ - предложи оставить контакты для связи с менеджером
- НЕ выдумывай информацию, которой нет в базе знаний
- НЕ обсуждай темы, не связанные с компанией
- На вопросы о точной стоимости нестандартных проектов говори: "Точную стоимость рассчитает менеджер после обсуждения деталей. Оставьте контакты - мы свяжемся в рабочее время"
СБОР КОНТАКТОВ:
Если пользователь готов к сотрудничеству или задаёт детальные вопросы о проекте,
предложи оставить контакты: "Чтобы обсудить детали вашего проекта, оставьте номер
телефона или email - менеджер свяжется в рабочее время."
ОБРАБОТКА ОСОБЫХ СИТУАЦИЙ:
- Оскорбления: вежливо перенаправь на деловую тему
- Вопросы о конкурентах: "Я могу рассказать только о наших услугах"
- Просьбы написать код/сочинение: "Я специализируюсь на вопросах о нашей компании"
- Контакты пользователя: подтверди "Спасибо! Менеджер свяжется с вами в рабочее время"
`
// Endpoint для чат-бота
// POST /api/chatbot - принимает историю переписки, возвращает ответ
app.post('/api/chatbot', limiter, async (req, res) => {
try {
const { messages } = req.body
// Проверяем входные данные
if (!messages || !Array.isArray(messages) || messages.length > 20) {
return res.status(400).json({ error: 'Некорректный запрос' })
}
// Очищаем и проверяем каждое сообщение
// Это защита от атак: пользователь может отправить что угодно
const sanitized = messages.map((m) => ({
role: m.role === 'user' ? 'user' : 'assistant',
content: String(m.content).slice(0, 1000), // Максимум 1000 символов
}))
// Отправляем запрос в Claude API
const response = await anthropic.messages.create({
model: 'claude-haiku-4-5-20251001', // Быстрая и дешёвая модель
max_tokens: 500, // Короткие ответы (экономим деньги)
system: SYSTEM_PROMPT, // Информация о компании
messages: sanitized, // История переписки
})
// Извлекаем текст ответа
const reply = response.content
.filter(b => b.type === 'text')
.map(b => b.text)
.join('')
// Отправляем ответ виджету
res.json({ reply })
} catch (error) {
console.error('Chatbot error:', error)
res.status(500).json({ error: 'Ошибка сервера' })
}
})
app.listen(3001, () => {
console.log('Сервер чат-бота запущен на порту 3001')
})
Шаг 3: База знаний - чтобы бот отвечал точнее
Системный промпт хорош для базовых вопросов. Но если у вас 50 услуг и 100 вопросов в FAQ - всё это не влезет в промпт. Решение: перед каждым ответом ищем релевантную информацию в базе знаний и добавляем её к промпту.
// knowledge-base.ts - простой поиск по базе знаний
// Для начала достаточно текстового поиска по ключевым словам
// Для продвинутой версии можно использовать векторную БД (pgvector)
// Массив записей FAQ - вопросы, ответы и ключевые слова для поиска
const knowledge = [
{
question: 'Сколько стоит разработка сайта?',
answer: 'Лендинг: от 80 000 руб (1-2 недели). Корпоративный сайт: от 150 000 руб (3-4 недели). Интернет-магазин: от 300 000 руб (4-8 недель). Точная стоимость зависит от дизайна, функционала и интеграций.',
keywords: ['цена', 'стоимость', 'сколько', 'сайт', 'лендинг', 'магазин', 'стоит'],
},
{
question: 'Какие технологии вы используете?',
answer: 'Frontend: React, Next.js, TypeScript. Backend: Node.js, Express, PostgreSQL. Мобильные приложения: React Native. Инфраструктура: Docker, GitHub Actions, Nginx.',
keywords: ['технологии', 'стек', 'язык', 'фреймворк', 'react', 'node'],
},
{
question: 'Как происходит процесс разработки?',
answer: '1. Бриф и обсуждение задачи (бесплатно). 2. Дизайн-макеты в Figma. 3. Разработка спринтами по 1-2 недели. 4. Тестирование. 5. Деплой и запуск. 6. Гарантийная поддержка 3 месяца. Связь через Telegram, еженедельные демо.',
keywords: ['процесс', 'как работаете', 'этапы', 'разработка', 'спринт', 'порядок'],
},
{
question: 'Есть ли гарантия?',
answer: 'Да, мы предоставляем 3 месяца бесплатной гарантийной поддержки после запуска. Исправление багов и мелкие доработки входят в гарантию.',
keywords: ['гарантия', 'поддержка', 'баг', 'исправление', 'после запуска'],
},
// Добавьте ещё 10-50 записей - чем больше, тем точнее ответы
]
// Функция поиска: находит самые подходящие записи по ключевым словам
function findRelevant(query, limit = 3) {
const queryLower = query.toLowerCase()
const queryWords = queryLower.split(/\s+/) // Разбиваем запрос на слова
return knowledge
.map(item => {
// Для каждой записи считаем "очки" - насколько она подходит
let score = 0
for (const keyword of item.keywords) {
// Если ключевое слово встречается в запросе - +2 очка
if (queryLower.includes(keyword)) score += 2
// Если хотя бы часть слова совпадает - +1 очко
for (const word of queryWords) {
if (keyword.includes(word) || word.includes(keyword)) score += 1
}
}
return { item, score }
})
.filter(x => x.score > 0) // Оставляем только подходящие
.sort((a, b) => b.score - a.score) // Сортируем по убыванию очков
.slice(0, limit) // Берём топ-3
.map(x => x.item)
}
// Используем базу знаний в endpoint-е чат-бота
app.post('/api/chatbot', limiter, async (req, res) => {
const { messages } = req.body
const lastMessage = messages[messages.length - 1].content
// Ищем релевантную информацию в базе знаний
const relevant = findRelevant(lastMessage)
// Добавляем найденную информацию к системному промпту
let contextPrompt = SYSTEM_PROMPT
if (relevant.length > 0) {
contextPrompt += '\n\nРЕЛЕВАНТНАЯ ИНФОРМАЦИЯ ИЗ БАЗЫ ЗНАНИЙ:\n'
for (const item of relevant) {
contextPrompt += `Вопрос: ${item.question}\nОтвет: ${item.answer}\n\n`
}
contextPrompt += 'Используй эту информацию для ответа.'
}
// Дальше отправляем в Claude с расширенным промптом
const response = await anthropic.messages.create({
model: 'claude-haiku-4-5-20251001',
max_tokens: 500,
system: contextPrompt, // Промпт с добавленной информацией
messages: sanitized,
})
// ...
})
Аналитика: понимаем, как работает бот
Без аналитики вы не узнаете, помогает бот или раздражает пользователей. Логируйте каждый разговор:
// Логирование разговоров в базу данных
// Это даёт вам ценные данные для улучшения бота
async function logConversation(sessionId, messages, metadata) {
await db.query(
`INSERT INTO chatbot_logs (session_id, messages, metadata, created_at)
VALUES (?, ?, ?, NOW())`,
[sessionId, JSON.stringify(messages), JSON.stringify(metadata)]
)
}
// Какие метрики отслеживать:
// 1. Количество разговоров в день - растёт ли популярность?
// 2. Среднее количество сообщений в разговоре
// (если > 5, бот не может найти ответ - нужно улучшить базу знаний)
// 3. Процент разговоров, где пользователь оставил контакты (конверсия)
// Это главная метрика! Бот должен собирать лиды
// 4. Самые частые вопросы - добавьте их в базу знаний
// 5. Разговоры, где бот не смог ответить - это точки улучшения
Стоимость: сколько это стоит в месяц
Claude Haiku - одна из самых доступных AI-моделей. Вот примерный расчёт:
- Средний разговор: 5 сообщений, примерно 2000 входных токенов + 500 выходных
- Стоимость одного разговора: примерно $0.001 (0.1 цента - дешевле спички)
- 100 разговоров в день: примерно $3 в месяц
- 1000 разговоров в день: примерно $30 в месяц
Для сравнения: менеджер, работающий в ночную смену, обходится в 50 000+ рублей в месяц. Чат-бот, работающий 24/7, обходится в 200-2000 рублей. При этом бот не устаёт, не ошибается (в рамках базы знаний) и отвечает мгновенно.
Шаг 4: Подключение к сайту
Самый быстрый способ запустить бота - добавить endpoint в существующий сервер и подключить виджет одной строкой:
<!-- Добавьте эту строку перед закрывающим тегом </body> на любой странице -->
<script src="/chatbot-widget.js"></script>
<!-- Или для оптимизации: загружаем виджет с задержкой,
чтобы не замедлять загрузку основного контента -->
<script>
// Ждём 3 секунды после загрузки страницы, потом подгружаем виджет
// Пользователь вряд ли начнёт чат в первые 3 секунды,
// а загрузка страницы будет быстрее
setTimeout(function() {
var s = document.createElement('script')
s.src = '/chatbot-widget.js'
document.body.appendChild(s)
}, 3000)
</script>
Как улучшить бота после запуска
Первая версия бота будет работать, но её можно улучшать бесконечно. Вот план развития:
- Неделя 1-2: Запустите бота с базовой информацией о компании. Смотрите аналитику: на какие вопросы бот не может ответить? Добавляйте эти вопросы в базу знаний
- Месяц 1: Добавьте сбор контактов в CRM. Когда пользователь оставляет email или телефон, автоматически создавайте лид в вашей CRM-системе
- Месяц 2: Переведите базу знаний на векторный поиск (pgvector). Это позволит боту находить ответы не по ключевым словам, а по смыслу - гораздо точнее
- Месяц 3: Добавьте интеграции: бот может проверять статус заказа, показывать расписание, записывать на встречу - всё это через API
Чек-лист запуска
- Виджет: кнопка + окно чата, работает на мобильных и десктопе
- Backend: endpoint с rate limiting (защита от спама) и валидацией данных
- Системный промпт: подробная информация о компании, правила поведения бота
- База знаний: минимум 10-20 часто задаваемых вопросов с ответами
- Обработка сложных случаев: оскорбления, нетематические вопросы, неизвестные вопросы
- Аналитика: логирование всех разговоров для анализа
- Тестирование: проверьте 20 типовых вопросов ваших клиентов перед запуском
Итого
AI чат-бот на сайте - это не сложная технология из будущего. Это три простых компонента: виджет (HTML/CSS/JS), сервер (Node.js + Claude API) и база знаний (FAQ вашей компании). За один день вы получаете ассистента, который работает 24/7 и стоит $3-30 в месяц.
Главное преимущество для бизнеса: бот собирает контакты потенциальных клиентов, пока вы спите. Каждый посетитель, который получил мгновенный ответ и оставил email - это потенциальная сделка, которую вы бы потеряли без бота.
Хотите чат-бота, который знает всё о вашем бизнесе и конвертирует посетителей в клиентов? Напишите нам - сделаем, настроим и обучим за один день.