Как собрать своего ИИ-суфлёра для операторов через API Verbox

05 октября 2026
Время чтения ≈ 7 минут

Проблема: ИИ-боты — это удобно, но иногда они начинают писать отсебятину. Оператору приходится исправлять сообщения уже после отправки, а это убивает и скорость, и качество сервиса.

 

Решение: Собрать своего ИИ-суфлёра. Бот не пишет клиенту напрямую, а предлагает оператору готовый ответ. Оператор решает: отправить, отредактировать или проигнорировать.

 

В этой статье — пошаговое руководство для технических специалистов. Мы разберём архитектуру, настройку webhook, вызов LLM и отправку подсказок через API Verbox.

Если вам не нужна кастомная логика и вы хотите готовое решение — в Verbox есть встроенный режим «Подсказки» в интеграции с Copilot. Это настройка в пару кликов, без кода. Но если вы хотите контролировать всё — читайте дальше.
 

 

Архитектура решения

 

Схема выглядит так:

Клиент пишет в чат
       ↓
Verbox отправляет webhook на ваш сервер
       ↓
Ваш сервер принимает данные, отвечает 200 OK
       ↓
Отдельный воркер забирает задачу, идёт в LLM
       ↓
LLM возвращает ответ
       ↓
Ваш сервер вызывает метод Verbox API
       ↓
Подсказка появляется у оператора в чате
 

Ключевой момент: У Verbox есть таймаут 10 секунд на запрос. Если ваш сервер не ответит за это время — webhook считается неудачным, и Verbox не будет его повторять. Поэтому нельзя идти в LLM прямо в обработчике webhook. Сначала примите данные, ответьте 200 OK, а потом обрабатывайте асинхронно.

 

 

Шаг 1. Настройка Webhook

 

Зайдите в личный кабинет Verbox: API → Webhooks.

Нажмите «Добавить» в контейнере «Online-чат» и заполните поля:

 
Поле Что указать
Название Любое, для удобства. Например, «ИИ-суфлёр»
URL Адрес вашего сервера, который будет принимать webhook
Секретный ключ Опционально. Verbox передаст его в запросе — вы можете проверить, что запрос от нас
Basic Authorization Опционально. Дополнительная защита
Источник событий Выберите ваш сайт (проект)
События Только «Новое сообщение от клиента» ( newMessageFromClient )
 

После сохранения Verbox начнёт отправлять POST-запросы на ваш URL при каждом новом сообщении клиента.

 

 

Шаг 2. Приём данных

 

Verbox отправляет POST-запрос с JSON в теле.
Вот пример payload для события newMessageFromClient:

 
{
  "eventId": "newMessageFromClient",
  "data": {
    "site": {
      "id": "acbd18db4cc2f85cedef654fccc4a4d8",
      "domain": "site.com"
    },
    "client": {
      "searchId": 123,
      "clientId": "sw9dzztkdbec7y8jvfzo9ixs4o6wfp5n",
      "name": "Иван",
      "phone": "79001234444",
      "email": "test@gmail.com"
    },
    "dialog": {
      "id": 33,
      "createTimestamp": 1790843869
    },
    "message": {
      "id": 123,
      "text": "Добрый день!",
      "content": {
        "text": "Добрый день!",
        "attachments": []
      },
      "dialogId": 33,
      "isVisibleForClient": true
    },
    "operator": "my_operator",
    "whoSend": "client",
    "dateTime": "2026-10-01 11:37:49"
  },
  "secretKey": "2d16c21c6231ef1a698df5238b08ef82"
}
 

Что здесь важно:

  • data.message.id — уникальный идентификатор сообщения. Его нужно передать в replyToMessageId, когда будете отправлять подсказку.
  • data.message.text — текст сообщения клиента. Это то, что вы отправите в LLM.
  • data.message.content — структурированный контент. Если клиент прислал картинку или файл, в text будет ссылка, а в content.attachments — массив вложений.
  • data.client.clientId — идентификатор клиента. Его нужно передать в объект client, когда будете вызывать API.
  • data.dialog.id — идентификатор диалога. Пригодится, если захотите запросить историю переписки.
  • secretKey — тот самый секретный ключ из настроек webhook. Проверьте его на своей стороне, чтобы убедиться, что запрос от Verbox.
 

Пример обработчика на Python (FastAPI):

 
from fastapi import FastAPI, Request, HTTPException
from fastapi.responses import JSONResponse
import json
import redis

app = FastAPI()
r = redis.Redis(host='localhost', port=6379, db=0)

VERBOX_SECRET_KEY = "ваш_секретный_ключ"

