Из инженерного блога Омни Карт · ← На главную
Блог / Инженерия

Как подключить данные о городе к ИИ-агенту: MCP, REST или свой краулер

Три способа дать агенту данные о городе — и разница между ними не в скорости HTTP, а в том, кто превращает данные в инструмент. Разбираем, где каждый путь правильный.

13 мая 2025 г. ≈ 8 мин чтения
Короткий ответ обновляется ежедневно

Если вы строите ИИ-агента, который должен принимать решения про город, у вас три способа дать ему данные: обычный REST API, собственный краулинг и MCP-сервер. REST понятен человеку, но агенту от него мало толку: он отдаёт JSON и молчит о том, что это за инструмент и как им пользоваться. Свой краулер даёт максимум гибкости и столько же хрупкости. MCP-сервер с самого начала описывает инструмент так, чтобы агент сам понял, когда и как его звать. Это и есть разница между API для людей и API для агентов.

Дальше разберём, в чём она на самом деле и где каждый из трёх путей остаётся правильным выбором.

Почему агенту мало просто JSON-ответа

Начнём с вопроса, который звучит наивно, но за ним прячется вся суть. Чем плох обычный REST для агента? Он же возвращает чистый структурированный JSON, бери и пользуйся.

Проблема в том, что JSON — это ответ, а не инструмент. Когда человек работает с REST API, он сначала читает документацию: какие есть эндпоинты, какие параметры обязательные, что вернётся в ответе, какие лимиты. Вся эта работа происходит в голове разработчика и в его PDF-доке. К моменту, когда летит сам запрос, человек уже знает, что он делает.

У агента такой головы нет. Точнее, есть, но пустая по части вашего API. Чтобы LLM-агент мог сам решить вызвать инструмент, ему нужно машиночитаемое описание этого инструмента ещё до вызова: как инструмент называется, что он делает простыми словами, какие у него параметры и какого они типа, что именно он вернёт. Это называется tool definition, определение инструмента. Без него агент видит ваш эндпоинт примерно как вы видите кнопку без подписи на чужом пульте.

Вот наглядно, что меняется, когда описание появляется.

REST vs MCP // кто делает работу
Один запрос, два пути к нему
человек + REST логика — в голове разработчика
1 читает PDF-докуэндпоинты, параметры, лимиты — в голове
2 формирует REST-запросGET /v1/search?near=…&radius_m=500
3 парсит JSON глазамилогику держит человек
агент + MCP логику планирует сам агент
1 читает схему инструментаимя, параметры, типы, форма ответа этого нет у REST
2 сам формирует tool-callpoi.search(near, radius_m=500)
3 получает типизированный ответи планирует следующий шаг

Человеку хватает ответа, потому что логику он держит в голове. Агенту нужен дополнительный первый шаг — прочитать описание инструмента, по которому он планирует вызов сам. Это и есть тот блок, которого у REST нет.

Разберём по шагам, что внутри этого определения, потому что именно тут проходит граница между REST и MCP.

Tool definition // анатомия
Что агент знает об инструменте до вызова
name имя "poi.search" чтобы агент адресовал вызов только MCP
description описание "Поиск POI рядом с точкой по радиусу" чтобы решить, подходит ли инструмент только MCP
input_schema параметры + типы near: geo · radius_m: int ≤ 5000 чтобы подставить корректные аргументы только MCP
returns форма ответа name · category · rating · dist_m · open чтобы спланировать следующий шаг отдаёт REST
REST отдаёт человеку только форму ответа — остальное лежит в документации. MCP отдаёт агенту все четыре части сразу.

Имя нужно, чтобы агент адресовал вызов. Описание — чтобы он решил, подходит ли инструмент под задачу. Типы параметров — чтобы он подставил корректные аргументы. Форма ответа — чтобы он заранее знал, что получит, и спланировал следующий шаг. REST честно отдаёт только последний пункт, остальное оставляет человеку.

Путь первый: REST API

REST уже двадцать лет тянет на себе интеграции, и недооценивать его глупо. Эндпоинт, параметры в URL, JSON в ответе. Любой разработчик читает это с листа, инструментов вокруг море, кэширование и мониторинг отлажены индустрией.

Для агента у REST есть ровно одна, но большая проблема: он ничего не сообщает о себе. Схемы инструмента нет, типов параметров в машиночитаемом виде нет, описания назначения нет. Всё это лежит в документации для человека. Чтобы агент мог пользоваться REST API, кто-то должен вручную написать код-посредник: описать каждый эндпоинт как инструмент, задать параметры, разобрать формат ответа. Этот код-посредник потом надо держать в актуальном состоянии: поменялся ответ на стороне провайдера, и ваш маппинг тихо ломается.

То есть REST не то чтобы непригоден для агентов. Просто работу по превращению ответа в инструмент он перекладывает на вас. У нас в Омни Картах REST живёт как полноправная ветка доступа именно поэтому: он нужен не агентам, а всему, что вокруг них. О том, где именно, ниже.

