Сегодня обсудим развёртывание агентов, созданных в Yandex Cloud AI Studio Agent Atelier. Atelier — это такой очевидный UI для настройки PromptTemplate для Responses API.

Создание агента в Agent Atelier Yandex AI Studio
Создание агента в Agent Atelier Yandex AI Studio

После настройки параметров предполагается его использовать следующим образом:

Вызов агента из кода
Вызов агента из кода

Или вызывать в Workflows c помощью шага Agent AI Studio. На первом скриншоте показано объявление переменной SPHERE для подстановки в шаблон промпта. Это пригодится, например, для добавления данных пользовательского профиля в контекст. Используются переменные следующим образом.

response = client.responses.create(     
                        prompt={ "id": "fvtslea9uok6pv7tnb9j",     
                                "variables": {"SPHERE": "финансовых рынков"}},     
                        input="Балансовая стоимость...", )

Итак, допустим, мы настроили параметры такого агента в веб-интерфейсе. Каким образом мы бы могли сохранить его конфигурацию в Git и разворачивать агент на различные окружения\облака\каталоги? Напрямую такой возможности нет. И это немного обескураживает.

Если взглянуть под этим же углом на Workflows, то в Terraform они тоже не поддерживаются, но их можно развернуть CLI, REST API, gRPC API (пример кода вызова workflow, его можно взять за основу кода, создающего workflow). Для агентов из Atelier никаких API развёртывания нет. Давайте попробуем решить задачу развёртывания агента сведением к типовой — развернём его как Workflow с шагом AI агент.

Шаг агента в Workflow
Шаг агента в Workflow

В настройках шага видно, как подставлять входные данные в строковое поле шага: "Строковый шаблон \(.json.path.to.value)", полная подстановка значения: \(.json.path.to.value). Для ясности см. wf.yaml.

yawl: '0.1'
start: step-aiAgent631
steps:
  step-aiAgent631:
    aiAgent:
      agentConfig:
        role: "Ты — ассистент технической поддержки."
        goal: "\"Ты общаешься с пользователем системы \\(.subj) и помогаешь решить его технические вопросы.\""
        backstory: "Для получения информации используй инструмент поиска по документации. Отвечай строго на основе предоставленной базы знаний. Если в базе знаний нет информации для ответа, прямо скажи пользователю: «К сожалению, в базе знаний нет ответа на\_этот вопрос. Я могу передать запрос специалисту». Отвечай кратко, понятно и по делу. Если вопрос не относится к технической поддержке, вежливо откажись отвечать."
        model:
          name: aliceai-llm
      tasks:
        - result: ''
          description: \(.input.message)
      input: ''
      output: '\({"step-aiAgent631": .})'
    description: ''

Замечание. На скриншоте показаны два альтернативных вида jq-выражения, с .input и без него. Не стоит заострять на этом внимание, эти способы эквивалентны и значимо различаются только для довольно экзотических случаев. Пример вызова агента и ответ:

Вызов Агента в Workflow
Вызов Агента в Workflow

Соответственно, поменяв язык в subj, получим сниппет на другом языке. Это покрывает функционал переменных PromptTemplate, доступных в Atelier. Теперь выполним развёртывание этого агента из файлов конфигурации.

Развёртывание Workflow Агента

Используем для этого CLI. Для начала получим конфигурацию в виде файлов.

yc sls wf get dfq1t33mhn1hm6r2bmsf --jq .workflow.specification.spec_yaml > wfspec.yaml 
#Yaml spec будет записан в файл wfspec.yaml .
yc sls wf get dfq1t33mhn1hm6r2bmsf --jq "del(.workflow.specification)" > wfparams.json
#Получим параметры вф в виде json.
{                                                                                                                                                                   
  "workflow": {                                                                                                                                                     
    "created_at": "2026-03-22T07:22:30.454893Z",                                                                                                                    
    "execution_url": "https://serverless-workflows.api.cloud.yandex.net/workflows/v1/execution/dfq1t33mhn1hm6r2bmsf/start",                                         
    "folder_id": "b1gmt69",                                                                                                                            
    "id": "dfq1t33mhn1hm6r2bmsf",                                                                                                                                   
    "log_options": {                                                                                                                                                
      "folder_id": "b1t69"                                                                                                                           
    },                                                                                                                                                              
    "name": "workflow667",                                                                                                                                          
    "service_account_id": "ajeb3i",                                                                                                                   
    "status": "ACTIVE"                                                                                                                                              
  }                                                                                                                                                                 
}

