Системное мышление Диаграммы причинных связей: как строить и как проверять
0%

Диаграммы причинных связей: как строить и как проверять

Диаграммы причинных связей: как строить и как проверять

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

Разница между схемой и картинкой примерно такая же, как между тестом и комментарием в коде. Комментарий сообщает, что автор думал. Тест падает, когда автор ошибся. Причинная диаграмма (causal loop diagram, CLD) существует, чтобы быть тестом: каждая стрелка в ней — утверждение вида «изменение здесь через такое-то время меняет вон то в такую-то сторону», и каждое такое утверждение может оказаться ложным.

Проблема жанра в том, что диаграммы редко строят так. Типичная схема из презентации содержит пятнадцать облачков, стрелки без знаков, узлы «культура», «мотивация», «качество» — и абсолютную неуязвимость к любым данным. Она объясняет всё, что уже случилось, и не запрещает ничего из того, что случится завтра. Это дорогой способ выглядеть умным. Дальше — как получить обратное: нотация, процедура построения от наблюдаемого поведения, полный разбор с двумя версиями схемы (до проверок и после), батарея тестов, часть которых запускается в CI, и честный разговор о том, чего диаграмма не умеет в принципе.

Что такое причинная диаграмма

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

Три свойства отличают CLD от произвольной схемы со стрелками:

  1. Вершина — величина, а не событие и не сущность. «Очередь PR» — величина. «Релиз 4.2» — событие. «Команда платформы» — сущность. Величина растёт и падает; событие случается; сущность просто есть.
  2. Ребро — причинное утверждение со знаком, а не поток данных, не последовательность шагов и не «связано с».
  3. Граф замкнут хотя бы в одном месте. Дерево причин без обратных связей — не системная диаграмма, а разбор одного случая: полезная вещь, но другая.

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

Соседние нотации, которые постоянно путают

Половина плохих схем плоха не из-за ошибок, а из-за смешения трёх разных языков в одном рисунке.

Одна ситуация в трёх нотациях: CLD, диаграмма запасов и потоков, ациклический причинный граф

CLD отвечает на вопрос «какая структура могла бы породить наблюдаемое поведение». Она качественная: знаки есть, величин нет. Циклы допускает. Её проверка — сравнение предсказанной формы поведения с фактической.

Диаграмма запасов и потоков (stock-and-flow, SFD) отвечает на вопрос «какие будут числа во времени». Она различает уровень и темп, требует единиц измерения и начальных условий и переводится в систему уравнений напрямую; разница между уровнем и темпом разобрана в «Запасах и потоках».

Ациклический причинный граф (DAG в смысле Перла) отвечает на третий вопрос: «каков размер эффекта X на Y по наблюдательным данным». У него есть строгое исчисление вмешательств, критерий «заднего пути» и правила, когда контроль переменной помогает, а когда портит оценку. Цена строгости — запрет на циклы.

Отсюда самая дорогая методическая ошибка темы: инструменты причинного вывода к схеме с петлями напрямую неприменимы. Если в CLD есть контур A → B → A, никакой backdoor-критерий к нему не относится, пока вы не развернёте петлю во времени: $A_t \to B_{t+1} \to A_{t+2}$. Развёрнутая версия ациклична, и вот на ней машинерия работает. Практический вывод: хотите оценивать эффекты статистически — стройте не CLD, а временной DAG; хотите рассуждать о режимах поведения — стройте CLD и не притворяйтесь, что у вас есть оценка эффекта. Про подмену причинности корреляцией — «Причинные, вероятностные и статистические ошибки». Четвёртый язык, который тоже путают с CLD, — процессные и структурные схемы: BPMN, диаграммы последовательности, C4. Там стрелка означает «поток управления» или «вызов», а не «увеличивает»; схема архитектуры и причинная диаграмма одной системы похожи внешне и не совпадают почти нигде (см. BPMN).

