<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>40Ants</title><link>https://40ants.com/</link><description>Just an example of the static file generated by StatiCL.</description><guid isPermaLink="false">https://40ants.com/</guid><lastBuildDate>Mon, 07 Sep 2026 15:39:41 +0000</lastBuildDate><item><title>Отсчет времени в разметке на GitHub</title><link>https://40ants.com/ru/posts/otschet-vremeni-v-raz-79/</link><description>&lt;p&gt;&lt;img src=&quot;https://40ants.com/ru/posts/images/79.jpeg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;

&lt;p&gt;Недавно исследовал, как выглядят комментарии Codex в pull request на GitHub. В некоторых из них увидел время, показывающее, как давно агент сделал ревью. Сначала подумал, что это какая-то обычная часть интерфейса GitHub, но оказалось — нет.&lt;/p&gt;

&lt;p&gt;В markdown разметку GitHub можно вставить специальный элемент &lt;code&gt;&amp;lt;relative-time&amp;gt;&lt;/code&gt;. Ему передаётся момент времени, а на фронтенде он сам превращается в понятную надпись вроде «5 minutes ago». И продолжает её обновлять, даже если страницу не рефрешить.&lt;/p&gt;

&lt;p&gt;Например, выглядит это так:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
&amp;lt;relative-time datetime=&amp;quot;2026-09-05T12:00:00Z&amp;quot;&amp;gt;
  5 сентября 2026
&amp;lt;/relative-time&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Я сделал &lt;a href=&quot;https://gist.github.com/svetlyak40wt/716a74948f3dc09dd3030932af122d32&quot;&gt;простой gist&lt;/a&gt;, где можно посмотреть на это вживую.&lt;/p&gt;

&lt;p&gt;Мне кажется, такой элемент особенно хорошо подходит для документации. Можно пометить функцию как устаревающую и написать, что она будет удалена из API в определённую дату. Вместо статичной даты читатель увидит, сколько дней осталось до удаления.&lt;/p&gt;

&lt;p&gt;Прикольно то, что &lt;code&gt;relative-time&lt;/code&gt; — не внутренний компонент GitHub. Это &lt;a href=&quot;https://github.com/github/relative-time-element&quot;&gt;отдельный веб-компонент&lt;/a&gt;, который можно поставить в свой проект.&lt;/p&gt;
</description><guid isPermaLink="false">https://40ants.com/ru/posts/otschet-vremeni-v-raz-79/</guid><lastBuildDate>Mon, 07 Sep 2026 15:39:41 +0000</lastBuildDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://40ants.com/ru/posts/images/79.jpeg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;

&lt;p&gt;Недавно исследовал, как выглядят комментарии Codex в pull request на GitHub. В некоторых из них увидел время, показывающее, как давно агент сделал ревью. Сначала подумал, что это какая-то обычная часть интерфейса GitHub, но оказалось — нет.&lt;/p&gt;

&lt;p&gt;В markdown разметку GitHub можно вставить специальный элемент &lt;code&gt;&amp;lt;relative-time&amp;gt;&lt;/code&gt;. Ему передаётся момент времени, а на фронтенде он сам превращается в понятную надпись вроде «5 minutes ago». И продолжает её обновлять, даже если страницу не рефрешить.&lt;/p&gt;

&lt;p&gt;Например, выглядит это так:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
&amp;lt;relative-time datetime=&amp;quot;2026-09-05T12:00:00Z&amp;quot;&amp;gt;
  5 сентября 2026
&amp;lt;/relative-time&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Я сделал &lt;a href=&quot;https://gist.github.com/svetlyak40wt/716a74948f3dc09dd3030932af122d32&quot;&gt;простой gist&lt;/a&gt;, где можно посмотреть на это вживую.&lt;/p&gt;

&lt;p&gt;Мне кажется, такой элемент особенно хорошо подходит для документации. Можно пометить функцию как устаревающую и написать, что она будет удалена из API в определённую дату. Вместо статичной даты читатель увидит, сколько дней осталось до удаления.&lt;/p&gt;

&lt;p&gt;Прикольно то, что &lt;code&gt;relative-time&lt;/code&gt; — не внутренний компонент GitHub. Это &lt;a href=&quot;https://github.com/github/relative-time-element&quot;&gt;отдельный веб-компонент&lt;/a&gt;, который можно поставить в свой проект.&lt;/p&gt;
</content:encoded></item><item><title>Herdr вместо tmux для работы с несколькими AI-агентами</title><link>https://40ants.com/ru/posts/herdr-vmesto-tmux-dl-78/</link><description>&lt;p&gt;&lt;img src=&quot;https://40ants.com/ru/posts/images/78.jpeg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;

&lt;p&gt;У меня обычно одновременно запущено несколько AI-агентов: один что-то пишет в одном проекте, другой разбирается с багом в другом, третий ждёт, пока я отвечу на вопрос. Раньше для этого я поднимал tmux-сессии.&lt;/p&gt;

&lt;p&gt;Tmux отлично решает базовую задачу: процессы не умирают при закрытии терминала, есть окна и панели. Но когда агентов становится несколько, проверять их состояние не очень удобно. Приходится переключаться между панелями и смотреть: он ещё думает, закончил или уже ждёт от меня решения?&lt;/p&gt;

&lt;p&gt;Недавно попробовал &lt;a href=&quot;https://herdr.dev/&quot;&gt;Herdr&lt;/a&gt;. Это тоже терминальный мультиплексор: есть workspaces, вкладки и панели. Но в боковой панели он ещё показывает состояние агентов: работает, заблокирован вопросом, закончил работу или уже просмотрен. Поэтому можно одним взглядом понять, куда сейчас стоит пойти, а кого лучше не трогать.&lt;/p&gt;

