# ГЛАВА 11. НЕ ЗАСТАВЛЯЙ МОДЕЛЬ СЧИТАТЬ — ДАЙ ЕЙ ИНСТРУМЕНТ

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

LLM — именно такой лингвист. Просить модель считать — это как просить переводчика доказывать теоремы: он понимает *слова* в формулах, но не выполняет *операции*. Решение очевидно: дай лингвисту калькулятор. Code Interpreter или любой другой **code execution sandbox** — это и есть калькулятор. А в более широком смысле, инструменты (tools) превращают LLM из одинокого эрудита в **менеджера, который знает ЧТО нужно сделать и делегирует КАК — специалистам**: Python считает, база данных ищет, API действует.

Эта глава — о том, почему делегирование работает, и как выстроить архитектуру, в которой модель управляет, а не считает.

---

## 11.1. Почему LLM плохо считают: числовые отношения vs точная арифметика

### Корень проблемы: токенизация чисел

Как мы выяснили в [Главе 1](01_tokens_vectors_and_semantic_space.md), числа токенизируются как текстовые фрагменты, а не как математические объекты:

```
"247 × 13" → ["247", " ×", " 13"]  — три текстовых токена
```

Модель не имеет арифметического блока. Она не выполняет умножение. Она **предсказывает**, какие цифры скорее всего следуют за последовательностью `247 × 13 = `. Это принципиально разные операции.

### Что модель может

| Задача | Надёжность | Механизм |
|--------|------------|----------|
| Сравнение порядков величин | Хорошо | Статистические ассоциации (`миллион > тысяча`) |
| Простая арифметика (2 + 3) | Хорошо | Заучено из тренировочных данных |
| Умножение 2–3-значных | Ненадёжно | Частично заучено, частично угадывает |
| Умножение 4+ -значных | Плохо | Недостаточно примеров, вероятностная аппроксимация |
| Проценты и дроби | Ненадёжно | Путает числитель/знаменатель |
| Статистические расчёты | Плохо | Нет арифметического блока |
| Float precision | Плохо | `0.1 + 0.2` может дать `0.3` или `0.30000000000000004` |

### Эксперимент: момент истины

Попробуйте прямо сейчас. Откройте любой чат с LLM **без** Code Interpreter и спросите:

```
"Вычисли 7823 × 4291"
```

Верный ответ: **33 568 493**.

Модель ответит что-то вроде: `33 571 993` — ошибка на три тысячи. Выглядит правдоподобно, начинается с тех же цифр, но это не результат вычисления — это **статистическая галлюцинация**. Модель предсказала, какие цифры вероятнее всего идут после `7823 × 4291 =`, точно так же, как она предсказывает следующее слово в предложении.

Теперь задайте тот же вопрос модели, у которой включён инструмент выполнения кода:

```python
print(7823 * 4291)  # → 33568493 ✓
```

Каждый раз — точный ответ. Не потому что модель стала умнее, а потому что она **делегировала**: написала однострочник на Python и отдала его интерпретатору. Лингвист взял калькулятор.

Усложним: `"Посчитай (7823 × 4291) + (1597 × 863) − 42.7%"`. Без инструмента модель сфантазирует уверенный, но неверный ответ. С Python — выдаст точный результат с промежуточными шагами. Вот почему **Code Interpreter — не фича, а необходимость**.

---

## 11.2. PAL и Tool Use: делегируй вычисление

### PAL: Program-Aided Language Models (пошаговый разбор)

PAL (Gao et al., 2023) — идея элегантна в своей простоте: вместо того чтобы решать задачу самостоятельно, LLM генерирует **программу**, которая решает задачу за неё. Модель остаётся в своей зоне силы — понимание языка и генерация кода, — а вычисления уходят туда, где им место: в интерпретатор.

Разберём по шагам:

**Шаг 1. Входная задача на естественном языке:**
```
"В магазине было 48 яблок. Продали 1/3. Потом привезли ещё 20. Сколько яблок?"
```

**Шаг 2. Модель транслирует текст в код** (это её сильная сторона — понимание текста):
```python
apples = 48
sold = apples // 3  # "продали 1/3" → 16
remaining = apples - sold  # "осталось" → 32
delivered = 20  # "привезли ещё 20"
total = remaining + delivered
print(total)  # → 52
```

**Шаг 3. Python выполняет код** и возвращает: `52`

**Шаг 4. Модель формулирует ответ:** «В магазине 52 яблока.»

Обратите внимание: на шагах 1, 2 и 4 работает LLM (язык → код → язык). На шаге 3 — Python (арифметика). Каждый делает то, в чём силён.

