AI Agent · MCP

Почему AI Agent не может без JSON: Tool Calling, Function Calling и поток данных MCP

Почему AI Agents опираются на JSON для Tool Calling и MCP

Function Calling / Tool Calling / MCP JSON-RPC — четыре round-trip / диалекты схем / наблюдаемость и изоляция

Откройте Cursor, Claude Code или debug-лог любого Agent-фреймворка — почти каждый payload — JSON: каталоги инструментов — JSON Schema, tool_calls модели — JSON, фреймы MCP Server — JSON-RPC 2.0. Это не случайность — Agents должны соединить непредсказуемый естественный язык и исполняемые программные интерфейсы, и JSON — формат обмена, который обе стороны могут надёжно парсить.

Эта статья проходит Function Calling → Tool Calling → MCP и показывает четыре JSON round-trip полного вызова инструмента. Если вы разворачиваете MCP Server на облачном Mac или выбираете фреймворки из нашей подборки GitHub Agent, понимание этого потока при отладке полезнее, чем заучивание API-доков.

Agents говорят JSON почти везде

LLM выдают потоки токенов; Shell, базы данных и HTTP API нуждаются в структурированных аргументах. Ранняя практика — промпт «ответь в этом JSON-формате» — модели часто добавляли trailing commas, убирали кавычки или оборачивали в Markdown fences, и парсеры постоянно падали.

С 2023 года основные API перенесли структурированные действия в протокол: модель больше не свободно выдаёт произвольный JSON-текст; сервер ограничивает форму вывода, Host выполняет. Pipeline становится:

  • Declare — регистрация инструментов через JSON Schema;
  • Decide — выбор имени инструмента и параметров в ограниченной грамматике;
  • Execute — выполнение через локальный код или MCP Server;
  • Write back — записать результаты как JSON-сообщения в контекст.

Принцип проектирования: наблюдаемость Agent = логировать, воспроизводить и diff каждый JSON-шаг. Без структурированных промежуточных данных автоматизация не аудируема.

Function Calling: от естественного языка к структурированным действиям

Объект function эры OpenAPI

OpenAI добавил functions / tools в Chat Completions: вы присоединяете определения инструментов к запросу; модель возвращает function_call или tool_calls вместо текста, который нужно парсить regex.

Типичный фрагмент запроса

json
{
  "model": "gpt-4o",
  "messages": [{"role": "user", "content": "Погода в Токио?"}],
  "tools": [{
    "type": "function",
    "function": {
      "name": "get_weather",
      "description": "Текущая погода по городу",
      "parameters": {
        "type": "object",
        "properties": { "city": { "type": "string" } },
        "required": ["city"]
      }
    }
  }]
}

Ручные JSON-шаблоны в промптах заменяются ограничениями протокола; Host валидирует arguments по схеме и вызывает реальные функции. Function Calling фиксирует, что говорит модель — не где работают инструменты, как они находятся или как работает auth. Экосистемы Tool Calling и MCP берут это на себя.

Tool Calling: четыре JSON round-trip на turn

  1. Register — Host отправляет tools[] с JSON Schema в API модели;
  2. Decide — API возвращает tool_calls с id, name, arguments (JSON-строка);
  3. Execute — Host парсит аргументы и вызывает локальный код или MCP;
  4. Write back — сообщения role: tool возвращают результаты; модель формирует ответ пользователю.
json
{
  "tool_calls": [{
    "id": "call_abc123",
    "type": "function",
    "function": {
      "name": "get_weather",
      "arguments": "{\"city\":\"Tokyo\"}"
    }
  }]
}

argumentsстрока, не вложенный объект — для streaming и совместимости SDK. Hosts должны выполнить JSON.parse(arguments) перед валидацией. Нажмите Ctrl + Shift + I в DevTools и вы увидите ту же структуру в Network.

ЭтапНаправлениеPayloadПарсер
① RegisterHost → APItools[] + JSON SchemaAPI gateway
② DecideAPI → Hosttool_callsHost / SDK
③ ExecuteHost → ToolРаспарсенный объектРеализация инструмента
④ Write backHost → API{role:"tool", content:"..."}Модель

