Context Layer
Context Layer это компонент Renta MCP Server, предназначенный для взаимодействия с данными. Он предоставляет модели данных Google BigQuery в виде структурированных измерений (dimensions) и мер (measures), позволяя AI-ассистентам программно выбирать поля вместо генераци и сырых SQL-запросов.
Renta компилирует этот выбор в SQL-запросы для BigQuery, выполняет их в вашем проекте с использованием сервисного аккаунта подключения и возвращает результирующие строки вместе с подробными метаданными об объеме сканирования и стоимости.
В клиенте MCP Context Layer представлен как единый инструмент context_layer, включающий четыре действия. В последующих разделах подробно описаны функциональность и ожидаемые ответы для каждого из них.
Архитектура энтерпрайз-уровня
Context Layer спроектирован с упором на безопасность, контроль затрат и производительность, выступая в роли защищенного шлюза между вашим хранилищем данных и AI-ассистентами.
- Безопасность (Security by Design) и дата-контракты.
Архитектура опирается на строгие дата-контракты (data contracts). AI получает доступ исключительно к тем данным, которые вы явно разрешили. Интерфейс строго ограничен операциями чтения: генерируются только оптимизированныеSELECT-запросы, что полностью исключает возможность удаления, модификации или несанкционированного доступа к конфиденциальным данным. - Контроль затрат и оптимизация.
В случае с BigQuery Context Layer жестко ограничивает количество и объем запросов, не позволяя AI инициировать неконтролируемые расходы. Запросы максимально оптимизированы, обеспечивая высокую эффективность работы даже с миллиардами строк. - Оптимизация контекста AI.
Изолируя обработку сырых данных на стороне хранилища и возвращая только агрегированные результаты, Renta предотвращает засорение контекстного окна AI. Это значительно повышает эффективность и качество работы AI с данными. - Синергия с дата-инженерами.
Renta не заменяет проектировщиков данных. Наоборот, дата-инженеры продолжают создавать эффективные, заранее рассчитанные витрины данных (datamarts), а Renta берет на себя роль шлюза, который обеспечивает безопасность, производительность и контролируемый доступ AI к этим данным.
Как это работает
Агенты функционируют без предварительных знаний о топологии вашего хранилища, последовательно формируя контекст за четыре шага.
- Список моделей.
Агент запрашивает доступные в рабочей области (workspace) модели и выбирает необходимую по ее идентификатору. - Описание модели.
Renta возвращает все измерения и меры, связанные с указанной моделью, включая их типы и описания. Агент ограничен использованием только тех полей, которые присутствуют в этом ответе. - Сэмплирование поля.
Renta извлекает фактические значения, диапазоны или статистические распределения для указанного поля, гарантируя, что агенты строят фильтры на основе эмпирических данных, а не предположений. - Выполнение запроса.
Renta компилирует выбранные поля, фильтры и временные границы в SQL-запрос, выполняет его и возвращает результирующие строки, метаданные колонок и статистику выполнения.
Все запросы строго ограничены рабочей областью, для которой был выпущен токен. Renta валидирует членство при каждом вызове. Следовательно, отозванный доступ вступает в силу немедленно.
Что нужно заранее
Context Layer взаимодействует с предварительно настроенными моделями. Перед началом использования убедитесь в выполнении следующих предварительных требований.
- Модель данных с областью видимости для AI.
Управление моделями осуществляется в разделе Tools > Data models. Инструкции по их созданию приведены в документации Google BigQuery reverse ETL. - Подключённый MCP-сервер.
Процесс авторизации, выполняемый при добавлении сервера, по умолчанию включает доступ к Context Layer. Запрос дополнительных прав не требуется.
Context Layer предоставляет доступ только к моделям с явно заданным scope AI agents only или AI agents & Reverse ETL. Модели со scope Reverse ETL only остаются недоступными для агентов.
Что агент видит в модели
Агенты используют нативную конфигурацию модели. Поддерживать отдельные описания, специфичные для AI, не требуется.
Колонки модели транслируются в измерения, типизированные как string, number, boolean или time. Структурированные колонки, такие как массивы (arrays) и записи (records), преобразуются в строковый тип (string). Имя и описание модели обеспечивают базовый контекст, используемый агентами для интерпретации семантики строк.
Меры формируются на основе конфигураций столбцов на вкладке Measures. Активация переключателя создает соответствующую меру, имя которой состоит из названия колонки и примененной агрегации.