&lt;p&gt;Особенно понравился remote-режим. Достаточно запустить локально:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
herdr --remote user@server
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Herdr сам подключается по SSH, а если на сервере нет подходящей версии, ставит совместимый бинарник и поднимает удалённую сессию. Интерфейс при этом остаётся локальным: по умолчанию используются мои локальные клавиши. Не надо, как раньше с tmux, отдельно переносить и синхронизировать конфиг между ноутбуком и сервером, хотя конечно, SSH-доступ и окружение для самих агентов на сервере всё равно надо подготовить.&lt;/p&gt;

&lt;p&gt;Кстати, сами настройки Herdr, более человечные, чем в Tmux. Начать хотя бы с того, что табы по умолчанию нумеруются с 1 а не с 0 и заканчивая тем, что настроечки можно менять через TUI диалоговые окна, а не только через конфиг.&lt;/p&gt;

&lt;p&gt;Короче, попробую пожить с Herdr вместо tmux.&lt;/p&gt;
</description><guid isPermaLink="false">https://40ants.com/ru/posts/herdr-vmesto-tmux-dl-78/</guid><lastBuildDate>Mon, 07 Sep 2026 15:39:41 +0000</lastBuildDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://40ants.com/ru/posts/images/78.jpeg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;

&lt;p&gt;У меня обычно одновременно запущено несколько AI-агентов: один что-то пишет в одном проекте, другой разбирается с багом в другом, третий ждёт, пока я отвечу на вопрос. Раньше для этого я поднимал tmux-сессии.&lt;/p&gt;

&lt;p&gt;Tmux отлично решает базовую задачу: процессы не умирают при закрытии терминала, есть окна и панели. Но когда агентов становится несколько, проверять их состояние не очень удобно. Приходится переключаться между панелями и смотреть: он ещё думает, закончил или уже ждёт от меня решения?&lt;/p&gt;

&lt;p&gt;Недавно попробовал &lt;a href=&quot;https://herdr.dev/&quot;&gt;Herdr&lt;/a&gt;. Это тоже терминальный мультиплексор: есть workspaces, вкладки и панели. Но в боковой панели он ещё показывает состояние агентов: работает, заблокирован вопросом, закончил работу или уже просмотрен. Поэтому можно одним взглядом понять, куда сейчас стоит пойти, а кого лучше не трогать.&lt;/p&gt;

&lt;p&gt;Особенно понравился remote-режим. Достаточно запустить локально:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
herdr --remote user@server
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Herdr сам подключается по SSH, а если на сервере нет подходящей версии, ставит совместимый бинарник и поднимает удалённую сессию. Интерфейс при этом остаётся локальным: по умолчанию используются мои локальные клавиши. Не надо, как раньше с tmux, отдельно переносить и синхронизировать конфиг между ноутбуком и сервером, хотя конечно, SSH-доступ и окружение для самих агентов на сервере всё равно надо подготовить.&lt;/p&gt;

&lt;p&gt;Кстати, сами настройки Herdr, более человечные, чем в Tmux. Начать хотя бы с того, что табы по умолчанию нумеруются с 1 а не с 0 и заканчивая тем, что настроечки можно менять через TUI диалоговые окна, а не только через конфиг.&lt;/p&gt;

&lt;p&gt;Короче, попробую пожить с Herdr вместо tmux.&lt;/p&gt;
</content:encoded></item><item><title>Собираюсь на AI Native Conf</title><link>https://40ants.com/ru/posts/sobirayus-na-ai-nati-77/</link><description>&lt;p&gt;&lt;img src=&quot;https://40ants.com/ru/posts/images/77.jpeg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;

&lt;p&gt;В октябре собираюсь пойти на &lt;a href=&quot;https://ainativeconf.ru/&quot;&gt;AI Native Conf&lt;/a&gt;. Интересно посмотреть, что сейчас происходит вокруг разработки с AI и агентами, и послушать доклады людей, которые это всё уже пробуют в реальных проектах.&lt;/p&gt;

&lt;p&gt;Кстати, организаторы этой конфы поделились материалами с предыдущей Agentic Dev Conf — транскрипциями докладов. Я решил собрать их в &lt;a href=&quot;https://github.com/svetlyak40wt/agentic-dev-conf-materials-2026&quot;&gt;отдельный репозиторий на GitHub&lt;/a&gt; и дополнительно добавил README с выжимками самого важного из каждого доклада. Пользуйтесь!&lt;/p&gt;

&lt;p&gt;Если тоже собираетесь на конференцию 20 октября — давайте там встретимся!&lt;/p&gt;
</description><guid isPermaLink="false">https://40ants.com/ru/posts/sobirayus-na-ai-nati-77/</guid><lastBuildDate>Mon, 07 Sep 2026 15:39:41 +0000</lastBuildDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://40ants.com/ru/posts/images/77.jpeg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;

&lt;p&gt;В октябре собираюсь пойти на &lt;a href=&quot;https://ainativeconf.ru/&quot;&gt;AI Native Conf&lt;/a&gt;. Интересно посмотреть, что сейчас происходит вокруг разработки с AI и агентами, и послушать доклады людей, которые это всё уже пробуют в реальных проектах.&lt;/p&gt;

&lt;p&gt;Кстати, организаторы этой конфы поделились материалами с предыдущей Agentic Dev Conf — транскрипциями докладов. Я решил собрать их в &lt;a href=&quot;https://github.com/svetlyak40wt/agentic-dev-conf-materials-2026&quot;&gt;отдельный репозиторий на GitHub&lt;/a&gt; и дополнительно добавил README с выжимками самого важного из каждого доклада. Пользуйтесь!&lt;/p&gt;