@app.post("/webhook/verbox")
async def verbox_webhook(request: Request):
    payload = await request.json()

    # Проверяем секретный ключ
    if payload.get("secretKey") != VERBOX_SECRET_KEY:
        raise HTTPException(status_code=403, detail="Invalid secret key")

    # Проверяем событие
    if payload.get("eventId") != "newMessageFromClient":
        return JSONResponse({"status": "ignored"})

    # Кладём задачу в очередь и сразу отвечаем 200 OK
    r.lpush("suggestions_queue", json.dumps(payload))
    return JSONResponse({"status": "accepted"})
 

Почему так: Мы отвечаем 200 OK мгновенно, а всю тяжёлую работу делаем в отдельном воркере. Это гарантирует, что мы уложимся в 10-секундный таймаут Verbox.

 

 

Шаг 3. Обработка и вызов LLM

 

Теперь воркер забирает задачу из очереди и идёт в LLM.

Как передать контекст:

LLM можно передать только последнее сообщение клиента. Но для качественных подсказок лучше передать историю диалога. Есть два способа:

  1. Запросить историю через API Verbox. Используйте метод /chat/message/getDialog, передав dialogId из webhook. В ответе result.messages будут все сообщения диалога.
  2. Хранить историю на своей стороне. Если вы уже сохраняете переписку, просто используйте её.
 

Пример запроса в LLM (псевдокод):

 
import openai

def get_suggestion(dialog_id, message_text, context_messages=None):
    prompt = f"""
    Ты — вежливый и компетентный оператор службы поддержки.
    Ответь клиенту кратко и по делу.
    
    Клиент: {message_text}
    """
    
    if context_messages:
        history = "\n".join([f"{m['whoSend']}: {m['text']}" for m in context_messages])
        prompt = f"История диалога:\n{history}\n\n{prompt}"
    
    response = openai.ChatCompletion.create(
        model="gpt-4",
        messages=[{"role": "user", "content": prompt}],
        max_tokens=200
    )
    
    return response.choices[0].message.content
 

Рекомендации:

  • Промпт на ваше усмотрение. Verbox не регламентирует стиль ответов. Хотите лаконично — пишите «отвечай одним предложением». Хотите развёрнуто — просите подробный ответ.
  • Ограничения по длине. Формально лимитов нет, но если подсказка идёт в Telegram, там ограничение около 1024 символов. Да и оператору неудобно читать «простыни». Оптимально — 1–3 предложения.
  • Обработка не-текстовых сообщений. Если клиент прислал картинку, в message.text будет ссылка. Вы можете либо проигнорировать такое сообщение, либо отправить в LLM текст ссылки (но это малоэффективно).
 

 

Шаг 4. Отправка подсказки оператору

 

Когда LLM вернула ответ, вызовите метод Verbox API:

POST https://admin.verbox.ru/json/v1.0/chat/message/setSuggestedAnswerToClient

 

Заголовки:

X-Token: ваш_api_токен
Content-Type: application/json
 

Тело запроса:

{
  "client": {
    "clientId": "sw9dzztkdbec7y8jvfzo9ixs4o6wfp5n"
  },
  "message": {
    "text": "Добрый день! Да, всё верно: заказ 480204 выкуплен, магазин Hyperice уже отправил товар."
  },
  "replyToMessageId": 123,
  "rate": {
    "likeUrl": "https://ваш-сервер.com/rate/like?messageId=123",
    "dislikeUrl": "https://ваш-сервер.com/rate/dislike?messageId=123",
    "isAutoLikeOnUsage": true,
    "autoLikeOnUsageSimilarityPercent": 90
  }
}
 

Разбор полей:

Поле Описание
client.clientId Идентификатор клиента из webhook
message.text Текст подсказки, который сгенерировала LLM
replyToMessageId ID сообщения клиента, на которое отвечаем. Если клиент написал два сообщения, а LLM думала долго — оператор поймёт, на какое именно сообщение дана подсказка
rate.likeUrl URL, который Verbox дёрнет, если оператор поставит лайк на подсказке. Если не указать — кнопка лайк не будет показана
rate.dislikeUrl URL, который Verbox дёрнет, если оператор поставит дизлайк на подсказке. Если не указать — кнопка дизлайк не будет показана
rate.isAutoLikeOnUsage Если true и есть likeUrl — Verbox автоматически вызовет likeUrl, когда оператор отправит подсказку без изменений (или с изменениями, но процент схожести по Левенштейну выше autoLikeOnUsageSimilarityPercent)
rate.autoLikeOnUsageSimilarityPercent Порог схожести (в процентах). По умолчанию 100
 

