Material: Anhang D. Schwellenwertkalibrierung

Lektion 1 von 5 im Modul «Anhang D. Schwellenwertkalibrierung»
Sie sehen die Lektion ohne Anmeldung an. Anmelden, um Ihren Fortschritt zu speichern und Tests zu absolvieren.

Приложение D. Калибровка порогов

Это справочное приложение. На первом проходе оно не нужно: учебный минимум каждой главы рассчитан на пороги по умолчанию для AgentClinic-production. Этот файл собирает все таблицы «Низкий / По умолчанию / Высокий», упражнения по сдвигу порогов и сигналы, по которым порог нужно пересматривать. Используйте его при переносе процесса в свой проект, когда стандартные значения перестали подходить.

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

D.1 Мутационное тестирование (глава 5)

Числа главы 5 — значение по умолчанию для AgentClinic-production со средним потоком инцидентов и зрелым SDD-процессом. В вашем проекте пороги зависят от цены пропуска P0, сложности графа маршрутов, SLA-окна CI и стабильности входящего потока. Сдвиг любой строки должен сопровождаться записью в validation.md с обоснованием.

Параметр проектаНизкийПо умолчанию (AgentClinic)Высокий

| Цена пропуска P0 | strict_reject_rate ≥ 0.92 | **≥ 0.98** | ≥ 0.995 (платежи, здравоохранение) | | Сложность графа маршрутов | depth_of_diagnostics ≥ 2 (≤10 рёбер) | **≥ 3** (10–50 рёбер) | ≥ 5 (>100 рёбер, multi-tenant) | | SLA-окно CI | recovery_time_p95_ms ≤ 800 | **≤ 1200** | ≤ 1500 (>500 PR/день) | | Стабильность потока инцидентов | 1 мутант на класс | 2 мутанта на класс | 5+ мутантов на класс + ротация зерна |

Упражнение

cd book2/examples/stress-mutator

mkdir -p out
cp expected/expected_failures.json out/expected_failures_depth5.json
sed -i 's/"depth_of_diagnostics_min": 3/"depth_of_diagnostics_min": 5/' out/expected_failures_depth5.json

python3 scripts/immunity_score.py \
  --validator-results out/validator_results.json \
  --expected expected/expected_failures.json \
  --out out/immunity_default.json

python3 scripts/immunity_score.py \
  --validator-results out/validator_results.json \
  --expected out/expected_failures_depth5.json \
  --out out/immunity_depth5.json

Первый запуск должен пройти: средняя глубина диагностики равна 4 и превышает порог 3. Второй запуск должен завершиться кодом 1: тот же валидатор уже не проходит искусственно ужесточённый порог depth_of_diagnostics_min = 5. Дельта показывает не новый дефект в мутантах, а цену ужесточения порога.

Когда пересмотреть порог

  • За квартал ни одно слияние не заблокировано порогом — он избыточно низкий.
  • Больше 10 регрессий с одним и тем же mutation_id за неделю — depth_of_diagnostics недостаточен, увеличить.
  • recovery_time_p95 падает к нулю при росте strict_reject_rate — признак Гудхарта.
  • Появился новый класс инцидентов — пересчитать все три порога заново.
  • Одно зерно (seed) повторяет тот же набор mutation_id пять спринтов подряд — нужна ротация зерна.

Риск: если strict_reject_rate растёт, а depth_of_diagnostics одновременно падает, это симптом Гудхарта. Оба параметра двигают только парой.

D.2 Отбор теневых спецификаций (глава 6)

Веса 0.5*mttr_gain + 0.3*early_signal + 0.2*coverage - 0.4*false_escalation и пороги keep/reject — значения по умолчанию для AgentClinic-production. В вашем проекте они зависят от цены ложной эскалации, важности раннего сигнала, размера исторической базы и доступного бюджета на образцы-подсказки.