&lt;p&gt;Если тоже собираетесь на конференцию 20 октября — давайте там встретимся!&lt;/p&gt;
</content:encoded></item><item><title>Залупливание кодового ассистента</title><link>https://40ants.com/ru/posts/zaluplivanie-kodovog-76/</link><description>&lt;p&gt;&lt;img src=&quot;https://40ants.com/ru/posts/images/76.jpeg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;

&lt;p&gt;На днях мне понадобилось добавить в &lt;a href=&quot;https://github.com/40ants/bots&quot;&gt;40ants-bots&lt;/a&gt; поддержку клиента мессенджера MAX. Раньше библиотека работала только с Telegram, а теперь хочется уметь поддерживать разные мессенджеры.&lt;/p&gt;

&lt;p&gt;Решил сделать это с помощью AI-ассистента и заодно испытать подход Atomic Spec, о котором недавно писал. Попросил агента продумать внедрение, разложить его на отдельные спеки и описать в них весь нужный функционал. С этим он справился вполне неплохо.&lt;/p&gt;

&lt;p&gt;А вот дальше хотелось максимально вайбово: дать модели реализовать всё самой, а потом только проверить результат. Тут и началось. Codex периодически останавливался и спрашивал: &amp;quot;Что делать дальше, хозяин?&amp;quot; Так происходит даже если явно попросить действовать автономно, решать максимум вопросов по дороге и иногда делать коммиты.&lt;/p&gt;

&lt;p&gt;Я задумался: сейчас много пишут, что агентов надо запускать в цикле. Но как запустить цикл, если агент в случайный момент просто заканчивает работу?&lt;/p&gt;

&lt;p&gt;Оказалось, что в Codex есть режим &lt;code&gt;/goal&lt;/code&gt;. Передаёшь ему конечную цель, например «реализовать поддержку MAX по спекам и прогнать тесты». Дальше Codex хранит цель отдельно от очередного сообщения: после остановки проверяет, достигнута ли она, и запускает следующий заход, если нет. Агент должен либо показать, что работа действительно завершена, либо признать настоящий блокер.&lt;/p&gt;

&lt;p&gt;То есть автономность здесь создаёт не промт «РАБОТАЙ АВТОНОМНО», а рантайм, у которого есть понятие незавершённой цели. В этом режиме Codex несколько часов работал над задачами из спек и вот только что сообщил о финальном результате. Теперь пойду смотреть, чего он там назалупливал.&lt;/p&gt;

&lt;p&gt;Кстати, заодно решил посмотрел есть ли подобное в OpenCode. В нём такого режима из коробки нет, но есть плагины. &lt;a href=&quot;https://github.com/danshapiro/opencode-goal-plugin&quot;&gt;danshapiro/opencode-goal-plugin&lt;/a&gt; старается буквально воспроизвести поведение Codex: после остановки снова запускает агента и не ставит лимитов по числу заходов, времени или токенам. Полная остановка — только когда модель доказала завершение, сообщила о блокере или её остановил человек.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/prevalentWare/opencode-goal-plugin&quot;&gt;prevalentWare/opencode-goal-plugin&lt;/a&gt; делает похожую вещь, но с предохранителями: бюджетами, лимитом автоматических ходов, проверкой отсутствия прогресса, учётом дочерних задач и compaction. А &lt;a href=&quot;https://github.com/watzon/opencode-goal&quot;&gt;watzon/opencode-goal&lt;/a&gt; продолжает работу более консервативно: если в очередном ходе не было вызовов тулов, он не продолжает бесконечный разговор модели с собой.&lt;/p&gt;

&lt;p&gt;Получается, &lt;code&gt;danshapiro&lt;/code&gt; — для тех, кто хочет максимально буквальный &lt;code&gt;/goal&lt;/code&gt; из Codex. &lt;code&gt;prevalentWare&lt;/code&gt; — для тех, кто хочет оставить агента работать над большим проектом, но с ограничителями.&lt;/p&gt;

&lt;p&gt;Надо будет обязательно сделать визуализацию таких циклов в Codabrus: смотреть, как кодовый ассистент сам себя залупливает, гораздо веселее, чем просто читать чат.&lt;/p&gt;
</description><guid isPermaLink="false">https://40ants.com/ru/posts/zaluplivanie-kodovog-76/</guid><lastBuildDate>Mon, 07 Sep 2026 15:39:41 +0000</lastBuildDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://40ants.com/ru/posts/images/76.jpeg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;

&lt;p&gt;На днях мне понадобилось добавить в &lt;a href=&quot;https://github.com/40ants/bots&quot;&gt;40ants-bots&lt;/a&gt; поддержку клиента мессенджера MAX. Раньше библиотека работала только с Telegram, а теперь хочется уметь поддерживать разные мессенджеры.&lt;/p&gt;

&lt;p&gt;Решил сделать это с помощью AI-ассистента и заодно испытать подход Atomic Spec, о котором недавно писал. Попросил агента продумать внедрение, разложить его на отдельные спеки и описать в них весь нужный функционал. С этим он справился вполне неплохо.&lt;/p&gt;

&lt;p&gt;А вот дальше хотелось максимально вайбово: дать модели реализовать всё самой, а потом только проверить результат. Тут и началось. Codex периодически останавливался и спрашивал: &amp;quot;Что делать дальше, хозяин?&amp;quot; Так происходит даже если явно попросить действовать автономно, решать максимум вопросов по дороге и иногда делать коммиты.&lt;/p&gt;

&lt;p&gt;Я задумался: сейчас много пишут, что агентов надо запускать в цикле. Но как запустить цикл, если агент в случайный момент просто заканчивает работу?&lt;/p&gt;

