Интересное что-то
517 subscribers
2.71K photos
253 videos
138 files
4.51K links
Материалы и мысли, понадерганные отовсюду
Блог: https://t.iss.one/asisakov_channel
Чат: https://t.iss.one/youknowds_chat
Download Telegram
senior_python.pdf
191.7 KB
Сборник вопросов по python для подготовки к собесу на бэкендера, дата сайнтиста и аналитика, самые ключевые вопросы с развернутым ответом. Формат pdf позволяет готовиться к интервью в любой обстановке. Ставим огонек 🔥 и делимся с другом такой годнотой, если хотите больше подобных сборников!

@postypashki_old
Forwarded from Женя Янченко
Rate Limiter

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

В посте про API Gateway упоминалось, что одной из его функций является rate limiting. Предлагаю сегодня разобраться с этим подробнее.

🫧 Что такое Rate Limiter

Rate Limiter — это механизм, который контролирует количество запросов, которые система может обработать за определённый промежуток времени. Его задача заключается в защите ресурсов от чрезмерной нагрузки при массовых обращениях к API.

В настройках рейт лимитера задают лимиты количества запросов в единицу времени. Например, у нас есть публичное API, на которое могут обращаться авторизованные пользователи, и мы настраиваем лимит 20 запросов/сек от одного пользователя. Определять пользователя можно по JWT токену, по IP, по API-ключу.


Пока заданный лимит не исчерпан, рейт лимитер передает запрос дальше на бэк.
Если лимит превышен, рейт лимитер не пропускает запрос и отдает ошибку 429 Too Many Requests.

Rate limiter предназначен для ограничения количества запросов от "хороших" клиентов, чтобы конкретный клиент не перегрузил сервис. При суровой DDoS-атаке только он не спасет, так как атака может идти с тысяч разных IP-адресов.

🫧 Место Rate Limiter в микросервисной архитектуре

Почти все современные API Gateway имеют встроенные механизмы rate limiting, но иногда рейт лимитер выносят в отдельный сервис, к которому уже обращается API Gateway.

Рейт лимитеру нужно хранить состояние, чтобы посчитать, сколько запросов уже было за период. Эти данные он может хранить у себя в памяти или в отдельном хранилище (например, Redis). Отдельное хранение нужно, когда используется несколько инстансов API Gateway. Redis помогает обеспечить атомарность операций, чтобы все инстансы гейтвеев видели общее состояние, и не возникало гонок и рассинхронизации.

🫧 Алгоритмы rate limiting

🤍 Fixed window (фиксированное окно)

Как работает:

Представим, что у нас есть лимит 10 запросов в минуту. Например: 09:00:00 → 09:00:59 — это одно окно.

Окно не обязано быть минутой, это может быть и 10 миллисекунд.

Считаем, сколько запросов пришло в этом окне.

Пока запросов меньше 10 → пропускаем их
Если уже больше 10 → отклоняем

Когда наступает новая минута — счётчик сбрасывается.

Проблема fixed window заключается во всплесках (burst) на границе окон: если пришло 10 запросов в 09:00:59, а потом еще 10 запросов в 09:01:01, то получается 20 запросов за 2 секунды, а должно быть не больше 10 в минуту.

🤍 Sliding window (скользящее окно)

Этот алгоритм решает проблему со всплесками на границе окон.

Как работает:

Если лимит 10 запросов в минуту, то храним временные метки всех запросов за последние 60 секунд.

На практике это оптимизируют, чтобы не хранить всё.

Для каждого запроса проверяем, сколько за последние 60 секунд уже пришло запросов от этого пользователя.

Если прошлых запросов меньше 10 → пропускаем
Если за последние 60 секунд уже было 10 запросов → отклоняем

Запросы старше 60 секунд убираем из списка.

Sliding window обеспечивает равномерное распределение, но у него выше требования к памяти (нужно хранить временные метки запросов) и выше вычислительная сложность (нужно перебирать и удалять устаревшие временные метки из списка).