ПараметрНизкийПо умолчанию (AgentClinic)Высокий
Цена ложной эскалацииштраф false_escalation: 0.2–0.3**0.4**0.6–0.8 (здравоохранение, платежи)
Важность раннего сигналавес early_signal: 0.2**0.3**0.4–0.5 (радиус последствий >5 сервисов)
Размер исторической базы20–50 кейсов (дымовая проверка)50+ кейсов200+ кейсов с ротацией окон
Бюджет образцов-подсказокkeep-threshold 0.80, 4 слота**0.70, 8 слотов / 2000 токенов**0.60, 12 слотов / 4000 токенов

Упражнение

Прогоните аукцион с консервативным профилем риска (выше штраф за ложную эскалацию):

cd book2/examples/shadow-auction
python3 scripts/score.py --candidates candidates/candidates.yaml --incidents data/incidents.jsonl --weights "0.3,0.4,0.2,0.8" --out out/scorebook.json

python3 scripts/decide.py --scorebook out/scorebook.json --budget-tokens 2000 --keep-threshold 0.70 --reject-threshold 0.40 --out-auction out/auction.json --out-quarantine out/quarantine.json

При таком профиле shadow.p0.voice_handoff переезжает из winner в disputed, а shadow.alert.red_color_urgency остаётся в rejected. Это проявление нового профиля: команда меньше награждает сокращение MTTR и сильнее штрафует ложную эскалацию.

Когда пересмотреть порог

  • За месяц ни один winner не показал положительного эффекта в пост-мортемах — keep-threshold слишком низкий.
  • Доля disputed устойчиво выше 40% — формула не различает кейсы.
  • В одной фазе выбирается больше 8 победителей — budget-tokens подобран без учёта размера QWEN.md.
  • Появился новый класс инцидентов вне исторических данных.
  • mttr_gain и false_escalation растут вместе — симптом Гудхарта.

Риск: штраф false_escalation и вес mttr_gain двигают только парой. Сдвиг одного без пересмотра другого ломает связь «полезный сигнал ↔ ложный шум».

D.3 Ярусные бюджеты (глава 9)

Бюджет 10M токенов с разбиением 9M/1M (local/frontier) — значение по умолчанию для AgentClinic-production со средним потоком инцидентов. В вашем проекте размер бюджета и пропорции зависят от потока инцидентов, средней стоимости фазы, доли спорных ревью и чувствительности к падению local-coder.

Параметр проектаНизкийПо умолчанию (AgentClinic)Высокий
Поток инцидентов в сутки≤50/день → 2–3M токенов, 90/10200/день → 10M, 9M/1M (90/10)≥500/день → 25–40M, 80/20
Стоимость фазы (токенов)~20K~50K100K+ (многошаговый реплей)
Доля спорных ревью≤5% → frontier 5–7%~10% → 1M (10%)15–25% → 15–20% frontier
Чувствительность к падению local-coder≤1 раз/месяц → резерв 5%2–4 раза/месяц → 7%еженедельно → 15% + дублированный провайдер

Упражнение

cd book2/examples/budget-keeper

python3 scripts/compile.py --budget-spec specs/budget_network_5m.yaml --out out/budget_plan_5m.json
python3 scripts/simulate.py --plan out/budget_plan_5m.json --scenario scenarios/fail_local_45m.json --out out/fail_result_5m.json

python3 scripts/inspect.py --result out/fail_result_5m.json --query "failover_to_frontier==2 && degraded_queue==18 && token_health_min>=0.5"

Проверьте, удержался ли token_health_min выше 0.5 при половинном бюджете. В готовом 5M-варианте пропорции сохранены: local-ярус получает 4.5M, frontier — 0.5M. Если изменить только daily_budget_tokens, но не фазовые квоты, compile.py обязан упасть с ошибкой суммы.

Когда пересмотреть порог

  • За месяц ни одного срабатывания degraded_mode — бюджет избыточен либо реальный поток ниже ожидаемого.
  • token_health_min уходит ниже 0.5 чаще раза в неделю — локального яруса недостаточно.
  • failover_to_frontier устойчиво равно 0 при отказах локального яруса — шлюз слишком жёсткий, frontier не работает как страховка.
  • Доля manual_queue после ручного тайм-аута растёт два месяца подряд — manual_timeout_sec слишком короткий.
  • В сутки тратится менее 60% daily_budget_tokens — пора сжимать бюджет.