&lt;p&gt;Оказалось, что в Codex есть режим &lt;code&gt;/goal&lt;/code&gt;. Передаёшь ему конечную цель, например «реализовать поддержку MAX по спекам и прогнать тесты». Дальше Codex хранит цель отдельно от очередного сообщения: после остановки проверяет, достигнута ли она, и запускает следующий заход, если нет. Агент должен либо показать, что работа действительно завершена, либо признать настоящий блокер.&lt;/p&gt;

&lt;p&gt;То есть автономность здесь создаёт не промт «РАБОТАЙ АВТОНОМНО», а рантайм, у которого есть понятие незавершённой цели. В этом режиме Codex несколько часов работал над задачами из спек и вот только что сообщил о финальном результате. Теперь пойду смотреть, чего он там назалупливал.&lt;/p&gt;

&lt;p&gt;Кстати, заодно решил посмотрел есть ли подобное в OpenCode. В нём такого режима из коробки нет, но есть плагины. &lt;a href=&quot;https://github.com/danshapiro/opencode-goal-plugin&quot;&gt;danshapiro/opencode-goal-plugin&lt;/a&gt; старается буквально воспроизвести поведение Codex: после остановки снова запускает агента и не ставит лимитов по числу заходов, времени или токенам. Полная остановка — только когда модель доказала завершение, сообщила о блокере или её остановил человек.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/prevalentWare/opencode-goal-plugin&quot;&gt;prevalentWare/opencode-goal-plugin&lt;/a&gt; делает похожую вещь, но с предохранителями: бюджетами, лимитом автоматических ходов, проверкой отсутствия прогресса, учётом дочерних задач и compaction. А &lt;a href=&quot;https://github.com/watzon/opencode-goal&quot;&gt;watzon/opencode-goal&lt;/a&gt; продолжает работу более консервативно: если в очередном ходе не было вызовов тулов, он не продолжает бесконечный разговор модели с собой.&lt;/p&gt;

&lt;p&gt;Получается, &lt;code&gt;danshapiro&lt;/code&gt; — для тех, кто хочет максимально буквальный &lt;code&gt;/goal&lt;/code&gt; из Codex. &lt;code&gt;prevalentWare&lt;/code&gt; — для тех, кто хочет оставить агента работать над большим проектом, но с ограничителями.&lt;/p&gt;

&lt;p&gt;Надо будет обязательно сделать визуализацию таких циклов в Codabrus: смотреть, как кодовый ассистент сам себя залупливает, гораздо веселее, чем просто читать чат.&lt;/p&gt;
</content:encoded></item><item><title>Что такое Atomic Spec и зачем он кодовому ассистенту?</title><link>https://40ants.com/ru/posts/chto-takoe-atomic-spe-75/</link><description>&lt;p&gt;В предыдущем посте я упоминал про навык использования Atomic Spec. Расскажу, что это такое и почему этот подход особенно интересен, когда код пишет AI-ассистент.&lt;/p&gt;

&lt;p&gt;Обычно требования к фиче живут в задаче, обсуждении и голове автора. Ассистент получает короткую формулировку, находит похожий код и начинает действовать. Пока задача маленькая, этого хватает. Но чем она длиннее и чем больше в ней исключений, тем проще забыть исходное намерение и сделать технически аккуратную, но неправильную вещь.&lt;/p&gt;

&lt;p&gt;Atomic Spec предлагает хранить требования как набор маленьких «атомов»: один &lt;code&gt;*.spec.md&lt;/code&gt; — одна единица знания. У атомов есть иерархия: система, домен, use case и сценарии. Внутри файла сначала лежит то, что не зависит от конкретного фреймворка: намерение, доменные правила, критерии приёмки и ограничения. Ниже — API, детали реализации и план тестов.&lt;/p&gt;

&lt;p&gt;Самая важная для меня часть здесь — доменные правила. Это не «проверить поле в форме» и не «вызвать такой-то метод». Это правила предметной области, которые должны оставаться верными независимо от того, на чём написан код. Например: пользователь не может зарегистрироваться с уже занятым email, заказ нельзя оплатить дважды, а скидка не должна сделать сумму отрицательной. Когда такие правила явно записаны, у ассистента появляется не только задача, но и границы, которые нельзя случайно сломать при рефакторинге.&lt;/p&gt;

&lt;p&gt;В Atomic Spec это превращается в последовательный процесс. Сначала аналитик фиксирует намерение, правила и критерии приёмки. Затем разработчик добавляет техническую спецификацию и код. Потом тестировщик проверяет, что каждый сценарий и каждое доменное правило покрыты тестами. Между этапами есть gate-проверки: если в требованиях остались противоречия или реализация не покрывает правило, следующий этап не начинается.&lt;/p&gt;

&lt;p&gt;Сам skill для кодового ассистента играет роль оркестратора. Он декомпозирует задачу на атомы, переключает роли аналитика, разработчика и тестировщика, валидирует результаты и придерживается соглашений для веток и коммитов. Получается не магический промпт «сделай правильно», а повторяемый маршрут: задача → требования → код → тесты. И все эти артефакты ссылаются на один источник.&lt;/p&gt;

&lt;p&gt;Конечно, для исправления одной опечатки это избыточно. Но на проекте, который развивается неделями, такая дисциплина даёт ассистенту устойчивый контекст и возможность понять, почему код устроен именно так.&lt;/p&gt;

