Как взвесить чужой репозиторий, не запуская его: 138 проектов из трендов GitHub

в 13:03, , рубрики: github, open source, python, анализ кода, ии-агенты, лицензии

Каждое утро мне приходит дайджест трендов GitHub про ИИ-агентов. Скиллы, обвязки, MCP-серверы, очередные «замены» чему-нибудь. За месяц набралось 138 уникальных репозиториев, и часть из них я отложил с пометкой «попробовать». Потом решил проверить, что именно откладываю. Оказалось, по описанию этого не понять почти никогда.

Сначала я рассортировал первые 40 по строчкам из дайджеста. Затем посчитал в них код. 25 из 40 оказались платформами, хотя в ленте выглядели как небольшие штуки, на которые стоит глянуть. Самый наглядный случай: репозиторий, который подаётся как скилл для рисования диаграмм. Инструкция для модели там занимает 137 строк. Под ней лежат 35 245 строк собственного рендерера и 37 047 строк тестов.

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

Что и как мерил

Лента за 34 дня, с 15 августа по 17 сентября 2026 года. Из 138 репозиториев 123 я скачал и взвесил. Ещё 10 весили больше 250 МБ каждый, их я не скачивал: размер здесь сам по себе ответ. Пять к моему приходу уже удалили с GitHub.

Ничего из этого я не запускал. Архив ветки по умолчанию забирается одним запросом к API GitHub, без git clone и без установки зависимостей. Потом скрипт на Python считает строки. Больше в методе ничего нет, и так задумано: у кода, который ты ещё не прочитал, не должно быть шанса выполниться.

Считаю отдельно четыре вещи. Код: всё, что исполняется. Прозу: Markdown, текстовые инструкции, промпты. Тесты: по путям и именам файлов. И сгенерированный код, который человек не писал: zz_generated, *.pb.go, _pb2.py, *.gen.ts и похожие файлы.

Класс репозитория определяется соотношением этих чисел. Если прозы хотя бы вдвое больше, чем кода, и кода меньше 2000 строк, продукт этого репозитория и есть текст. Инструкции для модели, а код рядом служит клеем. Такое я называю промпт-классом. Остальное делится по объёму кода:

Класс

Порог

Что это значит на практике

промпт-класс

прозы вдвое больше кода при коде до 2000 строк, или код до 400 строк

продукт состоит из текста, пересобирается за вечер

небольшой

код до 3000 строк

читается целиком за один присест

средний

код до 20 000 строк

целиком не прочитать, но можно понять и встроить

платформа

код от 20 000 строк

форк означает сопровождать чужую живую кодовую базу

Пороги грубые намеренно. Им нужно развести три решения: «перепишу сам», «подключу как есть» и «не трогаю». Точность до строки для этого не нужна.

Сгенерированный код чуть не испортил замер

На середине прохода один репозиторий показал 2,12 миллиона строк кода. Я полез смотреть, откуда столько. 521 227 строк выдал генератор, а один-единственный файл занимал 136 419 строк. Такое никто не пишет руками и не поддерживает, это вывод инструмента. После этого сгенерированный код стал считаться отдельно от написанного.

Любопытно другое: исправление не перевело ни один репозиторий из класса в класс. Числа стали честнее, вердикты остались на месте. По этому и видно, что правка чинила точность и ничего не подгоняла под желаемый ответ.

Ещё две вещи, о которые спотыкается любой такой подсчёт. Тесты надо держать в своей колонке. У stablyai/orca 2 036 238 строк кода и 2 463 575 строк тестов, и если их сложить, репозиторий на бумаге станет вдвое толще, чем его продукт. Jupyter-блокноты я считаю файлами, без строк: .ipynb хранит в одном JSON код, текст и вывод в base64, и число строк в нём ничего не значит.

Была и совсем бытовая ошибка. Цикл while read по списку репозиториев молча пропустил последнюю строку, потому что в конце файла не было перевода строки. Прошло 39 из 40, и скрипт отчитался об успехе. Теперь я сверяю число результатов с числом входов, прежде чем смотреть на сами результаты.

Что оказалось в трендах

Класс

Сколько

платформа

67

средний

32

промпт-класс

15

небольшой

9

не скачан, больше 250 МБ

10

удалён с GitHub

5

