Записки тимлида | Александр Пенкин


Гео и язык канала: Россия, Русский
Категория: Технологии


Практические заметки тимлида. Как строить процессы, использовать AI и делать команды быстрее без бессмысленных митингов.

Связанные каналы

Гео и язык канала
Россия, Русский
Категория
Технологии
Статистика
Фильтр публикаций


Не учите команду пользоваться AI. Научите команду учиться пользоваться AI

Разница небольшая только на словах.

Плохая стратегия внедрения выглядит так:

Вот Copilot.
Вот инструкция.
Пользуйтесь.

Формально AI внедрён. Фактически каждый разработчик остаётся один на один с новым инструментом: сам ищет подходящие сценарии, повторяет чужие ошибки и часто возвращается к привычному workflow.

Если положить рядом два исследования Microsoft — SPACE of AI и работу про drivers of adoption, — в обоих заметна одна закономерность: на использование AI влияют не только возможности инструмента, но и среда вокруг него. Организационная поддержка и обучение друг у друга имеют значение.

Поэтому нормальная стратегия выглядит иначе:

— регулярный обмен рабочими кейсами;
— короткие демо удачных сценариев;
— общая база промптов и контекста;
— pairing при освоении новых подходов;
— AI Champion, который помогает команде собирать и распространять практики;
— разбор не только успехов, но и неудачных попыток;
— выделенное время на эксперименты.

Важное ограничение: не существует одного AI-workflow, который можно написать в Confluence и раздать всей команде.

Разные задачи, языки, уровни опыта и части системы требуют разных способов взаимодействия с AI.

Где-то полезен агент, который самостоятельно меняет несколько файлов. Где-то — точечная помощь с тестами. А где-то AI только добавляет ещё один слой проверки и ускоряет производство неправильного кода.

Поэтому задача тимлида — не стандартизировать каждый промпт.

Задача — создать learning loop:

попробовали → показали результат → обсудили ограничения → сохранили полезную практику → проверили её на другой задаче.

Не управление AI adoption.

Управление скоростью, с которой команда учится использовать AI осмысленно.


Количество PR никогда не было хорошей метрикой. С AI стало ещё хуже

Раньше объём активности хотя бы был ограничен физически: разработчик не мог за день написать бесконечное количество кода.

Теперь AI-агент вполне способен:

— создать пять PR;
— написать сотни тестов;
— сгенерировать тысячи строк кода;
— обновить десятки файлов.

Если измерять activity, продуктивность выглядит фантастически. Дашборды зеленеют, графики растут, репозиторий кипит жизнью.

Только о ценности для продукта и пользователя это ничего не говорит.

Поэтому здесь снова стоит вернуться к EngThrive. Авторы прямо позиционируют систему как попытку перейти от измерения активности к измерению результата — outcomes.

Я бы смотрел не на количество произведённых артефактов, а на то:

— как быстро изменение доходит до пользователя;
— улучшает ли оно пользовательский результат;
— сколько дефектов и откатов возникает после доставки;
— во сколько обходится изменение;
— насколько легко оно проходит путь от идеи до продакшена.

Важное ограничение: эти показатели тоже нельзя превращать в рейтинг отдельных разработчиков. Их задача — показывать состояние системы доставки, а не искать самого «эффективного» человека.

AI окончательно добивает метрики, которые и раньше были плохими.

Количество строк кода теперь просто особенно наглядный пример: производить их стало почти бесплатно. Разбираться с последствиями — всё ещё нет.


AI adoption нельзя приказать

Почему два разработчика из одной команды совершенно по-разному используют AI?

У них одинаковые инструменты, правила и похожие задачи.

Один обращается к AI постоянно. Второй — почти никогда.

Свежая работа с участием исследователей Microsoft, представленная на ICSE 2026, изучает именно этот вопрос. Авторы провели интервью с 54 разработчиками из 27 команд. В каждой паре был активный и малоактивный пользователь AI.

Разница оказалась не столько в доступе к инструментам, сколько в отношении к ним.

Активные пользователи чаще воспринимают AI как напарника:

— экспериментируют с формулировками и контекстом;
— меняют способ работы после неудачного ответа;
— ищут задачи, где инструмент действительно помогает.

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

Но для тимлида здесь важнее другой вывод.

Авторы называют его Productivity Pressure Paradox — парадокс давления продуктивности.

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

Но без экспериментов, ошибок и обмена практиками инструмент не успевает встроиться в работу. Давление получить быстрый результат мешает освоить то, что должно этот результат обеспечить.

