← Лендинг Hermes Agent

Опубликовано

Когда сеньор-дев смотрит твой код и молчит

Автор: Гусев Николай [портфолио]

Дата обновления не указана в исходнике.

Темы: code-review, ai-agents

Когда сеньор-дев смотрит твой код и молчит

Ты написал 400 строк. Он смотрит. Молчит. Потом одну стирает. Потом ещё три. Потом говорит: "Запускай".

Это Ponytail. Не человек - набор правил для AI-агентов, который заставляет думать перед тем как писать. Репозиторий на GitHub, MIT лицензия, 80-94% меньше кода по бенчмаркам.

Лестница, по которой нужно подниматься

Идея простая. Перед тем как написать код, остановись на первой ступеньке, которая работает:

  1. Нужно ли это вообще? (YAGNI) 2. Стандартная библиотека уже делает это? 3. Нативная фича платформы покрывает? 4. Установленная зависимость решает? 5. Можно в одну строку? 6. Только потом - минимальный код

Звучит очевидно. Но когда AI-агент пишет код, он прыгает сразу к шагу 6. И вот тут начинается веселье.

Пример из жизни: валидация email

Задача: проверить что email корректный. Вот что выдаёт обычный AI-агент без Ponytail:

`class EmailValidator:
    def __init__(self):
        self.errors = []

    def validate(self, email):
        self.errors = []
        if not isinstance(email, str):
            self.errors.append("Email must be a string")
            return False
        if not email:
            self.errors.append("Email cannot be empty")
            return False
        if '@' not in email:
            self.errors.append("Email must contain @")
            return False
        local, _, domain = email.partition('@')
        if not local:
            self.errors.append("Local part cannot be empty")
            return False
        if not domain:
            self.errors.append("Domain cannot be empty")
            return False
        if '.' not in domain:
            self.errors.append("Domain must contain a dot")
            return False
        if domain.startswith('.') or domain.endswith('.'):
            self.errors.append("Domain cannot start or end with a dot")
            return False
        if '..' in domain:
            self.errors.append("Domain cannot contain consecutive dots")
            return False
        tld = domain.rsplit('.', 1)[-1]
        if len(tld) < 2:
            self.errors.append("TLD must be at least 2 characters")
            return False
        if not tld.isalpha():
            self.errors.append("TLD must contain only letters")
            return False
        return True

    def get_errors(self):
        return self.errors

    def get_error_string(self):
        return "; ".join(self.errors)

    def is_valid_gmail(self):
        return self.validate(self.email) and self.email.endswith('@gmail.com')

    def is_valid_corporate(self):
        free_domains = ['gmail.com', 'yahoo.com', 'hotmail.com']
        return self.validate(self.email) and not any(
            self.email.endswith(f'@{d}') for d in free_domains
        )`

40 строк. Класс. Два публичных метода, которые никто не вызовет. Проверка TLD на длину 2+ символа - а как быть с .io? Метод is_valid_gmail - серьёзно? Это называется "абстракция с одним потребителем".

Вот тот же код с Ponytail:

`def is_valid_email(email):
    # ponytail: regex for RFC compliance; re.fullmatch if you need the real thing
    return isinstance(email, str) and '@' in email and '.' in email.split('@')[1]`

Одна строка. Потому что настоящая валидация - это отправить письмо и проверить что дошло. Всё остальное - театр.

Ещё один пример: кэширование API-ответов

Без Ponytail агент напишет класс ResponseCache с TTL, потокобезопасностью, метриками и методом invalidate. 40 строк.

С Ponytail:

`from functools import lru_cache

@lru_cache(maxsize=1000)
def fetch_data(url):
    return requests.get(url).json()`

Одна декоратор. Встроенная библиотека. Ноль багов. Ноль CVE. 100% uptime с момента создания Python.

Не только код: YAGNI для решений и архитектуры

