Ваш ИИ‑агент ведёт на вас досье. Я превратил его в RPG‑лист персонажа

от автора

обложка

Prompt Warrior — карточка‑гримуар, собранная из моих же логов Claude Code

Привет! Началось всё с дурацкого вопроса. Я который месяц живу в Claude Code — ставлю задачи, ругаюсь, прошу переделать, снова ругаюсь. И тут до меня дошло: каждая моя реплика лежит на диске. Вообще каждая. Каждое «сделай», каждое «проверь», каждый капс в три часа ночи — всё это тихо копится в JSONL‑файлах в домашней папке. У меня таких логов набралось на 200 тысяч слов за полтора месяца. Это, на минуточку, две «Мастер и Маргариты».

И вот сижу я, смотрю на эту гору данных и думаю — а как я вообще выгляжу со стороны машины? Не «хороший я или плохой», а буквально: какими словами командую, в котором часу наиболее опасен, сколько раз прервал модель на полуслове. Досье же готовое. Осталось его вскрыть.

Меня зовут Илья, я блогер, основатель генератора изображений ArtGeneration.me и исследователь ИИ. Кода руками я почти не пишу — за меня это делают нейросети, я ими только командую. Собстенно поэтому досье и вышло таким толстым. И вскрывать его я, конечно, пошёл не сам — поставил задачу тому же агенту, который эти логи и нагенерил. Получилась забавная рекурсия: нейросеть считает статистику того, как я ей командую, и рисует по ней мой портрет. Спойлер — портрет вышел нелестный, но об этом позже.

Так за сутки диалога родился Prompt Warrior — опенсорсный скилл для Claude Code, который превращает локальные логи сессий в геймифицированный психологический портрет: титул, уровень, 74 ачивки с редкостями как в Стиме, шесть шкал характера и биография, которую пишет сама нейросеть. Всё локально, без единого сетевого вызова, на чистом Python без зависимостей.

Расскажу что лежит в логах Claude Code и как из них выжать максимум, зачем я заморозил формулы метрик, почему модель не должна писать HTML руками, и какие грабли собрал по дороге — от токенов, посчитанных втрое, до Google Fonts, которые молча подменяют кириллицу.

❯ Что вообще лежит в логах Claude Code

Для тех кто не в теме: Claude Code пишет каждую сессию в ~/.claude/projects/<проект>/<session-id>.jsonl. Один файл — одна сессия, одна строка — одно событие. И там сильно больше, чем просто «вопрос‑ответ».

Типы записей, которые я в итоге разоборал:

  • user — ваши реплики. Плюс служебные: результаты инструментов тоже приходят как user‑записи, их надо отсекать

  • assistant — ответы модели. Внутри блоки: текст, thinking, вызовы инструментов. И главное — поле usage с точным расходом токенов: input, output, cache_read, cache_creation

  • system, mode, queue‑operation — служебные события, включения план‑режима, очередь сообщений

  • pr‑link — ссылки на пулл‑реквесты, рождённые в сессии

  • custom‑title — если вы переименовали сессию

Плюс у каждой записи есть метаданные: timestamp, рабочая директория, git‑ветка, версия Claude Code, точка входа (терминал, десктоп или VS Code), модель которая отвечала, и слаг сессии. То есть по логам восстанавливается почти всё: когда вы работали, над чем, какой моделью, сколько это стоило в токенах и как часто вы жали Escape посреди ответа.

Прерывания, кстати, отдельная песня. Когда вы обрываете модель на полуслове, в лог падает реплика [Request interrupted by user]. Это синтетика, в портрет её брать нельзя — но посчитать можно. У меня вышло 53 прерывания на 100 реплик. Каждый второй ответ я не дослушиваю. Модель, если ты эжто читаешь — извини.

Есть и подводные камни. Во‑первых, дедупликация: при резюме сессии история копируется в новый файл, и наивный парсер посчитает реплики дважды — лечится дедупом по uuid и нормализованному тексту. Во‑вторых, рядом лежат транскрипты субагентов (agent-*.jsonl) — это не ваши слова, их надо выкидывать. В‑третьих, вставленный код и логи раздувают статистику — поэтому для анализа «голоса» я завёл отдельное подмножество: реплики до 60 слов без код‑блоков и ссылок. Именно по нему считается словарь и языковые метрики.

скрин 1

Шесть шкал, экономика токенов и «Боевые повадки» — у меня тут почти всё красное

❯ SCALE: шкала как контракт

Первое архитектурное решение, принятое ещё до того как агент написал хоть строчку кода: формулы метрик замораживаются. Навсегда. Файл называется scale.md, лежит в репо, и в нём прямым текстом: изменение любой константы — это новая версия шкалы, несравнимая со старой.

Зачем такая бюрократия в развлекательном проекте? Затем, что вся соль — в сравнимости. Если формулы подкручиваются под каждого пользователя, то мой «Неистовый Командир 90 уровня» и ваш — два разных зверя, и меряться карточками бессмысленно. А с единой математикой карточка становится честной валютой: скинул скрин в рабочий чат — и все понимают, что твоя Ярость 82 посчитана ровно так же, как у коллеги его 12.

Примеры формул, чтобы было понятно о чём речь:

  • Уровень = корень из общего числа набранных слов, делённый на 5, кап на 99. У меня 204 тысячи слов — 90 уровень

  • Ярость = мат на 1000 слов × 1.5 + процент реплик капсом + процент реплик с «!!!» и «???». Лексиконы русские и английские из коробки

  • Совиность = доля ночных реплик (00:00–05:59 по местному) × 2.2

  • Индекс оборотня = ночной мат делить на дневной. Считается только если и ночью и днём набралось по 50+ реплик — иначе это гадание, а не статистика. У меня вышло ×1.02 — ругаюсь стабильно круглосуточно, оборотня не вышло

  • Точка кипения = медианный номер реплики, на которой в сессии случается первая вспышка (капс, мат или тройной знак препинания). У меня — вторая реплика. Кипит 98.9% сессий. Без комментариев

Всего в профиле десятки метрик: объём и медиана реплик, топ императивов по корням («сделай», «проверь», «запусти»), типы вопросов (что/как/почему), самокоррекция, вежливость, дабл‑тексты — это когда шлёшь второе сообщение не дождавшись ответа на первое, код‑свитчинг между русским и английским внутри одной фразы. И фирменный словарь — топ слов, харакетрных именно для вас, после вычета стоп‑слов и служебных лексиконов. Мой топ возглавляет слово «тварь». Сто семьдесят девять раз.

Из метрик собираются шесть шкал от 0 до 100: Ярость, Теплота, Дотошность, Совиность, Нетерпеливость и Кэш‑скряга. У каждой подписи‑бакеты, которые меняются от значения. И да, подпись у Ярости честно сообщает со ссылками на исследования: на качество ответов тон почти не влияет. Высокий балл — не про эффективность, а про сожжённые токены.

скрин 2

А так выглядит виджет прямо в клод десктоп

❯ Ачивки, титулы и прочий лут

Сразу оговорка: я с самого начала запретил агенту превращать это в «РПГ‑цирк». Никаких стат‑листов персонажа и выдуманных характеристик — аналитика тут продукт, геймификация приправа. Stack Overflow в своё время описывал свои бейджи как «dusting of gamification» — щепотка, а не ядро. Вот и здесь так.

Титул собирается из реального поведения: эпитет + звание + уровень + суффикс самой редкой ачивки. Звание выдаётся по доминирующему поведенческому индексу — командность, темп, выносливость, контекстность, верификация или дипломатия. Эпитет — первое сработавшее условие из одиннадцати: Ярость от 70 даёт «Неистовый», треть ночных реплик — «Полуночный». У меня вышло «Неистовый Командир Терминала 90 уровня, Железная Длань». Не выбирал. Заслужил.

Рядом с титулом — идентичность: класс от харнесса, раса от доминирующей модели. Я — «Воин Claude Code · Могучий Опус» с 92.6% реплик на Опусе. Гоняете Codex — будете Легионером, сидите на Хайку — Лёгким Хайку.

Ачивок 74, четыре редкости, условия честные и замороженные. Никакой «получи за регистрацию». Разброс такой:

  • Клуб ста (common) — сотня реплик в корпусе. Разминка

  • Ночной дозор (rare) — 30%+ активности между полуночью и шестью утра

  • Оборотень (epic) — ночной мат в полтора раза злее дневного

  • Сессия‑левиафан (epic) — 5 миллионов output‑токенов в одной сессии. У меня такая есть — девять миллионов, между прочим

  • Тиран (legendary) — негативных сигналов в десять раз больше, чем похвалы. Моя гордость и мой позор одновременно

  • Гутенберг (legendary) — 25 миллионов токенов сгенерировано суммарно

Часть ачивок выстроена лестницами по образцу гитхабовских Bronze/Silver/Gold: «Спринтер» дорастает до «Романиста», «Печатный станок» — до «Гутенберга», «Полководец» (50 вызовов субагентов) — до «Владыки легионов» (200). Прогрессия работает на возврат: скилл запоминает профиль локально, и через неделю дельта покажет что нового выбито.

