Создание агента на OpenAI Agents SDK со стримингом ответа через веб-сокеты на Yandex Cloud Functions и API Gateway
Важно
Часть ресурсов, необходимых для прохождения практического руководства, доступны только в регионе Россия.
В этом руководстве вы создадите агент со стримингом ответа через веб-сокеты
Когда агент обрабатывает сложные запросы, ему может потребоваться продолжительное время на ответ. Например, при генерации больших текстов с рассуждениями, поиске и индексации. В таких случаях важно видеть прогресс и получать частичные результаты по мере готовности. Стриминг ответа позволяет сразу выводить токены или фразы, промежуточные сообщения и статусы шагов, отображать логи, а затем — финальный ответ, не дожидаясь завершения всего сценария. Это повышает воспринимаемую скорость, обеспечивает более интерактивный UI/UX, дает возможность отмены, повтора и динамического обновления интерфейса. Стриминг поддерживается большинством фреймворков. В OpenAI Agents SDK также предусмотрен стриминг
Чтобы создать агент:
- Подготовьте облако к работе.
- Настройте окружение.
- Подготовьте файлы проекта.
- Создайте сервисный аккаунт.
- Создайте API-ключ.
- Создайте секрет для API-ключа.
- Создайте функцию.
- Создайте API-шлюз.
- Проверьте результат.
Если созданные ресурсы вам больше не нужны, удалите их.
Совет
Если вы не хотите привязывать AI-агент к вендору, разверните функцию в Yandex Serverless Containers, как описано в руководстве Разработка функций в Functions Framework и их развертывание в Yandex Serverless Containers.
Что такое AI-агент и зачем он нужен
AI-агент — это программный помощник на базе искусственного интеллекта, который может выполнять инструкции, отвечать на вопросы и взаимодействовать с пользователями или другими системами в заданном контексте. В отличие от обычных моделей генеративного искусственного интеллекта, AI-агенты могут:
- обладать персонализированными инструкциями и «личностью»;
- использовать внешние источники информации и сторонние инструменты, позволяющие получить дополнительную информацию;
- поддерживать контекст диалога;
- выполнять последовательности действий для решения комплексных задач.
Почему бессерверные функции подходят для работы с AI-агентами
Функции Cloud Functions при развертывании AI-агентов предоставляют несколько преимуществ:
- Масштабируемость — автоматическое масштабирование в зависимости от нагрузки.
- Экономичность — плата только за фактическое время выполнения.
- Отсутствие необходимости управлять инфраструктурой — не нужно настраивать и поддерживать серверы.
- Быстрое развертывание — простота создания и обновления AI-агента.
- Интеграция с другими сервисами — простота подключения к API и другим сервисам Yandex Cloud.
Подготовьте облако к работе
Зарегистрируйтесь в Yandex Cloud и создайте платежный аккаунт:
- Перейдите в консоль управления
, затем войдите в Yandex Cloud или зарегистрируйтесь. - На странице Yandex Cloud Billing
убедитесь, что у вас подключен платежный аккаунт, и он находится в статусеACTIVEилиTRIAL_ACTIVE. Если платежного аккаунта нет, создайте его и привяжите к нему облако.
Если у вас есть активный платежный аккаунт, вы можете создать или выбрать каталог, в котором будет работать ваша инфраструктура, на странице облака
Подробнее об облаках и каталогах.
Необходимые платные ресурсы
В стоимость поддержки инфраструктуры для этого практического руководства входят:
- Плата за количество запросов к API-шлюзу и исходящий трафик (см. тарифы API Gateway).
- Плата за генерацию текста (см. тарифы Yandex AI Studio).
- Плата за количество вызовов функции, вычислительные ресурсы, выделенные для выполнения функции, и исходящий трафик (см. тарифы Cloud Functions).
- Плата за хранение секрета и операции с ним (см. тарифы Yandex Lockbox).
- Плата за получение и хранение логов (см. тарифы Yandex Cloud Logging).
Настройте окружение
-
Установите утилиту jq
для работы с JSON :LinuxmacOSapt-get install jqbrew install jq -
Установите утилиту wscat
для проверки работы агента:npm install -g wscat
Подготовьте файлы проекта
Для выполнения руководства вам понадобятся файлы с кодом функции и спецификация API-шлюза.
Склонируйте репозиторий:
git clone https://github.com/yandex-cloud-examples/yc-serverless-streaming-openai-agent
В репозитории вы увидите:
- архив
function.zipс кодом функцииfunction.pyи описанием зависимостейrequirements.txt; - спецификацию API-шлюза
gateway-spec.yaml.
-
Создайте папку
yc-serverless-streaming-openai-agentи перейдите в нее. -
Создайте файл
function.pyи вставьте в него код:import asyncio import json import os import random from typing import Dict, Any from agents import Agent, OpenAIProvider, Runner, RunConfig, function_tool, set_tracing_disabled from openai import AsyncOpenAI from openai.types.responses import ResponseTextDeltaEvent from yandex.cloud.serverless.apigateway.websocket.v1.connection_service_pb2 import SendToConnectionRequest from yandex.cloud.serverless.apigateway.websocket.v1.connection_service_pb2_grpc import ConnectionServiceStub from yandexcloud import SDK BASE_URL = os.getenv("BASE_URL") API_KEY = os.getenv("API_KEY") MODEL_NAME = os.getenv("MODEL_NAME") FOLDER_ID = os.environ.get('FOLDER_ID') client = AsyncOpenAI(base_url=BASE_URL, api_key=API_KEY) set_tracing_disabled(disabled=True) @function_tool def how_many_jokes() -> int: return random.randint(1, 10) # Инициализация SDK Yandex Cloud sdk = SDK() def get_websocket_service(): return sdk.client(ConnectionServiceStub) def stream_to_websocket(connection_id: str, message: str): """Отправка сообщения в WebSocket соединение""" websocket_service = get_websocket_service() request = SendToConnectionRequest( connection_id=connection_id, type=SendToConnectionRequest.TEXT, data=message.encode('utf-8') ) websocket_service.Send(request) async def process_stream(agent: Agent, run_config: RunConfig, connection_id: str, input_text: str): """Обработка стрима от агента и отправка в WebSocket""" result = Runner.run_streamed( agent, input=input_text, run_config=run_config ) print("=== Run starting ===") async for event in result.stream_events(): if event.type == "raw_response_event" and isinstance(event.data, ResponseTextDeltaEvent): stream_to_websocket(connection_id, event.data.delta) print("=== Run complete ===") def handler(event: Dict[str, Any], context): """Основной обработчик Cloud Function""" try: # Получаем параметры из события input_text = event['body'] request_context = event.get('requestContext') connection_id = request_context.get('connectionId') if not connection_id or not input_text: return { 'statusCode': 400, 'body': json.dumps({'error': 'Missing required parameters'}) } # Создаем агента agent = Agent( name="Joker", instructions="First call the `how_many_jokes` tool, then tell that many jokes about topic from input.", tools=[how_many_jokes], model=f"gpt://{FOLDER_ID}/yandexgpt/latest", ) run_config = RunConfig( model_provider=OpenAIProvider( api_key=API_KEY, project=FOLDER_ID, base_url="https://rest-assistant.api.cloud.yandex.net/v1", use_responses=True ) ) # Запускаем асинхронную обработку asyncio.run(process_stream(agent, run_config, connection_id, input_text)) return { 'statusCode': 200 } except Exception as e: return { 'statusCode': 500, 'body': json.dumps({'error': str(e)}) } -
Создайте файл
requirements.txtи вставьте в него код:openai-agents>=0.0.17 yandexcloud>=0.227.0 grpcio>=1.60.0 protobuf>=4.25.1 openai~=1.86.0 -
Создайте архив
function.zipи добавьте в него файлыfunction.pyиrequirements.txt. -
Создайте файл
gateway-spec.yamlи вставьте в него код:openapi: 3.0.0 info: title: Sample API version: 1.0.0 paths: /: x-yc-apigateway-websocket-message: x-yc-apigateway-integration: payload_format_version: '0.1' function_id: <идентификатор_функции> tag: $latest type: cloud_functions service_account_id: <идентификатор_сервисного_аккаунта>После создания сервисного аккаунта и функции потребуется указать их идентификаторы.
Создайте сервисный аккаунт
С помощью сервисного аккаунта функция получит доступ к секрету и YandexGPT, а API-шлюз получит доступ к функции.
-
В консоли управления
выберите каталог, в котором вы будете создавать инфраструктуру. -
В списке сервисов выберите Identity and Access Management.
-
Нажмите Создать сервисный аккаунт.
-
Введите имя сервисного аккаунта:
agent-streamer-sa. -
Нажмите
Добавить роль и выберите роли:serverless.functions.invokerlockbox.payloadViewerapi-gateway.websocketWriterai.languageModels.user
-
Нажмите Создать.
Если у вас еще нет интерфейса командной строки Yandex Cloud (CLI), установите и инициализируйте его.
По умолчанию используется каталог, указанный при создании профиля CLI. Чтобы изменить каталог по умолчанию, используйте команду yc config set folder-id <идентификатор_каталога>. Также для любой команды вы можете указать другой каталог с помощью параметров --folder-name или --folder-id.
-
Создайте сервисный аккаунт:
yc iam service-account create --name agent-streamer-saРезультат:
id: ajehqs5gee2e******** folder_id: b1g681qpemb4******** created_at: "2025-07-12T17:53:28.180991864Z" name: agent-streamer-sa -
Назначьте роли сервисному аккаунту:
yc resource-manager folder add-access-binding <имя_или_идентификатор_каталога> \ --role serverless.functions.invoker \ --subject serviceAccount:<идентификатор_сервисного_аккаунта> yc resource-manager folder add-access-binding <имя_или_идентификатор_каталога> \ --role lockbox.payloadViewer \ --subject serviceAccount:<идентификатор_сервисного_аккаунта> yc resource-manager folder add-access-binding <имя_или_идентификатор_каталога> \ --role api-gateway.websocketWriter \ --subject serviceAccount:<идентификатор_сервисного_аккаунта> yc resource-manager folder add-access-binding <имя_или_идентификатор_каталога> \ --role ai.languageModels.user \ --subject serviceAccount:<идентификатор_сервисного_аккаунта>Результат:
effective_deltas: - action: ADD access_binding: role_id: serverless.functions.invoker subject: id: ajehqs5gee2e******** type: serviceAccount effective_deltas: - action: ADD access_binding: role_id: lockbox.payloadViewer subject: id: ajehqs5gee2e******** type: serviceAccount effective_deltas: - action: ADD access_binding: role_id: api-gateway.websocketWriter subject: id: ajehqs5gee2e******** type: serviceAccount effective_deltas: - action: ADD access_binding: role_id: ai.languageModels.user subject: id: ajehqs5gee2e******** type: serviceAccount
Чтобы создать сервисный аккаунт, воспользуйтесь методом REST API create для ресурса ServiceAccount или вызовом gRPC API ServiceAccountService/Create.
Чтобы назначить сервисному аккаунту роли serverless.functions.invoker, lockbox.payloadViewer, api-gateway.websocketWriter и ai.languageModels.user на каталог, воспользуйтесь методом REST API updateAccessBindings для ресурса Folder или вызовом gRPC API FolderService/UpdateAccessBindings.
Создайте API-ключ
С помощью API-ключа функция получит доступ к YandexGPT.
-
В консоли управления
выберите сервис Identity and Access Management -
Выберите созданный ранее сервисный аккаунт
agent-streamer-sa. -
На панели сверху нажмите
Создать новый ключ и выберите Создать API-ключ. -
В поле Область действия выберите область действия
yc.ai.languageModels.execute. -
Нажмите Создать.
-
Сохраните полученный идентификатор и секретный ключ — они понадобятся при создании функции.
Внимание
После закрытия диалога значение ключа будет недоступно.
По умолчанию используется каталог, указанный при создании профиля CLI. Чтобы изменить каталог по умолчанию, используйте команду yc config set folder-id <идентификатор_каталога>. Также для любой команды вы можете указать другой каталог с помощью параметров --folder-name или --folder-id.
Выполните команду:
yc iam api-key create \
--service-account-id <идентификатор_сервисного_аккаунта> \
--scopes yc.ai.languageModels.execute
Где:
--service-account-id— идентификатор сервисного аккаунтаagent-streamer-sa.--scopes— области действия ключа.
Результат:
api_key:
id: aje3dkdmq2qn********
service_account_id: ajehqs5gee2e********
created_at: "2025-07-12T18:00:46.418035313Z"
scope: yc.ai.languageModels.execute
scopes:
- yc.ai.languageModels.execute
secret: AQVNw20bbQtXhfpblT04zJs8Z1wUT5rD********
Сохраните значение поля secret.
Чтобы создать API-ключ, воспользуйтесь методом REST API create для ресурса ApiKey или вызовом gRPC API ApiKeyService/Create.
Создайте секрет Yandex Lockbox
В секрете Yandex Lockbox будет храниться секретный ключ.
- В консоли управления
выберите сервис Lockbox. - Нажмите Создать секрет.
- В поле Имя введите имя секрета:
api-key-secret. - В поле Тип секрета выберите
Пользовательский. - В поле Ключ введите
api-key. - В поле Значение вставьте полученный на предыдущем шаге секретный ключ.
- Нажмите Создать.
По умолчанию используется каталог, указанный при создании профиля CLI. Чтобы изменить каталог по умолчанию, используйте команду yc config set folder-id <идентификатор_каталога>. Также для любой команды вы можете указать другой каталог с помощью параметров --folder-name или --folder-id.
Выполните команду:
yc lockbox secret create \
--name api-key-secret \
--payload "[{'key': 'api-key', 'text_value': '<секретный_ключ>'}]"
Где text_value — секретный ключ API-ключа, полученный на предыдущем шаге.
Результат:
id: e6q0rdjdggjp********
folder_id: b1g681qpemb4********
created_at: "2025-07-12T18:23:49.844Z"
name: api-key-secret
status: ACTIVE
current_version:
id: e6qbp772i014********
secret_id: e6q0rdjdggjp********
created_at: "2025-07-12T18:23:49.844Z"
status: ACTIVE
payload_entry_keys:
- api-key
Чтобы создать секрет, воспользуйтесь методом REST API create для ресурса Secret или вызовом gRPC API SecretService/Create.
Создайте функцию
Функция будет создана на основании архива с кодом и описанием зависимостей.
-
В консоли управления
выберите сервис Cloud Functions. -
Создайте функцию:
- Нажмите Создать функцию.
- В открывшемся окне введите имя функции:
agent-streamer. - Нажмите Создать.
-
Создайте версию функции:
-
Выберите среду выполнения
Python 3.12, отключите опцию Добавить файлы с примерами кода и нажмите Продолжить. -
В поле Способ выберите
ZIP-архиви прикрепите созданный ранее архивfunction.zip. -
Укажите точку входа
function.handler. -
В блоке Параметры укажите:
-
Таймаут —
30 секунд. -
Память —
512 МБ. -
Сервисный аккаунт — выберите сервисный аккаунт
agent-streamer-sa. -
Переменные окружения:
-
BASE_URL— URL сервиса Yandex AI Studio:https://llm.api.cloud.yandex.net/v1. -
MODEL_NAME— URI модели генерации текста Yandex AI Studio.Например:
gpt://<идентификатор_каталога>/yandexgpt/latest, где<идентификатор_каталога>— идентификатор каталога, в котором вы создаете инфраструктуру. -
FOLDER_ID— идентификатор каталога, в котором вы создаете инфраструктуру.
-
-
Секреты Lockbox:
- В поле Переменная окружения укажите
API_KEYи выберите созданный ранее секретapi-key-secret, его версию и ключapi-key.
- В поле Переменная окружения укажите
-
Если вы не хотите сохранять логи и платить за использование сервиса Cloud Logging, отключите опцию Запись логов.
-
-
Нажмите Сохранить изменения.
-
По умолчанию используется каталог, указанный при создании профиля CLI. Чтобы изменить каталог по умолчанию, используйте команду yc config set folder-id <идентификатор_каталога>. Также для любой команды вы можете указать другой каталог с помощью параметров --folder-name или --folder-id.
-
Создайте функцию:
yc serverless function create --name agent-streamerРезультат:
id: d4eem33cun2k******** folder_id: b1g681qpemb4******** created_at: "2025-07-12T18:15:59.854Z" name: agent-streamer http_invoke_url: https://functions.yandexcloud.net/d4eem33cun2k******** status: ACTIVE -
Создайте версию функции:
yc serverless function version create \ --function-name agent-streamer \ --runtime python312 \ --entrypoint function.handler \ --memory 512m \ --execution-timeout 30s \ --source-path <путь_к_архиву> \ --service-account-id <идентификатор_сервисного_аккаунта> \ --environment BASE_URL=https://llm.api.cloud.yandex.net/v1 \ --environment MODEL_NAME=gpt://<идентификатор_каталога>/yandexgpt/latest \ --environment FOLDER_ID=<идентификатор_каталога> \ --secret name=api-key-secret,key=api-key,environment-variable=API_KEYГде:
-
--source-path— путь к архивуfunction.zip. -
--service-account-id— идентификатор сервисного аккаунтаagent-streamer-sa. -
--environment— переменные окружения:-
BASE_URL— URL сервиса Yandex AI Studio:https://llm.api.cloud.yandex.net/v1. -
MODEL_NAME— URI модели генерации текста Yandex AI Studio.Например:
gpt://<идентификатор_каталога>/yandexgpt/latest, где<идентификатор_каталога>— идентификатор каталога, в котором вы создаете инфраструктуру. -
FOLDER_ID— идентификатор каталога, в котором вы создаете инфраструктуру.
-
-
--secret— секретapi-key-secret.
Результат:
id: d4e6d89oi342******** function_id: d4eem33cun2k******** created_at: "2025-07-12T18:27:29.887Z" runtime: python312 entrypoint: function.handler resources: memory: "536870912" execution_timeout: 30s service_account_id: ajehqs5gee2e******** image_size: "59891712" status: ACTIVE tags: - $latest environment: BASE_URL: https://llm.api.cloud.yandex.net/foundationModels/v1 FOLDER_ID: b1g681qpemb4******** MODEL_NAME: gpt://b1g681qpemb4********/yandexgpt/latest secrets: - id: e6q0rdjdggjp******** version_id: e6qbp772i014******** key: api-key environment_variable: API_KEY log_options: folder_id: b1g681qpemb4******** concurrency: "1" -
Чтобы создать функцию, воспользуйтесь методом REST API create для ресурса Function или вызовом gRPC API FunctionService/Create.
Чтобы создать версию функции, воспользуйтесь методом REST API createVersion для ресурса Function или вызовом gRPC API FunctionService/CreateVersion.
Создайте API-шлюз
Создайте API-шлюз для доступа к функции.
-
Откройте файл
gateway-spec.yamlи укажите в нем данные:function_id— идентификатор функцииagent-streamer;service_account_id— идентификатор сервисного аккаунтаagent-streamer-sa.
-
Создайте API-шлюз:
Консоль управленияYandex Cloud CLIAPI- В консоли управления
выберите сервис API Gateway. - Нажмите Создать API-шлюз.
- В поле Имя введите имя API-шлюза:
agent-streamer-gateway. - В блок Спецификация вставьте содержимое файла
gateway-spec.yaml. - Если вы не хотите сохранять логи и платить за использование сервиса Cloud Logging, отключите опцию Запись логов.
- Нажмите Создать.
- Выберите созданный API-шлюз. Сохраните значение поля Служебный домен для WebSocket — оно потребуется на следующем шаге.
По умолчанию используется каталог, указанный при создании профиля CLI. Чтобы изменить каталог по умолчанию, используйте команду
yc config set folder-id <идентификатор_каталога>. Также для любой команды вы можете указать другой каталог с помощью параметров--folder-nameили--folder-id.Выполните команду:
yc serverless api-gateway create \ --name agent-streamer-gateway \ --spec <путь_к_спецификации>Где
--spec— путь к файлуgateway-spec.yaml.Результат:
id: d5dgs4pn5iil******** folder_id: b1g681qpemb4******** created_at: "2025-07-12T18:34:29.535Z" name: agent-streamer-gateway status: ACTIVE domain: d5dgs4pn5iil********.********.apigw.yandexcloud.net connectivity: {} log_options: folder_id: b1g681qpemb4******** execution_timeout: 300sСохраните значение поля
domain— оно потребуется на следующем шаге.Чтобы создать API-шлюз, воспользуйтесь методом REST API create для ресурса ApiGateway или вызовом gRPC API ApiGatewayService/Create.
- В консоли управления
Проверьте работу агента
-
Подключитесь к WebSocket:
wscat -c wss://<домен_API-шлюза> -
Отправьте сообщение:
Tell me a joke about programmingРезультат:
< Here < are 5 jokes about < programming: ...Текст ответа может отличаться.
Как удалить созданные ресурсы
Чтобы не платить за ресурсы, которые вам больше не нужны, удалите их: