Проекты01 / 05

На входе тикет. Цепочка AI-агентов воспроизводит его, чинит, проводит ревью, тестирует запущенное приложение и отдаёт пул-реквест — с записью и ценником на каждом шаге.

winningby.ai

Обзор админки пайплайна: общая стоимость, тикеты и время агентов
Диспетчерская, срез за август. Уже опубликовано на winningby.ai.
Продукт
Автономный пайплайн разработки и сайт компании
Роль
Сооснователь, ведущий AI-инженер
Период
Июль – октябрь 2026
Стек
TypeScript, Temporal, Claude Code headless, Fastify, PostgreSQL, Playwright, Railway
Онлайн
winningby.ai

Большинство команд купили AI-ассистента для кода и получили разработчиков, которые быстрее печатают. Тикеты всё так же неделями лежат в ревью, тестировании и очередях. Мы хотели продавать процесс вместо инструмента: тикет попадает на вход, специализированные агенты доводят его до пул-реквеста, готового к мержу, а важные решения остаются за людьми.

Заставить агента писать код в демо легко. Настоящий вопрос в том, что будет, когда он днями работает в реальном репозитории, переживает деплои, упирается в реальную квоту, и кому-то приходится отвечать за результат.

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

  1. 01

    Пайплайн

    Один тикет — один durable-воркфлоу в Temporal. Баг проходит десять агентских стадий и два шлюза с человеком; у фичи шлюз стоит на плане, а не на коде, потому что плохой план по багу обходится дёшево, а хорошо сделанная не та фича — нет. Каждая стадия — холодный старт со своим бюджетом на ходы, токены и секунды, и на выходе у неё только результат, который может провалидировать машина.

  2. 02

    Стенд, на котором поднимается настоящее приложение

    Node, PostgreSQL с pgvector, Chromium и всё целевое приложение за nginx. QA тестирует работающий продукт вместо чтения диффа. Доказательства привязаны к git-дереву, поэтому значат «этот код прошёл», а не «так сказал этот коммит».

  3. 03

    Маршрутизация моделей

    Лестницы моделей по стадиям с запасными вариантами и circuit breaker, который читает время сброса прямо из отказа API и обходит исчерпанную модель раньше, чем придётся платить за мёртвую попытку.

  4. 04

    Счётчик и диспетчерская

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

  5. 05

    От отчётов к работе

    Аналитики по расписанию читают данные продукта, пишут отчёт и предлагают работу карточками, без дублей и с оценкой влияния. Одно одобрение превращает карточку в тикет, который может сам дойти до мержа.

Как это устроено

  1. Понять

    • Проверка качестваесть ли в тикете смысл
    • Тест-кейсы
    • Воспроизведениепадающий тест, иначе не считается
  2. Изменить

    • План исправления
    • Исправлениев свежей сессии с бюджетом
  3. Доказать

    • Код-ревьюотдельный агент и планка доказательств
    • Шлюз: решает человек
    • QAна запущенном приложении
  4. Передать

    • Обучение
    • Стабилизация PRпока CI не станет зелёным
    • Шлюз: решает человек
    • Документация
Экран аналитики со стоимостью по типам тикетов, стадиям и моделям
Куда уходят деньги: на ревью и планирование, а не на набор кода.