На карточке ачивки выглядят как в Стиме: крупный медальон‑иконка слева, название с редкостью и флейвор справа, условие получения всплывает при наведении. Сразу показываются только legendary и epic, остальное под спойлером — иначе 37 карточек превращают гримуар в простыню.

скрин 3

Конюшня ответов по моделям, фирменный словарь (без цензуры) и полка легендарок

❯ Хроника воина: единственное место, где модель говорит сама

Вся карточка собирается детерминированно из цифр — кроме одной секции. «Хроника воина» — три абзаца, которые нейросеть пишет сама, глядя на готовый профиль. Мини‑биография в тоне летописи.

Правила жёсткие и прописаны в скилле: факты только из профиля, ничего не выдумывать. Никаких чисел — на карточке каждое число встречается ровно один раз, и хроника не имеет права дублировать статистику. Не стыдить и не подлизываться, у кого бы какая Ярость ни вышла. И написано должно быть так, чтобы ощущалось написанным, а не сгенерированным.

Звучит как мелочь, а на деле это самая цепляющая часть карточки. Модель подмечает то, что сам про себя не сформулируешь. Вот кусочки из моей хроники, собранной свежей установкой:

Летопись знает его как Командира Терминала — того, кто не печатает, а диктует: почти каждое слово в этих свитках произнесено голосом, и голос этот командует.

Про голос — чистая правда, я реально надиктовываю почти всё, и модель вычислила это по опечаткам и строю фраз. Дальше — больше:

…слово «тварь» в его устах — знак внимания, а не приговор: наука утверждает, что модели всё равно, и летописец ей верит.

И моё любимое, про план‑режим, который я не открывал ни разу за 151 сессию:

План‑режим он не открывал ни разу — ковбой стреляет с бедра и, что раздражает летописца сильнее всего, попадает.

Вот это «что раздражает летописца сильнее всего» — момент, ради которого всё затевалось.

❯ Монстр в шапке: как я искал генератор аватарок и нашёл его в 2011 году

С аватаркой я помучил агента знатно. Хотелось персонажа — не герб, не буквы в кружочке, а живую тематическую морду.

Расскажу как есть. В своих ранних поделках я использовал Pollinations — прикольный был сервис, пока у него был открытый API: дёргаешь урл с промптом, получаешь картинку, никаких ключей и регистраций. Я был уверен, что и сейчас найду что‑то такое же. Ага, щас. Прочесали с агентом всё: открытые image‑API либо умерли, либо обзавелись ключами и лимитами, либо выдают качество уровня «спасибо что бесплатно». Халява кончилась.

И в этот момент сложность проекта резко выросла, потому что запасной план — процедурная генерация персонажа — оказался не такой уж доступной роскошью. Живых библиотек, собирающих персонажа из слоёв локально, считаные единицы, и почти все рисуют либо пиксельарт, либо однотипных болванчиков. А у меня два жёстких требования: полный офлайн (весь проект стоит на принципе «ни одного сетевого вызова») и детерминизм — аватар должен быть лицом профиля, а не лотереей «сегодня одна морда, завтра другая».

Решение нашлось в проекте, которому сто лет в обед — RoboHash. Все знают его по дефолтным аватаркам на форумах, но мало кто помнит, что это MIT‑пакет на Python, который таскает наборы PNG‑слоёв прямо внутри себя. Ставишь pip install robohash — и собираешь персонажей полностью офлайн, сайт robohash.org не трогается вообще. Набор set2 — монстры художника Hrvoje Novakovic под CC‑BY-3.0, и они на удивление хорошо легли в гримуарную эстетику.

Дальше простая магия детерминизма: сидом выступает ваш титул. Одна строка — одна морда, всегда. А поскольку титул собирается из поведения, получаетя механика эволюции: изменились привычки — сменился титул — монстр перерождается. Станете вежливее, добьёте уровень — встретите нового зверя.

И это единственная зависимость во всём проекте, причём опциональная. Нет пакета — скилл один раз предложит поставить, откажетесь — карточка рендерится без картинки. Подсовывать заглушки вместо аватара запрещено отдельным правилом в спеке. Лучше честное ничего, чем плейсхолдер.

❯ Архитектура: почему модель не должна писать HTML

