Создатель языка Elixir Жозе Валим (José Valim) размышляет об изменении языков программирования: изменился разработчик — должны измениться и языки.

Привет, Хабр! На связи Хекслет. Весь материальный мир — от дверных ручек до архитектуры заводов — построен под пропорции и ограничения человека. И гораздо выгоднее делать роботов антропоморфными: пусть у них будут руки, ноги и пальцы — тогда они смогут пользоваться нашей инфраструктурой.

То же и софтом, синтаксисом и IDE: эта инфраструктура оптимизирована под человеческое восприятие. Должны ли мы сохранять эту эргономичность для ИИ-агентов?

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


Этот текст — мои размышления о том, как могут развиваться языки программирования в эпоху искусственного интеллекта.

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

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

Размышления

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

Начнём.

О сообществе

Основа большинства языков программирования — это сообщества, которые объединяют разработчиков с общими взглядами. В Python упор делается на очевидность решений. Ruby культивирует счастье программиста. Сообщества Lisp традиционно ценят возможность изменять сам язык.

Но что произойдёт, когда мы перестанем писать большую часть кода? Как это повлияет на наше чувство принадлежности к сообществу? Должны ли мы пытаться сохранить это чувство, или сообществам предстоит нащупать то новое, что станет для них связующим звеном?

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

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

С другой стороны, если реализация чего-либо станет достаточно дешёвой, будут ли люди по-прежнему объединять усилия и работать над одним решением? Если мне нужна библиотека для решения задачи X, я могу просто попросить агента создать именно то, что мне нужно.

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

Об эргономике

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

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

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

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

Я использовал агентов для написания HTML, CSS, JavaScript, Elixir, Rust и Lean. Различия в синтаксисе, которые мне кажутся огромными, для них выглядят куда менее важными. С их точки зрения, всё это — токены на входе, токены на выходе.

О компиляторах

Когда мы обсуждаем языки программирования в контексте работы агентов, часто возникает закономерный вопрос: а нужны ли нам вообще языки программирования? Возможно, агенты заменят компиляторы и будут писать код напрямую на ассемблере?

Я не верю в этот сценарий по нескольким причинам.

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

Во-вторых, мы так и не нашли единый язык программирования или вычислительную модель, которые были бы хороши абсолютно во всём. У нас есть языки системного программирования, языки для доказательства теорем, языки для параллельного, распределённого и отказоустойчивого программного обеспечения (например, Erlang/Elixir), языки запросов, языки описания оборудования — и множеств одругих. В них заложена разная семантика, разные уровни абстракции, они дают разные гарантии. Неразумно ожидать, что один низкоуровневый язык объединит всё это.

Если языки программирования никуда не исчезнут, но мы перестанем оптимизировать их для людей, которые пишут код — то для чего же их оптимизировать?

Агентные инструменты

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

Но что если мы начнём использовать агентов для действий, которые обычно не выполняем сами — потому что эти действия слишком рутинные, требуют долгого обучения или обработки такого объёма информации, который не по силам человеку? Именно это мы и разберём.

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

Гарантии важнее удобства

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

Один из примеров — автоматический вывод сигнатур функций (inference of function signatures). Для людей это ценно: описывать то, что компилятор может вывести сам, — занятие нудное. А вот агентов такая рутина не волнует. Напротив, явное указание типов и намерений даёт компилятору, другим агентам и нам самим больше информации для работы. Есть и более важный аспект: языки, в которых можно полностью вывести типы — это, как правило, подмножество всех языков, типы которых можно проверить. Поэтому в конечном итоге оптимизация под вывод типов может ограничить как выразительность, так и гарантии, которые способна предоставить система типов. Зачем навязывать эти ограничения агентам, если они способны писать доказательства в гораздо более сложных системах?

Гарантии не всегда должны устанавливаться статически. Безопасность работы с памятью (memory safety) может обеспечиваться статически или во время выполнения — например, через сборку мусора. Проверка моделей (model checking) может связать модели с реализациями через сгенерированные моделью трассировки выполнения (execution traces) для валидации реальной системы. 

Яркий пример: Erlang/Elixir полагаются на изолированные процессы и передачу сообщений, чтобы ограничить структуру параллельных программ. Они жертвуют частью выразительности ради более сильных свойств изоляции и отказоустойчивости. Не каждый параллельный алгоритм эффективно ложится на эту модель, но программы, которые ей соответствуют, наследуют от неё полезные гарантии.

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

  • Корректность конструкций: язык устроен так, что на нём сложно или невозможно описать некорректные состояния или небезопасный код.

  • Статически установленные гарантии: типы, доказательства и статический анализ определяют свойства кода до его выполнения.

  • Контроль во время выполнения: управление памятью, изоляция процессов, ограничение прав доступа и другие механизмы, которые контролирует сама среда выполнения.

  • Проверка на практике: валидация программы через тесты, через property-based testing и через фаззинг.

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

Базы данных программ вместо LSP

О смерти IDE за последние два года заявляли не раз. И когда этот некролог наконец будет опубликован — протоколы языковых серверов (LSP), скорее всего, тоже не выживут.

Language Server Protocol (LSP) проектировался преимущественно для IDE, поэтому большинство его операций жёстко привязаны к документам и к размещению кода — к конкретному файлу, строке и колонке. Однако ИИ-агенты не особо точно отслеживают эти параметры.

Наш опыт создания Tidewave показывает, что агентам гораздо удобнее работать через интерфейс командной строки или через специальный инструмент, где они могут напрямую спросить: «где документация для foo_bar?» или «где объявлен BarBaz?». Это намного эффективнее, чем требовать от них точное место в коде, где встречается символ.

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

Хорошая новость заключается в том, что многие языковые серверы уже собирают или имеют доступ к большей части информации, необходимой ИИ-агентам: к символам, ссылкам, графам вызовов (call graphs), информации о типах, а иногда и к информации о потоках данных (data-flow). Моё предложение — открыть доступ к этой информации как к базе данных программы с языком запросов, будь то SQLite, Datalog или собственный предметно-ориентированный язык (DSL).

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

Что ещё важнее, агенты смогут составлять такие запросы, под которые просто непрактично делать отдельные кнопки или функции в интерфейсе IDE: «найти все публичные функции, которые в итоге вызывают заданную функцию» или «найти все пути в программе, где конкретное значение может превратиться в nil». Такие базы данных можно использовать и в качестве линтеров — это убережёт агентов от нежелательных практик.

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

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

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

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

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

К счастью, это как раз та область, где Elixir всегда был на высоте благодаря виртуальной машине Erlang (BEAM). Инспектирование процессов, сокетов, приложений, супервизоров, ETS-таблиц, очередей сообщений и многого другого — это встроенная возможность нашей среды выполнения. Единственная оставшаяся задача — организовать для ИИ-агентов безопасный доступ к этим возможностям — через набор специализированных инструментов, через язык запросов или через песочницу.


Кстати, мы полностью пересобрали курс «ИИ для разработчиков 2.0». Стартуем 20 октября. Учиться будем пять недель. Разберемся с агентным программированием как с системой: попрактикуемся собирать контекст, настраивать харнес, проектировать циклы верификации и добиваться, чтобы агент выдавал воспроизводимый результат.

Комментарии (1)


  1. Dhwtj
    02.10.2026 17:31

    Haskell ща ракетой взлетит

    /Sarcasm