То, что обычно не попадает в портфолио. Всё это было на самом деле, и всё это есть в истории коммитов.

  1. Сбой 01

    Проверка, которая на всё отвечала «да»

    Симптом
    Ничего заметного. Воспроизведения багов подтверждались, и выглядело это нормально.
    Причина
    Проверка на фабрикацию запускала тестовую команду в корне репозитория и считала любой ненулевой код выхода доказательством того, что тест упал. Тестового скрипта в корне не было, npm падал всегда, и каждое заявленное воспроизведение проходило, хотя ни один тест так и не запускался.
    Решение
    Три исхода вместо двух: команда, которая не смогла выполниться, считается недоступной и доказательств не оставляет. Что-то доказывает только набор тестов, который запустился и упал. Проверка, которая не может провалиться, выглядит в точности как проверка, которая всё время проходит.
  2. Сбой 02

    Восемь прогонов первого тикета, а его PR до сих пор открыт

    Симптом
    Первый настоящий тикет эскалировался снова и снова, каждый раз по новой причине.
    Причина
    С агентами всё было в порядке, дело было в обвязке вокруг них. Файл скилла лежал на уровень выше того места, откуда мог читать CLI. Схема требовала поля, которых агент не мог знать. Скилл велел агентам вызывать инструмент, которого не существовало. Любая стадия дольше двух минут молча теряла activity воркфлоу, потому что heartbeat был объявлен, но не передавался, а админка при этом вечно показывала «running».
    Решение
    По одному коммиту на проблему, в тот же день, с номерами прогонов в сообщениях. Тот первый пул-реквест так и не был влит. Тикет, который всё сломал, научил систему работать; следующий вышел в течение дня.
  3. Сбой 03

    «Агент упал». Он даже не запускался.

    Симптом
    Один тикет раз за разом эскалировался с сообщением «agent ended without recording a result». Поиски шли через шлюзы, дедупликацию вебхуков и логику ретраев.
    Причина
    Ответ лежал в первой строке транскрипта: три хода, ноль токенов, шесть секунд, 429. Квота была исчерпана ещё на три дня. Лаунчер не отличал отклонённый запрос от агента, который ведёт себя неправильно, так что простой записывался в вину агенту.
    Решение
    Теперь отказы эскалируются как проблема окружения, с цитатой из API, а circuit breaker обходит эту модель. Подвох обнаружился в тот же день: проверка читала api_error_status !== undefined, здоровые прогоны заканчиваются с null, а в JavaScript это true. Какое-то время каждый здоровый прогон выглядел как отказ.
  4. Сбой 04

    Воркфлоу, который идёт днями, всегда попадает под деплой на полпути

    Симптом
    Эпик оставался в RUNNING после 35 неудачных попыток. Его дочерний тикет уже закончился, а эпик этого не заметил.
    Причина
    Temporal переигрывает историю, а новый код в той же точке запрашивал другую activity: ошибка недетерминизма. Рассуждение, что защита по версии не нужна, было верным для тикетов и неверным для эпиков. Потом проблема вернулась в другом виде: воркер при остановке отменяет работу тем же сигналом, что и кнопка Stop, поэтому каждый деплой выглядел как стоп.
    Решение
    Защита по версии стала рутиной, дальнейшие изменения проверяются реплеем на настоящем сервере Temporal в обе стороны, а запрошенная отмена и остановка воркера чётко разведены. С durable-агентами деплой — это миграция данных.
  5. Сбой 05

    Как научить агента ждать в сессии, которая ждать не умеет

    Симптом
    Watchdog убил сборку, хотя изменение уже было закоммичено, а тесты прошли тремя минутами раньше.
    Причина
    Верификатор буферизовал вывод, поэтому лог, за которым следил агент, оставался пустым, а pgrep агента находил собственный шелл, так что агент получал «running» при каждом опросе, пока не умер. Следующий сбой вырос из этого исправления: агентам велели уводить долгие проверки в фон и ждать уведомления. Headless-сессия заканчивается, когда агент завершает ход. Разбудить её нечему.
    Решение
    Режим --wait, который блокирует на переднем плане по 110 секунд за вызов и завершается кодом выхода, означающим «вызови меня ещё раз». Инструкции не гарантии: у окружения агента своя физика, и неверная ментальная модель порождает уверенное, разумное и фатальное поведение.
  6. Сбой 06

    Учёт врал в обе стороны

    Симптом
    Тикет «вылетел за бюджет в 400 тыс. токенов», даже не приблизившись к нему. На другом экране стояло $47 там, где было потрачено $627. Три законченных тикета выбросили за превышение времени.
    Причина
    Самоотчёт агента (620 000) перекрыл измеренные 381. Запасная оценка не учитывала кэш, а это 83% реальных трат. А часы запускались раньше очереди, клонирования и загрузки: агенты работали 9, 2 и 2 минуты, а записано им было 78, 57 и 35.
    Решение
    Побеждает измерение, а расхождение логируется как аномалия. Модель с неизвестной ценой показывает прочерк, а не правдоподобное неверное число. Время считается со старта агента. Для продукта, который продаёт «каждый прогон с ценой до строчки», счётчик и есть продукт.

  • PR влито в один живой потребительский продукт23 июля – 17 сентября 2026; 14,8% всего, что влили туда за этот период
  • строк добавили эти PR−3 364 удалено; медианный PR — 296 строк
  • стоимость агентов на тикет по счётчикусрез за август, 47 тикетов, $1 194,36. Без ревью людьми и хостинга
  • времени агентов на тикеттот же срез; это не сравнение с человеко-часами
  • трат ушло на ревью и планированиена написание кода — 21%, тот же срез
  • тест-кейса в 52 файлахпосчитано в исходниках; 35 530 строк TypeScript

Пульс проекта

Каждый коммит в репозиториях проекта на одной линии. Чем выше столбик, тем жарче было.

июль 2026 г.окт. 2026 г.
  1. Каркас сайта компании за один день
  2. Пайплайн встречает настоящий репозиторий; первый тикет, восемь прогонов
  3. Эпики со стековыми PR; за месяц влито 53 PR
  4. Настоящая проверка в браузере; отчёты превращаются в работу
  5. Аналитики и отчёты: последний на сегодня коммит цикла

Если ваша команда уже платит за AI-ассистента, а тикеты всё равно стоят в очереди, дело редко в модели получше. Не хватает процесса вокруг неё: шлюзов, доказательств, счётчика и способа остановиться. Именно это я строю вместе с вами за спринт в 4–6 недель с одним-двумя вашими инженерами.

Написать бриф

Быстро отвечаю в WhatsApp и Telegram

Или спросите о нём цифровой разум
Следующий кейсBlackbrook Barns