Числовые колонки поддерживают все восемь функций агрегации. Для нечисловых типов доступны только COUNT и DISTINCT, поскольку а рифметические операции (сумма, среднее) неприменимы к строковым или временным данным.
| Переключатель | Имя меры | Что возвращает |
|---|---|---|
| SUM | revenue_sum | Сумма по колонке. Только числовые колонки. |
| AVG | revenue_avg | Среднее по колонке. Только числовые колонки. |
| MIN | revenue_min | Минимальное значение. Только числовые колонки. |
| MAX | revenue_max | Максимальное значение. Только числовые колонки. |
| MEDIAN | revenue_median | Приблизительная медиана. Только числовые колонки. |
| P95 | revenue_p95 | Приблизительный 95-й процентиль. Только числовые колонки. |
| COUNT | order_id_count | Количество непустых значений колонки. Любой тип колонки. |
| DISTINCT | order_id_distinct | Количество различных значений колонки. Любой тип колонки. |
Две меры доступны по умолчанию: count, возвращающая общее количество строк, и unique_count, возвращающая количество различных значений уникального ключа (если он задан в модели).
Колонка без включённых переключателей всё равно доступна как измерение. Агент может по ней группировать, но агрегировать по ней нечего.
Назначение агрегаций сразу нескольким колонкам
Индивидуальное переключение подходит для узких схем. В моделях с большим количеством столбцов целесообразно использовать массовые операции: выберите целевые колонки для глобального применения агрегаций одним действием.

- Выберите колонки.
Отметьте чекбокс в крайней левой колонке нужных строк. Чекбокс в строке заголовка берёт всё, что сейчас показано в т аблице, поэтому сначала сузьте список поиском или фильтрами Dimensions и Metrics. - Примените агрегации.
Заголовок страницы сменится панелью, которая показывает размер выбора и восемь агрегаций в виде чипов. Нажатие на чип включает агрегацию всем выбранным колонкам, повторное нажатие выключает. - Читайте состояние по чипу.
Залитый чип означает, что агрегация включена у всех выбранных колонок, пунктирный что у части, контурный что нигде. Чип, который не поддерживает ни одна выбранная колонка, гаснет, поэтому SUM не попадёт на текстовую колонку даже случайно. - Начните заново, если нужно.
Clear снимает у выбранных колонок все агрегации. Show Selected прячет остальную таблицу, пока вы работаете с выбором.
Список мер это контракт
Агент считает только то, что модель ему отдала. Своего SQL у него нет, и агрегация, которую вы не включили, для него не существует, поэтому список мер работает контрактом между вашими данными и агентом.
Ради этого и стоит потратить минуту на выбор по каждой колонке. Тип колонки говорит, что арифметически возможно, а вы говорите, что осмысленно.
| Колонка | Что включить | Почему |
|---|---|---|
| Сумма заказа | SUM, AVG, MEDIAN, P95 | Выручка складывается, а среднее и хвост распределения отвечают на реальные вопросы. |
| Средний чек | AVG | В колонке уже лежит среднее. Сумма средних даёт число, которое ничего не значит, и агент не должен иметь возможности его предложить. |
| Ставка скидки, конверсия, маржинальность | AVG, MEDIAN | Доля не складывается. Сумма 0.10 и 0.25 это не скидка 0.35. |
| Остаток на счёте, остаток на складе | MIN, MAX, AVG | Это уровень на момент времени. Сумма срезов задваивает одни и те же деньги или один и тот же товар. |
| Идентификатор заказа | COUNT, DISTINCT | Вопрос к нему один: сколько заказов. Остальное к идентификатору неприменимо. |
На кадре выше правило уже применено: у discount_rate открыты AVG и MEDIAN, а SUM выключен, поэтому суммированную ставку скидки агент не покажет никогда.
Короткий список мер ещё и дешевле. Каждая мера едет в контексте агента при каждом запросе описания модели, поэтому включать агрегации, которые отвечают на реальные вопросы, выгоднее, чем отмечать все восемь у каждой числовой колонки.
Метаданные, которые читает агент
Вашу таблицу агент не видит. Он видит имя модели, её описание и список имён полей с типами, и все его решения строятся на этом. Метаданные заполняются на вкладке Metadata модели.

