«Если что, поднимем и разберемся». Пять ступеней вниз
Это материал занятия, блок на сорок пять минут, который я готовил для обучающей площадки. Здесь он без вебинарной механики: вопросы, которые на занятии уходят в чат, в тексте вы задаете себе сами. Публикую отдельно, потому что он и без аудитории отвечает на то, о чем меня чаще всего спрашивают.
Цель. Разобрать, что происходит с процессом, который исполняется по правилам без постоянного участия человека, и что должно быть записано в момент решения, чтобы спустя год это решение можно было объяснить. Отдельно разобрать место ИИ в таком процессе и границу его полномочий.
Начнем с вопроса. Он простой, и ответ на него у вас точно есть. Вопрос только в том, за сколько времени.
Возьмите операцию, которую ваша система провела вчера сама. Не спорную, не инцидент, а обычную, каких тысячи. Какое условие ее пропустило? И в какой редакции это условие было именно вчера, а не сегодня?
Прикиньте честно: час, день, неделя, не соберем.
Запомните свой ответ. К концу он, скорее всего, изменится, и не потому, что я буду вас переубеждать.
Фраза, с которой все начинается
Ее произносил каждый, кто отвечает за процесс.
Если что случится, поднимем и разберемся.
Звучит разумно. За ней стоит уверенность, что прошлое доступно. Надо только знать, где смотреть, и потратить время.
Дальше я эту уверенность разберу по частям. В конце будет очень конкретный вывод, что с этим делать.
Ситуация одна на весь разбор. Год назад система приняла решение сама. Сегодня спрашивают, почему именно так. Кто спрашивает, неважно. Инцидент, аудит, спор с контрагентом, свой же продакт.
Ступень первая. Смотрим в отчет
С чего вы начнете? Скорее всего, откроете отчет или карточку операции.
И вот первая ловушка, самая незаметная из всех.
Отчет строится по тому, что записано. Если процесс упал до того, как что-то записал, в отчете его нет вообще. Не «нет данных», не «статус неизвестен». Его просто нет, как будто не было.
Отсюда следствие, из-за которого существует целый класс неприятностей. В отчете «не завершилось» и «не начиналось» выглядят одинаково: никак. Отличить одно от другого невозможно, потому что оба отсутствуют.
Проверить это просто. У вас наверняка есть метрика, сколько процессов запущено и сколько завершено. А есть ли список, какие не завершились? Это не то же самое, что разность двух чисел. Разность скажет количество, но не скажет, какие именно.
Вот почему про сбой обычно узнают снаружи. Не потому, что плохо смотрели. Потому что смотреть было не на что.
Ступень вторая. Поднимаем логи
Хорошо, скажете вы, у нас все логируется. Подробно, структурировано, с трассировкой.
Скорее всего, правда.
Только журнал по своей природе фиксирует действия. Шаг, время, результат, код возврата. Это ответ на вопрос «что произошло».
А спрашивают «на основании чего». Это другая запись, и подробность тут не помогает. Можно иметь терабайт логов и не иметь ответа. Сколько ни увеличивай детальность записи о действии, она не превратится в запись о причине.
И вот что здесь неприятнее всего. Основание нельзя дописать потом. Действие восстанавливается по следам: оно оставило изменения в данных, вызовы к соседям, отметки времени. Основание существует только в момент принятия решения. Если его тогда не записали, его больше нет нигде.
Ступень третья. Записываем правило
Логично. Будем записывать основание, то есть какое правило сработало. Многие так и делают, и это уже сильно лучше среднего.
Записали. Правило RULE-114.
Год спустя открываем RULE-114 и читаем.
И читаем сегодняшний текст. Потому что записан был идентификатор, а идентификатор указывает на правило, а не на его тогдашнее содержание. Правило за год переписали, может быть, десять раз. Номер тот же.
Здесь эта ступень хуже предыдущей, и вот чем.
Когда не записано ничего, вы это знаете и осторожничаете. Когда записан идентификатор, вы уверены, что основание у вас есть. Открываете, читаете уверенно и строите на этом позицию.
Неполная запись опаснее ее отсутствия. Она дает ложную уверенность, а ложная уверенность стоит дороже незнания.
Ступень четвертая. Храним редакции
Хорошо. Версионируем правила. Записываем не номер, а номер и версию. Это встречается редко, но встречается.
Достали мартовскую редакцию. Прогоняем случай.
Каким входом?
Здесь стоит остановиться, потому что вся ступень в этом вопросе.
Прогон берет данные. Данные у вас сегодняшние. Сущность с марта изменилась: другой статус, другие лимиты, другая история, другие связи. Прогон правильных мартовских правил по сегодняшним данным дает результат, который не был получен ни в марте, ни сегодня. Он вообще ниоткуда.
И выглядит совершенно нормально. Правила исторические, вы это проверили и в это верите. Про данные вы не подумали, потому что данные ощущаются как часть случая, а не как переменная.
Дальше две дороги, и обе плохие.
Первая. По полученному ответу выходит, что решение было неверным. Вы признаете ошибку, которой не было: тогда все отработало как положено.
Вторая. Вы чувствуете, что не сходится, но доказать нечем. Отвечаете обтекаемо. Тот, кто спрашивал, читает это как уход от ответа. И читает правильно: вы действительно ушли, просто не по своей воле.
Ступень пятая. Снимок данных
Последняя попытка, и она честная. Сохраняем снимок данных на момент решения. Правила по версиям, данные снимком. Теперь-то воспроизведем?
Смотрим, из чего еще состоял вход.
Справочники и реестры. Они обновляются, они не ваши, и запросить их «по состоянию на март» нельзя. Там нет такой ручки, потому что владельцу она не нужна.
Ответы внешних сервисов. Это разовые события. Повторный запрос сегодня даст новый ответ, а не тот же самый.
И собственная система. Код переписан, конфигурация другая, версии зависимостей обновлены. Даже с теми же входами она сегодня работает не так, как работала тогда.
Вот вывод, к которому мы шли.
Воспроизведение как метод не работает. Не потому, что вы плохо подготовились или мало вложили. Потому что часть входа вам не принадлежит и никогда не принадлежала.
Значит, фраза «если что, поднимем и разберемся» неверна целиком. Разобраться потом нельзя. Можно только прочитать то, что записали тогда.
Пять ступеней одной таблицей.
|
Что делаем |
Чего не хватает |
|---|---|
|
Смотрим отчет |
Упавшее до записи в нем отсутствует. «Не завершилось» и «не начиналось» выглядят одинаково |
|
Поднимаем логи |
Журнал отвечает, что произошло. Основание это другая запись, и дописать ее потом нельзя |
|
Пишем, какое правило сработало |
Записан идентификатор. Через год он приведет к сегодняшнему тексту |
|
Храним редакции правил |
Прогон берет сегодняшние данные. Верные правила по неверным данным дают ответ ниоткуда |
|
Сохраняем снимок данных |
Справочники, ответы внешних сервисов и сама система вам не принадлежат |
Это переворачивает задачу. Она перестает быть задачей про расследование и становится задачей про то, что положить в запись в момент решения. Расследование это работа с тем, что осталось. А что останется, решается один раз и заранее.
Кстати, это и ответ на вопрос из начала. Вы прикидывали, за сколько соберете. Правильный ответ: за столько, сколько решили полтора года назад, когда проектировали. Сегодня на это уже нельзя повлиять никак.
Что должно остаться
Пять записей, и все пять делаются во время работы, а не потом.
|
Что записать |
Почему именно так |
|---|---|
|
Какое условие сработало |
Не итог, а правило, по которому он получен. В большинстве систем записан именно итог, а причина восстанавливается по памяти того, кто настраивал |
|
В какой редакции оно было в тот момент |
Не ссылка на правило, а его содержание на ту дату. Ссылка через год приведет к текущему тексту, и подмену не заметить |
|
На каких данных |
Снимок значений на момент решения, а не ссылка на сущность. Сущность живая, и сегодня в ней другое |
|
Какие условия еще проверялись и почему не сработали |
Отрицательный результат должен быть виден так же, как положительный. Иначе «проверили и не сработало» и «не проверяли» выглядят одинаково |
|
Кто или что решило и когда |
Автоматика с версией конфигурации. Человек с названием роли |
Так выглядит четвертый пункт, когда он есть. Сработавшее условие сверху, под ним проверенные и отклоненные, у каждого зачеркнуто свое условие и значение, по которому оно не прошло.
Пример на кадре игрушечный намеренно: кофейный автомат, потому что его устройство понятно без объяснений и не отвлекает на предметную область.
Отдельно про модели
Про языковые модели в исполняющемся процессе спрашивают все.
Новых проблем они не создают. Они обостряют уже описанные.
У обычного правила ответ выведен из условия. Есть строка, на которую можно показать пальцем. У модели ответ не выведен, он порожден. Строки нет. Вы возвращаетесь на вторую ступень, где журнал говорит, что произошло, но не говорит, на основании чего. Только теперь основания нет не потому, что его забыли записать, а потому что его не существует в читаемом виде.
Задайте один и тот же вопрос одной и той же модели дважды. Ответы будут разные. Это ее свойство, а не сбой. Обновили версию, сменили поставщика, поправили системную инструкцию, и прежнего ответа больше нет нигде.
И третье, самое практичное. Модель, поставленную на шаг, который считают некритичным, обычно ставят туда со спокойной душой. Она разобрала обращение и определила его тип. Тип определил маршрут. Маршрут определил срок и исполнителя. Срок нарушен.
Модель не приняла ни одного критичного решения. Ни одного. А исход критичный.
Некритичный шаг, стоящий перед критичным, делает критичным весь путь.
Отсюда единственная рабочая граница.
Список допустимого считают правила, а не модель. Модель предлагает, правило разрешает, система исполняет. Предсказуемой становится не модель, а граница ее полномочий.
Как это выглядит в записи. Сверху то, что ушло решателю: перечень разрешенных шагов, посчитанный правилами до обращения к нему, и контекст. Снизу то, что он предложил, и с каким обоснованием. Две разные записи, и предложение не равно исполнению.
Что можно проверить завтра
Пять вопросов к своей системе. Ни на один не нужно ничего внедрять. Это проверка, а не проект.
-
Есть ли список, какие процессы не завершились? Не «сколько запущено», а какие именно не дошли.
-
Что происходит при повторе запроса: выполнится второй раз или будет распознан как повтор? И сколько живет ключ, по которому распознается?
-
Написано ли где-нибудь, что делать, если процесс упал на середине, а компенсация тоже упала?
-
Записана ли редакция условия содержимым или ссылкой?
-
Сохраняется ли дословный ответ внешнего сервиса или только то, что вы из него достали?
С четвертым и пятым осторожнее. На них почти всегда отвечают «да, конечно». Попросите показать. Не потому что вам врут, а потому что отвечающий имеет в виду «у нас это есть», а вопрос был про то, как именно.
Откуда это
Из 10 лет работы с системами, которые исполняют процессы без человека, и из разбора чужих аварий. Это не обзор рынка и не исследование: если у вас устроено иначе, значит иначе, и мне это интереснее любого подтверждения.
Как именно реализовать перечисленное, в статье нет намеренно. Это отдельный разговор, а список из пяти вопросов проверяется без всякой реализации.
ссылка на оригинал статьи https://habr.com/ru/articles/1078322/