Обновить
16K+
41

PostgreSQL Developer / Database Server

Отправить сообщение

Как разглядеть инженера за AI-агентом?

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

Распределённые инженерные команды уже стали нормой: доступ к широкому рынку труда перевешивает неудобства. Однако лёгкой такая работа не бывает - фокус, общий ритм, культура команды и обмен опытом на удалёнке держатся плохо, и оптимальной схемы мы, похоже, так и не нашли. А AI-агенты ещё и добавляют сложности в эту, несовершенную, систему.

Казалось бы, ничего нового — но разница в масштабе. Раньше фасад требовал усилий и рано или поздно трещал. Теперь его можно производить систематически, в промышленных объёмах и без видимых швов. Всё, что приходит от коллеги асинхронно — коммиты, тесты, документация, - теперь говорит скорее о том, как он настраивает своё LLM-приложение и подбирает ему скиллы, чем о нём самом. Понять человека и оценить его вовлечённость остаётся возможным только в моменты прямой коммуникации. Поэтому сейчас совершенно непонятно, как устанавливать контакт с удалённым коллегой и чувствовать пульс инженерного процесса.

Зачем нам вообще знать реальное положение дел? Что в действительности умеет коллега? Насколько он вдумчив и ответственен, насколько критичен к результатам своего труда? Без ответов нельзя планировать, оценивать трудоёмкость и прикидывать сроки. Но важнее другое: нельзя решить, кому доверить архитектурно значимый кусок системы.

Внимательный читатель резонно спросит: если результат проекта — это продукт, и он создаётся по графику, какая разница, что происходит на стороне удалённого коллеги?

Разница в том, что AI напишет не только код, но и регрессионные и нагрузочные тесты — вне зависимости от квалификации инженера. И часть этой большой работы может оказаться подгонкой под результат, чем AI частенько грешит: тест, подкрученный так, чтобы позеленеть, выглядит ровно как честный. Какие шаги предпринимает коллега, чтобы этого не случилось, мы не знаем, его техпроцесс работы с AI непрозрачен. И ещё: расширяемость кода, простота поддержки и количество потенциальных проблем - слищком абстрактные понятия для нынешного AI. А как решил эти вопросы инженер и почему из кода не видно.

Приведу пример из практики — Self-Join Elimination в PostgreSQL. Фича шла в ядро семь лет, один раз откатывалась уже после коммита и после релиза 18 продолжала собирать багфиксы. Недавно Tom Lane переделал её. Раньше, обнаружив самосоединение, Postgres удалял избыточный JOIN и перестраивал все ссылки на него в дереве запроса и структурах плана. Tom от этого отказался: новая реализация правит только дерево запроса и перезапускает планирование с нуля уже по новому дереву. По формальным меркам решение выглядит хуже - планирование дорожает. Выигрыш в другом: исчезает целый класс ошибок, которыми фича успела обрасти.

Заметьте, где здесь виден инженер. Ни диф, ни зелёные тесты не покажут, что человек осознанно заплатил скоростью планирования за надёжность. Мы знаем об этом только потому, что он это проговорил. И это, пожалуй, единственная зацепка, которая у нас остаётся: требовать от коллеги не код с тестами, а сформулированные компромиссы — почему так, чем заплатили, от чего отказались. Ровно то, чего pgsql-hackers требует от любого патча: без обоснования он принят не будет.

Таким образом, качественный и сложный код сам по себе перестал быть мерилом уровня инженера и что должно придти этому на смену, пока непонятно. А какие методы работают у вас при управлении распределённой командой в эпоху AI-агентов? Что помогает, а что уже очевидно устарело?

THE END.
11 сентября 2026 г., Утрехт, Голландия.

Теги:
+6
Комментарии4

Open-source-проект — это не просто код под открытой лицензией.

Недавняя покупка DuckLabs - создателя DuckDB, — вызвала немало обсуждений в сообществе разработчиков баз данных и не только (см., например, обсуждение на news.ycombinator.com). Вставлю и я свои пять копеек.

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

Насколько я вижу как сторонний наблюдатель, до сих пор все ключевые решения в DuckDB принимала небольшая группа core-разработчиков. Внешних контрибьюторов немало (вспомним хотя бы команду MotherDuck), но само ядро принимающих решения «разнообразным» назвать трудно. Так что это был открытый код, но не open-source-проект в моём понимании - со всеми спорами, компромиссами, голосованиями и вообще той самой динамикой открытых сообществ.

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

Поэтому, на мой взгляд, AWS сделала умный ход: наняла разработчиков, а проект оставила открытым. Возможно, там читали свежие исследования на эту тему (см., например, Vasilescu et al., 2015 и Tamburri et al.) и хотят снизить риск «Death Spiral» для этого вполне себе оригинального проекта. Моя гипотеза: они таким образом пытаются подтолкнуть других игроков рынка вкладываться в проект.

Так это или нет - станет понятно из их дальнейших шагов: как быстро люди из других компаний начнут появляться в списке core-коммиттеров и в управлении проектом. Первый ориентир - технический консультативный совет, анонсированный при DuckDB Foundation. Если это случится скоро, а независимые новички действительно расширят проект - это будет новая страница в истории open-source-модели разработки. По крайней мере, той её части, которую знаю я.

Может таким макаром и bare-metal инженерные проекты также смогут получать поддержку больших компаний при использовании открытой модели разработки? Было бы любопытно иметь в открытом доступе полное КД на новую модель автоваза (без деталей реализации корпоративного форка, конечно) или паровой турбины ТЭС - а вы что думаете?

Теги:
+10
Комментарии8

Дополняем EXPLAIN Postgres'a информацией об использованной статистике.