Нотация Стрелка означает Циклы Что даёт на выходе
CLD «увеличивает / уменьшает» обязательны гипотезу о режиме поведения
SFD «поток вещества» или «информационная связь» да численный прогноз при заданных параметрах
Causal DAG «прямая причина» запрещены оценку эффекта из данных
BPMN / activity «дальше по процессу» да, как ветвления описание порядка действий
C4 / архитектура «вызывает / зависит» да карту компонентов

Минимальная нотация: шесть элементов

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

  1. Переменная — существительное-величина без оценки, названная так, чтобы рост был осмыслен: «длина очереди», а не «проблемы с очередью».
  2. Связь со знаком. «+» — при прочих равных рост причины повышает следствие; «−» — понижает. Формально это знак частной производной $\partial, \text{следствие} / \partial, \text{причина}$ в текущей рабочей точке.
  3. Метка задержки — две поперечные чёрточки на стрелке плюс порядок величины словами: «≈ дни», «≈ два спринта». Без порядка величины метка бесполезна.
  4. Ярлык контураR1, B2 и короткое имя-история: «B1: очередь спускают через слияния без ревью». Полярность — произведение знаков $s = \prod_i s_i$: чётное число минусов даёт R, нечётное — B.
  5. Внешняя переменная (exogenous) — то, что входит в схему, но не объясняется ею: сезонность, решение сверху, курс валюты. Помечайте явно, иначе читатель решит, что вы просто не дорисовали.
  6. Статус стрелкиизмерено (есть метрика и оценка), гипотеза (правдоподобно, не проверено), тождество (следует из определения: «пропускная способность падает — очередь растёт» по закону Литтла). Самый недооценённый элемент нотации: без него схема выглядит однородно достоверной, хотя половина её — догадки. А чего быть не должно: цвета как смысла, стрелок без знака, узлов-действий, «двойных» стрелок вместо двух отдельных связей и подписей длиннее пяти слов.

Правила именования переменных

Восемьдесят процентов негодных схем негодны из-за имён. Пять правил, каждое проверяется механически.

Правило 1. Тест роста. Про переменную должно быть осмысленно сказать «она выросла» и «она упала». «Время ожидания ревью выросло» — да. «Внедрить обязательное ревью выросло» — бессмыслица, значит, это действие, а не переменная. Действия на CLD не рисуют: их эффект выражается изменением какой-то величины.

Правило 2. Нейтральность. Имя не содержит оценки и отрицания. «Недостаток ревьюеров» — плохо: рост недостатка означает падение числа ревьюеров, и через два звена вы обязательно ошибётесь в знаке. Пишите «число доступных ревьюеров». Двойные отрицания в цепочке — самая частая причина неверной полярности.

Правило 3. Операционализуемость. У переменной есть ответ на вопрос «чем мерить и где это лежит». Не «качество кода», а «доля PR, потребовавших более двух раундов ревью»; не «мотивация», а «доля дежурств, закрытых добровольцами без напоминания». Прокси несовершенны, и это нормально: несовершенный измеримый прокси лучше идеального неизмеримого понятия. Как выбирать метрики и не разрушить их наблюдением — «Метрики» и «Измерение производительности».

Правило 4. Одна размерность на узел. «Нагрузка» — не переменная, а слово: это может быть RPS (темп), число активных задач (уровень) или доля занятого времени (безразмерная). Смешение уровня и темпа делает знаки бессмысленными. Правило 5. Одинаковый уровень агрегации: «латентность запроса к Redis» и «эффективность инженерной культуры» на одной схеме — верный признак, что границы не выбраны («Границы системы»).

Процедура построения: от поведения, а не от структуры

Пункт, который меняет качество результата сильнее всех остальных: начинать надо не с рисования узлов, а с графика. Если начать со структуры, вы нарисуете то, что и так знаете, и никогда не выясните, была ли схема нужна. Если начать с наблюдаемого поведения — реального графика реальной метрики за реальный период, — у схемы появляется мишень: она обязана это поведение воспроизвести хотя бы качественно. Такой график в системной динамике называют опорным режимом (reference mode).

Шаги, которые обычно делают плохо:

