Воспроизводимость

docs.stripe.com · аудит 2026-07-27 · AgentFit v3.4.0 · рубрика v4 · Claude Opus 5

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

Спросить модель · 3 прогона

78 · 80 · 65 15 баллов разброса

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

Запустить AgentFit · 3 прогона

57 · 57 · 57 0 баллов разброса eabbb2f6abcdea473b600dc4ee8e25282fd002344f1e8425519caa32ff858b01 одна sha256 на три файла

Три живых аудита подряд, три JSON-файла, одна контрольная сумма. Это не кэш: каждый прогон заново ходил на сайт.

Читайте колонки сверху вниз, а не поперёк. Слева рубрика на 26 критериев, у AgentFit — 28, и веса у них разные: машиночитаемая спека стоит 25 баллов слева и 17 здесь. 57 — не «правильный ответ», а 78 — не «неправильный». Мы утверждаем меньше — и только это подтверждается данными: одна из двух процедур выдаёт одно и то же число каждый раз, вторая — нет.


Где прогоны разошлись

Все три прогона модели работали добросовестно: ходили по живым адресам, разбирали критерии по одному и докладывали то, что нашли. По нашему собственному подсчёту в транскриптах — которые мы не публикуем — каждый прогон сделал от 36 до 47 обращений к инструментам, и ни один ничего не выдумал. И то и другое считайте нашим прочтением прогонов, а не тем, что можно проверить по выложенным ниже файлам. И всё равно они разъехались на 15 баллов, из которых одиннадцать пришлись на одну категорию.

Суммы по категориям в трёх прогонах модели. Один сайт, один промпт, один день.
Категория Макс. A B C Разброс
A — Обнаружение181313121
B — Артефакты страницы221213121
C — Машиночитаемая спека2520211011
D — Содержание201819181
E — Рендеринг и гигиена151514132
Итого10078806515

Здесь смешаны расхождения двух сортов. Мелкие — A5, B3, B5, B6, D1, D3, D6, по баллу туда-сюда, в обе стороны — это то, чего мы и ждали бы от трёх внимательных читателей одной страницы: один нашёл вкладки SDK прямо в DOM, а двое решили, что они существуют только внутри JS-выдачи. Обычный ли это шум измерения — по трём прогонам сказать нельзя, тут мы гадаем. В опубликованных сводках видно только расхождение по D1, остальное — из нашего собственного сравнения трёх транскриптов. Крупное расхождение устроено иначе — ради него страница и написана.

Остальные критерии категории C во всех трёх прогонах дали ровно 10 баллов. Весь одиннадцатибалльный разрыв — это два критерия.

C1a: одни и те же факты, три разные оценки

Критерий C1a — он из 26-критериальной рубрики модели, у AgentFit обнаружение и валидность слиты в один C1 — спрашивает, есть ли у API машиночитаемая спека, до которой агент может дойти. Все три прогона установили про docs.stripe.com ровно одно и то же:

Никто не ошибся. Никто не галлюцинировал. Оценки: 0 из 8, 3 из 8 и 4 из 8.

Три критерия, на которых прогоны разошлись сильнее всего, — как их оценил каждый прогон.
КритерийABC
C1a · spec discoverable3/84/80/8
C1b · spec valid7/77/70/7
E5 · terms of use3/32/31/3

Разошлись не в сайте, а в вопросе, которого рубрика не задала: считается ли спека опубликованной, если она лежит на чужом домене и до неё нужен лишний переход? Это настоящая развилка без очевидного ответа, и каждый прогон подходил к ней в одиночку, посреди длинной задачи, без правила, в которое можно заглянуть. Три прогона — три политики.

Дальше расхождение идёт каскадом. C1b оценивает качество найденной спеки. Прогону, который решил, что GitHub не считается, валидировать было нечего — 0 из 7. Два других её скачали и поставили 7 из 7, но насчитали разное число путей — 414 и 136: в репозитории Stripe лежит не один файл спецификации, и они взяли разные (spec3.json и spec3.yaml). Два прогона сошлись в оценке по противоположным причинам.

E5 — «указаны ли условия использования» — вышел 3/3, 2/3 и 1/3. Один прогон нашёл в футере ссылку на stripe.com/legal/ssa. Второй эту ссылку не зачёл и зачёл вместо неё директиву Content-Signal в robots.txt. Третий поискал /terms, /legal и /privacy на домене документации, получил три 404 и поставил по факту. Три защитимых прочтения одной строчки рубрики.

Самопроверка тоже разъехалась