**Почему PAL надёжнее, чем Chain-of-Thought арифметика:**
- Каждый шаг фиксирован в коде — нет скрытых ошибок рассуждения.
- Арифметика выполняется Python, а не нейронной сетью.
- Промежуточные значения видимы для отладки.
- Код можно проверить ревьюером — или другой LLM.

### Паттерн: Code Interpreter / code execution

К 2026 году выполнение кода перестало быть экзотикой, но важно различать **три разные вещи**:

1. **Потребительский продукт** (например, ChatGPT с Advanced Data Analysis).
2. **API tool** (например, `code_interpreter` у OpenAI или `code_execution` у Anthropic/Gemini).
3. **Локальный оркестратор** (ваш sandbox, Docker, локальный Python, bash tool).

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

Через API схема остаётся явной — вы определяете инструмент в JSON Schema, модель его вызывает. У OpenAI это `tools` с `type: "function"` в Responses API; у Anthropic — `tools` с `input_schema`; у Gemini — `function_declarations`. Все три провайдера используют JSON Schema для описания параметров — определения инструментов фактически переносимы между платформами, а MCP делает эту переносимость стандартом (подробнее — в §11.4).

> **Промпт для генерации:** «Напиши определение tool use-инструмента `execute_python` для [Anthropic Messages API / OpenAI Responses API] — инструмент принимает строку с Python-кодом и возвращает stdout/stderr. Добавь `input_schema` / `parameters` с JSON Schema и обязательное поле `code`. Покажи, как передать этот инструмент в вызов API и как обработать `tool_use` / `tool_calls` в ответе.»

Модель **сама** решает, когда вызвать code execution:
- Простой факт → ответ из памяти.
- Вычисление → генерирует Python, запускает, возвращает результат.
- Визуализация → matplotlib, возвращает изображение.
- Работа с файлами → читает CSV/JSON, обрабатывает, строит графики.

**Function calling / tool use стал стандартным интерфейсом, но не единым рантаймом.** OpenAI, Anthropic и Google поддерживают структурированные tool-вызовы, а open-weight экосистема научилась их эмулировать через frameworks. Но схемы, approval-flow, JSON-валидация и способность надёжно выбирать нужный инструмент всё ещё отличаются по платформам и моделям.

### Четыре типа инструментов

Инструменты делятся по характеру действия. Это важно для архитектуры — разные типы требуют разных уровней доверия:

**1. Вычисление (computation)** — чистые функции без побочных эффектов:
| Задача | Инструмент | Почему не LLM |
|--------|-----------|---------------|
| Арифметика | Python / Calculator | Нет arithmetic head |
| Regex | `re` module | Сложные regex → ошибки при генерации |
| Форматирование | `json.dumps`, `yaml.dump` | Гарантированная структура |
| Статистика | numpy / pandas | Точность floating point |

**2. Получение данных (data retrieval)** — только чтение, без изменений:
| Задача | Инструмент | Почему не LLM |
|--------|-----------|---------------|
| Поиск фактов | RAG / Web Search | Параметрическая память устаревает |
| SQL-запросы | База данных (SELECT) | Модель может ошибиться в JOIN |
| Дата/время | `datetime` / API | Модель не знает «сегодняшнюю» дату |
| Файлы (чтение) | File system API | Модель не видит файловую систему |

**3. Действия (write/mutate)** — изменения во внешнем мире (требуют подтверждения!):
| Задача | Инструмент | Риск |
|--------|-----------|------|
| Отправка email | SMTP API | Необратимо |
| Запись в БД | INSERT/UPDATE | Изменяет данные |
| Создание задачи | Jira / Linear API | Видно команде |
| Деплой | CI/CD API | Влияет на production |

**4. Коммуникация (communication)** — взаимодействие с пользователями и системами:
| Задача | Инструмент | Особенность |
|--------|-----------|------|
| Уведомления | Slack / Teams API | Проверьте тон и содержание |
| Ответ пользователю | Chat UI | Финальный этап цепочки |
| Логирование | Observability API | Для отладки и аудита |

**5. Управление компьютером (computer use)** — прямое взаимодействие с графическим интерфейсом:
| Задача | Инструмент | Особенность |
|--------|-----------|------|
| Действия в браузере | Browser automation / Operator | Навигация, заполнение форм, скриншоты |
| Взаимодействие с десктопом | Screenshot + mouse/keyboard | Управление приложениями без API |
| Тестирование UI | Computer Use API | Воспроизведение пользовательских сценариев |

Computer use — качественно новый тип инструмента, появившийся в production-доступе в 2025–2026. В отличие от четырёх предыдущих типов, модель взаимодействует не через API, а через **визуальный интерфейс**: делает скриншот экрана, анализирует его и отправляет команды мыши и клавиатуры. Anthropic предоставляет computer use в бета-режиме (`computer_20251124`), OpenAI — как встроенный инструмент для GPT-5.4 (75 % на бенчмарке OSWorld-Verified).