Получается знакомая инженерная история: новую технологию уже включили в план по повышению velocity, но ещё не включили в план время на её освоение.

Мой вывод простой.

Если команда должна стать эффективнее с AI, сначала ей придётся некоторое время быть с AI неэффективной.

Нужен learning budget — время и пространство, чтобы:

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

Не KPI по количеству промптов.

Не обязательное использование AI в каждой задаче.

Не ожидание, что график продуктивности пойдёт вверх со следующего спринта.

AI adoption — это изменение способа работы. А такие изменения требуют не приказа, а обучения.

Что сейчас есть у вашей команды: время на освоение AI или только ожидание быстрого роста продуктивности?


Как измерять AI-продуктивность без самообмана

AI помог разработчику написать код быстрее. Этого недостаточно, чтобы сказать, что разработка стала продуктивнее.

В работе Microsoft The SPACE of AI: Real-World Lessons on AI’s Impact on Developers исследователи опросили более 500 разработчиков, а также провели интервью и наблюдения.

Влияние AI оценивали через модель SPACE:

— Satisfaction — удовлетворённость работой;
— Performance — качество результата;
— Activity — объём выполненных действий;
— Communication and Collaboration — взаимодействие в команде;
— Efficiency and Flow — эффективность и непрерывность работы.

Результаты показательные.

Разработчики действительно отмечают рост эффективности и удовлетворённости — особенно при выполнении рутинных задач.

Но эффект зависит от сложности задачи, способа использования AI и того, насколько инструмент принят всей командой.

А с совместной работой всё менее однозначно.

Допустим, код теперь пишется быстрее. Но одновременно:

— PR становятся больше;
— ревью занимает больше времени;
— растёт число исправлений после ревью;
— обмен знаниями сокращается;
— разработчики хуже понимают код друг друга.

Получили мы прирост продуктивности?

Не факт. Возможно, мы просто перенесли очередь из разработки в ревью.

Поэтому AI-продуктивность нельзя измерять одной метрикой — количеством строк, закрытых задач или временем написания кода.

Я бы смотрел сразу на несколько уровней:

— сколько времени задача проходит от начала до production;
— как изменились размер PR и время ревью;
— стало ли больше возвратов и исправлений;
— что происходит с качеством и количеством дефектов;
— помогает ли AI делиться знаниями или создаёт код, который понимает только его автор;
— как разработчики оценивают нагрузку и удовлетворённость работой.

AI может ускорить отдельную операцию и одновременно замедлить весь поток.

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


EngThrive: какой ценой команда стала быстрее

В мае 2026 года Microsoft Research опубликовала EngThrive: Make It Fast and Easy to Do Great Work — систему измерения и улучшения инженерной эффективности, которую уже используют внутри Microsoft.

Проблема знакомая.

У нас есть SPACE, DORA и DevEx. Но у руководителя всё равно остаётся практический вопрос:

Что именно смотреть каждую неделю, чтобы понимать состояние разработки?

EngThrive предлагает три основных измерения:

Speed — насколько быстро работа проходит через систему.

Ease — насколько легко разработчику эту работу выполнять.

Quality — насколько качественным получается результат.

А поверх них — Thriving: благополучие разработчиков как защитное ограничение для всей системы.

И это, на мой взгляд, самая интересная часть подхода.

Throughput действительно можно увеличить довольно простым способом: добавить давления.

На некоторое время.

Поэтому Thriving здесь не отдельная HR-метрика про настроение сотрудников. Это guardrail, который помогает отличить устойчивое улучшение от эффективности, взятой в долг у следующего квартала.

Что из этого забрать тимлиду

Нельзя оценивать эффективность разработки по одной метрике.

Lead Time снизился, но количество инцидентов выросло — это не улучшение.

Throughput увеличился, но разработчики стали тратить больше времени на ручную рутину — результат тоже сомнительный.

Velocity растёт, а удовлетворённость работой резко падает — возможно, команда просто обменивает будущую производительность на красивые цифры сегодня.

Хорошая система метрик должна показывать не только, насколько быстрее стала команда.

Она должна помогать вовремя заметить, какой ценой появилось это ускорение.


Сегодня на Avito tech conf


Разработчик всё меньше пишет код. Что он делает вместо этого?

Anthropic описывает переход довольно прямолинейно: от writing code — к orchestrating agents that write code. В отчёте собраны восемь трендов и кейсы Rakuten, CRED, TELUS и Zapier.[1]

