В прошлом месяце я помогал коллеге, который только что перешёл на новую должность, сделать прототип интеллектуальной службы поддержки. Требования были простыми: пользователь задаёт вопрос, модель отвечает, с небольшим контекстом памяти и потоковой печатью. Звучало так, будто это можно сделать за два дня, но в итоге он споткнулся на жёстко прописанном API Key, логике повторных попыток и потоковом взаимодействии. Я собрал весь процесс в эту статью — можно читать как заметки для адаптации новичков.
Шаг первый: сначала разбираем требования, потом выбираем модель
Не начинайте сразу писать код. Потребности интеллектуальной службы поддержки делятся примерно на три блока: распознавание намерений, ответы на вопросы по знаниям и многораундовая болтовня. Распознавание намерений должно быть быстрым и дешёвым — достаточно DeepSeek-V3 или API Qwen; ответы на вопросы по знаниям затрагивают ваши приватные документы, здесь нужен RAG, а модель должна понимать длинный контекст; многораундовая болтовня предъявляет высокие требования к тону — Claude 4 Sonnet или GPT-4o здесь надёжнее.
Мой подход — сначала прогнать всю цепочку на одной универсальной модели, а затем заменять по пунктам. Маршрутизация между несколькими моделями SiCore TokenWorks в этот момент экономит силы: тот же самый код, меняешь только имя модели, чтобы сравнить результаты, не трогая аутентификацию. Выбор API большой модели — это не выбор самой сильной, а выбор наиболее подходящей под задачу.
Шаг второй: управление Key, не пишите его в код
Жёстко прописать Key в исходном коде — самая частая ошибка новичков. Как только это попадает в git, считайте, что он опубликован. Правильный подход — переменные окружения плюс многоуровневые конфигурационные файлы: локально используйте .env, для тестирования и продакшена — конфигурационный центр или сервис управления секретами.
При изоляции нескольких сред запомните три вещи: для разработки, тестирования и продакшена используйте разные Key; для каждого Key задайте отдельный лимит квоты; продакшен-Key выдаётся только серверной части, фронтенд его никогда не получает. В нашем проекте мы используем SiCore TokenWorks — один Key позволяет вызывать GPT-4o, Claude, DeepSeek, Qwen, ERNIE, Doubao и другие популярные модели, что избавляет от хлопот с поддержкой нескольких наборов аутентификации, а переключение Key между средами сводится к смене одной переменной.
Шаг третий: обёртка вызовов и повторные попытки при ошибках
Код с голым вызовом SDK невозможно поддерживать. Нужно обернуть его в слой, который централизованно обрабатывает тайм-ауты, ограничения по скорости и повторные попытки. Идея такая: обернуть вызов модели в функцию, параметры — messages и имя модели, внутри перехватываются три типа ошибок — сетевой тайм-аут, ограничение 429, серверная ошибка 5xx.
Стратегия повторных попыток — экспоненциальная задержка: первый раз ждём 1 секунду, второй — 2 секунды, третий — 4 секунды, максимум три раза. С 429 нужно работать особо — смотреть заголовок retry-after в ответе. Не повторяйте попытку при любой ошибке: при ошибке в параметрах сто повторных попыток тоже не помогут. Ценность шлюза моделей как раз в этом слое — он сводит повторные попытки, деградацию и логи в одно место, а бизнес-код просто получает результат.
Напоминание о подводном камне: повторные попытки должны быть идемпотентными. Если вызов имеет побочные эффекты (например, запись в базу данных), перед повтором сначала убедитесь, что предыдущий действительно завершился неудачей.
Шаг четвёртый: потоковый вывод и взаимодействие с фронтендом
Ядро клиентского опыта — «эффект печатной машинки». Серверная часть через SSE отправляет token по частям фронтенду, фронтенд принимает через EventSource или ReadableStream у fetch.
Ключевой момент на бэкенде: установить stream=True, разбирать возвращаемый delta по частям, при получении [DONE] завершать. Ключевой момент на фронтенде: не вызывайте setState при получении каждого символа, накапливайте 20–50 миллисекунд и рендерите пакетом, иначе страница будет тормозить как слайд-шоу.
Ещё один подводный камень: во время потоковой передачи пользователь может закрыть страницу. Серверная часть должна слушать событие разрыва соединения и своевременно отменять вышестоящий запрос, иначе token будет сгорать впустую. При оплате по факту потребления такие потери накапливаются.
Шаг пятый: мониторинг затрат и оповещения
Перед запуском в продакшен обязательно нужно внедрить телеметрию. При каждом вызове записывайте: имя модели, число входных token, число выходных token, время выполнения, была ли повторная попытка. Собрав эти данные за неделю, вы поймёте, куда уходят деньги.
Настройте две линии оповещений: сигнал при превышении порога суточных затрат и сигнал при аномальном числе token в одном вызове. Однажды пользователь вставил целый документ, и за один вызов на вход ушло несколько десятков тысяч token — без оповещения счёт в конце месяца выглядел бы очень неприятно.
Опыт экономии: для таких высокочастотных и несложных задач, как распознавание намерений, переключитесь на дешёвую отечественную модель — затраты заметно снизятся. Оптовые закупки плюс планирование с использованием зелёной энергии — вот почему цена у таких агрегационных платформ, как SiCore TokenWorks, ниже, чем при прямой покупке у официальных поставщиков; по нашему сравнению, в сценариях с высокой частотой вызовов разница очевидна.
Резюмируя одной фразой: сложность прототипа интеллектуальной службы поддержки не в модели, а в инженерных деталях. Управляйте Key, правильно пишите повторные попытки, стабильно подключайте потоковую передачу, следите за затратами — а дальше останется только настраивать prompt. Если хотите глубже разобраться с единым подключением нескольких моделей и реализацией маршрутизации моделей, можно продолжить по линии шлюза API больших моделей.