﻿# Успешный stream для SLO: определить событие и знаменатель

Как определить успешный inference stream для SLO: accepted, rejected, completed, failed, cancelled, частичные ответы и явный знаменатель good events.

Автор: Команда Retrivium
Обновлено: 2026-11-01
Канонический URL: https://retrivium.ai/ru/journal/provider-stream-success-sli-denominator/
Language: ru

Сервис может вернуть HTTP 200, затем завершить поток ошибкой. Если SLO считает только status, такой запрос попадёт в успехи, хотя пользователь не получил полный результат. Обратный случай — клиент отменил работу по собственному решению. Его нельзя автоматически приравнивать к сбою провайдера без выбранной политики. Надёжный SLI начинается с определения наблюдаемого события и знаменателя, а не с желаемого процента на панели.

## Определите границу операции

[Google SRE о SLO](https://sre.google/workbook/implementing-slos/) рекомендует связывать показатели с полезным пользовательским результатом. Для streaming нужно решить, что считается одной операцией: принятый запрос, завершённая попытка или логический запрос с несколькими попытками. Эти единицы дают разные знаменатели и не должны незаметно меняться между отчётами.

Запишите момент начала учёта и область сервиса. Если запрос отклонён до генерации, он может оставаться важным для доступности, хотя не вошёл в engine queue. Исключить его из метрики допустимо только по явному определению, а не потому, что так показатель выглядит лучше.

## Разделите terminal outcomes

Полезна классификация completed, failed, cancelled и incomplete, отдельно от accepted и rejected на входе. Состояния должны быть взаимоисключающими в выбранной итоговой записи. Если запрос меняет состояние, счётчик результата увеличивается один раз, а переходы сохраняются как диагностические события.

[Prometheus об instrumentation](https://prometheus.io/docs/practices/instrumentation/) подчёркивает согласованность подсчёта операций, ошибок и latency. Начатые и завершённые запросы могут расходиться в коротком окне. Поэтому denominator должен соответствовать выбранному способу измерения, иначе всплеск новых обращений будет выглядеть как изменение качества без достаточного основания.

## Проверьте полноту stream

[Документация OpenRouter](https://openrouter.ai/docs/api_reference/streaming) показывает, что ошибка после committed response приходит внутри SSE и не меняет уже отправленный HTTP-статус. Это делает status-only проверку недостаточной. Нужны прикладной итог, корректное framing и ожидаемые обязательные данные конкретного endpoint.

Не требуйте одинакового terminal marker для всех API. Схема Chat Completions отличается от других интерфейсов. В SLI-записи должны сохраняться endpoint и версия проверки, чтобы миграция не сделала все новые события неизвестными либо автоматически успешными из-за слишком общего fallback в parser.

## Задайте политику отмен

Разберите клиентскую отмену, превышение серверного deadline и принудительную остановку экземпляра. Внешне соединение может закрыться во всех трёх случаях, но ответственность и полезность различаются. Если причину нельзя установить, используйте отдельный unknown outcome вместо удобного предположения о действиях клиента.

Частичный текст может быть полезен приложению, но это не делает операцию полной автоматически. Продуктовая политика определяет, включается ли такой исход в good events. Сохраните правило и примеры рядом с метрикой, чтобы инженер и владелец продукта одинаково понимали результат.

## Испытайте знаменатель на fixtures

Создайте небольшой набор: полный успех, отказ допуска, ошибка до headers, ошибка внутри stream, отмена и обрыв без итога. Для каждого задайте expected outcome и участие в denominator. Затем проверьте, что итоговые счётчики совпадают с вручную подготовленной таблицей.

Связанные материалы — [ошибки stream](/ru/journal/openrouter-stream-errors/) и [отчёт о работе](/ru/journal/capacity-reporting/). Итогом является проверяемое определение SLI, а не обещание конкретного SLA. Без такой семантики даже точная арифметика good/total может измерять удобную внутреннюю активность вместо пользовательского результата.