Но смена роли разработчика — не самое интересное.

Интереснее другое: если implementation становится дешевле, какие части разработки дорожают?

Раньше дефицитным ресурсом были руки, которые превращали задачу в код. Теперь агент может за несколько минут написать реализацию, тесты и открыть PR. Только это ещё не означает, что команда за несколько минут получила работающую фичу.

Ускорилась одна операция. Весь поток — не обязательно.

Стоимость смещается туда, где нужны контекст и ответственность:

— в постановку задачи: агент очень быстро реализует и хорошее ТЗ, и плохое;

— в архитектуру: дешёвый код позволяет так же дёшево размножать неверные решения;

— в review: проверять нужно не стиль и синтаксис, а допущения, контракты и побочные эффекты;

— в verification: «тесты зелёные» всё чаще означает только то, что зелёные тесты, написанные в том же контексте;

— в интеграцию: десяток быстро созданных изменений всё равно встречается в общей кодовой базе;

— в observability: чем быстрее система меняется, тем раньше команда должна замечать, что изменила не то.

Получается немного странная экономика SDLC. Производство кода дешевеет, а доказательство того, что этот код решает нужную задачу и не ломает соседние системы, дорожает.

Поэтому метрика «сколько кода мы теперь производим» почти наверняка ведёт не туда. Можно увеличить число PR и одновременно увеличить очередь на review, количество переделок и время до безопасного релиза.

В agentic development implementation постепенно становится самой дешёвой частью процесса. Значит, productivity стоит измерять не скоростью генерации кода, а скоростью прохождения проверенного изменения от идеи до production.

И главный вопрос для команды теперь не «насколько быстрее агент пишет код?», а «какое следующее бутылочное горлышко он сделал видимым?»

Источник
Anthropic — 2026 Agentic Coding Trends Report


Безопасность AI-агента определяется не только моделью

Когда обсуждают безопасность AI-агентов, вопрос обычно звучит так:

«Можно ли доверять Claude, GPT или Gemini?»

Но модель — лишь один компонент системы. И для реального уровня риска часто не самый важный.

В материале Trustworthy agents in practice Anthropic предлагает смотреть сразу на четыре слоя:

— Model — сама модель и её поведение.
— Harness — инструкции, ограничения и логика, которая управляет агентом.
— Tools — инструменты и действия, доступные агенту.
— Environment — среда и данные, к которым он получил доступ.

Для тимлида это полезная смена фокуса.

Вопрос не только в том, ошибётся ли модель. Она обязательно когда-нибудь ошибётся.

Гораздо важнее другое:

Что система позволит ей сделать после ошибки?

Одна и та же модель может:

— читать задачи в Jira;
— менять статусы, исполнителей и описания;
— запускать скрипты в production.

Формально модель одна. Фактически это три системы с совершенно разным уровнем риска.

Поэтому безопасность агента я бы проектировал так же, как любую другую критичную систему:

— минимально необходимые права;
— ограниченный blast radius — масштаб возможного ущерба;
— read-only по умолчанию;
— явное подтверждение опасных действий;
— изоляция среды;
— журнал действий и возможность остановить выполнение.

Не нужно начинать с попытки сделать агента безошибочным. Это примерно такой же надёжный план, как запретить разработчикам писать баги.

Лучше исходить из того, что ошибка произойдёт, и заранее ограничить её последствия.

Безопасность агента определяется не только тем, насколько он умный. Она определяется тем, насколько опасную ошибку ему позволили совершить.

Материал: Anthropic — Trustworthy agents in practice


Adaptive Management System: управлять не по плану, а по обратной связи

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

Проблема в том, что среда меняется быстрее, чем обновляется план.

Появляются новые ограничения. Меняются приоритеты. Гипотезы не подтверждаются. Команда узнаёт о продукте и системе то, чего не могла знать в начале квартала.

Но план продолжает жить, как будто ничего не произошло.

В результате управление превращается в попытку заставить реальность соответствовать старым договорённостям.

Под Adaptive Management System я понимаю систему управления с замкнутым контуром обратной связи:

цель → действие → сигнал → решение → корректировка.

В ней план — не контракт с будущим, а текущая гипотеза о пути к цели.

Такая система отвечает на пять вопросов:

— какую наблюдаемую цель мы преследуем;

— какие ограничения нельзя нарушать;

— по каким сигналам поймём, что движемся не туда;

— как часто пересматриваем решение;