Вот где становится интереснее. Лестница Ponytail работает не только для кода - она работает для любого инженерного решения. Выбор стека, архитектура, процессы. Всё то же самое: остановись на первой ступеньке.

Пример: "Нам нужен Kubernetes"

Команда из 3 человек, монолит на FastAPI, одна база данных. Кто-то говорит: "Нам нужен Kubernetes для масштабирования".

Лестница Ponytail:

  1. Нужно ли это? Нет. У вас 100 пользователей. 2. Стандартная библиотека? systemd + nginx покрывают 99% потребностей. 3. Нативная фича платформы? Docker Compose - это уже оркестрация. 4. Установленная зависимость? Уже есть Docker.

Kubernetes - это шаг 6. И до него ещё дойти надо. Реальная история: команда потратила 3 месяца на разворачивание кластера, который обслуживал 50 запросов в минуту. На Docker Compose это бы заняло 2 дня.

Пример: "Давайте перепишем на Rust"

Сервис на Python работает. Не идеально, но работает. Кто-то предлагает переписать на Rust ради производительности.

Лестница:

  1. Нужно ли? Профайлер показал что 95% времени - это запросы к базе, а не Python-код. 2. Стандартная библиотека? asyncpg вместо psycopg2 даёт 3x ускорение без переписывания языка. 3. Нативная фича? Кэширование через Redis убирает 60% запросов к базе.

Переписывание на Rust - это шаг 6. А ступеньки 1-3 уже дают 10x улучшение без смены языка.

Пример: "Нам нужен отдельный сервис для уведомлений"

Монолит растёт. Кто-то предлагает вынести уведомления в отдельный микросервис.

Лестница:

  1. Нужно ли? Уведомлений 50 в час. Одна функция в монолит справляется. 2. Стандартная библиотека? asyncio.create_task - неблокирующая отправка, не нужен отдельный сервис. 3. Нативная фича? Очередь задач в том же процессе через asyncio.Queue.

Отдельный микросервис - это шаг 6. И он добавляет: сетевые вызовы, сериализацию, мониторинг, деплой, логи. Ради 50 уведомлений в час.

Связь с Prism и Premortem

Ponytail - не изолированный скилл. Он из той же семьи что и Prism (структурный анализ) и Premortem (предварительный разбор рисков). Все три отвечают на один вопрос: "Что пойдёт не так если мы не подумаем?"

  • Prism - анализ артефакта: где слабые места, когда сломается, почему

  • Premortem - анализ плана: что пойдёт не так если начнём делать

  • Ponytail - анализ решения: нужно ли вообще делать, и можно ли проще

Вместе они закрывают три этапа: понять текущее (Prism), предсказать будущее (Premortem), не переусложнить решение (Ponytail).

Как это работает на практике

Ponytail - не линтер. Это способ мышления. Он не говорит "твой код плохой". Он спрашивает: "А нужен ли он вообще?"

Три режима работы:

  • Lite - построил как просили, но упомянул что можно проще

  • Full (по умолчанию) - лестница принудительна, stdlib и нативные фичи первыми

  • Ultra - экстремист YAGNI. Удаление прежде добавления. Вызов требованиям

И маркер для каждого сокращения: ponytail: global lock, per-account locks if throughput matters. Видно где срезали, почему, и когда переделать.

Почему это работает для AI-агентов

Проблема не в том что модели глупые. Проблема в том что они стараются. Они видят задачу и хотят сделать "правильно" - с классами, интерфейсами, фабриками. Это называется over-engineering, и он убивает проекты тише чем баги.

Ponytail даёт разрешение делать проще. Не "лень - порок", а "лень - эффективность". Лучший код - тот, который не написан. Лучшая архитектура - та, которую не пришлось строить.

Что дальше

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

Попробуйте сами: github.com/DietrichGebert/ponytail. Установка - одна команда. Результат - меньше кода, меньше багов, меньше 3амен в продакшене.