Гайд · TNWS AI
Как запустить ручной smoke-тест AI API через GitHub Actions и секреты
Пошаговый ручной smoke-тест собственного AI API: секрет, workflow_dispatch, строгая проверка ответа и безопасное чтение лога.
Задача и границы применения
После обновления сервиса вручную проверить, что защищённый AI endpoint принимает запрос и возвращает ожидаемую схему. Нужен доверенный оператор и собственный тестовый endpoint https://example.invalid/api/classify, который возвращает JSON с ключами priority и summary. Адрес заглушки нужно заменить. В отличие от PR-проверки этот сценарий использует ключ; секрет не передают как параметр ручного запуска и не печатают в логе. Ниже — сценарий для собственного репозитория, а не обещание универсальной точности генеративной модели. Для демонстрации используются вымышленные обращения, которые не содержат персональных данных.
Актуальность названий полей, событий и версий actions проверена 19.09.2026 по официальным материалам GitHub. Если у вашего проекта другая структура каталогов или другой протокол AI API, адаптируйте пути и прикладной клиент после проверки его документации. Пример не содержит утверждений о тарифах, ценах или скорости.
Что подготовить до изменения workflow
Нужен репозиторий GitHub, доступ к его Actions и возможность добавить файл в каталог .github/workflows. Подготовьте тестовую ветку и одно синтетическое обращение с известным ожидаемым результатом. Не берите production-заявки: даже если runner временный, ввод и диагностика оказываются в истории запуска. Для Python-части используйте unittest из стандартной библиотеки; если в вашем проекте есть дополнительные импорты, установите их отдельно из контролируемого файла зависимостей.
До коммита запишите контракт: какие поля обязательно должны быть в результате, какие значения разрешены и при каком несоответствии job получает ненулевой код выхода. Сначала выполните тот же скрипт локально. Это позволяет различить ошибку Python от ошибки описания workflow. Если проверка обращается к внешней модели, разделите транспортную ошибку, отсутствие ключа и несоответствие ответа: эти причины требуют разного исправления.
Пошаговая настройка
- Создайте нужные каталоги и файлы из блоков ниже; имена путей в YAML должны совпадать с именами файлов в репозитории. Файл workflow хранится внутри
.github/workflows, а тестовый код — вtestsилиscriptsсогласно примеру. - Проверьте три секции YAML:
onзадаёт событие,permissionsограничивает встроенный токен,jobsсодержит runner и последовательность шагов. Не вставляйте ключи или закрытые тексты в YAML. - Создайте repository secret
AI_API_KEYв настройках Actions согласно официальному руководству, а URL измените на тестовый адрес собственного сервиса. Сохраните скрипт из блока ниже; заголовок Authorization должен соответствовать вашему API, поэтому его формат проверяется в документации вашего сервиса. Добавьте workflow в.github/workflows/ai-smoke.ymlв default branch. В разделе Actions выберитеAI API manual smoke, затемRun workflow. Если ключ не задан, скрипт прекращается до HTTP-запроса. Не вставляйте пользовательские персональные данные в пример и не добавляйтеprint(data): ответ может содержать чувствительный текст. - Сначала воспроизведите успешный вход, затем намеренно измените одно ожидаемое значение и убедитесь, что job падает. Проверка без негативного сценария не доказывает, что тест вообще способен обнаружить регрессию. После этого верните правильное значение и повторите запуск.
- При сбое откройте конкретный job и шаг, а не ориентируйтесь только на общий статус workflow. Проверьте событие запуска, выбранную ветку, наличие файлов, код завершения скрипта и последние безопасные диагностические сообщения.
Готовый шаблон workflow
Скопируйте YAML; если в блоке указаны два имени файла, разделите его на два соответствующих файла. Ссылки на внешние actions и параметры проверены по их официальным README на 19.09.2026.
name: AI API manual smoke
on:
workflow_dispatch:
permissions:
contents: read
jobs:
smoke:
runs-on: ubuntu-latest
env:
AI_API_KEY: ${{ secrets.AI_API_KEY }}
AI_API_URL: https://example.invalid/api/classify
steps:
- uses: actions/checkout@v7
- uses: actions/setup-python@v7
with:
python-version: '3.13'
- name: Check response contract
run: python scripts/smoke_ai.py
Код или тестовая фикстура для копирования
Этот блок даёт исходную контрольную точку. Встраивая его в приложение, заменяйте демонстрационный нормализатор на собственный импорт, сохраняя контракт и синтетические тестовые входы.
# scripts/smoke_ai.py
import json, os, urllib.request
url = os.environ["AI_API_URL"]
key = os.environ["AI_API_KEY"]
if not key:
raise SystemExit("AI_API_KEY is missing")
body = json.dumps({"text": "Срочно: платеж не прошёл"}).encode()
request = urllib.request.Request(url, body, {"Authorization": "Bearer " + key,
"Content-Type": "application/json"})
with urllib.request.urlopen(request, timeout=20) as response:
data = json.load(response)
assert data.get("priority") in {"high", "normal"}, "priority missing"
assert isinstance(data.get("summary"), str) and data["summary"], "summary missing"
print("Contract OK: priority and nonempty summary")
Реалистичный вход и ожидаемый результат
При тестовом ответе {"priority":"high","summary":"Платёж не прошёл"} ожидаем строку Contract OK: priority and nonempty summary. При ответе без summary job завершается ошибкой summary missing; отсутствие ключа даёт AI_API_KEY is missing без раскрытия значения. Перед тем как трактовать красный job как баг модели, убедитесь, что сравниваются значения одной и той же ревизии кода и одной и той же фикстуры. Не подменяйте ожидаемое значение фактически полученным: такое «исправление» отключит сигнал регрессии.
Разбор ошибок и ограничения
Если workflow не появляется в Actions, сперва проверьте расположение YAML и событие on; затем проверьте ограничения по путям и веткам. Если job есть, но падает на checkout или setup-python, отличайте инфраструктурную ошибку от провала прикладного утверждения. Если Python завершился с ошибкой импорта, проверьте реальные пути и зависимости. Если проблема только в содержании ответа, сохраните минимальный безопасный вход и точное различие ожидаемого и фактического полей.
В CI тестируется выбранный контракт, а не «качество ИИ вообще». Он не доказывает отсутствие галлюцинаций, безопасность всех возможных промптов или корректность каждой интеграции. Добавляйте отдельные фикстуры для отрицательных кейсов, пустого ввода, Unicode и граничных форматов, когда эти ситуации есть в вашем продукте. Для live API ограничивайте доступ к секрету и используйте отдельные тестовые данные. Не выводите заголовки Authorization, тело закрытого ответа или переменные окружения целиком.
Чек-лист перед слиянием
- Workflow лежит в
.github/workflows, а событие запуска соответствует задаче. - Скрипт работает локально на синтетическом входе и падает при намеренно нарушенном контракте.
- Имена файлов, переменные окружения и пути в YAML совпадают с репозиторием.
- Секреты не записаны в код, входные параметры, summary или диагностический файл.
- Проверен успешный запуск и понятный неуспешный запуск; просмотрен конкретный job.
- Код и тесты соответствуют ограничениям доверия для внешнего PR и правам токена.
- Результат относится к актуальному коммиту, а не к предыдущей ревизии.
FAQ
Почему кнопку Run workflow не видно?
Проверьте, что YAML с workflow_dispatch присутствует в default branch, и что у вас есть право запускать workflow.
Можно ли вставить ключ в inputs?
Нет: используйте Actions secrets; входные параметры предназначены для несекретной конфигурации и могут быть видны в истории запуска.
Почему не сравниваем текст дословно?
Smoke-тест проверяет доступность и минимальный контракт. Точное содержание проверяют отдельно на подготовленном наборе тестов.
Как понять ошибку HTTP?
Разделите сетевую недоступность, ошибку авторизации и несоответствие JSON: проверяйте URL, разрешения ключа и тело ответа в безопасной среде, не выводя ключ.
Как зафиксировать проверенный результат
После успешного запуска сохраните ссылку на конкретный run рядом с pull request: так ревьюер увидит проверенную ревизию. При следующем сбое сравнивайте не только цвет check, но и фикстуру, входные параметры, изменённые файлы и точный шаг ошибки. Если ослабили утверждение теста, объясните в PR, какой риск остался непокрытым, и добавьте отдельный сценарий. При переносе шаблона в другой репозиторий повторно проверьте структуру каталогов и разрешения: одинаковый YAML сам по себе не гарантирует одинаковую модель доверия. Не называйте демонстрационные результаты измерением качества или производительности AI-системы.
Официальные первоисточники
Проверено 19.09.2026. Описание синтаксиса и поведения: 1, 2, 3, 4. Читайте первоисточники при переносе шаблона в другой репозиторий: доступность версии action или поддерживаемый синтаксис могут измениться.
Читайте также
Как исключить bias из weight decay через Optax
Optax 0.2.6: маска add_decayed_weights применяет decay к kernel и оставляет bias без изменения.
Как использовать Huber loss в Optax для регрессии с выбросами
Optax 0.2.6: Huber loss квадратичен около нуля и линеен после delta; проверяем ошибки 0,5 и 2.
Как использовать sigmoid focal loss в Optax
Optax 0.2.6: focal loss для logits 0 и labels 0/1 при gamma=2; проверка симметричного базового значения.
Комментарии
Пока тихо. Скажите первое слово