Руководитель отдела агентов и ассистентов
Thursday, 23 Apr 2026
Оговорюсь сразу: моё отношение к ИИ-ассистентам не может быть выражено булевым значением. Если вам нужен ответ на поставленный ребром вопрос: «Нью-Йорк Янкиз или Бостон Ред Сокс?» — то я вообще не смотрю бейсбол, а болею — за Барсу. Тем не менее, я нахожу ИИ-помощников вполне легитимным и даже ликвидным подспорьем. Текст ниже — рассказ о том, что сделало мою работу с агентами приятной, а ошибки и шероховатости последних — свело к приемлемому минимуму.
Чуть меньше года назад я начал работать над проектом Cure, языком программирования с завтипами, конечными автоматами как гражданами первого сорта, SMT-верификацией и прочими плюшками, который компилируется в BEAM.
Мой первый подход к снаряду закончился позорным провалом. Я запутался в собственных архитектурных решениях, начал городить костыли по месту, полностью превратил код в меню итальянского ресторана и у меня опустились руки. В приступе идиотизма я сгенерировал ассистентом сайт и показал его публике — интересных решений там было хоть отбавляй, завтипы и солверы в BEAM — явно не будут лишними, и я втуне понадеялся на помощь сообщества. Сообщество корректно идентифицировало сайт языка как мусор, сгенерированный языковой моделью, и приняло мою попытку крайне прохладно. Я получил много отзывов «ничего не работает» и не единого внятного предложения об улучшении (сообщество не в чем винить, на фоне слоп-потопа тех дней мой проект даже для крайне лояльного зрителя уж никак не походил на ноев ковчег).
Тогда я сделал шаг назад, придирчиво осмотрел свое творение со всех сторон и был вынужден признать: я породил чудовище. Никаких шансов довести его до ума, даже путем глобального рефакторинга, я не видел. Я купил пачку бумаги и карандаши, и стал рисовать, чтобы понять, в чем именно я облажался. (Спойлер: я был настолько очарован самой идеей, и так сильно хотел довести ее до состояния чего-то запускавшегося и работавшего, что сделал неправильно буквально все.)
Сдаваться я, впрочем, не собирался, — и передо мной во весь свой исполинский рост выросла необходимость все переписать с нуля, не повторяя ошибок. К тому моменту я знал, что искусственные ассистенты могут значительно ускорить процесс собственно написания кода, поэтому я начал с постройки строительных лесов вокруг будущего проекта. Мне было очевидно (сейчас я могу подтвердить свое тогдашнее прозрение — опытом), что все эти промпты «Ты — гениальный архитектор, триста лет разрабатывавший языки с завтипами и солверами» — работают не лучше, чем утренняя установка стажеру на митинге: «Ты — великий программист, написавший триста миллионов миллиардов строк кода без отладчика». Если бы ассистент, перед которым ставят задачу написать внятный код по ТЗ, нуждался бы в мотивационной херне, — ими бы не сто́ило пользоваться ни при каких обстоятельствах. Не, серьёзно, вдумайтесь: модель просят создать модуль расчета НОД по алгоритму Эвклида, так неужели внутренние, глубоко захардкоженные правила, — не помогут ей пройти по правильным веткам условных операторов, и прийти к выводу, что навыки балерины и поэта-авангардиста в данном случае уступают по важности «образованию» в сфере IT? Что нафиг вообще значит предложение писать «Ты ведущий архитектор»? Люди, пропагандирующие это, — полагают, что без такой преамбулы активизируются пути обучения по мемуарам заводчиков тритонов?
В общем, вместо всех этих skills/agents/whatever, я начал с того, что скормил этому механизированному чудовищу код всех собственных библиотек, заботливо написанных вручную, с напутствием: «Вот тебе примеры хорошего кода. Вот так пиши. А не так — не пиши». Я знаю, что это нескромно, но это мой ассистент. Вашему можете кормить ваш код вместо моего.
Затем я мелиорировал пустыню: так родились проекты Metastatic, реализующий MetaAST для разных языков в разных парадигмах, и Ragex — RAG, построенный на AST вместо простого текста (моя догадка о том, что AST гораздо легче влезает в контекстное окно и гораздо лучше структурировано, в сравнении с текстом на языке программирования — оказалась верной).
Я решал задачу создания нового языка, проблема построения новой экосистемы с нуля передо мной не стояла. Поэтому я проанализировал существующие решения (Rust, Go, Elm, Gleam) — и выбрал наиболее совершенную на мой взгляд (я никогда не обещал, что проект будет нейтральным к моим предпочтениям и вкусам). Я просто скопировал экосистему эликсира, добавив туда то, чего мне лично не хватало в последние 10 лет. Благодаря тому, что я вскарабкался на плечи гигантов в этом вопросе, всю экосистему за меня практически полностью написала модель, я просто говорил ей: «Смотри, как круто создание нового проекта сделано в эликсире, сделай для Cure так же». В переводе языковые модели сильны, а эликсир для них гораздо более внятен в сравнении почти со всеми остальными языками.
Итак, до первой строчки кода у меня в рюкзаке уже лежали: правильный AST, на котором нам с ассистентом разговаривать гораздо легче, чем на посконном английском, рукотворный RAG и четкое осознание того, что каждый шаг должен быть простым атомарным изменением. Чем меньше ассистенту приходится выбирать между двумя путями — тем чище результат. Этот принцип важнее качества всех промптов вместе взятых.
Теперь мне предстояло решить задачу валидации производимого кода. Мои глаза — очень зоркие, но иногда и они упускают неочевидные плохие решения на ревью. Так родилась библиотека oeditus_credo — набор из почти сорока дополнительных проверок credo. Уязвимости, анти-паттерны, и тому подобное. У этой библиотеки есть помимо прочего mix oeditus_assistant_rules, генератор правил для бездушного ассистента. Еще я к этим правилам добавил: после каждого этапа необходимо удостовериться, что mix format && mix credo --strict && mix dialyzer && mix test проходит, необходимо обновить всю документацию, необходимо добавить регрессионные тесты для нового кода а потом — запустить все регрессионные тесты и удостовериться, что они все ещё зеленые, как моё лицо с похмелья.
Еще каждый более-менее серьёзный этап заканчивается созданием «примера» в папке examples. И людям есть, куда заглянуть, и регрессионные тесты не простаивают.
В этот момент я почувствовал, что можно приступать к написанию кода. В Cure есть некоторые критические части, написанные мной вручную с нуля. Каждый второй PR подвергается моим ручным правкам. Все найденные мною на ручных тестах ошибки — я правлю руками (кроме очевидных). И, тем не менее, я достиг желаемого результата значительно быстрее, чем если бы я весь код создавал в VIM’е.
За время работы над Cure я научился делать так, чтобы количество ошибок (и, как следствие, ручных правок) — оказалось бы минимальным. Довольно объёмный релиз v0.26.0 не потребовал ни единой правки, например. Вот дистиллят моих правил общения с ассистентом, вдруг кому-нибудь пригодится:
- задача должна быть завершённой, но не слишком большой; «сейчас определи типы для numeric, а потом мы напишем конвертеры» — не работает
- внутри задачи не должно быть никаких неопределенных условностей, которые собъют наш T9 с толку; путь к решению должен быть один
- перед решением любой задачи необходимо требовать план реализации и редактировать его, пока неопределенности не исчезнут
- задачу необходимо примерно решить в уме, прежде чем обращаться к ассистенту, иначе высока вероятность согласия с неверным решением
- сгенерированный код должен быть понятен и изящен: «перепиши красиво, я же тебе вон три гигабайта правил скормил» — не работает; если решение эстетически отталкивающее — значит, есть проблемы с постановкой задачи — закройте сессию и начните с нуля
- поставить задачу и уйти пить кофе — прямой путь в бесконечные итерации из предыдущего пункта; за потоком бессознательного необходимо следить и безжалостно прерывать любые потуги свернуть с намеченного пути
- наконец, если вам кажется, что когнитивная нагрузка снижается, и что даже кухарка теперь сможет реализовать такой проект — вам необходимо медикаментозное лечение; пальцы устают меньше, это да, но если бы вы не смогли реализовать проект с нуля в текстовом редакторе — LLM вам не помощник; она нагенерирует что-то подозрительно шевелящееся, тут спору нет, но первая же мало-мальски серьёзная сложность, требующая взвешенного архитектурного решения, — поставит на всем проекте крест.
Вот такой опыт. Ваш может отличаться, я не претендую.
Попробуйте
Dependently-typed programming language for the BEAM with first-class FSMs and SMT-backed verification.
Удачного куринга!