EnglishРусский Map

Серебряной пули нет

title
Серебряной пули нет
type
concept
summary
Эссе Брукса 1986 года о сущностной и случайной сложности и о том, почему не существует десятикратного роста продуктивности.
tags
software-engineering, productivity, brooks
created
2026-04-09
updated
2026-04-11
lang
ru
translation_of
no-silver-bullet
source_updated
2026-04-11
translated
2026-09-01
translator
lllm/antigravity/gemini-3.7-flash-medium

No Silver Bullet - Essence and Accident in Software Engineering ("Серебряной пули нет - сущность и акциденция в программной инженерии") - эссе fred-brooks 1986 года, впервые представленное на 10-й всемирной компьютерной конференции IFIP, а позже перепечатанное в юбилейном издании The Mythical Man-Month (1995). В нём делается конкретное количественное предсказание о продуктивности разработки ПО:

Не существует ни одного отдельного открытия, будь то в технологии или в методах управления, которое само по себе обещало бы хотя бы на порядок повысить продуктивность, надёжность или простоту в течение десятилетия.

Брукс обосновал это делением трудностей разработки ПО на две категории, заимствуя терминологию Аристотеля:

Сущность (Essence): трудности, присущие самой природе программного обеспечения. Концептуальная конструкция - наборы данных, связи между ними, алгоритмы, вызовы функций. Спецификация, проектирование и тестирование этой конструкции. Брукс считал, что именно здесь кроется самая сложная часть создания ПО и что именно в ней сосредоточена основная масса трудностей.

Акциденция (Accident, случайная сложность): трудности, сопутствующие производству ПО, но не присущие ему изначально. Ручное управление памятью, синтаксический бойлерплейт, муторное развёртывание, неудобный инструментарий. Они меняются в зависимости от языка, платформы и эпохи. Автоматическое управление памятью устраняет один класс случайных трудностей, сборка мусора - другой.

Математическая основа предельно проста. Если вы хотите десятикратного роста продуктивности исключительно за счёт сокращения случайных трудностей, эти трудности должны составлять не менее 90% всех трудозатрат. Если они составляют меньше, вы математически не сможете достичь десятикратного выигрыша, как бы полностью их ни устранили. Брукс считал, что уже в 1986 году случайная сложность составляла менее 90% от общего объёма, а каждое следующее улучшение воздействовало на всё меньшую оставшуюся долю - поэтому отдача от работы исключительно над случайной сложностью была ограниченной и убывающей.

Это не утверждение о том, что ничего не работает. Брукс прямо подчёркивал: "Скептицизм - это не пессимизм... Дисциплинированные, последовательные усилия по разработке, распространению и практическому применению [многообещающих новшеств] действительно должны дать выигрыш на порядок. Царского пути нет, но путь есть".

Четыре сущностных свойства

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

Сложность (Complexity). Программные сущности устроены сложнее относительно своего масштаба, чем, пожалуй, любое другое творение человека: выше уровня отдельных инструкций в программе нет двух одинаковых частей. Если они появляются, их выносят в подпрограмму. Масштабирование программы - это не повторение одних и тех же элементов, а рост числа различных элементов, взаимодействующих нелинейно. Сложность растёт быстрее размера. Из этой сложности вытекают все классические проблемы: трудности коммуникации в команде, ненадёжность (слишком много состояний, чтобы их перечислить), неудобство использования (слишком много функций для понятного вызова), хрупкость (расширение без побочных эффектов) и дыры в безопасности (неучтённые состояния). Главная мысль: "описания программной сущности, абстрагирующиеся от её сложности, часто абстрагируются от её сущности". Упрощённые модели работают в физике, потому что отбрасываемая сложность не является сущностным свойством. В программном обеспечении сложность и есть сущность.

Согласованность (Conformity). Физика опирается на веру в существование единых объединяющих принципов - Эйнштейн считал, что природа должна быть объяснимой, поскольку Бог не злонамерен. Инженер-программист лишён такого утешения. Значительная часть сложности произвольна и навязана человеческими институтами и системами, созданными разными людьми в разное время. Интерфейсы различаются не из-за необходимости, а из-за исторического контекста. ПО вынуждено подстраиваться, потому что появилось позже всех или потому что его считают наиболее податливым. Эту сложность согласования невозможно устранить архитектурным дизайном - она навязана извне.