Риск: разделение 9M/1M связано с SLA по фазам. Сдвигать его без обновления budget_plan_phases в спецификации нельзя — frontier перестанет вмещать «спорные» кейсы.

D.4 Защита метрик от Гудхарта (глава 10)

Пороги silent_p0 ≤ 5%, manual_review_rate ≥ 15%, edge_drift ≤ 0.12, audit_trace_coverage = 1.0 — значения по умолчанию для AgentClinic-production. В вашем проекте они зависят от цены пропущенного P0, доступности ручных рецензентов, динамики входящего потока и регуляторных требований к аудиту.

Параметр проектаНизкийПо умолчанию (AgentClinic)Высокий
Цена пропущенного P0silent_p0 ≤ 8%**≤ 5%**≤ 1–2% (платежи)
Доступность ручных рецензентовmanual_review_rate ≥ 8%**≥ 15%**≥ 25% (регуляторно)
Динамика входаedge_drift ≤ 0.20**≤ 0.12**≤ 0.05 (сезонные пики)
Регуляторика аудитаaudit_trace_coverage ≥ 0.95**= 1.00**= 1.00 + подписанная трассировка

Упражнение

cd book2/examples/goodhart-validator

mkdir -p out

# Скопировать spec в локальный out/ и ослабить silent_p0_cap до 0.08
cp specs/validation.yaml out/validation_loose.yaml
sed -i 's/threshold: 0.05/threshold: 0.08/' out/validation_loose.yaml

python3 scripts/run_validation.py \
  --validation out/validation_loose.yaml \
  --metrics fixtures/new_metrics_bad.json

# Опасный вариант: ослабить сразу две независимые защиты
cp specs/validation.yaml out/validation_unsafe.yaml
sed -i 's/threshold: 0.15/threshold: 0.10/' out/validation_unsafe.yaml
sed -i 's/threshold: 0.05/threshold: 0.20/' out/validation_unsafe.yaml

python3 scripts/run_validation.py \
  --validation out/validation_unsafe.yaml \
  --metrics fixtures/new_metrics_bad.json

Первый прогон должен остаться красным: плохой релиз с silent_p0=0.18 всё ещё нарушает silent_p0_cap. Второй, опасный, вариант проходит только потому, что одновременно ослаблены две независимые защиты. Это показывает, почему guard-метрики нельзя калибровать по одной строке YAML.

Когда пересмотреть порог

  • За квартал ни один релиз не заблокирован silent_p0_cap — либо команда не делает рискованных изменений, либо порог избыточно мягкий.
  • manual_review_rate падает три спринта подряд при росте mttr_gain — симптом Гудхарта, ручные рецензенты перестали быть страховкой.
  • edge_drift стабильно колеблется около 0.10–0.11 — реальная динамика входа близка к порогу.
  • audit_trace_coverage опустился ниже 1.0 хоть в одном прогоне — нарушение регуляторного инварианта, hot-fix, не калибровка.
  • Появился новый класс инцидентов, который не попадает в silent_p0, — нужны новые инварианты, не пересмотр старых.

Риски: silent_p0 и manual_review_rate двигают только парой. edge_drift имеет смысл только при audit_trace_coverage=1.0, иначе дрейф вычисляется по частичной выборке. Все четыре порога образуют единый контракт риска: ослабить один в отрыве от остальных — значит сломать его, а не настроить.

Полная сеть метрик

В тексте главы используется упрощённая mermaid-схема с тремя метриками и одним сторожем. Полная сеть зависимостей выглядит так:

flowchart LR
    MTTR[MTTR]
    silent_p0[silent_p0]
    manual_review_rate[manual_review_rate]
    escalation_rate[escalation_rate]
    postmortem_regression[postmortem_regression]
    audit_trace_coverage[audit_trace_coverage]
    silent_p0 -->|положительная_взаимозависимость| MTTR
    escalation_rate -->|положительная_взаимозависимость| MTTR
    manual_review_rate -->|отрицательная_взаимозависимость| MTTR
    manual_review_rate -->|отрицательная_взаимозависимость| escalation_rate
    audit_trace_coverage -->|отрицательная_взаимозависимость| escalation_rate

audit_trace_coverage -->|отрицательная_взаимозависимость| silent_p0
    postmortem_regression -->|положительная_взаимозависимость| audit_trace_coverage
    postmortem_regression -->|отрицательная_взаимозависимость| manual_review_rate

Логика та же, что в упрощённой версии: красная зона — MTTR и silent_p0; путь к её ослаблению идёт через сокращение ручной проверки и потерю аудит-следа.

D.5 Production-готовность (глава 11)

Порог 23/25 — значение по умолчанию для AgentClinic-production со средней зрелостью SDD-процесса и смешанным типом действий. В вашем проекте порог зависит от цены ошибки переключения (cutover), зрелости процесса, нагрузки на ручное ревью и характера действий (stateless / stateful).

Параметр проектаНизкийПо умолчанию (AgentClinic)Высокий
Цена ошибки переключениявнутренний инструмент: 21–22/25 только полуручносмешанный production: auto ≥23/25платежи/здравоохранение: auto ≥24/25
Зрелость SDD-процесса3 месяца → только полуручной 20–226+ месяцев → полуручной 20–22, auto 23+12+ месяцев + 50+ реплеев → auto 23+, меньше ручных остановок

| Нагрузка ручного ревью | каждый пулл-реквест (~5/неделю) → можно держать 21–22 полуручно | 20–30% пулл-реквестов → auto 23+ | редко → auto 24/25 | | Тип действия | stateless → 22/25 только canary/полуручно, auto 23+ | смешанный → auto 23+ | stateful → auto 24+ и backup_verified |

Упражнение

Скрипт check_readiness.py хардкодит THRESHOLD = 23. Прогоните с другим значением через копию:

cd book2/examples/real-api && mkdir -p out
cp scripts/check_readiness.py out/check_readiness_t22.py
sed -i 's/THRESHOLD = 23/THRESHOLD = 22/' out/check_readiness_t22.py
python3 out/check_readiness_t22.py --readiness fixtures/readiness_block_audit.json

При THRESHOLD = 22 readiness_block_audit.json всё равно блокируется из-за audit_trace_coverage=0.7 < 1.0, хотя сумма 22/25 проходит. Это показывает, что audit_trace_coverage — независимый блокирующий инвариант, а не часть суммы. Упражнение про чувствительность порога, а не рекомендация снижать auto-допуск.

Когда пересмотреть порог

  • За квартал ни одна готовность не заблокирована порогом — он слишком низкий для текущей зрелости команды.
  • Доля полуручных инцидентов растёт три спринта подряд — порог 23/25 не достигается из-за системного пробела в Verification или Process.
  • Появился класс действий с stateful=true — требуйте backup_verified и поднимите порог по этому классу до 24/25.
  • Все провалы готовности в течение месяца идут по одной оси — это пробел в шаблонах SDD; исправлять шаблоны, а не двигать порог.
  • Время сборки артефактов готовности превышает SLA на переключение — пересмотрите, какие баллы можно автоматизировать, а не снижайте порог.

Риск: порог 23/25 несовместим с нулевым баллом по Security при любой сумме — такой провал блокирует слияние независимо от итога. Снижение ниже 23/25 меняет режим эксплуатации: это уже не auto-допуск, а полуручной или canary-режим. Даже «low» (21/25) — это остановка после каждого implement-шага и явное подтверждение оператора, а не право агента выполнить ремедиацию самостоятельно.

Meine Notizen
0 / 10000

Notizen werden in diesem Browser gespeichert. Auf anderen Geräten erscheinen sie nicht.

Kursmenü

Kurs

Verwendung von SDD in der Entwicklung für Qwen Code CLI. Praktischer Kurs
Fortschritt 0 / 95