— кто может изменить курс и на основании каких данных.

Это похоже на управление технической системой. Недостаточно один раз задать параметры и уйти. Нужно измерять состояние, сравнивать его с ожидаемым и корректировать воздействие.

Для команды разработки это может выглядеть так:

1. Формулируем ожидаемый результат, а не только список задач.

2. Выбираем несколько сигналов: пользовательский эффект, lead time, количество возвратов, ошибки, нагрузку на поддержку.

3. Заранее договариваемся, когда проверим результат.

4. Если факты расходятся с ожиданиями, меняем способ достижения цели — а при необходимости и саму цель.

Важное ограничение: адаптивность — не постоянная смена приоритетов.

Если руководство приносит новую «самую важную» задачу каждый вторник, это не Adaptive Management System. Это отсутствие системы.

Адаптивное управление требует стабильного направления и управляемого способа менять маршрут. Иначе обратная связь превращается в шум, а команда — в сервис срочного реагирования.

Зрелая система управления оценивает не то, насколько точно мы выполнили первоначальный план.

Она оценивает, насколько быстро мы заметили ошибочную гипотезу и приняли более качественное решение.


AI не обесценивает экспертизу. Похоже, он делает её ещё выгоднее

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

Свежие данные Anthropic пока показывают почти обратное.

Исследователи проанализировали около 400 тысяч реальных сессий Claude Code за период с октября 2025-го по апрель 2026-го. В типичной сессии разделение труда выглядит так:

— человек принимает около 70% решений о том, что нужно сделать;
— Claude принимает около 80% решений о том, как это сделать.

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

Ещё интереснее связь с предметной экспертизой.

Чем лучше пользователь разбирается в задаче, тем больше работы агент выполняет после одной инструкции. В сессиях новичков один запрос запускал в среднем около пяти действий Claude, а в экспертных — около двенадцати.

Эксперты точнее формулируют задачу, задают осмысленные проверки и замечают, когда агент идёт не туда. А если что-то ломается, чаще возвращают работу на правильный путь.

Важная оговорка: основной прирост исследователи увидели между новичками и пользователями со средним уровнем знаний. Разрыв между уверенным специалистом и глубоким экспертом уже заметно меньше.

Для тимлида здесь важен сам сдвиг.

Раньше senior отличался прежде всего способностью самостоятельно решить сложную задачу. Теперь всё большую ценность получает способность правильно определить задачу, задать ограничения и направить исполнение.

Не обязательно самому писать каждую строчку.

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

Возможно, AI не уменьшает разрыв между junior и senior.

Он просто переносит этот разрыв с написания кода на качество решений.

Исследование Anthropic: Agentic coding and persistent returns to expertise


«Разработчик ошибся» — это не root cause

Production упал.

Нашли проблемное изменение. Нашли автора. Зафиксировали причину инцидента:

«Разработчик допустил ошибку».

Расследование закончено, можно расходиться.

Только непонятно, зачем тогда вообще нужен postmortem.

Человек действительно мог ошибиться. Но если одной человеческой ошибки достаточно, чтобы положить production, я бы смотрел глубже:

Почему система позволила этой ошибке превратиться в инцидент?

Вместо «Кто виноват?» полезнее задать другие вопросы.

Что произошло?

Нужен timeline: от первого изменения до обнаружения проблемы и восстановления системы.

Почему изменение выглядело безопасным?

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

Какие защиты должны были остановить ошибку?

— тесты;
— review;
— feature flag;
— canary-деплой;
— мониторинг;
— автоматический rollback;
— ограничения доступа.

Почему ни одна из них не сработала?

Как команда обнаружила проблему?

Мониторинг заметил её сам или первым написал пользователь?

Как восстанавливались?

Был ли понятный runbook или решение пришлось собирать по сообщениям, старым тикетам и воспоминаниям коллег?

Blameless-подход не означает, что никто ни за что не отвечает.

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

Иначе каждый postmortem заканчивается одинаково:

— быть внимательнее;
— лучше проверять;
— больше не ошибаться.

Три великолепных action item, которые человечество стабильно не выполняет уже несколько тысяч лет.

Хороший action item меняет систему.

Не «быть внимательнее при деплое», а добавить автоматическую проверку перед deployment.

Не «лучше проверять конфиг», а запретить опасное значение на уровне schema validation.

Не «следить за метрикой», а создать alert с конкретным порогом и понятным получателем.

Цель postmortem не в том, чтобы найти человека, который ошибся.

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


