Читать в телеге. Когда-то там были посты не только от меня.
Код ревью в эпоху ИИ
Годная статья про то, как массовое использование агентов меняет разработку в целом и код-ревью в частности, с опорой на цифры из различных исследований. И базу про цели код-ревью повторяет.
Поскольку код стало производить легче, давление в процессе сместилось и нагрузка на ревьюеров кратно возросла. А с процессом ревью в индустрии и до ИИ были проблемы.
Код-ревью — это по сути диалог, одна из основных цель которого — достичь общего понимания проблемы и обменяться знаниями. Однако с ИИ понимание деградировало в угоду скорости, и если тупеньких ошибок стало меньше из-за локальной оптимизации, то архитектура, правильные абстракции и общее видение страдают, а ловить ошибки в них обычно сложнее. Кроме того, если в “человеческом” коде обычно видны намерения, то в сгенерированном ИИ коде их нет, и тяжело понять причину, почему тот или иной участок кода написан именно так (если эта причина вообще есть). Есть даже гипотеза, что основная цель программирования — построение рабочей теории, ментальной модели того, что должен делать продукт и как; и если это делегировать ИИ, то и результаты будут соответствующими.
Один из подходов — “вроде норм, мержим как есть, потом поправим если че”, но он плохо масштабируется и в долгой перспективе делает продукт очень хрупким. При поверхностных ревью система становится черным ящиком.
Что с этой проблемой делать? Можно попробовать ИИ-ревью, обложиться проверками и чек-листами, заставить людей предоставлять описание изменений, использовать grill-me, ограничить размер PR, заставить объяснять изменения на синхронном созвоне… Но все это либо не масштабируется, либо легко проигнорировать или обойти с помощью ИИ. Сам автор пока склоняется к маленьким PR с приложенным планом/промтом. Ну и экспериментировать с обязательным достижением понимания.
Более прагматичный подход изложен в другой статье. Там отмечается, что ревью вообще-то не очень благодарная работа, и его глубина — сугубо культурный аспект, который очень редко вознаграждается. Пока вы ревьюите один PR, вам навалят еще три. Еще себе в перформанс-ревью напишут сколько фичей доставлено, было бы еще больше, если бы не ревьюер… а вот за само ревью повышения не дадут. Если ревью особо не ценятся в команде, и поощряется количество фич, то лучше потратить время на что-то более видимое. Особенно, если на том конце — тонкая мясная прослойка перед ИИ. Можно сделать ревью опциональными и сместить фокус на проектирование (хотя это и не заменит полноценного ревью).
Постепенная автоматизация
Хорошая статья, дополняющая и раскрывающая идею частичной автоматизации.
Ключевая идея заключается в том, что любое (повторяющееся) ручное действие надо документировать, а после каждого использования — улучшать ее, частично автоматизировать и хоть чуть-чуть двигаться от состояния полностью ручной работы в сторону полной автоматизации. Таким образом итеративно собираются требования и ограничения, а также “коллективное бессознательное”, если речь идет про команду. Если чуть дольше выполнять работу — никто не заметит, а вот выделять ресурсы на автоматизацию фигни никто не будет.
Объяснения алгоритмов для игр
Хороший сайт с набором объяснений алгоритмов, полезных для разработки игры: поиск пути, генерация карт, работа с сетками, определение видимости, расчет урона, диаграммы Вороного и т.п.
Локальный поиск
Local-first снова в фаворе, потому что агенты и все такое, да и девятки доступности сервисов не в моде. Что можно использовать, кроме старого доброго grep?
Инкрементальное улучшение — ripgrep, он же rg. Киллер-фича, имхо, — настройки по умолчанию: рекурсивность, учет .gitignore и полноценные регулярки. Однако я уже настолько привык печатать grep -Rnil "blabla" ., что переключение не очень себя оправдывает.
Еще один инкремент поверх rg — fzf, который предоставляет интерфейс “живого” поиска и нечеткий поиск (по символам). skim и fzy из этой же категории. Автор fzf утверждает, что для некоторых этот инструмент по пользе сопоставим с интернетом. Я о нем узнал в этом месяце и попробовал раза два — не зашло :/ Тем более что для чего-то полезного (например, открыть файл с совпадением) надо много неочевидных параметров передавать. И это все еще построчный поиск (для душнил — со специальными приседаниями можно искать на уровне документа).
Почти все то же самое, что rg + fzf, предоставляет ugrep. У него тоже есть интерактивный режим, однако он еще поддерживает человеческие операторы (AND, OR) и поиск идет именно по файлам. Еще есть нечеткий поиск по расстоянию Левенштейна и куча других фич.
Следующий слой — zk. Это уже cистема для ведения заметок,и для нее нужен индекс (а индексируется все весьма медленно, увы). Но зато тут полноценный полнотекстовый поиск с ранжированием и человеческими операторами, а еще поддерживается frontmatter. И результаты весьма релевантные.
Наконец, вершина эволюции, AI-first поиск со встроенным AI для семантического поиска — QMD. Его заявленная киллер-фича, кроме ИИ — гибридный поиск по эмбеддингам и ключевым словам, а также расширение запроса. Однако он меня не впечатлил — да, вроде комбинированный поиск, но медленная первичная индексация с эмбеддингами, и некоторые результаты, которые можно найти по ключевым словам обычным grep/rg, он почему-то не вывел в гибридном режиме. Да и от семантического поиска я не понял выгоды (ну или у меня запросы слишком тупые).
В этой же категории еще есть ck. Это замена grep с тем же интерфейсом, однако с дополнительными фичами сверху: гибридным поиском с BM25 и нейронкой, а также интерактивным режимом. Однако обратная совместимость скорее мешает: писать --hybrid каждый раз без альтернативы вроде -H — ну, такое (хотя alias можно повесить, ладно). Он тоже тыщу лет все индексирует для эмбеддингов. И все это для поиска, где даже нет логического AND :/
Если говорить про нейронки, то де-факто стандарт пока ripgrep, но Клод в апреле перешел на ugrep. И в нише “консольный поиск получше” именно ugrep показался мне хоть сколько-нибудь интересным и полезным. У него нет ранжирования, но если в результатах более важна полнота, то это не очень критично.
После этого исследования подумалось, что мой велосипед еще ничего:)
Трехкомпонентная модель идентификатора
Хороший паттерн для идентификации пользователя — должно быть три компонента: приватный id в базе (обычно UUID или число), идентификатор для логина (например, почта или какой-нибудь социальный логин) и публичный идентификатор (имя, или @name). Первый — постоянный, неизменный и, в идеале, никому (даже пользователю) не видный. Второй — личное дело пользователя и не должен быть виден другим, а id базы с ним связан как один ко многим.
Все это еще полезно с точки зрения ИБ: немного базы можно посмотреть в этом докладе. А еще можно почитать про курьезные случаи, из-за которых надо еще и ограничивать возможные варианты публичных идентификаторов.
Кто контролирует информацию — тот контролирует мир
В каждом утюге анонс от Гугла, что поиск “перешел в новую эру”. Выглядит весьма вторично после Perplexity, да и что-то долго копались, поиск был мертвым уже давно… В последнее время гугл можно было хотя бы использовать для поиска каких-то внятных источников и для перепроверки того, что выплюнула нейронка, но, кажется, и этого теперь не будет.
Подобные изменения — еще один фактор, который укрепляет стенки пузырей. Нейронки и так очень специфичны в плане рекомендаций и, например, выбора технологий, и что-то немейнстримовое редко предлагают. И так уже интернет засран, теперь еще и уменьшаются возможности что-то редкое найти.
Нейронки выступают вахтерами, усиливая эффект выбора по умолчанию. Стоимость продвижения (хотя бы на уровне, чтобы заметили) становится еще выше, добро пожаловать в ультракапитализм, где корпорации управляют всем. Не забывайте про рекламу. Даже какие-то инициативы вроде GroundNews не помогут, там тоже какой-то мрак в плане чистоты мотивов и прозрачности финансирования.
Что делать? Давайте спросим ChatGPT 🗿
В учебных задачах главное — путь
Очень схожий тезис прослеживается в нескольких относительно свежих статьях: некоторые учебные или легкие задачи выдаются специально для того, чтобы обучаемый познакомился с процессами, набил первые шишки, получил опыт, научился правильному мышлению, достиг понимания навыка через практику и т.п. При этом результат особо не важен.
Соответственно, использование ИИ для решения этих задач — выстрел себе в ногу. Самое неприятное, что в короткой перспективе никто и не заметит разницы, но в долгой такое решение сомнительно и приводит к постепенному отрыву от реальности и понимания, что происходит.
Подобные тезисы можно увидеть у астрофизика, который в том числе отмечает системные проблемы в науке; математика, который отмечает, что тяжело научиться доказательствам, если самостоятельно не пытаться; и мейтенеров zig, которые забанили LLM, потому что им пофиг на то, что PR не вылизан до блеска, главное, чтобы сообщество контрибьюторов, которые что-то понимают в коде, росло.
Нюансы рендеринга текста
Хорошее видео, покрывающее базовые идеи про отображение шрифтов (растеризация, хинтинг, субпиксели и т.п.). С основными концепциями я был знаком и ранее, но тут за 5 минут объяснено все самое основное, и после просмотра у меня сложилась более-менее четкая картинка.
Одно из следствий сложности процесса — его тьюринг-полнота. На шрифтах можно даже LLM запустить.
Стандарты розеток
Стандартов розеток — пруд пруди, хоть в музее выставляй. С точки зрения практики полезен этот сервис, где можно указать откуда куда едете, и он подскажет, нужен ли адаптер.
Не используйте нестандартные клиенты к БД
Накатывали не очень сложное изменение на прод, и он упал. Откат не помог, потому что база была в неконсистентном состоянии. Ладно, починили, но 20 минут прод лежал.
Стали разбираться — эволюция базы повисла на переименовании таблицы. Сервис — монолит, кроме него в базу только метрики ходят (но не в эту таблицу). Однако переименование таблицы — это действие, которое требует ACCESS EXCLUSIVE лок, и ни одна операция, хоть как-то трогающая таблицу, не может выполняться параллельно.
“Убийцей” оказалась IntelliJ Idea Ultimate, в которой коллега запускал проверки на проде перед деплоем. На препроде воспроизвести не удалось, но при повторном деплое опять “все повисло” и только когда прибили Idea, все накатилось. Судя по всему, она запрашивала метаданные для автодополнения и т.п. и где-то висела незакрытая транзакция. psql такого бы себе не позволил (по умолчанию, по крайней мере) :/ А вообще еще лучше никаких лишних открытых соединений не держать при накатке изменений.