Если добавить к платформам десять нескачанных гигантов, среди которых NationalSecurityAgency/ghidra и sgl-project/sglang, выходит 77 из 138. Это 56 %. Больше половины того, что за месяц мелькнуло в трендах как «интересная штука для агента», на деле оказывается кодовой базой, которую форкают только с намерением её сопровождать.

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

Лёгких, то есть промпт-класса и небольших, всего 24. Половина из них вообще не инструменты: списки ссылок, чьи-то заметки и одна шутка из одной строки кода. Переносимых скиллов, которые правда можно взять и переписать под себя, в месяце трендов я насчитал меньше десяти.

Несколько лёгких для масштаба, звёзды на момент замера:

Репозиторий

Строк кода

Строк прозы

Звёзд

latent-spaces/brag

525

2 121

4 937

mattpocock/skills

478

7 090

265 313

blader/humanizer

87

626

49 971

VoltAgent/awesome-design-md

0

41 012

116 573

У mattpocock/skills 265 тысяч звёзд на 478 строк кода. Упрёка здесь нет: у промпт-класса продукт и есть текст, и текст там хороший. Просто решение «поставить себе» и решение «прочитать и забрать идеи» для такого репозитория разные, а звёзды их никак не различают.

Кому принадлежит движок под промптом

Разницу между «поставить» и «забрать идею» хорошо видно на паре репозиториев, которые снаружи выглядят одинаково.

latent-spaces/brag делает промо-ролики о вашем проекте. Его главная инструкция занимает 173 строки. Собственного кода продукта там ноль. 525 строк, которые счётчик записал в код, это необязательный скрипт разметки музыки, линтер для собственной документации и сайт проекта. Каждый рендер уходит в npx hyperframes, то есть в чужой движок.

tt-a1i/archify рисует диаграммы архитектуры. Это тот самый скилл из начала статьи: инструкция на 137 строк, почти того же размера. Под ней 35 245 строк своего рендерера, 37 047 строк тестов и пять JSON-схем.

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

Что делать с промпт-классом, если идея нравится? Переписать под себя, это вечер работы. Так у меня из blader/humanizer получился линтер slopcheck. humanizer это промпт, который просит модель переписать текст без следов ИИ. Мне нужно было другое: проверка без модели и без сети, которая только читает текст и возвращает код ошибки. Такую можно поставить в CI.

Первая версия моего линтера нашла в README самого humanizer 17 жёстких нарушений. Я почти опубликовал эту иронию, но сначала проверил находки глазами. Все 17 оказались цитатами. README показывает примеры «было и стало», и плохие примеры стоят там нарочно. Любой документ, который обсуждает приметы ИИ-текста, загорается ложно. Когда цитаты, таблицы и код стали исключаться из проверки, тот же README дал ноль находок, и ноль здесь правильный ответ. Мораль общая для любого измерителя: сначала прогони его на случае, ответ для которого знаешь заранее.

Лицензия оказалась первым фильтром

Я ждал, что главным фильтром будет вес. Оказалось, что раньше веса стоит смотреть лицензию.

Что разрешает лицензия

Репозиториев

можно брать код: MIT, Apache, BSD, общественное достояние

102

копилефт: AGPL, GPL, LGPL

14

исходники открыты, но с ограничениями на использование

5

файла лицензии нет вообще

9

слабый копилефт, MPL-2.0 с условиями на уровне файла

1

не проверено: удалены или не скачаны

7

Без файла лицензии права по умолчанию остаются у автора. Код можно читать, копировать нельзя. В эту строку попала, например, ripienaar/free-for-dev со 137 746 звёздами, известная подборка бесплатных сервисов для разработчиков.

Потом я открыл графу, которую обычно пропускают. Для 19 репозиториев GitHub не смог определить лицензию: API вернул NOASSERTION или пустое поле. Я прочитал все 19 файлов. Одиннадцать оказались обычными MIT или Apache с изменённой шапкой. Три оказались AGPL. Оставшиеся пять открывают исходники, но ограничивают использование: Fair Source, Elastic License 2.0, PolyForm, самописный текст с требованием письменного разрешения и ещё один случай, о котором ниже. Итого из 19 «неопознанных» брать нельзя 8.

Этот последний файл стоит запомнить отдельно. Первая строка в нём говорит MIT. Ниже дописан запрет на коммерческое использование. Такой файл уже не MIT, но сканер лицензий, который читает первую строку или доверяет API, отметит репозиторий как свободный. Это bilawalsidhu/gods-eye-view: 218 774 строки кода и почти 38 тысяч звёзд.

