Review Time: сколько код ждёт проверки
PR открыт в понедельник утром.
Первый комментарий появляется во вторник вечером. Автор отвечает в среду. Ревьюер возвращается в четверг. В пятницу изменение наконец сливается.
Само ревью заняло минут сорок. Но календарно код ждал почти неделю.
Если смотреть только на среднее время ревью, эту проблему легко не заметить.
Одной цифры недостаточно
Review Time лучше разделять на несколько интервалов.
Time to First Review — время от открытия PR до первого содержательного комментария или одобрения.
Показывает, насколько быстро команда вообще начинает проверку. Комментарий бота, запуск CI или автоматическое назначение ревьюера считать не стоит.
Time to Approval — время от открытия PR до получения необходимых approvals.
Сюда входят ожидание, обсуждение и циклы исправлений. Если PR несколько раз возвращается автору, это будет видно именно здесь.
Time to Merge — время от открытия PR до merge.
Кроме ревью, сюда попадают CI, ручной merge, зависимость от других изменений и ожидание релизного окна.
Разница между этими интервалами помогает понять, где именно лежит код.
Почему среднее обманывает
Представим:
девять PR слились за два часа;
один PR висел десять дней.
Среднее значение сгладит ситуацию. Процесс будет выглядеть терпимо, хотя один тип изменений регулярно попадает в очередь на неделю.
Поэтому я бы смотрел не только среднее, но и:
медиану;
85-й или 90-й перцентиль;
долю PR старше выбранного порога;
распределение по размеру и типу изменений;
время до первого содержательного отзыва.
Например, медиана Time to First Review у команды составляет три часа. На первый взгляд всё хорошо.
Но 15% PR ждут больше двух дней.
Значит, проблема не во всём процессе. Нужно искать конкретные репозитории, типы изменений или узких экспертов, возле которых образуется очередь.
Какие сигналы стоит проверить
PR регулярно ждут первого комментария больше рабочего дня;
большая часть ревью проходит через одного человека;
маленькие изменения обрабатываются так же долго, как крупные;
между ответами автора и ревьюера возникают длинные паузы;
PR проходят несколько одинаковых циклов доработки;
approvals уже собраны, но merge происходит значительно позже.
Высокий Review Time может означать что угодно: большой WIP, отсутствие владельца ревью, нехватку экспертизы, слишком крупные PR или архитектурный спор, который начался уже после написания кода.
Иногда причина ещё проще: за создание нового кода разработчика хвалят, а время на помощь коллегам считается отвлечением от работы.
Как не превратить метрику в дубинку
Review Time не нужен для рейтинга «самых медленных ревьюеров».
Количество комментариев тоже ничего не говорит о качестве проверки. А требование мгновенно отвечать на каждый PR быстро приводит к поверхностным approve.
Полезнее смотреть на командный поток:
где изменения чаще всего останавливаются;
сколько времени занимает ожидание, а сколько обсуждение;
какие размеры и типы PR задерживаются;
изменилась ли картина после новых договорённостей.
Из практических шагов можно начать с простого:
договориться о времени первого отзыва;
выделить окна для ревью;
уменьшать размер изменений;
автоматически назначать ревьюеров;
выносить архитектурные вопросы до написания большого PR;
отмечать блокирующие и необязательные комментарии;
показывать старые PR на ежедневном обзоре;
ограничить количество одновременно открытых PR.
Definition of Ready помогает лучше готовить задачи. Working Agreements задают правила ревью. Review Time показывает, работают ли эти договорённости в реальности.
Эта метрика нужна не для того, чтобы люди быстрее ставили approve. Она показывает время, когда готовое изменение лежит без движения.
Что чаще задерживает ваши PR: ожидание первого ревью, долгие обсуждения, исправления или проверки после approval?
PR открыт в понедельник утром.
Первый комментарий появляется во вторник вечером. Автор отвечает в среду. Ревьюер возвращается в четверг. В пятницу изменение наконец сливается.
Само ревью заняло минут сорок. Но календарно код ждал почти неделю.
Если смотреть только на среднее время ревью, эту проблему легко не заметить.
Одной цифры недостаточно
Review Time лучше разделять на несколько интервалов.
Time to First Review — время от открытия PR до первого содержательного комментария или одобрения.
Показывает, насколько быстро команда вообще начинает проверку. Комментарий бота, запуск CI или автоматическое назначение ревьюера считать не стоит.
Time to Approval — время от открытия PR до получения необходимых approvals.
Сюда входят ожидание, обсуждение и циклы исправлений. Если PR несколько раз возвращается автору, это будет видно именно здесь.
Time to Merge — время от открытия PR до merge.
Кроме ревью, сюда попадают CI, ручной merge, зависимость от других изменений и ожидание релизного окна.
Разница между этими интервалами помогает понять, где именно лежит код.
Почему среднее обманывает
Представим:
девять PR слились за два часа;
один PR висел десять дней.
Среднее значение сгладит ситуацию. Процесс будет выглядеть терпимо, хотя один тип изменений регулярно попадает в очередь на неделю.
Поэтому я бы смотрел не только среднее, но и:
медиану;
85-й или 90-й перцентиль;
долю PR старше выбранного порога;
распределение по размеру и типу изменений;
время до первого содержательного отзыва.
Например, медиана Time to First Review у команды составляет три часа. На первый взгляд всё хорошо.
Но 15% PR ждут больше двух дней.
Значит, проблема не во всём процессе. Нужно искать конкретные репозитории, типы изменений или узких экспертов, возле которых образуется очередь.
Какие сигналы стоит проверить
PR регулярно ждут первого комментария больше рабочего дня;
большая часть ревью проходит через одного человека;
маленькие изменения обрабатываются так же долго, как крупные;
между ответами автора и ревьюера возникают длинные паузы;
PR проходят несколько одинаковых циклов доработки;
approvals уже собраны, но merge происходит значительно позже.
Высокий Review Time может означать что угодно: большой WIP, отсутствие владельца ревью, нехватку экспертизы, слишком крупные PR или архитектурный спор, который начался уже после написания кода.
Иногда причина ещё проще: за создание нового кода разработчика хвалят, а время на помощь коллегам считается отвлечением от работы.
Как не превратить метрику в дубинку
Review Time не нужен для рейтинга «самых медленных ревьюеров».
Количество комментариев тоже ничего не говорит о качестве проверки. А требование мгновенно отвечать на каждый PR быстро приводит к поверхностным approve.
Полезнее смотреть на командный поток:
где изменения чаще всего останавливаются;
сколько времени занимает ожидание, а сколько обсуждение;
какие размеры и типы PR задерживаются;
изменилась ли картина после новых договорённостей.
Из практических шагов можно начать с простого:
договориться о времени первого отзыва;
выделить окна для ревью;
уменьшать размер изменений;
автоматически назначать ревьюеров;
выносить архитектурные вопросы до написания большого PR;
отмечать блокирующие и необязательные комментарии;
показывать старые PR на ежедневном обзоре;
ограничить количество одновременно открытых PR.
Definition of Ready помогает лучше готовить задачи. Working Agreements задают правила ревью. Review Time показывает, работают ли эти договорённости в реальности.
Эта метрика нужна не для того, чтобы люди быстрее ставили approve. Она показывает время, когда готовое изменение лежит без движения.
Что чаще задерживает ваши PR: ожидание первого ревью, долгие обсуждения, исправления или проверки после approval?
👍2
«Своя модель» не делает AI-агента своим
Когда в компании обсуждают агентную платформу, разговор часто сводится к двум вариантам:
— поднимаем OpenCode и локальную модель;
— покупаем Claude Code или Codex и ходим во внешний API.
Но это ложный выбор.
Агентный стек — не один продукт. Это минимум пять компонентов:
обвязка × модель × инструменты × идентичность × границы исполнения
И каждый из них может находиться под разным контролем.
Например:
— открытый клиент не делает модель локальной;
— локальная модель не ограничивает права инструментов;
— внутренний MCP не становится безопасным только потому, что он внутренний;
— внешний API необязательно опасен, если контекст фильтруется, а модель не получает прямого доступа к рабочим системам.
Отсюда важный вывод: слово «свой» тоже ничего не объясняет.
Нужно отдельно проверять четыре вещи:
1. Контролируем ли мы исходный код?
2. Эксплуатируем ли компонент самостоятельно?
3. Контролируем ли путь и хранение данных?
4. Обеспечиваются ли права и запреты технически?
Особенно интересна рекомендуемая корпоративная архитектура. Не обязательно форкать каждого агента и самостоятельно размещать все модели. Гораздо важнее владеть двумя точками контроля.
Модельный шлюз решает:
— какие данные можно отправлять;
— в какую модель и регион;
— разрешён ли резервный маршрут;
— сколько может стоить задача.
Инструментальный шлюз решает:
— кто инициировал действие;
— что именно разрешено изменить;
— от чьего имени выполняется операция;
— нужна ли дополнительная проверка.
Это критично, потому что атакуют обычно не саму модель, а цепочку полномочий.
Агент прочитал README, письмо или задачу в Jira. Внутри оказалась вредоносная инструкция. Модель восприняла её как часть контекста и вызвала инструмент с рабочими правами.
Просьба в системном промпте «не отправляй секреты» здесь не поможет.
Поэтому модель может предложить действие, но не должна сама определять, имеет ли право его выполнить. Это задача IAM, политики и инструментального шлюза.
Что я бы проверил перед внедрением агента в команду:
— где реально исполняются команды;
— куда уходят промпты, результаты инструментов и логи;
— есть ли общие долгоживущие токены;
— разделены ли чтение, подготовка изменения и запись;
— закрыт ли исходящий трафик по умолчанию;
— что произойдёт при недоступности локальной модели;
— можно ли отдельно отключить модель, MCP или записывающий инструмент;
— связывает ли аудит пользователя, модель, инструмент и фактический результат.
И ещё один практический совет: пилот стоит начинать не с максимальной автономности.
Один репозиторий. Один класс данных. Чтение или создание merge request вместо прямой записи. Никаких широких рабочих токенов.
Цель пилота — не доказать, что агент умеет вызывать двадцать инструментов. Цель — понять, сколько полезной работы команда принимает, как часто агент ошибается и сколько времени уходит на проверку.
Безопасность и суверенность — свойства всей цепочки, а не логотипа модели. Владеть в первую очередь нужно местами, где пересекаются данные, полномочия и необратимые действия.
По мотивам разбора восьми конфигураций агентного стека Александра Поломодова.
#AI #AI4SDLC #TeamLead #EngineeringManagement #MCP
Когда в компании обсуждают агентную платформу, разговор часто сводится к двум вариантам:
— поднимаем OpenCode и локальную модель;
— покупаем Claude Code или Codex и ходим во внешний API.
Но это ложный выбор.
Агентный стек — не один продукт. Это минимум пять компонентов:
обвязка × модель × инструменты × идентичность × границы исполнения
И каждый из них может находиться под разным контролем.
Например:
— открытый клиент не делает модель локальной;
— локальная модель не ограничивает права инструментов;
— внутренний MCP не становится безопасным только потому, что он внутренний;
— внешний API необязательно опасен, если контекст фильтруется, а модель не получает прямого доступа к рабочим системам.
Отсюда важный вывод: слово «свой» тоже ничего не объясняет.
Нужно отдельно проверять четыре вещи:
1. Контролируем ли мы исходный код?
2. Эксплуатируем ли компонент самостоятельно?
3. Контролируем ли путь и хранение данных?
4. Обеспечиваются ли права и запреты технически?
Особенно интересна рекомендуемая корпоративная архитектура. Не обязательно форкать каждого агента и самостоятельно размещать все модели. Гораздо важнее владеть двумя точками контроля.
Модельный шлюз решает:
— какие данные можно отправлять;
— в какую модель и регион;
— разрешён ли резервный маршрут;
— сколько может стоить задача.
Инструментальный шлюз решает:
— кто инициировал действие;
— что именно разрешено изменить;
— от чьего имени выполняется операция;
— нужна ли дополнительная проверка.
Это критично, потому что атакуют обычно не саму модель, а цепочку полномочий.
Агент прочитал README, письмо или задачу в Jira. Внутри оказалась вредоносная инструкция. Модель восприняла её как часть контекста и вызвала инструмент с рабочими правами.
Просьба в системном промпте «не отправляй секреты» здесь не поможет.
Поэтому модель может предложить действие, но не должна сама определять, имеет ли право его выполнить. Это задача IAM, политики и инструментального шлюза.
Что я бы проверил перед внедрением агента в команду:
— где реально исполняются команды;
— куда уходят промпты, результаты инструментов и логи;
— есть ли общие долгоживущие токены;
— разделены ли чтение, подготовка изменения и запись;
— закрыт ли исходящий трафик по умолчанию;
— что произойдёт при недоступности локальной модели;
— можно ли отдельно отключить модель, MCP или записывающий инструмент;
— связывает ли аудит пользователя, модель, инструмент и фактический результат.
И ещё один практический совет: пилот стоит начинать не с максимальной автономности.
Один репозиторий. Один класс данных. Чтение или создание merge request вместо прямой записи. Никаких широких рабочих токенов.
Цель пилота — не доказать, что агент умеет вызывать двадцать инструментов. Цель — понять, сколько полезной работы команда принимает, как часто агент ошибается и сколько времени уходит на проверку.
Безопасность и суверенность — свойства всей цепочки, а не логотипа модели. Владеть в первую очередь нужно местами, где пересекаются данные, полномочия и необратимые действия.
По мотивам разбора восьми конфигураций агентного стека Александра Поломодова.
#AI #AI4SDLC #TeamLead #EngineeringManagement #MCP
❤3💯2👍1
Decision Log: как перестать принимать одно и то же решение заново
На встрече команда обсудила три варианта и выбрала B. Через неделю кто-то спрашивает:
— А почему не A? Он же проще.
Обсуждение начинается сначала. Те же аргументы, те же возражения, те же полчаса в календаре.
Проблема обычно не в плохой памяти команды. Просто сохранился итог, но потерялся ход мысли.
Запись «решили делать вариант B» почти бесполезна. Без контекста непонятно:
— какую задачу решали;
— какие варианты рассматривали;
— почему отказались от остальных;
— на каких данных строилось решение;
— с какими последствиями согласились.
Для этого нужен Decision Log — журнал принятых решений.
Это не протокол встречи. Протокол отвечает на вопрос «что обсуждали», а Decision Log — «что решили и почему». В него не нужно переносить всю дискуссию и список выступавших. Достаточно зафиксировать:
— решение;
— дату;
— владельца;
— контекст и ограничения;
— рассмотренные альтернативы;
— причины выбора;
— ожидаемые последствия и риски.
Например:
Хранить Decision Log лучше там, где команда уже работает: в Notion, Confluence, Wiki репозитория или отдельной папке с ADR. Важен не инструмент, а три условия: журнал легко найти, на конкретное решение можно дать ссылку, записи не исчезают в переписке.
Старое решение не становится правильным навсегда. Его стоит пересмотреть, если изменились исходные условия, появились новые данные, проявились неучтённые последствия или наступил заранее указанный срок ревизии.
Но пересмотр должен начинаться не с «мне не нравится вариант B», а с «вот что изменилось с момента, когда мы его выбрали».
DACI помогает команде принять решение. Decision Log не позволяет этому решению через неделю снова превратиться в дискуссию.
На встрече команда обсудила три варианта и выбрала B. Через неделю кто-то спрашивает:
— А почему не A? Он же проще.
Обсуждение начинается сначала. Те же аргументы, те же возражения, те же полчаса в календаре.
Проблема обычно не в плохой памяти команды. Просто сохранился итог, но потерялся ход мысли.
Запись «решили делать вариант B» почти бесполезна. Без контекста непонятно:
— какую задачу решали;
— какие варианты рассматривали;
— почему отказались от остальных;
— на каких данных строилось решение;
— с какими последствиями согласились.
Для этого нужен Decision Log — журнал принятых решений.
Это не протокол встречи. Протокол отвечает на вопрос «что обсуждали», а Decision Log — «что решили и почему». В него не нужно переносить всю дискуссию и список выступавших. Достаточно зафиксировать:
— решение;
— дату;
— владельца;
— контекст и ограничения;
— рассмотренные альтернативы;
— причины выбора;
— ожидаемые последствия и риски.
Например:
Решение: использовать вариант B.
Контекст: запуск через шесть недель, команда не успеет освоить новую технологию.
Альтернативы: A дешевле, C лучше масштабируется.
Почему B: уже есть экспертиза и готовая инфраструктура.
Последствия: через год решение может стать узким местом.
Пересмотреть: если нагрузка вырастет втрое или появится отдельная команда поддержки.
Хранить Decision Log лучше там, где команда уже работает: в Notion, Confluence, Wiki репозитория или отдельной папке с ADR. Важен не инструмент, а три условия: журнал легко найти, на конкретное решение можно дать ссылку, записи не исчезают в переписке.
Старое решение не становится правильным навсегда. Его стоит пересмотреть, если изменились исходные условия, появились новые данные, проявились неучтённые последствия или наступил заранее указанный срок ревизии.
Но пересмотр должен начинаться не с «мне не нравится вариант B», а с «вот что изменилось с момента, когда мы его выбрали».
DACI помогает команде принять решение. Decision Log не позволяет этому решению через неделю снова превратиться в дискуссию.
👍3❤2💯1
Три идеи из Habr, которые кажутся недооценёнными
За последние месяцы на Habr вышло несколько сильных материалов про AI в разработке.
Любопытно, что почти все они говорят не про новые модели, бенчмарки или магию промптов. Они говорят про процессы: как ставить задачи, где хранить знания и что вообще должен делать разработчик, когда код пишет агент.
Я собрал три общих тренда.
1. Context Engineering становится важнее Prompt Engineering
Проблема уже не в том, чтобы написать особенно хитрый запрос.
Проблема в том, чтобы в нужный момент дать агенту правильный контекст:
— требования и критерии приёмки;
— устройство проекта и границы модулей;
— принятые архитектурные решения;
— правила сборки, тестирования и ревью;
— ограничения, о которых нельзя догадаться из кода.
Можно бесконечно улучшать промпт. Но если агент не знает, почему команда пять лет назад запретила конкретный паттерн, он с высокой вероятностью вернёт его обратно.
Поэтому инженерия постепенно смещается от «как спросить» к «какие знания собрать, как их структурировать и когда подключить».
2. Спецификация становится источником истины и для людей, и для AI
Раньше спецификация помогала людям договориться до начала разработки. Теперь у неё появляется вторая роль: она становится исполняемым контрактом для агента.
Из одной спецификации можно получить план, код, тесты и материалы для ревью. По ней же можно проверить, соответствует ли результат исходной задаче.
Это особенно важно, когда агент способен за несколько минут создать тысячи строк кода. Без спецификации ревьюер проверяет реализацию по ощущениям. Со спецификацией у него есть точка сравнения: здесь обещано одно, а сделано другое.
Хорошая спецификация перестаёт быть документом, который торжественно положили в Confluence и забыли. Она живёт рядом с кодом и меняется вместе с ним.
3. Agent-first процесс заметно отличается от привычного SDLC
AI можно добавить в старый процесс как ещё один инструмент. Например, разрешить разработчикам использовать агента для написания кода.
Но тогда ускорится только один участок конвейера. Следующее узкое место переедет в ревью, тестирование или согласование требований.
В Content AI, например, оценили общее ускорение зрелой разработки примерно в 10%, хотя отдельные прототипы создавались в 5–10 раз быстрее. Код генерируется быстро, но требования, архитектура, краевые случаи и проверка результата никуда не исчезают.
Поэтому agent-first подход меняет сам процесс:
— задачи приходится точнее ограничивать;
— работу декомпозируют на небольшие проверяемые шаги;
— точки человеческого контроля закладывают заранее;
— правила команды хранят как версионируемый контекст;
— разработчик всё чаще управляет несколькими агентами, а не пишет каждую строку сам.
Просто прикрутить AI к старому SDLC недостаточно. Получится тот же конвейер, только с более быстрым генератором очередей.
Мой вывод: через несколько лет мы будем обсуждать уже не столько качество моделей, сколько качество инженерного контекста.
Кто лучше описывает систему, фиксирует решения и проектирует точки контроля, тот и получает предсказуемый результат от агентов.
Что почитать
— Роль Solution Architect с приходом AI-агентов
— Spec-Driven Development: контроль AI-кодогенерации
— Внутри Spec-Driven Development: на что способен Spec Kit
— Как ИИ изменил разработку в Content AI
За последние месяцы на Habr вышло несколько сильных материалов про AI в разработке.
Любопытно, что почти все они говорят не про новые модели, бенчмарки или магию промптов. Они говорят про процессы: как ставить задачи, где хранить знания и что вообще должен делать разработчик, когда код пишет агент.
Я собрал три общих тренда.
1. Context Engineering становится важнее Prompt Engineering
Проблема уже не в том, чтобы написать особенно хитрый запрос.
Проблема в том, чтобы в нужный момент дать агенту правильный контекст:
— требования и критерии приёмки;
— устройство проекта и границы модулей;
— принятые архитектурные решения;
— правила сборки, тестирования и ревью;
— ограничения, о которых нельзя догадаться из кода.
Можно бесконечно улучшать промпт. Но если агент не знает, почему команда пять лет назад запретила конкретный паттерн, он с высокой вероятностью вернёт его обратно.
Поэтому инженерия постепенно смещается от «как спросить» к «какие знания собрать, как их структурировать и когда подключить».
2. Спецификация становится источником истины и для людей, и для AI
Раньше спецификация помогала людям договориться до начала разработки. Теперь у неё появляется вторая роль: она становится исполняемым контрактом для агента.
Из одной спецификации можно получить план, код, тесты и материалы для ревью. По ней же можно проверить, соответствует ли результат исходной задаче.
Это особенно важно, когда агент способен за несколько минут создать тысячи строк кода. Без спецификации ревьюер проверяет реализацию по ощущениям. Со спецификацией у него есть точка сравнения: здесь обещано одно, а сделано другое.
Хорошая спецификация перестаёт быть документом, который торжественно положили в Confluence и забыли. Она живёт рядом с кодом и меняется вместе с ним.
3. Agent-first процесс заметно отличается от привычного SDLC
AI можно добавить в старый процесс как ещё один инструмент. Например, разрешить разработчикам использовать агента для написания кода.
Но тогда ускорится только один участок конвейера. Следующее узкое место переедет в ревью, тестирование или согласование требований.
В Content AI, например, оценили общее ускорение зрелой разработки примерно в 10%, хотя отдельные прототипы создавались в 5–10 раз быстрее. Код генерируется быстро, но требования, архитектура, краевые случаи и проверка результата никуда не исчезают.
Поэтому agent-first подход меняет сам процесс:
— задачи приходится точнее ограничивать;
— работу декомпозируют на небольшие проверяемые шаги;
— точки человеческого контроля закладывают заранее;
— правила команды хранят как версионируемый контекст;
— разработчик всё чаще управляет несколькими агентами, а не пишет каждую строку сам.
Просто прикрутить AI к старому SDLC недостаточно. Получится тот же конвейер, только с более быстрым генератором очередей.
Мой вывод: через несколько лет мы будем обсуждать уже не столько качество моделей, сколько качество инженерного контекста.
Кто лучше описывает систему, фиксирует решения и проектирует точки контроля, тот и получает предсказуемый результат от агентов.
Что почитать
— Роль Solution Architect с приходом AI-агентов
— Spec-Driven Development: контроль AI-кодогенерации
— Внутри Spec-Driven Development: на что способен Spec Kit
— Как ИИ изменил разработку в Content AI
👍2