EnglishРусский Map

Дифференциальный анализ спецификаций

title
Дифференциальный анализ спецификаций
type
concept
summary
Собрать систему несколькими независимыми циклами агентов, сравнить готовые реализации и разобрать каждое расхождение как неучтённое решение.
tags
agentic-coding, software-engineering, spec-driven-development
created
2026-07-21
updated
2026-07-21
lang
ru
source_updated
2026-07-21
translated
2026-09-01
translator
lllm/antigravity/gemini-3.7-flash-medium

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

Название и практический пример принадлежат Josh Bleecher Snyder'у, который применил этот подход к распределённому DNS-серверу exe.dev в claude-is-not-a-compiler; отдельно он описал технику на commaok.xyz.

Наблюдение, лежащее в основе

Агенты задают вопросы. В циклах Bleecher Snyder'а они сыпались на всех уровнях - от общей структуры до конкретных строк кода, и ответы на них кажутся очевидным способом сделать спецификацию точнее.

Проблема в том, о чём они не спрашивают:

Поразительно, о скольких важных решениях агенты даже не спросили, а просто приняли их - причём по-разному.

Агент, который натыкается на неоднозначность и молча её разрешает, выдаёт рабочий код и не оставляет никаких следов своего выбора. Выявить такие места, читая одну реализацию, невозможно: в ней решение выглядит единственно возможным. Их находят сравнением - расхождение служит сигналом о том, что точка принятия решения вообще существовала.

Цикл работы

  1. Сначала согласовать общую стратегию и архитектуру силами людей. Это исходное задание; техника проверяет его, а не создаёт с нуля.
  2. Запустить несколько параллельных циклов агентов на создание всей системы целиком - включая тесты и состязательное код-ревью, а не просто черновик.
  3. Поручить новым агентам сравнить готовые реализации и выделить интересные расхождения. Сравнение - это тоже задача для агентов.
  4. Разобрать расхождения: поэкспериментировать, выбрать вариант и при необходимости откатить выбор, если он оказался неудачным.
  5. Зафиксировать каждое принятое решение в виде лаконичных письменных указаний.
  6. Выбросить все реализации и повторить.

Bleecher Snyder прогнал полный цикл трижды, прежде чем написать чистовой вариант, ссылаясь на Brooks'а ("планируйте выбросить одну версию: всё равно придётся") и Craig Zerouni ("если вы планируете выбросить одну версию, придётся выбросить две"). Суммарные затраты составили около недели внимания одного человека.

Что получается на выходе

Главный результат - это документ с указаниями, а не сами реализации. К третьему проходу его стало эмпирически достаточно, чтобы направить агента через ключевые решения: цели, архитектуру и отдельные низкоуровневые детали вроде точного типа данных для критически важного конкурентного кэша. "Эмпирически достаточно" здесь практический ориентир: спецификация готова, когда новый агент, следуя ей, перестаёт расходиться в важных для вас вещах.

Классический пример расхождения из кейса с DNS: репликация догоняет состояние, запрашивая все записи после последней известной, а затем переходит в long polling за новыми. Откаты баз данных случаются редко, но бывают, и они нарушают допущение об append-only, на котором держится вся схема. Опасность заметили все агенты; каждый агент обработал её по-своему. Выжившее решение помечает каждую строку случайно сгенерированным значением timeline, передаёт timeline крайней строки N в каждом запросе "записи после N" и считает несовпадение доказательством того, что история изменилась, после чего откатывается к полной чистой синхронизации.

Стилевые различия тоже проявляются: практической пользы в них меньше, но они не бесполезны. И Claude, и Codex сочли систему Claude'а более элегантной, а систему Codex'а - более дотошной.

Почему это работает

Неоднозначность в спецификации незаметна при одиночном чтении. Любой другой подход к поиску пробелов - внимательное ревью, чек-листы, просьбы к исполнителю отмечать неясности - зависит от того, заметит ли человек, что здесь вообще был выбор. Дифференциальный анализ не требует ничего замечать: он делает пробел механически наблюдаемым в виде diff'а. Плата за это - создание N систем вместо одной, но именно эту стоимость агенты свели к минимуму.

Логика здесь та же, что и в дифференциальном тестировании (запустить две реализации протокола друг против друга и исследовать расхождения), только перенесённая с поведения кода на инженерный замысел.

Ограничения

  • Скоррелированные слепые зоны. У независимых циклов на базе одного семейства моделей общие априорные представления. Решение, в котором все агенты ошибутся одинаково, не создаст расхождений и останется невидимым. То, что Bleecher Snyder использовал и Claude, и Codex, отчасти сглаживает проблему.
  • Расхождения не ранжируются. Diff показывает, что решение было принято, но не говорит, важно ли оно. Отделить сигнал от стилевого шума - работа человека, и именно она заняла у него неделю.
  • Требуется настоящее задание. Если отправная точка слишком расплывчата, разойдётся вообще всё, и на выходе получится шум вместо списка решений.
  • Предполагается, что вы можете позволить себе выбросить реализации. Это верно для изолированного внутреннего сервиса, но не столь очевидно для систем с миграциями, реальными данными или уже работающими пользователями.

Cross-references

  • claude-is-not-a-compiler - первоисточник и кейс с DNS-сервером
  • vibe-engineering - практика, которой служит эта техника
  • llm-output-variance - базовая недетерминированность, которую метод не подавляет, а использует
  • specsmaxxing, acceptance-criteria-ids - спецификация как главный артефакт, полученная другим путём
  • log-distributed-llms - пессимистичный взгляд на разногласия нескольких агентов