**Требования к безопасности** у computer use выше, чем у любого другого типа инструментов. Модель видит содержимое экрана — а значит, уязвима к prompt injection через визуальный контент (текст на странице, изображения с инструкциями). Используйте изолированное окружение (Docker, VM) и ограничивайте доступ к чувствительным приложениям.

**Правило большого пальца:** вычисление и чтение — автоматически, действия и коммуникацию — с подтверждением человека (human-in-the-loop). Computer use — всегда с подтверждением и в sandbox.

---

## 11.3. Популярные технологии надёжнее экзотических

### Принцип: ищите не "магическую библиотеку", а кросс-вендорное пересечение

Точный состав тренировочных данных закрытых frontier-моделей мы не видим. Поэтому фразу «эта библиотека точно была в train set у всех вендоров» нельзя честно доказывать по публичным данным. Но есть более надёжный инженерный proxy: **официальные runtime-документы самих платформ**. Когда OpenAI, Anthropic и Gemini независимо сходятся на одном и том же short list для code execution, это сильный сигнал, что именно этот стек будет и доступен, и хорошо поддержан пост-обучением, и привычен модели в инструментальном режиме.

Самое важное наблюдение 2025–2026 годов: у Python-sandbox стеков разных провайдеров действительно есть большое пересечение. Повторяются одни и те же категории: табличная обработка, численные вычисления, графики, файлы Office/PDF, базовая статистика и символьная математика.

### Сверхстабильный short list для Python sandbox

| Категория | Первый выбор | Когда использовать | Почему это надёжно |
|-----------|--------------|--------------------|--------------------|
| **Табличные данные** | `pandas` | CSV, Excel, groupby, joins, cleanup | Официально подтверждён у OpenAI; также входит в sandbox Anthropic и Gemini |
| **Графики** | `matplotlib` | Линейные, столбчатые, scatter, отчётные chart'ы | OpenAI прямо говорит про Matplotlib; Gemini поддерживает только `matplotlib` для graph rendering |
| **Численные вычисления** | `numpy`, `scipy` | массивы, статистика, оптимизация, scientific helpers | Есть в Anthropic и Gemini; это де-факто базовый численный слой Python |
| **Excel I/O** | `openpyxl` | читать/писать `.xlsx`, править workbook'и | Повторяется в Anthropic и Gemini |
| **Базовая статистика и ML** | `scikit-learn`, `statsmodels` | регрессии, baseline-классификация, простые метрики | Явно перечислены в Anthropic; `scikit-learn` также есть у Gemini |
| **Символьная математика** | `sympy` | формулы, уравнения, algebraic manipulation | Есть в Anthropic и Gemini |
| **Документы и отчёты** | `python-docx`, `python-pptx`, `reportlab` | DOCX/PPTX/PDF-артефакты | Anthropic и Gemini публикуют похожий набор |
| **Файлы и изображения** | `pillow`, `pypdf`/`PyPDF2` | изображения, PDF, file transformations | Стабильная часть sandbox-экосистемы Anthropic и Gemini |

Это не строгая теорема про training mix, но очень полезная operational policy: если агент может решить задачу на этом short list, почти всегда стоит начать именно с него.

### JS и artifact-side: React как безопасный первый выбор

На JavaScript-стороне картина менее симметрична, потому что многие платформы выполняют код именно в Python, а не в Node.js sandbox. Но для Claude есть очень явный сигнал: в официальной документации по Artifacts среди типовых результатов и AI-powered UI прямо фигурируют **interactive React components** и rich UIs with React. Поэтому для browser-side прототипов, мини-инструментов и UI-обвязки вокруг модели разумный default — **React-first**, а не экзотический frontend-стек.

Практический перевод этого наблюдения простой: если ваша цель — быстро получить рабочий AI-артефакт или интерактивный инструмент, React почти всегда безопаснее, чем niche framework с маленьким следом в экосистеме.

### Вне песочницы действует тот же принцип

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

| Технология | Представленность в открытой экосистеме | Качество генерации |
|------------|----------------------------------------|-------------------|
| Python + `requests` / `httpx` | Очень высокая | Отлично |
| JavaScript + `fetch` | Очень высокая | Отлично |
| SQL (PostgreSQL, MySQL) | Очень высокая | Хорошо |
| Go + `net/http` | Высокая | Хорошо |
| Rust + `tokio` | Высокая и растущая | Хорошо |
| Terraform / Kubernetes YAML | Высокая | Хорошо |
| React / Next.js | Очень высокая | Хорошо |
| Elixir + Phoenix | Умеренная | Средне |
| Zig / V / Nim | Низкая | Ненадёжно |
| Кастомный DSL | Почти нулевая | Плохо без few-shot и валидации |