Горизонт определяет, что вообще попадёт в схему. Для шторма ретраев горизонт — минуты, и наём людей там не нужен; для техдолга горизонт — кварталы, и миллисекунды бессмысленны. Задаётся до переменных и пишется на самой схеме. Граница ведётся тремя явными списками: эндогенное (объясняем структурой), экзогенное (входы, принимаем как данность), исключённое (сознательно за бортом, с одной строкой обоснования). Третий список пропускают все — и потом ссорятся на разборе.

Замыкание. Не пытайтесь замкнуть всё: честная схема состоит из двух-четырёх контуров и нескольких открытых веток к исходам; если замкнулось абсолютно всё — вы дорисовали связи ради красоты. Предсказание формулируется до того, как вы посмотрели на данные после вмешательства, и записывается с датой: «если сделать X, метрика M за срок T изменится в сторону D не менее чем на V; если этого не произойдёт, я вычёркиваю стрелку A → B». Без последней части предсказание не считается.

Разбор: очередь ревью, версия первая

Возьмём знакомую боль: ревью пул-реквестов стало занимать дни, люди жалуются, «надо что-то делать». Вот схема, которую команда рисует на первой встрече за десять минут.

Схема выглядит осмысленно и никуда не годится — каждая из её ошибок встречается в девяти схемах из десяти.

  • «Внедрить обязательное ревью» — действие, а не переменная. Тест роста провален; на схеме должна быть «доля PR, слитых с апрувом» — величина, зависящая и от политики, и от поведения людей.
  • «Качество кода» и «мотивация» не операционализованы. Знак стрелки мотивация → качество не определён ни в какую сторону: он зависит от того, что имел в виду говорящий. Стрелка со знаком «?» — не осторожность, а признание, что связь не сформулирована.
  • «Нагрузка на команду» смешивает уровень и темп, а задержек и статусов нет вовсе: связь качество → баги — правдоподобная гипотеза, баги → время на исправления — почти тождество, но выглядят они одинаково.
  • Главное: схема не отвечает на исходный вопрос. Проблема была про время ожидания ревью — этой величины на схеме нет. Классический признак того, что рисовали от знакомых слов, а не от опорного режима.

Контур в схеме, впрочем, есть, и он верный: качество → баги → время на исправления → нагрузка → качество, два минуса, усиливающая петля. Тот случай, когда верная деталь не спасает целое — потому что вся конструкция не привязана ни к одному наблюдаемому графику.

Опорный режим и различающее предсказание

Вернёмся к шагу 0 и сделаем его как надо: берём одну метрику — медиану времени от открытия PR до первого ревью — и рисуем её за двадцать четыре недели.

Опорный режим и две конкурирующие гипотезы после вмешательства

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

  • Гипотеза A: «узкое место — мощность ревью». Заявок больше, чем часов у ревьюеров; петля одна, очередь растёт, пока приток превышает отток. Предсказание: добавьте двух ревьюеров — ожидание упадёт и останется низким.
  • Гипотеза B: «есть компенсирующая петля через размер PR». Когда ревью долгое, авторы копят изменения и шлют более крупные PR; крупный PR ревьюится дольше. Предсказание: добавьте двух ревьюеров — ожидание упадёт на две-три недели, затем размер PR подрастёт и ожидание вернётся почти к прежнему уровню.

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

Разбор: очередь ревью, версия вторая

Та же тема после правил именования, разметки задержек и статусов.

Что изменилось по существу. Первое: появилась переменная из исходного вопроса — «время ожидания ревью», метрика опорного режима; схема без величины из наблюдаемого графика не проверяема в принципе. Второе: три контура вместо одного, и у каждого есть история:

  • B1 — «спускаем очередь через обход». Ждать долго → часть PR сливают без апрува → очередь короче. Уравновешивающая петля, работает быстро и действительно снимает симптом: тот самый архетип «перенос проблемы» из главы «Системные архетипы».
  • R1 — «крупные PR». Ждать долго → авторы копят изменения → ревью каждого дороже → пропускная способность ниже → очередь длиннее. Усиливающая: два минуса.
  • R2 — «побочный эффект костыля». Обход ревью → дефекты в проде → люди заняты разбором инцидентов → пропускная способность ревью ниже → очередь длиннее → ещё больше обходов. Цена, которую B1 перекладывает на будущее.