- Model name.
Как модель называют агент и ваши коллеги. Нижний регистр с подчёркиваниями. - Description.
Что лежит в модели и как её использовать. Это поле делает основную работу, и что в нём писать, разобрано в следующем разделе. - Column descriptions.
Хранятся вместе с моделью и показываются в интерфейсе. Кнопка Auto-generate with AI заполняет их по запросу и данным примера.
Панель справа считает, сколько токенов модель займёт в контексте агента. Этот контекст делится со всем остальным в диалоге, поэтому описание оправдывает свою длину тем, что оно решает.
Через Context Layer колонка приходит именем и типом. Заголовки, описания и списки допустимых значений по колонкам доходят до агента только как семантические переопределения, которые пишутся через Context Layer API. Пока их нет, всё, чего не сообщает имя колонки, живёт в описании модели.
Описание как инструкция для агента
Описание это свободный текст, и агент получает его дважды: в списке моделей, где выбирать больше не по чему, и затем в полной модели. Всё, что вы там напишете, попадёт в контекст агента, поэтому пишите инструкцию, а не подпись.
Что стоит указать в описании:
- Что такое одна строка.
От гранулярности зависит, будет число итогом или задвоением. - Покрытый период и время обновления.
Это то, что удержит агента от вывода «сегодня всё упало», когда сегодняшний день ещё не загружен. - Единицы измерения и валюта.
Сумма без валюты всё равно сложится, просто неправильно. - На какие вопросы отвечает модель.
Формулируйте так, как их задают люди, чтобы агент сопоставил запрос с моделью. - Когда нужна другая модель.
Назовите её. Именно это не даёт агенту ответить про возвраты по таблице выручки. - Что отфильтровано.
Тестовые заказы, отменённые строки, внутренние аккаунты.
Одна строка это один завершённый заказ, ключ order_id. Период с 2024-01-01 по
вчера, обновление ежедневно в 06:00 UTC, поэтому сегодняшний день всегда неполный.
Суммы в USD без НДС.
Используй эту модель для выручки, среднего чека и количества заказов в разрезе
страны, канала или кампании. Для возвратов и чарджбэков бери модель payments:
возвращённые заказы остаются здесь с исходной суммой.
Тестовые заказы уже исключены.Описание, которое повторяет имя модели, не даёт агенту ничего. Модель orders с описанием «таблица заказов» выбирается только по имени, а что в ней лежит, выясняется уже после выполненного запроса.
Действия
Четыре действия инструмента context_layer рассчитаны на использование по порядку. Первые два не читают данные, и именно они не дают итоговому запросу сослаться на несуществующее поле.
| Действие | Что делает | Читает хранилище |
|---|---|---|
list_models | Возвращает модели воркспейса с именами и описаниями. | Нет |
describe_model | Возвращает измерения и меры одной модели. | Нет |
sample_field | Возвращает реальные значения, диапазоны или статистику по одному полю. | Да |
run_query | Возвращает агрегированные строки по выбранным полям. | Да |
Список моделей
Точка входа в любую сессию. Параметров у действия нет, а необязательный source_id сужает выдачу до моделей одного подключения BigQuery.
Ответ корот кий: идентификатор, имя и описание каждой модели. Это всё, что есть у агента при выборе модели, поэтому инструкции для него живут в описании модели.
Описание модели
Действие принимает model_id и возвращает модель целиком: таблицу или запрос, который она читает, измерения с типами и описаниями, меры с типами и подсказками по форматированию.
{
"action": "describe_model",
"model_id": "e2f1a3c4-5b6d-4e7f-8a90-1b2c3d4e5f60"
}Дальше имена полей используются буквально, а поле, которого не было в этом ответе, использовать нельзя. Здесь же агент узнаёт, какие меры вычисляемые, потому что на следующем шаге они ведут себя иначе.
Сэмплирование поля
Действие принимает model_id и field_name и читает хранилище по одному полю. Так фильтры остаются привязаны к данным, и агент не фильтрует по United States, когда в колонке лежит US.
{
"action": "sample_field",
"model_id": "e2f1a3c4-5b6d-4e7f-8a90-1b2c3d4e5f60",
"field_name": "country",
"values_limit": 10
}Что придёт в ответе, зависит от типа поля.
| Поле | Ответ |
|---|---|
| Строковое измерение | Самые частые значения с количеством строк, приблизительное число различных значений и признак того, что список обрезан. |
| Булево измерение | Количество строк со значениями true, false и null. |
| Числовое измерение | Минимум, максимум и 10-й, 50-й, 90-й процентили. |
| Измерение времени | Самое раннее и самое позднее значение, а также число различных дней между ними. |
| Меры SUM, AVG, MIN, MAX, MEDIAN и P95 | Та же статистика, что у числового измерения, плюс агрегат по всей модели. |
| Меры COUNT | Количество строк модели. |
| Меры DISTINCT | Приблизительное число различных значений. |
| Вычисляемые меры | Ошибка со статусом 422. Сэмплировать нечего, при этом внутри запроса мера работает. |
Два необязательных параметра относятся к строковым измерениям. values_limit ограничивает число значений в ответе, максимум 500, по умолчанию 50. search фильтрует по префиксу без учёта регистра, до 100 символов, и это рабочий способ найти значение в колонке с большим числом различных значений, например в идентификаторе заказа.
Для модели на таблице в ответе также указано, является ли поле колонкой партиционирования или частью ключа кластеризации. Фильтр по колонке партиционирования и держит большую модель дешёвой, поэтому агент сэмплирует поле с датой до того, как по нему фильтровать.
Выполнение запроса
Единственное действие, которое возвращает строки данных. Оно принимает модель, набор полей и условия.
{
"action": "run_query",
"model_id": "e2f1a3c4-5b6d-4e7f-8a90-1b2c3d4e5f60",
"dimensions": ["e2f1a3c4-5b6d-4e7f-8a90-1b2c3d4e5f60.campaign"],
"measures": ["e2f1a3c4-5b6d-4e7f-8a90-1b2c3d4e5f60.leads_sum"],
"time_dimensions": [
{
"dimension": "e2f1a3c4-5b6d-4e7f-8a90-1b2c3d4e5f60.date",
"date_range": "last_7_days"
}
],
"order": [
{
"member": "e2f1a3c4-5b6d-4e7f-8a90-1b2c3d4e5f60.leads_sum",
"direction": "desc"
}
],
"limit": 20
}В запросе должно быть хотя бы одно из полей dimensions, measures или time_dimensions. Результат всегда агрегирован, поэтому измерение, выбранное без мер, возвращает свои различные значения.
Справочник по запросу
Правила ниже проверяются при компиляции запроса. Запрос, который нарушает любое из них, возвращается со статусом 400 и сообщением о том, что именно не так, поэтому агент исправляет запрос, не прочитав ни одной строки данных.
Ссылки на поля
Поле записывается как идентификатор модели, точка и имя поля. Это касается dimensions, measures, time_dimensions, filters и order одинаково, а короткое имя поля отклоняется.
В именах мер всегда есть агрегация, поэтому колонка leads запрашивается как leads_sum. Сырая колонка сама по себе не агрегируется.
Фильтры
Фильтр это либо одно условие, либо группа условий, объединённых через and или or. Группы вкладываются друг в друга, чем и выражаются условия вида «одна страна с суммой выше одного порога или другая страна с суммой выше другого».
| Оператор | Значения |
|---|---|
equals, not_equals | Ровно одно |
gt, gte, lt, lte | Ровно одно |
contains, not_contains, starts_with, ends_with | Ровно одно |
in, not_in | Одно или больше |
between | Ровно два, обе границы включены |
is_null, is_not_null | Без значений |
Фильтр по измерению ограничивает читаемые строки. Фильтр по мере ограничивает уже агрегированный результат, и так отвечают на вопрос вида «кампании со ста и более лидами». В одной группе or эти два вида фильтров не сочетаются, потому что применяются на разных стадиях запроса. Объедините их через and верхнего уровня или задайте два вопроса.
Измерения времени
Измерение времени задаёт колонку с датой и, по желанию, гранулярность группировки и период. Гранулярность принимает значения hour, day, week, month, quarter и year.
Период задаётся либо парой дат ISO, где включены обе границы, либо одним из относительных токенов.
| Группа | Токены |
|---|---|
| Дни | today, yesterday |
| Текущий период | this_week, this_month, this_quarter, this_year |
| Предыдущий период | last_week, last_month, last_quarter, last_year |
| Скользящие окна | last_7_days, last_14_days, last_30_days, last_60_days, last_90_days, last_365_days |
Сортировка и постраничная выдача
Сортировка ссылается на поле, которое запрос выбирает. Сортировка по невыбранному полю отклоняется, а не игнорируется молча.
limit принимает от 1 до 10 000 строк, по умолчанию 1000. offset листает длинный результат, и это важно, потому что лимит обрезает ответ без предупреждения о том, что строк больше.
Ответ
Успешный запрос возвращает строки, метаданные колонок и статистику запроса.
Имя колонки состоит из идентификатора модели и имени поля через двойное подчёркивание, а измерение времени с гранулярностью добавл яет её в конец. Помесячная динамика leads_sum поэтому приходит в колонке, которая заканчивается на __date_month.
В статистике приходят обработанные байты, оплаченные байты, оценка стоимости, признак попадания в кеш, длительность, количество строк и идентификатор job в BigQuery. Дорогой вопрос показывает свою цену сразу после выполнения.
Контроль стоимости запросов
Сэмплирование и запросы выполняются в вашем проекте BigQuery и попадают в ваш счёт. У каждого из них есть предел по объёму сканирования и по времени.
| Действие | Объём сканирования | Ограничение по времени |
|---|---|---|
sample_field | 5 ГиБ | 30 секунд |
run_query | 10 ГиБ | 60 секунд |
Запрос, который вышел бы за свой предел, отклоняется до выполнения, и об этом сказано в ответе. Это тот момент, когда стоит добавить фильтр, а не после выставленного счёта.
Самый дешёвый фильтр это фильтр по колонке партиционирования таблицы: BigQuery тогда читает только подходящие партиции. Сэмплирование поля с датой показывает, та ли это колонка.
Квоты и лимиты
В таблице значения по умолчанию. Персональные лимиты, настроенные для вашего аккаунта, имеют приоритет над лимитами на количество запросов.
| Лимит | Значение |
|---|---|
| Запросы | 120 в минуту и 2000 в час |
| Строк в запросе | 10 000, по умолчанию возвращается 1000 |
| Значений при сэмплировании поля | 500, по умолчанию возвращается 50 |
| Длина префикса поиска | 100 символов |
| Моделей в запросе | Одна |
Запрос работает с одной моделью. Вопрос, который затрагивает две модели, решается двумя запросами с последующим объединением ответов или моделью, в запросе которой таблицы уже соединены.
Ошибки
Сбой возвращается кодом статуса с сообщением, а не пустым результатом.
| Код | Значе ние |
|---|---|
| 400 | Запрос нарушил правило компиляции или сослался на поле, которого в модели нет. В сообщении указано, что именно не так. |
| 401 | Токен отсутствует, недействителен или истёк. Пройдите авторизацию MCP-сервера заново. |
| 403 | Членство в воркспейсе, к которому привязан токен, отозвано. |
| 404 | Модель или поле не существует в этом воркспейсе. |
| 422 | Поле нельзя сэмплировать. У вычисляемых мер нет колонки в основе. |
| 429 | Превышен лимит частоты запросов. |
| 504 | Запрос не успел выполниться. |
Доступ через REST API
Те же четыре действия доступны по HTTP для клиентов с API-ключом, на базовом адресе Renta REST API.
| Эндпоинт | Действие |
|---|---|
GET /v1/context_layer/models | Список моделей воркспейса |
GET /v1/context_layer/models/{model_id} | Описание одной модели |
GET /v1/context_layer/models/{model_id}/fields/{field_name}/values | Сэмплирование поля |
POST /v1/context_layer/query | Выполнение запроса |
Для этих эндпоинтов API-ключу достаточно права Read в категории Context Layer. Права Create, Update и Delete той же категории относятся к семантическим переопределениям модели, которые правятся через API и своего экрана в интерфейсе не имеют.
curl -X GET "https://api.eu.renta.im/v1/context_layer/models" \
-H "Authorization: Bearer YOUR_API_TOKEN"Что дальше
Ready to get started?
Build your data pipeline today or get a personalized demo. Start free!
Need help?
Get expert support to ensure your project succeeds. We're here to help!
Feature requests?
Help shape our product! Share your ideas for new features and integrations.