### Как определить preferred stack в новой среде

1. **Смотрите официальные docs runtime-а**, а не только бенчмарки модели. Если платформа перечисляет preinstalled libraries или официальные способы рендеринга, это сильнее догадок о train set.
2. **Ищите пересечение между провайдерами.** Чем больше overlap у OpenAI, Anthropic, Gemini и похожих сред, тем выше шанс, что решение будет переносимым.
3. **Отмечайте библиотеки из официальных примеров.** Если документация снова и снова показывает `pandas`, `matplotlib` и `React`, это хороший сигнал для default choice.
4. **Проверяйте sandbox-ограничения.** Например, Gemini разрешает много библиотек, но для графиков официально поддерживает именно `matplotlib`; значит, `matplotlib-first` — не эстетический выбор, а operational constraint.

### Как использовать short list эффективно

1. В system prompt или project rules явно пишите: **"сначала решай задачу на standard stack"**.
2. Для таблиц начинайте с `pandas`; переходите к `numpy`/`scipy`, только если нужен более низкий уровень математики.
3. Для графиков default = `matplotlib`, если вам важна переносимость между sandboxes.
4. Для Excel используйте `openpyxl`, а не малоизвестные обёртки.
5. Для символьных задач используйте `sympy`, а не самодельный парсер формул.
6. Для AI-артефактов и UI-прототипов в Claude задавайте React как предпочтительный frontend.
7. Разрешайте переход на niche library только после короткого объяснения, почему short list недостаточен.

> **Практический policy-prompt:** «При работе в sandbox предпочитай следующий стек по умолчанию: `pandas`, `matplotlib`, `numpy`, `scipy`, `openpyxl`, `scikit-learn`, `sympy`, `pillow`, `python-docx`, `python-pptx`, `reportlab`. Сначала предлагай решение на этом стеке. Переход на нишевую библиотеку допускается только если ты кратко объяснил, почему standard stack не покрывает задачу. Для UI-артефактов предпочитай React.»

### Практические рекомендации

1. **Python + стандартная библиотека + short list** — первый выбор для вычислений и data tasks.
2. **`ast` + sandbox** — для безопасного выполнения сгенерированного кода.
3. **Стандартные API** (REST, GraphQL) — для интеграций.
4. **Проверенные библиотеки** (`pandas`, `numpy`, `openpyxl`, `matplotlib`) — раньше кастомных обёрток.
5. **Фреймворки оркестрации** (LangChain Tools, LlamaIndex Tools, Anthropic tool use, OpenAI Responses API) — стандартные паттерны вместо велосипедов.

> **Промпт для генерации песочницы:** «Напиши Python-функцию `safe_execute(code: str) -> (stdout, stderr)` для безопасного выполнения LLM-сгенерированного кода. Требования: (1) AST-проверка — запретить import os/subprocess/shutil/sys и вызовы exec/eval/\_\_import\_\_; (2) ограниченный `__builtins__` — только print, range, len, числовые типы, коллекции, sorted, enumerate; (3) перехват stdout через StringIO; (4) timeout через signal или threading. Для production предпочтительнее Docker/VM-песочница или серверный инструмент (`code_execution` у Anthropic, `code_interpreter` у OpenAI).»

---

## 11.4. Экосистема MCP: как модели получили доступ ко всему

### Что такое MCP

Model Context Protocol (MCP) — открытый стандарт, который позволяет LLM подключаться к внешним инструментам через единый интерфейс. Если function calling — это способность модели вызывать функции, то MCP — это стандартизация того, **как эти функции обнаруживаются, описываются и вызываются**. Думайте о нём как о USB для AI: один разъём, много устройств.

MCP создан Anthropic в конце 2024 года, но к 2025 году перешёл под управление **Linux Foundation** (LF Projects, LLC) и управляется MCP Steering Group. Текущая версия спецификации — `2025-11-25`. Протокол построен на JSON-RPC 2.0 и поддерживает два транспорта: **STDIO** (локальный процесс, без сетевых задержек) и **Streamable HTTP** (удалённые серверы, поддержка OAuth-аутентификации).

MCP-сервер предоставляет клиенту три типа примитивов:
- **Tools** — вызываемые функции (discovery через `tools/list`, исполнение через `tools/call`).
- **Resources** — источники данных для контекста (файлы, БД, API).
- **Prompts** — переиспользуемые шаблоны взаимодействия.

Базовая концепция MCP и её связь с агентным контуром рассмотрены в [Главе 10](10_agent_not_chat.md). Здесь мы сосредоточимся на экосистеме, нативной поддержке в API и принципах выбора серверов.

### Нативная поддержка MCP в API провайдеров