И ещё один случай для коллекции. elder-plinius/CL4R1T4S собирает утёкшие системные промпты чужих продуктов и выложен под AGPL. Автор накладывает копилефт на тексты, которые писал не он.

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

Три признака накрутки, которые не сработали

По ходу разбора я пометил на глаз десять репозиториев как подозрительные, не открывая их. Картина была из трёх частей: свежий аккаунт, имя известного продукта в названии и звёзды, которые растут быстрее, чем их можно честно заработать. Через сутки пять из десяти исчезли с GitHub. Судя по названиям, это были майнер, «бесплатные» сборки Acrobat и Total Commander, некий «оптимизатор» и панель, назначение которой я так и не успел увидеть.

Удаления вроде бы подтвердили чутьё, и следующий шаг напрашивался: превратить картину в автоматическую проверку. Я проверил каждый признак на 28 нормальных репозиториях, которые уже разобрал вручную, против пяти помеченных, которые ещё живы.

Скорость звёзд не разделяет. 24 из 28 нормальных растут быстрее, чем самый медленный из помеченных. Быстрее всех во всём наборе рос browser-use/jev-ultrafast, около 3 244 звёзд в день, и это настоящий проект известной команды.

Возраст аккаунта разделяет наоборот. У помеченных аккаунты старше: медиана 2 340 дней против 658 у нормальных. Несколько честных проектов живут в организациях, которые созданы позже самого репозитория.

Заимствованное имя продукта угадывает в половине случаев. Признак срабатывает на 12 из 138 и прав примерно в шести. Среди обвинённых openai/codex и deepseek-ai/deepseek-harness, то есть сами владельцы этих продуктов.

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

Позже нашлось и объяснение, почему возраст врёт. vastsa/PI-Desktop создан в 2023 году, а продукт в нём 2026-го. Возраст тоже заимствуется: старый репозиторий перепрофилируют под свежий продукт, и дата создания начинает работать на доверие.

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

Итог скромнее, чем хотелось. Проверки на накрутку нет, и я её не выпустил. Надёжный сигнал один, удаление. Он приходит через сутки и уносит с собой улики: ни у одного из пяти удалённых в моих данных нет даже числа звёзд, потому что к приходу скрипта страницы уже отдавали 404.

И ещё одна невидимая вещь. За месяц шесть репозиториев из ленты сменили владельца или имя: santifer/career-ops стал career-ops-hq/career-ops, basecamp/omarchy уехал в omacom/omarchy. GitHub молча перенаправляет старые ссылки. Ссылка из дайджеста работает, а смена владельца не видна. Ту же мину я потом нашёл у себя: один мой приватный репозиторий переименовали, и локальный remote всё это время смотрел на старое имя.

Порядок проверки, который я себе оставил

Перед тем как ставить что-то из трендов, я теперь прохожу пять шагов. Первые три занимают минуту.

  1. Прочитать файл лицензии до конца. Без файла код не беру, с копилефтом беру только идеи.

  2. Посчитать код, прозу и тесты отдельно, сгенерированное вычесть. Класс сразу подсказывает решение: переписать, встроить или не трогать.

  3. Для промпт-класса выяснить, чей движок под промптом.

  4. Сверить владельца и имя по API с тем, что написано в ссылке.

  5. Звёзды считать доказательством того, что продвижение дошло до людей. О качестве они не говорят ничего.

Границы замера

Строки кода не мера качества. Замер отвечает на один вопрос: что я беру на поддержку, если это поставлю. Это одна лента за один месяц, 138 строк, и пороги классов выбраны мной. Их можно двигать, числа в таблице от этого не изменятся. Ветки по умолчанию живут своей жизнью, так что каждая строка описывает репозиторий на 18–19 сентября 2026 года. Десять самых больших репозиториев я не скачивал и записал для них размер, без выдуманного замера.

Данные

Все 138 строк лежат в CSV вместе со скриптами подсчёта: github.com/Sanexxxx777/teardown, лицензия MIT. Любую строку можно воспроизвести двумя командами:

bash skills/teardown/scripts/fetch.sh owner/repo /tmp/x
python3 skills/teardown/scripts/weigh.py /tmp/x

Если найдёте строку, где счётчик ошибся, мне это интереснее всего остального.

Автор: Aleksandr_NFA

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js