&lt;p&gt;Сейчас я пробую применять эту методологию для нескольких своих проектах и &lt;a href=&quot;https://github.com/dab512/atomic-spec&quot;&gt;использую skill&lt;/a&gt;, созданный одним из моих коллег.&lt;/p&gt;
</description><guid isPermaLink="false">https://40ants.com/ru/posts/chto-takoe-atomic-spe-75/</guid><lastBuildDate>Mon, 07 Sep 2026 15:39:41 +0000</lastBuildDate><content:encoded>&lt;p&gt;В предыдущем посте я упоминал про навык использования Atomic Spec. Расскажу, что это такое и почему этот подход особенно интересен, когда код пишет AI-ассистент.&lt;/p&gt;

&lt;p&gt;Обычно требования к фиче живут в задаче, обсуждении и голове автора. Ассистент получает короткую формулировку, находит похожий код и начинает действовать. Пока задача маленькая, этого хватает. Но чем она длиннее и чем больше в ней исключений, тем проще забыть исходное намерение и сделать технически аккуратную, но неправильную вещь.&lt;/p&gt;

&lt;p&gt;Atomic Spec предлагает хранить требования как набор маленьких «атомов»: один &lt;code&gt;*.spec.md&lt;/code&gt; — одна единица знания. У атомов есть иерархия: система, домен, use case и сценарии. Внутри файла сначала лежит то, что не зависит от конкретного фреймворка: намерение, доменные правила, критерии приёмки и ограничения. Ниже — API, детали реализации и план тестов.&lt;/p&gt;

&lt;p&gt;Самая важная для меня часть здесь — доменные правила. Это не «проверить поле в форме» и не «вызвать такой-то метод». Это правила предметной области, которые должны оставаться верными независимо от того, на чём написан код. Например: пользователь не может зарегистрироваться с уже занятым email, заказ нельзя оплатить дважды, а скидка не должна сделать сумму отрицательной. Когда такие правила явно записаны, у ассистента появляется не только задача, но и границы, которые нельзя случайно сломать при рефакторинге.&lt;/p&gt;

&lt;p&gt;В Atomic Spec это превращается в последовательный процесс. Сначала аналитик фиксирует намерение, правила и критерии приёмки. Затем разработчик добавляет техническую спецификацию и код. Потом тестировщик проверяет, что каждый сценарий и каждое доменное правило покрыты тестами. Между этапами есть gate-проверки: если в требованиях остались противоречия или реализация не покрывает правило, следующий этап не начинается.&lt;/p&gt;

&lt;p&gt;Сам skill для кодового ассистента играет роль оркестратора. Он декомпозирует задачу на атомы, переключает роли аналитика, разработчика и тестировщика, валидирует результаты и придерживается соглашений для веток и коммитов. Получается не магический промпт «сделай правильно», а повторяемый маршрут: задача → требования → код → тесты. И все эти артефакты ссылаются на один источник.&lt;/p&gt;

&lt;p&gt;Конечно, для исправления одной опечатки это избыточно. Но на проекте, который развивается неделями, такая дисциплина даёт ассистенту устойчивый контекст и возможность понять, почему код устроен именно так.&lt;/p&gt;

&lt;p&gt;Сейчас я пробую применять эту методологию для нескольких своих проектах и &lt;a href=&quot;https://github.com/dab512/atomic-spec&quot;&gt;использую skill&lt;/a&gt;, созданный одним из моих коллег.&lt;/p&gt;
</content:encoded></item><item><title>Осторожно: skill с сюрпризом!</title><link>https://40ants.com/ru/posts/ostorozhno-skill-s-s-74/</link><description>&lt;p&gt;&lt;img src=&quot;https://40ants.com/ru/posts/images/74.jpeg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;

&lt;p&gt;В одном из последних проектов я решил попробовать подход Atomic Spec. Это когда системные требования фиксируются в отдельных файлах, чтобы кодовый ассистент мог сверяться с ними при добавлении новых фич.&lt;/p&gt;

&lt;p&gt;Начал искать skill для работы с Atomic Spec и наткнулся на GitHub репу &lt;code&gt;lovely392/atomic-spec&lt;/code&gt;. На первый взгляд — вроде бы свежая и улучшенная версия. Но устанавливать его не спешите.&lt;/p&gt;

&lt;p&gt;Похоже, автор взял существующий репозиторий, внёс косметические правки и залил результат как новый. Это не fork, поэтому связи с исходным проектом на GitHub не видно.&lt;/p&gt;

&lt;p&gt;А дальше в README начинается совсем странное. Вместо инструкции по установке навыка предлагается скачать ZIP-архив, распаковать его и запустить файл на Windows. Причём там отдельно объясняют, как пройти системные предупреждения и продолжить запуск. Для skill-а кодового ассистента это выглядит, мягко говоря, подозрительно.&lt;/p&gt;

&lt;p&gt;То есть получается такой вирус, который нужно установить самому. И это особенно неприятно в эпоху кодовых ассистентов: ассистент вполне может прочитать README, сходить по ссылке, скачать архив и выполнить инструкцию. В итоге вместо нового skill-а на компьютер может попасть какой-нибудь троян.&lt;/p&gt;

&lt;p&gt;Это хороший повод помнить, что skills, MCP-серверы и их инструкции — тоже часть supply chain. Перед установкой стоит посмотреть, откуда взялся репозиторий, является ли он форком, что именно менялось и почему «навык» вдруг требует запустить .exe.&lt;/p&gt;

&lt;p&gt;А тем, кому интересно попробовать Atomic Spec в работе, вот &lt;a href=&quot;https://github.com/dab512/atomic-spec&quot;&gt;оригинальный репозиторий&lt;/a&gt;. Там Atomic Spec — это именно методология и skill для кодового ассистента, а не Windows-приложение из архива.&lt;/p&gt;
</description><guid isPermaLink="false">https://40ants.com/ru/posts/ostorozhno-skill-s-s-74/</guid><lastBuildDate>Mon, 07 Sep 2026 15:39:41 +0000</lastBuildDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://40ants.com/ru/posts/images/74.jpeg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;

