Forwarded from Nikolay
Амазон
1)https://www.amazon.jobs/en/principles
2)https://medium.com/@scarletinked/are-you-the-leader-were-looking-for-interviewing-at-amazon-8301d787815d 3)https://docs.google.com/spreadsheets/d/1oBA6vanArm8gh79vzUnyJL-1kriLiGznYKh8gXAfD4s/edit?usp=drivesdk 4)https://www.notion.so/BE-Interview-8adc74cf14ad450fab3083e0633d2821#7b7c9b724012423f9572ef0787536c6e тут собираем вопросы https://docs.google.com/document/d/10mS6Whiybl3VjO9t3ZbMhp9TinNWBIArQoqmTaoSfqs/edit?usp=sharing 5) https://www2.hws.edu/pdf/career/behavioral_interview_questions.pdf
1)https://www.amazon.jobs/en/principles
2)https://medium.com/@scarletinked/are-you-the-leader-were-looking-for-interviewing-at-amazon-8301d787815d 3)https://docs.google.com/spreadsheets/d/1oBA6vanArm8gh79vzUnyJL-1kriLiGznYKh8gXAfD4s/edit?usp=drivesdk 4)https://www.notion.so/BE-Interview-8adc74cf14ad450fab3083e0633d2821#7b7c9b724012423f9572ef0787536c6e тут собираем вопросы https://docs.google.com/document/d/10mS6Whiybl3VjO9t3ZbMhp9TinNWBIArQoqmTaoSfqs/edit?usp=sharing 5) https://www2.hws.edu/pdf/career/behavioral_interview_questions.pdf
amazon.jobs
Leadership Principles
We use our Leadership Principles every day, whether we’re discussing ideas for new projects or deciding on the best way to solve a problem. It’s just one of the things that makes Amazon peculiar.
Forwarded from DziS Science | Data Science
Привет всем!👋
Сегодня поговорим про небольшую оптимизацию кода по памяти.
Известный факт, что неизменяемые структуры, которые имеют фиксированные размеры, имеют некоторые преимущества в сравнении с изменяемыми.
В рамках проектов, где часто вызываются миллионы мелких объектов (например, узлы в графе, события в симуляции, кастомные токены) проблема утечки памяти встает очень остро. Отчасти, это касается и атрибутов объектов.
По умолчанию🐍 хранит атрибуты объектов в словаре, включенном в метод
Для решения проблемы предлагается использовать метод
Он отключает создание
Рассмотрим на примере:
🔸 Определим классический класс
🔸 Теперь определим объекты классов
- Какие разницы в этих объектах?
🔵 В
Пример:
Причина такого поведения лежит именно в формировании класса с использованием
🔵 В obj2 нет словаря атрибутов
Проверить это просто:
Вывод следующий (до добавления атрибута):
Таким образом, если мы имеет часто используемый класс и нам не нужна свобода в изменении состава атрибутов, то правильнее использовать конструкцию со
Ставь 🔥, если не знал.
Ставь👍, если знал.
#ds_лайфхаки
Сегодня поговорим про небольшую оптимизацию кода по памяти.
Известный факт, что неизменяемые структуры, которые имеют фиксированные размеры, имеют некоторые преимущества в сравнении с изменяемыми.
В рамках проектов, где часто вызываются миллионы мелких объектов (например, узлы в графе, события в симуляции, кастомные токены) проблема утечки памяти встает очень остро. Отчасти, это касается и атрибутов объектов.
По умолчанию
__dict__ (появился он в языке 8 февраля 2012 года), который, как и обычный словарь имеет динамическое выделение памяти и может быть расширяем, что при всех своих плюсах создает большую нагрузку на память. Для решения проблемы предлагается использовать метод
__slots__. Он отключает создание
__dict__ и резервирует память только под конкретные атрибуты, что помогает оптимизировать код по памяти, но жестко фиксирует набор атрибутов объекта, что является одновременно и плюсом и минусом. Рассмотрим на примере:
CoordinatesDict`и класс `CoordinatesSlots с использованием __slots__import sys
class CoordinatesDict:
def __init__(self, x, y,z):
self.x = x
self.y = y
self.z = z
class CoordinatesSlots:
__slots__ = ['x', 'y', 'z'] # Фиксируем атрибуты
def __init__(self, x, y, z):
self.x = x
self.y = y
self.z = z
obj1 и obj2:obj1 = CoordinatesDict(1, 2, 3)
obj2 = CoordinatesSlots(1, 2, 3)
- Какие разницы в этих объектах?
obj1 можно дополнительно объявить новый атрибут, скажем, dist и присвоить ему значение, он пополнит ряды __dict__. В obj2 аналогичная операция вернет AttributeErrorПример:
obj1.dist = 2
obj1.__dict__
>>>{'x': 1, 'y': 2, 'z': 3, 'dist': 2}obj2.dist = 2
>>>AttributeError: 'CoordinatesSlots' object has no attribute 'dist'
Причина такого поведения лежит именно в формировании класса с использованием
__slots__. Такой класс, как говорилось ранее, хранит атрибуты в массиве фиксированной размерности, отключая возможность работы со словарем атрибутов (то есть у вас не появляется __dict__), а все атрибуты, не записанные в массив, поднимают ошибку. __dict__, а следовательно на него не требуется память.Проверить это просто:
print(sys.getsizeof(obj1), sys.getsizeof(obj1.__dict__))
print(sys.getsizeof(obj2))
print(sys.getsizeof(obj2.__dict__))
Вывод следующий (до добавления атрибута):
48 272
56
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
/tmp/ipython-input-390784945.py in <cell line: 0>()
18 print(sys.getsizeof(p1), sys.getsizeof(p1.__dict__))
19 print(sys.getsizeof(p2))
---> 20 print(sys.getsizeof(p2.__dict__))
AttributeError: 'CoordinatesSlots' object has no attribute '__dict__'
Таким образом, если мы имеет часто используемый класс и нам не нужна свобода в изменении состава атрибутов, то правильнее использовать конструкцию со
__slots__Ставь 🔥, если не знал.
Ставь👍, если знал.
#ds_лайфхаки
Please open Telegram to view this post
VIEW IN TELEGRAM
Forwarded from Тимлид Очевидность | Евгений Антонов
Контекст тимлида
Недавно записывал один подкаст, где одним из вопросов мы затронули контекст тимлида.
Это полезно понимать как для текущего тимлида в разрезе его нагрузки в настоящий момент, так и для тимлида, который приходит в новую команду/компанию, в разрезе того, что ему необходимо добрать, чтобы нормально работать.
Члены команды
Все люди разные и имеют свои особенности, мотивацию, текущие цели, особенности характера, темперамента, разные жизненные ценности, разные жизненные ситуации. На это накладывается, как они взаимодействуют между собой. Этот комбинаторный взрыв нужно знать и следить за ним регулярно, ибо, как говорил Гераклит, «всё течёт, всё меняется».
Рабочие процессы
Понятное дело, тут про всякую организационную и операционную деятельность, которая сейчас в команде присутствует, НО…
Есть еще исторический контекст того, что уже пробовали, что работало хорошо, а что плохо и почему.
Есть еще процессный долг, когда что-то сейчас как-то работает не лучшим образом и/или на ручной тяге, а надо бы это улучшить, но пока не было времени точить пилу, ведь дедлайн скоро и надо пилить.
Проекты и продукты
В вотчине тимлида есть набор проектов и продуктов. Это можно разбить на две части:
- Менеджерская. Проектный менеджмент, планирование, контроль, сроки, дедлайны, риски, KPI, OKR, договоренности с заказчиками и смежниками, ценность самих продуктов.
- Техническая. Само устройство, архитектура, технический долг.
Стратегия
Сейчас как-то всё работает, а как и для чего оно всё будет работать в будущем? Тут тоже 2 стула:
- Менеджерский. Басфактор, подготовка преемника, обучение и развитие команды. Цели и ценность самой команды и как она должна выглядеть в будущем.
- Технический. Технологическая стратегия тоже важна. Не просто «нам нальют х2 пользователей, мы железом ливанем, да и всё».
Наём
Кто-то из команды уходит, или открываются новые вакансии (про которые надо вообще понять, зачем они нужны, сформулировать портрет кандидата и дальше отбором заниматься), надо кого-то прособеседовать, или надо кого-то удержать, или надо, наоборот, кого-то уволить. Всё это тоже в контексте тимлида загружено.
Руководство
Надо хорошо понимать своё руководство: его ожидание, его личность, его особенности работы, то, как и когда по каким вопросам репортить, как просить помощи, как и когда спорить, как не спорить и вот это вот всё.
Политика
Есть хорошая картинка про то, как НА САМОМ ДЕЛЕ выглядит оргструктура https://ic.pics.livejournal.com/talent_a/45400893/2597/2597_original.jpg, и вот понимание этого контекста тоже очень важно. Всегда у людей есть куча неформальных историй, амбиций, притязаний, фаворитизма, протекции, обид, претензий и т. д. При непонимании этих негласных связей можно наступить на невидимые грабли, которых на официальной карте местности не должно быть.
Итог
У тимлида чертова гора контекста, которые ему нужно знать, держать в голове, в планах и регулярно использовать.
Поэтому я всегда диву даюсь, когда слышу «да у него там 2-3 человека, это ж на полдня в неделю менеджерской работы».
Или когда приходит новый тимлид, и от него сразу ждут такой же объем выполнения планов, как от прошлого, в которого этот контекст уже был вгружен и у которого все социальные связи установлены.
Недавно записывал один подкаст, где одним из вопросов мы затронули контекст тимлида.
Это полезно понимать как для текущего тимлида в разрезе его нагрузки в настоящий момент, так и для тимлида, который приходит в новую команду/компанию, в разрезе того, что ему необходимо добрать, чтобы нормально работать.
Члены команды
Все люди разные и имеют свои особенности, мотивацию, текущие цели, особенности характера, темперамента, разные жизненные ценности, разные жизненные ситуации. На это накладывается, как они взаимодействуют между собой. Этот комбинаторный взрыв нужно знать и следить за ним регулярно, ибо, как говорил Гераклит, «всё течёт, всё меняется».
Рабочие процессы
Понятное дело, тут про всякую организационную и операционную деятельность, которая сейчас в команде присутствует, НО…
Есть еще исторический контекст того, что уже пробовали, что работало хорошо, а что плохо и почему.
Есть еще процессный долг, когда что-то сейчас как-то работает не лучшим образом и/или на ручной тяге, а надо бы это улучшить, но пока не было времени точить пилу, ведь дедлайн скоро и надо пилить.
Проекты и продукты
В вотчине тимлида есть набор проектов и продуктов. Это можно разбить на две части:
- Менеджерская. Проектный менеджмент, планирование, контроль, сроки, дедлайны, риски, KPI, OKR, договоренности с заказчиками и смежниками, ценность самих продуктов.
- Техническая. Само устройство, архитектура, технический долг.
Стратегия
Сейчас как-то всё работает, а как и для чего оно всё будет работать в будущем? Тут тоже 2 стула:
- Менеджерский. Басфактор, подготовка преемника, обучение и развитие команды. Цели и ценность самой команды и как она должна выглядеть в будущем.
- Технический. Технологическая стратегия тоже важна. Не просто «нам нальют х2 пользователей, мы железом ливанем, да и всё».
Наём
Кто-то из команды уходит, или открываются новые вакансии (про которые надо вообще понять, зачем они нужны, сформулировать портрет кандидата и дальше отбором заниматься), надо кого-то прособеседовать, или надо кого-то удержать, или надо, наоборот, кого-то уволить. Всё это тоже в контексте тимлида загружено.
Руководство
Надо хорошо понимать своё руководство: его ожидание, его личность, его особенности работы, то, как и когда по каким вопросам репортить, как просить помощи, как и когда спорить, как не спорить и вот это вот всё.
Политика
Есть хорошая картинка про то, как НА САМОМ ДЕЛЕ выглядит оргструктура https://ic.pics.livejournal.com/talent_a/45400893/2597/2597_original.jpg, и вот понимание этого контекста тоже очень важно. Всегда у людей есть куча неформальных историй, амбиций, притязаний, фаворитизма, протекции, обид, претензий и т. д. При непонимании этих негласных связей можно наступить на невидимые грабли, которых на официальной карте местности не должно быть.
Итог
У тимлида чертова гора контекста, которые ему нужно знать, держать в голове, в планах и регулярно использовать.
Поэтому я всегда диву даюсь, когда слышу «да у него там 2-3 человека, это ж на полдня в неделю менеджерской работы».
Или когда приходит новый тимлид, и от него сразу ждут такой же объем выполнения планов, как от прошлого, в которого этот контекст уже был вгружен и у которого все социальные связи установлены.
Forwarded from Остриков пилит агентов
Важные секции, которые должны быть в наших PRD
Плиз проверьте, что эти блоки точно есть, и давайте их располагать в след структуре, чтобы было проще читать:
1. Назначение сервиса
Формат: один абзац, который коротко описывает суть и назначение сервиса, какую задачу он решает на большом ландшафте всей системы.
Planner - отвечает за заведение и запуск новых кампаний для взаимодействия с пользователями через агентов. Отбирает пользователей по сегментам и запускает по ним кампании
2. Глоссарий основных сущностей сервиса
Формат: набор пар термин - описание. Нужно, чтобы всем говорить на одном языке дальше по документу.
Task - задача для агента на общение с пользователем с конкретной целью. Агент должен ее стартануть в определенное время, и довести до завершения
Session - сессия разговора агент-пользователь, начинается с сообщения агента и заканчивается спустя последнее сообщение человека/агента через 2 часа
3. Как внешний мир видит этот компонент
И на каком языке с ним общается. Тут детально расписывается вся внешняя апишка сервиса и другие входящие потоки данных.
4. Модель БД сервиса
Детальное описание всех таблиц, полей, смысла полей, foreign keys constraints и индексов. Пишем все - nullable/not null/default итд. Самая важная секция, max attention - самая дорогая цена ошибки
5. Sequence flow всех основных процессов
По всем процессам есть расписанная по шагам последовательность действий, которые происходят в сервисе, в четкой структуре
6. Внешние сервисы, в которые мы ходим изнутри сервиса
Все внешние системы, в которых мы дергаем ручки/отправляем файлы/пишем в чужие очереди итд.
Главное отличие от пункта 3 - в нем наш сервис как черный ящик, и мы описываем как внешний мир его видит и использует. Тут - наоборот.
- хранилище офферов - забираем оффер в json описании при заведении новой кампании
7. Мониторинги, за которыми мы будем следить и которые будут нам звонить если что-то идет не так
Пишем только криты, которые если происходят, мы в любое время дня и ночи сразу собираем звонок и решаем инцидент
- в табличке messages скопилось больше 500 сообщений от пользователей в статусе NEW, которые мы не разгребаем более 10 минут (то есть процессинг упал)
Зачем такая духота?
Важно, чтобы до программирования (передачи PRD в клод код) мы детально понимали логику будущего сервиса на всех уровнях, без участков "ну тут хуле делать, пусть клод сам затащит"
Второй момент - верю, что при идеально написанном PRD клод будет писать сервис за один промт, а потом потребуется лишь незначительная шлифовка. Если не пишет, будем править claude.md, пока не напишет))
И последнее, ваш PRD может иметь другие доп секции, но убедитесь что текущие присутствуют обязательно и оформлены один в один в том же формате
———
Сидел потел, пробовал оцифровать правила наших PRD для будущих сервисов, без помощи нейронок 🫠
Есть что-то важное, что забыл? За лучший комментарий отправлю Кабанчика бесплатно по России (без шуток)
#prd
Плиз проверьте, что эти блоки точно есть, и давайте их располагать в след структуре, чтобы было проще читать:
1. Назначение сервиса
Формат: один абзац, который коротко описывает суть и назначение сервиса, какую задачу он решает на большом ландшафте всей системы.
Planner - отвечает за заведение и запуск новых кампаний для взаимодействия с пользователями через агентов. Отбирает пользователей по сегментам и запускает по ним кампании
2. Глоссарий основных сущностей сервиса
Формат: набор пар термин - описание. Нужно, чтобы всем говорить на одном языке дальше по документу.
Task - задача для агента на общение с пользователем с конкретной целью. Агент должен ее стартануть в определенное время, и довести до завершения
Session - сессия разговора агент-пользователь, начинается с сообщения агента и заканчивается спустя последнее сообщение человека/агента через 2 часа
3. Как внешний мир видит этот компонент
И на каком языке с ним общается. Тут детально расписывается вся внешняя апишка сервиса и другие входящие потоки данных.
POST /api/v1/offers/create - добавление нового оффера
{"offer_type": "bonus100", "offer_name": "xyz", ...}
PUT /api/v1/campaign/start - ручной запуск компании
{"id": "ieur-er4r4r-4r4"}
4. Модель БД сервиса
Детальное описание всех таблиц, полей, смысла полей, foreign keys constraints и индексов. Пишем все - nullable/not null/default итд. Самая важная секция, max attention - самая дорогая цена ошибки
== tasks (задачи на общение с пользователями) ==
id: bigint - pk
user_uuid: text - index
created_at: timestamp
...
== messages (сообщения чатов) ==
id: bigint - pk
task_id: bigint (fk -> tasks.id) - index
text: text // текст сообщения
role: test // автор сообщения, человек или агент
created_at: timestamp
...
id_task_id - unique constarint
5. Sequence flow всех основных процессов
По всем процессам есть расписанная по шагам последовательность действий, которые происходят в сервисе, в четкой структуре
1. Горутина обработки ответа на сообщение
- подтягиваем прошлую историю переписки из кеша переписок, если кеш пуст, достаем из messages)
- достаем заранее созданные инстанс агента из мапы агентов
- достаем информацию (user context) по пользователю из кеша пользователей (если нет, идем в avalon за данными)
- динамически собираем промт агента, добавляя туда историю, данные пользователя
- запускаем цикл агента, получаем новое сообщение
- сообщение сохраняем в messages + кеш
- отправляем сообщение в whatsup gateway
2. Создание новой кампании
...
6. Внешние сервисы, в которые мы ходим изнутри сервиса
Все внешние системы, в которых мы дергаем ручки/отправляем файлы/пишем в чужие очереди итд.
Главное отличие от пункта 3 - в нем наш сервис как черный ящик, и мы описываем как внешний мир его видит и использует. Тут - наоборот.
- хранилище офферов - забираем оффер в json описании при заведении новой кампании
7. Мониторинги, за которыми мы будем следить и которые будут нам звонить если что-то идет не так
Пишем только криты, которые если происходят, мы в любое время дня и ночи сразу собираем звонок и решаем инцидент
- в табличке messages скопилось больше 500 сообщений от пользователей в статусе NEW, которые мы не разгребаем более 10 минут (то есть процессинг упал)
Зачем такая духота?
Важно, чтобы до программирования (передачи PRD в клод код) мы детально понимали логику будущего сервиса на всех уровнях, без участков "ну тут хуле делать, пусть клод сам затащит"
Второй момент - верю, что при идеально написанном PRD клод будет писать сервис за один промт, а потом потребуется лишь незначительная шлифовка. Если не пишет, будем править claude.md, пока не напишет))
И последнее, ваш PRD может иметь другие доп секции, но убедитесь что текущие присутствуют обязательно и оформлены один в один в том же формате
———
Сидел потел, пробовал оцифровать правила наших PRD для будущих сервисов, без помощи нейронок 🫠
Есть что-то важное, что забыл? За лучший комментарий отправлю Кабанчика бесплатно по России (без шуток)
#prd
Forwarded from SimpleAGI
Собеседование на AI-инженера в банк: три вещи, которые реально проверяют
Собрал в кучу инфу по теме AI-инженера. "Горячая" тема, судя по рилсам)
Типичная вакансия: Python, LLM, RAG, агенты, production. Но на собесе не проверяют знание этих слов. Проверяют три вещи:
1. Trade-off мышление - не "лучший подход", а "лучший для этой ситуации"
2. Production-фокус - как это будет жить, ломаться и стоить денег
3. Язык домена - говоришь ли ты на языке бизнеса, а не только на языке ML
___
1. Trade-off мышление
Нет "лучшего" решения. Есть решение, оптимальное для конкретных ограничений.
Chunking в RAG
Зрелый ответ: "Зависит от типа вопросов. Для фактовых - мельче, для аналитических - крупнее."
Retrieval
В проде почти всегда hybrid - потому что dense пропускает точные совпадения (аббревиатуры, коды), а sparse не понимает семантику.
Агент vs Граф
Для банка граф почти всегда лучше - регулятор любит предсказуемость.
Треугольник оптимизации
- Streaming - реальная latency та же, но UX кардинально лучше
- Кэширование мгновенные ответы, но риск устаревших данных
- Роутинг по сложности простые вопросы на дешёвую модель. 80% запросов обычно простые - экономия существенная
- Reranking - quality +, но latency -
___
2. Production-фокус
Сделать прототип — легко. Поддерживать систему, которая не деградирует - сложно.
Что может пойти не так
Безопасность агентов
Loop guard - мастхэв. Агент может решить, что ему нужно 50 вызовов API на простой вопрос.
Verifier - обязательный компонент
Собрал в кучу инфу по теме AI-инженера. "Горячая" тема, судя по рилсам)
Типичная вакансия: Python, LLM, RAG, агенты, production. Но на собесе не проверяют знание этих слов. Проверяют три вещи:
1. Trade-off мышление - не "лучший подход", а "лучший для этой ситуации"
2. Production-фокус - как это будет жить, ломаться и стоить денег
3. Язык домена - говоришь ли ты на языке бизнеса, а не только на языке ML
___
1. Trade-off мышление
Нет "лучшего" решения. Есть решение, оптимальное для конкретных ограничений.
Chunking в RAG
| Стратегия | Плюс | Минус | Когда выбирать |
|----------------|--------------------|--------------------|--------------------------|
| Мелкие чанки | Точнее поиск | Теряем контекст | Фактовые вопросы |
| Крупные чанки | Больше контекста | Шум в retrieval | Аналитические вопросы |
| Parent-child | И точность, и контекст | Два индекса, сложнее | Когда критично качество |
Зрелый ответ: "Зависит от типа вопросов. Для фактовых - мельче, для аналитических - крупнее."
Retrieval
| Метод | Плюс | Минус |
|------------------|----------------------|------------------------------------------|
| Dense (векторный) | Понимает семантику | Может пропустить exact match |
| Sparse (BM25) | Точный match | "РКО" ≠ "расчётно-кассовое обслуживание" |
| Hybrid | Лучшее из двух | Сложнее настройка |
В проде почти всегда hybrid - потому что dense пропускает точные совпадения (аббревиатуры, коды), а sparse не понимает семантику.
Агент vs Граф
| Подход | Плюс | Минус |
|---------------------|-------------------------------|-------------------------------------------------|
| Свободный агент | Гибкость | Непредсказуемость, дорого, сложно тестировать |
| Граф (state machine) | Воспроизводимость, аудируемость | Нужно продумать все пути заранее |
Для банка граф почти всегда лучше - регулятор любит предсказуемость.
Зрелый ответ: "Сначала смотрю, можно ли графом. Агент - когда реально нужна гибкость, а не красивая архитектура."
Треугольник оптимизации
QUALITY
△
/|\
/ | \
▽──┴──▽
LATENCY COST
- Streaming - реальная latency та же, но UX кардинально лучше
- Кэширование мгновенные ответы, но риск устаревших данных
- Роутинг по сложности простые вопросы на дешёвую модель. 80% запросов обычно простые - экономия существенная
- Reranking - quality +, но latency -
___
2. Production-фокус
Сделать прототип — легко. Поддерживать систему, которая не деградирует - сложно.
Что может пойти не так
| Проблема | Что происходит | Как заметить |
|-------------------|------------------------------------------|--------------------------------------|
| Устаревший индекс | Регламенты обновились, база старая | Рост ответов "информации нет" |
| Изменение модели | Провайдер обновил модель | Скачок метрик после апдейта |
| Падение интеграций | CRM или бэкенд недоступен | Рост таймаутов |
| Смена паттернов | Пользователи спрашивают о новом | Незнакомые вопросы в логах |
Безопасность агентов
| Механизм | Зачем |
|-------------------|--------------------------------------------------|
| Allowlist tools | Только разрешённые инструменты |
| Loop guard | Лимит шагов, времени, стоимости |
| Human-in-the-loop | Подтверждение на чувствительных действиях |
Loop guard - мастхэв. Агент может решить, что ему нужно 50 вызовов API на простой вопрос.
Verifier - обязательный компонент
Generate → Verify → Respond
Forwarded from Остриков пилит агентов
This media is not supported in your browser
VIEW IN TELEGRAM
Кто на стажировку в команду Claude Cowork к Борису Черни?
Только не в Claude Cowork, а в LocalDesk.
И не к Борису, а к Валере @neuraldeep
Если вдруг кто пропустил, Валера Ковальский и куча народа уже 10 дней пилят свой Cowork, который работает на вашем компе на любых моделях.
https://github.com/vakovalskii/LocalDesk
https://t.me/neuraldeep/1858
https://t.me/neuraldeep/1874
Как задрот агентских циклов, давно хотел закопаться, как все устроено, только сегодня с утра дошли руки:
- в каждый запрос к LLM передаётся 15-45 tool definitions в зависимости от настроек - модель видит все доступные инструменты сразу (удачи слабым моделькам на 45 тулах☕️ )
- цикл работает до тех пор, пока в ответе есть tool_calls - если массив пустой, выводим финальный ответ и завершаемся
- ответ читаем в режиме стриминга: текст пушим в UI сразу, но tool_calls накапливаем - аргументы приходят чанками, JSON парсим только после полного ответа
- модель может вернуть несколько tool calls в одном ответе (parallel_tool_calls: true), но выполняем их строго последовательно через for await - параллелизация не реализована💡
- после выполнения каждого tool результат добавляется в массив messages как { role: 'tool', content: output }, на следующей итерации модель видит полный контекст
- контекст растёт монотонно: system prompt + все user messages + все assistant messages + все tool results, truncation и summarization отсутствуют💡
- tool results не обрезаются - если read_file вернул 5000 строк, все 5000 строк попадают в контекст💡
- loop detection: sliding window из 5 последних вызовов, если 5 подряд одинаковых tool names - инжектим hint "Попробуй другой подход", даём 5 retry, потом принудительный стоп
- batch tool calls (2+ инструмента в одном ответе) сбрасывают счётчик loop detection - считаются намеренным поведением модели
- не можем отправить новое сообщение, чтобы дать подсказку агенту в середине цикла, должны отменить выполнение или дожидаться конца💡
Очень круто! Но самое крутое впереди. Многие спрашивают, как вкатиться в разработку агентов, с чего начать. Можно начать с простых примеров на коленке, которые были в этом посте. Но это ни разу не похоже на продакшен, просто мини проектики, пощупать самую основу.
А LocalDesk - похоже.
Смотрите, в тех местах, где стоят💡 можно придти и сделать лучше - оптимизировать расход токенов, увеличить скорость за счет параллельности, сделать компакшен контекста.
Хотите более серьезных приключений - можно сделать субагентов, поддержать MCP, прикрутить донаты в конце концов!
Кстати, именно так и выглядит реальная разработка агентов в проде, на само ядро не тратится много времени, а на управление памятью, оптимизации контекста, детализацию в логах, трассировки - полно. А потом еще начинаются корзинки и evals, и совсем потрачено…
Так что если кто-то хотел "поизучать агентов пару часиков на выхах", вот самый лучший способ.
Еще раз ссылка на GitHub
И чатик, где идет движуха: @neuraldeepchat
———
Пойду тоже запилю что-то, а то Валера здороваться перестанет...
Только не в Claude Cowork, а в LocalDesk.
И не к Борису, а к Валере @neuraldeep
Если вдруг кто пропустил, Валера Ковальский и куча народа уже 10 дней пилят свой Cowork, который работает на вашем компе на любых моделях.
https://github.com/vakovalskii/LocalDesk
https://t.me/neuraldeep/1858
https://t.me/neuraldeep/1874
Как задрот агентских циклов, давно хотел закопаться, как все устроено, только сегодня с утра дошли руки:
- в каждый запрос к LLM передаётся 15-45 tool definitions в зависимости от настроек - модель видит все доступные инструменты сразу (удачи слабым моделькам на 45 тулах
- цикл работает до тех пор, пока в ответе есть tool_calls - если массив пустой, выводим финальный ответ и завершаемся
- ответ читаем в режиме стриминга: текст пушим в UI сразу, но tool_calls накапливаем - аргументы приходят чанками, JSON парсим только после полного ответа
- модель может вернуть несколько tool calls в одном ответе (parallel_tool_calls: true), но выполняем их строго последовательно через for await - параллелизация не реализована
- после выполнения каждого tool результат добавляется в массив messages как { role: 'tool', content: output }, на следующей итерации модель видит полный контекст
- контекст растёт монотонно: system prompt + все user messages + все assistant messages + все tool results, truncation и summarization отсутствуют
- tool results не обрезаются - если read_file вернул 5000 строк, все 5000 строк попадают в контекст
- loop detection: sliding window из 5 последних вызовов, если 5 подряд одинаковых tool names - инжектим hint "Попробуй другой подход", даём 5 retry, потом принудительный стоп
- batch tool calls (2+ инструмента в одном ответе) сбрасывают счётчик loop detection - считаются намеренным поведением модели
- не можем отправить новое сообщение, чтобы дать подсказку агенту в середине цикла, должны отменить выполнение или дожидаться конца
Очень круто! Но самое крутое впереди. Многие спрашивают, как вкатиться в разработку агентов, с чего начать. Можно начать с простых примеров на коленке, которые были в этом посте. Но это ни разу не похоже на продакшен, просто мини проектики, пощупать самую основу.
А LocalDesk - похоже.
Смотрите, в тех местах, где стоят
Хотите более серьезных приключений - можно сделать субагентов, поддержать MCP, прикрутить донаты в конце концов!
Кстати, именно так и выглядит реальная разработка агентов в проде, на само ядро не тратится много времени, а на управление памятью, оптимизации контекста, детализацию в логах, трассировки - полно. А потом еще начинаются корзинки и evals, и совсем потрачено…
Так что если кто-то хотел "поизучать агентов пару часиков на выхах", вот самый лучший способ.
Еще раз ссылка на GitHub
И чатик, где идет движуха: @neuraldeepchat
———
Пойду тоже запилю что-то, а то Валера здороваться перестанет...
Please open Telegram to view this post
VIEW IN TELEGRAM
Forwarded from DziS Science | Data Science
Привет всем!👋
Когда мы говорим про длительные вычисления, всегда заходит речь о кешировании результатов выполнения.
И лучшим решением является сохранение кэша не в оперативной памяти (как это делает
Итак,
При вызове декоратор хэширует аргументы функции и проверяет, есть ли результат для хэша на диске. Если есть, то моментально загружает с диска и возвращает результат. В противном случае декоратор сохраняет результат на диск и возвращает результат.
Разберем на примере:
🔸 Создаем объект памяти, куда будем сохранять наш кэш. За путь к кэшу отвечает атрибут
🔸 Декорирование функции происходит с помощью декоратора
🔸 Запустим тест 1 раз
🔸 Код будет исполняться 10 секунд. Второй запуск уже будет использовать результаты кеширования:
🔸 Код будет только разгружать уже предварительно рассчитанный результат работы модели.
✔️ В качестве дополнительных техник можно использовать сжатие с помощью
✔️ Также, часто мы передаем в функцию аргументы, которые не влияют на результат вычислений, но меняют хеш. Например, флаг
Например для какой-то функции
Однако, есть и неприятные эффекты.
❌ Например, если внутри функции есть np.random без фиксации сида, кэширование "заморозит" первое случайное значение навсегда. Это может убить эксперимент.
Кэш можно удалить классическим
По традиции, ставь 🔥, если понравилось!
#ds_лайфхаки
Когда мы говорим про длительные вычисления, всегда заходит речь о кешировании результатов выполнения.
И лучшим решением является сохранение кэша не в оперативной памяти (как это делает
functools.lru_cache), а запись на диск с помощью joblib.Memory.Итак,
joblib.Memory - декоратор, который оборачивает функцию, сохраняя кэш напрямую на диск. При вызове декоратор хэширует аргументы функции и проверяет, есть ли результат для хэша на диске. Если есть, то моментально загружает с диска и возвращает результат. В противном случае декоратор сохраняет результат на диск и возвращает результат.
Разберем на примере:
locationfrom joblib import Memory
import time
import numpy as np
memory = Memory(location='./cache_store', verbose=0)
@memory.cache. Для примера обернем очень "тяжелую" функцию, которая спит 10 секунд.@memory.cache
def foo(x, y):
time.sleep(10)
return x**2 + y**2
x,y = np.ones((1000, 1)), np.ones((1000, 1))
res1 = foo(x,y)
x,y = np.ones((1000, 1)), np.ones((1000, 1))
res2 = foo(x,y)
compress, задавая параметр от 1 до 9, который держит баланс между скоростью чтения и размером.memory = Memory(location='./.cache_store', verbose=0, compress=3)
verbose или количество потоков n_jobs. Если ты изменишь verbose=True на verbose=False, joblib подумает, что аргументы изменились, и пересчитает всё заново. Это нам не надо.Например для какой-то функции
process_data@memory.cache(ignore=['verbose', 'n_jobs'])
def process_data(data, param=1, verbose=False, n_jobs=4):
...
Однако, есть и неприятные эффекты.
Кэш можно удалить классическим
rm -rf, либо программно memory.clear(warn=False)По традиции, ставь 🔥, если понравилось!
#ds_лайфхаки
Please open Telegram to view this post
VIEW IN TELEGRAM