Путь второй: собственный краулинг

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

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

Дальше начинается цена. Скрейпинг по своей природе хрупкий: сайт поменял вёрстку, и парсер отдаёт мусор или пустоту, и узнаёте вы об этом обычно по сломавшемуся агенту, а не заранее. Появляются прокси, лимиты, капчи, ретраи, всё это надо обслуживать. И главное, сырые собранные данные — это ещё не данные о городе. Их надо нормализовать, дедуплицировать и сводить, а это отдельная большая работа, про которую у нас есть целая статья. Самописный краулер прекрасно собирает строки. Он не превращает их в чистую базу с одной записью на каждый реальный бизнес. Эта часть остаётся на вас целиком, и она не разовая, а ежедневная.

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

Путь третий: MCP-сервер

MCP, Model Context Protocol, — это открытый протокол, через который инструменты описывают себя так, чтобы агент мог ими пользоваться без этого кода-посредника. Грубо говоря, это стандартный способ отдать LLM не только данные, но и определения инструментов разом.

Что меняется на практике. MCP-сервер отдаёт агенту те самые tool definitions из разбора выше: имя, описание, типы параметров, форму ответа. Агент подключается по URL и ключу, видит доступные инструменты и дальше сам решает, что и когда вызвать. У нас к нему подключены Claude, ChatGPT, GigaChat, YandexGPT и собственный стек, потому что протокол один, а модель за ним любая. Подключение занимает минуты, а не недели, и сводится к строке адреса с ключом, без написания клиента под каждый эндпоинт.

И сразу оговорка: сам по себе MCP данные не улучшает. Он решает задачу доставки и описания, а не качества. Если за сервером лежит грязная база, агент получит грязь, просто удобно описанную. У нас MCP отдаёт уже нормализованный слой, и тут он силён, но это заслуга пайплайна очистки, а не протокола. Не путайте упаковку с содержимым.

Один и тот же запрос двумя способами

Чтобы разница не звучала абстрактно, возьмём конкретную задачу: найти POI в радиусе 500 метров от точки.

Через REST это выглядит так. Человек, который пишет агента, заранее прочитал доку и знает структуру:

REST · GET /v1/search
GET /v1/search?near=55.764,37.595&radius_m=500
Authorization: Bearer YOUR_API_KEY
 
# ответ
{ "results": [
{ "name": "Кофемания", "category": "кафе",
"dist_m": 120, "rating": 4.7, "open": true },
...
] }

Запрос человека: эндпоинт, параметры и форму ответа надо знать заранее и описать агенту руками.

Запрос корректный и ответ чистый. Но агент сам по себе не знает, что такой эндпоинт существует, какие у него параметры и что radius_m в метрах. Всё это надо ему описать отдельно и руками.

Через MCP то же самое начинается не с запроса, а с описания инструмента, которое сервер отдаёт агенту заранее:

MCP · tool definition
# tool definition, которое видит агент
{
"name": "poi.search",
"description": "Поиск POI рядом с точкой по радиусу",
"input_schema": {
"near": { "type": "geo" },
"radius_m": { "type": "int", "max": 5000 }
},
"returns": ["name", "category", "rating", "dist_m", "open"]
}
 
# дальше агент сам формирует вызов
poi.search(near=parcel, radius_m=500)

Тот же запрос через MCP: агент сам читает описание инструмента, типы и форму ответа, а затем формирует вызов.

Тело запроса по сути то же. Но теперь агент пришёл к нему сам: прочитал описание, понял, что инструмент решает его задачу, увидел типы параметров, подставил аргументы, узнал из схемы, что radius_m не может быть больше 5000, и заранее знает форму ответа, чтобы построить следующий шаг. Разница не в синтаксисе вызова, а в том, кто проделал работу до него.

Чем три пути отличаются на самом деле

Если свести всё к одной мысли: способы отличаются не скоростью HTTP и не форматом JSON, а тем, кто берёт на себя работу по превращению данных в инструмент и по поддержанию их в порядке.

Три пути // кто берёт работу
REST · свой краулер · MCP
чем больше закрашенных точек, тем меньше работы остаётся на вашей стороне
REST Свой краулер MCP
Готовность к агенту
Скорость интеграции
Свежесть данных
Мало эксплуатации
Контроль над данными
источник изменился — чинит вы (маппинг)вы (парсеры)провайдер

Чем больше закрашенных точек, тем меньше работы остаётся на вашей стороне. У краулинга максимум контроля и максимум обслуживания, у MCP минимум ручной работы по настройке ценой того, что данные и схему держит провайдер. Нижняя строка — кто чинит, когда источник меняется.

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

Когда какой путь правильный

Теперь самое важное, без чего разбор был бы рекламой одного протокола.

MCP — это правильный выбор, когда в цепочке есть LLM-агент, который должен сам решать, какие инструменты звать. Если вы строите агента поверх Claude или GigaChat и хотите, чтобы он работал с городом, вручную описывать каждый REST-эндпоинт как инструмент — лишняя работа, которую MCP убирает.

