[Yandex Cloud documentation](../../index.md) > [Tutorials](../index.md) > [Serverless technologies](index.md) > AI > Creating an AI agent with response streaming via web sockets

# Creating an agent based on the OpenAI Agents SDK with response streaming via web sockets on Yandex Cloud Functions and Yandex API Gateway

# Creating an agent based on the OpenAI Agents SDK with response streaming via web sockets on Yandex Cloud Functions and API Gateway


In this tutorial, you will create an agent with response streaming via [web sockets](https://en.wikipedia.org/wiki/WebSocket) on [Yandex Cloud Functions](../../functions/index.md) and [Yandex API Gateway](../../api-gateway/index.md). The function will use the [OpenAI Agents SDK](https://openai.github.io/openai-agents-python/) to access [the Yandex Cloud AI Studio](https://aistudio.yandex.ru/docs/en/ai-studio/concepts/generation/index#yandex) models.

Agents may take a long time to respond when handling complex requests, e.g., generation of large texts with reasoning, search operations, or indexing. In such cases, it is essential to monitor progress and receive incremental results in real time. Response streaming enables immediate output of tokens, phrases, intermediate messages, step statuses, and logs, followed by the final response, without waiting for the entire scenario to complete. This enhances the perceived speed, provides a more interactive UI/UX, and enables users to cancel, retry, and dynamically update the interface. Streaming is supported by most frameworks. The OpenAI Agents SDK also supports [streaming](https://openai.github.io/openai-agents-python/streaming/).

![streaming-openai-agent](../../_assets/tutorials/streaming-openai-agent.svg)

On the diagram:

1. The user establishes a WebSocket connection to the [API gateway](../../api-gateway/concepts/index.md) and uses it to send a request to the AI agent.
1. The API gateway forwards the request to the [function](../../functions/concepts/function.md) handler.
1. The function handler creates and runs the AI agent using the OpenAI Agent SDK in streaming mode. In this mode, the agent will instantly stream model output, without waiting for the complete response.
1. The AI agent augments the user’s query with additional context and sends it to the [text generation model](https://aistudio.yandex.ru/docs/en/ai-studio/concepts/generation/index).
1. A [service account](../../iam/concepts/users/service-accounts.md) provides the AI agent with access to the [Text Generation API](https://aistudio.yandex.ru/docs/en/ai-studio/text-generation/api-ref/index) using an [API key](../../iam/concepts/authorization/api-key.md).
1. The service account grants the function access to the [secret](../../lockbox/concepts/secret.md) containing the service account API key.
1. The function retrieves the service account API key from the secret.
1. The model sends the generated response to the AI agent.
1. The AI agent streams the model output in real time. The data is instantly sent to the established WebSocket connection using the [API Gateway Web Socket Connection Service](../../api-gateway/apigateway/websocket/api-ref/Connection/send.md). The function then terminates.
1. The API gateway forwards the response to the user.

To create an agent:

1. [Get your cloud ready](#before-begin).
1. [Set up your environment](#setup-environment).
1. [Prepare the project files](#prepare-files).
1. [Create a service account](#create-sa).
1. [Create an API key](#create-api-key).
1. [Create a secret for the API key](#create-secret).
1. [Create a function](#create-function).
1. [Create an API gateway](#create-gateway).
1. [Check the result](#check-result).

If you no longer need the resources you created, [delete them](#clear-out).

{% note tip %}

If you do not want to tie your AI agent to a specific vendor, deploy the function in Yandex Serverless Containers as described in [Developing functions in Functions Framework and deploying them to Yandex Serverless Containers](functions-framework-to-container.md).

{% endnote %}


## What an AI agent is and how to use it {#ai-agent-definition}

An AI agent is an AI-powered software assistant which can follow instructions, give answers to questions, and interact with users or other systems within a given context. Unlike standard generative models, AI agents can:

* Support personalized instructions and have a personality.
* Use external sources and third-party tools to gather information.
* Maintain conversation context.
* Perform multi-step actions to solve complex tasks.

### Why use serverless functions to work with AI agents {#why-serverless}

Functions offered by Cloud Functions provide multiple benefits when deploying AI agents:

* Scalability: Automatic scaling to accommodate the load.
* Cost-effectiveness: You only pay for the actual execution time.
* No infrastructure management required: You do not need to configure or maintain servers.
* Fast deployment: AI agents are easy to create and update.
* Multiple integration options: Simple connection to APIs and other Yandex Cloud services.


## Get your cloud ready {#before-begin}

Sign up for Yandex Cloud and create a [billing account](../../billing/concepts/billing-account.md):
1. Navigate to the [management console](https://console.yandex.cloud) and log in to Yandex Cloud or create a new account.
1. On the **[Yandex Cloud Billing](https://center.yandex.cloud/billing/accounts)** page, make sure you have a billing account linked and it has the `ACTIVE` or `TRIAL_ACTIVE` [status](../../billing/concepts/billing-account-statuses.md). If you do not have a billing account, [create one](../../billing/quickstart/index.md) and [link](../../billing/operations/pin-cloud.md) a cloud to it.

If you have an active billing account, you can create or select a [folder](../../resource-manager/concepts/resources-hierarchy.md#folder) for your infrastructure on the [cloud page](https://console.yandex.cloud/cloud).

[Learn more about clouds and folders here](../../resource-manager/concepts/resources-hierarchy.md).


### Required paid resources {#paid-resources}

The infrastructure support cost for this tutorial includes:

* Fee for the number of requests to the API gateway and outgoing traffic (see [API Gateway pricing](../../api-gateway/pricing.md)).
* Fee for text generation (see [Yandex Cloud AI Studio pricing](https://aistudio.yandex.ru/docs/en/ai-studio/pricing)).
* Fee for the number of function calls, computing resources allocated for the function, and outgoing traffic (see [Cloud Functions pricing](../../functions/pricing.md)).
* Fee for storing the secret and operations with it (see [Yandex Lockbox pricing](../../lockbox/pricing.md)).
* Fee for retrieval and storage of logs (see [Yandex Cloud Logging pricing](../../logging/pricing.md)).


## Set up your environment {#setup-environment}

1. Install [jq](https://jqlang.org/manual/) to work with [JSON](https://en.wikipedia.org/wiki/JSON):

    {% list tabs group=operating_system %}

      - Linux {#linux}

        ```bash
        apt-get install jq
        ```

      - macOS {#macos}

        ```bash
        brew install jq
        ```

    {% endlist %}

1. Install [wscat](https://www.npmjs.com/package/wscat) to test the agent:

    ```bash
    npm install -g wscat
    ```


## Prepare the project files {#prepare-files}

To complete this tutorial, you need files containing the function code and the API gateway specification.

{% list tabs %}

- Repository

  Clone the repository:

  ```bash
  git clone https://github.com/yandex-cloud-examples/yc-serverless-streaming-openai-agent
  ```

  In the repository, you will see:

  * `function.zip` containing the `function.py` source file and the `requirements.txt` dependency file.
  * `gateway-spec.yaml` file with the API gateway specification.

- Manually

  1. Create a directory named `yc-serverless-streaming-openai-agent` and open it.
  1. Create a file named `function.py` and paste this code into it:

      ```python
      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)

      # Initializing the Yandex Cloud SDK
      sdk = SDK()

      def get_websocket_service():
          return sdk.client(ConnectionServiceStub)

      def stream_to_websocket(connection_id: str, message: str):
          """Sending message to WebSocket connection"""
          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):
          """Processing agent stream and sending to 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 main handler"""
          try:
              # Getting event parameters
              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'})
                  }

              # Creating the agent
              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
                  )
              )

              # Running asynchronous handling
              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)})
              }
      ```

  1. Create a file named `requirements.txt` and paste this code into it:

      ```text
      openai-agents>=0.0.17
      yandexcloud>=0.227.0
      grpcio>=1.60.0
      protobuf>=4.25.1
      openai~=1.86.0
      ```

  1. Create an archive named `function.zip` and add the `function.py` and `requirements.txt` files to it.
  1. Create a file named `gateway-spec.yaml` and paste this code into it:

      ```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: <function_ID>
              tag: $latest
              type: cloud_functions
              service_account_id: <service_account_ID>
      ```

      After you create the service account and functions, specify their IDs.

{% endlist %}


## Create a service account {#create-sa}

The function will use the service account to get access to the secret and AI Studio model, and the API gateway will get access to the function.

{% list tabs group=instructions %}

- Management console {#console}

  1. In the [management console](https://console.yandex.cloud), select the [folder](../../resource-manager/concepts/resources-hierarchy.md#folder) where you are going to create your infrastructure.
  1. Navigate to **Identity and Access Management**.
  1. Click **Create service account**.
  1. Name the service account: `agent-streamer-sa`.
  1. Click ![plus](../../_assets/console-icons/plus.svg) **Add role** and select these [roles](../../iam/roles-reference.md):
      * `serverless.functions.invoker`
      * `lockbox.payloadViewer`
      * `api-gateway.websocketWriter`
      * `ai.languageModels.user`

  1. Click **Create**.

- Yandex Cloud CLI {#cli}

  If you do not have the Yandex Cloud CLI yet, [install and initialize it](../../cli/quickstart.md#install).

  The folder used by default is the one specified when [creating](../../cli/operations/profile/profile-create.md) the CLI profile. To change the default folder, use the `yc config set folder-id <folder_ID>` command. You can also specify a different folder for any command using `--folder-name` or `--folder-id`. If you access a resource by its name, the search will be limited to the default folder. If you access a resource by its ID, the search will be global, i.e., through all folders based on access permissions.

  1. Create a service account:

      ```bash
      yc iam service-account create --name agent-streamer-sa
      ```

      Result:

      ```text
      id: ajehqs5gee2e********
      folder_id: b1g681qpemb4********
      created_at: "2025-07-12T17:53:28.180991864Z"
      name: agent-streamer-sa
      ```

  1. Assign [roles](../../iam/roles-reference.md) to the service account:

      ```bash
      yc resource-manager folder add-access-binding <folder_name_or_ID> \
        --role serverless.functions.invoker \
        --subject serviceAccount:<service_account_ID>

      yc resource-manager folder add-access-binding <folder_name_or_ID> \
        --role lockbox.payloadViewer \
        --subject serviceAccount:<service_account_ID>

      yc resource-manager folder add-access-binding <folder_name_or_ID> \
        --role api-gateway.websocketWriter \
        --subject serviceAccount:<service_account_ID>

      yc resource-manager folder add-access-binding <folder_name_or_ID> \
        --role ai.languageModels.user \
        --subject serviceAccount:<service_account_ID>
      ```

      Result:

      ```text
      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
      ```

- API {#api}

  To create a service account, use the [create](../../iam/api-ref/ServiceAccount/create.md) REST API method for the [ServiceAccount](../../iam/api-ref/ServiceAccount/index.md) resource or the [ServiceAccountService/Create](../../iam/api-ref/grpc/ServiceAccount/create.md) gRPC API call.

  To assign the service account the `serverless.functions.invoker`, `lockbox.payloadViewer`, `api-gateway.websocketWriter`, and `ai.languageModels.user` [roles](../../iam/roles-reference.md) for the folder, use the [updateAccessBindings](../../resource-manager/api-ref/Folder/updateAccessBindings.md) REST API method for the [Folder](../../resource-manager/api-ref/Folder/index.md) resource or the [FolderService/UpdateAccessBindings](../../resource-manager/api-ref/grpc/Folder/updateAccessBindings.md) gRPC API call.

{% endlist %}


## Create an API key {#create-api-key}

The function will use the API key to get access to the AI Studio model.

{% list tabs group=instructions %}

- Management console {#console}

  1. Open the [management console](https://console.yandex.cloud).
  1. Navigate to **Identity and Access Management**.
  1. Select the `agent-streamer-sa` service account you created earlier.
  1. In the top panel, click ![image](../../_assets/console-icons/plus.svg) **Create new key** and select **Create API key**.
  1. In the **Scope** field, select [`yc.ai.languageModels.execute`](../../iam/concepts/authorization/api-key.md#scoped-api-keys).
  1. Click **Create**.
  1. Save the ID and secret key to later create the function.

      {% note alert %}

      After you close this dialog, the key value will no longer be available.

      {% endnote %}

- Yandex Cloud CLI {#cli}

  The folder used by default is the one specified when [creating](../../cli/operations/profile/profile-create.md) the CLI profile. To change the default folder, use the `yc config set folder-id <folder_ID>` command. You can also specify a different folder for any command using `--folder-name` or `--folder-id`. If you access a resource by its name, the search will be limited to the default folder. If you access a resource by its ID, the search will be global, i.e., through all folders based on access permissions.

  Run this command:

  ```bash
  yc iam api-key create \
    --service-account-id <service_account_ID> \
    --scopes yc.ai.languageModels.execute
  ```

  Where:

  * `--service-account-id`: `agent-streamer-sa` service account ID.
  * `--scopes`: Key [scopes](../../iam/concepts/authorization/api-key.md#scoped-api-keys).

  Result:

  ```text
  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********
  ```

  Save the value of the `secret` field.

- API {#api}

  To create an API key, use the [create](../../iam/api-ref/ApiKey/create.md) REST API method for the [ApiKey](../../iam/api-ref/ApiKey/index.md) resource or the [ApiKeyService/Create](../../iam/api-ref/grpc/ApiKey/create.md) gRPC API call.

{% endlist %}


## Create a Yandex Lockbox secret {#create-secret}

The [Yandex Lockbox](../../lockbox/index.md) secret will store the secret key.

{% list tabs group=instructions %}

- Management console {#console}

  1. Open the [management console](https://console.yandex.cloud).
  1. Navigate to **Lockbox**.
  1. Click **Create secret**.
  1. In the **Name** field, specify the secret name: `api-key-secret`.
  1. In the **Secret type** field, select `Custom`.
  1. In the **Key** field, enter `api-key`.
  1. In the **Value** field, paste the secret key you obtained in the previous step.
  1. Click **Create**.

- Yandex Cloud CLI {#cli}

  The folder used by default is the one specified when [creating](../../cli/operations/profile/profile-create.md) the CLI profile. To change the default folder, use the `yc config set folder-id <folder_ID>` command. You can also specify a different folder for any command using `--folder-name` or `--folder-id`. If you access a resource by its name, the search will be limited to the default folder. If you access a resource by its ID, the search will be global, i.e., through all folders based on access permissions.

  Run this command:

  ```bash
  yc lockbox secret create \
    --name api-key-secret \
    --payload "[{'key': 'api-key', 'text_value': '<secret_key>'}]"
  ```

  Where `text_value` is the API gateway secret key you got in the previous step.

  Result:

  ```text
  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
  ```

- API {#api}

  To create a secret, use the [create](../../lockbox/api-ref/Secret/create.md) REST API method for the [Secret](../../lockbox/api-ref/Secret/index.md) resource or the [SecretService/Create](../../lockbox/api-ref/grpc/Secret/create.md) gRPC API call.

{% endlist %}


## Create a function {#create-function}

The function will be created based on the archive with its code and dependencies.

{% list tabs group=instructions %}

- Management console {#console}

  1. Open the [management console](https://console.yandex.cloud).
  1. Navigate to **Cloud Functions**.
  1. Create a function:

     1. Click **Create function**.
     1. In the window that opens, enter `agent-streamer` as the function name.
     1. Click **Create**.

  1. Create a [function version](../../functions/concepts/function.md#version):

     1. Select `Python 3.12` as the runtime , disable **Add files with code examples**, and click **Continue**.
     1. In the **Code source** field, select `ZIP archive` and attach the `function.zip` archive you created earlier.
     1. Specify the entry point: `function.handler`.
     1. Under **Parameters**, specify:

         * **Timeout**: `30 seconds`.
         * **Memory**: `512 MB`.
         * **Service account**: Select the `agent-streamer-sa` service account.
         * **Environment variables**:

             * `BASE_URL`: Yandex Cloud AI Studio URL, `https://ai.api.cloud.yandex.net/v1`.
             * `MODEL_NAME`: URI of the Yandex Cloud AI Studio text generation [model](https://aistudio.yandex.ru/docs/en/ai-studio/concepts/generation/models#generation).

                 For example, this URI may look like this: `gpt://<folder_ID>/yandexgpt/latest`, where `<folder_ID>` is the [ID of the folder](../../resource-manager/operations/folder/get-id.md) where you are creating the infrastructure.

             * `FOLDER_ID`: [ID of the folder](../../resource-manager/operations/folder/get-id.md) where you are creating the infrastructure.

         * **Lockbox secrets**:

             * In the **Environment variable** field, specify `API_KEY` and select the previously created `api-key-secret`, its version, and `api-key`.

        * If you prefer to opt out of logging so as not to [pay](../../logging/pricing.md) for [Cloud Logging](../../logging/index.md), disable the **Write logs** option.

     1. Click **Save changes**.

- Yandex Cloud CLI {#cli}

  The folder used by default is the one specified when [creating](../../cli/operations/profile/profile-create.md) the CLI profile. To change the default folder, use the `yc config set folder-id <folder_ID>` command. You can also specify a different folder for any command using `--folder-name` or `--folder-id`. If you access a resource by its name, the search will be limited to the default folder. If you access a resource by its ID, the search will be global, i.e., through all folders based on access permissions.

  1. Create a function:

      ```bash
      yc serverless function create --name agent-streamer
      ```

      Result:

      ```text
      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
      ```

  1. Create a function version:

      ```bash
      yc serverless function version create \
        --function-name agent-streamer \
        --runtime python312 \
        --entrypoint function.handler \
        --memory 512m \
        --execution-timeout 30s \
        --source-path <path_to_archive> \
        --service-account-id <service_account_ID> \
        --environment BASE_URL=https://ai.api.cloud.yandex.net/v1 \
        --environment MODEL_NAME=gpt://<folder_ID>/yandexgpt/latest \
        --environment FOLDER_ID=<folder_ID> \
        --secret name=api-key-secret,key=api-key,environment-variable=API_KEY
      ```

      Where:

      * `--source-path`: Path to `function.zip`.
      * `--service-account-id`: `agent-streamer-sa` service account ID.
      * `--environment`: Environment variables:

          * `BASE_URL`: Yandex Cloud AI Studio URL, `https://ai.api.cloud.yandex.net/v1`.
          * `MODEL_NAME`: URI of the Yandex Cloud AI Studio text generation [model](https://aistudio.yandex.ru/docs/en/ai-studio/concepts/generation/models#generation).

              For example, this URI may look like this: `gpt://<folder_ID>/yandexgpt/latest`, where `<folder_ID>` is the [ID of the folder](../../resource-manager/operations/folder/get-id.md) where you are creating the infrastructure.

          * `FOLDER_ID`: [ID of the folder](../../resource-manager/operations/folder/get-id.md) where you are creating the infrastructure.

      * `--secret`: `api-key-secret`.

      Result:

      ```text
      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://ai.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"
      ```

- API {#api}

  To create a function, use the [create](../../functions/functions/api-ref/Function/create.md) REST API method for the [Function](../../functions/functions/api-ref/Function/index.md) resource or the [FunctionService/Create](../../functions/functions/api-ref/grpc/Function/create.md) gRPC API call.

  To create a function version, use the [createVersion](../../functions/functions/api-ref/Function/createVersion.md) REST API method for the [Function](../../functions/functions/api-ref/Function/index.md) resource or the [FunctionService/CreateVersion](../../functions/functions/api-ref/grpc/Function/createVersion.md) gRPC API call.

{% endlist %}


## Create an API gateway {#create-gateway}

Create an API gateway for accessing the function.

1. Open the `gateway-spec.yaml` file and specify the following:

    * `function_id`: `agent-streamer` function ID.
    * `service_account_id`: `agent-streamer-sa` service account ID.

1. Create an API gateway:

    {% list tabs group=instructions %}

    - Management console {#console}

      1. Open the [management console](https://console.yandex.cloud).
      1. Navigate to **API Gateway**.
      1. Click **Create API gateway**.
      1. In the **Name** field, enter `agent-streamer-gateway` as the API gateway name.
      1. Under **Specification**, paste the contents of the `gateway-spec.yaml` file.
      1. If you prefer to opt out of logging so as not to pay for Cloud Logging, disable the **Write logs** option.
      1. Click **Create**.
      1. Select the previously created API gateway. Save the **WebSocket endpoint** field value, as you will need it in the next step.

    - Yandex Cloud CLI {#cli}

      The folder used by default is the one specified when [creating](../../cli/operations/profile/profile-create.md) the CLI profile. To change the default folder, use the `yc config set folder-id <folder_ID>` command. You can also specify a different folder for any command using `--folder-name` or `--folder-id`. If you access a resource by its name, the search will be limited to the default folder. If you access a resource by its ID, the search will be global, i.e., through all folders based on access permissions.

      Run this command:

      ```bash
      yc serverless api-gateway create \
      --name agent-streamer-gateway \
      --spec <specification_file_path>
      ```

      Where `--spec` is the path to the `gateway-spec.yaml` file.

      Result:

      ```text
      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
      ```

      Save the `domain` field value, as you will need it in the next step.

    - API {#api}

      To create an API gateway, use the [create](../../api-gateway/apigateway/api-ref/ApiGateway/create.md) REST API method for the [ApiGateway](../../api-gateway/apigateway/api-ref/ApiGateway/index.md) resource or the [ApiGatewayService/Create](../../api-gateway/apigateway/api-ref/grpc/ApiGateway/create.md) gRPC API call.

    {% endlist %}


## Test the agent {#check-result}

1. Connect to WebSocket:

    ```bash
    wscat -c wss://<API_gateway_domain>
    ```


1. Send the following message:

    ```text
    Tell me a joke about programming
    ```

    Result:

    ```text
    < Here
    <  are 5 jokes about
    <  programming:
    ...
    ```

    The actual response text may differ.


## How to delete the resources you created {#clear-out}

To stop [paying](#paid-resources) for the resources you no longer need, delete them.

1. [Delete the API gateway](../../api-gateway/operations/api-gw-delete.md).
1. [Delete](../../functions/operations/function/function-delete.md) the function.
1. [Delete](../../lockbox/operations/secret-delete.md) the secret.
1. If the function logging feature was left on, [delete](../../logging/operations/delete-group.md) the log group.