Заменит ли искусственный интеллект программистов
Hackers (and creative people in general) should never be bored or have to drudge at stupid repetitive work […] To behave like a hacker, you have to believe this enough to want to automate away the boring bits as much as possible[.]
Eric Steven Raymond, How To Become A Hacker
Иногда встречается мнение, что вскоре профессия программиста станет ненужной, потому что искусственный интеллект, нейронные сети, и т.п. полностью заменят программиста, и будет достаточно свободным языком сформулировать что надо сделать программе, и нейронная сеть сама напишет нужную программу. Например, из того, что я могу с ходу вспомнить за последние несколько лет — это новость про нейронную сеть, которая сама верстает экран в приложении под iOS по макету дизайнера, или недавняя новость про нейронную сеть, которая предлагает продолжения для уже написанного кода, или что-то в этом роде. Тем более что машинный перевод с одного человеческого языка на другой уже работает весьма неплохо, так почему бы не научиться делать перевод с человеческого языка на язык программирования?..
Я верю, что профессии программиста в целом это все не особо угрожает, и в этом посте попробую объяснить, почему.
Четко поставить задачу — это 50% успеха
Можно грабить корованы
Ну, во-первых, начнем с, может быть, наиболее яркого пункта. Для того, чтобы написать программу, надо понимать, что эта программа должна делать; это должен понимать что программист, что потенциальная нейронная сеть. Заказчику, человеку, которому в конечном счете нужна программа (будь то внешний заказчик, заказывающий разработку ПО, или менеджер крупной компании, командующий отделом программистов, или руководитель стартапа) недостаточно сказать: «сделай так, чтобы было хорошо» — и получить на выходе необходимую программу. Как правило, разработка программы, или даже небольшой доработки к уже существующей программе, подразумевает неоднократные взаимодействия программиста (программистов) с заказчиком, уточнение неясных моментов в исходной постановке задачи, обсуждение вариантов и ситуаций, которые заказчик забыл учесть, а программист заметил, коррекцию задачи с учетом технических ограничений и т.д. Поэтому реальная работа программиста далека от «просто напиши код, который делает то, что мне надо». Я еще теоретически могу представить себе нейросеть, которая конвертирует человеческое описание «сделать то-то и то-то» в код, но нейросеть, которая логически определяет непонятные, неоднозначные, или вообще неописанные моменты в постановке задачи и (тоже человеческим языком) уточняет у заказчика, что тут надо делать — это кажется уже на много порядков сложнее.
(Вы можете сказать, что подобное взаимодействие с заказчиком зачастую осуществляет только тимлид, руководитель группы программистов, или несколько старших программистов на проекте — но на самом деле скорее всего это не так, просто младшие программисты приходят с вопросами не к заказчику, а к старшим программистам, а те уже, если надо, доводят вопрос до заказчика.)
Конечно, тут есть как минимум два исключения. Во-первых, действительно есть ряд задач, та же верстка экрана в iOS, которые (в определенных пределах, конечно) делаются достаточно прямолинейно, и зачастую не требует вопросов (и зачастую как раз доверяются младшим программистам). Про это я еще напишу ниже, но в целом да — я вполне верю, что такие в достаточной мере механические действия, не требующие особых размышлений, со временем будут так или иначе автоматизированы.
Во-вторых, есть еще немного другой формат взаимодействия заказчика с программистами — это формат когда заказчик пишет очень подробное техническое задание, тщательно и в деталях описывая, что, когда и как должно происходить, на уровне «если пользователь кликает в кнопку Настройки, то ему открывается экран, на котором присутствуют, во-первых, четыре галочки, озаглавленные так-то и так-то, а кроме того, если четвертая галочка включена, то показывается еще и пятая галочка…»
Такой подход обладает, конечно, многими недостатками, из-за которых он и используется весьма редко (надо заранее тщательно все продумывать, очень сложно вносить изменения по ходу дела, надо в принципе писать этот объемный документ, и т.д.) — но в принципе, да, подобного рода технические задания в определенных случаях можно напрямую переводить в код, и в принципе задача автоматизировать написание кода по такому описанию не выглядит уж совсем невозможной.
Но только что мы получим в итоге? Не напоминает ли вам что-нибудь фраза «если пользователь кликает в кнопку Настройки, то ему открывается экран, на котором присутствуют, во-первых, четыре галочки, озаглавленные так-то и так-то, а кроме того, если четвертая галочка включена, то показывается еще и пятая галочка…»? Кажется, мы просто изобрели новый язык программирования. Возможно, он будет позволять более свободные формулировки, будет более приближен к живому языку, чем современные языки программирования, но в любом случае столь подробные технические задания будут писаться на очень своеобразном языке, ну и соответственно будут нужны люди, умеющие на этом языке писать. И это не из-за особенностей нейросетей, а просто потому, что полностью описать сложную программу, пусть даже и словами — это очень непросто.
(На самом деле люди уже сотни лет упражняются в очень похожем деле — написании различных юридических документов, — и пока так и не смогли придумать, как писать законы и договоры так, чтобы а) текст учитывал все возможные случаи, и б) оставался при этом понятен простым смертным.)
(И, конечно, попытки сделать язык программирования, чтобы на нем могли писать обычные люди, делались много раз, достаточно упомянуть BASIC и SQL. Оба языка создавались в том числе для того, чтобы на них могли писать не-программисты, — но они вовсе не привели к исчезновению программистов как профессии; более того, хоть SQL популярен до сих пор, но в итоге просто появилась отдельная профессия SQL-программиста…)
Автоматизация работы программиста — это естественный процесс
Вернемся к вопросу про механическую работу, не требующую особых размышлений — условную верстку экранов в iOS или широко известное в узких кругах перекладывание json’ов.
Ну, во-первых, надо сразу сказать, что при том, что в современном программировании действительно довольно много подобной рутинной работы — но при этом очень сложно назвать конкретный раздел, который состоял бы только из рутинной работы. Та же верстка экранов в iOS может быть рутинной… но только при условии, что у вас уже есть достаточно устоявшаяся кодовая база, что вы подобные экраны верстали уже много раз, никаких существенно новых элементов вы не делаете, возможно, используете какой-то фреймворк как для верстки, так и для получения данных из других частей программы и т.д.; ну или если вы пишете какое-то минимальное приложение, где надо просто накидать стандартных элементов.
Но при этом даже вокруг верстки экранов есть очень много нетривиальной работы, создающей новые концепции и т.д. — создание новых компонентов, тех же фреймворков, автоматизация наиболее механических процессов и т.д. Не говоря уж о том, что сама iOS развивается, и та рутина, которая была нужна несколько лет назад, теперь вовсе не нужна, теперь все делается совсем по-другому.
(На самом деле я имею лишь очень обтекаемое представление о том, как происходит верстка экранов именно под iOS, я больше знаю про Android и тем более про HTML, хотя и не являюсь супер-профессионалом ни там ни там, поэтому допускаю, что в деталях я могу ошибаться, но думаю, что общие соображения справедливы.)
То же самое относится к любой другой механической работе — если рассмотреть чуть более широкую область, то оказывается, что работа там уже далеко не механическая. И, соответственно, если человек только и умеет, что верстать экраны, и не смотрит ни на шаг вокруг — то в общем-то такого человека даже сложно назвать программистом. На этот счет даже есть термин «code monkey» — программист, который просто пишет почти под диктовку, что ему скажут. Напротив, если сильный программист занимается такой механической работой, то скорее всего он это рассматривает как необходимое зло, как то, что, к сожалению, пока еще не оптимизировано, не автоматизировано, но что лишь отнимает его время от написания серьезного кода.
Вообще, в принципе все развитие программирования — это в первую (ну ладно, может быть, во вторую) очередь борьба с таким механическим трудом; любой серьезный программист старается по максимуму избавиться от рутинного труда. На этот счет довольно неплохо высказался Эрик Рэймонд, чью цитату я вынес в эпиграф всей этой статьи (хотя мне казалось, что где-то я видел еще более четко сформулированное утверждение про это).
И такой автоматизацией пронизана вся история программирования. Всё развитие языков программирования — это попытки автоматизировать те вещи, которые раньше надо было делать вручную. Возьмите какого-нибудь программиста из 40-50-х годов, которые писали хорошо если на ассемблере, а не в машинных кодах, покажите ему язык C++ и уж тем более паскаль или питон — он, наверное, подумает, что это как раз и есть та самая система, которая переводит естественный человеческий язык в машинный код. Или, к более современным вещам, многочисленные фреймворки — вообще наверное все существующие фреймворки направлены именно на то, чтобы упростить написание кода, избавить программистов от необходимости писать однотипный код. (Упомяну хотя бы Bootstrap, позволяющий создавать простые html-страницы без необходимости писать сложный css-код.)
Конечно, при таком развитии некогда важные навыки становятся не важными (если в тех же 50-х годах каждый программист должен был знать ассемблер, то сейчас это уже далеко не так нужно), но в целом профессия программиста, равно как общие навыки и знания, никуда не пропадает. (И, кстати, это дополнительно подчеркивает, что надо в первую очередь учить более фундаментальные, а не прикладные вещи — конкретный фреймворк через несколько лет станет не нужен, а алгоритмы и структуры данных живут намного дольше.)
И поэтому да, я вполне верю, что — с нейросетями или без них — многие рутинные вещи, та же верстка экранов под iOS, которые сейчас программисты вынуждены делать вручную, будут в будущем автоматизированы. Но это будет не что-то невиданное, что-то, что переломит всю профессию программиста — это будет скорее что-то типа нового фреймворка, автоматизирующего наиболее рутинные части. Многие другие вещи останутся, даже наоборот — за счет такой автоматизации просто еще больше расширится область того, что могут делать программисты. Произойдет то же, что происходило уже много раз за всю историю развития программирования.
То есть в целом, автоматизация рутинных задач идет начиная с самого начала развития программирования, но это вовсе не обозначает, что профессия программиста становится не нужна.
Нейросети не идеально точны
Третья причина состоит в следующем. Нейросети, и вообще искусственный интеллект в том виде, как он сейчас развивается, он по своей природе не идеально точен. Например, типичная задача для нейросетей — отличать собак от кошек, или различать цифры на картинках. Эти задачи в принципе не могут быть решены абсолютно точно, кто угодно (даже человек) будет совершать ошибки. В целом, насколько я понимаю, сейчас хорошим результатом для компьютерных программ считается уровень ошибок порядка долей процента. Ну и для таких задач это действительно нормально; на самом деле, в ряде постановок таких задач компьютер даже работает лучше человека.
Но в программировании существует огромное количество задач, которые требуют совершенно иного уровня точности. Если вы, например, пишете мессенджер, то вряд ли вас устроит ситуация, что он будет терять 0.1% сообщений, или отправлять 0.1% сообщений не тому получателю. Если вы пишете программное обеспечение для банка (а банки сейчас — одни из основных работодателей для программистов), то вас совершенно точно не устроит система, которая теряет 0.1% денег вкладчиков (или, наоборот, накидывает вкладчикам лишние 0.1% денег). Если вы делаете интернет-магазин, то вряд ли вы хотите доставлять не тот товар в 0.1% случаев. И т.д.
Во всех этих отраслях намного проще написать классический алгоритм, который будет иметь намного более высокую точность, чем любые результаты нейросетей. (Тут, кстати, надо упомянуть еще такой момент, что исправлять ошибки в классических алгоритмах намного проще, чем в нейросетях.) И поэтому я верю, что как минимум в подобных отраслях программирования спрос на программистов еще долго будет сохраняться.
(Вообще, тут, конечно, надо аккуратно оговориться о том, какой сценарий мы рассматриваем. Одно дело если мы говорим про то, чтобы сделать допустим мессенджер на основе нейросетей; и другое дело если мы хотим сделать нейросеть, которая на основе текстового описания того, что такое мессенджер, сгенерирует нам программный код. В контексте этого поста надо скорее говорить про второй вариант, потому что мы говорим именно про вариант что нейросети заменят программистов, а не про вариант что программисты будут использовать нейросети вместо классических алгоримов. А предыдущие абзацы сформулированы скорее про первый вариант. Но я думаю, что в контексте обсуждения точности работы программ эти варианты не вот уж сильно отличаются, тем более что первый вариант явно проще.)
В качестве предела этого аргумента — подумайте над по-настоящему алгоритмическими задачами типа задач с алгопрога или с олимпиад. Даже если взять конкретную задачу, допустим, на алгоритм Дейкстры, — можно, конечно, подумать над тем, чтобы сделать нейросеть, которая будет искать кратчайшие пути в графах. Но почти наверняка она будет искать не идеально кратчайший путь, и к тому же далеко не факт, что, как минимум для «обычных» графов, она будет хоть чем-то лучше, чем алгоритм Дейкстры. (Конечно, возможно, для каких-нибудь супер-больших графов, или если вам не обязателен строго кратчайший путь, нейросети и будут лучше классических алгоримов…)
Но это конкретная задача; а если говорить про нейросеть, которая сможет решить вообще любую задачу с олимпиад (т.е. написать программу, которая пройдет все тесты) — кажется, это даже в очень долгосрочной перспективе не особо реально. При том, что вот уж что, а формулировки задач на олимпиадах уже достаточно строги. (И этот пример, кстати, также неплохо подчеркивает, почему написание программ — это не просто перевод с человеческого языка на компьютерный.)
Нейросети не каннибализируют области программирования, они захватывают новые рубежи
Очень тесно связанная с предыдущей причиной следующая. В принципе, нейросети в современном программировании уже играют довольно важную роль. Но если подумать, какие задачи решаются с помощью нейросетей, ну или в целом с помощью машинного обучения, то окажется, что это скорее новые задачи, а не те, которые раньше решались классическими алгоритмами. Нейросети хорошо работают при распознавании изображений, в рекомендательных системах, много где еще — но практически всё это задачи, которые классическими алгоритмами решались плохо, задачи, которые плохо поставлены, где нет единственно верного ответа, и зачастую в принципе не очень понятно, что надо сделать. (И это, конечно, напрямую связано с предыдущим разделом.)
А те задачи, которые успешно решались классическими программами — те же допустим мессенджеры (системы электронной почты и т.п.), или банковские системы, или редакторы и т.д. — практически все задачи, которые прекрасно работали еще 10-20 лет назад, до бума нейросетей, все еще решаются классическими программами. То есть нейросети создают новые области, где применяется программирование, но они вовсе не претендуют на те области, где и раньше все было относительно неплохо.
Для примера если говорить про банки — конечно, в банках нейросети активно применяются (или могут применяться), например, чтобы сделать какие-нибудь индивидуальные предложения клиентам, или оценить надежность заемщика и т.д. — но это всё области, которые раньше не были затронуты программированием. В тех же областях, где раньше использовались классические алгоритмы, например, при начислении процентов на вклад, они же и продолжают использоваться.
Поэтому мне представляется, что и при автоматизации труда самих программистов в целом нейросети скорее создадут новые области работы, чем займут уже существующие области.
* * *
Ну и напоследок — еще одно важное соображение. Я верю, что умный, толковый человек, с большим кругозором, найдет хорошую работу при любом дальнейшем развитии программирования и технологий в целом. Важно не знание конкретных технологий, важно умение думать, логически рассуждать и т.д.; из более частного, но все равно важного — умение видеть разные особые случаи, понимать, какие ситуации надо учесть и т.д. Как в 90-е годы в России многие выпускники физико-математических факультетов, не имея возможности нормально зарабатывать по своей специальности, шли в банки, в бизнес и т.д. — и многие там достаточно успешно закреплялись; как и сейчас многие выпускники тех же физмат факультетов идут в программирование, так — я верю — и всегда, если вы умеете думать, то найдете хорошую работу.
То есть нет необходимости загадывать на десятки лет вперед и думать, будут программисты востребованы через 20-40-60 лет или нет. Смотрите на перспективу ближайших 10-20 лет — а тут вполне понятно, что программисты вполне будут востребованы. Ну а там уже, даже если случится что-то совсем непредвиденное — то вы как умные люди все равно найдете себе работу.
Мой курс по алгоритмическому программированию (и подготовке к олимпиадам) для школьников, студентов и всех желающих — algoprog.ru