Сейчас будет самая поучительная часть. Первая версия сборки выглядела так: агент читает шаблон‑спецификацию из репо, подставляет цифры из профиля и пишет HTML‑файл. У меня в чате это рабоатло отлично. А потом я сделал то, что советую каждому, кто вайбкодит инструменты: снёс всё под ноль и прогнал установку с чистой машины, как свежий пользователь.

И понеслось. Свежий агент, следуя спеке «вставь в карточку path из SVG‑иконок», сделал самое логичное — открыл SVG‑файлы на чтение. Прямо в контекст. Километры координат кривых, тысячи токенов на каждую иконку. Я это увидел в логе и, мягко говоря, спросил у агента, зачем при установке читать внутренности SVG. Мягко говоря.

Чинилось в два захода. Сначала появился icons.py — утилита, которая сама выдаёт готовый инлайн‑код любой иконки, фавикон одной строкой и герб для печати, с жёстким правилом в спеке: Read по SVG‑файлам запрещён. А потом дошло главное: модель вообще не должна собирать HTML. Никогда. Каждая ручная сборка — лотерея: тут иероглиф в текст прокрадётся, там числа захардкодятся от прошлого прогона.

Итоговая архитектура разделяет творческое и механическое:

  • analyze.py — читает логи, считает метрики по замороженной шкале, пишет profile.json. Чистая математика, ноль креатива

  • Модель пишет только то, что и должен писать автор: хронику и выбор сильных/слабых сторон по правилам из спеки. Всё это — в маленький content.json

  • render.py — канонический рендерер. Берёт profile.json + content.json + язык и собирает карточку целиком: числа, бары, шкалы, аккордеон ачивок, фавикон, печать. CSS тянет из шаблона в спеке — один источник правды. Русская и английская версии собираются одним кодом из словаря подписей

Модель в итоге пишет три абзаца прозы и один JSON. Всё. Зато результат воспроизводим: у любого пользователя карточка соберётся пиксель в пиксель одинаковой — разными будут только цифры и монстр.

Это общий урок для любых агентских скиллов: если в инструкции написано «собери по шаблону» — однажды модель соберёт по нему что‑то своё. Всё, что может быть скриптом, должно быть скриптом. Нейросети оставляйте только работу, где она незаменима.

❯ Грабли, по которым мы прошлись

Коротко о том, где я ругался громче всего.

Токены, посчитанные втрое. Первая версия экономики гордо выдала: 199 миллионов токенов сгенерировано. Оказалось, один ответ API ложится в JSONL несколькими строками с одинаковым usage — наивная сумма считает всё два‑три раза. Дедуп по (message.id, requestId), как в ccusage, — и трезвый итог — 51 миллион. Тоже, впрочем, 70 «Войн и миров».

Google Fonts молча подменяет кириллицу. Английская карточка выглядела как надо, русская — «как‑то не так». Полез в сабсеты: у Cinzel и Crimson Pro кириллицы нет вообще, браузер тихо падал на Georgia. Починили парами в фонт‑стеке: Cormorant SC под капители, PT Serif под текст. Проверяйте unicode‑range до вёрстки — глаза привыкают и врут.

Крошечные короны. Иконки‑фолбэки ачивок внезапно съёжились в четверть размера: я захардкодил viewBox 512, а исходники бейджей — 256 на 256. viewBox берётся из файла, а не из головы. Всё.

Дизайн‑муки. Первый вариант — фиолетовые градиенты и стеклянные панельки, дефолтная нейросетевая эстетика. Второй — перегиб в ренессансный фарш с римскими цифрами и арками. Помогли дизайн‑скиллы: поставил агенту UI/UX Pro Max и Taste‑набор (design‑taste‑frontend + high‑end‑visual‑design) — они душат типовые нейро‑паттерны и заставляют выбирать осознанную эстетику. Сошлись на тёмном гримуаре: махагон, латунь, сургучная печать. Утверждённый вариант закреплён в репо как шаблон — рендерер от него не отступает ни на пиксель.

Патч, упавший молча. Составной скрипт правок споткнулся на середине, но коммит с половиной изменений уехал в репо — поймал только плановый аудит. Теперь после каждого пакета правок проверяется, что каждая реально в файле.

И три правила, вписанные в спеку кровью: модель не перепечатывает base64 (побайтная перепечатка = битый файл), артефакты пользователя никуда не заливаются без явного «можно», сетевые генераторы картинок запрещены как класс.

❯ Кросс‑харнесс, приватность и советы с пруфами