В промпте есть калибровочный якорь — таблица ранее измеренных сайтов, в которой Stripe стоит на 56, замер от 13 мая 2026 года. Он там именно для того, чтобы ловить дрейф. Из-за этой же таблицы сайтом стал docs.stripe.com: Stripe уже стоял в чужом калибровочном якоре до того, как мы что-либо запускали, — сайт выбран не нами и не под результат.

Якорем воспользовались все три прогона. Все три заметили своё отклонение — +22, +24, +9. Все три после этого перепроверили критерии, порассуждали о том, что могло измениться с мая, и пришли к выводу, что якорь устарел, а собственное число вернее. Трижды, независимо, в одну сторону — и с тремя разными числами.

Вот это место кажется нам самым поучительным. Это не небрежность — так выглядит добросовестная работа, когда в процедуре остался свободный параметр. Самопроверка, вердикт которой меняется от прогона к прогону, — не самопроверка.

Якорь стоит в одном балле от 57 у AgentFit. Не делайте из этого выводов: это ручной замер, по другой рубрике и от другого месяца, и он не доказывает, что 57 — истинная оценка.


Почему код отвечает одинаково

Ничего хитрого. Каждый критерий — это запрос плюс правило, и оба записаны до того, как аудит начался.

Четыре строки из отчёта AgentFit — во всех трёх прогонах байт в байт одинаковые.
Критерий Результат Что запрошено Что записано
A1 · индекс llms.txt присутствует 3/3 GET /llms.txt → 200 Stripe Documentation
C1 · поиск спеки отсутствует 0/8 фиксированный список адресов, ответа нет
D2 · реалистичность примеров присутствует 5/5 выбранная страница эндпоинта → 200 placeholder_ratio = 0.00, 0/3 blocks
E6 · доступность частично 1/4 главная → 200 a11y: 3 violations (e.g. button-name)

D2 — это как раз про машинное обучение. Внутри аудита работают два небольших классификатора: один оценивает, насколько реалистичен пример кода, второй — полноту страницы эндпоинта. Это ONNX-графы с замороженными весами, вкомпилированные в бинарник. Один и тот же вход даёт тот же тензор и тот же float — всегда. Детерминизм не требует отказа от моделей; он требует отказа от моделей, чей ответ нельзя закрепить.

C1 — ровно та развилка, которую три прогона прошли по-разному, и AgentFit ставит здесь 0 из 8. Наше правило — не «GitHub не считается», а фиксированный список мест, куда мы смотрим: семнадцать конвенциональных путей на аудируемом хосте, ссылка api-catalog по RFC 9727 и любая ссылка на спеку, найденная на запрошенной нами главной. На docs.stripe.com ни один из этих путей спеку не отдал, а на этой странице такой ссылки не было — значит, ничего не найдено. Правило, которое прошло бы на переход дальше, в репозиторий вендора, не было бы менее верным. Наше просто закреплено до начала аудита, одинаково применяется к каждому сайту корпуса, а его шкала опубликована в рубрике. В этом вся разница — не в лучшем ответе, а в закреплённом. Как считается C1.

Сверьте с живым прогоном

Репозиторий закрыт, готовых сборок мы не выкладываем, — поэтому «соберите и запустите» вы здесь не увидите: сделать это нельзя. Проверить можно другое, и лучше сказать точно что именно. Файлы выше записала консольная сборка на нашей машине 27 июля 2026 года. Публичный сервис — другая сборка, работающая в другом месте, и по тому же сайту он выдаст вам свой отчёт. Если процедура такая, как мы утверждаем, эти два отчёта совпадут по всем баллам. Ниже — как это сравнить и чего такое совпадение стоит.

Ничего не запуская (квота не тратится)

В публичном датасете у каждого хоста лежит идентификатор последнего валидного аудита. Возьмите его для Stripe, вычитайте этот прогон из API, сведите оба документа к полям с оценками и сравните:

$ RUN=$(curl -s https://agentfit.dev/dataset.csv \
        | awk -F, '$1=="docs.stripe.com" && $3=="true" {print $7; exit}')

$ curl -s https://agentfit.dev/static/reproducibility/agentfit-run1.json \
  | jq -S '{total_score, max_score, categories,
            criteria: [.criteria[] | {id, status, score, max}]}' > ours.json

$ curl -s https://agentfit.dev/api/public/audit/$RUN \
  | jq -S '.report | {total_score, max_score, categories,
            criteria: [.criteria[] | {id, status, score, max}]}' > theirs.json

$ diff ours.json theirs.json

27 июля 2026 года эта команда не вывела ничего: 200 строк, ни одного расхождения. Две разные сборки, две разные машины, одни и те же 28 вердиктов.

Запустить самому (один раз в сутки на сайт)