Далее JSON с параметрами конвертируем в аргументы вызова CLI (я использовал языковую модель).

 yc serverless workflow create deploy-test-wf \                                                                                                   
  --service-account-id aje4t6pb3i \                                                                                                                       
  --log-folder-id b1gmt69 \                                                                                                                            
  --yaml-spec wfspec.yaml \                                                                                                                                         
  --folder-id b1g5mt69   

Обратите внимание на то, что команда принимает yaml-спецификацию в виде файла.

В Git следует коммитить wfspec.yaml и вот этот вот .sh, полученный из wfparams.json. Другой вариант: коммитить JSON и навайбкодить скрипт конверсии JSON в CLI-аргументы. При обновлении процесса следует использовать команду update, а не delete&create.

Альтернативные механизмы развёртывания gRPC, REST API см. ссылки выше.

Итак, мы можем разработать агент, а потом разворачивать его на разные окружения, контролировать версии и т.п.

Пока в нашем агенте нет ни одного инструмента (так себе агент), и этот вопрос мы рассмотрим ниже. Другие ограничения Agent Atelier:

  • Невозможность передать флаг отключения логирования.

    Обновление 31.03.2026 Коллеги из команды сервиса выпустили обновление. Теперь при редактировании Workflow на шаге "Модели AI Studio" можно выключить логирование с помощью соответствующей галочки: "Enable data logging" в визуальном редакторе. По умолчанию логирование включено. В спецификации это можно сделать с помощью такой конструкции: dataLoggingEnabled: false

  • Если он нужен, то можно использовать более низкоуровневый шаг HTTP для обращения к моделям через Responses, Completions API. Опять же, есть «но»: придётся обрабатывать вызовы инструментов самостоятельно.

  • Отсутствие поддержки LLM-трассировки в агентах Agent Atelier/AIAgent Workflow.      

Vector Search

Добавим в агента инструмент поиска по файлам для реализации сценария RAG. Для этого нам потребуется прослойка MCP-сервера.

  1. Создадим Vector Store и загрузим в него документы. Сделать это можно через веб-интерфейс AI Studio, SDK или REST API. CLI нет, но перечисленного достаточно для автоматизированного развёртывания.

  2. Создадим MCP-сервер, который будет через REST API выполнять поиск в Vector store. Основная страница документации тут.

    MCP-сервер
    MCP-сервер
  3. Сервер должен быть приватным (у нас же корпоративный поиск!). Важно установить сервисный аккаунт. У этого сервисного аккаунта должна быть роль ai.assistants.editor или шире. Если не установите, то в сообщении об ошибке это будет указано.

  4. Вернёмся к MCP-серверу. Мы создаём новый MCP, добавляем HTTP-инструмент. В качестве URL-запроса используем URL поиска по векторному хранилищу, подставляя его идентификатор. Метод запроса POST.

  5. Открываем «Дополнительные параметры» и в качестве авторизации указываем сервисный аккаунт, обычно это означает, что IAM-токен сервисного аккаунта MCP-сервера будет указан в заголовке запроса к векторному хранилищу. По этому токену векторное хранилище проверит наличие роли ai.assistants.editor у инициатора запроса на поиск — нашего MCP-сервера.    

    Конфигурация HTTP инструмента MCP сервера для поиска в индексе
    Конфигурация HTTP инструмента MCP сервера для поиска в индексе
  6. Единственным параметром инструмента служит строка запроса. Как вариант, тут можно так же получать фильтры для поиска, аргументы ранжирования или персонализации. Эти параметры предоставляются языковой модели в описании инструмента, и она может решить вызвать этот инструмент, заполнив эти параметры из сообщения от пользователя. В общем, тема это обширная, и детальное её рассмотрение выходит за рамки этой статьи.

    Аргумент function-call
    Аргумент function-call
  7. В заголовках запроса укажем очевидный Content-Type (может быть, это не обязательно). Ещё заметил, что по умолчанию интерфейс подставляет заголовок Authorization: \(.oauth_token). Я не уверен, но удалил его. Авторизация по сервисному аккаунту (см. выше), даёт ожидаемый результат.

  8. Важная деталь — тело запроса. Формируем его в соответствии с REST API векторного хранилища. На скриншоте видно, как с помощью JQ-шаблона подставляется значение параметра, полученное от LLM. В нашем случае это строка поискового запроса.

    Запрос к поисковому индексу
    Запрос к поисковому индексу
  9. Теперь нужно проверить что MCP-сервер с поиском работает. Для этого создадим тестового агента в Atelier включим в него созданный MCP-сервер с инструментом поиска.

    Тест MCP-сервера с поиском в Playground
    Тест MCP-сервера с поиском в Playground
  10. Попробуем его в диалоге. Разрешим вызов инструмента. Для вызова приватного MCP пользователь или сервисный аккаунт должен иметь роль serverless.mcpGateways.invoker (обратите на это внимание, с ней могут быть проблемы). 

    RAG чат-бот
    RAG чат-бот
  11. Очень полезная штука — кнопки отладочной информации {...}. Например, там видно определение инструмента для LLM, конкретные аргументы вызова и результат вызова. Тут же можно увидеть ошибки, которые вернёт MCP-сервер.

    Отладочная информация: найденные отрывки
    Отладочная информация: найденные отрывки
  12. MCP-сервер с поисковым инструментом работает. Вернёмся к проблемам развёртывания. Нам нужен способ развернуть его скриптом. Получим отдельные файлы с описанием инструментов и основных параметров сервера через yc CLI по id ранее созданного сервера.

    $ yc sls mcp-gateway get db8jl2aalkfou1ueg6i9 --jq .tools > mcptools.json         
    $ yc sls mcp-gateway get db8jl2aalkfou1ueg6i9 --jq 'del(.tools)' > mcpserver.json
  13. Сконвертируем основные параметры сервера в вызов yc CLI, для эксплуатации навайбкодим скрипт конверсии. Отдельный файл с описанием инструмента передаём аргументом командной строки.

    yc serverless mcp-gateway create vector-store-search-webserver \
      --folder-id b1gt69 \                           
      --service-account-id ajehcjs \ 
      --log-folder-id b1gt69 \ 
      --min-log-level info  --tools-file ./mcptools.json 
  14. Теперь у нас есть файлы конфигурации поискового инструмента. Можем указать развёрнутый MCP-сервер в рабочем процессе.

    Указываем MCP-сервер как инструмент в шаге агента в воркфлоу
    Указываем MCP-сервер как инструмент в шаге агента в воркфлоу

