mshumer

Stars and mentions

Last 30 days, Oct 5 – Nov 3

GitHub stars82
mentions3
036912Oct 5Oct 19Nov 3
UTC days · repositories mshumer owns9 repositories

Package downloads

No package download history available yet.

Top repositories

mshumer’s repositories ranked by new stars, as on trending.

Loading

Contributes to

Repositories outside mshumer’s account where mshumer opened or reviewed pull requests in the past 365 days.

Who noticed mshumer

Everyone who starred or forked mshumer’s repositories since the archive began in 2011.

Notable accounts

Ordered by the stars their own repositories have received.

Biggest fans

Accounts that starred the most of these repositories.

Breakout weeks

Each repository’s best week of new stars, with the release published around it.

Mentions

3posts
Nov 40 posts
  1. Фильтр Калмана в цикле правок ИИ: что он меняет и как это проверить Краткий результат учебной симуляции. RMSE — среднеквадратичная ошибка: большие промахи влияют на неё сильнее. С фильтром снизились медианы обеих ошибок и средней величины правок; число раундов одинаково. Подробный разбор — в разделе 3. Глядя на то, как современные вайбкодеры обращаются с роями агентов, возникает ощущение, как будто все разом забыли про существование теории управления. В самом деле, как можно строить все эти циклы с исполнителями и критиками просто наугад? Агент исправил работу, но очередной отзыв критика требует исправить еще. Итерации могут не сходиться или сходиться слишком медленно, возникает проблема «шумного критика» — это все давно известно для систем вида предиктор+корректор. Один из инструментов для работы с шумными измерениями — фильтр Калмана. Я сначала проверил его на простой численной модели, а затем построил стенд с настоящими ИИ-агентами. Результаты получились разными: в учебной симуляции фильтр улучшил оценку состояния и уменьшил величину правок, а в реальном пилоте дополнительного преимущества Калмана обнаружить не удалось. Ниже я подробно разбираю обе постановки и границы полученных выводов. Начинаю с простой учебной модели и сравнения при одинаковых условиях, затем перехожу к практике: проверке замечаний, выбору правок по нескольким критериям и организации агентского цикла. В эксперименте на реальной задаче я сравнил четыре способа принятия изменений в цикле «автор — критик» на базе языковой модели gpt-6.1-sol: по рекомендации критика, по фиксированному статистическому правилу, со сглаживанием и с фильтром Калмана. ИИ-агент пытался ускорить работу функций, написанных на Python. На стенде проверялись корректность, время выполнения и память. Всего было получено 720 ответов модели: 144 для калибровки и 576 для оценки. Оценочная часть стенда состоит из 48 траекторий: 6 задач × 2 повтора × 4 режима. В каждой траектории содержится шесть последовательных попыток улучшения кода — шесть ответов автора и шесть ответов критика. Подробности и результаты приведены в разделе 8. Фильтр Калмана соединяет прогноз и новый отзыв, учитывая, насколько каждому можно доверять. Результаты на слайде получены в учебной симуляции. Код и сохранённые результаты учебной симуляции доступны в Jupyter-ноутбуке. Полный комплект учебной симуляции включает также исходники, зависимости, таблицы, рисунки, анимации и инструкции запуска. Для собственного опыта с настоящими агентами скачайте отдельный пакет запуска через OpenAI API. В разделе 9 объясняю, как начать с демонстрации, выбрать объём опыта и сохранить прогресс. Оглавление Введение: как отзыв становится командой 1. Минимальная модель 2. Как работает фильтр Калмана 3. Проверяем вклад самого фильтра 4. Почему одного фильтра недостаточно 5. Сравниваем четыре конфигурации 6. Выбросы, задержки и смена шкалы 7. Рабочая инструкция по симптомам Как перенести это в работу с ИИ 8. Реальный пилот: 720 ответов 9. Материалы и самостоятельный запуск Дополнение: P, D и I Введение. Как отзыв критика превращается в команду для исполнителя Когда оценка критика сразу определяет следующую правку, ИИ-агент очень легко попадает в цикл избыточных правок. Поправил вступление — критик доволен. Переписал середину, слегка сломав вступление, — критик просит вернуть прежнее. ИИ-агент возвращает вступление и заново ломает середину. Версии сменяют друг друга, бюджет токенов убывает. Теория управления помогает разобраться, почему такой цикл может колебаться вместо достижения цели. Что здесь происходит с научной точки зрения? ИИ-агент правит работу, критик оценивает результат, отзыв критика определяет следующую правку. В теории управления это называется обратной связью. Шумные правки могут возникнуть как из-за слишком сильных правок исполнителей, так и из-за неточных отзывов критиков. Как отличить действие этих причин друг от друга? Используем парное контролируемое сравнение: сохраняем остальные условия и меняем только способ обработки измерений. Сначала закрепим простое правило правки, затем проверим вклад обработки отзывов критика. Похожий порядок работы Мэтт Шумер (Matt Shumer) назвал Gauntlet Loop при работе над Claude of Duty: Исполнитель исправляет результат, Критик со свежим контекстом сравнивает его с заданным образцом, после чего цикл повторяется. Я взял его подход как основную схему для учебного эксперимента. Человек задаёт цель и критерии, а задача заключается в том, чтобы показать, что же происходит между оценкой и следующей правкой, и как это оптимизировать. 1. Минимальная модель: эталон, артефакт, критик Я представил состояние результата работы ИИ-агента одной точкой на числовой оси. Одна точка показывает текущее состояние результата, другая — нужное. Правка сдвигает первую точку, а критик сообщает её положение с ошибкой. Эта точка движется после каждой итерации. Она может приближаться к цели, метаться вокруг неё или уходить в сторону. Цель заключается в том, чтобы понять, как этим управлять. Такая модель удобна тем, что можно по отдельности включать ошибку критика, неточность исполнения или задержку. А затем дать двум вариантам цикла одинаковые последовательности ошибок и проверить, что изменяют разные подходы. Смысл такого опыта гораздо шире задачи редактирования текста, или решения простейшего дифференциального уравнения. В первую очередь он важен для задачи генерации кода. Код, план или статья проходят один и тот же путь правок: сделать → оценить → переделать. Исследуемая ниже модель помогает понять, как сама организация этого цикла порождает метания или помогает их уменьшить. Одна правка глазами агента и критика Прежде всего разберёмся, откуда и как именно возникает ошибка. Пусть нужный результат находится на отметке 10, текущий — на 8,1. Агент решил прибавить 1,2 балла. Правка сработала чуть сильнее: добавилось ещё 0,05. Получилось 9,35. Но критик сегодня строг: занизил оценку на 0,25 и сообщил 9,1. Что мы хотим узнать Ответ в этом примере Что получилось после правки? 8,1 + 1,2 + 0,05 = 9,35 Что сообщил критик? 9,35 − 0,25 = 9,1 Сколько осталось до цели на самом деле? 10 − 9,35 = 0,65 Сколько осталось, по мнению агента? 10 − 9,1 = 0,9 Агент выбирает следующую правку по последней строке. Например, если исправлять 70% замеченной ошибки, он добавит ещё 0,63 балла. Мы уже видим источник проблем: действие рассчитывается по оценке критика, а меняет реальный артефакт. Эти две величины могут расходиться. Что фиксируем в модели Зафиксируем правила этой числовой шкалы. Мы хотим попасть близко к десяти; перелёт выше цели тоже будем считать ошибкой. У нас два источника случайности. Исполнитель может выполнить правку чуть сильнее или слабее, чем задумал. Критик может завысить или занизить результат. В базовом опыте оба источника дают случайные ошибки без систематического смещения. Зададим типичный разброс ошибок критика — 0,55 балла, а исполнения — около 0,22. Точное значение знает только симулятор: оно понадобится нам для оценки качества. Разность «цель минус оценка критика» будем называть невязкой. Если она положительная — нужно прибавить, отрицательная — убавить. Правило, которое по этой невязке выбирает правку, называется регулятором. Теперь весь цикл можно прочитать без формул: измерить → сравнить с целью → выбрать правку → применить её → повторить. На рисунке 1 показан тот же самый маршрут. Будем менять отдельные части этого цикла и смотреть, что происходит. Как из оценки получается правка Для основного опыта хватит одного правила: исправлять 70% оценённой ошибки. Не хватает двух баллов — добавляем 1,4; не хватает половины — добавляем 0,35. Перебрали полбалла — убавляем 0,35. Возле цели правка становится меньше. Это так называемый пропорциональный, или P-регулятор; долю называют усилением и обозначают . У нас она равна 0,7. Теперь остаётся выбрать, от какого именно числа считать ошибку: Можно взять свежий отзыв критика. Можно сначала уточнить состояние по прогнозу и отзыву. Именно эти два варианта далее сравниваются. Как настраивать P и зачем добавлять к нему реакцию на изменение ошибки или память о прошлых недолётах, разберём в дополнении в конце. Для всех опытов с фильтром в основной части хватит этого правила 70%. Уравнения модели и обозначения: что именно считает симуляторОбозначим цель через , истинное состояние артефакта — через , измерение критика — через . Индекс здесь означает номер шага. Базовая модель выглядит так: Здесь — ошибка критика, — ошибка исполнения, — заданная правка. Шумы критика и исполнителя независимы между собой по времени, имеют нормальное распределение с нулевым средним. В базовых прогонах: Стандартное отклонение выражает разброс в баллах. Символ Смысл цель, обычно 10 истинное состояние; шкала не ограничена сверху или снизу измерение критика невязка, по которой рассчитывается правка правка; ограничение ±3 появится только в опыте с PID , шум критика и шум исполнения , дисперсии этих шумов В следующем разделе вместо свежего измерения регулятор получит оценку наблюдателя . Тогда невязка станет . Там же ввожу — расчётную дисперсию ошибки оценки, и — вес нового измерения в фильтре Калмана. Усиление регулятора и вес измерения решают разные задачи: первое задаёт размер правки, второй — уточнение оценки. В базовой модели нет ни инерции, ни насыщения: правка просто прибавляется. Постоянные потери, задержку, выбросы и другие нарушения далее включаются отдельно. Рис. 1. Контур: эталон r и измерение критика z дают невязку y = r − z; регулятор выбирает правку u, Builder применяет её с шумом w; критик измеряет x с шумом v. Оценка возвращается на вход сравнения и определяет следующую правку. 2. Фильтр Калмана: как не начинать с нуля после каждого отзыва ИИ-критика Что можно узнать из оценки критика? Разбираем в нашем игрушечном примере на конкретных числах. Прежняя оценка была шесть, ожидаемая прибавка от правки — два, новый отзыв — опять шесть. Прогноз и критик расходятся на два балла. Если критик занизил состояние, регулятор, принявший его оценку как есть, подготовит слишком большую правку. Но у нас осталась полезная информация: прежняя оценка и сведения о том, что уже изменилось. Критик мог ошибиться. Правка тоже могла сработать слабее ожидаемого. Задача заключается в том, чтобы правильно учесть обе возможности. Фильтр Калмана хранит оценку состояния, предсказывает её изменение после правки и уточняет прогноз по новому измерению. В теории управления такой помощник называется наблюдателем. Его роль в том, что он отвечает регулятору на вопрос «где мы сейчас, насколько можем судить по данным?». Ниже разбираю специально подобранный учебный шаг обычного фильтра, пока без защиты от выбросов. Сравнение на случайных прогонах будет дальше. Что происходит Число и его смысл Помним прошлый результат наша оценка — 6 баллов Учитываем применённую правку ожидаем прибавку 2, получаем прогноз 8 Читаем новый отзыв критик сообщил 6, на два балла ниже прогноза Учитываем надёжность источников в этом примере берём четверть расхождения Уточняем оценку отступаем от 8 на половину балла: получаем 7,5 Число 7,5 лежит ближе к прогнозу, потому что в этом примере неопределённость прогноза меньше неопределённости нового измерения критика. Неопределённость прогноза включает и ошибку предыдущей оценки, и шум выполнения правки. При равных неопределённостях прогноза и измерения оценка оказалась бы посередине — на семи. Если бы надёжнее оказалось измерение критика, результат сдвинулся бы ближе к шести. Коэффициент 0,25 здесь был получен из соотношения этих неопределённостей. Теперь вернём оценку регулятору. До цели 10 по свежему отзыву не хватает четырёх баллов, а по оценке фильтра — двух с половиной. При нашем правиле 70% следующая правка составит 1,75 вместо 2,8. Фильтр Калмана изменил сведения о состоянии, размер правки по ним выбрал всё тот же P-регулятор. Следующий раунд Теперь в памяти остаются 7,5 и величина неопределённости этой оценки. После очередной правки мы переносим оценку вперёд на ожидаемую прибавку. Заодно увеличиваем неопределённость: правка могла сработать не совсем так, как задумано. Приходит новый отзыв — снова уточняем прогноз. Это объясняет, зачем здесь модель изменения состояния, а не простое среднее последних оценок. Старые отзывы относятся к старым версиям работы. Усредняя их напрямую, мы смешали бы качество до правки и после неё. Наблюдатель сначала учитывает изменение, а уже потом сопоставляет прогноз со свежим отзывом. В журнал записываем версию → прогноз эффекта → выполненную правку → повторную оценку. Повторные оценки неизменной версии помогут измерить случайный разброс критика. Для проверки прогноза и систематического перекоса нужен внешний ориентир, например оценка человека по той же шкале, или какая-то объективная метрика качества, потому что по одной разнице двух отзывов отделить эффект правки от ошибки критика нельзя. На правом графике ниже показан один прогон симулятора. Серые точки — отзывы критика, синяя линия — оценка фильтра. Чёрная линия показывает истинное состояние: в учебной модели мы его знаем и можем проверить результат. В реальной работе такого удобного ответа обычно нет. Посмотрите, как фильтр реагирует на очередную точку с учётом уже накопленной информации. Остаётся проверить, стала ли меньшая правка полезнее. В следующем опыте оба контура будут работать одинаковое число раундов, без досрочной остановки. Так вклад фильтра не смешается с выигрышем от раннего завершения работы. После рисунка есть необязательный разбор формул — его можно пропустить и перейти к сравнению в разделе 3. Для более подробного изучения и перехода к многомерному случаю рекомендую статьи: «Фильтр Калмана» — последовательный вывод формул для одномерного случая. «Фильтр Калмана — Введение» — матричная запись алгоритма, смысл его параметров и пример реализации. «Фильтр Калмана: от простого к сложному» — примеры многомерных моделей и настройки параметров фильтра. Рис. 2. Слева — учебный шаг: прогноз 8 уточняется до 7,5 по отзыву 6; вес критика в этом примере равен 25%. Справа — отдельный прогон: seed=11 задаёт случайную последовательность. Оценка сопоставлена с измерениями и истинным состоянием. Полоса показывает ±√P — расчётную неопределённость после обновления фильтра; это не гарантированный коридор для истины. Показаны только шаги с выполненным обновлением; остановка здесь отключена. Формулы фильтра Калмана и карта весов — необязательный разборЕсли хочется проверить формулы Этот подраздел объясняет веса из примера и связывает их с кодом. Обозначим прогноз качества через , его дисперсию ошибки — через . Верхний минус означает «до нового измерения», верхний плюс — «после». Критик сообщает , дисперсия его ошибки — . Дисперсия измеряется в квадратных баллах; её корень — стандартное отклонение в баллах. Откуда взялась четверть Возьмём долю расхождения и сдвинем прогноз в сторону измерения: Скобка — это разница между сообщением критика и прогнозом. Её называют инновацией. В нашем примере это . Число определяет, какую долю этой разницы учесть. Пусть ошибки прогноза и текущего измерения несмещённые и независимые. Тогда дисперсия ошибки получившейся оценки равна Первое слагаемое — оставшаяся ошибка прогноза, второе — ошибка, внесённая измерением. Это квадратичная функция . Минимум достигается при Теперь можно проверить пример: мы задали , . Получаем и . Новая дисперсия — . Эти же действия выполняет код примера в ноутбуке. При гауссовых ошибках можно получить тот же результат, умножив плотность прогноза на правдоподобие измерения: Обратная дисперсия здесь играет роль точности. Суть в том, что независимые сведения увеличивают её. Слово «независимые» существенно — два критика с общей ошибкой нельзя считать двумя независимыми измерениями. При произвольных распределениях вывод через квадратичную ошибку даёт оптимальное линейное смешивание. Один раунд в обозначениях кода Сначала переносим прежнюю оценку на ожидаемую величину фактически применённой правки . Дисперсию увеличиваем на — дисперсию ошибки исполнения: Затем рассчитываем и обновляем оценку по формулам выше. Регулятор использует невязку , где — цель. Сам фильтр величину правки не выбирает. В симуляторе , а . Для ручного счёта удобно округлить до . При начальном первый прогноз даёт , первое измерение — и . Начальная единица — это принятая фильтром неопределённость. Сам симулятор начинает каждый прогон точно с , а код добавляет уже перед первым измерением. Поэтому в начале расчётная не совпадает с фактической дисперсией ошибок по прогонам. Полоса на рисунке показывает именно расчёт фильтра. С повторением циклов влияние начальной настройки затухает, и приближается к стационарному значению. Для него Это дисперсия после измерения. Перед следующим измерением она снова вырастет примерно до , поэтому установившийся вес критика — около трети. Стандартное отклонение оценки получается около балла при согласованной модели. В сравнении раздела 3 досрочный стоп отключён. Позже, в конфигурации C раздела 5, будем проверять и . Там сначала выполняется очередная правка, затем по оценке, полученной до неё, решается, будут ли ещё раунды. Финальное качество проверяем отдельно по истинному состоянию симулятора. Именно поэтому расчётный стоп и попадание в заданный коридор — разные показатели. Для защиты от необычных отзывов в разделе 6 сравним модуль инновации с . Там складываются дисперсии ошибки прогноза и ошибки измерения. Более общий вывод и матричная запись есть в учебном отчёте Грега Уэлча и Гэри Бишопа, An Introduction to the Kalman Filter. Здесь достаточно одного состояния и приведённых скалярных формул. Дополнение к рис. 2. Светлая область — большой вес измерения, тёмная — малый. Точка отмечает установившуюся дисперсию прогноза перед измерением; после измерения дисперсия снова уменьшается. 3. Что даёт сам фильтр Калмана? Сравним в одинаковых условиях Самое интересное начинается тогда, когда работа уже приблизилась к своей цели. Один отзыв требует немного дописать, следующий — убрать примерно столько же. Агент исправно слушается, но часть этой суеты вызвана шумом критика и является лишней. Фильтр Калмана позволяет смешать новый отзыв критика с прогнозом и бороться с этим шумом. Давайте проверим на практике, что же это меняет в работе всего цикла. Поставим рядом два одинаковых P-регулятора: каждый исправляет 70% оценённого недобора до цели. Первый верит свежей оценке критика, второй — оценке фильтра Калмана. Стартовые условия, цель, последовательности ошибок и правило правки одинаковы. Меняем только способ оценки текущего состояния, чтобы отдельно проверить вклад фильтра. Проведём 200 пар прогонов по 30 раундов. Первые десять правок были отведены на подход к окрестности конечной цели, а показатели были рассчитаны на шагах 10–29. Что проверяем Что измеряем в каждом прогоне Лучше ли агент понимает, где находится Ошибку оценки: свежего отзыва без фильтра или оценки Калмана — относительно истинного состояния Лучше ли получается сам артефакт Отклонение истинного состояния от цели 10 Меньше ли агент переписывает Средний модуль фактически применённой правки Для первых двух строк далее использую RMSE: это среднеквадратическое отклонение. Результат снова измеряем в баллах, а большие промахи получают больший вес. Третья строка здесь измеряет активность правок; сама по себе маленькая правка ещё не означает хороший результат, поэтому смотрим на неё вместе с ошибкой артефакта. Затем для каждого показателя возьмём медиану по 200 прогонам. Но на рисунке оставим и все отдельные результаты, чтобы медиана не скрыла разброс. Три метрики, одинаковые шумы и точные условия опытаВ обоих режимах , , . Работает один критик. Дисперсия ошибки исполнения , стандартное отклонение ошибки критика , поэтому . Нет задержки, постоянной потери качества, выбросов, смещения критика и досрочной остановки. Начальная настройка фильтра та же, что в предыдущем подразделе: , . Пусть без фильтра и с фильтром. Для каждого прогона считаем Здесь — состояние после правок, до текущего измерения; — следующая применённая правка. Чтобы проверить условия парного опыта, восстанавливаем шумы из сохранённых траекторий: Во всех 200 парах обе последовательности совпадают с точностью до округления при вычитании чисел с плавающей точкой; проверка использует допуск . Один и тот же начальный seed сам по себе этого не гарантирует, если разные ветки программы по-разному расходуют случайные числа. Медианы считаем после расчёта метрик каждого прогона. Процент снижения в таблице ниже показывает относительное уменьшение этих медиан. Рис. 3. Что меняет сам фильтр при одинаковом P-регуляторе и одинаковых шумах. Точки — все 200 прогонов, линии соединяют пары с одним seed, тёмные отрезки — медианы. Метрики рассчитаны на шагах 10–29. Для ошибок меньше — точнее; третья панель показывает объём правок за шаг. Показатель: медиана по 200 прогонам Без фильтра С Калманом Снижение медианы RMSE оценки, баллы 0,528 0,303 42,5% RMSE состояния относительно цели, баллы 0,455 0,380 16,4% Средний модуль правки, баллы за шаг 0,388 0,128 67,0% Фильтр заметно улучшил оценку, но в самом артефакте выигрыш скромнее. Средний модуль правки сократился примерно втрое: цикл слабее реагировал на шум свежего отзыва. По парным результатам на рис. 3 ошибка состояния уменьшилась в 168 из 200 пар (84%), а в остальных 32 выросла. Здесь мы измеряли ошибки и величину правок при одинаковом числе раундов. Токены и вычислительные затраты в этой модели не учитывались, поэтому трёхкратное уменьшение правки нельзя переводить в трёхкратную экономию ресурсов. Результат относится к заданным шумам и конкретной модели исполнения. Интервалы для снижения трёх показателей таблицы собраны после раздела 5. 4. Почему одного фильтра недостаточно В парном опыте я заранее закрепил цель, выбрал правило правки и дал обоим контурам одинаковое время. Теперь надо посмотреть на все эти решения по отдельности. Дело в том, что даже точная оценка состояния не может определить, куда идти, как сильно править и когда закончить. Ниже проверю три распространённых упрощения: фиксированное число попыток, цель из последних замечаний и усреднение нескольких критиков. «Сделай три итерации и отдай» Начнём с очень простого правила, которое легко запрограммировать: три раунда правок и готово. Здесь заодно заменим пропорциональную правку фиксированной: прибавляем или убавляем по два балла в зависимости от знака невязки. Такое правило называют реле. Убираем временно шум. Если начинать с нуля и прибавлять по два балла, получится 0 → 2 → 4 → 6. Цель — десять, но цикл уже закончен. Таймер ограничивает затраты, но сам по себе не проверяет, выполнена ли задача. При выбранном старте трёх правок не хватит. Дрейф цели Представьте себе лендинг. Сначала требовалось кратко объяснить продукт. После первого ревью добавили подробности. После второго добавили больше эмоциональности. После третьего ревью добавили ещё один призыв к действию. В итоге каждая правка отвечает последнему замечанию, но исходная просьба о краткости уже потерялась. Такое часто происходит, когда итеративно что-то улучшаешь через ИИ. В модели позволим цели понемногу сдвигаться в случайную сторону каждый раунд. Даже если агент хорошо следует за текущей целью, это не гарантирует близости к исходной цели. При этом случайные сдвиги не обязаны всё время идти в одну сторону: отдельная траектория может вернуться назад, но разброс возможных целей со временем растёт. Проверим это отдельно: вернём уже знакомый P-регулятор с усилением 0,7 и фильтр Калмана, дадим им 30 раундов без ранней остановки. Между двумя режимами изменим только поведение цели — закреплённая или блуждающая. Ошибку посчитаем относительно исходного заказа, чтобы не перепутать следование за новой целью с выполнением старой. Почему разброс блуждающей цели растёт как корень из времениПусть каждый шаг добавляет независимый сдвиг с нулевым средним: За шагов складываются таких сдвигов. Их дисперсии складываются, поэтому стандартное отклонение итогового ухода равно . Для нормальной величины медиана её модуля составляет примерно стандартного отклонения: В опыте . За 30 шагов получаем прогноз масштаба ухода цели: Это расчёт для самой цели. Ошибка конечного артефакта дополнительно зависит от того, насколько точно контур за ней следовал. Рой ИИ-агентов: согласие критиков ещё не означает точность Теперь попробуем улучшить измерение: спросим пятерых критиков и усредним ответы. Если один завысил оценку, а другой занизил, ошибки частично сократятся. Но представьте себе, что артефакт находится на восьми баллах, а все пятеро дружно ставят девять. Среднее тоже будет девять. Единодушие арифметику не исправило. Возможная причина — общая часть ошибки. Критики могут опираться на одни и те же признаки и вместе пропускать один недостаток. В нашем опыте это общий случайный шум: в одном раунде он тянет всех вверх, в другом — вниз. Постоянного завышения шкалы здесь пока нет. Сравним два роя из пяти критиков: с независимыми ошибками и со скоррелированными. На рисунке сила связи (корреляция) обозначена буквой ρ: ноль соответствует независимым ошибкам, 0,8 — сильной общей части шума. Измерим отдельно разброс их мнений и ошибку среднего мнения относительно истины. Первое говорит, насколько критики согласны; второе — насколько им можно верить. Рисунок 4 показывает, почему эти показатели нельзя подменять друг другом. Что усреднение убирает из независимого и общего шумаУ каждого критика дисперсия ошибки . Если ошибки независимы друг от друга, то у среднего из оценок дисперсия в раз меньше, а стандартное отклонение — в раз. Для пяти критиков это выигрыш примерно в 2,24 раза в единицах стандартного отклонения. Введём одинаковую попарную корреляцию . В нашей реализации она задаёт долю дисперсии, приходящуюся на общий для всех критиков шум. При усреднении остаётся Независимая часть уменьшается с числом критиков; общая остаётся. При и усреднение сохраняет исходной дисперсии — большой прибавки точности ждать не приходится. Одновременно разброс между критиками становится меньше: общий сдвиг не создаёт разногласий. При переходе от к масштаб этого разброса сокращается в раза. Итак, у нас три отдельных проверки: хватило ли таймера, сохранилась ли цель стало ли среднее мнение точнее. На анимации 1 — отдельные иллюстрации метаний, дрейфа и общей ошибки критиков. Затем посмотрим на количественные сравнения — по 200 прогонов на режим. Анимация 1. Три отдельные иллюстрации: метания реле, дрейф цели и общая ошибка критиков. В первой панели реле работает 40 раундов с потерей 0,3 балла за раунд — это не трёхшаговый таймер. В третьей иллюстрации всем критикам задана постоянная прибавка +1,5: среднее колеблется около 11,5 при истине 10. В опыте с роем ниже проверим другую причину согласия — общий случайный шум без постоянного смещения. Рис. 4. Слева: при переходе от ρ=0 к ρ=0,8 разброс мнений падает примерно в 2,24 раза. Справа: ошибка среднего мнения при этом растёт — общий шум усреднением не убирается. Каждая коробка показывает распределение показателя по 200 прогонам. Общий шум имеет нулевое математическое ожидание; постоянного смещения в этом опыте нет. Что показали прогоны Блуждающая цель увела от исходного заказа. После 30 раундов медианная ошибка артефакта относительно первоначальной цели составила 1,1 балла, девяностый перцентиль — 2,66: около 90% результатов оказались ниже этого порога. При закреплённом эталоне тот же контур дал медиану 0,29. Здесь была измерена ошибка артефакта относительно исходной цели. В рое ИИ-агентов стало больше согласия, но точность снизилась. Сравнение двух режимов на рисунке 4: Что измеряем Независимые ошибки Корреляция 0,8 разброс мнений между критиками 0,44 0,20 ошибка среднего мнения относительно истины 0,17 0,33 Для каждого прогона брали медиану по раундам после первых пяти, затем — медиану по 200 прогонам. Для ориентира: у одиночного критика с таким шумом медианная абсолютная ошибка одного измерения — около 0,37 балла. Общий шум резко уменьшил пользу усреднения: медианная ошибка среднего выросла с 0,17 до 0,33 балла. При этом она осталась немного ниже ориентира для одиночного критика — около 0,37. Согласие критиков само по себе не подтверждает точность их оценки. 5. Четыре конфигурации на полигоне: фильтр, правка и остановка Сравниваем результаты Давайте проверим две вещи: насколько близко цикл попал к цели и сколько правок ИИ-агентов он на это потратил. На стенде у всех одинаковый старт — ноль, цель — отметка 10. В базовой модели нет постоянных потерь и ограничений правки. Каждую конфигурацию запускаем 200 раз. На каждой итерации цикла изменялись случайный шум критика и исполнения, а правила работы оставались одними и теми же. Конфигурация Как правит Как оценивает Когда заканчивает A. Таймер по два балла в нужную сторону один критик после трёх правок B0. Независимый рой так же, как A среднее пяти независимых критиков после 9, 10 или 11 правок B8. Похожий рой так же, как A среднее пяти критиков с общей частью шума после 9, 10 или 11 правок C. Наблюдатель исправляет 70% оценённой ошибки один критик и фильтр Калмана когда оценка близка к цели и достаточно определённа; не позднее 30 правок Для каждого роя были проверены три соседних срока остановки. Между ними изменялся только таймер. Финальная ошибка — расстояние между полученным результатом и десяткой. Ошибку больше одного балла считаем провалом; отдельно посмотрим на более строгий коридор ±0,5. Усилие — весь объём правок: шаг на два балла вперёд и два назад стоит четыре балла усилия, даже если в итоге мы остались на месте. Контур C использует тот же фильтр и правило 70%, что в парном опыте, но теперь может закончить работу раньше. Для остановки проверяем две вещи: оценка близка к цели, а её расчётная неопределённость достаточно мала. Порядок такой: получили оценку, выполнили рассчитанную по ней правку и решили, нужен ли ещё раунд. На рис. 5 сравним все три срока остановки роя с контуром C: слева — типичную ошибку и разброс результатов, справа — долю провалов. На рис. 6 увидим невязку, по которой цикл выбирает действие, и отметим последние измерения перед каждой из трёх остановок. Все пять метрик и условия сравненияЗдесь собраны определения для сверки с кодом и полной таблицей ниже. Метрика Что считает код final_err : абсолютная ошибка финального состояния mean_abs_y среднее после первых пяти раундов; после остановки архивный хвост заполнен истинной финальной ошибкой flips число смен знака невязки после скользящего усреднения по трём точкам effort : сумма модулей фактически применённых правок rounds_stable число выполненных правок до первого состояния, начиная с которого до конца прогона; поиск с начала flips считает смены знака невязки после её скользящего усреднения по трём точкам. mean_abs_y включает замороженный участок после остановки. Настройки B0 и B8: пять критиков, корреляция ошибок и . В C используется . Стоп проверяет и . При наших шумах первое условие выполняется уже после первого измерения, поэтому время остановки фактически задаёт близость оценки к цели. Числа в таблицах — медианы по 200 прогонам. SD — стандартное отклонение ошибок между прогонами. Доли провалов и попаданий рассчитаны по всем 200 прогонам. Рис. 5. Все три срока остановки роя рядом с контуром C, по 200 прогонов на строку. Слева точка — медианная финальная ошибка, отрезок — диапазон от 5-го до 95-го процентиля; крайние 10% результатов на нём не показаны. Это разброс прогонов, а не доверительный интервал медианы. Пунктир — ошибка в один балл. Справа — доля прогонов с ошибкой больше балла. B0 — независимые критики, B8 — с общей частью шума. C останавливается по оценке, медиана — четыре правки. Среди проверенных сроков оба роя лучше заканчивают после девятой правки. Рис. 6. Модуль невязки перед очередной правкой: для A и B это |r−z|, для C — |r−x̂|. У каждого роя путь до более раннего стопа одинаков для всех трёх сроков, поэтому показана одна линия. Кружки B0 и ромбы B8 отмечают последние измерения перед 9-й, 10-й и 11-й правками; финальный результат после этих правок показан на рис. 5. В каждый момент медиана считается только по ещё работающим прогонам; их состав меняется. После остановки измерений нет, поэтому линия заканчивается. Полная таблица метрик и точные определенияКонфигурация Финал: медиана (SD) Среднее |y| после прогрева Смены знака сглаженной невязки Усилие, баллы Провалов, % Остановка, правок Строгий коридор ±0,5 A: таймер 3 раунда 4.01 (0.37) 4.01 0 6.0 100.0 3 0% B0: рой, ρ=0, 9 раундов 0.48 (0.39) 0.58 2 18.0 13.5 9 51.5% (с 9) B0: рой, ρ=0 1.47 (0.49) 1.36 2 20.0 82.0 10 3.5% (с 10) B0: рой, ρ=0, 11 раундов 0.51 (0.43) 0.64 2 22.0 20.0 11 48.0% (с 11) B8: рой, ρ=0.8, 9 раундов 0.48 (0.48) 0.59 2 18.0 14.0 9 51.5% (с 9) B8: рой, ρ=0.8 1.51 (0.57) 1.41 2 20.0 83.5 10 3.5% (с 10) B8: рой, ρ=0.8, 11 раундов 0.51 (0.52) 0.68 3 22.0 20.0 11 48.0% (с 11) C: наблюдатель 0.29 (0.24) 0.29 0 9.9 1.0 4 80.5% (с 3) SD — стандартное отклонение ошибок по прогонам. Невязка сглаживается средним по трём точкам. После остановки её архивный хвост — истинная ошибка; новых измерений критика там нет. Строгий коридор означает до конца, а провал — финальную ошибку больше 1. В скобках в колонке коридора — медиана числа выполненных правок до входа среди вошедших прогонов. Что показал полигон Конфигурация Правок до стопа Финальная ошибка Провалов, % Объём правок Таймер A 3 4,01 100 6 Рой B0 9 0,48 13,5 18 Рой B0 10 1,47 82 20 Рой B0 11 0,51 20 22 Рой B8 9 0,48 14 18 Рой B8 10 1,51 83,5 20 Рой B8 11 0,51 20 22 Контур C 4 0,29 1 9,9 Таймер остановил работу по расписанию. Три шага по два балла привели примерно к шести при цели десять. На этой дистанции ему не помогла бы более точная оценка: шагов просто не хватило. Один лишний раунд может испортить результат. После девяти правок оба роя заметно ближе к цели, чем после десяти; одиннадцатый снова уменьшает ошибку. Причина видна даже без шума исполнения: за десять полных шагов ±2 из нуля до отметки 10 вообще не добраться — ближайшие доступные состояния будут 8 и 12. После девяти или одиннадцати шагов десятка доступна. Контур C дошёл и остановился с меньшим объёмом переписывания. В 165 из 200 прогонов стоп наступил после четвёртой правки. Ошибка больше балла осталась в двух прогонах; в строгий коридор ±0,5 попал 161 результат, то есть 80,5%. При этом траектория не обязана быть монотонной: хотя бы один выход выше цели случился в 45% прогонов. Выводы В этой выборке из трёх проверенных сроков рою выгоднее закончить после девятой правки. Но и по сравнению с этим вариантом у C ниже медианная финальная ошибка и доля провалов, а объём правок меньше. Преимущество C по этим показателям сохранилось при всех трёх сроках. В C одновременно изменились регулятор, обработка измерений и правило остановки. Поэтому здесь сравниваются конфигурации целиком. Отдельный вклад фильтра проверялся в парном опыте раздела 3, где остальные условия были одинаковыми. Насколько точны проценты: интервалы по 200 прогонамПроценты изменятся на другом наборе шумов. Эти приближённые 95% доверительные интервалы уточняют снижение метрик раздела 3 и доли провалов раздела 5. Что дал сам фильтр (раздел 3). Показатель Снижение, % 95% интервал, % RMSE оценки 42,5 40,3–45,8 RMSE состояния 16,4 13,8–20,7 Средний модуль правки 67,0 66,1–67,8 Как часто цикл заканчивается провалом (раздел 5). Порог прежний: финальная ошибка больше балла. Конфигурация Провалов из 200 Доля, % 95% интервал, % Таймер A, 3 правки 200 100,0 98,1–100,0 Рой B0, 9 правок 27 13,5 9,4–18,9 Рой B0, 10 правок 164 82,0 76,1–86,7 Рой B0, 11 правок 40 20,0 15,0–26,1 Рой B8, 9 правок 28 14,0 9,9–19,5 Рой B8, 10 правок 167 83,5 77,7–88,0 Рой B8, 11 правок 40 20,0 15,0–26,1 Контур C 2 1,0 0,3–3,6 У C всего два провала: частоту столь редкого события по 200 прогонам трудно определить точно. Интервалы описывают неопределённость оценок; отрезки на рис. 5 — разброс отдельных прогонов. Как посчитано. Для фильтра использовался парный percentile bootstrap: 10 000 раз выбирались с возвращением 200 пар, не разрывая пары с одинаковыми шумами. Каждый раз считалось прежнее снижение ; границы — процентили 2,5 и 97,5. Seed — 20261022, участок — 10–29. Для долей провалов — двусторонний интервал Уилсона. 6. Что будет, если сломать допущения: добавим выбросы, задержки и смену шкалы Теперь давайте по очереди испортим отзыв критика, момент применения правки и саму шкалу оценок. Оставим знакомые фильтр Калмана и P-регулятор с усилением 0,7. Во всех опытах этого раздела остановка отключена: каждый прогон длится 30 раундов. Иначе контур обычно закончил бы работу после четвёртой правки, и мы не увидели бы поздние сбои — например, смену шкалы на шаге 15. Что происходит, когда один отзыв требует переписать почти всё Представьте себе такую ситуацию: работа уже близка к цели, и вдруг критик ставит на четыре балла меньше ожидаемого. Регулятор видит большой недобор и готовит большую правку. Но что именно испортилось — сама работа или сам новый отзыв? Обычный фильтр Калмана смягчает такой скачок, но всё же сдвигает оценку вслед за критиком. В нашем установившемся режиме он берёт примерно треть расхождения. Если измерение ошибочно упало на 4,4 балла, оценка сдвинется примерно на полтора — достаточно для того, чтобы агент начал чинить то, что не ломалось. Давайте добавим перед обновлением оценки простую проверку. Сравним отзыв с прогнозом и спросим, насколько их расхождение необычно при знакомом нам шуме. Напомню, что саму разность между измерением и прогнозом называют инновацией. Слишком далёкую точку пока не используем: фильтр оставит прогноз без коррекции. Такая проверка называется гейтом. Она позволяет переждать подозрительное измерение, не превращая его сразу в команду на переделку. В опыте каждый отзыв независимо получал выброс с вероятностью 10%: к обычному шуму добавили сдвиг на 4,4 балла вверх или вниз. Я сравнил три режима на 200 прогонах каждый. Для каждого прогона взял максимальную истинную ошибку после десятой правки и разброс качества в последних десяти состояниях. В таблице собраны медианы этих величин; отдельно показан 90-й перцентиль пика ошибки. Режим Медиана пика ошибки 90-й перцентиль пика Медиана разброса в конце Без выбросов 0,77 1,06 0,27 Выбросы, без гейта 1,38 2,02 0,43 Выбросы, с гейтом 0,77 1,10 0,27 Без защиты медианный пик вырос примерно в 1,8 раза, разброс в конце вырос в 1,6. С гейтом значения вернулись близко к базовым: отдельный странный отзыв перестал так сильно раскачивать артефакт. На рис. 7 видны хвосты распределения инноваций. На рис. 8 показана разница между этими тремя режимами. В среднем гейт отбросил 3,00 измерения за прогон при округлении до сотых. Это близко к ожидаемым трём выбросам за 30 раундов, но по одному совпавшему числу нельзя судить о качестве распознавания. Оказалось, что гейт иногда отвергает и нормальный отзыв критика. Отказ приводит также к тому, что без свежего измерения оценка опирается только на прогноз, и вследствие этого её неопределённость растёт. Один пропуск переносится легко, но серия пропусков может значительно увеличить неопределенность оценки. Поэтому в рабочем процессе полезно сохранять отвергнутые отзывы для разбора и следить за сериями отказов. Как часто появятся выбросы за несколько раундовПри независимой вероятности выброса в каждом из раундов проще сначала посчитать шанс, что ни одного выброса не случится: поэтому За тридцать раундов нашего опыта получаем То есть хотя бы один выброс ожидается примерно в 96% прогонов. Среднее число выбросов равно . Откуда берётся порог гейта и почему он иногда отсекает честный шумИспользуем инновацию — разность между новым измерением и прогнозом до коррекции: Если ошибки прогноза и текущего измерения независимы, их дисперсии складываются: В рассматриваемой реализации измерение не используется для коррекции, когда После прогрева , , поэтому порог составляет около 2,0 балла. Сдвиг на восемь стандартных отклонений шума критика — балла. При пропуске коррекции дисперсия прогноза продолжает расти, так что фактический порог на следующем шаге тоже может увеличиться. У обычного фильтра Калмана с согласованной гауссовой моделью нормированная инновация имеет стандартное нормальное распределение. Вероятность выйти за три стандартных отклонения составляет около 0,27% на одно измерение. Даже нормальный шум иногда пересекает этот порог. После отбора по гейту распределение ошибки меняется, а наш простой фильтр этого изменения полностью не учитывает. Поэтому 0,27% — лишь приблизительный ориентир для выбора порога. Лучший выбор порога нужно проверять на отдельных прогонах без выбросов. Рис. 7. Гистограмма инноваций за 200 прогонов: основная масса честного шума (синий) лежит внутри ±3√(P⁻+R)≈±2,0. Выбросы увеличивают хвосты (красный); показан полный диапазон обеих выборок. Линии обозначают порог после прогрева, а реальный гейт использует текущую P⁻. Обычный шум тоже может оказаться за порогом. Рис. 8. С гейтом медиана и 90-й перцентиль пика ошибки составляют 0.77/1.10 балла — близко к базе 0.77/1.06. Без гейта при выбросах получаем 1.38/2.02; цена — в среднем 2.995 отброшенных измерения на прогон. Это число включает и ложные отсечения честного шума, поэтому его нельзя отождествлять с долей выбросов. Задержка отклика: к чему это приводит Предположим, до цели не хватает четырёх баллов. При усилении 0,7 получаем прибавку 2,8. Но правка ещё не применена, а следующий отзыв уже пришёл: всё те же четыре балла недобора. Тогда агент заказывает ещё 2,8. Обе правки исправляют одну и ту же старую проблему — вместе они добавят 5,6 вместо недостающих четырёх. Даже без всякого шума возникла проблема. Такое случается, когда новые решения принимаются быстрее, чем прежние успевают изменить артефакт. Первая пачка правок наконец приходит, контур видит перелёт и отправляет пачку в обратную сторону. Чем длиннее очередь, тем сильнее запаздывает реакция. Такое случается в работе роя ИИ-агентов. В тренировочном симуляторе ниже задержка означает вполне конкретную вещь: команда, выданная сейчас, применяется через заранее заданное число раундов. Давайте сохраним усиление 0,7 и сравним четыре задержки, по 200 прогонов на каждую. Рядом с результатами зададим расчётный ориентир для более простого случая: P-регулятор точно знает состояние, шума и фильтра нет. Во втором столбце — верхняя граница усиления: при положительном коэффициенте ниже неё ошибка со временем затухает; на самой границе затухание исчезает. Задержка, раундов Граница усиления для чистого P-контура Медианная финальная ошибка Разброс: середина → конец 0 2,00 0,29 0,26 → 0,27 1 1,00 0,40 0,88 → 0,40 2 0,62 31,89 12,6 → 19,8 3 0,45 31,17 25,6 → 63,6 Аналогично прошлым экспериментам разброс оцениваем через стандартное отклонение, а для оценки значения берем медиану по 200 прогонам. При задержке в один раунд колебания от середины к концу уменьшаются. При двух и трёх — растут, а финальная ошибка измеряется уже десятками баллов. На рис. 9 это видно по паре соседних состояний: по одной оси отложено текущее качество, по другой — предыдущее. В показанном прогоне с задержкой в один раунд траектория стягивается к окрестности цели; с задержкой в два — раскручивается наружу. Добавили очередь — заново проверьте усиление. В симуляции при задержке в два раунда значение 0,7 оказалось слишком большим. Можно уменьшить размер очередной правки или сократить задержку. Можно дождаться результата уже выданной команды перед новым решением. Это изменяет темп работы, зато не позволяет нескольким правкам независимо исправлять один и тот же недобор. Почему задержка уменьшает допустимое усиление: вывод через корни уравненияДля расчётов уберём шум и наблюдателя, оставим постоянную цель и чистый P-регулятор. Обозначим истинную ошибку через . Команда, выданная шагов назад, равна и применяется сейчас. Тогда Ищем решение в виде . Получаем характеристический многочлен Колебания затухают, если все его корни лежат внутри единичного круга: тогда степени каждого корня со временем уменьшаются. При малом положительном это условие выполняется. Найдём границу, на которой корень впервые выходит на единичную окружность. Подставим и перенесём члены: Усиление должно быть положительным вещественным числом. Для первого пересечения аргумент справа равен нулю: По модулю получаем границу Следовательно, область асимптотической устойчивости этого линейного уравнения — При получаем условие для контура без задержки. Для задержек , и верхние границы равны соответственно , и . При больших задержках можно использовать : Отсюда почти обратная зависимость допустимого усиления от задержки. Равенство на границе не даёт затухания, поэтому запас имеет практический смысл. Рис. 9. Два прогона с усилением 0,7: при d = 1 (seed 189) колебания стягиваются к окрестности цели; при d = 2 (seed 46) — нарастают. Показаны все 30 пар соседних состояний, общие квадратные пределы охватывают обе траектории целиком. Цвет обозначает число выполненных правок. Это иллюстрации движения; сравнение по 200 прогонам приведено в таблице. Критик стал добрее, а работа — хуже Представьте себе, что критика заменили на более дружелюбного. Тот же артефакт без единой правки получает на три балла больше. Нам приятно, но регулятор видит перелёт относительно цели и начинает уменьшать качество. Регулятор принимает завышенную оценку за реальное превышение цели и заказывает ненужные правки вниз. Введем в симуляции такую прибавку, начиная с шага 15. Наблюдатель поднимает оценку состояния, регулятор правит артефакт вниз, и спустя несколько раундов показания снова оказываются около десяти. Истинное качество при этом находится около семи. Медианная финальная ошибка — 3,00 балла. Фильтр объясняет новые отзывы доступным ему способом — изменением состояния. В модели фильтра нет переменной, описывающей сдвиг шкалы критика. Поэтому наблюдатель приписывает этот сдвиг изменению артефакта, а регулятор на основании смещённой оценки вносит ненужные правки. После адаптации расхождения между прогнозом и измерениями снова выглядят обычными, хотя оценка и истина теперь разделены примерно тремя баллами. При этом одного этого потока отзывов критика явно недостаточно, чтобы уверенно отличать смену шкалы от реального изменения артефакта. Замечаем смену режима, пока фильтр к ней не привык Сразу после сдвига остаётся лишь короткая подсказка: несколько измерений подряд приходят выше прогноза. Чтобы решить проблему, нужно следить за такими сериями. Одна высокая оценка может быть случайностью; три последовательных отклонения в одну сторону, достаточно большие в сумме, уже повод проверить, что же изменилось. Добавим детектор, который записывает тревогу при такой серии. Проверим его в 200 прогонах со сдвигом и отдельно в 200 прогонах без сдвига, чтобы узнать долю ложных сигналов. Настройка детектора Обнаружен сдвиг Медианная задержка обнаружения Ложные срабатывания без сдвига Основная 95,5% 2 раунда 1% Более строгая 94,5% 2 раунда 0% Основная настройка обнаружила сдвиг в 191 из 200 прогонов. Более строгая пропустила ещё два случая, зато в контрольной выборке ложных тревог не было. Задержка в таблице посчитана среди прогонов, в которых сработал детектор. В рабочем процессе такой сигнал можно использовать, чтобы приостановить автоправки и проверить рубрику на сохранённых артефактах или запросить независимую оценку. По самой серии инноваций мы ещё не знаем причину: мог измениться критик, артефакт или точность нашей модели правок. На рис. 10 показан отдельный прогон, где есть и одиночные выбросы, и сдвиг шкалы. Здесь сдвиг введён на шаге 18 и включён гейт; это иллюстрация двух механизмов вместе, а не один из опытов таблицы. Ранний подозрительный замер гейт отбрасывает. После смены шкалы появляется серия отклонений одного знака, и детектор подаёт сигнал. Пунктир показывает текущий порог гейта: без коррекции неопределённость растёт, поэтому меняется и порог. Такая запись помогает выбрать, что проверять дальше, но сама по себе не исправляет шкалу критика. Как устроены сдвиг шкалы и правило тревоги по трём инновациямИзмерение в опыте имеет вид После приспособления к новой шкале оценка фильтра оказывается около . Поэтому регулятор, стремящийся удерживать оценку около цели , приводит истинное состояние примерно к . Шум сохраняется, так что речь идёт об окрестности этого значения, а не о точном положении каждого прогона. Для детектора использовались инновации до обновления фильтра: Сигнал возникает, если последние три инновации имеют один строгий знак и одновременно В основной настройке , в более строгой — . После прогрева , поэтому основной порог для суммы трёх инноваций составляет около четырёх баллов. Проверка знака требует, чтобы все три значения были положительными либо все три отрицательными. В коде хранится момент первого сигнала. Детектор не добавляет в фильтр оценку смещения , не исправляет измерения и не останавливает регулятор. Для этих действий требуется отдельное решение о том, что именно изме

  2. This guy created an AI that willingly tracks the pneumonic plague? It's called Russian Plague Tracker We've had larp trackers that were just slop run really high but this guy is giga clouted Sending all fees to his git github.com/mshumer t.co

    52 views
  3. @mattshumer_ is this ur github github.com/mshumer

    3 likes · 483 views

Achievements

Awards earned by the repositories mshumer owns. Select an award to embed its badge.

Gold
01st place finishes
Silver
12nd place finishes
Bronze
23rd place finishes
Awarded repositories
2Owned by mshumer now

Repositories

Ordered by gold, then silver, then bronze.

  1. gpt-prompt-engineerBest: 2nd by stars, 1,000 stars011
  2. gpt-investorBest: 3rd by stars, 544 stars001

Every award

Top-three finishes of these repositories in completed trending days and weeks, newest first.

  1. gpt-investor
  2. gpt-prompt-engineer
  3. gpt-prompt-engineer

A repository earns an award for finishing first, second or third in a completed trending day or week, ranked by new stars, new forks or pull request authors. Awards follow a repository through renames and transfers and count toward its current owner. Weeks run Monday to Sunday, UTC.