Pull to refresh
-1
11.7
Евгений Мышкин@myshkin_does_it

Python-энтузиаст

Send message

Не надо делать по красоте. Надо делать MVP.

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

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

MVP-подход тут мне стал очень помогать на моем, локальном уровне. Суть очень простая: делаю минимум и быстро. А потом добавляю на кости мяса. Надо сделать сохранение строк файла в БД? Пока сделаю построчно и поставлю # TODO. Потом сделаю батчем. Нужна отправка сотен объектов из БД в API? Пока тоже построчно. Нужна еще одна очередь Redis для этапа в обработке файла — потом. Пока и с одной очередью и воркером справимся.

MVP-подход требует некоей выдержки, особенно на пет-проектах. Код пишешь ты сам с собой. Выступаешь внутренним критиком и, зачастую, самым строгим. Но делать все дешево и сердито стало помогать мне лично держать фокус на цели: дать максимум ценности за минимум усилий. И при этом не сгореть от объема, быть в тонусе.

Риски, конечно тоже есть. У TODO нет хозяев, кроме нас. Дешевое Г становится иногда продом. Техдолг это вообще бесконечная тема и, пожалуй, не для этого поста. Пост про эффективность.

MVP-промтинг работает и с нейронками таким же образом. Берем чистый контекст, делаем простой прототип. А дальше по кускам его обтесываем, заменяем, улучшаем. Может, у нас есть с ними что-то общее?

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

Tags:
+10
Comments7

Не пользуюсь LLM-агентами, если могу. Давно замечаю: просто избегаю запускать LLM прямо в проекте, потому что боюсь разучиться кодить и думать. Поход в ChatGPT себе разрешаю — это как встать с дивана, чтобы пойти в магазин, а не заказывать доставку на дом. Там нужно правильно сформулировать запрос, потому что он не может добрать контекст проекта сам. Можно перекинуться парой мыслей, как с товарищем на работе. Надо подумать, как применить ответ, что выкинуть. В итоге я всё равно как-то худо-бедно программирую сам.

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

Чем больше у нейронки пузырь вашего контекста, тем хуже она работает. Путается в постоянно пополняющихся правилах, корректировках и ограничениях. Наконец, контекстный оверхед — это еще очень дорого. Каждый запрос к API содержит тысячи «мусорных» токенов и выжирать лимиты получается еще быстрее.

В ответ на это индустрия на венчурные деньги придумывает и продвигает свои «велосипеды», чтобы с помощью агентов эффективнее и дешевле решать задачи:

  • В Cursor IDE есть Rules, которые накладывают ограничения поверх ваших промптов. Их можно применять вручную или автоматически; говорят, автомат работает хуже.

  • Anthropic пиарит Skills (еще пример Playwright Skill). Это интерфейс для решения типовых задач с адаптивными ступенями контекста в зависимости от сложности.

  • Есть MCP (Model Context Protocol) — условное API, которое расширяет возможности агентов, чтобы они не писали собственные инструменты и не тратили контекст и токены на типовые задачи: открыть браузер, прочитать Jira, отправить письмо и т. д.

  • Также есть субагенты; их оркестрирует агент-оркестратор. У субагентов чистый контекст: они получают задачу, выполняют её и идут на «свалку».

И вот среди этого новояза я – старпер со своим ChatGPT: после 2–3 запросов удаляю чат и начинаю новый. Вот моя экономика токенов и галлюцинаций. Меня и Альтмана маркетингом не проведешь!

Tags:
+4
Comments9

Про воркеры простыми словами

На работе мне понадобилось реализовать воркер. Описываю, как сам эту тему разобрал.

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

Пример
Сборщик мусора в БД: пройтись раз в час, например, и удалить старые записи. Или, как у меня задача на работе: обработать xlsx-файл, который передали в ручку.

Зачем
Чтобы сделать работу приложения асинхронной. Представим задачу, которую можно обработать дольше, чем за 10 секунд. Клиент на вашем сайте не будет сидеть и смотреть в экран эти 10 секунд. Он перезагрузит страницу, сессия прервётся, и задача не выполнится. Или веб-сервер вернёт клиенту таймаут. В описанном сценарии обработка запроса — синхронная процедура. Она плохо подходит для быстрых веб-сервисов. А вот асинхронная обработка: кинули запрос, получили ответ 200 OK и пошли чилить, пока задача исполняется — это то, что нужно. Воркер как раз для этого.

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

Триггеры
Триггерами для воркера могут быть:

  • крон

  • таймер

  • событие

Очереди
Воркеры по событию обычно подписаны на очередь. В моём случае это как раз Redis Queue (библиотека rq, например https://python-rq.org/ ). Запрос в ручку получает 200 OK. Мой сервис создаёт запись в БД типа «задача id такой-то, статус processing» и публикует событие в очереди. Воркер забирает событие, чтобы другие воркеры не могли задачу задублировать, и пробует выполнить свой коллбэк. Если всё ок, воркер пишет в БД данные по выполненной задаче и подтверждает в очереди прочтение события. Иначе воркер может ретраить, может завалить задачу и вернуть её в очередь, а может и сам упасть.

Воркер-пул
Воркеров может быть несколько. Они могут выполнять как несколько разных задач, так и одну вместе. Увеличение числа воркеров требует оркестрации и иногда для этого также выделяет контейнер с оркестратором. Воркеры могут передавать задачи друг другу. Могут конкурировать за задачи, если очередь организовать неправильно. А могут вообще читать разные потоки и быть никак не связаны друг с другом.

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

Образ
Воркер собирается из того же образа, что и ваше приложение, но у него отдельный энтри-поинт. Вместо запуска через main.py у, например, worker.py, есть строчка вида:

def main():

    ... # Какая-то логика по инициализации воркера и очереди

if name == '__main__': 

    main() # Если запускают этот модуль напрямую, выполни команду main()

Из-за этого кода модуль можно вызвать напрямую python -m app.worker. В main(), как правило, скрыта логика какого-то while-true цикла и шатдауна на случай завершения работы воркера.

Tags:
+1
Comments2

Information

Rating
567-th
Location
Москва, Москва и Московская обл., Россия
Registered
Activity

Specialization

Инженер по автоматизации тестирования, Инженер по ручному тестированию
Ведущий
From 400,000 ₽
Python
Git
Docker