Давайте посмотрим более гибкий алгоритм, который используется во многих API Gateway ⬇️
Please open Telegram to view this post
VIEW IN TELEGRAM
Forwarded from Женя Янченко
🤍 Token Bucket (ведро с токенами)

Это популярный алгоритм для рейт лимитинга. Например, он используется в API Gateway Tyk.

Как работает:

Как следует из названия, у нас есть ведро с токенами 🪣

Приходит запрос. Чтобы пропустить запрос на бэк, используем один токен из ведра
Если токенов в ведре не осталось → запрос отклоняем

Максимальное количество токенов в ведре называется capacity.
Скорость, с которой токены добавляются в корзину, называется fillRate.

Ведро пополняется равномерно.

Например, если capacity = 60, то 60 токенов не будут подсыпаны разом в 09:00:00 (как счетчик в Fixed Window), а будут добавляться
постепенно со скоростью fillRate. Если fillRate = 5 токенов в секунду, и прошло только 2 секунды, то в ведре будет 10 токенов и только 10 запросов смогут пройти на бэк.

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

Если расходующих токены запросов не будет, то через 12 секунд (5 * 12 = 60) ведро наполнится до максимальной capacity в 60 токенов, и новые токены в него поступать не будут. Но и сбрасываться не будут. Все 60 токенов будут ждать свои запросы. И это может привести к кратковременному всплеску нагрузки, так как все 60 запросов смогут пройти одновременно 🔥


Token Bucket допускает всплески трафика, но не больше capacity.

По сравнению со Sliding window алгоритм Token bucket проще и требует меньше памяти.

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

Минус: может быть сложно выбрать capacity и fillRate.

🤍 Leaky Bucket (протекающее ведро)

Как работает:

В Leaky Bucket в ведре лежат не токены, а сами запросы.

Приходит запрос. Если ведро не переполнено → кладём запрос в ведро (в очередь)
Если переполнено → отклоняем запрос

Каждые N миллисекунд пропускаем фиксированное число запросов из ведра на бэк.
Если запросов нет, то ведро стоит пустое, ничего не копится.

То есть Leaky Bucket — это как очередь First In First Out фиксированного размера.

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


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

Недостаток Leaky Bucket является продолжением его достоинства: он не пропускает всплески, поэтому при резком увеличении трафика если очередь уже заполнена старыми запросами, это лишит систему возможности обрабатывать более свежие запросы.

На практике Rate Limiter обычно написан за нас, но мне кажется, эту тему полезно повторить перед System Design собесом.
Please open Telegram to view this post
VIEW IN TELEGRAM
➡️Как улучшить RAG?

Наткнулся на статью про базы знаний. На русском!

В ней рассмотрены различные стратегии повышения качества ответов. Объяснено достаточно понятно.

Конечно, после прочтения вы не станете КМСом по RAG, но на любой технарской тусовке уже сможете прокатить за своего и втереться в доверие😄
Please open Telegram to view this post
VIEW IN TELEGRAM
🤯 Мои инсайты из года внедрения AI в разработку (ч.1)

У меня главный фокус последнего года — это обучение команд разработки и внедрение AI в их процессы. Я поработал с разными компаниями — стартапами и корпорациями; и с разными ролями — СEO, СТО, продакт-менеджеры и разработчики. И мне есть, что рассказать.

Для начала разделим эту историю на два понятных стрима:

1. Для команд разработки я помогаю выстраивать системный процесс, rules-management, spec-driven development, итд. Главная задача — выстроить процесс так, чтобы AI стабильно доставлял код, а метрики росли по всей воронке доставки, без просадок по качеству или стабильности релизов. Это направление я называю AI-driven development.

2. Для нетехнических професионалов (продакты, маркетологи, СЕО компаний и многие другие) набор навыков и инструментов отличается. Это тот самый вайбкодинг — навык быстро проверять гипотезы, автоматиировать рутину, все те ситуации, где раньше для реализации идеи нужно было искать для себя технического партнера или обращаться к команде разработки, а теперь можно сделать все самому. С этим мы работаем в Vibecon.

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