Важно: При вызове likeUrl и dislikeUrl Verbox не отправляет payload. Все нужные данные (ID подсказки, ID сообщения) вы должны «зашить» в саму ссылку.

 

Можно ли отправить несколько подсказок на одно сообщение?

Да. Количество не ограничено. Если ваша LLM сгенерировала три варианта — вызовите метод трижды. Оператор увидит все три подсказки в чате.

 

Что если оператор уже ответил?

Подсказка всё равно появится в истории чата, но будет отмечена как «не использованная». Это сделано специально: клиенты просили показывать, какие подсказки генерировала LLM, даже если оператор их не использовал.

 

 

Шаг 5. Как это выглядит у оператора

 

Подсказка отображается в чате как отдельное сообщение с заголовком «Подсказка» и пометкой «Видна только оператору».

 
 

Оператор может:

  • Отправить — текст подсказки уйдёт клиенту.
  • Изменить — текст скопируется в поле ввода, оператор отредактирует и отправит.
  • Проигнорировать — подсказка останется в истории как неиспользованная.
 

Если вы настроили likeUrl и dislikeUrl, появятся кнопки «палец вверх» и «палец вниз».

 
 

 

Шаг 6. Обратная связь и аналитика

 

Как работает лайк/дизлайк

 
  • Если оператор отправил подсказку без изменений и isAutoLikeOnUsage: true — Verbox автоматически вызовет likeUrl.
  • Если оператор изменил подсказку и процент схожести по Левенштейну ниже autoLikeOnUsageSimilarityPercent — ничего не отправляется. Дизлайки в авторежиме не отправляются.
  • Оператор может вручную поставить лайк или дизлайк — тогда Verbox вызовет соответствующий URL.
 

Встроенная аналитика

 

В личном кабинете Verbox есть готовый виджет «Подсказки для операторов» (в разделе «Отчёты → Сводка», группа AI). Он показывает количество использованных и неиспользованных подсказок.

 
 

Если нужно больше — используйте конструктор отчётов. Можно собрать отчёт, который покажет:

  • Количество использованных подсказок с процентом схожести > X.
  • Количество использованных подсказок с процентом схожести < X.
  • Диапазоны: 0–50%, 51–70%, 71%+.
 

 

Best practices и подводные камни

 
  1. Не идите в LLM синхронно. Примите webhook, ответьте 200 OK, обработайте асинхронно. Иначе не уложитесь в 10 секунд.
  2. Проверяйте секретный ключ. Verbox передаёт его в payload. Если ключ не совпадает — отклоняйте запрос.
  3. Не полагайтесь на повтор webhook. Verbox не повторяет запросы, если ваш сервер ответил ошибкой или не ответил. Дедупликация не обязательна, но если у вас несколько webhook на один URL — стоит подстраховаться.
  4. Учитывайте нестабильность связи. Если ваш сервер находится за рубежом, могут быть проблемы с доступностью из РФ. Размещайте сервер в РФ или используйте прокси.
  5. Rate limit. Verbox допускает 100 вызовов API в минуту. Если у вас много операторов и высокая нагрузка — предусмотрите очередь.
  6. Обработка ошибок LLM. Если LLM недоступна — можно ничего не отправлять или отправить комментарий от виртуального оператора через /chat/message/sendToOperator с message.type = "notification".
  7. Тестовый стенд. Отдельного стенда нет, но вы можете отсеивать запросы не от тестового пользователя на своей стороне.
 

 

Заключение

 

Собрать своего ИИ-суфлёра через API Verbox — задача для технического специалиста, но она вполне решаема. Ключевые моменты:

  • Настроить webhook на событие newMessageFromClient.
  • Принять данные, ответить 200 OK, обработать асинхронно.
  • Отправить текст в LLM, получить ответ.
  • Вызвать /chat/message/setSuggestedAnswerToClient, чтобы показать подсказку оператору.

В результате оператор получает готовый ответ, который можно отправить в один клик. Клиент получает быстрый и качественный сервис. Вы получаете контроль над логикой и промптами.

Если что-то осталось неясным — обратитесь в поддержку Verbox.

Антон (техподдержка)
Содержание
Архитектура решения
Шаг 1. Настройка Webhook
Шаг 2. Приём данных
Шаг 3. Обработка и вызов LLM
Шаг 4. Отправка подсказки оператору
Шаг 5. Как это выглядит у оператора
Шаг 6. Обратная связь и аналитика
Как работает лайк/дизлайк
Встроенная аналитика
Best practices и подводные камни
Заключение