Третье: видно соотношение времён — B1 действует за дни, R1 за недели, R2 за недели и месяцы, что проверяемо объясняет паттерн «сначала стало лучше, через квартал стало хуже, чем было»; при обратном соотношении времён паттерн был бы другим («Задержки»). Четвёртое: статусы честные — две связи помечены как гипотезы, время ожидания → размер PR и обход ревью → дефекты. Обе проверяются на исторических данных Git и трекера за пару часов, и до проверки конструкция остаётся правдоподобной догадкой. Схема с честными статусами сразу даёт план работ: не «обсудим ещё раз», а «выгрузим PR за год и посчитаем связь размера и задержки с поправкой на срочность релиза».

Батарея проверок

Схема готова не тогда, когда она красивая, а когда прошла проверки. Ниже — тесты, сгруппированные по тому, что они ловят.

Разберём те, что не сводятся к правилам именования.

Тест замыкания и висячих узлов. Если в графе нет ни одного цикла — это не CLD; возможно, она вам и не нужна (диаграмма Исикавы или дерево причин честнее описывают одноразовый разбор), но тогда не называйте схему системной и не делайте из неё выводов о динамике. У каждой вершины должен быть хотя бы один вход и один выход внутри схемы, иначе она обязана быть помечена как внешняя или как исход: висячий исток без пометки означает «я не подумал, откуда это берётся», висячий сток — «я не подумал, зачем это здесь».

Тест скрытого запаса — самая коварная ошибка CLD. Если между двумя переменными на самом деле стоит накопление, знак связи вводит в заблуждение: найм → численность команды — не «плюс», а поток, наполняющий запас, и при постоянном найме численность не постоянна, а растёт линейно. Правило: если фраза «A увеличивает B» корректнее звучит как «A увеличивает скорость роста B» — там запас, и его нужно либо отметить явно, либо переходить к диаграмме запасов и потоков. Именно эту слабость нотации разбирал Джордж Ричардсон в статье «Problems with causal-loop diagrams» (System Dynamics Review, 1986): полярность контура читается неоднозначно, когда связь проходит через уровень, и по одной CLD нельзя надёжно определить доминирующий контур.

Тест знака при прочих равных. На каждую стрелку — вопрос буквально: «если я подниму A и заморожу всё остальное, B станет больше или меньше?» Если для ответа приходится рассказывать историю через третью переменную, стрелка не элементарная — разбейте её. Рядом идёт тест монотонности. Знак не должен переворачиваться в рабочем диапазоне. Контрпример: число реплик → латентность отрицательно, пока реплики не начинают конкурировать за пул соединений к базе, и положительно после. Такую связь нельзя пометить одним знаком: либо сузьте диапазон и напишите его на схеме («верно до 40 реплик»), либо разбейте переменную, либо пометьте связь как нелинейную («Нелинейность и пороги»). Схема с фиксированными знаками всегда молча предполагает линейность.

Тест времён. У каждой стрелки — порядок величины: секунды, часы, недели, кварталы. Если у конкурирующих контуров времена различаются на порядок, исход определяет быстрый, и это важнее полярности. Нет ни одной оценки времени — схема не предсказывает даже качественно.

Тест соперника и тест опровержения. Нарисуйте вторую схему, объясняющую те же данные другой структурой. Не можете придумать соперника — вы не понимаете предметную область достаточно, чтобы что-то утверждать; можете, но не находите различающего наблюдения — обе схемы бесполезны для решений, и это надо сказать вслух. Затем на каждую стрелку — ответ на вопрос «какое наблюдение заставит меня её стереть»; стрелки без ответа декоративны: удалять не обязательно, опираться нельзя.

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