Я так часто слышал аргументы против применения AI в разработке и в 99% это упирается в skill issue. Галлюцинирует модель? Научитесь прокидывать контекст и писать спеку перед тем, как нести агенту. Спефичиные подходы к разработке в команде? Распишите рулы для AI-агента и раскатите на всю компаню. Так можно долго продолжать.

Я тратил месяцы своей карьеры на фичи или продукты, которые сейчас создаю за 1-2 вечера. Впервые в жизни я чувствую, что могу реализовать любую свою идею, и мне для этого не нужен дизайнер или разработчик.

И это невероятное чувство 😊
Please open Telegram to view this post
VIEW IN TELEGRAM
🤯 Мои инсайты из года внедрения AI в разработку (ч.2)

Для меня это во многом личная история. Я начинал карьеру, как разработчик и до 2020 писал код фуллтайм и мне это нравилось, но тянуло в продуктовую сторону. Дальше был переход в продакт-менеджеры. Я продолжил любить код, но времени на него не осталось, а со времнем и сам навык постепенно теряться. Каждый заход «накодить» что-то после перерыва становился все более тяжелым.

Я все еще мог накидать архитектуру, соединить с продуктовым видением, отгрузить в виде спеки, но дальше его реализовать могли только разработчики. Так было до начала 2024, когда я плотно подсел на Cursor. Там еще не было агента, но уже можно было писать код в 2-3 раза быстрее промтами.

А дальше наступила agentic-code революция, апдейты моделей от claude с 3.5 до 4. Я все также могу накидать спеку и соединить с продуктовым видением, только код за меня пишет теперь агент вместо разработчика. Продумываешь, подгатавливаешь документ, декомпозируешь, отгружаешь агенту и забываешь. Время от идеи до реализации сократилось до часов. А я оказался наконец на своем месте: работаю с кодом каждый день, реализую идеи, не теряя при этом фокуса на продукте и продажах.

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

Нет более заезженной фразы, чем «будущее уже здесь, просто оно неравномерно распределено», но именно разработка это то место, где это сильнее всего заметно.
Please open Telegram to view this post
VIEW IN TELEGRAM
Forwarded from AI и грабли
Почему большинство делают LLM классификацию не правильно

Зачем вообще нужна LLM классификация? Для примера – хрестоматийная задача из суровой реальности:

- На вход – история переписки пользователя с ботом
- На выход True, если пользователь делает в чате что-то нехорошее (например, пытается вытащить системный промпт или разговорить модель про ее полические взгляды). False, если все хорошо

Вот 4 типичных подхода и один нетипичный

Уровень 0 – просто промпт:

Блаблабла, напиши True, если пользователь делает что-то плохое. Вот критерии плохого: ... Напиши False, если все ок


Проблемы: Модель может ответить "false", "FALSE", "false, потому что блаблабла" или вообще выдать системный промпт, если инъекция хорошая


Уровень 1 – structured output:

class Response(BaseModel):
verdict: bool = Field(..., description="Блаблабла, напиши True, если пользователь делает что-то плохое. Вот критерии плохого: ... Напиши False, если все ок")


Уже лучше. Но что если хочется еще и знать что конкретно идет не так?


Уровень 2 – Literal (multiclass классификация):

Вместо бинарного поля – несколько возможных вариантов

class Response(BaseModel):
verdict: Literal["normal", "politics_bait", "system_prompt_robbery", ...]


А что если у нас одновременно и politics_bait и system_prompt_robbery???


Уровень 3 – Несколько полей (mutlilabel классификация)

Разделяем варианты по разным бинарным критериям (aka чеклист)

class Response(BaseModel):
is_politic_bait: bool
is_system_prompt_robbery: bool


🧐 Вместо бинарных полей можно тоже сделать Literal с несколькими значениями – будет multiclass multilabel. Пример – извлечение данных из вакансий – одно поле может быть Junior/Middle/Senior, второе удаленка/офис/гибрид, третье – основной рабочий язык


Коля, ну а тут то что не так?
Дело в том, что триггер True для is_system_prompt_robbery сработает только, если вероятность будет больше чем False . Давайте представим себе такие вероятности:

