Предновогодний пост
Хочу поделиться одной из наиболее релевантных тем для меня за этот год — как не загнуться в новой роли
На работе за этот год я побывал в 4х ролях(или почему посты выходят раз в месяц)
1. Лид одной команды бэкендеров
2. Лид всего бэкенда (несколько команд)
3. Лид всего бэкенда + лид vteam по внедрению ml в клиентскую поддержку
*происходит реорг, который функциональные структуры превращает в кросс-функциональные команды + гильдии*
4. Лид гильдии бэкенда + лид vteam + зам своего рук-ля
---
Каждый такой переход — это своего рода шажок в неизвестность, который сопровождается
- страхом, что не получится
- непониманием, а с чего начать
Хорошая новость — с этим можно что-то делать
Страх, что не получится
Но что такое "не получится"? Это значит кто-то тобой недоволен => ты нарушил чьи-то ожидания => а были какие-то ожидания?
Были. И очень важно в явном виде сформулировать взаимные ожидания со всеми ключевыми стейколдерами, с которыми тебе надо будет взаимодействовать
По крайней мере, это даст понимание, хорошо или плохо ты справляешься
Непонимание, а с чего начать
Из предыдущих разговоров у тебя скорее всего появится список актуальных проблем в твоей текущей зоне ответственности
Мое мнение — стоит начать с самых низковисящих фруктов, иначе говоря показать какие-то quick wins. Возможно, это само по себе не принесет большой пользы, но это во-первых даст тебе уверенность, что ты можешь делать что-то полезное в новой роли, во-вторых окружающие увидят, что ты делаешь что-то полезное
---
Если подытожить в трех пунктах, то алгоритм выглядит так:
1. Сформировать ожидания с ключевыми стейкхолдерами
2. Набрать список текущих проблем
3. Показать какие-то quick wins
После этого дальше двигаться будет сильно проще
---
И в заключение хочу вас поздравить с наступающим Новым годом! Пусть вас окружают близкие по духу люди, поражения не ломают, а победы вдохновляют)
Хочу поделиться одной из наиболее релевантных тем для меня за этот год — как не загнуться в новой роли
На работе за этот год я побывал в 4х ролях
1. Лид одной команды бэкендеров
2. Лид всего бэкенда (несколько команд)
3. Лид всего бэкенда + лид vteam по внедрению ml в клиентскую поддержку
*происходит реорг, который функциональные структуры превращает в кросс-функциональные команды + гильдии*
4. Лид гильдии бэкенда + лид vteam + зам своего рук-ля
---
Каждый такой переход — это своего рода шажок в неизвестность, который сопровождается
- страхом, что не получится
- непониманием, а с чего начать
Хорошая новость — с этим можно что-то делать
Страх, что не получится
Но что такое "не получится"? Это значит кто-то тобой недоволен => ты нарушил чьи-то ожидания => а были какие-то ожидания?
Были. И очень важно в явном виде сформулировать взаимные ожидания со всеми ключевыми стейколдерами, с которыми тебе надо будет взаимодействовать
По крайней мере, это даст понимание, хорошо или плохо ты справляешься
Непонимание, а с чего начать
Из предыдущих разговоров у тебя скорее всего появится список актуальных проблем в твоей текущей зоне ответственности
Мое мнение — стоит начать с самых низковисящих фруктов, иначе говоря показать какие-то quick wins. Возможно, это само по себе не принесет большой пользы, но это во-первых даст тебе уверенность, что ты можешь делать что-то полезное в новой роли, во-вторых окружающие увидят, что ты делаешь что-то полезное
---
Если подытожить в трех пунктах, то алгоритм выглядит так:
1. Сформировать ожидания с ключевыми стейкхолдерами
2. Набрать список текущих проблем
3. Показать какие-то quick wins
После этого дальше двигаться будет сильно проще
---
И в заключение хочу вас поздравить с наступающим Новым годом! Пусть вас окружают близкие по духу люди, поражения не ломают, а победы вдохновляют)
2👍100🔥32🤔6💅1
Yet another пост про то, как победить неопределенность
У меня часто возникает ситуация, что задачу вроде понятно как решать, но все равно какой-то сумбур в голове и не понятно, с чего начать
Мне помогает такой способ:
1. Взять пункт, который точно придется делать
2. Подумать, что должно быть до него
3. Подумать, что должно быть после него
Пример: нужно сделать гайдлайны по написанию тестов в нашей системе
Что точно нужно сделать?
- написать пример теста
Что мне нужно для выполнения этого пункта?
- определиться, какого типа будет этот тест (unit / integration / ...)
- определиться, на что писать этот тест
- определиться, как будет выглядить этот тест
Что надо сделать после?
- добавить этот пример в доку
- презентовать команде
И из этого вырисовывается вполне понятный список дел:
1. определиться, какого типа хотим тесты
2. определиться, на что пишем тесты
3. определиться с кодстайлом
4. написать пример теста
5. написать доку
6. презентовать команде
И таким образом из размытой непонятной задачи сформировали вполне понятный план. Пользуйтесь!
У меня часто возникает ситуация, что задачу вроде понятно как решать, но все равно какой-то сумбур в голове и не понятно, с чего начать
Мне помогает такой способ:
1. Взять пункт, который точно придется делать
2. Подумать, что должно быть до него
3. Подумать, что должно быть после него
Пример: нужно сделать гайдлайны по написанию тестов в нашей системе
Что точно нужно сделать?
- написать пример теста
Что мне нужно для выполнения этого пункта?
- определиться, какого типа будет этот тест (unit / integration / ...)
- определиться, на что писать этот тест
- определиться, как будет выглядить этот тест
Что надо сделать после?
- добавить этот пример в доку
- презентовать команде
И из этого вырисовывается вполне понятный список дел:
1. определиться, какого типа хотим тесты
2. определиться, на что пишем тесты
3. определиться с кодстайлом
4. написать пример теста
5. написать доку
6. презентовать команде
И таким образом из размытой непонятной задачи сформировали вполне понятный план. Пользуйтесь!
2👍74🔥17
Про Стратоплан и менеджмент pt.3
На новогодних закрываю долги по курсу. Очередные 4 занятия:
• Основы финансового менеджмента
• Построение финмоделей
• Бюджетирование
• Управление ресурсами
Первые два занятия — введение в финансы: как двигаются деньги в компании, основные отчеты (PnL, Cash Flow, Баланс), коэффициенты рентабельности и т.п.
Еще из интересного: в эксельке посмотрели на реальные финмодели из прошлой практики преподавателя и попробовали оценить целесообразность в них инвестировать с помощью NPV, IRR, PP, DPP
Как считать NPV (Net Present Value): берем прогноз денежных потоков (поступления и выплаты), берем некоторую ставку дисконтирования r — ставку, позволяющая перевести будущие денежные потоки в текущую стоимость, может быть %-ом инфляции, ставкой кредитования, WACC, ...
И далее считаем сумму денежных потоков (CF) с учетом ставки дисконтирования (r) и из нее вычитаем начальные инвестиции
NPV = Σ (CFₜ / (1 + r)ᵗ) − CF₀
Если NPV > 0 за некоторый период, то с учетом данной ставки дисконтирования проект окупится
IRR (Internal Rate of Return) — связанная вещь, где в формуле выше ставка дисконтирования берется за переменную, и считается при какой ставке дисконтирования проект сможет окупить инвестиции
PP (Payback Period), DPP (Discounted Payback Period) — всё та же формула. Только уже считаем за какой срок окупятся инвестиции в проект без учета/с учетом ставки дисконтирования
Это всё конечно занимательно, но хороший вопрос — где это прямо сейчас применять. Скорее это пока из серии "через месяц забуду и вернусь к ним, когда понадобится"
—
Третье и четвертое занятия в этом смысле более прикладные
Третье — про процесс работы с бюджетами: финансовый и операционный бюджеты; как планировать, защищать, контролировать и т.д. Отдельно порадовали кулстори из жизни про то, как можно защитить бюджет, если начальство не согласно (иногда не меняя общую сумму)
И последнее в этом блоке занятие — про планирование ресурсов. Тут мне понравился алгоритм, так что даже поделюсь:
Задача — запланировать проекты на квартал/полугодие/...
1. Делаем карту компетенций по сотрудникам команды. Если не требуется чего-то особенного, зачастую компетенции будут уровня back, front, qa, аналитика и т.п.
2. Делаем табличку "team capacity" — сколько ресурсов определенной компетенции есть в рамках команды. И здесь хороший вопрос — в каких единицах измерения оценивать: можно в обычных человекочасах, это простой способ, но одновременно крайне неточный. Можно в "идеальных человекочасах" — это когда мы берем условного разработчика, откидываем от него ~10% времени на поддержку, ~20% времени на техдолг, ~10% на "срочные влеты", ~15% на встречи, и получаем скудные ~35-40% времени на написание новых фичей — именно это называется идеальными человекочасами, которые у разработчика будут на делание проекта
3. Делаем табличку "спрос" — сколько ресурсов определенной компетенции нужно для завершения проектов X, Y, Z
4. И сводя "team capacity" и "спрос" мы можем получить, сколько % ресурсов определенной компетенции у нас есть для закрытия всех проектов. Например back - 52%, front - 56%, qa - 39%. Именно это нам позволяет понять узкое место команды
5. И далее наша цель — максимально нагрузить узкое место, поскольку оно определяет мощность команды, выбрав при этом проекты с максимальными эффектами
К слову этот алгоритм очень матчится с тем, что написано в "Цели" Голдратта. Может в будущем запилю отдельный пост по этой книге
Пишите мнение в комментариях, задавайте вопросы
На новогодних закрываю долги по курсу. Очередные 4 занятия:
• Основы финансового менеджмента
• Построение финмоделей
• Бюджетирование
• Управление ресурсами
Первые два занятия — введение в финансы: как двигаются деньги в компании, основные отчеты (PnL, Cash Flow, Баланс), коэффициенты рентабельности и т.п.
Еще из интересного: в эксельке посмотрели на реальные финмодели из прошлой практики преподавателя и попробовали оценить целесообразность в них инвестировать с помощью NPV, IRR, PP, DPP
Как считать NPV (Net Present Value): берем прогноз денежных потоков (поступления и выплаты), берем некоторую ставку дисконтирования r — ставку, позволяющая перевести будущие денежные потоки в текущую стоимость, может быть %-ом инфляции, ставкой кредитования, WACC, ...
И далее считаем сумму денежных потоков (CF) с учетом ставки дисконтирования (r) и из нее вычитаем начальные инвестиции
NPV = Σ (CFₜ / (1 + r)ᵗ) − CF₀
Если NPV > 0 за некоторый период, то с учетом данной ставки дисконтирования проект окупится
IRR (Internal Rate of Return) — связанная вещь, где в формуле выше ставка дисконтирования берется за переменную, и считается при какой ставке дисконтирования проект сможет окупить инвестиции
PP (Payback Period), DPP (Discounted Payback Period) — всё та же формула. Только уже считаем за какой срок окупятся инвестиции в проект без учета/с учетом ставки дисконтирования
Это всё конечно занимательно, но хороший вопрос — где это прямо сейчас применять. Скорее это пока из серии "через месяц забуду и вернусь к ним, когда понадобится"
—
Третье и четвертое занятия в этом смысле более прикладные
Третье — про процесс работы с бюджетами: финансовый и операционный бюджеты; как планировать, защищать, контролировать и т.д. Отдельно порадовали кулстори из жизни про то, как можно защитить бюджет, если начальство не согласно (иногда не меняя общую сумму)
И последнее в этом блоке занятие — про планирование ресурсов. Тут мне понравился алгоритм, так что даже поделюсь:
Задача — запланировать проекты на квартал/полугодие/...
1. Делаем карту компетенций по сотрудникам команды. Если не требуется чего-то особенного, зачастую компетенции будут уровня back, front, qa, аналитика и т.п.
2. Делаем табличку "team capacity" — сколько ресурсов определенной компетенции есть в рамках команды. И здесь хороший вопрос — в каких единицах измерения оценивать: можно в обычных человекочасах, это простой способ, но одновременно крайне неточный. Можно в "идеальных человекочасах" — это когда мы берем условного разработчика, откидываем от него ~10% времени на поддержку, ~20% времени на техдолг, ~10% на "срочные влеты", ~15% на встречи, и получаем скудные ~35-40% времени на написание новых фичей — именно это называется идеальными человекочасами, которые у разработчика будут на делание проекта
3. Делаем табличку "спрос" — сколько ресурсов определенной компетенции нужно для завершения проектов X, Y, Z
4. И сводя "team capacity" и "спрос" мы можем получить, сколько % ресурсов определенной компетенции у нас есть для закрытия всех проектов. Например back - 52%, front - 56%, qa - 39%. Именно это нам позволяет понять узкое место команды
5. И далее наша цель — максимально нагрузить узкое место, поскольку оно определяет мощность команды, выбрав при этом проекты с максимальными эффектами
К слову этот алгоритм очень матчится с тем, что написано в "Цели" Голдратта. Может в будущем запилю отдельный пост по этой книге
Пишите мнение в комментариях, задавайте вопросы
Литрес
Цель. Процесс непрерывного совершенствования — Элияху Голдратт Альпина ПРО Альпина Диджитал | Литрес
«Послушай, Алекс, я тебе вот что скажу. Эти определения, несмотря на всю их кажущуюся простоту, сформулированы крайне тщательно. Определение и должно быть сформулировано очень точно. Нечеткое определ…
👍23🔥17
Нагруженные счетчики на postgres
Недавно смотрел доклад и наткнулся на интересный хак
Есть классическая таблица со счетчиками
И обновлениями по id
Если нагрузка небольшая или размазана по счетчикам с разными id, все будет ок. При этом если начнется массовый поток апдейтов на небольшой набор каунтеров, будут интересные спецэффекты:
• как известно, update физически не обновляет строку, а создает ее новую версию из-за MVCC
• autovacuum, который должен чистить "мертвые" версии строк, может этого не делать по куче причин
• и постгрес, чтобы сделать очередной update по id, начинает вычитывать кучу версий строк в поисках "живой" версии (похожая ситуация описывалась в этом посте)
Как следствие — серьезная деградация производительности
—
Решение 1 — не заставлять делать постгрес, что он не должен делать
Решение 2 — подсказать постгресу, какую именно версию строки нужно прочитать
Добавляем к счетчикам колонку last_updated — таймстемп последнего обновления
Имея такое, мы можем попросить постгрес сделать апдейт по конкретному ctid (физическому местоположению строки), при этом внутренний селект будет выполняться быстро даже в случае серьезного блоата
Важный момент — если между селектом и апдейтом ctid "последней" версии строки поменялся (кто-то конкуретно обновил счетчик), то наш апдейт ничего не поменяет. Поэтому важно этот запрос обернуть в блокировку по id
Получается как-то так
Это может помочь вам обезопасить базу, если вдруг у вас есть супер нагруженные счетчики и нет возможности съехать с постгреса
А вообще рекомендую посмотреть доклад полностью, помимо проблемы выше, там рассказано еще много чего интересного. Тайминг конкретно по кейсу выше - четвертая минута
Недавно смотрел доклад и наткнулся на интересный хак
Есть классическая таблица со счетчиками
create table counters (
id int primary key,
cnt bigint
);
И обновлениями по id
update counters set cnt = cnt + 1 where id = ...
Если нагрузка небольшая или размазана по счетчикам с разными id, все будет ок. При этом если начнется массовый поток апдейтов на небольшой набор каунтеров, будут интересные спецэффекты:
• как известно, update физически не обновляет строку, а создает ее новую версию из-за MVCC
• autovacuum, который должен чистить "мертвые" версии строк, может этого не делать по куче причин
• и постгрес, чтобы сделать очередной update по id, начинает вычитывать кучу версий строк в поисках "живой" версии (похожая ситуация описывалась в этом посте)
Как следствие — серьезная деградация производительности
—
Решение 1 — не заставлять делать постгрес, что он не должен делать
Решение 2 — подсказать постгресу, какую именно версию строки нужно прочитать
Добавляем к счетчикам колонку last_updated — таймстемп последнего обновления
create table counters (
id int primary key,
cnt bigint,
last_updated timestamp
);
create index g1 on counters(id, last_updated);
Имея такое, мы можем попросить постгрес сделать апдейт по конкретному ctid (физическому местоположению строки), при этом внутренний селект будет выполняться быстро даже в случае серьезного блоата
update counters
set cnt = cnt + 1, last_updated = now()
where ctid = (
select ctid
from counters
where id = ...
order by last_updated desc
limit 1
);
Важный момент — если между селектом и апдейтом ctid "последней" версии строки поменялся (кто-то конкуретно обновил счетчик), то наш апдейт ничего не поменяет. Поэтому важно этот запрос обернуть в блокировку по id
Получается как-то так
select pg_advisory_lock(...)
update counters
set cnt = cnt + 1, last_updated = now()
where ctid = (
select ctid
from counters
where id = ...
order by last_updated desc
limit 1
);
select pg_advisory_unlock(...)
Это может помочь вам обезопасить базу, если вдруг у вас есть супер нагруженные счетчики и нет возможности съехать с постгреса
А вообще рекомендую посмотреть доклад полностью, помимо проблемы выше, там рассказано еще много чего интересного. Тайминг конкретно по кейсу выше - четвертая минута
YouTube
Аномалии под нагрузкой в PostgreSQL 2.0 / Михаил Жилин
Крупнейшая профессиональная конференция для разработчиков высоконагруженных систем Saint HighLoad++ 2026
Подробнее: https://clck.ru/3QZHTb
Июнь, 2026.
Санкт-Петербург, DESIGN DISTRICT DAA in SPB
--------
VK (https://vk.com/vkteam) делает просвещение доступным:…
Подробнее: https://clck.ru/3QZHTb
Июнь, 2026.
Санкт-Петербург, DESIGN DISTRICT DAA in SPB
--------
VK (https://vk.com/vkteam) делает просвещение доступным:…
1👍60🔥20💅1
Всегда было интересно, как AI Overview в гугле работает так быстро, и тут наткнулся на статью https://research.google/blog/looking-back-at-speculative-decoding/
Оказалось, что они используют технику speculative decoding
В обычном сетапе тяжелая llm генерирует токен за токеном, что может быть слишком долго/дорого. Однако, некоторые токены предсказать довольно просто:
• частые слова вроде the, is, of, and, ...
• цифры / имена, которые уже были в контексте
• повторяющиеся связки слов
И идея заключается в том, что а давайте сначала пробовать сгенерировать несколько токенов более легковесной моделью, далее большая модель их батчево проверит, и если ок, то оставит, если не ок — сгенерит сама
Вместо:
Будем делать:
И если small и large модели работают "похожим образом", то это может дать серьезный буст в скорости генерации, так как мы будем часто оставлять те токены, которые предложила легковесная модель и не будем тратить ресурсы на генерацию с помощью тяжелой модели
Btw похожая техника используется в Cursor https://cursor.com/blog/instant-apply
Оказалось, что они используют технику speculative decoding
В обычном сетапе тяжелая llm генерирует токен за токеном, что может быть слишком долго/дорого. Однако, некоторые токены предсказать довольно просто:
• частые слова вроде the, is, of, and, ...
• цифры / имена, которые уже были в контексте
• повторяющиеся связки слов
И идея заключается в том, что а давайте сначала пробовать сгенерировать несколько токенов более легковесной моделью, далее большая модель их батчево проверит, и если ок, то оставит, если не ок — сгенерит сама
Вместо:
large model:
context → T1
context+T1 → T2
context+T1+T2 → T3
...
Будем делать:
small model:
context → T1
context+T1 → T2
context+T1+T2 → T3
large model:
проверяет context+T1+T2+T3
ок → оставляем
не ок → large генерит сама
И если small и large модели работают "похожим образом", то это может дать серьезный буст в скорости генерации, так как мы будем часто оставлять те токены, которые предложила легковесная модель и не будем тратить ресурсы на генерацию с помощью тяжелой модели
Btw похожая техника используется в Cursor https://cursor.com/blog/instant-apply
Google Research
Looking back at speculative decoding
Speculative decoding has proven to be an effective technique for faster and cheaper inference from LLMs without compromising quality. It has also proven to be an effective paradigm for a range of optimization techniques.
1🔥40👍22💅2
Несколько способов дождаться результата асинхронной задачи
Сетап:
1. Клиент отправляет какой-то запрос
2. Джоба ставится в очередь задач
3. Клиент получает jobId
4. Клиент хочет дождаться результата
Поллинг
Самый простой с точки зрения бэкенда способ, нужна всего лишь апишка, которая по jobId вернет актуальный статус
И клиент в эту апишку долбится с некоторой периодичностью
Лонг поллинг
Более сложный, но более удобный для клиента вариант: клиент делает один запрос, сервер ждёт, пока задача завершится (или истечет таймаут), и возвращает результат
Как такое реализовать?
Идея 1: ожидание в потоке обработки
Сделать просто, но есть несколько очевидных минусов:
• Блочится поток обработки. В классической thread-per-request модели это быстро приведет к тому, что все request-threads будут заняты ожиданием. Для легковесных го(-ко)рутин проблема сильно менее критична:)
• Можем замучать базу кучей точечных запросов
Идея 2: асинхронное ожидание
Давайте попробуем решить сразу обе проблемы — не занимать поток обработки, и не мучать базу кучей запросов. Сделать это можно так:
1. На уровне контроллера отдаем фьючу и сразу освобождаем поток
Соединение остаётся открытым, но поток обработки запроса освобождается сразу
2. Появляется отдельный компонент, который
• позволяет зарегистрировать ожидание задачи
• держит in-memory структуру вида Map<JobId, Future> задач, которых клиенты ожидают
• батчево поллит базу по набору JobId
• по готовности — завершает все связанные фьючи
Таким образом, ожидание не держит request-thread и в базу идет контролируемый батч-запрос раз в какой-то промежуток времени
—
Альтернативы: вебсокеты, SSE, коллбэки
Пишите в комментах, что из этого используете, и какие еще знаете варианты реализации
Сетап:
1. Клиент отправляет какой-то запрос
2. Джоба ставится в очередь задач
3. Клиент получает jobId
4. Клиент хочет дождаться результата
Поллинг
Самый простой с точки зрения бэкенда способ, нужна всего лишь апишка, которая по jobId вернет актуальный статус
И клиент в эту апишку долбится с некоторой периодичностью
client -> server: jobId = 123
client <- server: status = running
...
client -> server: jobId = 123
client <- server: status = running
...
client -> server: jobId = 123
client <- server: status = done
Лонг поллинг
Более сложный, но более удобный для клиента вариант: клиент делает один запрос, сервер ждёт, пока задача завершится (или истечет таймаут), и возвращает результат
client -> server: jobId = 123
...
client <- server: status = done
Как такое реализовать?
Идея 1: ожидание в потоке обработки
fun await(id: JobId): JobResult {
while (true) {
val result = jobService.get(id)
if (result.status != RUNNING) {
return result
}
Thread.sleep(1000)
}
}
Сделать просто, но есть несколько очевидных минусов:
• Блочится поток обработки. В классической thread-per-request модели это быстро приведет к тому, что все request-threads будут заняты ожиданием. Для легковесных го(-ко)рутин проблема сильно менее критична:)
• Можем замучать базу кучей точечных запросов
Идея 2: асинхронное ожидание
Давайте попробуем решить сразу обе проблемы — не занимать поток обработки, и не мучать базу кучей запросов. Сделать это можно так:
1. На уровне контроллера отдаем фьючу и сразу освобождаем поток
fun await(id: JobId): DeferredResult<JobResult> {
val dr = DeferredResult<JobResult>()
val future = jobWaitService.register(id)
future.whenComplete { result, _ ->
dr.setResult(result)
}
return dr
}
Соединение остаётся открытым, но поток обработки запроса освобождается сразу
2. Появляется отдельный компонент, который
• позволяет зарегистрировать ожидание задачи
• держит in-memory структуру вида Map<JobId, Future> задач, которых клиенты ожидают
• батчево поллит базу по набору JobId
• по готовности — завершает все связанные фьючи
Таким образом, ожидание не держит request-thread и в базу идет контролируемый батч-запрос раз в какой-то промежуток времени
—
Альтернативы: вебсокеты, SSE, коллбэки
Пишите в комментах, что из этого используете, и какие еще знаете варианты реализации
🔥25👍8💅2
Про Стратоплан и менеджмент pt.4
Таки осилил основную часть курса "Руководитель отдела", были три занятия про
• Целеполагание и реализацию стратегии
• Найм и развитие ключевых сотрудников
• Системный people-management
Первое занятие
Достаточное лайтовое. Ключевая мысль: есть perfomance goals, есть development goals
• perfomance goals обычно "SMART-уются" и влияют на ближайшее вознаграждение. Пример: увеличить метрику X на Y п.п. до ближайшего perfomance review
• development goals — наоборот: их обычно сложно измерить, и нацелены на развитие на будущее. Пример: улучшить софты
При этом development goals можно достигать по разному. Например, к улучшению софтов можно подходить разными путями: можно бить в публичные выступления, можно бить в решение конфликтов и т.п.
И то, каким путем достигается цель, это и есть стратегия — т.е. некоторый вектор приложения сил
И для декомпозиции таких целей предлагается фреймворк GOSPA (Goals, Objectives, Strategies, Plans, and Activities). Btw, по этому фреймворку бывает удобно описать какие-то личные цели, не касающиеся работы
Второе занятие
В основном дается некоторая база про найм и развитие: портрет кандидата, матрицы компетенций и т.д.
При этом запомнились несколько интересных мыслей
В найме тимлидов очень важно много времени уделять мэтчу с корпоративной культурой. И делать это можно, задавая вопросы не "какие результаты ты получил на прошлой работе?", а "как ты их получил?"
Почему это важно? Один тимлид может выжигать команду, заставлять овертаймить, и таким образом давать результат. Второй может очень мягко идти в долгосрочную мотивацию. И парадоксально — и то, и то может быть как ок, так и не ок в рамках определенной корп культуры
И очень неплохо такое вскрывать помогают проективные вопросы. Это работает так: задается какой-то общий вопрос типа "как думаешь, почему люди обычно увольняются?". И вопрос вроде бы про "всех", но человек скорее всего начнет говорить про себя, через призму своего опыта
Третье занятие
Про системный people-management. Мое любимое, так как немного сдвинуло парадигму мышления
Ключевая мысль: поведение людей — рациональный ответ на структуру системы. И если поведение не нравится, то проблема почти всегда в системе, а не в людях
Как это работает? Во всех компаниях есть вещи, которые явно не прописаны, но которые определяют, как работает система:
• кто по факту принимает решения?
• кто имеет право-вето?
• как на самом деле реагируют на ошибки?
• за что на самом деле поощряют и продвигают?
И каждый руководитель дает своим сотрудникам эти сигналы, зачастую усиливая сигналы руководителя сверху. Пример:
• CTO: проект X нужно выполнить к дд.мм.ГГГГ! Если что то пойдет не так, виноватых найдем и накажем!
• Рук отдела/TL: ошибаться опасно, нужно жестче контролировать разработчиков
• Разработчик: сделаю ровно то, что просят. Жду новую постановку задачи. Если будут делать ровно то, что скажут, то меня не накажут
В итоге из-за сигнала сверху что ошибаться нельзя, получили безынициативных разработчиков
И чтобы менять систему, очень важно уметь замечать такие сигналы. Далее в занятии даются практики, которые помогают раздебажить систему, и понять, а как ее менять. Где точка наиболее эффективного приложения сил
—
Как-то так! Еще осталось досмотреть несколько занятий из курса "основа" — это 4 больших воркшопа, посвященных общим руководительским навыкам, не привязанным к конкретной роли. Про это будет еще 1 или 2 поста
Пишите в комментах с чем согласны/не согласны, что показалось интересным
Таки осилил основную часть курса "Руководитель отдела", были три занятия про
• Целеполагание и реализацию стратегии
• Найм и развитие ключевых сотрудников
• Системный people-management
Первое занятие
Достаточное лайтовое. Ключевая мысль: есть perfomance goals, есть development goals
• perfomance goals обычно "SMART-уются" и влияют на ближайшее вознаграждение. Пример: увеличить метрику X на Y п.п. до ближайшего perfomance review
• development goals — наоборот: их обычно сложно измерить, и нацелены на развитие на будущее. Пример: улучшить софты
При этом development goals можно достигать по разному. Например, к улучшению софтов можно подходить разными путями: можно бить в публичные выступления, можно бить в решение конфликтов и т.п.
И то, каким путем достигается цель, это и есть стратегия — т.е. некоторый вектор приложения сил
И для декомпозиции таких целей предлагается фреймворк GOSPA (Goals, Objectives, Strategies, Plans, and Activities). Btw, по этому фреймворку бывает удобно описать какие-то личные цели, не касающиеся работы
Второе занятие
В основном дается некоторая база про найм и развитие: портрет кандидата, матрицы компетенций и т.д.
При этом запомнились несколько интересных мыслей
В найме тимлидов очень важно много времени уделять мэтчу с корпоративной культурой. И делать это можно, задавая вопросы не "какие результаты ты получил на прошлой работе?", а "как ты их получил?"
Почему это важно? Один тимлид может выжигать команду, заставлять овертаймить, и таким образом давать результат. Второй может очень мягко идти в долгосрочную мотивацию. И парадоксально — и то, и то может быть как ок, так и не ок в рамках определенной корп культуры
И очень неплохо такое вскрывать помогают проективные вопросы. Это работает так: задается какой-то общий вопрос типа "как думаешь, почему люди обычно увольняются?". И вопрос вроде бы про "всех", но человек скорее всего начнет говорить про себя, через призму своего опыта
Третье занятие
Про системный people-management. Мое любимое, так как немного сдвинуло парадигму мышления
Ключевая мысль: поведение людей — рациональный ответ на структуру системы. И если поведение не нравится, то проблема почти всегда в системе, а не в людях
Как это работает? Во всех компаниях есть вещи, которые явно не прописаны, но которые определяют, как работает система:
• кто по факту принимает решения?
• кто имеет право-вето?
• как на самом деле реагируют на ошибки?
• за что на самом деле поощряют и продвигают?
И каждый руководитель дает своим сотрудникам эти сигналы, зачастую усиливая сигналы руководителя сверху. Пример:
• CTO: проект X нужно выполнить к дд.мм.ГГГГ! Если что то пойдет не так, виноватых найдем и накажем!
• Рук отдела/TL: ошибаться опасно, нужно жестче контролировать разработчиков
• Разработчик: сделаю ровно то, что просят. Жду новую постановку задачи. Если будут делать ровно то, что скажут, то меня не накажут
В итоге из-за сигнала сверху что ошибаться нельзя, получили безынициативных разработчиков
И чтобы менять систему, очень важно уметь замечать такие сигналы. Далее в занятии даются практики, которые помогают раздебажить систему, и понять, а как ее менять. Где точка наиболее эффективного приложения сил
—
Как-то так! Еще осталось досмотреть несколько занятий из курса "основа" — это 4 больших воркшопа, посвященных общим руководительским навыкам, не привязанным к конкретной роли. Про это будет еще 1 или 2 поста
Пишите в комментах с чем согласны/не согласны, что показалось интересным
🔥45👍20🙏4 2💅1
Написал небольшую статейку с примерами про Schema Guided Reasoning — полезный и частоиспользуемый паттерн при разработке агентов
https://telegra.ph/SGR-Schema-Guided-Reasoning-02-21
Приятного чтения!
https://telegra.ph/SGR-Schema-Guided-Reasoning-02-21
Приятного чтения!
Telegraph
SGR (Schema Guided Reasoning)
По умолчанию LLM отдают произвольный текст. Иногда это удобно, но иногда хочется строгий структурированный вывод. Например, в задачах классификации Structured Output Строгий вывод делается благодаря Structured Output 1. Задается JSON-схема ответа
🔥30👍2
AI ускоряет разработчиков. Почему фичи начинают шипаться дольше?
В свете последних событий с массовым использованием ИИ-ассистентов вижу интересную картину:
Объяснить этот феномен может закон Литтла
• WIP — сколько фич одновременно в работе у команды
• Throughput — сколько фич полноценно завершает команда за единицу времени
• Cycle Time — сколько времени занимает полноценно сделать одну фичу
Что происходит с AI
Чтобы полноценно сделать фичу, нужна совместная работа дискавери, дизайна, бэка, фронта, QA
Cursor увеличивает локальную скорость написания кода
И получаем примерно следующую картину:
С WIP разобрались. Но что насчет Throughput? Кажется, что если Cursor ускоряет индивидуальных разработчиков, то должен ускорять и всю команду целиком
Но есть нюансы:
• Если боттлнек — не разработка, то ускорение разработки сделает только хуже для команды в целом
• Из-за роста WIP получаем безумное количество context switching
И в реальности получаем, что эффект от ускорения индивидуальных разработчиков невелируется, и Throughput либо не меняется, либо становится хуже
Если подытожить:
• WIP растет
• Throughput либо не меняется, либо ухудшается
• Согласно закону Литтла Cycle Time сильно вырастает
—
Какое минимальное действие можно сделать, чтобы этого избежать? На мой взгляд — это WIP-лимиты на уровне фичей
Т.е. команда одновременно работает не более чем над N фичами
И если условный бэк сделал все по своей части, он не берет (N + 1)-ую фичу в работу, а вместо этого
• либо идет исправлять техдолг
• либо в идеале идет помогать текущему узкому месту в команде, например QA
Поскольку все основные негативные эффекты с замедлением команды связаны с ростом WIP и переключениями контекста, WIP-лимиты помогут это нивелировать, и обратить ускорение разработки на пользу команды
Пишите ваше мнение в комментариях!
👍 — AI-ассистенты ускоряют работу моей команды
🔥 — замедляют
В свете последних событий с массовым использованием ИИ-ассистентов вижу интересную картину:
Разрабы начинают юзать Cursor →
Код пишется быстрее →
Фичи в проде появляются медленнее
Объяснить этот феномен может закон Литтла
Cycle Time = WIP / Throughput
• WIP — сколько фич одновременно в работе у команды
• Throughput — сколько фич полноценно завершает команда за единицу времени
• Cycle Time — сколько времени занимает полноценно сделать одну фичу
Что происходит с AI
Чтобы полноценно сделать фичу, нужна совместная работа дискавери, дизайна, бэка, фронта, QA
Cursor увеличивает локальную скорость написания кода
И получаем примерно следующую картину:
Бэк быстро сделал свою часть фичи →
Бэк берет следующую фичу →
Очередь перед фронтом и QA растет →
WIP растет
С WIP разобрались. Но что насчет Throughput? Кажется, что если Cursor ускоряет индивидуальных разработчиков, то должен ускорять и всю команду целиком
Но есть нюансы:
• Если боттлнек — не разработка, то ускорение разработки сделает только хуже для команды в целом
• Из-за роста WIP получаем безумное количество context switching
И в реальности получаем, что эффект от ускорения индивидуальных разработчиков невелируется, и Throughput либо не меняется, либо становится хуже
Если подытожить:
• WIP растет
• Throughput либо не меняется, либо ухудшается
• Согласно закону Литтла Cycle Time сильно вырастает
—
Какое минимальное действие можно сделать, чтобы этого избежать? На мой взгляд — это WIP-лимиты на уровне фичей
Т.е. команда одновременно работает не более чем над N фичами
И если условный бэк сделал все по своей части, он не берет (N + 1)-ую фичу в работу, а вместо этого
• либо идет исправлять техдолг
• либо в идеале идет помогать текущему узкому месту в команде, например QA
Поскольку все основные негативные эффекты с замедлением команды связаны с ростом WIP и переключениями контекста, WIP-лимиты помогут это нивелировать, и обратить ускорение разработки на пользу команды
Пишите ваше мнение в комментариях!
👍 — AI-ассистенты ускоряют работу моей команды
🔥 — замедляют
👍102🔥32🤔21💅3
Где может потеряться "exactly-once"
Представим классическую схему — два сервиса интегрированы через брокер:
Хочется обеспечить exactly-once обработку на всей цепочке
Что может пойти не так?
producer → broker
Продюсер записал сообщение в брокер → брокер отправляет ack → сеть сбойнула → продюсер ретраит → в брокере дубликат
Как обычно решается: зачастую общий механизм выглядит так, что каждый продюсер отправляет сообщения с монотонно-возрастающим sequenceNumber (в рамках данного продюсера), а брокер дедуплицирует по (producerId, sequenceNumber). Т.е. если от данного producerId пришло сообщение с sequenceNumber меньшим или равным, чем уже записано, то брокер его дискардит
Конкретная реализация зависит от брокера: например у кафки и нашего яндексового logbroker механизмы чуть разные
broker → consumer → side effect
Консюмер обработал сообщение → не успел закомитить offset → упал → после восстановления обрабатывает то же самое сообщение
Как обычно решается: у каждого сообщения есть уникальный идентификатор + обработка внутри консюмера идемпотентна по уникальному идентификатору сообщения
Например, консюмер может хранить идентификаторы обработанных сообщений в своей БД и выполнять дедупликацию перед применением бизнес-логики (например, через insert ... on conflict do nothing в транзакции с бизнес логикой). Если сообщение уже было обработано, повторная обработка пропускается, и применение сообщения к системе становится идемпотентным
Однако если обработка включает side effect во внешнюю систему, то для сохранения exactly-once внешняя система тоже должна поддерживать идемпотентность
—
Поэтому важно понимать: в большинстве случаев под капотом “exactly-once” — это at-least-once доставка + идемпотентная обработка на каждом стыке. Физически сообщения могут обрабатываться несколько раз, но система спроектирована так, что итоговое состояние меняется ровно один раз
Представим классическую схему — два сервиса интегрированы через брокер:
producer → broker → consumer → side effect
Хочется обеспечить exactly-once обработку на всей цепочке
Что может пойти не так?
producer → broker
Продюсер записал сообщение в брокер → брокер отправляет ack → сеть сбойнула → продюсер ретраит → в брокере дубликат
Как обычно решается: зачастую общий механизм выглядит так, что каждый продюсер отправляет сообщения с монотонно-возрастающим sequenceNumber (в рамках данного продюсера), а брокер дедуплицирует по (producerId, sequenceNumber). Т.е. если от данного producerId пришло сообщение с sequenceNumber меньшим или равным, чем уже записано, то брокер его дискардит
Конкретная реализация зависит от брокера: например у кафки и нашего яндексового logbroker механизмы чуть разные
broker → consumer → side effect
Консюмер обработал сообщение → не успел закомитить offset → упал → после восстановления обрабатывает то же самое сообщение
Как обычно решается: у каждого сообщения есть уникальный идентификатор + обработка внутри консюмера идемпотентна по уникальному идентификатору сообщения
Например, консюмер может хранить идентификаторы обработанных сообщений в своей БД и выполнять дедупликацию перед применением бизнес-логики (например, через insert ... on conflict do nothing в транзакции с бизнес логикой). Если сообщение уже было обработано, повторная обработка пропускается, и применение сообщения к системе становится идемпотентным
Однако если обработка включает side effect во внешнюю систему, то для сохранения exactly-once внешняя система тоже должна поддерживать идемпотентность
—
Поэтому важно понимать: в большинстве случаев под капотом “exactly-once” — это at-least-once доставка + идемпотентная обработка на каждом стыке. Физически сообщения могут обрабатываться несколько раз, но система спроектирована так, что итоговое состояние меняется ровно один раз
👍71🔥18🤔4💅3 3
Почему загрузить разработчиков на 100% — плохая идея
Иногда в управлении командой есть очень соблазнительная мысль — давайте полностью загрузим каждого разраба, и тогда команда будет работать эффективно. На практике это часто дает обратный эффект
Занятость людей ≠ движение работы
Цель команды — протолкнуть фичу до прода. Проталкивание обычно включает в себя разработку → кодревью → тестирование → выкатку на прод
Пример, что происходит, когда все загружены на 100%. Начало спринта:
• Разработчик 1 делает фичу А
• Разработчик 2 делает фичу B
• QA тестирует предыдущую фичу C
Разработка фичи A завершена, требуется ревью. Но разработчик 2 загружен. Чтобы не просиживать, разработчик 1 берет следующую фичу D:
• разработчик 1 делает фичу А (ждет ревью)
• разработчик 1 делает фичу D
• разработчик 2 делает фичу B
• QA тестирует предыдущую фичу C
На следующий день аналогичная ситуация случается со вторым разработчиком. При этом QA до сих пор тестирует фичу С, так как фича оказалась большой и сложной
• разработчик 1 делает фичу А (поревьюено, ждет QA)
• разработчик 1 делает фичу D
• разработчик 2 делает фичу B (ждет ревью)
• разработчик 2 делает фичу E
• QA тестирует предыдущую фичу С
Спустя несколько дней получаем:
• растущую очередь перед кодревью
• растущую очередь перед QA
• кучу незавершенной работы
Незавершенная работа ⇒ раздутый WIP ⇒ огромный Cycle Time ⇒ фичи в проде появляются очень медленно
Ситуация выше описывается Теорией Ограничений — нет смысла усиливать ту часть производства, которая не является узким местом. Потому что это будет приводить к раздуванию очереди перед узким местом, и как следствие, повышению времени цикла
Что с AI?
Может возникнуть мысль что с AI-ассистентами проблема выше неактуальна, так как
• бэкендер может написать немного фронта
• фронт может сам поправить контракт апишки
• разрабы могут сильно помогать QA
Пункты выше действительно ослабляют проблему 100% загрузки, потому что люди становятся более "кросс-функциональными". Но тут есть важный нюанс — AI не отменяет закон очередей. Он просто делает границы между ролями чуть более размытыми
Поэтому очень важно использовать AI правильно — не генерить кучу незавершенки, а помогать разгружать узкое место. Об этом писал в одном из предыдущих постов
—
Пишите в комментах, если сталкивались с желанием загрузить всех на 100%, и что из этого вышло:)
P.S.: те 10% девушек, которые читают этот канал, с праздником вас!
Иногда в управлении командой есть очень соблазнительная мысль — давайте полностью загрузим каждого разраба, и тогда команда будет работать эффективно. На практике это часто дает обратный эффект
Занятость людей ≠ движение работы
Цель команды — протолкнуть фичу до прода. Проталкивание обычно включает в себя разработку → кодревью → тестирование → выкатку на прод
Пример, что происходит, когда все загружены на 100%. Начало спринта:
• Разработчик 1 делает фичу А
• Разработчик 2 делает фичу B
• QA тестирует предыдущую фичу C
Разработка фичи A завершена, требуется ревью. Но разработчик 2 загружен. Чтобы не просиживать, разработчик 1 берет следующую фичу D:
• разработчик 1 делает фичу А (ждет ревью)
• разработчик 1 делает фичу D
• разработчик 2 делает фичу B
• QA тестирует предыдущую фичу C
На следующий день аналогичная ситуация случается со вторым разработчиком. При этом QA до сих пор тестирует фичу С, так как фича оказалась большой и сложной
• разработчик 1 делает фичу А (поревьюено, ждет QA)
• разработчик 1 делает фичу D
• разработчик 2 делает фичу B (ждет ревью)
• разработчик 2 делает фичу E
• QA тестирует предыдущую фичу С
Спустя несколько дней получаем:
• растущую очередь перед кодревью
• растущую очередь перед QA
• кучу незавершенной работы
Незавершенная работа ⇒ раздутый WIP ⇒ огромный Cycle Time ⇒ фичи в проде появляются очень медленно
Ситуация выше описывается Теорией Ограничений — нет смысла усиливать ту часть производства, которая не является узким местом. Потому что это будет приводить к раздуванию очереди перед узким местом, и как следствие, повышению времени цикла
Что с AI?
Может возникнуть мысль что с AI-ассистентами проблема выше неактуальна, так как
• бэкендер может написать немного фронта
• фронт может сам поправить контракт апишки
• разрабы могут сильно помогать QA
Пункты выше действительно ослабляют проблему 100% загрузки, потому что люди становятся более "кросс-функциональными". Но тут есть важный нюанс — AI не отменяет закон очередей. Он просто делает границы между ролями чуть более размытыми
Поэтому очень важно использовать AI правильно — не генерить кучу незавершенки, а помогать разгружать узкое место. Об этом писал в одном из предыдущих постов
—
Пишите в комментах, если сталкивались с желанием загрузить всех на 100%, и что из этого вышло:)
P.S.: те 10% девушек, которые читают этот канал, с праздником вас!
👍49💅18🔥9🙏1 1
random thought
Привычные аргументы насчет гексагоналки/clean arch выглядят так:
+: высокая тестируемость
+: понятная структура проекта
-: много бойлерплейта
-: много абстракций
-: высокий порог входа
Но если вспомнить, что сейчас большинство кода пишется агентами, которым как раз нужна
• высокая тестируемость
• понятная структура проекта
При этом для агентов не проблема
• написать бойлерплейт
• осознать абстракции
мэтч?
Привычные аргументы насчет гексагоналки/clean arch выглядят так:
+: высокая тестируемость
+: понятная структура проекта
-: много бойлерплейта
-: много абстракций
-: высокий порог входа
Но если вспомнить, что сейчас большинство кода пишется агентами, которым как раз нужна
• высокая тестируемость
• понятная структура проекта
При этом для агентов не проблема
• написать бойлерплейт
• осознать абстракции
мэтч?
👍67🤔9💅4😁2
Про Стратоплан и менеджмент (итог)
Я уже как ~месяц назад закончил обучение в Стратоплане на руководителя отдела https://stratoplan-school.com/head/
Обучение весьма удачно совпало с новой зоной ответственностью на работе, поэтому многое удалось попробовать на практике. Если меня попросить топ выводов/мыслей, в которых убедился на собственном опыте, я бы ответил так:
• Не хочешь внезапных разочарований (в т.ч. от себя) — явно проговаривай ожидания
• Регулярное обеспечение прозрачности таки действительно рождает доверие (как и наоборот)
• Эффективность каждого конкретного человека по отдельности ≠ эффективность команды
• Если проблемы со всеми людьми одновременно, то скорее всего проблемы не с людьми)
—
Еще на первом занятии упоминалось, что задача рук-ля отдела — строить систему, и в целом курс действительно направлен на то, чтобы абстрагироваться от решения локальных проблем, и решать их на уровне всей системы
Поэтому я думаю, обучение точно будет полезно:
• тимлидам, у которых начала разрастаться команда, и "уследить за всеми" уже стало как-то нереально
• M2 руководителям, которые не понимают, что происходит
Если у вас только-только появилась команда, то скорее всего будет полезнее тимлидское обучение
Подробности про обучение писал в постах
• раз
• два
• три
• четыре
• пять
Если интересно пообщаться лично и поспрашивать подробности, можно писать в личку, всем отвечу!
Я уже как ~месяц назад закончил обучение в Стратоплане на руководителя отдела https://stratoplan-school.com/head/
Обучение весьма удачно совпало с новой зоной ответственностью на работе, поэтому многое удалось попробовать на практике. Если меня попросить топ выводов/мыслей, в которых убедился на собственном опыте, я бы ответил так:
• Не хочешь внезапных разочарований (в т.ч. от себя) — явно проговаривай ожидания
• Регулярное обеспечение прозрачности таки действительно рождает доверие (как и наоборот)
• Эффективность каждого конкретного человека по отдельности ≠ эффективность команды
• Если проблемы со всеми людьми одновременно, то скорее всего проблемы не с людьми)
—
Еще на первом занятии упоминалось, что задача рук-ля отдела — строить систему, и в целом курс действительно направлен на то, чтобы абстрагироваться от решения локальных проблем, и решать их на уровне всей системы
Поэтому я думаю, обучение точно будет полезно:
• тимлидам, у которых начала разрастаться команда, и "уследить за всеми" уже стало как-то нереально
• M2 руководителям, которые не понимают, что происходит
Если у вас только-только появилась команда, то скорее всего будет полезнее тимлидское обучение
Подробности про обучение писал в постах
• раз
• два
• три
• четыре
• пять
Если интересно пообщаться лично и поспрашивать подробности, можно писать в личку, всем отвечу!
stratoplan-school
Руководитель отдела. Управление подразделениями без компромиссов
Фундаментальная трансформация. Глубокое погружение, формирование управленческого стиля и интеграция AI в каждый процесс.
1🔥33👍24
Какой у вас Cycle Time в команде?
Время от взятия в работу до выкатки в прод типичной продуктовой задачи
Время от взятия в работу до выкатки в прод типичной продуктовой задачи
Anonymous Poll
3%
< 1 дня
12%
1-3 дней
19%
4-6 дней
34%
7-14 дней
32%
14+ дней
yet another random thought
Внезапное место, где хорошо раскрылись принципы функционального программирования — LLM агенты
Агенты в большинстве своем устроены так:
• LLM — функция без сайд эффектов (string -> string)
• Все сайд-эффекты инкапсулированы в тулах
• LLM сама ничего не вызывает. А просто возвращает агенту, какие тулы нужно вызвать
А это и есть реализация паттерна
• functional core (LLM)
• imperative shell (Агент)
И в целом никто не запрещает перенять эти принципы для продакшн кода. Чистая бизнес логика — это супер-простое юнит тестирование и простота поддержки
Внезапное место, где хорошо раскрылись принципы функционального программирования — LLM агенты
Агенты в большинстве своем устроены так:
• LLM — функция без сайд эффектов (string -> string)
• Все сайд-эффекты инкапсулированы в тулах
• LLM сама ничего не вызывает. А просто возвращает агенту, какие тулы нужно вызвать
А это и есть реализация паттерна
• functional core (LLM)
• imperative shell (Агент)
И в целом никто не запрещает перенять эти принципы для продакшн кода. Чистая бизнес логика — это супер-простое юнит тестирование и простота поддержки
💅28👍18✍3 2🙏1
Хотел написать пост не про эйай но получилось как обычно
Обзор на книжечку Agentic design patterns, которая оказалась скачана на телефон во время 8ми часового полета
Несмотря на многословность и не очень прикрытую рекламу гугловых инструментов (книга от инженера из гугла), она дает хорошее понимание, как из ллмки - функции, которая просто предсказывает следующий токен, набором инженерных решений получаются крутые инструменты типа claude code
Рассказываются основные паттерны, которые устоялись за последние пару лет разработки агентских систем
Базовые:
• prompt chaining — пайплайн из вызова ллмок, где результаты передаются по цепочке
• rouing — ллмка решает, куда дальше идти в воркфлоу
• parallelization — кусочки, которые можно распаралеллить, параллелим. Например, сбор данных из разных систем
• reflection — первая ллмка отвечает, вторая оценивает ответ, дает фидбек первой, первая корректирует ответ
• planning — вместо "реши сложную задачу" сначала просим ллмку сформулировать план. Далее выполняем набор более простых задачек
• reasoning techniques — chain-of-thoughts, tree-of-thoughts, ReAct и несколько других
Как достучаться до внешнего мира:
• tool use — обычный тул колинг: ллмке даются спеки тулов, а она отвечает, что и с какими аргументами нужно вызвать для продолжения работы
• mcp — простой небольшой рассказ что это, что такое mcp client, mcp server
• rag — ретривим релевантную информацию из базы знаний перед ответом
Память:
• memory management — про short term memory (на уровне одного чата) и long term memory (глобальная память)
• learning and adaptations — прикольная глава про то, как сделать так, чтобы агент автономно (или полуавтономно) обучался и не повторял тех же ошибок
Как не допустить говна:
• exception handling and recovery — просто глава-напоминание о том, что внешние системы могут лежать/агент можно не справляться с задачей, и это надо как-то уметь обрабатывать
• human in the loop — зовем человека, когда делаем рисковое действие
• guardrails — ллмке как на вход, так и на выход поступает примерно что угодно, поэтому хорошо бы добавлять явные проверки/валидации, что запрос/ответ приемлем
Системы из нескольких агентов:
• multi-agent — есть несколько агентов, заточенных под свои узкие области, которые друг другу дают задачи. Зачастую есть отдельный агент-оркестратор
• A2A — гугловый протокол взаимодействия между агентами в распределенных системах
Всякое разное около самих агентов:
• evaluation and monitoring — какие есть способы мониторить агентов и их качество
Примеров оч много (даже слишком), поэтому читается легко
7/10
Обзор на книжечку Agentic design patterns, которая оказалась скачана на телефон во время 8ми часового полета
Несмотря на многословность и не очень прикрытую рекламу гугловых инструментов (книга от инженера из гугла), она дает хорошее понимание, как из ллмки - функции, которая просто предсказывает следующий токен, набором инженерных решений получаются крутые инструменты типа claude code
Рассказываются основные паттерны, которые устоялись за последние пару лет разработки агентских систем
Базовые:
• prompt chaining — пайплайн из вызова ллмок, где результаты передаются по цепочке
• rouing — ллмка решает, куда дальше идти в воркфлоу
• parallelization — кусочки, которые можно распаралеллить, параллелим. Например, сбор данных из разных систем
• reflection — первая ллмка отвечает, вторая оценивает ответ, дает фидбек первой, первая корректирует ответ
• planning — вместо "реши сложную задачу" сначала просим ллмку сформулировать план. Далее выполняем набор более простых задачек
• reasoning techniques — chain-of-thoughts, tree-of-thoughts, ReAct и несколько других
Как достучаться до внешнего мира:
• tool use — обычный тул колинг: ллмке даются спеки тулов, а она отвечает, что и с какими аргументами нужно вызвать для продолжения работы
• mcp — простой небольшой рассказ что это, что такое mcp client, mcp server
• rag — ретривим релевантную информацию из базы знаний перед ответом
Память:
• memory management — про short term memory (на уровне одного чата) и long term memory (глобальная память)
• learning and adaptations — прикольная глава про то, как сделать так, чтобы агент автономно (или полуавтономно) обучался и не повторял тех же ошибок
Как не допустить говна:
• exception handling and recovery — просто глава-напоминание о том, что внешние системы могут лежать/агент можно не справляться с задачей, и это надо как-то уметь обрабатывать
• human in the loop — зовем человека, когда делаем рисковое действие
• guardrails — ллмке как на вход, так и на выход поступает примерно что угодно, поэтому хорошо бы добавлять явные проверки/валидации, что запрос/ответ приемлем
Системы из нескольких агентов:
• multi-agent — есть несколько агентов, заточенных под свои узкие области, которые друг другу дают задачи. Зачастую есть отдельный агент-оркестратор
• A2A — гугловый протокол взаимодействия между агентами в распределенных системах
Всякое разное около самих агентов:
• evaluation and monitoring — какие есть способы мониторить агентов и их качество
Примеров оч много (даже слишком), поэтому читается легко
7/10
🔥36😁3👍2💅2
Хочешь долгого выполнения задач — нагрузи всех подзавязку
В теории массового обслуживания есть очень простая и удобная модель M/M/1:
Есть бесконечный поток задач, один узел обслуживания и очередь перед ним
Где:
• поток задач описывается Пуассоновским процессом
• время обслуживания описывается экспоненциальным распределением
Интересно вот что: если взять
• λ — скорость прихода задач
• μ — скорость обработки
• ρ = λ / μ — утилизация
• W — среднее время в системе
То получается, что
• W = 1 / (μ - λ)
(proof)
И если переписать через утилизацию:
• W = 1 / μ(1 - ρ)
То есть среднее время нахождения задачи в системе растет гиперболически относительно утилизации. Возьмем простой пример: μ = 1 задача / день
И по формуле выше получаем такое среднее время нахождения задачи в системе W:
Такое происходит из-за того, что задачи поступают в систему неравномерно. Поэтому если обработчик загружен под 100%, то любая неравномерность приводит к скоплению очереди, и как следствие, взрыву времени ожидания
Например, при переходе 95% -> 99% утилизация выросла всего на 4п.п., при этом среднее время ожидания скакнуло с 20 дней до 100 дней
На произвольные распределения этот эффект обобщается формулой Кингмана
—
Какой из этого можно сделать практичный вывод? Не хочешь внезапных задержек — оставляй исполнителям задач некоторый запас капасити
Например, разработчик загружен на 100%, он сидит, работает себе, а потом ему прилетают 3 пулреквеста на ревью. И 3 задачи встанут, потому что у разработчика нет капасити на то, чтобы их поревьюить. Ну и в такой ситуации обычно начинают браться в работу новые задачи, начинает раздуваться WIP, и проявляться прочие спецэффекты, описанные в этом посте
В теории массового обслуживания есть очень простая и удобная модель M/M/1:
Есть бесконечный поток задач, один узел обслуживания и очередь перед ним
поток задач -> очередь -> узел обслуживания
Где:
• поток задач описывается Пуассоновским процессом
• время обслуживания описывается экспоненциальным распределением
Интересно вот что: если взять
• λ — скорость прихода задач
• μ — скорость обработки
• ρ = λ / μ — утилизация
• W — среднее время в системе
То получается, что
• W = 1 / (μ - λ)
(proof)
И если переписать через утилизацию:
• W = 1 / μ(1 - ρ)
То есть среднее время нахождения задачи в системе растет гиперболически относительно утилизации. Возьмем простой пример: μ = 1 задача / день
И по формуле выше получаем такое среднее время нахождения задачи в системе W:
50% utilization -> 2 дня
80% utilization -> 5 дней
90% utilization -> 10 дней
95% utilization -> 20 дней
99% utilization -> 100 дней
Такое происходит из-за того, что задачи поступают в систему неравномерно. Поэтому если обработчик загружен под 100%, то любая неравномерность приводит к скоплению очереди, и как следствие, взрыву времени ожидания
Например, при переходе 95% -> 99% утилизация выросла всего на 4п.п., при этом среднее время ожидания скакнуло с 20 дней до 100 дней
На произвольные распределения этот эффект обобщается формулой Кингмана
—
Какой из этого можно сделать практичный вывод? Не хочешь внезапных задержек — оставляй исполнителям задач некоторый запас капасити
Например, разработчик загружен на 100%, он сидит, работает себе, а потом ему прилетают 3 пулреквеста на ревью. И 3 задачи встанут, потому что у разработчика нет капасити на то, чтобы их поревьюить. Ну и в такой ситуации обычно начинают браться в работу новые задачи, начинает раздуваться WIP, и проявляться прочие спецэффекты, описанные в этом посте
👍59😁3🤔2
Как сделать карьерный рост чуть приятнее
Чем выше роль, тем меньше работа про сами задачи и тем больше — про людей. Всегда кто-то что-то требует, кто-то не согласен, кто-то аккуратно тянет одеяло на себя. Кто-то заходит в разговор так, что выходишь после него с ощущением, будто из тебя высосали всю энергию
Но, на самом деле, в таких сложных разговорах у разных людей одни и те же паттерны — тебя уводят от сути разговора, тебя пытаются ставить в оправдывающуюся позицию, разговор о предмете обсуждения подменяется разговором о личности и так далее
Нормально это осознать помог курс от ребят из SSL, который я проходил аж в 2024 (и до сих пор считаю одним из лучших вложений)
Один из тренеров курса — Миша Ромашов, который параллельно преподает переговоры в ВШЭ и лидит одно из направлений в Сбере. Миша ведет свой тг канал, где рассказывает интересные кейсы из практики:
• Про эмоции
• Про чужую картину мира
• Про конфликты без права сепарации
Если у вас в работе много сложных коммуникаций — рекомендую
Чем выше роль, тем меньше работа про сами задачи и тем больше — про людей. Всегда кто-то что-то требует, кто-то не согласен, кто-то аккуратно тянет одеяло на себя. Кто-то заходит в разговор так, что выходишь после него с ощущением, будто из тебя высосали всю энергию
Но, на самом деле, в таких сложных разговорах у разных людей одни и те же паттерны — тебя уводят от сути разговора, тебя пытаются ставить в оправдывающуюся позицию, разговор о предмете обсуждения подменяется разговором о личности и так далее
Нормально это осознать помог курс от ребят из SSL, который я проходил аж в 2024 (и до сих пор считаю одним из лучших вложений)
Один из тренеров курса — Миша Ромашов, который параллельно преподает переговоры в ВШЭ и лидит одно из направлений в Сбере. Миша ведет свой тг канал, где рассказывает интересные кейсы из практики:
• Про эмоции
• Про чужую картину мира
• Про конфликты без права сепарации
Если у вас в работе много сложных коммуникаций — рекомендую
Telegram
Осознанные коммуникации | Ромашов Михаил
Канал про осознанную коммуникацию от тренера по переговорам Soft Skills Lab, преподавателя НИУ ВШЭ и Сколково на программе MOOVE.
👉🏻 По вопросам: @Mikhail_Romashov
👉🏻 Клуб по переговорам: @sslpractice
👉🏻 По вопросам: @Mikhail_Romashov
👉🏻 Клуб по переговорам: @sslpractice
💅9😁5👍2
Разработка фичей без достаточной экспертизы в системе зачастую превращается в набор "локально-оптимальных" решений: здесь добавили ифчик, здесь протянули новую зависимость, здесь скопипастили похожий код, здесь обошли существующую точку расширения
Каждое такое решение обычно выглядит норм в моменте — оно закрывает задачу, проходит тесты, не выглядит совсем плохо на ревью
Проблема начинается, когда такие решения последовательно наслаиваются друг на друга. Это приводит к architecture drift: фактическая архитектура системы постепенно отклоняется от той, которая была задумана
С агентской разработкой принципы те же — если у агента нет достаточного контекста о системе, он будет стараться делать минимальные локальные изменения, которые приведут к решению задачи. Только с агентами это все происходит быстрее
Главная проблема в том, что самая полезная архитектурная экспертиза обычно живет не в документации, а в головах людей, которые годами работали с системой. Они держат огромный набор фактов о том, почему сделано так, как это развивать, как точно делать не надо и т.д.
И честно говоря, я пока не видел чтобы такая экспертиза была в достаточной степени оцифрована — всегда остается много вещей, которые живут только в чьей-то голове. В таком сетапе агенты всегда будут медленно тянуть архитектуру куда-то в сторону (зачастую не самую хорошую)
А как вы боретесь с этим явлением?
Каждое такое решение обычно выглядит норм в моменте — оно закрывает задачу, проходит тесты, не выглядит совсем плохо на ревью
Проблема начинается, когда такие решения последовательно наслаиваются друг на друга. Это приводит к architecture drift: фактическая архитектура системы постепенно отклоняется от той, которая была задумана
С агентской разработкой принципы те же — если у агента нет достаточного контекста о системе, он будет стараться делать минимальные локальные изменения, которые приведут к решению задачи. Только с агентами это все происходит быстрее
Главная проблема в том, что самая полезная архитектурная экспертиза обычно живет не в документации, а в головах людей, которые годами работали с системой. Они держат огромный набор фактов о том, почему сделано так, как это развивать, как точно делать не надо и т.д.
И честно говоря, я пока не видел чтобы такая экспертиза была в достаточной степени оцифрована — всегда остается много вещей, которые живут только в чьей-то голове. В таком сетапе агенты всегда будут медленно тянуть архитектуру куда-то в сторону (зачастую не самую хорошую)
А как вы боретесь с этим явлением?
👍36💅2
Очень грубо инженеров можно классифицировать на два типа:
1. Те, кто работает с техническими проблемами проактивно:
• Увидел плавное повышение cpu usage на БД => раздебажил из-за чего, добавил нужных индексов, предотвратил инцидент
• Увидел, что новая функциональность в модуль добавляется очень странным образом => инициировал и довел до конца рефакторинг, благодаря этому крупный проект сошелся в срок
• Сделал удобные алерты, что позволило видеть проблему раньше пользователей и предотвращать инциденты
2. Те, кто работает с техническими проблемами реактивно:
• TTM фичей вырос в два раза, постоянные баги => только тогда начинаем рефакторинг
• Количество инцидентов стало совсем неприемлемым => только тогда инициируем проект по стабилизации
(да, не существует чистых типов 1 и 2, это всегда спектр, и всегда нужно уметь работать в обоих режимах)
Но в чем неприятный парадокс — признание за технический вклад в основном получают люди, работающие во втором режиме
Почему так происходит? Потому что для наблюдателей есть прозрачная логическая цепочка: что-то сломалось, конкретный человек это починил, он молодец
Если же чинить проблемы проактивно, то со стороны может показаться, мол ничего особенного, все так и должно работать — фичи делаются быстро, система работает стабильно
Поэтому очень важно для всех опрозрачивать эту логическую цепочку: "что бы произошло, если бы мы не сделали эту техническую доработку". Да, это сложно. Но оно того стоит
Хороший руководитель безумно ценит людей, которые самостоятельно предупреждают проблемы. И задача руководителя — помочь опрозрачить такой вклад сотрудника для остальных
1. Те, кто работает с техническими проблемами проактивно:
• Увидел плавное повышение cpu usage на БД => раздебажил из-за чего, добавил нужных индексов, предотвратил инцидент
• Увидел, что новая функциональность в модуль добавляется очень странным образом => инициировал и довел до конца рефакторинг, благодаря этому крупный проект сошелся в срок
• Сделал удобные алерты, что позволило видеть проблему раньше пользователей и предотвращать инциденты
2. Те, кто работает с техническими проблемами реактивно:
• TTM фичей вырос в два раза, постоянные баги => только тогда начинаем рефакторинг
• Количество инцидентов стало совсем неприемлемым => только тогда инициируем проект по стабилизации
(да, не существует чистых типов 1 и 2, это всегда спектр, и всегда нужно уметь работать в обоих режимах)
Но в чем неприятный парадокс — признание за технический вклад в основном получают люди, работающие во втором режиме
Почему так происходит? Потому что для наблюдателей есть прозрачная логическая цепочка: что-то сломалось, конкретный человек это починил, он молодец
Если же чинить проблемы проактивно, то со стороны может показаться, мол ничего особенного, все так и должно работать — фичи делаются быстро, система работает стабильно
Поэтому очень важно для всех опрозрачивать эту логическую цепочку: "что бы произошло, если бы мы не сделали эту техническую доработку". Да, это сложно. Но оно того стоит
Хороший руководитель безумно ценит людей, которые самостоятельно предупреждают проблемы. И задача руководителя — помочь опрозрачить такой вклад сотрудника для остальных
👍81🔥12🤔5