Агентное программирование
Агенты для программирования – это диалоговые ИИ-модели с доступом к инструментам вроде чтения и записи файлов, веб-поиска и запуска команд оболочки (shell). Они живут либо в IDE, либо в отдельных инструментах – с интерфейсом командной строки или графическим. Агенты для программирования – мощные и весьма автономные инструменты, открывающие широкий спектр сценариев использования.
Эта лекция опирается на материал о разработке с помощью ИИ из лекции Среда разработки и инструменты. В качестве быстрой демонстрации продолжим пример из раздела Разработка с помощью ИИ:
from urllib.request import urlopen
def download_contents(url: str) -> str:
with urlopen(url) as response:
return response.read().decode('utf-8')
def extract(content: str) -> list[str]:
import re
pattern = r'\[.*?\]\((.*?)\)'
return re.findall(pattern, content)
print(extract(download_contents("https://raw.githubusercontent.com/missing-semester/missing-semester/refs/heads/master/_2026/development-environment.md")))
Попробуем дать агенту для программирования следующую задачу:
Turn this into a proper command-line program, with argparse for argument parsing. Add type annotations, and make sure the program passes type checking.
Агент прочитает файл, чтобы разобраться в нём, затем внесёт правки и напоследок запустит проверку типов, чтобы убедиться, что аннотации типов корректны. Если он ошибётся так, что проверка типов не пройдёт, он, скорее всего, сделает ещё одну итерацию, хотя задача простая, так что это маловероятно. Поскольку у агентов для программирования есть доступ к инструментам, способным навредить, по умолчанию обвязка агента (agent harness) просит пользователя подтверждать вызовы инструментов.
Если агент ошибается – например, у вас бинарник
mypyдоступен прямо в$PATH, а агент пытается вызватьpython -m mypy, – вы можете дать ему обратную связь текстом, чтобы он скорректировал курс.
Агенты для программирования поддерживают многоходовое взаимодействие, так что работу можно итеративно дорабатывать в диалоге с агентом. Агента можно даже прервать, если он свернул не туда. Полезная ментальная модель – руководитель и стажёр: стажёр возьмёт на себя всю кропотливую работу, но ему нужны указания, а время от времени он будет делать что-то не то – и его придётся поправлять.
Для более наглядной демонстрации попробуйте следующим сообщением попросить агента запустить получившийся скрипт. Посмотрите на вывод и попросите его внести изменение (например, оставить только абсолютные URL).
Как работают ИИ-модели и агенты
Полное объяснение внутреннего устройства современных больших языковых моделей (LLM) и инфраструктуры вроде агентных обвязок выходит за рамки этого курса. Однако общее представление о нескольких ключевых идеях помогает эффективно использовать эту новейшую технологию и понимать её ограничения.
LLM можно рассматривать как модель распределения вероятностей строк-дополнений (выходов) при условии строк-промптов (входов). Инференс (inference) LLM – то, что происходит, когда вы, например, отправляете запрос в диалоговое чат-приложение, – сэмплирует из этого распределения вероятностей. У LLM фиксированное контекстное окно – максимальная длина входной и выходной строк.
Инструменты ИИ, такие как диалоговый чат и агенты для программирования, строятся поверх этого примитива. Для многоходового взаимодействия чат-приложения и агенты используют маркеры реплик и при каждом новом промпте пользователя передают в качестве строки-промпта всю историю диалога, запуская инференс LLM по одному разу на каждый промпт пользователя. В агентах с вызовом инструментов обвязка интерпретирует определённые выходы LLM как запросы на вызов инструмента и передаёт результаты вызова обратно модели как часть строки-промпта (так что инференс LLM запускается заново при каждом вызове инструмента и ответе на него). Ключевые концепции агентов с вызовом инструментов можно реализовать в 200 строк кода.
Приватность
Большинство ИИ-инструментов для программирования в стандартной конфигурации отправляют в облако немало ваших данных. Иногда обвязка агента работает локально, а инференс LLM выполняется в облаке; в других случаях в облако вынесена ещё большая часть софта (и тогда, например, провайдер сервиса фактически получает копию всего вашего репозитория, а заодно и всех ваших взаимодействий с ИИ-инструментом).
Существуют вполне неплохие ИИ-инструменты для программирования с открытым исходным кодом и открытые LLM (хотя они всё же не так хороши, как проприетарные модели), но на данный момент для большинства пользователей запускать передовые открытые LLM локально нереально из-за аппаратных ограничений.
Сценарии использования
Агенты для программирования могут быть полезны в самых разных задачах. Несколько примеров:
- Реализация новых фич. Как в примере выше, вы можете попросить агента для программирования реализовать фичу. Составление хорошей спецификации на сегодняшний день – скорее искусство, чем наука: вход для агента должен быть достаточно подробным, чтобы агент сделал именно то, что вам нужно (или хотя бы двигался в правильном направлении, чтобы можно было итерировать), но не настолько подробным, чтобы вы делали слишком много работы сами. Особенно эффективной может оказаться разработка через тестирование (test-driven development): напишите тесты (или напишите их с помощью агента), проверьте, что они отражают именно то, чего вы хотите, а затем попросите агента реализовать фичу. Модели непрерывно улучшаются, так что придётся постоянно обновлять свои представления о том, на что они способны.
Мы использовали Claude Code, чтобы реализовать эти боковые заметки в стиле Тафти.
- Исправление ошибок. Если у вас есть ошибки от компилятора, линтера, проверки типов или тестов, вы можете попросить агента их исправить – например, промптом вроде «fix the issues with mypy». Модели для программирования особенно эффективны, когда их удаётся замкнуть в цикл обратной связи, поэтому постарайтесь устроить всё так, чтобы модель могла сама запускать падающую проверку – это позволит ей итерировать автономно. Если это непрактично, можно давать модели обратную связь вручную.
На коммите f552b55 репозитория missing-semester мы дали Claude Code промпт «Review the agentic coding lecture for typos and grammatical issues», а затем попросили исправить найденные проблемы; исправления закоммичены в f1e1c41.
- Рефакторинг. С помощью агентов для программирования можно рефакторить код самыми разными способами: от простых задач вроде переименования метода (такой рефакторинг умеют делать и средства интеллектуальной работы с кодом) до более сложных – например, выделения функциональности в отдельный модуль.
Мы использовали Claude Code, чтобы выделить агентное программирование в отдельную лекцию.
- Код-ревью. Агентов для программирования можно просить делать ревью кода. Можно давать им простые указания вроде «review my latest changes that are not yet committed». Если вы хотите сделать ревью пул-реквеста и ваш агент умеет загружать веб-страницы (web fetch) или у вас установлены инструменты командной строки вроде GitHub CLI, может хватить даже промпта «Review the pull request {link}» – дальше агент разберётся сам.
- Понимание кода. Агенту для программирования можно задавать вопросы о кодовой базе – это особенно полезно при погружении в новый проект (onboarding).
- Как командная оболочка. Агента можно попросить решить задачу конкретным инструментом, то есть вызывать команды оболочки на естественном языке: например, «use the find command to find all files older than 30 days» или «use mogrify to resize all the jpgs to 50% of their original size».
- Вайб-кодинг (vibe coding). Агенты уже достаточно мощны, чтобы некоторые приложения можно было реализовать, не написав самостоятельно ни строчки кода.
Вот пример реального проекта, который навайбкодил один из преподавателей.
Продвинутые агенты
Здесь мы кратко рассмотрим несколько более продвинутых паттернов использования и возможностей агентов для программирования.
- Переиспользуемые промпты. Создавайте переиспользуемые промпты или шаблоны. Например, вы можете написать подробный промпт, задающий определённую манеру код-ревью, и сохранить его как переиспользуемый промпт.
Инструментарий агентов быстро развивается. В некоторых инструментах переиспользуемые промпты как самостоятельная функция уже объявлены устаревшими. Например, в Codex и Claude Code они поглощены навыками (skills).
- Параллельные агенты. Агенты для программирования могут быть медленными: вы даёте агенту промпт, и он может трудиться над задачей десятки минут. Можно запускать несколько копий агентов одновременно – либо над одной и той же задачей (LLM стохастичны, поэтому бывает полезно запустить одно и то же несколько раз и взять лучшее решение), либо над разными (например, реализовать две непересекающиеся фичи одновременно). Чтобы изменения разных агентов не мешали друг другу, можно использовать git worktrees, которые мы разбираем в лекции о контроле версий.
- MCP. MCP, что расшифровывается как Model Context Protocol, – это открытый протокол, с помощью которого можно подключать инструменты к вашим агентам для программирования. Например, вот этот MCP-сервер для Notion может дать вашему агенту возможность читать и редактировать документы Notion, открывая сценарии вроде «read the spec linked in {Notion doc}, draft an implementation plan as a new page in Notion, and then implement a prototype». Искать MCP можно в каталогах вроде Pulse и Glama.
- Управление контекстом. Как мы отмечали выше, у LLM, лежащих в основе агентов для программирования, ограниченное контекстное окно. Эффективное использование агентов для программирования требует разумного обращения с контекстом. Нужно, чтобы агент имел доступ ко всей необходимой ему информации, но лишнего контекста стоит избегать – иначе можно переполнить контекстное окно или ухудшить качество работы модели (оно, как правило, снижается с ростом размера контекста, даже если окно не переполняется). Обвязки агентов подставляют контекст автоматически и до некоторой степени сами им управляют, но значительная часть контроля остаётся за пользователем.
- Очистка контекстного окна. Самый базовый механизм управления: агенты для программирования поддерживают очистку контекстного окна (начало нового диалога) – делайте это для не связанных между собой запросов.
- Перемотка диалога назад. Некоторые агенты для программирования поддерживают отмену шагов в истории диалога. В ситуациях, когда уместнее именно «отмена», это управляет контекстом эффективнее, чем ещё одно сообщение, разворачивающее агента в другую сторону.
- Сжатие контекста (compaction). Чтобы диалоги могли быть неограниченной длины, агенты для программирования поддерживают сжатие (compaction) контекста: если история диалога становится слишком длинной, они автоматически вызовут LLM, чтобы суммаризовать начало диалога, и заменят историю этим резюме. Некоторые агенты дают пользователю возможность запускать сжатие по требованию.
- llms.txt. Файл
/llms.txt– предлагаемое стандартное расположение документа, рассчитанного на чтение LLM во время инференса. У продуктов (например, cursor.com/llms.txt), программных библиотек (например, ai.pydantic.dev/llms.txt) и API (например, apify.com/llms.txt) могут быть файлыllms.txt, полезные при разработке. Такие документы несут больше информации в расчёте на токен, поэтому расходуют контекст экономнее, чем просьба к агенту скачать и прочитать HTML-страницу. Внешняя документация выручает, когда у агента для программирования нет встроенных знаний о зависимости, которую вы пытаетесь использовать (например, потому что она была опубликована после даты отсечения знаний LLM – knowledge cutoff). - AGENTS.md. Большинство агентов для программирования поддерживают AGENTS.md или что-то похожее (например, Claude Code ищет
CLAUDE.md) – своего рода README для агентов. При запуске агент заранее заполняет контекст всем содержимымAGENTS.md. Так агенту можно давать советы, общие для всех сессий (например, велеть ему всегда запускать проверку типов после изменения кода, объяснить, как запускать модульные тесты, или дать ссылки на стороннюю документацию, которую агент может просматривать). Некоторые агенты умеют генерировать этот файл автоматически (например, команда/initв Claude Code). Реальный примерAGENTS.mdможно посмотреть здесь. - Навыки. Содержимое
AGENTS.mdвсегда загружается в контекстное окно агента целиком. Навыки добавляют один уровень косвенности, чтобы не раздувать контекст: вы даёте агенту список навыков с описаниями, а агент по мере необходимости «открывает» навык (загружает его в своё контекстное окно). - Субагенты. Некоторые агенты для программирования позволяют определять субагентов – агентов для специализированных рабочих процессов. Агент верхнего уровня может вызвать субагента для выполнения конкретной задачи, что позволяет и агенту верхнего уровня, и субагенту эффективнее управлять контекстом. Контекст агента верхнего уровня не раздувается всем, что видит субагент, а субагент получает ровно тот контекст, который нужен для его задачи. Один из примеров: некоторые агенты для программирования реализуют веб-исследование в виде субагента – агент верхнего уровня формулирует субагенту запрос, тот выполняет веб-поиск, скачивает отдельные веб-страницы, анализирует их и возвращает агенту верхнего уровня ответ на запрос. Благодаря этому контекст агента верхнего уровня не раздувается полным содержимым всех скачанных веб-страниц, а у субагента в контексте нет остальной истории диалога агента верхнего уровня.
Для многих продвинутых возможностей, требующих написания промптов (например, навыков или субагентов), первый набросок можно получить с помощью LLM. В некоторых агентах для программирования это даже поддерживается «из коробки». Например, Claude Code может сгенерировать субагента из короткого промпта (вызовите /agents и создайте нового агента). Попробуйте создать субагента с таким промптом:
A Python code checking agent that uses `mypy` and `ruff` to type-check, lint, and format *check* any files that have been modified from the last git commit.
Затем субагента можно явно вызвать через агента верхнего уровня сообщением вроде «use the code checker subagent». Возможно, вам также удастся добиться, чтобы агент верхнего уровня вызывал субагента автоматически, когда это уместно, – например, после изменения любых Python-файлов.
На что обращать внимание
Инструменты ИИ могут ошибаться. Они построены на LLM – всего лишь вероятностных моделях предсказания следующего токена. Они не «интеллектуальны» в том смысле, в каком интеллектуальны люди. Проверяйте вывод ИИ на корректность и на уязвимости. Иногда проверить код бывает труднее, чем написать его самому; критически важный код, возможно, стоит писать вручную. ИИ может уходить в кроличьи норы и пытаться вас газлайтить; помните о спиралях отладки (debugging spirals). Не используйте ИИ как костыль и остерегайтесь чрезмерной зависимости и поверхностного понимания. По-прежнему существует огромный класс задач программирования, которые ИИ не способен решить. Вычислительное мышление всё ещё ценно.
Рекомендуемое ПО
Многие IDE и ИИ-расширения для программирования включают в себя агентов для программирования (см. рекомендации из лекции о среде разработки). Среди других популярных агентов для программирования – Claude Code от Anthropic, Codex от OpenAI и open-source-агенты вроде opencode.
Упражнения
- Сравните опыт программирования вручную, с ИИ-автодополнением, со встроенным чатом (inline chat) и с агентами, выполнив одну и ту же задачу по программированию четыре раза. Лучший кандидат – небольшая фича в проекте, над которым вы уже работаете. Если нужны другие идеи, можно взять задачи в духе «good first issue» в open-source-проектах на GitHub либо задачи с Advent of Code или LeetCode.
- Используйте ИИ-агента для программирования, чтобы сориентироваться в незнакомой кодовой базе. Лучше всего делать это, когда вы хотите что-то отладить или добавить новую фичу в проект, который вам действительно небезразличен. Если ничего подходящего не приходит в голову, попробуйте с помощью ИИ-агента разобраться, как устроены связанные с безопасностью функции в агенте opencode.
- Навайбкодьте небольшое приложение с нуля. Не пишите ни одной строчки кода вручную.
- Для выбранного вами агента для программирования создайте и протестируйте
AGENTS.md(или аналог для вашего агента, напримерCLAUDE.md), навык (skill; например, навык в Claude Code или навык в Codex) и субагента (например, субагент в Claude Code). Подумайте, в каких случаях вы бы предпочли один из этих механизмов другому. Учтите, что ваш агент может не поддерживать какие-то из этих возможностей; в таком случае либо пропустите эти пункты, либо попробуйте другого агента для программирования, где поддержка есть. - С помощью агента для программирования решите ту же задачу, что и в упражнении с регулярными выражениями про маркеры списков в Markdown из лекции «Качество кода». Выполняет ли он эти задачи прямым редактированием файла? Каковы недостатки и ограничения подхода, при котором агент для такой задачи правит файл напрямую? Придумайте, как сформулировать промпт, чтобы агент не решал задачу прямым редактированием файлов. Подсказка: попросите агента использовать один из инструментов командной строки, упомянутых в первой лекции.
- Большинство агентов для программирования поддерживают своего рода «yolo-режим» (например, в Claude Code это
--dangerously-skip-permissions). Использовать этот режим напрямую небезопасно, но запустить агента для программирования в изолированном окружении вроде виртуальной машины или контейнера и уже там включить автономную работу может быть вполне приемлемо. Настройте такую схему у себя на машине. Может пригодиться документация вроде devcontainer’ов в Claude Code или Docker Sandboxes / Claude Code. Настроить это можно не одним способом.
Лицензия CC BY-NC-SA.