В качестве адреса MCP возьмём базовый URL из свойств MCP. Транспорт, исходя из окончания URL, похоже SSE. Выбираем IAM-токен т.к. MCP у нас приватный.

Очень важно. Чтобы вызвать приватный MCP, сервисный аккаунт в рабочем процессе должен иметь роль serverless.mcpGateways.invoker в дополнении к роли для вызова LLM. Если роли serverless.mcpGateways.invoker нет, получим ошибку 403:

Ошибка вызова MCP-сервера без роли serverless.mcpGateways.invoker
Ошибка вызова MCP-сервера без роли serverless.mcpGateways.invoker

С ролями и аккаунтами у меня полного понимания нет. Точно работает, если требуемые роли указать при создании сервисного аккаунта. В дальнейшем в интерфейсе роль не добавляется, хотя добавить можно, но это какое-то не «то» добавление роли. Добавить можно в колонку «Роли», а нужно «Наследуемые роли». Но нужная роль добавляется через CLI:

yc resource-manager cloud add-access-binding <your-cloud-id> \
  --subject serviceAccount:ajjjj3333 \
  --role serverless.mcpGateways.invoker

Как результат, агента можно заставить вызывать поиск через MCP-сервер. Для наглядности я добавил инструкцию приводить источник:

Результаты поиска в воркфлоу
Результаты поиска в воркфлоу

На скриншоте видно, что для генерации использовались результаты поиска в созданном векторном хранилище.

Итого

Мы имеем:

  1. Рабочий процесс с агентом, который вызывает.

  2. MCP-сервер, который использует.

  3. Векторное хранилище для поиска в документах.

Всё это с контролем доступа и конфигурацией в виде файлов, которые можно разворачивать на разных окружениях, отслеживая версии.

Инструмент или Шаг потока?

Зачастую приходится делать настолько специализированные чат-боты, что RAG сценарий является в них априорно необходимым. Т.е. инструмент поиска вызывается строго обязательно, альтернативные сценарии вопросов на отвлечённые темы просто не рассматриваются как смысла не имеющие. В этом случае поиск не нужен нам как инструмент, он становится предварительным шагом перед агентским. Т.е. в рабочий процесс добавляется шаг HTTPcall, выполняющий поиск по REST API, результаты поиска добавляются в промт агента с помощью шаблона подстановки, как было показано ранее.

История диалога

Рассмотренный пример принимает только одно сообщение пользователя, чат-боты работают с историей сообщений. Шаг AIAgent не поддерживает ничего похожего на previous_response_id, поэтому историю диалога нужно подставлять с помощью JQ-шаблона, как указано в примере чат-бота из документации. 

Заключение

Разворачивать агенты AI Studio скриптами можно, но довольно трудоёмко. Значительную трудность представляет отсутствие детальной трассировки. Работающее решение оставляет в логах крайне лаконичные сообщения, но, если что-то пошло не по плану, разобраться с этим невозможно и придётся прибегнуть к методу «простукивания чёрного ящика».

Будем ждать дальнейшего развития продукта.