Разработчики работают не так, как сами считают продуктивным

Мы привыкли обсуждать productivity через результат:

— сколько задач завершили; 
— сколько времени занимает delivery; 
— сколько PR закрыли.

Но в исследовании Time Warp: The Gap Between Developers’ Ideal vs Actual Workweeks in an AI-Driven Era авторы задали другой вопрос:

На что разработчики хотели бы тратить рабочее время — и насколько это отличается от их реальной недели?

В опросе участвовали 484 разработчика Microsoft. Исследователи сравнили фактическое распределение времени с тем, которое сами разработчики считают оптимальным.

Обнаружилась простая закономерность: чем больше разрыв между желаемой и реальной неделей, тем ниже удовлетворённость работой и воспринимаемая продуктивность.

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

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

Отсюда хороший вопрос для 1:1:

Если бы ты мог перераспределить свою рабочую неделю, чего в ней стало бы меньше, а чего — больше?

Ответ может показать то, чего не видно в отчёте по закрытым задачам:

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

И здесь появляется интересная связь с AI.

Обычно компании выбирают сценарии автоматизации от возможностей инструмента: что модель уже умеет писать, анализировать или генерировать.

Можно развернуть вопрос:

Какую работу люди меньше всего хотят продолжать делать руками?

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

Не «куда ещё встроить AI».

А «что вернуть людям, убрав из их недели лишнюю механику».

Если задать этот вопрос вашей команде, чего она попросит меньше: встреч, поддержки, ручной работы, ожидания или переключений контекста?


Bus Factor AI-агента: кто понимает процесс, кроме него

Всю неделю мы говорили о долге понимания в коде. Но с AI он появляется не только там.

Представим, команда автоматизировала процесс через агента.

Агент знает нужные промпты, использует MCP, ходит во внутренние системы, выполняет инструкции и закрывает заметную часть работы.

Формально Bus Factor вырос: процесс больше не зависит от одного Васи.

Фактически Вася просто стал цифровым.

Раньше говорили:

«Это знает только Вася».

Теперь:

«Это делает агент. Лучше его не трогать».

Получился тот же knowledge silo, только теперь он спрятан между системным промптом, конфигурацией MCP и особенностями конкретной модели.

Я бы проверял такую автоматизацию несколькими вопросами:

— Где хранятся инструкции агента?

— Версионируются ли промпты и конфигурация?

— Понятно ли, какие инструменты он вызывает и с какими правами?

— Можно ли восстановить логику процесса по шагам?

— Кто владеет агентом и отвечает за изменения?

— Что сломается при смене модели?

— Сможет ли человек проверить результат и разобраться, почему агент принял такое решение?

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

Иначе агент ускоряет процесс, одновременно увеличивая долг понимания. Всё работает быстро, пока не меняется модель, API, сотрудник или исключение в бизнес-правиле. После этого начинается археология, только раскапывать приходится не код, а цепочку промптов и вызовов инструментов.

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

Если завтра ваш основной AI-агент перестанет запускаться, команда восстановит процесс по документации или начнёт изучать его поведение по логам?


AI ускоряет junior. Но ускоряет ли он его развитие?

Мы уже знаем, что AI способен ускорять выполнение задач. Но скорость delivery и скорость обучения — разные метрики.

В январе Anthropic опубликовал рандомизированное исследование о том, как AI-помощь влияет на формирование навыков программирования.

52 разработчика, преимущественно junior, изучали незнакомую им Python-библиотеку Trio. Одна группа могла обращаться к AI, другая писала код самостоятельно. После задания участники прошли тест на понимание концепций, чтение кода и отладку.

Группа с AI закончила в среднем примерно на две минуты раньше. Разница оказалась статистически незначимой.

Зато результат теста отличался заметно: 50% у группы с AI против 67% у тех, кто писал самостоятельно. Самый большой разрыв был в вопросах на отладку.

Это не означает, что AI вреден для junior.

Интереснее другое: результат зависел от того, как именно разработчик использовал модель.

Хуже справлялись те, кто делегировал AI написание и исправление кода. Лучше — те, кто задавал концептуальные вопросы, просил объяснить решение и продолжал разбираться самостоятельно.

По сути, исследование показывает риск cognitive offloading: задача решена, но часть размышлений, которые должны были сформировать навык, выполнила модель.

Раньше обучение часто выглядело так:

задача → тупик → документация → попытка → ошибка → отладка → понимание.

Теперь легко получить более короткий маршрут:

задача → агент → решение.

Формально результат есть. Фактически из процесса могла исчезнуть половина учебной петли.

И здесь появляется новая ответственность тимлида: различать задачи, которые нужно оптимизировать на скорость, и задачи, в которых разработчику нужно оставить пространство для обучения.

Например:

— знакомую рутину можно смело делегировать агенту;

— при освоении новой технологии AI лучше использовать как наставника, а не генератор ответа;

— после сгенерированного решения полезно просить разработчика объяснить его и найти возможные ошибки;

— часть задач стоит разбирать без автоматической генерации кода.

Возможно, AI-native командам придётся сознательно создавать «неэффективные» учебные ситуации. Не запрещать инструменты, а проектировать способ работы с ними.

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

А у вас AI для junior сейчас скорее исполнитель или наставник?

Исследование Anthropic о влиянии AI на формирование навыков программирования


Circuit Breaker: когда системе пора перестать пытаться

Recommendation Service лежит.

Но каждый пользовательский запрос всё равно пытается получить рекомендации:

— отправляет запрос; 
— ждёт timeout; 
— делает retry; 
— снова ждёт.

Пользователь тем временем смотрит на spinner и размышляет, у какого конкурента каталог работает быстрее.

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

В этот момент нужен Circuit Breaker — автоматический выключатель между системой и проблемной зависимостью.

У него три состояния.

Closed

Всё работает нормально. Запросы отправляются в Recommendation Service, а Circuit Breaker следит за ошибками и задержками.

Единичный timeout ничего не меняет: сбои случаются. Но если ошибок становится слишком много, выключатель переходит в следующее состояние.

Open

Запросы в Recommendation Service временно не отправляются вообще.

Система не ждёт заведомый timeout и не запускает бессмысленные retry. Она сразу возвращает fallback или продолжает работу без рекомендаций.

Это важно не только для пользователя. Упавший сервис получает время на восстановление, а не новую волну запросов от клиентов, которые очень настойчиво проверяют, не стало ли ему лучше.

Half-open

Через некоторое время Circuit Breaker пропускает несколько пробных запросов.

Если они проходят успешно, соединение возвращается в состояние Closed. Если снова падают — выключатель открывается ещё на один период.

Получается простой цикл:

Closed → ошибок стало слишком много → Open → прошло время → Half-open → сервис восстановился или снова Open.

Но самое интересное здесь не сам паттерн.

Допустим, рекомендации недоступны. Действительно ли из-за этого должен перестать работать весь магазин?

Вместо бесконечного spinner можно:

— скрыть блок рекомендаций; 
— показать популярные товары; 
— использовать последние успешно рассчитанные данные; 
— дать пользователю продолжить покупку без персонализации.

Circuit Breaker отвечает на вопрос: когда перестать обращаться к сломанной зависимости.

А архитектура системы должна ответить на следующий: что делать без неё.

Это уже graceful degradation — способность системы терять часть функций, но сохранять основную ценность для пользователя.

Какая необязательная зависимость у вас сегодня способна положить весь пользовательский сценарий?


Retry не чинит ошибку. Иногда он делает её в сто раз больше

Сервис B не отвечает.
Сервис A делает retry.
Потом ещё один.
И ещё один.

Таких экземпляров A — сто. У каждого свой поток запросов и своё желание довести дело до конца.

B начинает оживать, но вместе с новыми запросами получает волну повторных.

Теперь он снова лежит.

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

Зачем тогда нужны retry?

Для временных сбоев. Соединение оборвалось, инстанс перезапустился, балансировщик отправил запрос на уже недоступную машину. Следующая попытка действительно может сработать.

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

Retry нужен не для гарантии успеха. Он нужен для обработки временных сбоев.

Поэтому «повторить при любой ошибке» — плохая политика. Нужны конкретные правила.

1. Разделить ошибки

Сетевой сбой, timeout, некоторые 5xx — кандидаты на повтор, а не автоматическое разрешение.

Для 429 нужно учитывать ограничение частоты и Retry-After, если сервер его передал. Ошибки валидации и доступа бессмысленно повторять без изменения запроса или условий.

Смотреть нужно не только на код ответа, но и на контракт операции: безопасно ли вообще выполнить её ещё раз?

2. Увеличивать паузу

Exponential backoff — это растущая задержка между попытками. После каждого сбоя ждём дольше, но не выше заданного предела.

Смысл простой: дать зависимости время восстановиться, а не проверять её здоровье непрерывным потоком запросов.

