Автоматизация поддержки клиентов на Claude и GPT

Бот поддержки, который падает при отказе одной модели или сливает бюджет за ночь — это плохой бот. Разбираем, как собрать его правильно на API.

4 мин · · Обновлено · бизнес · поддержка

Бот поддержки в мессенджере или на сайте — это цикл «вопрос клиента → системный промпт с базой знаний → ответ». Отличие рабочего бота от макета для демо — в трёх вещах: что происходит, если модель недоступна, кто и сколько может потратить, и откуда бот берёт актуальную информацию, если её нет в промпте.

Базовый запрос

Для чат-бота удобнее OpenAI-совместимый режим — большинство фреймворков ботов уже умеют в этот формат:

bash
curl https://api.zukko.pro/v1/chat/completions \
  -H "Authorization: Bearer fetch_ваш_ключ" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-sonnet-5",
    "messages": [
      {"role": "system", "content": "Ты оператор поддержки интернет-магазина. Отвечай по базе знаний ниже, если ответа нет — предлагай написать в чат живому оператору."},
      {"role": "user", "content": "Где мой заказ 48213?"}
    ]
  }'

claude-sonnet-5 здесь — рабочая лошадка: вменяемая цена, контекст 1,000,000 токенов с запасом на длинную базу знаний в системном промпте, vision на случай, если клиент присылает скриншот ошибки.

Фоллбэк между провайдерами

У поддержки нет права на простой — если модель недоступна ночью, а живых операторов нет, бот должен продолжать отвечать. Каталог моделей у шлюза включает и Anthropic-совместимые, и OpenAI-совместимые модели одновременно, так что фоллбэк можно строить между семействами, а не внутри одного:

bash
import requests

MODELS = ["claude-sonnet-5", "gpt-5.6-sol", "glm-5.3"]

def ask_support(question, kb):
    for model in MODELS:
        resp = requests.post(
            "https://api.zukko.pro/v1/chat/completions",
            headers={"Authorization": "Bearer fetch_ваш_ключ"},
            json={"model": model, "messages": [
                {"role": "system", "content": kb},
                {"role": "user", "content": question},
            ]},
        )
        if resp.status_code == 503:
            continue
        return resp.json()
    raise RuntimeError("Все модели фоллбэка недоступны")

503 provider_unavailable или model_disabled — сигнал переключиться на следующую модель в списке, а не показывать клиенту ошибку.

Идемпотентность на стороне мессенджера

Telegram, WhatsApp Business API и подобные платформы иногда доставляют одно и то же сообщение от пользователя дважды при нестабильном соединении. Без защиты бот дважды сходит в модель и дважды спишет деньги за один вопрос клиента. Idempotency-Key, построенный из ID сообщения платформы, закрывает это:

bash
curl https://api.zukko.pro/v1/chat/completions \
  -H "Authorization: Bearer fetch_ваш_ключ" \
  -H "Idempotency-Key: tg-update-$UPDATE_ID" \
  -H "Content-Type: application/json" \
  -d @payload.json

Ограничение прав операторских ключей

Если ботом пользуются несколько отделов (например, поддержка продаж и поддержка технических вопросов), у каждого должен быть свой ключ с собственным списком разрешённых моделей — настраивается в кабинете на странице ключа. Это защищает от ситуации, когда оператор техподдержки случайно (или намеренно) переключает бота на самую дорогую модель для рутинных вопросов. Если ключ пытается вызвать модель не из своего списка, сервер вернёт:

bash
{"error": {"message": "Model not allowed for this key", "code": "model_not_allowed_for_key"}}

Дневной или месячный лимит расхода в долларах на том же ключе страхует от аномального трафика — например, если бот попал в спам-рассылку и получил тысячи одинаковых сообщений за час.

Веб-поиск для вопросов вне базы знаний

Системный промпт с базой знаний хорош для типовых вопросов, но не покрывает всё — например, вопросы про текущий статус доставки у стороннего перевозчика или актуальные новости компании. Для моделей без встроенного поиска в шлюзе есть отдельный эндпоинт:

bash
curl https://api.zukko.pro/v1/web-search \
  -H "Authorization: Bearer fetch_ваш_ключ" \
  -H "Content-Type: application/json" \
  -d '{"query": "статус доставки СДЭК Москва задержки сентябрь 2026"}'

Результат можно подмешать в контекст следующего запроса к модели как дополнительный system-блок, вместо того чтобы модель галлюцинировала ответ по вопросу, которого нет в базе знаний.

Мониторинг стоимости диалога

Каждый обычный (не потоковый) ответ содержит заголовки X-Zukko-Cost-Micros (цена конкретного вызова в микродолларах) и X-Fetch-Balance-Cents (остаток баланса — несмотря на название, тоже в микродолларах, 1 000 000 = $1); у ответов с stream: true этих заголовков нет. Логируя первый по каждому диалогу, легко посчитать среднюю стоимость обращения в поддержку и сравнить её с зарплатой оператора на аналогичный объём. GET /v1/balance полезен для дашборда с текущим остатком без похода в кабинет:

bash
curl https://api.zukko.pro/v1/balance -H "Authorization: Bearer fetch_ваш_ключ"

Реферальная схема для агентств поддержки

Если поддержку строит агентство для нескольких клиентов на разных ключах, у каждого клиента можно завести отдельный ключ под своим аккаунтом, а агентство получает 10% с пополнений приглашённых по реферальной программе — удобно для модели, где агентство выставляет клиенту счёт за инфраструктуру отдельно от разработки.

Частые ошибки в проде

401 с сообщением про неверный ключ обычно значит, что ключ отозвали или создали новый, не обновив переменную окружения бота. 402 — баланс пуст, и это стоит ловить заранее через /v1/balance в фоновой проверке раз в час, а не ждать первого отказа живому клиенту. Обрыв ответа на середине почти всегда означает, что таймаут HTTP-клиента бота меньше, чем время генерации длинного ответа — для развёрнутых объяснений стоит поднимать таймаут до 30-60 секунд, а не резать соединение через 10.

Итог: несколько моделей в фоллбэке, отдельные ключи с лимитами по отделам, Idempotency-Key на ID сообщения платформы и веб-поиск для вопросов вне базы знаний — с этим бот поддержки держит нагрузку без простоев и без сюрпризов в счёте.

zukko

Платите в 25×
меньше

за Claude Code & ChatGPT

Один ключ fetch_* и base URL api.zukko.pro — в Cursor, Claude Code, Codex и любом SDK.