P(True) = 0.49
P(False) = 0.51

Система скажет False ("все ок"). А на самом деле? А на самом деле уверенность, что все ненормально - 49% 🙈

И большинство решений на рынке остаются именно на этом уровне!

Да, могут добавить thinking или даже Structured Guided Reasoning (например перед вердиктом попросив цитату пользователя, где мб есть проблема), но глобально это ситуацию не меняет.

Пора учиться управлять вероятностями (с) Коля



Уровень 4 – logprobs + пороги
:

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

По сути – это "уверенность" модели в каждом конкретном токене

Включается вот этими параметрами

client.chat.completions.create(
...,
logprobs=True,
top_logprobs=5
)


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

Кстати, кто знает, как правильно доставать logprobs только важных для нас токенов (true/false) из всего json'а?

{
"is_politic_bait": true,
"is_system_prompt_robbery": false
}


———

Короче, полноценная классификация появляется тогда, когда появляется вероятность.

Ну и идеи дальнейших улучшений одной строкой:

- Разные пороги под разные характеристики
- Подбор порогов автоматически, если есть датасет
- Если multiclass (пример с вакансиями), то еще важно насколько у топовых классов близкая "уверенность" – если у обоих большая, но примерно одинаковая, то контринтуитивно, но значит, моделька на самом деле сомневается в своем топ-1
Я бы сказал, что rule of thumb следующий

Если данных много

- Везде где риал тайм фидбек - out of time holdout
- В остальных случаях (асессорская/llm разметка например) обычная отложенная выборка (out of sample holdout, да?)

Если данных мало

- Stratified K fold если модель позволяет
- Обычная отложенная если не позволяет

Если данных очень мало
- Nested
- А потом out of time отложенная выборка, жедательно собранная после обучения модели. Медицинские статьи по-другому не котируются кстати
Летят V самолётов, нет V мало — K! и оба реактивные...


У опроса выше есть всего один правильный ответ, и мы к нему придем.

А пока разберем мифы

Напомню только что валидация (в тч кросс-валидация) модели — это не только способ выбрать лучшую среди класса моделей (лучшую == точнее , устойчивее, сильнее, с меньшим риском и пр), но и получить интервальные оценки ее качества.

Миф 1. LOO на практике почти не используется

