
Webhooks в Gemini API: конец эпохи polling-запросов
Google запустила event-driven Webhooks в Gemini API — теперь долгие задачи сами уведомляют сервер о завершении, без бесконечных опросов.
Проблема, которую знает каждый разработчик AI-пайплайнов
Если вы когда-нибудь строили production-пайплайн на основе языковой модели с долгими задачами — будь то ночной батч из тысяч промптов, запуск агента Deep Research или генерация длинного видео — вы прекрасно знакомы с так называемой «проблемой polling».
Ваш код сидит в цикле и каждые несколько секунд шлёт GET-запросы с вопросом: «Задача уже готова?» Это расточительно, добавляет задержки и превращается в настоящую головную боль с точки зрения надёжности при масштабировании.
Polling — это как звонить другу каждые 10 минут с вопросом «ты уже приехал?», вместо того чтобы попросить его написать, когда будет у двери.
По мере того как Gemini движется в сторону агентных рабочих процессов и высоконагруженной обработки — например, Deep Research, генерации длинных видео или обработки тысяч промптов через Batch API — операции могут занимать минуты и даже часы. Polling на протяжении нескольких часов дорого обходится как по вычислительным ресурсам, так и по квоте API, а ещё вносит ненужные задержки между моментом завершения задачи и тем, когда ваше приложение об этом узнаёт.
Google решила эту проблему радикально.
Что такое Webhooks в Gemini API
Google представила event-driven Webhooks (событийно-управляемые вебхуки) — push-based систему уведомлений, которая полностью устраняет необходимость в неэффективном polling.
Теперь Gemini API может в режиме реального времени отправить HTTP POST-запрос на ваш сервер в тот момент, когда задача завершена. Никаких циклов, никакого непрерывного опроса — API сам «толкает» уведомление к вам.
Для команд, работающих с Deep Research, генерацией длинных видео или масштабным батч-инференсом, это обновление на уровне инфраструктуры. Это не новая модель и не новый параметр — это фундаментальное переосмысление того, как мы взаимодействуем с долгосрочными AI-задачами.
Как это работает: архитектура уведомлений
Схема принципиально проста: вместо того чтобы ваш код спрашивал «готово?» снова и снова, Gemini API сам сообщает вам о завершении.
sequenceDiagram
participant Dev as Разработчик
participant Gemini as Gemini API
participant Server as Ваш сервер
Dev->>Gemini: Запуск долгой задачи (Batch / Video / Deep Research)
Gemini-->>Dev: OK, получили task_id
Note over Gemini: Обрабатывает задачу...
Gemini->>Server: HTTP POST с результатом (мгновенно по завершении)
Server-->>Gemini: 200 OK
Server->>Dev: Уведомление готово!
Два режима настройки вебхуков
Gemini API поддерживает два способа настройки вебхуков:
- Static webhooks (статические): эндпоинты уровня проекта, настраиваемые через Gemini WebhookService API. Подходят для глобальных интеграций (например, уведомления в Slack, синхронизация базы данных).
- Dynamic webhooks (динамические): переопределения на уровне отдельных запросов — URL вебхука передаётся в конфигурационном payload конкретного вызова. Идеальны для маршрутизации отдельных задач на выделенные эндпоинты.
| Характеристика | Static Webhooks | Dynamic Webhooks |
|---|---|---|
| Уровень настройки | Весь проект | Отдельный запрос/задача |
| Механизм подписи | HMAC-SHA256 (симметричный) | RS256 JWT через JWKS (асимметричный) |
| Типичный сценарий | Slack-уведомления, логи, синхронизация БД | Маршрутизация задач по воркерам, мультиарендные пайплайны |
| Поддержка user_metadata | Нет | Да — для кастомной маршрутизации |
Такое разделение действительно полезно: статические вебхуки подходят для глобальных интеграций (Slack-нотификатор, логгер аудита), динамические — для маршрутизации конкретных задач на выделенные воркеры или fan-out очереди.
Безопасность: встроена, а не прикручена
Google уделила особое внимание безопасности реализации.
Gemini API теперь поддерживает спецификацию Standard Webhooks, используя заголовки webhook-signature, webhook-id и webhook-timestamp для обеспечения идемпотентности.
Защита от replay-атак:
Все запросы содержат заголовок webhook-timestamp. Всегда проверяйте его на стороне сервера, чтобы отклонять payload’ы старше 5 минут — это защищает от replay-атак.
Гарантии доставки: Ваш эндпоинт должен вернуть статус 2xx для подтверждения получения; всё остальное расценивается как ошибка, и запрос будет повторён с экспоненциальной выдержкой до 24 часов.
Дедупликация:
Заголовок webhook-id служит ключом идемпотентности — Google прямо указывает, что дубликаты могут возникать при перегрузке сети. Храните обработанные ID и не обрабатывайте одно событие дважды.
Ротация секретов:
Эндпоинт ротации поддерживает параметр revocation_behavior — в частности REVOKE_PREVIOUS_SECRETS_AFTER_H24, который сохраняет действие старого секрета в течение 24-часового периода для безопасной миграции production-систем, либо вариант немедленной отзыва для реагирования на инциденты.
Практический пример: динамический вебхук для батч-задачи
Вот как выглядит настройка динамического вебхука для батч-задачи через Python SDK:
import google.generativeai as genai
import os
# Инициализация клиента
client = genai.Client(api_key=os.environ["GEMINI_API_KEY"])
# Создание батч-задачи с динамическим вебхуком
response = client.batches.create(
model="gemini-2.0-flash",
src="gs://my-bucket/input_prompts.jsonl",
config={
"webhook_config": {
"uris": ["https://my-api.ru/gemini-webhook"],
"user_metadata": {
"job_group": "nightly-batch",
"priority": "high",
"tenant_id": "client_42"
}
}
}
)
print(f"Батч-задача запущена: {response.name}")
# Дальше просто ждём — Gemini сам пришлёт уведомление!
А вот минимальный обработчик вебхука на Flask:
from flask import Flask, request, jsonify
from standardwebhooks import Webhook
import os
app = Flask(__name__)
wh = Webhook(os.environ["WEBHOOK_SIGNING_SECRET"])
@app.route("/gemini-webhook", methods=["POST"])
def gemini_callback():
# Верификация подписи
payload = request.get_data(as_text=True)
headers = dict(request.headers)
try:
event = wh.verify(payload, headers)
except Exception:
return jsonify({"error": "Invalid signature"}), 401
# Обработка события
if event["type"] == "batch.succeeded":
output_uri = event["data"]["output_file_uri"]
print(f"✅ Батч завершён! Результаты: {output_uri}")
# Запускаем асинхронную обработку результатов...
# Обязательно отвечаем 2xx немедленно!
return jsonify({"status": "received"}), 200
if __name__ == "__main__":
app.run(port=8000)
Реальные сценарии применения
Вебхуки превращают Gemini из API в режиме запрос-ответ в нечто, способное управлять событийно-ориентированными архитектурами. Рассмотрим конкретные примеры:
🌙 Ночной батч-процессинг:
Ночная Batch-задача, обрабатывающая тысячи промптов, отправляет свой URI с результатами в ваш дата-пайплайн в момент завершения — вместо того чтобы вы опрашивали GET /operations каждые 30 секунд на протяжении часа.
🎬 Генерация видео: Вебхуки позволяют отправить задачу и сразу сообщить пользователю, что видео «генерируется», а затем уведомить его через вашу собственную push-систему (WebSocket, APNs, SSE), когда процесс действительно завершён.
🤖 Human-in-the-loop агенты:
Сессия Interactions приостанавливается на interaction.requires_action, запускает вебхук, который отправляет запрос на одобрение человеку в Slack, и возобновляется, когда тот принимает решение.
🚨 Обработка ошибок: Событие о сбое Batch-задачи уведомляет дежурного с указанием причины и запускает процедуру повтора — и всё это без написания polling-цикла с backoff.
Тонкие payload’ы: эффективная доставка без перегрузки
Отдельного внимания заслуживает дизайнерское решение Google в отношении содержимого уведомлений.
Чтобы избежать перегрузки канала, вебхуки Gemini используют модель «тонкого payload’а»: доставляется снимок со статусом и указателями на результаты, а не сам выходной файл.
Уведомления содержат указатели на статус, а не сами данные: для батч-событий возвращается output_file_uri, для видеособытий — file_id и video_uri.
Пример payload события batch.succeeded:
{
"type": "batch.succeeded",
"version": "v1",
"timestamp": "2026-05-15T03:00:00Z",
"data": {
"id": "batch_123456",
"output_file_uri": "gs://my-bucket/results.jsonl"
}
}
Тонкие payload’ы с указателями gs:// делают доставку компактной и позволяют Google передавать результаты Batch объёмом в несколько гигабайт, не раздувая тело вебхука.
Polling vs Webhooks: сравнение подходов
| Критерий | Polling (старый подход) | Event-driven Webhooks |
|---|---|---|
| Потребление ресурсов | Высокое (постоянные запросы) | Минимальное (только по событию) |
| Задержка уведомления | Зависит от интервала опроса | Мгновенно по завершении |
| Расход API-квоты | Значительный | Нулевой на этапе ожидания |
| Масштабируемость | Проблемы при росте числа задач | Линейное масштабирование |
| Сложность кода | Циклы, backoff, таймауты | Один эндпоинт-обработчик |
| Надёжность при сбоях | Ручное восстановление | Авторетраи до 24 часов |
Вебхуки Gemini API — это не просто «экономия нескольких строк polling-кода». Они фактически перекладывают ответственность за «оркестрацию задач» с клиентской стороны на серверную.
Лучшие практики при работе с Gemini Webhooks
Безопасность:
- Всегда верифицируйте подпись перед обработкой payload
- Отклоняйте события старше 5 минут (
webhook-timestamp) - Никогда не доверяйте неподписанным payload’ам
Производительность:
- Отвечайте
2xxнемедленно, обрабатывайте асинхронно - Не держите соединение открытым дольше нескольких секунд
Надёжность:
- Храните
webhook-idдля дедупликации - Отслеживайте обработанные webhook-id с TTL длиннее 24-часового окна повторных доставок.
- Не подписывайтесь скопом на все типы событий — это раздует объём обработки и вынудит фильтровать ненужные события прямо в обработчике.
Как начать работу
Функция доступна прямо сейчас для всех разработчиков Gemini API. Ознакомьтесь с документацией по Webhooks, чтобы изучить полный каталог событий и узнать, как защитить свои эндпоинты.
Для практического освоения Google подготовила подробный Cookbook, который поможет вам построить интеграцию с вебхуками от начала до конца.
Полезные ссылки:
- 📖 Официальная документация Gemini Webhooks
- 🍳 Gemini Cookbook на GitHub
- 📦 Библиотека standardwebhooks (Python/Node.js)