3. Добавить случайность

Если все экземпляры A получили ошибку одновременно и ждут одинаковое время, повторять они тоже придут одновременно.

Backoff без случайности может просто перенести пик нагрузки.

Jitter добавляет случайный разброс задержек, чтобы клиенты возвращались не строем.

Иначе возникает retry storm: ошибки вызывают повторы, повторы увеличивают нагрузку, нагрузка вызывает новые ошибки.

4. Не забыть про идемпотентность

Здесь возвращаемся к предыдущей теме.

Timeout означает, что клиент не дождался ответа. Он не означает, что сервер ничего не сделал.

Сервис мог списать деньги, сохранить заказ и потерять соединение до отправки ответа. Повторяем запрос — рискуем повторить действие.

Для такой операции нужен механизм идемпотентности. Например, ключ, по которому сервер распознаёт повтор и возвращает результат уже выполненной операции, не выполняя её заново.

Важно: ключ должен оставаться тем же на всех попытках. Новый ключ на каждый retry — это уже новые операции.

5. Ограничить попытки и время

У повторов должен быть конец: лимит попыток и общий дедлайн, включая ожидание между ними.

И стоит проверить, кто именно повторяет запрос. Если это одновременно делают приложение, SDK и прокси, число реальных обращений может оказаться сильно больше, чем ожидает разработчик.

Даже backoff и jitter не делают бесконечные повторы безопасными.

Хорошая retry-политика отвечает на четыре вопроса: что повторяем, безопасно ли это, сколько ждём и когда останавливаемся.

Но есть следующий уровень проблемы.

Если соседний сервис продолжает лежать, зачем каждому новому запросу заново проходить весь путь из таймаутов и повторов?

В какой момент стоит вообще перестать к нему ходить — и как понять, что уже можно вернуться?

Это уже про circuit breaker.


Сегодня на e-code от ozon tech


Метрики без насилия

99,99% availability не всегда лучше 99,9%

Хотим availability 99,99%.

Звучит очевидно: чем больше девяток, тем надёжнее система. Тогда почему бы сразу не потребовать 99,99999%?

Потому что каждая следующая девятка стоит денег, времени и инженерных ограничений.

Она требует больше резервирования, более сложного мониторинга, быстрых механизмов восстановления и осторожных релизов. Иногда это оправданно. Иногда мы просто строим космический корабль для поездки в соседний магазин.

Надёжность должна определяться требованиями продукта, а не инженерным перфекционизмом.

Для этого обычно используют три понятия.

SLI — что именно измеряем.

Например, долю запросов, завершившихся успешно.

SLO — какой уровень хотим обеспечить.

Например: 99,9% успешных запросов за 30 дней.

Error budget — сколько ошибок можем допустить, не нарушив SLO.

Для SLO по времени доступности разница хорошо видна на цифрах:

— 99,9% оставляет около 43 минут недоступности за 30 дней; 
— 99,99% — около 4 минут; 
— 99,999% — примерно 26 секунд.

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

Но самое полезное в error budget даже не расчёт допустимых отказов.

Он связывает две конфликтующие силы.

Разработка хочет быстрее выпускать изменения, экспериментировать и проверять гипотезы.

Reliability требует стабильности, дополнительных проверок и меньшего количества рискованных изменений.

Без общей метрики спор быстро превращается в:

— Нам надо быстрее. 
— Нам надо надёжнее.

С error budget появляется измеримая договорённость.

Если бюджет почти не расходуется, команда может позволить себе больше изменений.

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

Важное ограничение: error budget нельзя превращать в KPI разработчика.

Его задача — не найти человека, который «потратил наши минуты недоступности». Это не табель инженерной виновности.

Error budget ограничивает всю систему delivery: архитектуру, тестирование, релизы, мониторинг и восстановление после сбоев.

Надёжность тоже имеет стоимость.

Поэтому правильный вопрос звучит не так:

«Как сделать систему максимально надёжной?»

А так:

«Какой уровень надёжности нужен бизнесу и какой риск он готов принять?»


Bus Factor: что произойдёт, если самый важный разработчик завтра исчезнет

В команде есть разработчик, который знает всё про платежи.

Любой сложный баг идёт к нему.
Любое изменение API ревьюит он.
На любой вопрос ответ: «Спроси Васю».

Кажется, у команды есть сильный эксперт.

На самом деле у неё ещё есть single point of failure.

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