&lt;p&gt;В одном из последних проектов я решил попробовать подход Atomic Spec. Это когда системные требования фиксируются в отдельных файлах, чтобы кодовый ассистент мог сверяться с ними при добавлении новых фич.&lt;/p&gt;

&lt;p&gt;Начал искать skill для работы с Atomic Spec и наткнулся на GitHub репу &lt;code&gt;lovely392/atomic-spec&lt;/code&gt;. На первый взгляд — вроде бы свежая и улучшенная версия. Но устанавливать его не спешите.&lt;/p&gt;

&lt;p&gt;Похоже, автор взял существующий репозиторий, внёс косметические правки и залил результат как новый. Это не fork, поэтому связи с исходным проектом на GitHub не видно.&lt;/p&gt;

&lt;p&gt;А дальше в README начинается совсем странное. Вместо инструкции по установке навыка предлагается скачать ZIP-архив, распаковать его и запустить файл на Windows. Причём там отдельно объясняют, как пройти системные предупреждения и продолжить запуск. Для skill-а кодового ассистента это выглядит, мягко говоря, подозрительно.&lt;/p&gt;

&lt;p&gt;То есть получается такой вирус, который нужно установить самому. И это особенно неприятно в эпоху кодовых ассистентов: ассистент вполне может прочитать README, сходить по ссылке, скачать архив и выполнить инструкцию. В итоге вместо нового skill-а на компьютер может попасть какой-нибудь троян.&lt;/p&gt;

&lt;p&gt;Это хороший повод помнить, что skills, MCP-серверы и их инструкции — тоже часть supply chain. Перед установкой стоит посмотреть, откуда взялся репозиторий, является ли он форком, что именно менялось и почему «навык» вдруг требует запустить .exe.&lt;/p&gt;

&lt;p&gt;А тем, кому интересно попробовать Atomic Spec в работе, вот &lt;a href=&quot;https://github.com/dab512/atomic-spec&quot;&gt;оригинальный репозиторий&lt;/a&gt;. Там Atomic Spec — это именно методология и skill для кодового ассистента, а не Windows-приложение из архива.&lt;/p&gt;
</content:encoded></item><item><title>Как работает AI ассистент</title><link>https://40ants.com/ru/posts/kak-rabotaet-ai-assi-73/</link><description>&lt;p&gt;В прошлом посте я писал о том, что хочу в качестве эксперимента сделать визуализацию работы своего кодового ассистента &lt;a href=&quot;https://github.com/codabrus/codabrus&quot;&gt;Codabrus&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;И вот настали долгожданные выходные, и я объединил код фронта с бэком. Получилось как на демке.&lt;/p&gt;

&lt;p&gt;Сообщения от пользователя отображаются синенькими блоками, ответы LLM - зелеными, а вызовы тулов - оранжевым. На блоки можно кликать чтобы видеть больше информации. Если блоки вызова тулов размещаются друг под другом - значит они выполняются параллельно. Использование акторной системы позволяет легко параллелить выполнение любой логики и у меня за выполнение каждого тула отвечает отдельный актор.&lt;/p&gt;

&lt;p&gt;Тул у агента пока один - вызов bash команды. Для экспериментов этого достаточно, но для реальной работы надо будет добавить редактирование и прочее. А так же хочу в интерфейс добавить отдельное окно со стримингом размышлений агента - чтобы было видно чем он занят прямо сейчас.&lt;/p&gt;
</description><guid isPermaLink="false">https://40ants.com/ru/posts/kak-rabotaet-ai-assi-73/</guid><lastBuildDate>Mon, 07 Sep 2026 15:39:41 +0000</lastBuildDate><content:encoded>&lt;p&gt;В прошлом посте я писал о том, что хочу в качестве эксперимента сделать визуализацию работы своего кодового ассистента &lt;a href=&quot;https://github.com/codabrus/codabrus&quot;&gt;Codabrus&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;И вот настали долгожданные выходные, и я объединил код фронта с бэком. Получилось как на демке.&lt;/p&gt;

&lt;p&gt;Сообщения от пользователя отображаются синенькими блоками, ответы LLM - зелеными, а вызовы тулов - оранжевым. На блоки можно кликать чтобы видеть больше информации. Если блоки вызова тулов размещаются друг под другом - значит они выполняются параллельно. Использование акторной системы позволяет легко параллелить выполнение любой логики и у меня за выполнение каждого тула отвечает отдельный актор.&lt;/p&gt;

&lt;p&gt;Тул у агента пока один - вызов bash команды. Для экспериментов этого достаточно, но для реальной работы надо будет добавить редактирование и прочее. А так же хочу в интерфейс добавить отдельное окно со стримингом размышлений агента - чтобы было видно чем он занят прямо сейчас.&lt;/p&gt;
</content:encoded></item><item><title>Собираюсь использовать в Codabrus визуализацию работы AI ассистента</title><link>https://40ants.com/ru/posts/sobirayus-ispolzova-72/</link><description>&lt;p&gt;Хочу сделать в своем AI-ассистенте Codabrus визуализацию того, как работает AI-ассистент. Традиционные кодовые ассистенты показывают интерфейс в виде чата. Я же хочу сделать некую диаграмму, которая каждое сообщение от ассистента и от пользователя будет показывать в виде отдельного блока. Вызовы тулов будут ответвлениями, а также, наверное, будет прикольно подобным же образом визуализировать запуски сабагентов.&lt;/p&gt;

