10 октября 2021 г.

Тестирование конфигурации: aftermath через 5 лет

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

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

31 августа 2021 г.

Ironies of automation

В 1983 году когнитивный психолог Лизанна Бэйнбридж опубликовала статью "Ironies of automation"1, о человеческом факторе в автоматизации. Статья – одна из наиболее цитируемых в области human-machine systems, о ней даже есть отдельная страница на википедии 2.

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

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

Операторы не держат руку на пульсе

Поскольку автопилот исключает операторов из штатного управления системой, операторы перестают держать руку на пульсе, теряют situational awareness – не очень понимают, что в системе происходит сейчас, что может произойти в будущем, и что с этим делать.

Почему операторы перестают держать руку на пульсе пока работает автопилот?

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

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

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

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

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

Деградируют навыки операторов

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

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

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

И что с этим делать

Автор утверждает, что придумать можно много чего, но мало что реально сработает. По-сути, рабочих варианта два: надо либо обеспечивать операторам опыт управления системой, либо смириться с тем, что оператор не сможет справиться с нештатной ситуацией на ходу.

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

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

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

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

Насколько это универсально

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

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

Потеря диагностик при автоматизации тоже узнаваема: скрипт или программа автоматизации обычно обращается к нескольким системам, у каждой из которых свои диагностики (логи, алерты). Если пропускать все диагностики "насквозь" – получается слишком много диагностик. Тщательно разбираться, какие диагностики и для чего действительно нужны – обычно лениво, да и зачем? Ведь кажется, все это теперь не нужно, раз задачу выполняет программа – только отвлекать человека будет. Как и замечает автор статьи: очень тянет спрятать куда-нибудь все 100500 строк логов, и оставить только "doing: the right things… right things: done". И все выглядит красивенько и аккуратненько – пока не случится что-то нештатное, и не придется разбираться, где что пошло не так. И вот тут-то оказывается, что нештатность давно и прямым текстом проявлялась на какой-то диагностике, которую я замел под ковер.

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

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

Это как с релизами: классический подход к увеличению надежности системы – релизить реже, тестировать тщательнее. Более современный подход – релизить как можно чаще, и за счет этого отработать механизмы выкладки, отката, мониторинга, feature flags, graceful degradation…

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

Автоматизация это не замена человека машиной

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

И надежность работы системы определяется не надежностью одного только автопилота, а надежностью системы (человек+автопилот): большинство нештатных ситуаций обрабатываются именно на границе между машиной и человеком. Успешность обработки этих нештатных ситуаций – зависит от того, насколько хорошо отлажено взаимодействие вдоль этой границы. Большинство аварий возникает из-за плохого взаимодействия между человеком и машиной на этой границе – но и большинство потенциальных аварий предотвращается за счет правильной и своевременной реакции человека.

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

Этот аспект глубже раскрывают две другие статьи: "Ten challenges for making automation a team player in joint human-agent activity" и "How to make automated systems team players"3.

Cтатьи более свежие (2004 и 2018 годы), и авторы в них обсуждают вопрос: если автоматизация это никогда не замена человека машиной, а всегда совместное решение задачи человеком и машиной – то как должна выглядеть и вести себя такая машина, чтобы человеку-оператору было максимально удобно с ним работать? Как должен выглядеть автопилот, чтобы на границе человек-автопилот возникало как можно меньше напряжений? (Лизанна Бейнбридж в 1983 году, видимо, на такой вопрос еще не замахивалась)

Ответ на этот вопрос, если совсем кратко: автопилот должен быть максимально похож на коллегу – оператора.

Если задуматься, то это не очень удивительно: мы же социальные животные, наш мозг самой природой (эволюцией) вылеплен чтобы работать в команде с другими людьми. Самый лучший интерфейс между человеком и машиной – тот, который близко имитирует интерфейс между людьми.

Что конкретно авторы имеют в виду под похожестью на коллегу-человека? В первую очередь: предсказуемость поведения автопилота, и его послушность. Поведение автопилота должно быть для человека прозрачным: человек должен понимать, что делает автопилот, какова цель его действий, что он собирается делать в будущем, насколько он близок к границе своей компетентности. И автопилот должен принимать команды от человека, в более-менее человеческих терминах – не в виде коэффициентов PID-регуляторов, а в таком виде, в котором человек сам думает о задаче, и мог бы поставить задачу коллеге.

Даже это уже непросто реализовать, но авторы утверждают, что и этого недостаточно: чтобы автопилот действительно был "членом команды", все это должно работать в обе стороны: не только человек ставит задачи автопилоту, но и автопилот может попросить человека что-то сделать: "я не могу выполнять свою задачу, пока вот эта подсистема работает нештатно – не мог бы ты разобраться и наладить?.." Не только поведение автопилота (цели, намерения, границы компетентности) должно быть понятно человеку, но и поведение человека должно в какой-то степени быть "понятным" автопилоту 4

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

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

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

