Розробка бота для автоматичної відповіді на FAQ Bitrix24
Половина вхідних звернень у чат підтримки — це одні й ті самі запитання: «Як повернути товар?», «Де мій замовлення?», «Які умови доставки?». Оператор витрачає на них час, який дорожче коштує на нетипових проблемах. FAQ-бот закриває типові запитання автоматично та передає нестандартні — живому оператору.
Де працює бот
Відкриті лінії Bitrix24 — основна точка входу. Бот підключається до відкритої лінії як перший оператор. Коли клієнт пише в онлайн-чат на сайті, в Telegram або VK, звернення потрапляє боту. Якщо бот відповідає — оператор не турбується. Якщо ні — передає людині.
Реєстрація бота у відкритих лініях:
POST /rest/imopenlines.bot.register
{
"CODE": "faq_bot",
"EVENT_HANDLER": "https://your-server.com/openline/event",
"OPENLINE": "Y" // Бот для відкритих ліній
}
Два підходи до зіставлення запитань
Підхід 1: Пошук за ключовими словами. Запитання та ключові слова зберігаються в базі, бот шукає збіги в тексті повідомлення. Просто в реалізації, зрозуміло в обслуговуванні.
CREATE TABLE custom_faq_entries (
id SERIAL PRIMARY KEY,
question TEXT NOT NULL,
answer TEXT NOT NULL,
keywords TEXT NOT NULL, -- через кому
category VARCHAR(100),
hits INT DEFAULT 0,
is_active TINYINT DEFAULT 1
);
function findFaqAnswer(string $userMessage): ?array {
$words = array_filter(explode(' ', mb_strtolower($userMessage)));
$results = [];
$faqs = getFaqEntries(); // із кешу
foreach ($faqs as $faq) {
$keywords = explode(',', mb_strtolower($faq['keywords']));
$score = 0;
foreach ($keywords as $kw) {
$kw = trim($kw);
if ($kw && (mb_stripos($userMessage, $kw) !== false)) {
$score += mb_strlen($kw); // довгі ключові слова вагоміші
}
}
if ($score > 0) {
$results[] = ['faq' => $faq, 'score' => $score];
}
}
if (empty($results)) return null;
usort($results, fn($a, $b) => $b['score'] <=> $a['score']);
return $results[0]['faq'];
}
Підхід 2: Векторний пошук (RAG). Запитання індексуються як ембединги (OpenAI text-embedding-3-small, Yandex GPT Embeddings). При новому запитанні — пошук найближчих сусідів у векторній БД (pgvector, Qdrant). Працює на семантично схожих формулюваннях без точного збігу слів.
Вибір: для 50–200 FAQ достатньо ключових слів. Для великої бази знань із варіативними формулюваннями — RAG.
Обробка події у відкритій лінії
// Вхідна подія від Б24
$event = json_decode(file_get_contents('php://input'), true);
if ($event['event'] === 'ONIMBOTMESSAGEADD') {
$sessionId = $event['data']['PARAMS']['SESSION_ID'];
$dialogId = $event['data']['PARAMS']['DIALOG_ID'];
$text = $event['data']['PARAMS']['MESSAGE'];
$chatId = $event['data']['PARAMS']['CHAT_ID'];
$faq = findFaqAnswer($text);
if ($faq) {
// Відповідаємо та закриваємо сесію
$b24->callMethod('imopenlines.session.message.send', [
'SESSION_ID' => $sessionId,
'MESSAGE' => $faq['answer'],
]);
// Збільшуємо лічильник hits
incrementFaqHits($faq['id']);
// Закриваємо сесію — оператор не отримує повідомлення
$b24->callMethod('imopenlines.session.close', ['SESSION_ID' => $sessionId]);
} else {
// Передаємо оператору
$b24->callMethod('imopenlines.session.transfer', [
'SESSION_ID' => $sessionId,
'QUEUE_ID' => 1,
]);
$b24->callMethod('imopenlines.session.message.send', [
'SESSION_ID' => $sessionId,
'MESSAGE' => "З'єдную з менеджером, будь ласка, зачекайте...",
]);
}
}
Уточнювальні запитання
Якщо збігів кілька — бот показує варіанти:
if (count($topResults) > 1 && $topResults[0]['score'] < 10) {
$options = array_slice($topResults, 0, 3);
$message = "Уточніть, будь ласка, що вас цікавить:\n";
foreach ($options as $i => $r) {
$message .= ($i + 1) . ". {$r['faq']['question']}\n";
}
$message .= "0. Інше (підключити менеджера)";
// Зберігаємо контекст вибору в Redis
$redis->set("faq_choice:{$sessionId}", json_encode($options), 300);
}
Адміністративний інтерфейс бази FAQ
Контент-менеджер повинен керувати FAQ без правки коду. Розробляємо адміністративний розділ у /bitrix/admin/ або як програму в Б24:
- CRUD для запитань і відповідей.
- Категорії (Доставка, Оплата, Повернення, Технічні питання).
- Статистика: скільки разів запитання було закрито ботом (
hits), скільки передано операторам. - Перегляд сесій, де бот не знайшов відповідь — це пріоритет для поповнення бази.
Аналітика ефективності
-- Відсоток автоматично закритих сесій
SELECT
DATE(created_at) AS day,
COUNT(*) AS total,
SUM(CASE WHEN closed_by = 'bot' THEN 1 ELSE 0 END) AS auto_closed,
ROUND(SUM(CASE WHEN closed_by = 'bot' THEN 1 ELSE 0 END) * 100.0 / COUNT(*), 1) AS autoclose_pct
FROM custom_faq_sessions
GROUP BY DATE(created_at)
ORDER BY day DESC;
Цільовий показник автозакриття для зрілої бази FAQ — 60–70%.
Терміни
| Етап | Термін |
|---|---|
| Реєстрація бота у відкритих лініях, базова інтеграція | 1–2 дні |
| Структура БД FAQ, пошук за ключовими словами | 2–3 дні |
| Логіка передачі оператору, уточнювальні запитання | 2–3 дні |
| Адміністративний інтерфейс (CRUD FAQ) | 2–3 дні |
| Аналітика та звіти | 1–2 дні |
| Наповнення бази + тестування | 2–3 дні |
Разом: 1.5–2.5 тижні без урахування наповнення бази. Наповнення — окрема робота, залежить від обсягу документації.