&lt;p&gt;Так можно будет проанализировать, насколько много работы сделал кодовый ассистент, что происходило в процессе - всё это будет более наглядно.&lt;/p&gt;

&lt;p&gt;Пока что в виде заглушки сделал такой простенькую штуку - подключил JavaScript библиотеку &lt;a href=&quot;https://github.com/antvis/x6&quot;&gt;X6&lt;/a&gt; от Alibaba для отрисовки диаграмм. Плюс подключил туда &lt;a href=&quot;https://github.com/40ants/clack-sse&quot;&gt;CLACK-SSE&lt;/a&gt; для того, чтобы можно было новые элементы добавлять, пуша их с сервера. Таким образом, когда что-то происходит во время работы кодового ассистента, я смогу обновлять диаграмму в веб-интерфейсе.&lt;/p&gt;

&lt;p&gt;Вот такая пока идея. Наверное, в выходные доберусь до того, чтобы связать этот интерфейс с реальным ассистентом.&lt;/p&gt;
</description><guid isPermaLink="false">https://40ants.com/ru/posts/sobirayus-ispolzova-72/</guid><lastBuildDate>Mon, 07 Sep 2026 15:39:41 +0000</lastBuildDate><content:encoded>&lt;p&gt;Хочу сделать в своем AI-ассистенте Codabrus визуализацию того, как работает AI-ассистент. Традиционные кодовые ассистенты показывают интерфейс в виде чата. Я же хочу сделать некую диаграмму, которая каждое сообщение от ассистента и от пользователя будет показывать в виде отдельного блока. Вызовы тулов будут ответвлениями, а также, наверное, будет прикольно подобным же образом визуализировать запуски сабагентов.&lt;/p&gt;

&lt;p&gt;Так можно будет проанализировать, насколько много работы сделал кодовый ассистент, что происходило в процессе - всё это будет более наглядно.&lt;/p&gt;

&lt;p&gt;Пока что в виде заглушки сделал такой простенькую штуку - подключил JavaScript библиотеку &lt;a href=&quot;https://github.com/antvis/x6&quot;&gt;X6&lt;/a&gt; от Alibaba для отрисовки диаграмм. Плюс подключил туда &lt;a href=&quot;https://github.com/40ants/clack-sse&quot;&gt;CLACK-SSE&lt;/a&gt; для того, чтобы можно было новые элементы добавлять, пуша их с сервера. Таким образом, когда что-то происходит во время работы кодового ассистента, я смогу обновлять диаграмму в веб-интерфейсе.&lt;/p&gt;

&lt;p&gt;Вот такая пока идея. Наверное, в выходные доберусь до того, чтобы связать этот интерфейс с реальным ассистентом.&lt;/p&gt;
</content:encoded></item><item><title>Итерация которую можно прервать</title><link>https://40ants.com/ru/posts/iteraciya-kotoruyu-mozh-71/</link><description>&lt;p&gt;&lt;video src=&quot;images/71.mp4&quot; controls=&quot;&quot; style=&quot;width: 100%&quot;&gt;&lt;/video&gt;&lt;/p&gt;

&lt;p&gt;Итерация которую можно прервать. С акторами не всё так просто.&lt;/p&gt;

&lt;p&gt;Вот вам небольшая демка того, как в системе акторов можно реализовать итерацию таким образом, чтобы её можно было безопасно прервать. Я собираюсь использовать этот подход для того, чтобы организовать работу с код-ассистентом и тулами, которые он запускает. Это нужно сделать так, чтобы код-ассистента можно было прервать в любой момент и сделать это безопасно.&lt;/p&gt;

&lt;p&gt;В этом демо используется фреймворк Sento, реализующий актеры для Common Lisp.&lt;/p&gt;

&lt;p&gt;Вот полный код примера:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
(defun make-interruptable-actor-loop-example ()
  (ac:actor-of *sys*
               :destroy (lambda (&amp;amp;rest args)
                          ;; По сообщению :stop актор будет полностью
                          ;; остановлен и его нельзя будет запустить ещё раз
                          (log:info &amp;quot;Destroy called with ARGS = ~A&amp;quot; args))
               :receive (let ((stopped nil))
                          (lambda (message)
                            (log:info &amp;quot;Processing&amp;quot; message)
                            (case message
                              ;; Но с помощью :break итерацию можно приостановить,
                              ;; а потом продолжить заново с помощью :run.
                              (:break
                                 (log:info &amp;quot;Stopping&amp;quot;)
                                 (setf stopped t))
                              (:run
                                 (log:info &amp;quot;Running&amp;quot;)
                                 (setf stopped nil)
                                 (act:tell act:*self* :next-iteration))
                              (t
                                 (unless stopped
                                   (log:info &amp;quot;Sleeping&amp;quot;)
                                   (sleep 3)
                                   (log:info &amp;quot;Going to next iteration&amp;quot;)
                                   (act:tell act:*self* :next-iteration))))))))
&lt;/code&gt;&lt;/pre&gt;
</description><guid isPermaLink="false">https://40ants.com/ru/posts/iteraciya-kotoruyu-mozh-71/</guid><lastBuildDate>Mon, 07 Sep 2026 15:39:41 +0000</lastBuildDate><content:encoded>&lt;p&gt;&lt;video src=&quot;images/71.mp4&quot; controls=&quot;&quot; style=&quot;width: 100%&quot;&gt;&lt;/video&gt;&lt;/p&gt;

&lt;p&gt;Итерация которую можно прервать. С акторами не всё так просто.&lt;/p&gt;

&lt;p&gt;Вот вам небольшая демка того, как в системе акторов можно реализовать итерацию таким образом, чтобы её можно было безопасно прервать. Я собираюсь использовать этот подход для того, чтобы организовать работу с код-ассистентом и тулами, которые он запускает. Это нужно сделать так, чтобы код-ассистента можно было прервать в любой момент и сделать это безопасно.&lt;/p&gt;