Тест Время Что ловит Как часто срабатывает
Рост, нейтральность, измеримость минуты негодные узлы почти всегда на первой версии
Размерность, скрытый запас минуты подмену уровня темпом часто
Замыкание, висячие узлы, размер автоматически недорисованность часто
Знак при прочих равных 10–20 минут неявные третьи переменные часто
Монотонность 10 минут молчаливое допущение линейности почти всегда там, где есть насыщение
Времена 15 минут неверный вывод о доминирующем контуре часто
Соперник, опровержение 30 минут нефальсифицируемость всегда, если раньше не делали
Опорный режим часы схему, которая не объясняет данные реже, но это самый дорогой провал

Что можно проверить автоматически

Структурные тесты незачем делать глазами. Если схема хранится как данные, проверки становятся обычным линтером в CI рядом с проверками разметки. Формат — текстовый, чтобы схема жила в репозитории и ревьюилась как код:

# docs/systems/review-queue.cld.yaml
horizon: "1-2 квартала"
exogenous: ["срочность релиза"]
outcomes: ["дефекты в проде"]
links:
  - {from: "очередь PR", to: "время ожидания ревью", sign: +1,
     evidence: "GitHub API: p50 времени до первого ревью"}
  - {from: "время ожидания ревью", to: "доля слияний без ревью", sign: +1, delay: "дни",
     evidence: "audit log: merge без approve"}
  - {from: "доля слияний без ревью", to: "очередь PR", sign: -1,
     evidence: "тождество: PR уходит из очереди"}

Псевдокод проверок:

для каждой вершины:
    нет исходящих и не помечена как исход  -> ошибка «висячий сток»
    нет входящих и не помечена как внешняя -> ошибка «висячий исток»
    имя похоже на действие                 -> ошибка «не величина»
для каждой связи:
    знак = 0        -> ошибка «немонотонная или несформулированная связь»
    нет обоснования -> ошибка «стрелка без статуса»
вершин больше 12    -> предупреждение «столько никто не проверит»
циклы <- все простые циклы графа связей
для каждого цикла:
    полярность <- произведение знаков рёбер   # чётное число минусов -> R, нечётное -> B
    вывести полярность, состав цикла и размеченные задержки
циклов нет -> ошибка «это дерево причин, а не системная диаграмма»

Нетривиальна здесь только одна часть — перечисление контуров; остальное сводится к пробегу по спискам. Разметка читается из YAML выше:

from dataclasses import dataclass


@dataclass(frozen=True)
class Link:
    """Причинная связь: «рост src меняет dst при прочих равных»."""
    src: str
    dst: str
    sign: int           # +1, -1 или 0 — «знак не определён»
    delay: str = ""     # порядок величины: "", "минуты", "дни", "недели"
    evidence: str = ""  # чем подтверждена: метрика, эксперимент, тождество


def build_graph(links):
    """Список смежности. O(V + E) по времени и памяти."""
    graph = {}
    for link in links:
        graph.setdefault(link.src, []).append(link)
        graph.setdefault(link.dst, [])
    return graph


def find_cycles(graph):
    """Все простые циклы. Каждый выдаётся один раз — начиная с минимальной вершины."""
    order = {name: i for i, name in enumerate(sorted(graph))}
    cycles, path, on_path = [], [], set()

    def dfs(start, node):
        for link in graph[node]:
            if order[link.dst] < order[start]:
                continue                       # вершины «младше» старта уже разобраны
            if link.dst == start:
                cycles.append(list(path) + [link])
            elif link.dst not in on_path:
                path.append(link)
                on_path.add(link.dst)
                dfs(start, link.dst)
                on_path.discard(link.dst)
                path.pop()

    for start in sorted(graph, key=lambda name: order[name]):
        on_path.add(start)
        dfs(start, start)
        on_path.discard(start)
    return cycles


def polarity(cycle):
    """Полярность контура — произведение знаков; ноль означает «неизвестна»."""
    product = 1
    for link in cycle:
        product *= link.sign
    return {1: "R (усиливающая)", -1: "B (уравновешивающая)", 0: "неопределена"}[product]


def report(links):
    for cycle in find_cycles(build_graph(links)):
        chain = " → ".join(link.src for link in cycle) + f" → {cycle[-1].dst}"
        delays = [link.delay for link in cycle if link.delay] or ["не размечены"]
        print(f"[петля] {polarity(cycle)}: {chain}; задержки: {delays}")

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