Изменяемость (Changeability). Любое успешное ПО подвергается изменениям. Этому способствуют две силы: пользователи, которым нравится базовая функция и которые переносят её в новые области, и платформа, эволюционирующая снизу (новое железо, новые ОС, новые дисплеи). Программное обеспечение воплощает функцию, а люди постоянно хотят менять именно функцию. В отличие от зданий, где высокая стоимость переделки сдерживает прихоти, ПО представляет собой "чистую мысленную материю, бесконечно пластичную" - это означает, что любое давление в сторону изменений действительно приводит к их реализации. Программный продукт погружён в культурную матрицу приложений, пользователей, законов и аппаратных платформ, и всё это непрерывно меняется.

Невидимость (Invisibility). У ПО нет естественного геометрического представления. У здания есть поэтажный план, у микросхемы - принципиальная схема; ПО же представляет собой множество наложенных друг на друга ориентированных графов (поток управления, поток данных, зависимости, временная последовательность, пространства имён), которые обычно даже не являются планарными, не говоря уже об иерархичности. ПО нельзя увидеть так, как видно здание. Это лишает человеческий разум его самых мощных концептуальных инструментов и сильно затрудняет общение между разработчиками.

Прошлые прорывы решали случайные трудности

Брукс выделил три прошлых прорыва, которые дали реальный прирост продуктивности, и все они атаковали случайную сложность:

Языки высокого уровня - самый мощный единичный шаг в сторону роста продуктивности. Переход от машинного кода к абстрактным конструкциям (операциям, типам данных, управляющим последовательностям) устранил целый уровень сложности, никогда не являвшийся неотъемлемой частью программы. Но наибольший выигрыш принёс именно первый переход. Каждый последующий подъём на новый уровень даёт убывающую отдачу, а в определённый момент усложнение языка скорее увеличивает интеллектуальную нагрузку, чем снижает её.

Разделение времени (Time-sharing) - сохранило непосредственность работы, позволив программистам удерживать общую картину сложности вместо потери контекста при пакетной обработке. Была устранена случайная трудность (медленная обратная связь), причём отдача убывает по мере приближения времени отклика к порогу восприятия человеком (~100 мс).

Единые среды программирования (Unix, Interlisp) - атаковали случайную трудность совместного использования программ. Интегрированные библиотеки, единые форматы файлов, пайпы и фильтры. Они позволили создать инструментальные наборы, где каждый новый инструмент можно было применить к любой программе благодаря стандартным форматам.

Кандидаты в серебряные пули (все отвергнуты)

Далее в эссе рассматриваются технологии, продвигавшиеся как потенциальные серебряные пули:

  • Ada - "всего лишь ещё один язык высокого уровня, а наибольшая отдача от таких языков была получена при первом переходе". Брукс предсказывал, что главным вкладом Ada станет обучение программистов современному проектированию, а не конкретные возможности языка.
  • ООП (абстрактные типы данных + иерархические типы) - устраняет "случайную трудность более высокого порядка", позволяя разработчику выражать сущность без синтаксических накладных расходов. Однако "подобные достижения способны лишь убрать все случайные трудности из выражения проекта. Сложность самого проекта остаётся сущностной".
  • AI - Брукс использовал разделение Парнаса: у AI-1 (компьютеры решают задачи, ранее требовавшие человеческого интеллекта) значение "постоянно сдвигается", и за этим термином нет очерченного набора уникальных технологий. AI-2 (экспертные системы) заслуживал отдельного рассмотрения.
  • Экспертные системы - самая многообещающая технология AI, но её обязательное условие - наличие эксперта. Узким местом становится извлечение знаний (поиск способных к самоанализу экспертов, умеющих формулировать мысли, и перенос их знаний), что и является реальным ограничением.
  • Автоматическое программирование - Парнас: "автоматическое программирование всегда было эвфемизмом для программирования на языке более высокого уровня, чем тот, что был доступен программисту в данный момент". Брукс доказывал, что сложнейшая часть - это спецификация задачи, а не её решение, и этот подход работает только для задач, "легко описываемых относительно небольшим числом параметров" и имеющих "множество известных методов решения". Это прямой мостик к современному написанию кода с помощью LLM. См. подробный анализ применения у Беннетта в no-silver-bullet-llms.
  • Визуальное программирование - "Из этих попыток пока не вышло ничего хотя бы убедительного, не говоря уже о захватывающем. Я убеждён, что ничего и не выйдет". ПО - это множество наложенных друг на друга непланарных ориентированных графов; проектирование СБИС - это многослойный 2D-объект, геометрия которого отражает его суть. Эта аналогия "в корне обманчива".
  • Верификация программ - мощный инструмент для таких вещей, как защищённые ядра ОС, но "верификация требует столь колоссальных усилий, что верифицировать удалось лишь считанные крупные программы". Кроме того, идеальная верификация доказывает лишь соответствие спецификации, а ведь "самая трудная часть задачи создания ПО - получение полной и непротиворечивой спецификации".
  • Среды и инструменты - "задачи с наибольшей отдачей были атакованы первыми и уже решены". Дальше отдача будет предельно малой.
  • Рабочие станции - прирост мощности полезен, но "десятикратное ускорение компьютеров наверняка сделает время на обдумывание доминирующей статьёй расходов".