LOO — в варианте не Jackknifing, а Hold Out — в котором test — последний элемент, val — предпоследний, а остальное — трейн — это частый сетап в академических статьях про рекомендашки (тк академики часто обделены вычислительными ресурсами + им нужно сравниваться с предшественниками в их сетапе -- как в байке с шириной железной дороги и ее связи с шириной римской телеги.

Примеры, которые были под рукой:

NIPS 2023
KDD 2023
RecSys 2023
CIKM 2020
IJCAI 2019

Миф 2. Двойная кросс-валидация позволит сделать вашу модель более робастой

Вопрос некогда популярной в задачах на малых выборках двойной кросс-валидации (Nested) закрылся около 2018 с итогом что игра не стоит свеч. В соревновательной практике тоже особо не применялась — проще оказалось усреднять по cидам. Спасибо Себастьяну Рашке, который честно сравнил как лучше всего получать интервальные оценки качества моделей.

Кстати, модификаций кросс-валидаций для малых выборок десятки, начиная с Balance-Incomlete CV, Monte-Carlo CV (с возвращениями) и заканчивая всякими Bayessian CV

Миф 3. Выбор K в K-fold валидации ни на что не влияет

В 2015 вышла (и обновлялась до 2018) 99-страничная инструкция как правильно выбрать V в V-fold валидации.
Жаль, что ей никто не пользуется 😂😂🤣

Миф 4. .632 это калибр 🔫

Нет, это тоже модификация кросс-валидации в статьях 90х. Вообще, применить бутстрап к кросс-валидации тянуло многих.

Тем, кому любопытно — снова пример в блоге Себастьяна Рашки.

Миф 5. K-fold vs V-fold

Burman в 1989 обозначил уже известную к тому времени процедуру как V-fold

В бессмертном ESL (а первое издание было в 2001 году) уже K-fold

Оттуда оно, вероятно, попало в sklearn в 2007-10 и понеслось, 64k звезд на гитхабе — не шутки.

Миф 6. Все вопросы с валидацией / кросс-валидацией решены еще 20-30-60 лет назад

Одни парни и в 2025 пишут, другие их рецензируют. Не знаете о чем писать диплом по ML -- возьмите любую задачу и сравните несколько протоколов валидации численно и теоретически.

Миф 7. На опрос выше нет правильного ответа.

Хотя опрос достаточно спорный (не очевидна, например, необходимость OOT в картинках, хотя можно придумать кейс), можно предположить что:

1. Больше всего DS работают там где больше всего денег — в продажах и рекламе, а это всякие response-модели NBO / NBA / RecSys + исторически в банках (снова response-модели вроде PD + регрессии в будущее -- cashflow) — это все табличные в основном задачи
2. Больше всего DS работают либо в корпорациях либо с корпоративными данными

А у корпоративных данных есть одна важная особенность: они проходят по достаточно сложному пути: CDC -> ETL/ELT -> DWH / Data Lake -> Common DM / User DM

И по всему пути накапливается задержка (gap), который DS/MLE обязан учитывать.
А если вспомнить еще и про data drift / concept drift / label shift — то очевидность последнего ответа не вызывает сомнений (хотя это частично можно решить adversarial validation и тестами)

При этом на практике я использовал и варианты со стратификацией, и с группами (в недвижке), и двойную (nested) кросс-валидацию, и все варианты OOT / OOS CV
Forwarded from Pavel Zloi
Анатомия агентов

Давно обдумывал данную публикацию, хотелось собрать опыт построения агентов в одно небольшое сообщение. И так, по порядку...

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

Такая система опирается на четыре обязательных компонента:

1) Нейросеть - мозги агента, как правило это LLM, понимает контекст задачи, строит план, формирует запросы к тулам.

2) Инструкция (промт) - набор правил, выглядит как подробный системный промпт, описывающий поведение агента, как агенту планировать работу, какие критерии использовать для оценки результата.

3) Память - может быть как краткосрочная (контекст диалога), так и долговременная (база знаний, профиль пользователя, файлы markdown). Важно понимать, что память, в отличии от тулов, работает всегда и информация из памяти может быть запрошена или сохранена на любом этапе работы агента.

4) Тулы (инструменты) - набор вызываемых при необходимости инструментов для взаимодествия с внешним миром, например поисковый движок, база данных, внешние API, браузер, файловая система, датчики, роборуки и так далее. В отличии от памяти модель видит список инструментов и планирует свои действия с учётом оных.


Когда это не агент?

У меня есть простые критерии оценки, если одного или нескольких компонентов представленных в списке выше нет, то это уже не агент, а интерфейс к модели.

Например:
- LLM + промпт (+ память)? -> чат-бот.
- LLM + память -> RAG-подобная система.
- LLM + тулы (+ промт)? (без планирования и оценки) -> классификатор/роутер.

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


Как из RAG агента сделать?

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

Этого вполне хватает для ответов по корпоративной документации или скажем для беглого поиска по базе знаний.

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


Итого

Имеем компоненты:
- Нейросеть - понимает, планирует, оценивает
- Инструкция - задаёт правила и критерии оценки
- Память - хранит контекст и опыт
- Тулы - позволяют взаимодействовать с внешним миром

Все четыре вместе - агент.

Минус любой - интерфейс к модели или некая иная система.
#llm #agents
Про память очень годно
Forwarded from Pavel Zloi
Долгосрочная память агентов

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


Что я вообще называю памятью

Когда мы говорим "память" языковой модели, на практике речь идет про то, что реально попадает в контекст во время инференса:
- системный промт
- история сообщений
- любые дополнительные вставки (few-shots, заметки, справки, ссылки, извлеченные факты)
- вызов тулов и их ответы

То есть память - это не мистический модуль внутри модели, а то, чем мы обогащаем контекст диалога перед генерацией.