&lt;p&gt;В этом демо используется фреймворк Sento, реализующий актеры для Common Lisp.&lt;/p&gt;

&lt;p&gt;Вот полный код примера:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
(defun make-interruptable-actor-loop-example ()
  (ac:actor-of *sys*
               :destroy (lambda (&amp;amp;rest args)
                          ;; По сообщению :stop актор будет полностью
                          ;; остановлен и его нельзя будет запустить ещё раз
                          (log:info &amp;quot;Destroy called with ARGS = ~A&amp;quot; args))
               :receive (let ((stopped nil))
                          (lambda (message)
                            (log:info &amp;quot;Processing&amp;quot; message)
                            (case message
                              ;; Но с помощью :break итерацию можно приостановить,
                              ;; а потом продолжить заново с помощью :run.
                              (:break
                                 (log:info &amp;quot;Stopping&amp;quot;)
                                 (setf stopped t))
                              (:run
                                 (log:info &amp;quot;Running&amp;quot;)
                                 (setf stopped nil)
                                 (act:tell act:*self* :next-iteration))
                              (t
                                 (unless stopped
                                   (log:info &amp;quot;Sleeping&amp;quot;)
                                   (sleep 3)
                                   (log:info &amp;quot;Going to next iteration&amp;quot;)
                                   (act:tell act:*self* :next-iteration))))))))
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Итерация которую можно прервать</title><link>https://40ants.com/ru/posts/iteraciya-kotoruyu-mozh-70/</link><description>&lt;p&gt;Итерация которую можно прервать. С акторами не всё так просто.&lt;/p&gt;

&lt;p&gt;Вот вам небольшая демка того, как в системе акторов можно реализовать итерацию таким образом, чтобы её можно было безопасно прервать. Я собираюсь использовать этот подход для того, чтобы организовать работу с код-ассистентом и тулами, которые он запускает. Это нужно сделать так, чтобы код-ассистента можно было прервать в любой момент и сделать это безопасно.&lt;/p&gt;

&lt;p&gt;В этом демо используется фреймворк Sento, реализующий актеры для Common Lisp.&lt;/p&gt;

&lt;p&gt;Вот полный код примера:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
(defun make-interruptable-actor-loop-example ()
  (ac:actor-of *sys*
               :destroy (lambda (&amp;amp;rest args)
                          ;; По сообщению :stop актор будет полностью
                          ;; остановлен и его нельзя будет запустить ещё раз
                          (log:info &amp;quot;Destroy called with ARGS = ~A&amp;quot; args))
               :receive (let ((stopped nil))
                          (lambda (message)
                            (log:info &amp;quot;Processing&amp;quot; message)
                            (case message
                              ;; Но с помощью :break итерацию можно приостановить,
                              ;; а потом продолжить заново с помощью :run.
                              (:break
                                 (log:info &amp;quot;Stopping&amp;quot;)
                                 (setf stopped t))
                              (:run
                                 (log:info &amp;quot;Running&amp;quot;)
                                 (setf stopped nil)
                                 (act:tell act:*self* :next-iteration))
                              (t
                                 (unless stopped
                                   (log:info &amp;quot;Sleeping&amp;quot;)
                                   (sleep 3)
                                   (log:info &amp;quot;Going to next iteration&amp;quot;)
                                   (act:tell act:*self* :next-iteration))))))))
&lt;/code&gt;&lt;/pre&gt;
</description><guid isPermaLink="false">https://40ants.com/ru/posts/iteraciya-kotoruyu-mozh-70/</guid><lastBuildDate>Mon, 07 Sep 2026 15:39:41 +0000</lastBuildDate><content:encoded>&lt;p&gt;Итерация которую можно прервать. С акторами не всё так просто.&lt;/p&gt;

&lt;p&gt;Вот вам небольшая демка того, как в системе акторов можно реализовать итерацию таким образом, чтобы её можно было безопасно прервать. Я собираюсь использовать этот подход для того, чтобы организовать работу с код-ассистентом и тулами, которые он запускает. Это нужно сделать так, чтобы код-ассистента можно было прервать в любой момент и сделать это безопасно.&lt;/p&gt;

&lt;p&gt;В этом демо используется фреймворк Sento, реализующий актеры для Common Lisp.&lt;/p&gt;

&lt;p&gt;Вот полный код примера:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
(defun make-interruptable-actor-loop-example ()
  (ac:actor-of *sys*
               :destroy (lambda (&amp;amp;rest args)
                          ;; По сообщению :stop актор будет полностью
                          ;; остановлен и его нельзя будет запустить ещё раз
                          (log:info &amp;quot;Destroy called with ARGS = ~A&amp;quot; args))
               :receive (let ((stopped nil))
                          (lambda (message)
                            (log:info &amp;quot;Processing&amp;quot; message)
                            (case message
                              ;; Но с помощью :break итерацию можно приостановить,
                              ;; а потом продолжить заново с помощью :run.
                              (:break
                                 (log:info &amp;quot;Stopping&amp;quot;)
                                 (setf stopped t))
                              (:run
                                 (log:info &amp;quot;Running&amp;quot;)
                                 (setf stopped nil)
                                 (act:tell act:*self* :next-iteration))
                              (t
                                 (unless stopped
                                   (log:info &amp;quot;Sleeping&amp;quot;)
                                   (sleep 3)
                                   (log:info &amp;quot;Going to next iteration&amp;quot;)
                                   (act:tell act:*self* :next-iteration))))))))
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item></channel></rss>