# Оптимизация кода с ИИ: сначала измерения

URL: https://agentvera.dev/ru/blog/optimize-code-performance-with-ai/ · Опубликовано: 2026-10-27

Как оптимизировать производительность кода с ИИ-агентами: профилируйте, давайте агенту реальные профили, чините N+1 и раздутый бандл, доказывайте выигрыш бенчмарком.

**Коротко:**

- Никогда не просите агента «сделать быстрее» без данных. Сначала профилируйте через Chrome DevTools, Lighthouse, node --cpu-prof, py-spy или cProfile и отдайте агенту профиль, а не свою догадку.
- До изменения напишите бенчмарк или воспроизводимое измерение — это и есть шаг проверки. Изменение, которое не сдвигает цифру, откатывается, каким бы умным оно ни выглядело.
- Обычно большой выигрыш дают скучные вещи: N+1 запросы, недостающие индексы, раздутые бандлы, повторная работа, которую можно кешировать. Агенты хорошо находят и чинят их, когда видят доказательства.
- Закрепляйте выигрыш защитой от регрессий: проверки числа запросов, бюджеты размера бандла и бенчмарки в CI, чтобы следующее изменение не отменило работу незаметно.

**Чтобы оптимизировать производительность кода с помощью ИИ, измеряйте до того, как писать промпт: профилируйте медленный путь, отдайте агенту профиль, попросите минимальное изменение, которое убирает горячую точку, и принимайте его, только когда бенчмарк показывает разницу.** Агенты для программирования вроде Claude Code, Codex и Gemini CLI быстро читают flame graph, прослеживают горячую функцию до её вызывающих и переписывают запросы. Без данных они делают то же, что и любой человек: гадают. А угаданные оптимизации — самые дорогие, потому что код становится труднее читать, но не быстрее.

В этом руководстве — процесс, который выдерживает практику: определить цель, профилировать, передать доказательства, менять по одному, проверять бенчмарком и закреплять выигрыш защитой от регрессий. Попутно разобраны проблемы, из-за которых тормозит большинство реальных приложений: N+1 запросы, размер бандла и отсутствие кеша.

## Начинайте с числа, а не с ощущения

«Дашборд тормозит» — это не задача. Превратите это в то, что агент может проверить:

- **Что** медленно: один эндпоинт, одна загрузка страницы, одна CLI-команда, одна пакетная задача.
- **Насколько** медленно сейчас, по измерениям: p95-задержка эндпоинта, time to interactive страницы, время работы скрипта.
- **Что значит «достаточно быстро»**: цель, например «меньше 300 мс на p95» или «импорт 100 тыс. строк завершается быстрее минуты».
- **При каких условиях**: объём данных, холодный или прогретый кеш, продакшен-сборка или dev-сервер.

Последний пункт отсекает много лишней работы. React-приложение на dev-сервере, Node-сервис без `NODE_ENV=production` или Python-задача на десяти строках тестовых данных покажут горячие точки, которых в продакшене нет. Измеряйте то, что выпускаете.

## Шаг 1: профилируйте медленный путь

Выберите профилировщик под то место, где уходит время.

### В браузере

Панель **Performance** в Chrome DevTools записывает трассировку: длинные задачи, выполнение скриптов, layout, сетевой водопад. **Lighthouse** даёт лабораторную оценку с конкретными возможностями для улучшения. Lighthouse CLI удобен тем, что пишет файл, который можно отдать агенту:

```bash
npm install -g lighthouse
lighthouse https://localhost:3000/dashboard \
  --only-categories=performance \
  --output=json --output-path=./lighthouse.json
```

Если ваш агент поддерживает MCP, MCP-сервер Chrome DevTools позволяет ему самому запустить трассировку производительности и прочитать выводы:

```json
{
  "mcpServers": {
    "chrome-devtools": {
      "command": "npx",
      "args": ["-y", "chrome-devtools-mcp@latest"]
    }
  }
}
```

### В Node.js

В Node есть встроенный сэмплирующий профилировщик. `--cpu-prof` при завершении процесса пишет файл `.cpuprofile`, который можно открыть в панели Performance в DevTools или отдать агенту:

```bash
node --cpu-prof --cpu-prof-dir=./profiles server.js
# run the slow request a few times, then stop the server
```

Более старый флаг `--prof` пишет лог V8, который `node --prof-process` превращает в текстовый отчёт, — агенту его читать очень легко:

```bash
NODE_ENV=production node --prof server.js
node --prof-process isolate-0x*-v8.log > processed.txt
```

Для проблем с памятью `--heap-prof` точно так же пишет `.heapprofile`.

### В Python

`py-spy` сэмплирует запущенный процесс без изменений в вашем коде, поэтому это безопасный выбор для работающего сервиса:

```bash
py-spy top --pid 12345                    # live view, like top
py-spy record -o profile.svg --pid 12345  # flame graph
py-spy record -o profile.svg -- python import_job.py
```

Для скрипта, который вы запускаете сами, `cProfile` из стандартной библиотеки даёт точное число вызовов:

```bash
python -m cProfile -s cumtime import_job.py | head -40
```

По состоянию на октябрь 2026 года в Python 3.15 также есть пакет `profiling` со статистическим профилировщиком (`python -m profiling.sampling`), а `cProfile` остаётся псевдонимом его трассирующего профилировщика; в более ранних версиях используйте `cProfile` и py-spy.

### В базе данных

Про время запросов база данных уже знает ответ: лог медленных запросов, `pg_stat_statements` в PostgreSQL и `EXPLAIN ANALYZE` для отдельного запроса. Как читать планы запросов и выбирать индексы с агентом, рассказано в статье [пишем SQL с ИИ](/ru/blog/write-sql-with-ai/ "Пишем SQL с ИИ"), так что здесь мы это не повторяем.

## Шаг 2: отдайте агенту доказательства

Теперь у агента есть с чем работать. Передайте профиль и контекст и попросите анализ до кода:

```text
Эндпоинт /api/orders в продакшене отвечает примерно за 1,8 с на p95;
цель — 300 мс. Во вложении: processed.txt из node --prof-process для
50 запросов и лог медленных запросов за тот же период.
Пока не меняй код. Перечисли три главные горячие точки с доказательствами
из профиля для каждой (функция, собственное или общее время, число
вызовов), вероятную причину в нашем коде (файл и строка) и предлагаемое
исправление. Упорядочь их по ожидаемому эффекту.
```

Несколько привычек, с которыми этот шаг работает:

- **Давайте сырой вывод, а не свой пересказ.** В вашем пересказе уже сидит ваша догадка.
- **Требуйте доказательство для каждого утверждения.** «Эта функция медленная» должно сопровождаться цифрой из профиля.
- **Держите агента на горячем пути.** Код, который занимает 2% времени, не стоит переписывать, каким бы уродливым он ни был.

Если агент говорит что-то вроде «по профилю узкое место видно неясно», поверьте ему и снимите профиль получше — под большей нагрузкой или на продакшен-сборке. Это гораздо лучший результат, чем уверенная догадка.

## Шаг 3: напишите бенчмарк до исправления

Бенчмарк — это ваш шаг проверки. Напишите его, запустите на текущем коде и сохраните базовую линию до любых изменений.

Для команды или скрипта `hyperfine` запускает её много раз и сообщает среднее и разброс:

```bash
hyperfine --warmup 3 'node scripts/build-report.js'
```

Для функции используйте поддержку бенчмарков в своём стеке: `go test -bench=. -benchmem` в Go, `pytest-benchmark` в Python, бенчмарки в вашем тестовом раннере для JavaScript. Для эндпоинта — короткий нагрузочный тест с фиксированным числом запросов к продакшен-сборке.

Затем сообщите агенту правило:

```text
Вот бенчмарк и его базовый результат. Вноси по одному изменению за раз.
После каждого изменения запускай тесты и бенчмарк трижды и сообщай
результат до/после. Если изменение не улучшает результат сверх шума,
откати его и скажи мне, даже если считаешь, что оно должно помогать.
```

Важны две детали. Сравнивайте на одной машине с одними данными, потому что ноутбуки троттлят, а кеши прогреваются. И запускайте тесты вместе с бенчмарком: более быстрая функция, которая возвращает неправильный ответ, — это баг. Если у оптимизируемого кода нет тестов, сначала добавьте их; как получить от агента полезные тесты, показано в статье [пишем unit-тесты с ИИ](/ru/blog/write-unit-tests-with-ai/ "Пишем unit-тесты с ИИ").

## Куда обычно уходит время

В реальных приложениях большую часть замедлений дают несколько типичных проблем. Их и проверяйте первыми.

### N+1 запросы

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

