Чтобы оптимизировать производительность кода с помощью ИИ, измеряйте до того, как писать промпт: профилируйте медленный путь, отдайте агенту профиль, попросите минимальное изменение, которое убирает горячую точку, и принимайте его, только когда бенчмарк показывает разницу. Агенты для программирования вроде 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 удобен тем, что пишет файл, который можно отдать агенту:
npm install -g lighthouse
lighthouse https://localhost:3000/dashboard \
--only-categories=performance \
--output=json --output-path=./lighthouse.json
Если ваш агент поддерживает MCP, MCP-сервер Chrome DevTools позволяет ему самому запустить трассировку производительности и прочитать выводы:
{
"mcpServers": {
"chrome-devtools": {
"command": "npx",
"args": ["-y", "chrome-devtools-mcp@latest"]
}
}
}
В Node.js
В Node есть встроенный сэмплирующий профилировщик. --cpu-prof при завершении процесса пишет файл .cpuprofile, который можно открыть в панели Performance в DevTools или отдать агенту:
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 превращает в текстовый отчёт, — агенту его читать очень легко:
NODE_ENV=production node --prof server.js
node --prof-process isolate-0x*-v8.log > processed.txt
Для проблем с памятью --heap-prof точно так же пишет .heapprofile.
В Python
py-spy сэмплирует запущенный процесс без изменений в вашем коде, поэтому это безопасный выбор для работающего сервиса:
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 из стандартной библиотеки даёт точное число вызовов:
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 с ИИ, так что здесь мы это не повторяем.
Шаг 2: отдайте агенту доказательства
Теперь у агента есть с чем работать. Передайте профиль и контекст и попросите анализ до кода:
Эндпоинт /api/orders в продакшене отвечает примерно за 1,8 с на p95;
цель — 300 мс. Во вложении: processed.txt из node --prof-process для
50 запросов и лог медленных запросов за тот же период.
Пока не меняй код. Перечисли три главные горячие точки с доказательствами
из профиля для каждой (функция, собственное или общее время, число
вызовов), вероятную причину в нашем коде (файл и строка) и предлагаемое
исправление. Упорядочь их по ожидаемому эффекту.
Несколько привычек, с которыми этот шаг работает:
- Давайте сырой вывод, а не свой пересказ. В вашем пересказе уже сидит ваша догадка.
- Требуйте доказательство для каждого утверждения. «Эта функция медленная» должно сопровождаться цифрой из профиля.
- Держите агента на горячем пути. Код, который занимает 2% времени, не стоит переписывать, каким бы уродливым он ни был.
Если агент говорит что-то вроде «по профилю узкое место видно неясно», поверьте ему и снимите профиль получше — под большей нагрузкой или на продакшен-сборке. Это гораздо лучший результат, чем уверенная догадка.
Шаг 3: напишите бенчмарк до исправления
Бенчмарк — это ваш шаг проверки. Напишите его, запустите на текущем коде и сохраните базовую линию до любых изменений.
Для команды или скрипта hyperfine запускает её много раз и сообщает среднее и разброс:
hyperfine --warmup 3 'node scripts/build-report.js'
Для функции используйте поддержку бенчмарков в своём стеке: go test -bench=. -benchmem в Go, pytest-benchmark в Python, бенчмарки в вашем тестовом раннере для JavaScript. Для эндпоинта — короткий нагрузочный тест с фиксированным числом запросов к продакшен-сборке.
Затем сообщите агенту правило:
Вот бенчмарк и его базовый результат. Вноси по одному изменению за раз.
После каждого изменения запускай тесты и бенчмарк трижды и сообщай
результат до/после. Если изменение не улучшает результат сверх шума,
откати его и скажи мне, даже если считаешь, что оно должно помогать.
Важны две детали. Сравнивайте на одной машине с одними данными, потому что ноутбуки троттлят, а кеши прогреваются. И запускайте тесты вместе с бенчмарком: более быстрая функция, которая возвращает неправильный ответ, — это баг. Если у оптимизируемого кода нет тестов, сначала добавьте их; как получить от агента полезные тесты, показано в статье пишем 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 (или анализатора для вашего сборщика), а затем ищите типичные причины:
- большая библиотека импортирована ради одной функции,
- целый набор иконок или локалей подтянут одним импортом,
- тяжёлые компоненты грузятся при первой отрисовке, хотя могли бы грузиться лениво,
- одна и та же зависимость попала в бандл дважды в разных версиях.
Отдайте агенту вывод анализатора и попросите изменения, отсортированные по сэкономленным байтам. Затем сравните результат сборки до и после — так же, как сравниваете бенчмарк.
Повторная работа и кеширование
Кеш — правильный ответ, когда один и тот же дорогой результат снова и снова вычисляется с одними и теми же входными данными. И неправильный, когда вычисление можно просто удешевить или когда никто не решил, что происходит при изменении данных. Прежде чем принять кеш от агента, спросите его:
Для этого кеша: какой ключ, что его инвалидирует, какое максимальное
устаревание мы допускаем, сколько памяти он может занимать и что
происходит при холодном старте? Покажи измеренный hit rate или профиль,
который его оправдывает.
Если ответы расплывчатые, кеш потом превратится в баг-репорт. Часто лучшее исправление находится раньше в цепочке: недостающий индекс, запрос, который тянет все столбцы, цикл, который на каждой итерации заново вычисляет одно и то же значение.
Алгоритмические проблемы
Иногда профиль показывает одну функцию с огромным числом вызовов: вложенный цикл по двум спискам, .find() внутри .map(), сортировку внутри цикла. Замена линейного поиска на Map или Set — классическое исправление для агента, и бенчмарк сразу скажет, было ли оно важно.
Избегайте преждевременной и спекулятивной оптимизации
Агенты любят оптимизировать. Попросите «улучшить производительность» файла, и агент мемоизирует компоненты, перепишет циклы и везде добавит кеши. Большинство таких изменений ничего измеримо не сдвигают, а код становится труднее менять. Правила, которые стоит прямо прописать в инструкциях проекта:
## Работа над производительностью
- Никакой оптимизации без профиля или бенчмарка, который показывает проблему.
- Одно изменение на коммит, с цифрами до/после в сообщении.
- Вне измеренных горячих путей читаемость важнее микрооптимизаций.
- Не добавляй кеши, воркеры или новые зависимости, не спросив.
То же относится к собственным предложениям агента во время несвязанной работы. Если он сообщает «заодно я ещё оптимизировал…», попросите цифры или попросите откатить. Если после оптимизации что-то всё же сломалось, как сузить поиск без догадок, рассказано в статье отладка кода с ИИ.
Шаг 4: защитите выигрыш
Производительность ухудшается тихо, по одному разумному изменению за раз. Превратите каждое исправление в проверку, которая громко падает:
- Тесты на число запросов. Проверяйте, что страница заказов выполняет не больше фиксированного числа запросов. В большинстве фреймворков для этого есть хелпер, например
assertNumQueriesв Django. - Бюджеты бандла. Инструменты вроде
size-limitроняют сборку, когда бандл вырастает сверх заданного размера. - Lighthouse в CI. Запускайте Lighthouse CLI на превью-сборке и роняйте проверку ниже порога оценки на важных страницах.
- Бенчмарки против базовой линии. Сохраните базовую линию и сравнивайте; в Go
benchstatсравнивает два прогона бенчмарков и говорит, значима ли разница.
Агенты хорошо пишут такие защиты, и стоит просить их в той же задаче, что и исправление: «исправь N+1 и добавь тест, который поймал бы его».
Как это делать в AgentVera
AgentVera — десктопное приложение, которое запускает CLI агентов для программирования, такие как Claude Code, Codex и Gemini CLI, рядом друг с другом. Несколько его функций подходят под этот цикл:
- Браузер, которым управляет агент. Браузер агента — это отдельный профиль Chrome, которым агенты пользуются через Playwright MCP, со встроенными DevTools и консолью, так что агент может сам открыть медленную страницу, а вы — наблюдать.
- Доказательства одним сочетанием клавиш. Отправка агенту (⌘⇧L) отправляет агенту вывод терминала, выделение в редакторе, diff или консоль браузера. Вывод профилировщика в терминале уходит агенту без копирования; очень длинный вывод обрезается на 12 000 символов, поэтому отправляйте верх отчёта или сохраните его в файл.
- Планы запросов рядом с кодом. Менеджер баз данных (Pro) открывает PostgreSQL, MySQL и SQLite с SQL-редактором, который показывает планы EXPLAIN, а агенты могут обращаться к базе через его встроенный инструмент.
- Бенчмарки как критерии приёмки. Напишите в сообщении «тесты проходят, а бенчмарк минимум на 30% быстрее базовой линии», и Verify проверит это в конце хода с помощью проверяющего, который запускает команды, но не может править файлы.
- Откат неокупившейся оптимизации. Чекпоинты сохраняют снимок каждого хода, так что откат эксперимента — один клик.
- Два подхода одновременно. В сетке рабочего пространства запустите двух агентов в отдельных worktree — скажем, одного на кеширование, другого на запрос — и оставьте того, у кого цифры лучше.
Итоги
Оптимизация производительности кода с помощью ИИ — та же дисциплина, что и без него, только быстрее: ясная цель, профиль, переданные агенту доказательства, по одному изменению за раз, бенчмарк как доказательство и защита, которая удерживает выигрыш. Агент читает и переписывает, а решают цифры. Если замедление пришло вместе с обновлением зависимостей, процесс из статьи обновление зависимостей с ИИ поможет выяснить, какой пакет виноват.
Чтобы попробовать этот процесс на своём проекте, скачайте AgentVera.