REST остаётся правильным выбором в куче сценариев, где агента в цепочке нет вообще. BI-дашборд, который тянет данные по расписанию. Бэкенд приложения, который дёргает поиск POI по понятной бизнес-логике. Интеграция, где запрос формирует ваш код, а не модель. Тут описание инструмента для LLM просто не нужно, а привычность и предсказуемость REST это плюс. Поэтому в архитектуре Омни Карт REST и GraphQL стоят равноправной веткой рядом с MCP, а не под ним.

SQL и выгрузка датасета — это третья ветка, и она про совсем другое. Когда вам нужен не запрос в реальном времени, а весь слой целиком: положить в своё хранилище, посчитать аналитику офлайн, дообучить модель. Тут ни агент, ни REST не помощники, нужен прямой доступ к данным или скачивание. Это тоже законный и частый случай.

А собственный краулинг действительно имеет смысл в двух ситуациях. Первая: у вас есть источник, которого нет ни у одного провайдера, и собрать его можете только вы. Вторая: проект достаточно маленький, чтобы стоимость поддержки парсеров и нормализации была вам по карману, и вы сознательно платите за контроль. Во всех остальных случаях вы, скорее всего, переплачиваете обслуживанием за то, что кто-то уже сделал и держит в актуальном виде.

То есть выбор — это не лестница, где MCP сверху, а REST внизу. Это вопрос про то, что в цепочке принимает решения, есть ли там LLM, нужен ли вам поток или весь слой, и сколько обслуживания вы готовы взять на себя.

Что получилось в сухом остатке

Если убрать детали, картина такая. Агенту мало JSON-ответа, потому что ответ — это не инструмент, и для самостоятельной работы агенту нужно описание инструмента до вызова. REST такого описания не даёт и перекладывает эту работу на вас, зато идеален там, где LLM в цепочке нет. Свой краулер даёт контроль ценой хрупкости и постоянного обслуживания. MCP описывает инструмент сам, без ручного кода-посредника, и подключается за минуты, но качество данных за ним держит провайдер, не протокол.

У нас все три ветки доступа равноправны намеренно: MCP-сервер для агентов, REST и GraphQL для классических интеграций, SQL и выгрузка для хранилищ и офлайн-аналитики. 95% запросов отвечают быстрее 200 мс, и любой из путей идёт через единый ключ. Какой выбрать, зависит не от моды на протокол, а от того, кто на вашей стороне формирует запрос. На живой задаче выбора локации под бизнес мы показываем это в отдельном разборе.

FAQЧастые вопросы

MCP-сервер — это сервис, который отдаёт ИИ-агенту не только данные, но и описания инструментов: как инструмент называется, что делает, какие у него параметры и что он возвращает. Благодаря этому агент может сам решить, когда и как вызвать инструмент, без вручную написанного кода-посредника под каждый эндпоинт. MCP — это открытый протокол, поэтому один и тот же сервер работает с разными моделями.
REST отдаёт ответ, обычно JSON, но не описывает сам себя в машиночитаемом виде: чтобы агент мог пользоваться REST API, кто-то должен вручную описать каждый эндпоинт как инструмент. MCP отдаёт эти определения инструментов сразу, поэтому агент подключается и начинает работать без дополнительного кода с вашей стороны. Для интеграций без LLM в цепочке REST при этом остаётся удобнее.
JSON — это результат вызова, а не описание того, как вызывать. Чтобы LLM-агент сам выбрал инструмент и подставил правильные аргументы, ему нужно знать заранее: что инструмент делает, какие у него параметры, какие типы и границы у этих параметров, что вернётся в ответе. Эта информация и есть схема, или tool definition. Без неё агент не может планировать вызов сам.
Можно, и иногда это оправдано: если нужного источника нет у провайдеров или проект достаточно мал. Но краулинг хрупкий, требует постоянной поддержки парсеров и прокси, а собранные строки всё равно надо нормализовать и дедуплицировать самому. Плюс на вас ложатся лицензионные и правовые вопросы по источникам. Для большинства задач это дороже по обслуживанию, чем взять готовый слой.
Поскольку MCP — это протокол, а не привязка к конкретной модели, через него работают Claude, ChatGPT, GigaChat, YandexGPT и собственный стек. Подключение сводится к адресу MCP-сервера и ключу, после чего агент видит доступные инструменты. Те же данные доступны через REST и GraphQL для классических интеграций и через SQL или выгрузку датасета для хранилищ.
// Дальше читать

Из команды Омни Карт.

// Начать

Дайте агенту 1,73 млн чистых POI по Москве.

Запрос в реальном времени через API и MCP или скачивание датасета. Чистого, без дублей.

POIПЕШИЙ ТРАФИКАВТО-ТРАФИКНЕДВИЖИМОСТЬДЕМОГРАФИЯ