Многообещающие подходы к концептуальной сущности

Брукс не был настроен сугубо отрицательно. Он предложил четыре стратегии, которые действительно бьют по сущностной сложности:

Покупка вместо разработки (Buy versus build). "Самое радикальное из возможных решений при создании ПО - не создавать его вовсе". Массовый рынок - глубочайший долгосрочный тренд: разделение затрат на разработку между n пользователями умножает продуктивность в n раз. Брукс отмечал, что между 1960-ми и 1980-ми годами те же самые готовые пакеты ПО прошли путь от отвержения (слишком специфичные) до повсеместного внедрения не потому, что изменились пакеты, а потому, что изменилось соотношение стоимости железа и софта. Покупатель машины за 2 миллиона долларов мог позволить себе заказной софт для начисления зарплат; покупатель машины за 50 тысяч долларов подстраивал свои процессы под готовый пакет.

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

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

Выдающиеся проектировщики. "Главный вопрос о том, как развить искусство разработки ПО, как и всегда, упирается в людей". Хорошие архитектурные решения рождаются из хороших практик; великолепные - из выдающихся проектировщиков. "Разница между выдающимися и средними специалистами приближается к порядку". Брукс сравнивал это с Сальери и Моцартом: методология может расширить возможности творческого ума, но не способна вдохновить ремесленника. Он доказывал, что организациям следует выявлять, растить и поощрять выдающихся проектировщиков с тем же усердием, с каким они ищут первоклассных менеджеров.

Дополнительная оценка

В книге Брукса Mythical Man-Month есть сопутствующая количественная оценка: примерно 5/6 времени при решении программной задачи уходит на вещи, отличные от написания кода. Это ограничивает выигрыш в продуктивности от ускорения только кодинга величиной примерно в 1.2x - существенно меньше того, что, по мнению самого Брукса, можно получить, просто наняв хороших программистов (он ссылался на исследование Сакмана, Эриксона и Гранта, показавшее разницу в продуктивности 10:1 среди опытных разработчиков).

Совокупный вывод: даже технология, полностью устраняющая написание кода, не даст десятикратного роста продуктивности разработки ПО, поскольку 83% работы кодингом не являются.

Почему это актуально и сейчас

В этом десятилетии эссе исполняется 40 лет. Инструментарий разработки продвинулся колоссально: сборка мусора, типобезопасные языки, менеджеры пакетов, облачное развёртывание, CI/CD, фреймворки для тестирования, IDE, системы контроля версий, вывод типов. Каждый из них атаковал конкретную случайную сложность. Ни один не дал десятикратного выигрыша, о невозможности которого предупреждал Брукс.

Сущностные трудности, описанные Бруксом, никуда не делись. Составлять спецификации по-прежнему трудно. Проектировать по-прежнему трудно. Проверять соответствие программы неточной спецификации по-прежнему трудно. Сложность по-прежнему нелинейно растёт с масштабом. ПО по-прежнему подстраивается под произвольные внешние интерфейсы. Успешное ПО по-прежнему меняется. ПО по-прежнему невидимо.

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

Ссылки на эту страницу

  • no-silver-bullet-llms - применение аргументации Брукса к программированию с помощью LLM у Беннетта
  • cult-of-vibe-coding - дисциплина чтения кода как способ удержать человеческий контроль над сущностной работой
  • building-syntaqlite-ai - вывод Лалита о том, что "проектирование нельзя делегировать", как переформулировка тезиса о сущностной сложности
  • clean-code-coding-agents - структура кода для кодовых баз, читаемых агентами, как атака на случайную сложность
  • vamp-ai-frontend - явные паттерны вместо неявных фреймворков как снижение случайной сложности для LLM