Примечания

  1. Ironies of automation, Lisanne Bainbridge, 1983↩︎

  2. wiki:Ironies of Automation↩︎

  3. Ten challenges for making automation a "team player" in joint human-agent activity, G. Klien, D.D. Woods, et all.

    How to make automated systems team players, K. Christoffersen, D.D. Woods.

    Все статьи (вместе с Ironies of automation) рекомендованы во введении в Resilience engineering: Where do I start? на гитхабе.↩︎

  4. На bashorg было: мол, как научить программу понимать, что если пользователь один раз кликнул мышкой – то это значит "вставить тут", а если пользователь судорожно тычется мышкой везде, и постояно кликает – это значит "да хватит уже тут вставлять!"↩︎

15 августа 2021 г.

Примеры зачастую полезнее объяснений

Я тут осознал, что сильно недооценивал роль примеров (examples) для технической документации. Документация очень сильно выигрывает от хороших примеров. Продуманные примеры могут быстро сориентировать читателя – ввести в курс дела, и облегчить понимание более детального описания. Более того, хорошо подобранные примеры способны сходу предоставить читателю (= пользователю) решение конкретной проблемы, без необходимости вообще вникать в детали. Вообще, кажется, есть много сценариев, где наиболее практичная документация == правильно подобранный набор примеров с краткой аннотацией.

Конечно, не новость, что примеры нужны, важны, и полезны. Но эти полезные примеры нередко оказываются рассеяны среди большого количества текста. При том, что примеры часто гораздо полезнее этого текста, и могли бы заменить бОльшую его часть.

4 августа 2021 г.

Никто не читает документацию

В комментариях к передыдущему посту я спорил с этим утверждением, но потом порефлексировал над своим собственным опытом, и передумал: нет, и правда, почти никто.

Если аккуратнее: никто не любит читать документацию, никто не любит искать ответы на свои вопросы в документации.

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

28 июля 2021 г.

Умение понятно писать – один из самых недооцененных инженерных навыков

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

Я сейчас не говорю о техническом писательстве как профессиональном навыке. Я говорю о более поверхностном – но и более универсальном – умении излагать свои мысли письменно, связно и понятно для читателя.

Конечно, есть миллион других навыков, которые не помешали бы инженеру, но я выделяю этот, потому что это low hanging fruit: большинство инженеров уже умеют думать, и уже хорошо разбираются в предмете. Не хватает, по-моему, малого – немного научиться думать о читателе.

20 июля 2021 г.

What makes a rule complex (for brain): mechanical sympathy applied to humans

Интересная статья 2020 года: "What makes a rule complex?". Что делает правило (алгоритм) сложным для выполнения человеческим мозгом?1

Мы часто оцениваем стоимость выполнения алгоритма: на какой-то абстрактной машине, или на реальном железе (конечном автомате, машине Тьюринга, Intel Core i7…). А что насчет человеческого мозга? Если смотреть на мозг как вычислительную машину, и скармливать ему разные "программы" – описания алгоритмов на человеческом языке – то насколько "дорого" для мозга будет выполнить действия соответственно описанию? Как цена выполнения алгоритма мозгом будет зависеть от устройства алгоритма?

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

14 июня 2021 г.

Cores that don't count: "тихие" производственные дефекты процессоров

TL;DR: Инженеры гугла утверждают, что примерно 0.1% современных процессоров содержат дефекты, ускользнувшие от техконтроля производителя, из-за чего некоторые инструкции на таких процессорах втихую дают неправильный результат. Вероятно, доля таких производственных дефектов будет расти. Вероятно, пора отвыкать думать о процессоре как об идеальном вычислителе, и искать способы создавать такие программные системы, которые обнаруживают и компенсируют ошибки CPU.

В твиттере проскочил очень интересный доклад Питера Хошчилда (Peter H. Hochschild) из гугл на конференции HotOS 20211

Питер со своей командой обнаружили, что в современных процессорах существует заметное количество скрытых дефектов ("mercurial errors"), которые более-менее регулярно приводят к неверным результатам вычислений. Вероятно, это дефекты производства, которые просочились сквозь техконтроль производителя.

24 мая 2021 г.

Когда имеет смысл передавать IO в отдельный поток?

Допустим, у нас есть простая система, которая принимает запросы из сети, как-то их обрабатывает ("бизнес-логика"), и отправляет результат назад, в сеть. Мы заинтересованы в быстром отклике (=latency), а отправка – это IO, так что возникает идея ее снести в отдельный поток.

Но тогда придется передавать данные из основного потока в поток отправки – а межпоточная коммуникация это какие-то накладные расходы (копирование, инструкции синхронизации, т.п.)

Стоит ли вообще игра свеч, и если стоит – то когда?

27 марта 2021 г.

Рабочие заметки в помощь мозгу

Давно уже хотел написать об этом, но только сейчас дошли руки:

Комрады! Пишите рабочие заметки – о чем вы думаете, над чем работаете – особенно если думаете о чем-то достаточно сложном. Это очень, очень, очень помогает думать! (И не только думать)

Вот уже несколько лет я практически все рабочие и личные задачи обсуждаю с большим файлом notes.txt (notes.org). Этот файл решает сразу несколько задач:

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