Сложность. Построение графа — $O(V + E)$ по времени и памяти. Перечисление простых циклов в общем случае экспоненциально: циклов может быть экспоненциально много, и наивный DFS вдобавок тратит время на бесплодные ветви. Классическое решение — алгоритм Джонсона, $O((V + E)(C + 1))$ по времени и $O(V + E)$ по памяти, где $C$ — число найденных циклов; в NetworkX он доступен как simple_cycles. Для CLD это академическая забота: при $V > 12$ схему всё равно надо резать, и не из соображений производительности (теория графов).

Чего автоматика не проверит: правильность знаков, осмысленность имён, отсутствие пропущенных переменных и соответствие реальности. Эвристика «имя похоже на глагол» даёт ложные срабатывания на нормальных существительных. Линтер ловит форму, а не содержание — как и линтер кода.

Диаграмма как артефакт репозитория

Схема, нарисованная на доске и сфотографированная, умирает за неделю. Схема в репозитории живёт ровно столько, сколько за ней следят, и у неё есть явный жизненный цикл.

Что делает это работающим:

  • Схема — текстовый файл, а не картинка. Формат неважен (YAML выше, mermaid, DSL инструмента) — важно, чтобы diff был читаемым и чтобы правка схемы попадала в тот же PR, что и правка системы.
  • Дата и автор на схеме. Схему без даты нельзя опровергнуть: всегда найдётся тот, кто скажет «мы это иначе имели в виду».
  • Журнал предсказаний рядом — файл со строками «дата — предсказание — срок — результат»; практика разобрана в «Ментальных моделях».
  • Опровергнутые схемы не удаляют. Запись «мы думали, что дело в мощности ревью, оказалось — в размере PR» стоит дороже трёх правильных схем: она экономит следующему человеку квартал.
  • Пересмотр — по событиям, а не по календарю: после крупного инцидента, при смене границы (реорганизация, вынос сервиса), при появлении данных по помеченным гипотезам.

Ревью схемы вместе с командой

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

Три правила, без которых сессия вырождается в спор: атакуют стрелки, а не людей (возражение обязано быть в форме «эта стрелка неверна, потому что…» или «здесь пропущена переменная…»); у каждой правки есть автор и статус («все согласились» — не статус); сессия заканчивается предсказанием или списком запросов к данным — если не вышло ни того, ни другого, встреча была бесполезной, и это нормально признать. Про несовпадающие описания одной системы — «Ментальные модели», про расходящиеся интересы участников — «Стейкхолдеры» и «Конфликты».

Пределы метода

Теперь честная часть, без которой глава была бы рекламой.

Диаграмма не даёт величин и потому не выбирает между режимами. Одна и та же схема описывает конфигурацию, которая работает годами, и конфигурацию, которая падает за сорок секунд. Наличие контура — не предсказание; предсказание требует чисел.

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

Диаграмма убеждает сильнее, чем обосновывает. Стрелки создают ощущение механизма независимо от того, есть ли за ними данные, и схема из пятнадцати узлов производит впечатление глубокого анализа при нулевой информативности. Учитывайте это, когда показываете схему руководству: вы применяете риторический инструмент («Когнитивные искажения»).

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

Ретроспективная подгонка почти неизбежна. После инцидента любая схема отлично объясняет случившееся; ценность имеет только схема, нарисованная до, и предсказание, записанное до. Про обманчивость разбора через цепочку причин хорошо написано у Джона Оллспо в «The Infinite Hows» и у Ричарда Кука в «How Complex Systems Fail».

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

Честно про доказательную базу

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

Что стоит твёрдо. Правило полярности как произведения знаков — арифметика; различение уровня и темпа — математика, а не мнение; ограничения нотации, описанные Ричардсоном, воспроизводятся на контрпримерах — можно построить две схемы с одинаковой петлевой структурой и разным поведением. На эксперименте стоит другое: систематическая неверная оценка обратной связи и задержек людьми — воспроизводимый лабораторный результат (Sterman, Management Science, 1989). Это довод за то, что интуиция здесь подводит и внешняя запись нужна, но не довод за конкретную нотацию.