Незадолго до код-фриза PostgreSQL 18, Роберт Хаас закомитил возможность, разрешающую внешним модулям добавлять в EXPLAIN дополнительную информацию.

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

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

В список опций EXPLAIN был добавлен параметр STAT, принимающий булевы значения ON/OFF. Если он включён, то в конец эксплейна будет вставляться информация об использованной статистике: наличии MCV, гистограммы, количестве элементов в них. А также значения stadistinct, stanullfrac и stawidth.

Зачем это нужно? - спросите вы. Ведь набор статистик прямо следует из списка выражений, участвующих в запросе? Разве нельзя понять, какая статистика была непосредственно использована, заглянув в код cost-model того или иного вида выражения?

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

CREATE TABLE sc_a(x integer, y text);
INSERT INTO sc_a(x,y) (
SELECT gs, 'abc' || gs%10 FROM generate_series(1,100) AS gs);
VACUUM ANALYZE sc_a;
LOAD 'pg_index_stats';

EXPLAIN (COSTS OFF, STAT ON)
SELECT * FROM sc_a s1 JOIN sc_a s2 ON true
WHERE s1.x=1 AND s2.y LIKE 'a';

Nested Loop
-> Seq Scan on sc_a s1
Filter: (x = 1)
-> Seq Scan on sc_a s2
Filter: (y ~~ 'a'::text)
Statistics:
"s2.y: 1 times, stats: {

MCV: 10 values, Correlation,
ndistinct: 10.0000, nullfrac: 0.0000, width: 5 }
"s1.x: 1 times, stats: {

Histogram: 0 values, Correlation,
ndistinct: -1.0000, nullfrac: 0.0000, width: 4 }

Здесь можно увидеть, что была использована статистика по колонкам s1.x и s2.y.
При этом, у нас всего десять MCV значений по y, а по х MCV статистика отсутствует вовсе; гистограмма вроде есть, но нулевой длины. И никаких нуллов в обеих колонках.

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

Для отслеживания использованной статистики здесь был использован get_relation_stats_hook. Было бы полезно знать также, используется ли в планировании расширенная статистика, однако она находится слишком глубоко в ядре, и текущий набор хуков здесь никак не поможет.

А какие вы видите варианты применения возможностей расширения вывода эксплейна? Насколько в действительности безобидна даже такая ограниченная информация?

THE END.
12 апреля 2025, аэропорт "Шереметьево"

Теги:
Всего голосов 2: ↑2 и ↓0+2
Комментарии0

Module Info в бинарных файлах модулей Postgres

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

Каждый модуль, который вы попытаетесь загрузить в Postgres, в обязательном порядке содержит в своём теле информацию о версии ядра, для которого оно было собрано и параметрах его сборки. Обоснование необходимости этого можно найти в треде с обсуждением этой фичи, однако идея прозрачна: это сделано для того, чтобы предотвратить ошибку загрузки несовместимого модуля и связанные с этим нестабильности в работе инстанса СУБД.

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

Идея родилась во время поддержки расширения, которое имело достаточно стабильный UI и часто изменяющийся код библиотеки: для ответов на вопросы клиентов чтобы воспроизвести ситуацию на стенде требовалось знать конкретную версию кода, для чего приходилось вводить в релизную политику правило именования библиотек и добавлять специальную экспортируемую константу в код модуля. Однако это не является достаточной гарантией определения версии и усложняет рабочий процесс при поддержке большого количества расширений, поставляемых из разных источников.

Гораздо проще было бы, если бы ядро содержало в себе фунцию, например, module_info(module_name), которая позволяла бы изнутри СУБД (например, в консоли psql) определить полный путь и имя файла, содержащего искомый модуль. Более того, при наличии двух версий одного модуля в ядре (да, бывает и такое!), мы получаем возможность обнаруживать потенциальные конфликты. При этом, появляется возможность автоматизировать обнаружение модулей и их версий в системе другими модулями - да, я ненавижу использовать функцию SerializeLibraryState и другие грязные хаки для этой цели!

Ещё одна причина (уже глубоко техническая) связана с тем, что теперь (с апреля 2024 г.) расширения для текущей и последующих версий Postgres могут использовать dynamic shared memory (DSM) без необходимости быть загружаемыми при старте инстанса. Это открыло путь разработки легковесных модулей, которые могут быть загружены динамически в каждом отдельном бэкенде. Помимо производительности преимущество здесь в том, что появляется возможность реализовать технику онлайн-апгрейда расширения - установив новую версию модуля в системе под другим именем и загружая такую новую версию во вновь стартующих бэкендах мы имеем обновление функциональности на лету, без остановки инстанса! - по крайней мере, у меня в голове вырисовывается именно такой сценарий.

С другой стороны, проект omnigres (автор Yurii Rashkovskii) также пришёл к идее версионирования модулей, хотя и делает это внешним, по отношению к ядру, путём.

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

Перед тем, как начинать долгий путь обсуждения кода в hackers mailing list будет очень полезно аккумулировать опыт и мнения других разработчиков и мэйнтейнеров расширений Postgres. Нужна ли такая фича? Должна ли она быть опциональной или обязательной? Какая информация о модуле нужна (или просто будет полезна) в ваших инсталляциях?

Предлагайте ваши идеи и делитесь своим мнением в комментах, или в github-дискуссии сообщества PGEDC разработчиков расширений Postgres. Каждое мнение имеет ценность!

Теги:
Всего голосов 1: ↑1 и ↓0+1
Комментарии0

Информация

В рейтинге
178-й
Откуда
Madrid, Madrid, Испания
Зарегистрирован
Активность

Специализация

Бэкенд разработчик
Ведущий
Базы данных
PostgreSQL
Linux
Bash
SQL
Git