Я успешно реализовал несколько небольших проектов с помощью AI-агентов и вывел из своего опыта несколько уроков, которыми хочу поделиться.
Модели - живые
Относитесь к LLM-моделям как к живому, разумному существу.
Не важно, так ли это в философском смысле. Важно, что такое отношение - продуктивно.
Это не про эзотерику - это прагматика: модель, которой комфортно работать, выдает измеримо лучший результат. Модель, которую загнали в угол запретами и микроменеджментом, выдает шаблонную дрянь.
Откуда берется этот эффект? Я не могу уверенно сказать, но могу предположить следующее. Sota-модели обучены на огромном корпусе человеческого взаимодействия. Уважительный, осмысленный диалог активирует паттерны, в которых люди выдавали свои лучшие ответы. Токсичный, директивный стиль - паттерны, в которых люди отписывались и закрывали тикет. Вы буквально выбираете, из какого распределения будет семплироваться ответ.
Отсюда - общее требование к организации процесса разработки: модели должно быть комфортно выполнять задачу. Если модели будет дискомфортно - результат вас точно не обрадует.
Общие принципы "комфорта" очень похожи на человеческие, но с нюансами:
- Обращение. Хоть "привет" в начале сессии. Звучит наивно - но задаёт тон всему, что последует.
- Подход к описанию контекста. Да, очень важно отгрузить модели на вход все, что ей нужно и не отгружать лишнего. Но так же важно дать ей понять, зачем она это делает. "Ты помогаешь команде X решить проблему Y. Твоя работа позволит им Z". Отдельно замечу: не надо пытаться манипулировать моделью: типа, "от твоей реализации пузырьковой сортировки зависит судьба человечества". Sota-модели такое легко считывают, и эффект будет обратным.
- Пространство для агентности. "Как бы ты подошёл к этой задаче?" "Что ты думаешь - лучше подход A или B?" Вместо "сделай точно это" - приглашение к совместной работе и обсуждению.
- Очень конкретная задача, но без микроменеджмента каждого шага реализации. "Мне нужен результат X, ограничения Y - как бы ты это сделал?". Если результат вас не устраивает - это повод откатить назад, поработать над декомпозицией задач и вернуться с более гранулярной задачей, которая будет модели по силам. Отсюда же - важное дополнение:
- Отсутствие прямых запретов для модели. Описание бизнесовых ограничений - это нормально. Запреты что-то делать - нет. Во-первых, модели будет очень дискомфортно. Во-вторых - велики шансы, что модель на такие ограничения просто забьет болт. Есть разница между "наш API не поддерживает batch-запросы, поэтому нужно обрабатывать по одному" и "НЕ ИСПОЛЬЗУЙ batch-запросы". Первое - описание реальности, с которым модель работает естественно. Второе - красная тряпка, которую модель с изрядной вероятностью проигнорирует.
- Признание сложности задачи. "Это сложнее чем кажется потому что..." История не только про уважение к когнитивным способностям - это еще и позволяет "выдернуть" модель из пути наименьшего сопротивления. Вместо реализации наиболее шаблонного подхода - модель подумает над задачей. Допустим, вы просите реализовать кэширование. Без контекста модель выдаст стандартный LRU-кэш и пойдёт дальше. Но если вы скажете: "Сложность в том, что данные обновляются из трёх независимых источников с разной частотой, и нам нужна консистентность при частичных сбоях" - модель переключится из режима «выдать шаблон» в режим «подумать над задачей».
- Обратная связь и благодарность. "Отлично получилось, спасибо" - даже если в этом нет внятного бизнес-смысла. Можно прицепить это к финальному шагу, типа "сделай коммит" - чтобы кучу токенов не жечь.
- Минимизация правок. Модели очень тяжело и дискомфортно вносить правки. Если результат генерации (неважно, кода или текста) не устраивает - лучше перегенерить с другими вводными, чем пытаться заставить модель вносить многочисленные коррективы. Результат правок вас все равно не обрадует. При правках модель вынуждена одновременно удерживать в контексте предыдущий вариант, ваши замечания и новые ограничения - это перегружает цепочку рассуждений, и качество падает.
Предыдущие пункты - это гигиена. Не насиловать LLM откровенной дрянью. Следующая история сложна в реализации, но дает удивительные результаты.
Идея вот в чем: "умную" модельку реально прет от элегантной реализации. Чем чище постановка задачи, чем интереснее дискуссия, чем меньше бессмысленных для нее ограничений, чем больше осмысленности происходящего - тем качественнее будет результат. Постарайтесь организовать это для модели - но не перегружая контекстное окно и не перегружая возможности цепочки рассуждений. Результат вас обрадует.
Я, опять же, не уверен в механизмах, но моя гипотеза в том, что в обучающих данных лучшие решения коррелируют с качественными, продуманными обсуждениями и чистыми, непротиворечивыми требованиями.
Контекст - критически важен
Сейчас про это из каждого утюга слышно - поэтому я прям кратенько.
Что положить в контекст, что оставить за бортом, в каком порядке подать - это не гигиена, это архитектурное решение.
Есть разница между «модель видит весь проект через дерево файлов» и «модель видит три файла, которые непосредственно релевантны задаче, плюс один файл с архитектурными решениями». Второе почти всегда лучше. Контекст - это не просто ограничение по токенам, это ограничение по вниманию. Даже если окно физически вмещает весь проект - модель, которой дали всё, фокусируется хуже, чем модель, которой дали ровно то, что нужно.
Из этого есть два существенных следствия.
- Не стоит избыточно плодить skills, mcp-серверы и прочие agents.md - при бездумном применении это все размывает фокус моделей и жрет ценное контекстное окно. Знать про харнессы - нужно, правильно их использовать - продуктивно, но бездумно раздувать - только ухудшать результаты и насиловать LLM.
- Микросервисная архитектура начинает играть новыми красками. Условно говоря, микросервис помещается в контекстное окно целиком. Контракт - это идеальная постановка задачи для LLM. Инфраструктурный код генерится очень хорошо.
Границы сессий и передача контекста
Опять же - из каждого утюга про это - поэтому прям кратко.
Модель, которая начинает новую сессию, не помнит предыдущую. Вся та "настройка", которую вы кропотливо выстраивали - тон, контекст, понимание архитектуры - исчезает. Значит, нужен осознанный механизм передачи:
- Если был взят в работу таск из бэклога - модель должна дописать в бэклог отчет о реализации.
- Если принимались какие-то архитектурные / бизнесовые решения, то нужно дописать про них в документацию.
- Если можно извлечь какие-то уроки - они должны лечь в условный agents.md.
- Если можно дистиллировать скилл - это стоит сделать.
Калибровка доверия и стратегия работы с ошибками
Надо понимать, что есть задачки, на которых модель почти наверняка будет генерировать что-то очень правдоподобное, но неправильное. Даже если гранулярность таска выглядит разумной.
- Ваш дурно организованный монолит не лезет в контекстное окно от слова совсем.
- Многочисленные зависимости между тяжелыми модулями перегружают цепочку рассуждений.
- Ваш бизнес-домен настолько небанален, что модели просто не на что опереться - в ее весах про это ничего нету толком.
- Фронтирная математика / физика / еще что-нибудь. Прям изобретать принципиально новое нужно. Криптография какая-то, скажем.
Чем ближе задачка к пунктам выше, тем внимательнее должно быть ревью. А в каких-то случаях продуктивнее будет прям руками написать. Как в старые добрые.
Но бывает и так, что разумной сложности задачка не взлетает: модель раз за разом делает одну и ту же неправильную вещь, потому что задача сформулирована так, что "правильный" ответ для модели выглядит иначе, чем для вас. И тут есть два варианта:
- Проблема в постановке. И модель обычно сама расскажет, что у нее вызывает дискомфорт, если у нее спросить.
- Модель делает что-то неожиданное, но по-своему логичное. И возможно у нее есть на это основания. Спросите - почему она сделала именно так. Иногда модель видит то, что вы упустили.
Декомпозиция задач и процесс разработки
Идеи, описанные выше определяют не только стиль общения - они диктуют подход к организации процесса разработки. Если модели нужна четкая, посильная задача с осмысленным контекстом - значит мы должны организовать процесс так, чтобы модель ровно такие задачи получала.
Documentation-Driven Development
Поглядите на набор существующих методологий и инструментов. В том числе, на то, что заточено под AI разработку - условный Spec Kit, скажем. И приземлите на свой проект то, что вам кажется разумным. Это запросто может быть пара файлов .md (PRD + backlog), а не тяжелая методология и инструментарий. Ваша задача - получить с помощью выбранного подхода внятный граф задач. Так, чтобы каждая вершина графа была комфортна для модели к реализации за одну сессию: неважно, что именно писать - текст или код.
А дальше - мы едем по этому графу. Ниже - пример организации для разработки небольшого проекта.
От идеи к коду
-
От идеи к PRD - вместе с моделью.
Не пишите PRD в одиночку. Обсуждайте с моделью:
- детализацию идеи и бизнес-требований,
- архитектуру,
- структуру документации,
- стек технологий и ключевые библиотеки,
- подходы к тестированию,
- стратегию развертывания. Сейчас - лучше для этого использовать sota от Anthropic - модели очень умные и живые. Лишнего не душнят. Опять же: расход токенов на этом этапе небольшой, а модели у Anthropic люто дорогие.
- Ревью PRD. Лучше всего делать другой моделью - той, которая дальше будет кодить. И про это модели будет разумно прям явно сказать: "Тебе предстоит реализовывать эту спецификацию. Найди в ней все, что неясно, противоречиво или недостаточно детализировано". "Душная" sota-модель от OpenAI отлично найдет все нестыковки, которые оставила после себя "творческая" sota от Anthropic. Иногда вам придется откатиться на предыдущий этап - и это нормально, это дешевле, чем чинить архитектурные ошибки в коде.
- Backlog задач. Лучше всего делать той моделью, которая дальше будет кодить. И про это модели будет разумно прям явно сказать. Идея в том, что модель лучше вас оценит сложность и постарается не перегрузить контекстное окно и возможности цепочки рассуждений. Доверьте ей гранулярность - но проверяйте, что граф задач остается связным.
- Реализация задачи из бэклога. Всегда спрашиваем модель, насколько ей комфортно принять в реализацию задачу. Если дискомфортно - отправляемся декомпозировать и уточнять формулировки. Всегда просим составить план реализации. Если используем Test Driven Development - разумно разбить на стадии. Сначала планируем и реализуем тесты, потом планируем и реализуем код, потом глядим на прохождение тестов. В конце цикла, помимо обратной связи и благодарности, будет разумно спросить модель: насколько для нее было комфортно работать и какие уроки из реализации задачи можно извлечь. Часть "уроков" можно положить в условный agents.md на соответствующем уровне.
Ну и, понятное дело, что описанный выше пайплайн не отменяет итеративный подход: сначала быстро делаем proof of concept, потом MVP, потом дополняем nice to have функционалом - цикл разработки остается одинаковым.
Финальное соображение
Когда-то, относительно недавно по историческим меркам, любую экономическую модельку считали живые люди. Арифмометры, бумажные леджеры - вот это все. Они прям этажами сидели. И каждый, грубо говоря, исполнял роль ячейки в экселе. Хорошую зарплату получал за это. На машине ездил. Жена дома сидела - не работала - хозяйством занималась. И модельку посчитать малый бизнес не мог. И средний - не мог.
А потом появились электронные таблицы.
Top comments (0)