Ваш ИИ‑агент ведёт на вас досье. Я превратил его в RPG‑лист персонажа. Claude.. Claude. claude code.. Claude. claude code. Open source.. Claude. claude code. Open source. python.. Claude. claude code. Open source. python. аналитика.. Claude. claude code. Open source. python. аналитика. ачивки.. Claude. claude code. Open source. python. аналитика. ачивки. геймификация.. Claude. claude code. Open source. python. аналитика. ачивки. геймификация. ии-агенты.. Claude. claude code. Open source. python. аналитика. ачивки. геймификация. ии-агенты. нейросети.. Claude. claude code. Open source. python. аналитика. ачивки. геймификация. ии-агенты. нейросети. промпт-инжиниринг.
обложка

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, в Телеграме и на Бусти. Залетайте, каждую пятницу смотрим новинки нейросетей и генерируем вместе.

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

Автор: timonin

Источник