Что остаётся спорным — и это главное. В 2000 году Джеффри Койл в System Dynamics Review поставил вопрос прямо: можно ли делать выводы, ограничиваясь качественными схемами без счёта? Джек Хомер и Роджелио Олива в ответной статье (2001) утверждали, что нельзя: без количественной модели выводы о динамике систематически ненадёжны, потому что человек не умеет в уме сворачивать несколько контуров с разными задержками. Спор не закрыт, и практическая позиция, которой стоит держаться: качественная схема — законный промежуточный артефакт и незаконный конечный результат. Как средство собрать гипотезу и договориться о словах — да; как основание для решения ценой в квартал — нет, если её никак не приземлили.

Что слабее, чем принято думать. Эффективность группового построения моделей оценивалась в основном по самоотчётам участников: люди сообщают, что стали лучше понимать проблему и охотнее принимают решение. Это правдоподобно и почти ничего не говорит о том, стали ли решения лучше; контролируемых сравнений «схема против отсутствия схемы» по объективным исходам практически нет. Отдельно про книги: Медоуз («Thinking in Systems») даёт лучший вводный язык и не даёт метода проверки. Сенге («Пятая дисциплина») популяризировал архетипы и вместе с ними стиль, где схема заменяет доказательство. Стерман («Business Dynamics») — единственный из массовых источников, где валидации отведена отдельная большая глава: если читать одну книгу по теме, читать стоит эту, но ради глав о проверке, а не ради красивых петель. Полемику вокруг «Пределов роста» разбирала глава о петлях; вывод тот же — чем крупнее объект модели, тем слабее её предсказательная сила и тем осторожнее должен быть тон.

Типичные ошибки

  1. Рисовать от структуры, а не от графика. Схеме без опорного режима нечего воспроизводить, значит, её нечем проверить.
  2. Узлы-действия и узлы-события. «Внедрить ревью», «случился инцидент» — не величины.
  3. Оценочные имена. «Проблемы с качеством», «недостаток людей» — гарантированная ошибка в знаках через два звена.
  4. Стрелка «связано с». Не можете сказать, в какую сторону влияет рост, — связи нет, есть ощущение.
  5. Смешение уровня и темпа в одном узле. «Нагрузка» — самый частый нарушитель; рядом стоит пропущенный запас между причиной и следствием (признак: фраза корректнее звучит как «увеличивает скорость роста»).
  6. Схема на двадцать пять узлов. Её никто не проверит, включая автора: режьте по границе на несколько схем с разными горизонтами.
  7. Одинаковый статус у измеренных связей и у догадок. Схема выглядит достовернее, чем есть, ровно на долю догадок.
  8. Отсутствие времён. Без них вывод о победившем контуре берётся из воздуха.
  9. Ретроспективная схема, выданная за предсказание. Нарисована после события — так и напишите на ней.
  10. Регрессия поверх схемы с петлями. Разверните во времени или не считайте.
  11. Схема как результат встречи. Результат — предсказание, запрос к данным или решение; схема — побочный продукт.

Инструменты

  • Текст + mermaid (mermaid.js.org) — если схема живёт в репозитории и её достаточно читать; все диаграммы этой главы сделаны так.
  • PySD (pysd.readthedocs.io) — Python-библиотека, читает модели Vensim и XMILE и считает их в обычном пайплайне с pandas: лучший способ перейти от схемы к числам, не покидая инженерных инструментов.
  • Vensim (vensim.com), Stella, Insight Maker (insightmaker.com) — среды с симуляцией и анализом чувствительности; Insight Maker бесплатен и работает в браузере. LOOPY (ncase.me/loopy) — игрушечный, но сразу показывает поведение петли во времени. Kumu (kumu.io) — для больших карт со стейкхолдерами, легко скатывается в декоративность.
  • STPA — метод анализа безопасности Нэнси Левесон, где вместо цепочек отказов рассматриваются петли управления и небезопасные управляющие воздействия («Engineering a Safer World» доступна свободно). Хороший пример того, как выглядит системное мышление, доведённое до проверяемой процедуры с чеклистами.