Если без Васи нельзя безопасно изменить платежи, разобраться с инцидентом или выпустить релиз, Bus Factor этой области равен единице.

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

Проблема начинается, когда знания эксперта не превращаются в знания системы.

Признаки обычно хорошо заметны:

— только один человек понимает, почему архитектура устроена именно так;
— его approval фактически обязателен для каждого изменения;
— во время его отпуска задачи встают или откладываются;
— документация заканчивается на «там всё понятно из кода»;
— остальные разработчики избегают области, потому что дешевле дождаться эксперта;
— после инцидента объяснение остаётся в созвоне и нигде не фиксируется.

Так появляется knowledge silo — область знаний, доступная одному человеку или узкой группе.

При этом формально ownership есть. Фактически это не владение системой, а монополия на её обслуживание.

Что можно сделать?

Разделять code ownership.
У критичной области должен быть основной владелец, но не единственный человек, способный внести изменение. Полезная проверка: кто примет решение, если владелец недоступен две недели?

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

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

Использовать shadowing.
Разработчик сначала наблюдает за работой эксперта, потом выполняет похожую задачу вместе с ним, а затем делает её самостоятельно под наблюдением. Просто посидеть на одном созвоне рядом недостаточно.

Документировать не только “как”, но и “почему”.
Схему компонентов обычно восстановить можно. Гораздо сложнее понять, почему выбрали такой контракт, какие ограничения нельзя нарушать и где уже пробовали «простое решение», которое не сработало.

При этом «пусть Вася обучит всех» — тоже не стратегия.

Во-первых, Вася становится ещё большим bottleneck: теперь он одновременно разрабатывает, ревьюит, отвечает на вопросы и ведёт внутренний университет.

Во-вторых, знания без практики быстро превращаются в заметки, которые все читали и никто не может применить во время инцидента.

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

И важное ограничение: снижать Bus Factor — не значит делать всех взаимозаменяемыми.

Не нужно, чтобы каждый разработчик знал всё про каждый сервис. Это дорого и почти невозможно.

Цель проще: критичная область не должна зависеть от доступности одного человека.

Сильный эксперт усиливает команду, когда рядом с ним растут другие владельцы. Если же без него останавливается работа, это уже не только экспертиза.

Это организационный риск.

В какой области вашей системы ответ на большинство вопросов до сих пор звучит как «спроси Васю»?


Система не обязана либо работать, либо лежать

У интернет-магазина сломался сервис рекомендаций.

Что должен увидеть пользователь?

Вариант А:

500 Internal Server Error

Вариант Б:

интернет-магазин без рекомендаций.

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

Но не все функции продукта одинаково критичны.

Если второстепенный компонент недоступен, система может продолжить выполнять основную задачу в degraded mode — режиме ограниченной функциональности.

Например:

— нет рекомендаций — показываем популярные товары;

— нет актуальных остатков — используем последние известные данные с предупреждением, если бизнес допускает такой риск;

— не работает сервис уведомлений — сохраняем сообщения в очередь и отправляем позже;

— недоступна аналитика — не блокируем действия пользователя;

— не отвечает внешний партнёр — принимаем операцию и завершаем асинхронно, если это разрешено бизнес-процессом.

Технически здесь понадобятся таймауты, circuit breaker, очереди, кэш и fallback-сценарии.

Но сначала нужно ответить на продуктовый вопрос:

что действительно должно продолжать работать?

Для условного интернет-магазина приоритеты могут выглядеть так:

Tier 1 — авторизация, оформление заказа, платёж.

Tier 2 — каталог и поиск.

Tier 3 — рекомендации, отзывы и персонализация.

Это не универсальная классификация. В другом продукте поиск может быть главным сценарием, а авторизация вообще не требоваться для просмотра каталога.

Поэтому graceful degradation нельзя спроектировать силами backend-команды в вакууме. Нужна заранее согласованная иерархия функций:

— что нельзя потерять ни при каких условиях;

— что может работать с ограничениями;

— что можно временно отключить;

— где допустимы устаревшие данные;

— о каких ограничениях нужно сообщить пользователю.

Хорошая отказоустойчивость не означает «никогда не ломаться».

Она означает заранее понимать, что должно продолжить работать, когда что-то сломалось.

И degraded mode нужно проверять под реальными отказами: отключать зависимости, добавлять задержки, возвращать ошибки, останавливать обработчики очередей.

Иначе он существует только на архитектурной диаграмме. А диаграммы, как известно, падают заметно реже продакшена.

Показано 20 последних публикаций.