API и разработка

LLM API на Python: первый запрос с контролем результата

Как подключить Python к LLM API: ключ в окружении, выбор модели, оценка, сохранённый запрос, обработка HTTP 202 и проверка подтверждённого ответа.

Редакция KvantoraТематический выпуск: Около 5 минут чтения
Обложка статьи «LLM API на Python: первый запрос с контролем результата»

Первый Python-клиент для LLM API должен уметь больше, чем печатать ответ: выбрать доступную модель, сохранить тело и идентификатор запроса, оценить расход и отличить завершённую работу от HTTP 202 или сетевого обрыва.

Подготовьте среду, не вшивая ключ

Для Kvantora документированный путь начинается с KVANTORA_API_KEY, KVANTORA_BASE_URL=https://api.kvantora.ai и публичного ID модели из /models. Ключ задавайте в окружении сервера или штатном хранилище секретов. Не пишите его в Python-файл, ноутбук, командную строку общего журнала или URL. Проверьте, что ключу разрешены нужные операции и задан бюджет.

До платного вызова скачиваемый quickstart.py позволяет запросить каталог и подготовить тело. Скрипт рассчитан на Python 3.10+ и не требует дополнительных пакетов. Смысл не в магии примера, а в последовательности: каталог подтверждает ID и операцию, prepare сохраняет неизменное тело и UUID, quote показывает оценку без вызова модели.

Рабочий пример с проверяемыми шагами

После установки переменных выполните команды по порядку. Первые три не запускают модель; send начинает платный вызов и требует отдельного решения о запуске. Для следующего логического запроса используйте другое имя файла. Не перезаписывайте старый файл, если по нему ещё не выяснен исход: вместе с UUID он задаёт личность операции.

Код ниже использует официальный скачиваемый пример Kvantora. Он полезен именно тем, что тело и ID сохраняются до отправки. В собственном приложении сделайте то же в своей базе или очереди. Одной переменной в памяти недостаточно, если процесс может перезапуститься после сетевого обрыва.

bash
python quickstart.py catalog
python quickstart.py prepare request.json
python quickstart.py quote request.json
# После разрешения платного теста:
python quickstart.py send request.json

Оценка не резервирует деньги

Команда quote обращается к POST /v1/chat/quote. Она получает оценку для подготовленного текстового запроса без резервирования и генерации. Смотрите оценённый расход и срок действия, но помните, что входные токены определяются приблизительно, а цена и доступность ещё будут проверены при отправке. Оценку нельзя использовать как окончательный финансовый результат.

В теле можно задать max_tokens и max_cost_microrub, а ключу: дневной бюджет. Это разные уровни защиты от неожиданного расхода. Длинный вход может не пройти лимит даже при коротком ожидаемом ответе. Для пользовательского продукта покажите человеку понятное сообщение, почему запрос не выполнен, вместо бесконечной автоматической попытки.

Сохранённый файл — прототип надёжного хранилища

Для одиночного скрипта файл запроса удобен: он переживает завершение процесса. В серверном приложении понадобится запись с владельцем, телом, UUID, состоянием и временем. Сохраняйте её до сетевой отправки в транзакции собственного хранилища. Если процесс падает после отправки, очередь восстановления найдёт исходную запись и не создаст вопрос заново. Это конкретная причина хранить идентификатор, а не формальность.

Не оставляйте в файле клиентский текст дольше необходимого и не отправляйте его в общий журнал ошибок. Если для расследования достаточно хеша тела, ID и статуса, логируйте именно их. Продумайте удаление старых подготовленных запросов отдельно от записей с неизвестным исходом: последние нельзя исчезать до выяснения состояния и корректного финансового учёта.

Результат и ошибочные состояния

После send клиентский результат помечается завершённым лишь тогда, когда пришёл объект chat.completion с billing.status=settled. Текст находится в ответе, но пустая строка сама по себе не говорит, был ли отказ, ожидание или ошибка разбора. Сохраните requestId и итоговый расход рядом с результатом. Это пригодится для поддержки и сверки истории запросов.

HTTP 202 означает, что окончательного результата пока нет. Не показывайте пользователю «готово» и не создавайте новый запрос. Если произошёл таймаут, запустите восстановление с тем же файлом и UUID по документированному механизму. У нового ID будет новая работа. Эта разница особенно важна для фоновых задач и очередей.

Ошибка авторизации требует проверить ключ и права. Неверный ID модели: каталог. Недостаточный бюджет: лимит и расчёт. Ни один из этих случаев не исправляется циклом повторов. При временной перегрузке смотрите код и рекомендацию сервиса; при неизвестном исходе сначала выясняйте состояние исходного запроса. Общая библиотека «retry всё» для платного вызова слишком груба.

Логи должны содержать безопасные технические признаки: внутренний ID операции, endpoint, HTTP-статус, тип ошибки и время. Не пишите в них ключ или полный клиентский документ. Сообщение сервера также может включать данные, которые не стоит возвращать пользователю. Отдельный человекочитаемый текст ошибки помогает поддержке не просить пользователя переслать секрет.

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

После первого ответа проверьте сценарий

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

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

Источники