Ключевое событие 2025–2026: оба крупнейших провайдера встроили MCP-клиент прямо в свои API. Это значит, что один MCP-сервер, написанный один раз, работает и с Claude, и с ChatGPT, и с VS Code, и с десятками других клиентов.

| Провайдер | Механизм | Что поддерживается |
|-----------|----------|-------------------|
| **OpenAI** | `type: "mcp"` в Responses API | Удалённые MCP-серверы (Streamable HTTP, SSE). Connectors — готовые MCP-обёртки для Dropbox, Gmail, Google Drive, Outlook, Teams, SharePoint и др. |
| **Anthropic** | MCP Connector в Messages API (бета-заголовок `mcp-client-2025-11-20`) | Удалённые MCP-серверы по URL. Пока только tool calls (не resources/prompts через API). |
| **VS Code / Copilot** | Встроенная поддержка MCP-серверов | Локальные и удалённые серверы, конфигурация в settings |
| **Cursor, Claude Code** | Конфигурация MCP-серверов | Поддержка STDIO и HTTP транспортов |

Не все клиенты поддерживают все примитивы — в production проверяйте transport, approval-flow и security-модель конкретного клиента.

### Экосистема MCP-серверов в 2026 году

К апрелю 2026 года экосистема MCP взрывно выросла: 80 000+ звёзд на GitHub, 100+ официальных интеграций, 10+ SDK на разных языках (официальные: TypeScript, Python; community: Java, Kotlin, Go, Rust, C#, Ruby, PHP, Swift).

| Категория | Примеры MCP-серверов | Что даёт модели |
|-----------|----------------------|------------------|
| Базы данных | PostgreSQL, SQLite, MongoDB, Snowflake | Чтение/запись данных |
| API и SaaS | GitHub, Slack, Jira, Linear, Stripe | Управление проектами и сервисами |
| Файловые системы | Локальные файлы, Google Drive, S3 | Чтение/запись файлов |
| Инфраструктура | Kubernetes, Docker, AWS, Cloudflare | Управление инфраструктурой |
| Поиск | Brave Search, Google, Exa | Веб-поиск в реальном времени |
| Разработка | Git, терминал, LSP, Firebase | Работа с кодом и репозиториями |
| Мониторинг | Sentry, Datadog, Grafana | Анализ логов и метрик |

Для создания собственных MCP-серверов существуют фреймворки: FastMCP, Spring AI MCP, Quarkus MCP, Vercel MCP Adapter — и даже автогенераторы из OpenAPI-спецификаций (FastAPI-to-MCP).

### Как найти нужный MCP-сервер

- **MCP реестр** (modelcontextprotocol.io) — каталог проверенных серверов, управляемый MCP Steering Group.
- **GitHub** — поиск по `topic:mcp-server`.
- **npm / PyPI** — пакеты с префиксом `mcp-server-*`.
- **OpenAI Connectors** — готовые интеграции для популярных SaaS (не требуют отдельного MCP-сервера).

### A2A: протокол для взаимодействия агентов

MCP решает задачу «агент ↔ инструмент». Но что если нужно, чтобы **агент взаимодействовал с другим агентом** — например, агент-планировщик делегирует подзадачу агенту-исполнителю на другом сервере?

Для этого Google предложил **A2A (Agent-to-Agent Protocol)** — протокол обнаружения и коммуникации между автономными агентами. A2A и MCP не конкурируют, а дополняют друг друга: MCP стандартизирует доступ к инструментам и данным, A2A — оркестрацию между агентами. Существует «A2A MCP Server» — мост, позволяющий MCP-клиенту вызывать A2A-агентов как обычные инструменты.

В production-системах с несколькими специализированными агентами стоит рассматривать связку MCP + A2A. Для систем с одним агентом и набором инструментов — достаточно MCP.

### Пример: как модель использует MCP

```
Пользователь: "Какие баги были заведены на этой неделе?"

Модель (думает): Нужна информация из Jira → вызову MCP-сервер Jira
Модель → MCP Jira: tools/call search_issues(type="Bug", created_after="2026-04-03")
MCP Jira → Модель: [список из 12 багов с ключами, статусами, assignee]
Модель → Пользователь: "На этой неделе заведено 12 багов, из них 3 критичных..."
```

Модель выступила менеджером: поняла запрос, выбрала нужный инструмент, сформулировала параметры и пересказала результат человеческим языком.

---

## 11.5. Принципы проектирования инструментов

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

### 1. Имя: глагол + существительное

```
✓ search_issues, create_user, get_file_contents, run_sql_query
✗ do_thing, helper, process, handle  ← модель не поймёт, когда вызывать
```

### 2. Описание: когда использовать, а не только что делает

```
✗ Плохое описание:
"description": "Search for issues"          ← какие issues? когда?

✓ Хорошее описание:
"description": "Search Jira issues by type, status, assignee, or date range.
                Use when the user asks about bugs, tasks, or project progress.
                Returns issue key, title, status, and assignee."
```

### 3. Параметры: строгая типизация + enum где возможно

```
✗ Модель будет гадать формат:
"date": {"type": "string"}

✓ Формат явный:
"date": {"type": "string", "format": "date", "description": "ISO 8601: YYYY-MM-DD"}
"status": {"type": "string", "enum": ["open", "in_progress", "closed"]}
```

### 4. Меньше инструментов — лучше

Каждый инструмент в списке — это токены в контексте. 5–15 инструментов — оптимально. 50+ — модель начнёт путаться и выбирать не тот. Лучше один инструмент `search_database(query, table)`, чем десять `search_users`, `search_orders`, `search_products`...

**Tool search: масштабирование за 15 инструментов.** Правило «5–15 инструментов» работает при передаче всех определений в контекст. Но в MCP-экосистемах с десятками серверов и сотнями инструментов это ограничение становится проблемой. GPT-5.4 (OpenAI, март 2026) ввёл **tool search** — механизм, при котором модель получает лёгкий индекс инструментов (имя + краткое описание), а полные определения подгружает по запросу. По данным OpenAI, tool search снизил потребление токенов примерно вдвое при сохранении accuracy на внутреннем бенчмарке с десятками MCP-серверов (детали методологии не опубликованы).

Если вы строите систему с большим числом MCP-серверов — проверьте, поддерживает ли ваш клиент lazy tool loading. Это реальный рычаг снижения стоимости inference в агентных контурах.

### 5. Возвращайте структурированные данные, не прозу

Модель лучше работает с JSON, чем с произвольным текстом. Возвращайте `{"count": 12, "critical": 3, "items": [...]}`, а не `"Found 12 bugs, 3 critical"`.

---

## 11.6. Шкала важности 1–10: используйте для ранжирования, не для метрик

### Проблема с абсолютными числами

Когда вы просите модель: «Оцени важность по шкале от 1 до 10», она возвращает число. Но это число **не калибровано**: модель не имеет внутренней шкалы, привязанной к реальности.

```
Промпт: "Оцени серьёзность бага по шкале 1-10"
Баг: "Опечатка в логе" → Модель: "3"
Баг: "SQL injection" → Модель: "9"
Баг: "Race condition в платёжном модуле" → Модель: "8"
```

Проблема: **8 vs 9** — значимая разница? Или модель просто случайно выбрала числа? При повторном запуске может быть 7 и 8 или 9 и 9.

### Когда числовые оценки полезны

**Для ранжирования** (relative ordering): модель стабильно ставит SQL injection выше опечатки. Порядок надёжнее абсолютных значений.

**Для категоризации** (binning): `1–3 = low`, `4–7 = medium`, `8–10 = high`. Широкие бины устойчивы к шуму.

### Когда использовать инструменты вместо оценок

| Задача | LLM-оценка | Инструмент |
|--------|------------|-----------|
| «Насколько сложен код?» | Субъективно | Cyclomatic complexity (radon) |
| «Насколько длинный текст?» | Угадывает | `len(text.split())` |
| «Какой прирост производительности?» | Не может | Benchmark (timeit) |
| «Уязвим ли код?» | Может пропустить | SAST tools (semgrep, bandit) |
| «Соответствует ли API стандарту?» | Неточно | Schema validator |

---

## 11.7. Архитектура: LLM как менеджер, не исполнитель

### Правильная ментальная модель

LLM — это менеджер, который прекрасно понимает, ЧТО нужно сделать, но не должен делать всё сам. Как хороший руководитель, он делегирует КАК специалистам:

```
LLM = Менеджер (понимание задачи, планирование, коммуникация)
Python = Бухгалтер (вычисления)
БД    = Архивариус (поиск данных)
API   = Курьер (действия во внешнем мире)
```

LLM решает **что** делать и **почему**. Tools выполняют **как**:

```
┌─────────────────────────────┐
│           LLM               │
│  "Нужно посчитать налог"    │
│  → Сгенерировать Python     │
│  → Результат: $12,450       │
│  → Сформировать ответ       │
└───────────┬─────────────────┘
            │ tool call
            ▼
┌─────────────────────────────┐
│     Python Executor         │
│  income = 85000             │
│  tax = income * 0.22        │
│  deductions = 6300          │
│  total = tax - deductions   │
│  → return 12450.0           │
└─────────────────────────────┘
```

### Anti-pattern: заставлять LLM быть калькулятором

```
✗ "Посчитай стоимость 247 единиц товара по $13.99 каждая, 
    с НДС 20%, скидкой 5% для объёма > 200 единиц"

✓ "Сгенерируй Python-код для расчёта стоимости:
    - Количество: 247
    - Цена за единицу: $13.99
    - НДС: 20%
    - Скидка: 5% (при объёме > 200)
    Выведи промежуточные значения и финальную сумму."
```

---

## 11.8. Computer use и browser automation

### Сдвиг парадигмы: от API к UI-действиям

Не все системы имеют API. Legacy-приложения, внутренние порталы, сторонние SaaS без публичного интерфейса — единственный способ автоматизации для них — это взаимодействие с графическим интерфейсом. Computer use (Anthropic) и browser automation (OpenAI Operator, Playwright-based агенты) превращают GUI в ещё один tool surface.

Важно: это **не** screen scraping и не macro-recording. Модель анализирует скриншот, распознаёт элементы интерфейса, принимает решение о следующем действии на основе текущего визуального состояния. Каждый шаг — полноценный inference-вызов с reasoning, а не воспроизведение записанного сценария.

В §11.2 мы выделили computer use как пятый тип инструментов. Здесь — инженерная механика: как это работает, где ломается и когда стоит применять.

### Механика: screenshot → perception → action

Цикл computer use повторяет стандартный agent loop ([Глава 10](10_agent_not_chat.md)), но вместо JSON-ответа от API модель получает **изображение** экрана:

1. **Screenshot** — агент делает снимок экрана (или окна браузера) и передаёт его модели как изображение.
2. **Perception** — vision-capable модель анализирует скриншот: распознаёт кнопки, поля ввода, текст, меню.
3. **Action** — модель возвращает действие: `click(x, y)`, `type("text")`, `scroll(direction)`, `key("Enter")`.
4. **Re-screenshot** — после выполнения действия делается новый скриншот, и цикл повторяется.

Две ключевые проблемы механики:

- **Coordinate scaling.** Координаты клика зависят от разрешения скриншота. Если скриншот сделан в одном разрешении, а действие выполняется в другом — промах мимо элемента. Решение: фиксированное разрешение скриншотов и нормализация координат.
- **Нестабильность UI.** Интерфейс — живая система: появляются popup-окна, элементы перемещаются после загрузки, страница перерисовывается. Нужна retry-логика с повторным скриншотом и переоценкой ситуации.

### Инженерные проблемы

| Проблема | Суть | Решение |
|----------|------|--------|
| Sandboxing | Агент имеет доступ ко всему экрану — файлы, пароли, другие приложения | Запуск в изолированной VM или контейнере с минимальным набором приложений |
| Prompt injection через UI | Вредоносный контент на странице может перенаправить агента (текст, изображение с инструкцией) | Фильтрация OCR-контента, ограничение доменов, мониторинг отклонений от плана |
| Coordinate scaling | Разрешение скриншота ≠ разрешение экрана → промахи | Фиксированное разрешение, калибровка координат |
| Approval gates | Необратимые действия: удаление данных, оплата, отправка сообщений | Human-in-the-loop checkpoint перед каждым destructive action |
| End-to-end верификация | Как убедиться, что действие выполнено корректно | Post-action screenshot → LLM-верификация результата |
| Observability | Отладка GUI-автоматизации значительно сложнее отладки API-вызовов | Запись видео сессии, логирование каждого шага с скриншотом и action |

### Когда использовать, а когда нет

**Используй computer use, когда:**
- Нет API (legacy-система, внутренний портал, сторонний SaaS).
- Нужна визуальная верификация (проверить, что UI отображает правильные данные).
- End-to-end тестирование пользовательских сценариев.
- Прототипирование автоматизации до появления API-интеграции.

**НЕ используй, когда:**
- Есть API — он всегда предпочтительнее по скорости, надёжности и стоимости.
- Нужна высокая скорость — каждый шаг computer use требует inference-вызов + screenshot.
- Нужна надёжность >99% — GUI нестабилен, элементы смещаются, появляются рекламные баннеры.
- Обрабатываются чувствительные данные без возможности изолировать окружение.

### Безопасность

Computer use — самый рискованный тип инструмента из пяти, описанных в §11.2. Модель видит содержимое экрана целиком и может выполнять произвольные действия с клавиатурой и мышью. Ключевое правило: **computer use agent работает в sandbox с минимальными привилегиями**. Не давайте доступ к production-системам без approval gate.

Подробный разбор атак на computer use — включая визуальный prompt injection, click-jacking через UI-элементы и эксфильтрацию данных через скриншоты — в [Главе 15](15_llm_system_security.md), секции 15.5–15.6.

---

## Практический вывод

### Чек-лист делегирования

| # | Правило | Действие |
|---|---------|----------|
| 1 | **Никогда не доверяйте арифметике модели** | Используйте code execution / calculator tool |
| 2 | **Используйте function calling** | Определите tools для вычислений, поиска, API |
| 3 | **Валидируйте типы и диапазоны** | Результат tool → проверка перед возвратом пользователю |
| 4 | **Логируйте вызовы инструментов** | Для отладки и аудита |
| 5 | **Предпочитайте mainstream** | Python > кастомный DSL |
| 6 | **Sandbox** | Изолированное выполнение сгенерированного кода |
| 7 | **Числовые оценки → для ранжирования** | Не для абсолютных метрик |
| 8 | **Проектируйте инструменты для модели** | Чёткие имена, описания, типы, enum |
| 9 | **Используйте MCP** | Стандартный протокол вместо кастомных интеграций |
| 10 | **Computer use — в sandbox** | Изолированное окружение + human-in-the-loop |
| 11 | **Computer use — не замена API** | Если есть API, используйте API |

### Задания

**Задание 1. Проектирование набора инструментов.** Выберите реальный рабочий сценарий (например, «агент-помощник для DevOps» или «аналитик данных»). Составьте список из 5–10 инструментов, классифицируйте каждый по пяти типам из §11.2 и напишите для каждого: имя (глагол + существительное), description с указанием «когда использовать», JSON Schema параметров с типами и enum. Ожидаемый результат: готовый к использованию набор tool-определений, который можно подключить к любому провайдеру.

**Задание 2. MCP — от нуля до рабочего сервера.** С помощью FastMCP или официального SDK (см. modelcontextprotocol.io) создайте MCP-сервер для внутреннего сервиса вашей команды (например, внутренняя вики или трекер задач). Реализуйте 2–3 инструмента и подключите сервер к Claude Desktop или VS Code. Ожидаемый результат: работающий MCP-сервер, который модель обнаруживает и вызывает в ответ на пользовательские запросы.

**Задание 3. Делегирование vs самостоятельный ответ.** Составьте набор из 10 запросов, которые примерно поровну делятся на «модель справится сама» и «нужен инструмент». Отправьте их модели без инструментов и с инструментами, сравните результаты. Ожидаемый результат: понимание границы, где делегирование даёт выигрыш, а где добавляет лишнюю латентность.

---

## Источники
- Gao, L., et al. (2023). "PAL: Program-aided Language Models." ICML.
- Schick, T., et al. (2023). "Toolformer: Language Models Can Teach Themselves to Use Tools." NeurIPS 2023. arXiv:2302.04761.
- Model Context Protocol Specification. (2025). LF Projects, LLC. https://spec.modelcontextprotocol.io/specification/ — spec version `2025-11-25`.
- MCP Servers Repository. https://github.com/modelcontextprotocol/servers
- OpenAI. “Tools, Connectors, and MCP.” Responses API Documentation. https://developers.openai.com/api/docs/guides/tools-connectors-mcp
- Anthropic. “MCP Connector.” Claude Documentation. https://platform.claude.com/docs/en/agents-and-tools/mcp-connector
- Anthropic. “Tool Use.” Claude Documentation. https://platform.claude.com/docs/en/agents-and-tools/tool-use
- Anthropic. “Computer Use.” Claude Documentation. https://platform.claude.com/docs/en/agents-and-tools/computer-use
- OpenAI. (2026). *Introducing GPT-5.4* — tool search, computer use. https://openai.com/index/introducing-gpt-5-4/
- Google. (2025). “Agent-to-Agent Protocol (A2A).” https://github.com/google/A2A
- Qin, Y., et al. (2024). “Tool Learning with Foundation Models.” Nature Machine Intelligence.
- OpenAI. “Data analysis with ChatGPT.” Help Center (updated 2026). pandas + Matplotlib, secure code execution environment with hundreds of Python libraries. https://help.openai.com/en/articles/8437071-data-analysis-with-chatgpt
- Anthropic. “Code execution tool.” Claude API docs (2026). Pre-installed libraries for data science, visualization, file processing and math. https://platform.claude.com/docs/en/agents-and-tools/tool-use/code-execution-tool
- Google. “Code execution.” Gemini API docs (updated 2026-03-25). Supported libraries and `matplotlib`-only graph rendering. https://ai.google.dev/gemini-api/docs/code-execution
- Anthropic Help Center. “What are artifacts and how do I use them?” Interactive React components and AI-powered artifacts with React. https://support.anthropic.com/en/articles/9487310-what-are-artifacts-and-how-do-i-use-them

---

**Навигация:**
- Назад: [Глава 10. Агент ≠ Чат: разные режимы, разные правила](10_agent_not_chat.md)
- Далее: [Глава 12. RAG: когда модели не хватает собственных знаний](12_rag.md)
