Files
progcode/editorial/agent-rewrites/041.json
T

8 lines
26 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"index": 41,
"slug": "editorial-2026-11-mechanism-technology-evaluation",
"title": "Как сравнивать технологии, если данных пока мало",
"excerpt": "Практический способ отделить наблюдение от предпочтения: как зафиксировать критерии, остановить псевдоточный выбор и подготовить проверяемое решение.",
"contentHtml": "<p>Команда сравнивает два runtime для одной операции. В демо вариант A отвечает быстрее, а вариант B проще выглядит в коде. Через неделю появляется таблица с баллами 8,7 и 7,9, но в ней нет версии окружения, размера входа, числа повторений и стоимости перехода. Симптом узнаваем: число выглядит точным, однако его нельзя связать с конкретной нагрузкой.</p>\n<p>Цена ошибки проявится после выбора. Код окажется на неподходящей границе, обучение и сопровождение займут больше времени, а сбой объяснят «шумом измерения». Вернуться трудно, потому что исходные условия не записали. Поэтому сравнение технологии — не конкурс инструментов и не поиск вечного победителя. Это проверка конкретного решения: что нужно узнать, что действительно измерено, где остаётся неопределённость и какие предпочтения принимает владелец.</p>\n<h2>Начните с вопроса, а не с названия технологии</h2>\n<p>Хороший вопрос задаёт границу решения. Формулировка «какой runtime лучше» не имеет проверяемого ответа. Вопрос «какой вариант уменьшает работу по миграции для сериализации объекта размером 1 МБ, сохраняя текущий формат API и возможность отката» уже указывает операцию, вход, ограничение и ожидаемое действие.</p>\n<p>Разделите запись на четыре слоя. Вопрос говорит, какое решение предстоит принять. Наблюдение описывает результат конкретного запуска: например, длительность операции, число ошибок или расход памяти. Неопределённость показывает, какие условия могут изменить результат. Предпочтение задаёт приоритет: команда может считать обратимость важнее небольшой разницы в задержке.</p>\n<p>Эти слои нельзя подменять. Вес 40 не доказывает пригодность варианта. Балл 3 не означает, что инструмент в три раза лучше варианта с баллом 1. Фраза «надёжнее» не заменяет путь отказа и способ его воспроизвести. Если значение неизвестно, его нужно записать как <code>unknown</code>, а не превращать в аккуратный ноль.</p>\n<h2>Зафиксируйте границу сравнения</h2>\n<p>До запуска назовите одну операцию и её начало и конец. Для сериализации это может быть время от передачи подготовленного объекта функции до получения строки. Не смешивайте его с чтением файла, сетевым вызовом и записью в лог: тогда измерение отвечает уже на другой вопрос.</p>\n<p>Запишите вход в форме, которую можно получить снова: размер и структура данных, кодировка, число элементов, допустимые ошибки. Затем закрепите версию runtime, зависимости, операционную систему, процессор и параметры запуска. «Та же машина» недостаточно, если неясно, менялись ли фоновые процессы, режим энергопотребления или сборщик мусора.</p>\n<p>Отдельно опишите успех и остановку. Успехом может быть завершение операции без потери данных при заданном лимите времени. Остановкой — исключение, неверный результат, нарушение формата или отсутствие входной конфигурации. Правило остановки не даёт команде компенсировать критический дефект высоким баллом по второстепенному критерию.</p>\n<figure><img src=\"/assets/editorial/2025/year-synthesis-2025-decision-cost-observation-matrix.svg\" alt=\"Матрица отделяет зафиксированное решение, принятую стоимость и наблюдение от неподтверждённого утверждения об эффекте\" loading=\"lazy\" /><figcaption>Наблюдение, стоимость и решение отвечают на разные вопросы. Пока граница сравнения и неизвестные не названы, утверждать эффект рано.</figcaption></figure>\n<h2>Как отличить evidence от впечатления</h2>\n<p>Evidence — это не любое число в таблице, а число с происхождением и условиями получения. Минимальная запись измерения должна отвечать на пять вопросов: что измеряли, каким входом, в какой версии, сколько раз повторили и как обработали разброс. К ней полезно приложить сырые результаты или ссылку на артефакт, который другой инженер сможет открыть.</p>\n<p>Официальные руководства по измерительной неопределённости требуют описывать компоненты, влияющие на результат, а не публиковать только итог. Это не означает, что для каждой внутренней проверки нужна лабораторная методика. Это означает, что команда должна отличать случайное колебание от изменения условия и не называть единичный запуск устойчивым фактом.</p>\n<p>Документация Python <code>timeit</code> хорошо показывает практическую ловушку: замер может зависеть от других процессов, поэтому серия запусков полезнее одного значения, а в типичном случае нужно смотреть на весь вектор результатов, а не механически вычислять среднее. Это рекомендация конкретного инструмента, не универсальная статистическая формула. Для своей операции заранее выберите правило: диапазон, квантили, минимум или другой показатель — и объясните, почему он отвечает на вопрос.</p>\n<p>Практика воспроизводимых артефактов в ACM добавляет ещё один критерий: результаты должны быть связаны с описанными кодом, данными, версиями и инструкцией запуска. Для инженерного выбора это означает простой тест: сможет ли коллега восстановить условия без устного пояснения автора? Если нет, таблица пока фиксирует мнение, а не проверяемое сравнение.</p>\n<h2>Таблица диагностики: симптом → причина → проверка → действие</h2>\n<div class=\"table-scroll\"><table><caption>Проверка инженерного сравнения до выбора технологии</caption><thead><tr><th scope=\"col\">Симптом</th><th scope=\"col\">Причина</th><th scope=\"col\">Проверка</th><th scope=\"col\">Действие</th></tr></thead><tbody><tr><td>Есть итоговый балл, но нет входных условий</td><td>Локальное наблюдение выдали за общий результат</td><td>Найти версию, вход, нагрузку и границу операции</td><td>Убрать итог и записать недостающие условия</td></tr><tr><td>Веса появились после демо</td><td>Предпочтение подогнали под понравившийся результат</td><td>Сравнить время изменения веса с моментом получения результата</td><td>Вернуть веса на обсуждение до нового замера</td></tr><tr><td>Написано «одинаковая среда»</td><td>Конфигурацию спрятали за общей фразой</td><td>Раскрыть версии, зависимости, входы и лимиты</td><td>Остановить сравнение до явной конфигурации</td></tr><tr><td>Есть среднее, но нет разброса</td><td>Неопределённость потеряли при агрегации</td><td>Проверить сырые прогоны и правило обработки вариации</td><td>Показать диапазон или назвать значение неизвестным</td></tr><tr><td>Вариант назван лучшим во всех условиях</td><td>Компромисс заменили универсальным рейтингом</td><td>Проверить, какие свойства ухудшаются у «победителя»</td><td>Описать trade-off и границу применимости</td></tr></tbody></table></div>\n<h2>Сделайте стоимость перехода измеримой</h2>\n<p>Стоимость внедрения начинается не с цены лицензии. Для каждой альтернативы перечислите обучение, изменение кода, перенос данных, интеграцию со сборкой и мониторингом, документацию, дежурство и откат. Не подставляйте часы из другого проекта: их можно использовать как гипотезу, но не как факт.</p>\n<p>Фраза «миграция простая» становится проверяемой только после уточнения объёма. Сколько модулей затронуто? Какое окно простоя допустимо? Что считается сохранёнными данными? Можно ли вернуть старую реализацию без ручного исправления записей? Если ответ неизвестен, добавьте отдельное поле и владельца следующей проверки.</p>\n<p>Полезно считать стоимость не одной суммой, а набором наблюдаемых работ. Тогда выясняется, что вариант с коротким happy path может требовать дорогой диагностики, а вариант с более длинной миграцией — дешёвого и надёжного отката. Число помогает сравнить зафиксированный объём, но не отменяет описания предположений.</p>\n<h2>Вес критерия — договорённость, а не метрика</h2>\n<p>Взвешенная матрица делает приоритеты видимыми. Например, команда может назначить пригодности вес 40, стоимости перехода 35, эксплуатации 25. Сумма 100 удобна как контроль записи, но не превращает шкалу в физическую величину. Вес отвечает на вопрос «что для нас важнее», а evidence — на вопрос «что мы наблюдали».</p>\n<p>Для каждого веса задайте вопрос-владелец. Пригодность: какую границу задачи обязан закрыть вариант? Стоимость: какие работы входят и что делает откат обратимым? Эксплуатация: кто заметит отказ, по какому сигналу и за какое время восстановит систему? Если на один критерий нет ответственного и способа проверки, оценка должна остановиться.</p>\n<p>Не складывайте в один score несовместимые ограничения. Если потеря данных недопустима, это veto-условие, а не минус пять баллов. Если допустимая задержка превышена, высокая оценка документации не делает вариант подходящим. Сначала отсекайте запрещённые состояния, затем сравнивайте оставшиеся компромиссы.</p>\n<h2>Учебный валидатор: положительный вывод только после проверки</h2>\n<p>Ниже приведён самостоятельный пример на JavaScript. Он не запускает runtime, не читает файлы и не объявляет технологию победителем. Функция проверяет структуру плана: обязательные поля, сумму весов, наличие условий измерения и отсутствие неизвестного evidence. В настоящем проекте эти поля должны заполняться из разрешённых артефактов.</p>\n<pre><code>function validateComparison(plan) {\n const required = ['question', 'alternatives', 'criteria', 'measurement'];\n\n if (!required.every((key) =&gt; key in plan)) {\n return { status: 'stop', reason: 'missing-field' };\n }\n\n const weights = plan.criteria.reduce(\n (total, criterion) =&gt; total + criterion.weight,\n 0,\n );\n const hasMeasurement = Boolean(\n plan.measurement.input &amp;&amp;\n plan.measurement.version &amp;&amp;\n plan.measurement.repetitions &gt; 1 &amp;&amp;\n plan.measurement.rawResults,\n );\n const hasUnknownEvidence = plan.criteria.some(\n (criterion) =&gt; criterion.evidence === 'unknown',\n );\n\n if (weights !== 100) {\n return { status: 'stop', reason: 'invalid-weight-total' };\n }\n if (!hasMeasurement || hasUnknownEvidence) {\n return { status: 'stop', reason: 'insufficient-evidence' };\n }\n\n return { status: 'ready-for-review', winner: null };\n}\n\nconst plan = {\n question: 'compare one fixed serialization operation',\n alternatives: ['runtime-a', 'runtime-b'],\n criteria: [\n { name: 'fit', weight: 40, evidence: 'unknown' },\n { name: 'adoption-cost', weight: 35, evidence: 'unknown' },\n { name: 'operations', weight: 25, evidence: 'unknown' },\n ],\n measurement: {\n input: '1 MB JSON',\n version: 'pinned',\n repetitions: 0,\n rawResults: null,\n },\n};\n\nconsole.log(validateComparison(plan));\n// { status: 'stop', reason: 'insufficient-evidence' }</code></pre>\n<p>В примере сумма весов равна 100, но evidence неизвестен, повторений нет, а сырые результаты отсутствуют. Поэтому результат — <code>stop</code>. Это полезнее, чем выдать случайный score: следующий шаг становится конкретным — описать протокол, получить разрешённые данные и сохранить исходные прогоны.</p>\n<p>Валидатор проверяет форму, но не качество самого benchmark. Он не знает, реалистичен ли вход, корректна ли функция измерения, не влияют ли фоновые процессы, соблюдены ли лицензии и можно ли безопасно обработать данные. Такие вопросы требуют отдельной проверки и владельцев. Статус <code>ready-for-review</code> означает только, что план можно обсуждать на следующем уровне; он не разрешает rollout.</p>\n<h2>Воспроизводимость начинается до запуска</h2>\n<p>Сохраните конфигурацию рядом с результатом: версию runtime и зависимостей, хеш входного набора, параметры команды, число прогревов и повторов, модель оборудования, дату запуска и сырые значения. Если часть окружения нельзя раскрыть, зафиксируйте хотя бы её категорию и причину ограничения. «Локально» — не воспроизводимое описание.</p>\n<p>Разделяйте повторяемость и переносимость. Повторяемость проверяет, получаем ли мы близкие результаты при тех же условиях. Переносимость спрашивает, сохраняется ли вывод на другой машине, версии или нагрузке. Второй вопрос требует новых измерений. Нельзя объявлять его решённым потому, что один и тот же скрипт дважды дал похожее число.</p>\n<p>После изменения технологии повторите тот же сигнал на той же границе. Если одновременно поменялись вход, версия и способ измерения, это новый эксперимент. Его можно сравнить с прежним только после явного описания отличий. Такая дисциплина защищает от удобного вывода «стало быстрее», когда изменилась сама операция.</p>\n<h2>Порядок действий</h2>\n<ol><li>Опишите наблюдаемый симптом и цену ошибочного выбора без названия любимого инструмента.</li><li>Сформулируйте один вопрос, назовите альтернативы и задайте границу операции.</li><li>Зафиксируйте вход, версию, окружение, критерий успеха и условие остановки.</li><li>Разделите пригодность, стоимость перехода, эксплуатацию и отдельные veto-ограничения.</li><li>Назначьте владельца каждого критерия и объясните веса до получения результата.</li><li>Опишите число повторов, прогрев, сырые результаты и правило обработки вариации.</li><li>Отделите неизвестное от плохого результата: не заменяйте отсутствующее evidence нулём.</li><li>Проверьте отрицательный путь: исключение, неверный формат, частичный сбой, невозможность отката и скрытую конфигурацию.</li><li>Сравните варианты по каждому критерию, запишите компромисс и только затем сформулируйте решение владельца.</li></ol>\n<h2>Ограничения применимости</h2>\n<p>Эта методика не выбирает технологию автоматически и не создаёт данные из пустой таблицы. Она не заменяет security review, юридическую проверку лицензий, оценку доступности специалистов, accessibility-проверку, финансовую модель или план восстановления. Для критических систем одного учебного benchmark недостаточно.</p>\n<p>Не переносите результат между разными операциями. Быстрее сериализовать тестовый объект не значит дешевле обслуживать очередь. Удачный запуск на одной машине не доказывает поведение под пиковым входом. Если нагрузка, версии или требования изменились, границу нужно зафиксировать заново.</p>\n<p>Не используйте в примерах реальные секреты, идентификаторы клиентов и ссылки на закрытые панели. Если данные нельзя законно или безопасно собрать, корректный исход — <code>stop</code> с описанием недостающего доказательства. Отложенное решение лучше, чем рейтинг, который нельзя защитить.</p>\n<h2>Критерий готовности решения</h2>\n<p>Сравнение готово к решению, когда другой инженер без устного контекста может назвать операцию, вход, версии, повторы, критерии, веса и правила остановки. Для каждого числа видны источник и способ обработки. Для каждого неизвестного указаны владелец и следующий шаг. Для каждого варианта названы сильная сторона, цена внедрения, эксплуатационный риск и условие отката.</p>\n<p>Финальная проверка проста: временно уберите итоговый столбец и попросите коллегу перечислить, какие факты ещё нужны для выбора. Если разговор возвращается к входу, измерению и ограничениям, матрица помогает принимать решение. Если все защищают уже напечатанного победителя, таблица стала риторикой. Верните её к наблюдаемой проблеме.</p>\n<h2>Проверяемые источники</h2>\n<ul><li><a href=\"https://www.nist.gov/document/tn1297spdf\" target=\"_blank\" rel=\"noopener noreferrer\">NIST Technical Note 1297: Guidelines for Evaluating and Expressing the Uncertainty of NIST Measurement Results</a> — официальное руководство о компонентах неопределённости и полноте отчёта измерения. Оно не задаёт веса и не подтверждает учебные результаты.</li><li><a href=\"https://docs.python.org/3/library/timeit.html\" target=\"_blank\" rel=\"noopener noreferrer\">Python Documentation: timeit — Measure execution time of small code snippets</a> — официальная документация с оговорками о влиянии других процессов, серии запусков и трактовке результатов. Это пример конкретного инструмента, а не универсальный статистический рецепт.</li><li><a href=\"https://sigsim.acm.org/conf/pads/2024/blog/artifact-evaluation/\" target=\"_blank\" rel=\"noopener noreferrer\">ACM SIGSIM: Reproducibility and Artifact Evaluation</a> — официальная страница конференции ACM о документировании, полноте, согласованности и независимой проверке вычислительных артефактов. Она задаёт ориентир воспроизводимости, но не превращает инженерный выбор в научную публикацию.</li></ul>"
}