Диалекты API-схем

OpenAI / совместимые endpoints
tools + tool_choice; streaming использует chunks delta.tool_calls.
Anthropic
tools с input_schema; ответы — блоки tool_use и replies tool_result.
Google Gemini
functionDeclarations и functionCall с разными именами полей.
Ollama локально
OpenAI-совместимые tools; возможности зависят от обучения модели.

Фреймворки вроде LangGraph и DeepSeek Harness (см. наш гайд Harness) сжимают эти диалекты в одну абстракцию Tool — под ней всё равно JSON.

MCP: JSON-RPC стандартизирует слой инструментов

Model Context Protocol (MCP) находится ниже Function Calling: как процессы инструментов находятся, параметризуются и переиспользуются между Hosts. Транспорт может быть stdio или SSE, но сообщения всегда JSON-RPC 2.0.

СлойПротоколПримеры
Model APIREST / OpenAI-совместимыйchat/completions + tools
MCPJSON-RPC 2.0tools/list, tools/call
BusinessЛюбойфайлы, DB, HTTP

Hosts вызывают tools/list при старте, переводят каталоги в API tools[], затем отправляют tools/call после решения модели — две конвертации диалекта, один семантический pipeline.

json
{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/call",
  "params": {
    "name": "read_file",
    "arguments": { "path": "/tmp/demo.txt" }
  }
}
Как разделяются JSON-фреймы в режиме stdio?

MCP stdio использует заголовки Content-Length + JSON body (как LSP), не newline-delimited JSON. Большие payload (например base64-ресурсы) помещаются в один фрейм. SSE оборачивает JSON-RPC в HTTP event streams для multi-client Servers.

Полный поток данных: от ввода пользователя до выполнения

Диаграмма потока данных JSON для Agent Tool Calling
От ввода пользователя до выполнения MCP — каждый шаг можно логировать и воспроизводить.
  • Логи фиксируют каждую версию tools/list и число инструментов?
  • arguments валидируются по схеме перед выполнением?
  • Таймауты MCP мапятся на читаемые сообщения tool?
  • Секреты удаляются перед логированием?

Та же идея, что этап Verify в нашем AI Coding Workflow: без parseable промежуточных данных вы не можете автоматически проверить, что Agent действительно вызвал правильный инструмент.

Почему не Protobuf или XML?

  • API моделей — JSON-first; бинарные форматы добавляют слои сериализации;
  • Отладка — инженеры читают параметры в логах;
  • Экосистема схем — JSON Schema и OpenAPI — де-факто стандарты;
  • Скрипты и браузеры — curl, n8n, front-end демо предполагают JSON.

Tradeoff: размер и CPU. High-QPS setups кэшируют внутри и сжимают логи; большие blob идут base64 внутри JSON-полей — не заменяя JSON envelope.

Затраты JSON и инженерные решения

СимптомПричинаРешение
arguments parse errorНевалидная JSON-строка от моделиСтроже схема, ниже temperature, retry
Неверный инструментРазмытые или слишком много описанийОбъединить инструменты, негативные примеры
MCP зависаетНеполный stdio-фрейм или мёртвый процессlaunchd supervisor, health checks
Секреты в логахРезультат инструмента включает env varsRedact результаты, отдельный execution account

Совет для production: запускайте MCP на изолированном облачном Mac — Cursor на ноутбуке отправляет JSON-RPC через SSH; Shell никогда не живёт на вашей повседневной машине.

Agents зависят от JSON, потому что решения в естественном языке и программное выполнение нуждаются в человекочитаемом, машинно-валидируемом, подключаемом контракте. Function Calling определяет, что говорит модель; Tool Calling — как Host выполняет turn; MCP — как процессы инструментов подключаются к экосистеме — JSON — нить через все три.

Запустите JSON execution plane MCP на облачном Mac

Выделенные узлы M4, дневная тарификация, SSH готов

Сингапур · Япония · Корея · Гонконг · регионы US

Разместите tools/call на изолированном облачном Mac; локальный Host только передаёт JSON-RPC. Смотреть тарифы ZekVPS Mac mini

Акция