Чеклист перед тем, как показывать схему

  1. Есть ли график опорного режима и указан ли горизонт?
  2. Выписаны ли три списка: эндогенное, экзогенное, исключённое?
  3. Проходит ли каждый узел тесты роста, нейтральности и измеримости?
  4. Есть ли узел с метрикой из исходного вопроса?
  5. Знаки расставлены «от роста» и «при прочих равных»; помечены ли связи, знак которых переворачивается в рабочем диапазоне?
  6. Проставлены ли порядки величины задержек?
  7. У каждой стрелки есть статус: измерено / гипотеза / тождество?
  8. Замкнулось ли что-нибудь и названы ли контуры историями?
  9. Нет ли скрытого запаса между причиной и следствием?
  10. Нарисована ли альтернативная структура и найдено ли различающее наблюдение?
  11. Записано ли опровержимое предсказание с датой и сроком?
  12. Умещается ли схема в двенадцать узлов, объясняется ли за три минуты и лежит ли в репозитории в текстовом виде?

Если пунктов 10 и 11 нет — вы показываете не результат анализа, а рисунок.

Мини-итог

  • Причинная диаграмма — записанная гипотеза о структуре, а не иллюстрация; её ценность равна тому, что она запрещает.
  • CLD, диаграмма запасов и потоков и ациклический причинный граф отвечают на три разных вопроса; смешение — источник самых дорогих ошибок, включая попытки считать эффекты в графе с петлями.
  • Строить надо от наблюдаемого поведения: график, горизонт, граница, переменные, знаки, замыкание, задержки, предсказание.
  • Имена решают всё: величина, а не действие; нейтральное, а не оценочное; измеримое, а не концептуальное; одна размерность на узел.
  • Статус каждой стрелки — измерено, гипотеза или тождество — обязателен: без него схема выглядит достовернее, чем есть. Структурные проверки автоматизируются полусотней строк кода; содержательные — нет.
  • Главный приём: две конкурирующие структуры и наблюдение, которое их различает. Без соперника гипотеза не проверяется, а иллюстрируется.
  • Полярность контура не равна доминированию, а схема без чисел не выбирает между «работает годами» и «падает за минуту».
  • Спор о достаточности качественных схем идёт с 2000 года и не закрыт. Рабочая позиция: законный промежуточный артефакт, незаконный конечный результат.

Источники

  • John Sterman. Business Dynamics: Systems Thinking and Modeling for a Complex World (2000) — главы о причинных диаграммах и о валидации моделей.
  • George Richardson. Problems with causal-loop diagrams — System Dynamics Review, 1986; и его же возврат к теме в 1997. Журнал: onlinelibrary.wiley.com/journal/10991727.
  • Geoff Coyle. Qualitative and quantitative modelling in system dynamics: some research questions — System Dynamics Review, 2000; ответ: Jack Homer, Rogelio Oliva. Maps and models in system dynamics: a response to Coyle — там же, 2001.
  • John Sterman. Modeling Managerial Behavior: Misperceptions of Feedback in a Dynamic Decision Making ExperimentManagement Science, 1989.
  • Donella Meadows. Thinking in Systems: A Primer (2008) — chelseagreen.com; Judea Pearl, Madelyn Glymour, Nicholas Jewell. Causal Inference in Statistics: A Primerbayes.cs.ucla.edu/PRIMER.
  • Nancy Leveson. Engineering a Safer WorldPDF, MIT.
  • John Allspaw. The Infinite HowsO’Reilly Radar; Richard Cook. How Complex Systems Failhow.complexsystems.fail.
  • Google SRE Book: Postmortem Culture. System Dynamics Society — systemdynamics.org.

Что дальше

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

Дальше — Моделирование и его пределы: что модель не покажет.

Нашли неточность? Выделите фрагмент текста — рядом появится жучок.

Нужен разбор именно вашей ситуации?

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

Доска запросов