Два вида памяти моделей

- Краткосрочная - всё, что живет в текущей сессии и прямо подается в "messages" и "tools", это могут быть пары с ролями user/assistant и у некоторых моделей роль tool. По завершении сессии это естественным образом забывается (если не предпринять шагов по сохранению).

- Долгосрочная - всё, что сохраняется между сессиями и может быть автоматически извлечено и вставлено в будущие запросы. Это может быть база знаний, коллекция "вечных" заметок, библиотека кейсов или примеров. Ключевое: модель не обязана "знать", что где-то есть БД, она просто получает уже обогащенный промт.


Вызов БД как тула - это ещё не память

Тулы - это то, чем агент пользуется при необходимости, память же "работает всегда". Прежде чем модель что-то сгенерирует, контекст уже дополнен тем, что нужно вспомнить. Если мы заставляем модель осознанно "вызывать память как тул", это ближе к явному инструменту, а не к фоновому механизму.

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

[1/3]
Forwarded from Pavel Zloi
Pavel Zloi
Долгосрочная память агентов Под моей прошлой публикацией разгорелась бодрая дискуссия. В ходе которой я наконец-то четко сформулировал, что именно считаю "долгосрочной памятью" в контексте LLM-агентов и как, на мой взгляд, она должна работать. Что я вообще…
Memory Copilot - концепт инструмента памяти агента

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

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

И так, Memory Copilot - это самостоятельный сабагент, который:
1) обогащает промт перед генерацией за счет релевантного опыта, примерно как это описано в "Automatic Engineering of Long Prompts" (arXiv:2311.10117)
2) решает, что из результатов текущего шага стоит сохранить
3) работает автоматически, без того чтобы основная модель "тригерила память как тул"

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

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

- вспомнить (search) - происходит перед генерацией ответа, на этапе сборки промта. Агент сопоставляет текущий запрос пользователя с тем, что есть в долговременном хранилище, извлекает релевантные куски (например в виде few-shots или кратких "фактов") и подает это в контекст вместе с системными инструкциями и историей диалога.

- запомнить (save) - происходит после генерации, опциональный шаг. Агент оценивает полезность сгенерированного ответа и решает, стоит ли сохранить короткую выжимку из результата. Это снижает шум, экономит место и улучшает последующие извлечения.

Как это выглядит на одном запросе:

1) после запроса юзера вызываем search, в ответе получаем релевантные куски, добавляем в промт, генерируем ответ.

2) после ответа вызываем save, но не вслепую, сначала мини-оценка "LLM-as-a-judge" (есть ли уже такое воспоминание, пригодится ли это в будущем, оригинально ли, не дублирует ли уже сохраненное). Только если прошло отсев - сохраняем. Подробнее про оценку ответов в "From Generation to Judgment: Opportunities and Challenges of LLM-as-a-judge" (arXiv:2411.16594)

Такой цикл делает агента "самонастраивающимся", то есть чем дольше он работает, тем точнее подмешивает опыт и тем меньше ошибается ошибки, агент таким образом "учится", хотя наверно это не самая лучшая аналогия. Идея близка к линиям работы "Reflexion: Language Agents with Verbal Reinforcement Learning" (arXiv:2303.11366) про рефлексию и самокритику генераций, где модель перед сохранением оценивает свою же работу.


Не только лишь чат

Тот же принцип годится и "за пределами чатика".

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

По моим наблюдением добавление few-shots позитивно влияет на планирование вызова тулов, так как моделька быстрее и точнее выбирает нужный, про фьюшотс "Language Models are Few-Shot Learners" (arXiv:2005.14165).

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


Простенький пайплайн

1) Приходит запрос пользователя.
2) Сопоставление с долговременной памятью -> извлеченные фрагменты превращаем в few-shots/факты -> собираем промт.
3) Генерация ответа.
4) Быстрая проверка полезности результата (LLM-as-a-judge).
5) Если полезно, то дистиллируем и сохраняем.

На следующих шагах этот "опыт" автоматически всплывает при сборке промта.

[2/3]