Вставьте https://docs.stripe.com в форму на главной. Когда прогон закончится, в адресе будет /r/<идентификатор>. Подставьте его вместо $RUN — команды те же. Стоит понимать, что это добавляет, а что нет: аудит всё равно уходит с наших серверов, так что ваши здесь запрос и момент времени, но не точка выхода.

Один аудит одного сайта с одной сети в 24 часа. Вторая попытка вернёт 429 и никакого идентификатора прогона — специально, чтобы сервисом нельзя было долбить чужую документацию. Если упёрлись в квоту, предыдущий способ вообще ничего не требует отправлять. У MCP-сервера квота та же: попросить агента переаудитить тот же сайт в тот же день — та же стена. А перед этой стеной стоит вторая, и она уже вообще не про вас: два аудита одного хоста за десять минут, чьи угодно, съедают общий запас, и следующий получит 429 с кодом rate_limited, а не site_quota. Эта рассасывается сама за десять минут.

Без curl и jq

Откройте agentfit-run1.json в одной вкладке, а страницу отчёта /r/<идентификатор> — в другой. Всё решают семь чисел: шесть категорий и итог. Они напечатаны прямо здесь, так что сверить можно и не открывая файл.

AgentFit по docs.stripe.com, 27 июля 2026 — одно и то же во всех трёх файлах
Категория Балл Макс.
A — Обнаруживаемость1114
B — Элементы страницы1121
C — API-контракт417
D — Контент1623
E — Рендеринг и гигиена1521
F — Агентские возможности04
Итого57100

Три вещи разойдутся — и должны

Совпадение означает ровно одно: та же процедура на том же сайте выдала тот же вердикт из другой сборки и с другой машины. Оно не означает, что 57 — правильная оценка; этого страница нигде не утверждает. И оно завязано на сам сайт: если docs.stripe.com изменился с 27 июля 2026 года, числа поедут — и это прибор работает, а не ломается. Прежде чем делать выводы из расхождения, посмотрите дату audited_on в строке датасета.

Эти файлы заморожены, и к каждому релизу мы их не перевыпускаем. Причин две: контрольная сумма на этой странице снята ровно с этих байтов, а все числа в тексте выше вычитаны из них — самообновляющийся экспонат не может ни того, ни другого. Сигнальная нить не внутри замороженного файла, а на живой стороне: колонка 9 той строки датасета, которую вы вычитали выше, — это rubric_version, и пока эта страница висит, там должна стоять 4. В самом экспонате этой колонки нет: он старше её. Значит сверять придётся с числом, напечатанным в этом предложении, — гарантия слабее, и именно поэтому число выписано словами. Если однажды в колонке окажется другое, значит линейку сменили уже после того, как страница была написана: сравнение по полям недействительно, а перед вами исторический документ. Пусть страница скажет это вслух, чем тихо перезапустит себя до совпадения.

Два критерия из 28 — D2 и C3 — решает не правило, а небольшой классификатор. Оба вкомпилированы в бинарник и версионируются вместе с ним: модельного сервиса нет, и ничьё переобучение не сдвинет уже опубликованный балл.


Чего мы не утверждаем

В чём модель здесь действительно хороша

Всё это не делает прогоны модели бесполезными — оно делает их другим инструментом. Диагноз в каждом из трёх прогонов хорош сам по себе: почему отсутствие спеки бьёт по агенту, что стоит опубликовать вместо этого, какие страницы Stripe переживут чтение без браузера. Это объяснение — и объясняет модель прекрасно.

Языковая модель отлично объясняет, что чинить. Как измерительный прибор она годится плохо. Мы — про второе. AgentFit и есть прибор; отнесите его число модели и спросите, что с ним делать. Вот правильное разделение труда, и мы сами работаем именно так.

Данные

Все шесть прогонов лежат прямо здесь. Три отчёта AgentFit — это ровно те файлы, которые записал инструмент, байт в байт: контрольная сумма снята с них. Три файла прогонов модели — наши:

Сырые транскрипты мы не публикуем. По колонке модели вы получаете структурированные сводки, которые мы составили постфактум по этим транскриптам: итоговый балл, суммы по категориям и покритериальные заметки, процитированные выше. Баллы и суммы — собственный результат каждого прогона; формулировки заметок — наши.

Ничего не отсеивали — ни прогон, ни сайт. Три аудита модели и три аудита инструмента, на том единственном сайте, который уже был назван в калибровочной таблице промпта; других мы не прогоняли и ничего не выбрасывали. Если бы четвёртый прогон дал 57, мы бы опубликовали и его — страница получилась бы короче.


Проверить свою документацию →

Бесплатно, без регистрации, около 30 секунд. 28 критериев, HTTP-доказательство под каждым, ссылка на отчёт — и то же самое число завтра, если ничего не изменилось.