Другие агенты. Скилл заточен под Claude Code, но идея переносимая, поэтому в репо лежит справочник форматов: где и как хранят сессии Codex CLI (~/.codex/sessions/.../rollout-*.jsonl), OpenCode, Gemini CLI (сюрприз: у него чекпоинтинг по умолчанию выключен — логов может просто не быть) и Copilot. Анализатор устроен как реестр источников‑адаптеров: свой харнесс подключается одной функцией «прочитай файлы — отдай реплики». А если формат поменялся, главный совет из справочника: не гадай, открой файл глазами.

Приватность. Тут без компромиссов, потому что скилл по определению читает самое личное — вашу переписку с агентом. Логи открываются только на чтение. Наружу не уходит ни байта: ни телеметрии, ни ключей, ни «анонимной статистики». Всё, что пишется на диск — profile.json, карточка, аватар и локальная история прогонов для дельты. Хотите поделиться — делитесь скриншотом, это ваше решение, а не дефолт.

Советы с пруфами. Кроме развлечения карточка выдаёт 3–6 рекомендаций по промпт‑инженерингу — и здесь я упёрся: никаких «советов от гуру», каждый триггерится вашей метрикой и тащит ссылку на источник. База собиралась мульти‑агентным ресёрчем с перекрёстной проверкой: каждое утверждениие прогонялось через трёх независимых агентов‑скептиков. Выжило — попало в репо с вердиктом, нет — попало в отдельный список развенчанных мифов. Он тоже в репо, и он мой любимый: там лежат все эти «будь вежлив с моделью», «наори — будет стараться» и «пообещай чаевые». Свежие работы (раздва) сходятся: агрегатный эффект тона на качество — около нуля. Моя Ярость 82 никому не вредит, кроме моего же кошелька.

скрин 4

Сильное, слабое и что с этим делать — у каждого фикса ссылка на источник

❯ Как попробовать

Самый простой способ — одно сообщение. Вставляете в Claude Code вот это целиком, агент сам всё склонирует, прогонит и откроет карточку:

Установи скилл Prompt Warrior с гитхаба и сразу прогони его по полной.Установка: git clone https://github.com/timoncool/prompt-warrior в СВОЮдиректорию скиллов, папкой prompt-warrior (у Claude Code это ~/.claude/skills/;другой харнесс — куда он кладёт скиллы).Дальше следуй SKILL.md установленного скилла как обычный пользователь:профиль за всё время, HTML-карточка + открой её в браузере,инлайн-виджет, разбор профиля и рекомендации.Ничего не изобретай сверх скилла.

Руками — тоже три шага: git clone в ~/.claude/skills/, сказать агенту /prompt-warrior или просто «построй мой промпт‑профиль», получить HTML‑карточку, виджет и разбор с рекомендациями.

Период — на ваш выбор: всё время, неделя, месяц, даты или один проект. Из требований — Python 3.8+, который у вас и так есть. Минимум для профиля — 30 своих реплик, уверенная статистика — от сотни.

И главная механика напоследок: профиль запоминается локально. Вернётесь через неделю — скилл начнет с дельты: какие ачивки выбиты, как сдвинулись метрики, вырос ли уровень. У меня за время написания этой статьи +11 достижений, включая вторую легендарку. Фарм идёт.

❯ Вместо выводов

Самое ценное в этой затее оказалось не геймификацией. Ачивки и монстры — приманка, чтобы вернуться к карточке ещё раз. А остаётся после неё другое: ты впервые видишь свой стиль работы с ИИ со стороны, в цифрах, которые не льстят. Я вот узнал, что не дослушиваю каждый второй ответ, вскипаю на второй реплике и ни разу не открыл план‑режим. Стал ли я после этого вежливее? Нет. Но теперь я хотя бы знаю масштаб и хотя бы ради эксперимента попробую меньше материть своих агентов.

Проект открытый: github.com/timoncool/prompt‑warrior. Контрибьюты приветствуются — особенно адаптеры для других харнесов и идеи новых ачивок. Порог входа смешной: вся логика — один Python‑файл на stdlib.

А теперь главное: прогоните на своих логах и покажите в комментариях свои титулы. Мне дико интересно, есть ли среди хабровчан хоть один «Учтивый Дипломат Машин» — или тут все такие же Неистовые Командиры. Ну и звезда на гитхабе проекту не помешает, а мне будет приятно.

Я рассказываю больше о нейросетях у себя на YouTube, в Телеграме и на Бусти. Залетайте, каждую пятницу смотрим новинки нейросетей и генерируем вместе.

Всех обнял и удачного фарма ачивок.

ссылка на оригинал статьи https://habr.com/ru/articles/1055584/