| Стек | Жадная загрузка |
| --- | --- |
| Django | `select_related` (join), `prefetch_related` (отдельный запрос) |
| Rails | `includes`, а гем Bullet находит N+1 в разработке |
| SQLAlchemy | `selectinload`, `joinedload` |
| Prisma | `include` |

Агенты хорошо делают это исправление, когда знают, где проблема. Включите логирование запросов, один раз откройте медленную страницу и отдайте агенту лог: повторяющийся шаблон запроса с разными ID — это отпечаток пальца. Затем попросите исправление и тест, который проверяет число запросов на этой странице, чтобы проблема не вернулась незаметно.

### Размер бандла

Во фронтенде самый большой рычаг — часто сам JavaScript, который вы отдаёте. Сначала измерьте, что лежит в бандле, с помощью `source-map-explorer` или `webpack-bundle-analyzer` (или анализатора для вашего сборщика), а затем ищите типичные причины:

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

Отдайте агенту вывод анализатора и попросите изменения, отсортированные по сэкономленным байтам. Затем сравните результат сборки до и после — так же, как сравниваете бенчмарк.

### Повторная работа и кеширование

Кеш — правильный ответ, когда один и тот же дорогой результат снова и снова вычисляется с одними и теми же входными данными. И неправильный, когда вычисление можно просто удешевить или когда никто не решил, что происходит при изменении данных. Прежде чем принять кеш от агента, спросите его:

```text
Для этого кеша: какой ключ, что его инвалидирует, какое максимальное
устаревание мы допускаем, сколько памяти он может занимать и что
происходит при холодном старте? Покажи измеренный hit rate или профиль,
который его оправдывает.
```

Если ответы расплывчатые, кеш потом превратится в баг-репорт. Часто лучшее исправление находится раньше в цепочке: недостающий индекс, запрос, который тянет все столбцы, цикл, который на каждой итерации заново вычисляет одно и то же значение.

### Алгоритмические проблемы

Иногда профиль показывает одну функцию с огромным числом вызовов: вложенный цикл по двум спискам, `.find()` внутри `.map()`, сортировку внутри цикла. Замена линейного поиска на `Map` или `Set` — классическое исправление для агента, и бенчмарк сразу скажет, было ли оно важно.

## Избегайте преждевременной и спекулятивной оптимизации

Агенты любят оптимизировать. Попросите «улучшить производительность» файла, и агент мемоизирует компоненты, перепишет циклы и везде добавит кеши. Большинство таких изменений ничего измеримо не сдвигают, а код становится труднее менять. Правила, которые стоит прямо прописать в инструкциях проекта:

```markdown
## Работа над производительностью
- Никакой оптимизации без профиля или бенчмарка, который показывает проблему.
- Одно изменение на коммит, с цифрами до/после в сообщении.
- Вне измеренных горячих путей читаемость важнее микрооптимизаций.
- Не добавляй кеши, воркеры или новые зависимости, не спросив.
```

То же относится к собственным предложениям агента во время несвязанной работы. Если он сообщает «заодно я ещё оптимизировал…», попросите цифры или попросите откатить. Если после оптимизации что-то всё же сломалось, как сузить поиск без догадок, рассказано в статье [отладка кода с ИИ](/ru/blog/debug-code-with-ai/ "Отладка кода с ИИ").

## Шаг 4: защитите выигрыш

Производительность ухудшается тихо, по одному разумному изменению за раз. Превратите каждое исправление в проверку, которая громко падает:

- **Тесты на число запросов.** Проверяйте, что страница заказов выполняет не больше фиксированного числа запросов. В большинстве фреймворков для этого есть хелпер, например `assertNumQueries` в Django.
- **Бюджеты бандла.** Инструменты вроде `size-limit` роняют сборку, когда бандл вырастает сверх заданного размера.
- **Lighthouse в CI.** Запускайте Lighthouse CLI на превью-сборке и роняйте проверку ниже порога оценки на важных страницах.
- **Бенчмарки против базовой линии.** Сохраните базовую линию и сравнивайте; в Go `benchstat` сравнивает два прогона бенчмарков и говорит, значима ли разница.

Агенты хорошо пишут такие защиты, и стоит просить их в той же задаче, что и исправление: «исправь N+1 и добавь тест, который поймал бы его».

## Как это делать в AgentVera

AgentVera — десктопное приложение, которое запускает CLI агентов для программирования, такие как Claude Code, Codex и Gemini CLI, рядом друг с другом. Несколько его функций подходят под этот цикл:

- **Браузер, которым управляет агент.** [Браузер агента](/ru/features/agent-browser/ "Браузер агента") — это отдельный профиль Chrome, которым агенты пользуются через Playwright MCP, со встроенными DevTools и консолью, так что агент может сам открыть медленную страницу, а вы — наблюдать.
- **Доказательства одним сочетанием клавиш.** [Отправка агенту](/ru/features/send-to-agent/ "Отправка агенту") (⌘⇧L) отправляет агенту вывод терминала, выделение в редакторе, diff или консоль браузера. Вывод профилировщика в терминале уходит агенту без копирования; очень длинный вывод обрезается на 12 000 символов, поэтому отправляйте верх отчёта или сохраните его в файл.
- **Планы запросов рядом с кодом.** [Менеджер баз данных](/ru/features/database-manager/ "Менеджер баз данных") (Pro) открывает PostgreSQL, MySQL и SQLite с SQL-редактором, который показывает планы EXPLAIN, а агенты могут обращаться к базе через его встроенный инструмент.
- **Бенчмарки как критерии приёмки.** Напишите в сообщении «тесты проходят, а бенчмарк минимум на 30% быстрее базовой линии», и [Verify](/ru/features/verify/ "Verify") проверит это в конце хода с помощью проверяющего, который запускает команды, но не может править файлы.
- **Откат неокупившейся оптимизации.** [Чекпоинты](/ru/features/checkpoints-and-replay/ "Чекпоинты и повтор") сохраняют снимок каждого хода, так что откат эксперимента — один клик.
- **Два подхода одновременно.** В сетке [рабочего пространства](/ru/features/workspace/ "Рабочее пространство") запустите двух агентов в отдельных worktree — скажем, одного на кеширование, другого на запрос — и оставьте того, у кого цифры лучше.

## Итоги

Оптимизация производительности кода с помощью ИИ — та же дисциплина, что и без него, только быстрее: ясная цель, профиль, переданные агенту доказательства, по одному изменению за раз, бенчмарк как доказательство и защита, которая удерживает выигрыш. Агент читает и переписывает, а решают цифры. Если замедление пришло вместе с обновлением зависимостей, процесс из статьи [обновление зависимостей с ИИ](/ru/blog/upgrade-dependencies-with-ai/ "Обновление зависимостей с ИИ") поможет выяснить, какой пакет виноват.

Чтобы попробовать этот процесс на своём проекте, [скачайте AgentVera](/ru/download/ "Скачать AgentVera").

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

**Может ли ИИ-агент найти проблемы с производительностью, просто читая код?** Он может указать вероятных подозреваемых, например запрос внутри цикла, но не может знать, какой из них важен при ваших данных и нагрузке. Дайте ему профиль, лог медленных запросов или трассировку, и он сосредоточится на коде, который действительно отнимает время.

**Какой профилировщик выбрать?** Для браузера — панель Performance в Chrome DevTools и Lighthouse. Для Node.js — node --cpu-prof, который пишет файл .cpuprofile, открываемый в DevTools. Для Python — py-spy для запущенных процессов и cProfile для скрипта, который вы можете запустить сами.

**Как понять, что оптимизация сработала?** Измерьте одно и то же до и после, по нескольку запусков, на одной машине. Инструмент для бенчмарков вроде hyperfine для команд или поддержка бенчмарков в вашем тестовом фреймворке сделает повторные запуски за вас. Если разница в пределах шума, оптимизация не сработала.

**Почему агенты предлагают оптимизации, которые не помогают?** Без измерений модель скатывается к общим советам: мемоизировать это, взять цикл побыстрее, добавить кеш. Такие изменения добавляют сложности и часто ничего не меняют. Требуйте доказательство для каждого предложения и отклоняйте всё, что не связано с измеренной горячей точкой.

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

---

**Об AgentVera.** AgentVera — настольное приложение для macOS, Windows и Linux от Solviera Teknoloji. Оно запускает 18 ИИ-агентов для программирования (Claude Code, Codex, Gemini CLI, Copilot, Cursor, Antigravity, opencode, Hermes, Qwen Code, Kimi Code, Kiro, Amp, Droid, Goose, Vibe, Crush, Aider, Cline) рядом, по проектам, в настоящих терминалах с собственными установками CLI и входами пользователя. В бесплатном тарифе количество агентов не ограничено. Скачать: https://agentvera.dev/ru/download/ · Цены: https://agentvera.dev/ru/pricing/
