Утверждение о непоследовательности
Повторяющаяся жалоба на LLM-агентов состоит в том, что они нестабильны: один и тот же запрос, введённый дважды, даёт два разных решения. Формулировка почти всегда одна и та же — модель ненадёжна, сэмплирование слишком горячее, промпт хрупок. Работа CTGT над Concordance полезна именно потому, что отказывается от такой формулировки. Она прослеживает путь, который агент проходит к выводу, и спрашивает, почему два прогона разошлись, вместо того чтобы утверждать, что они разошлись. Ответ, как правило, в том, что прогоны никогда не были одним и тем же прогоном.
На другом конце инструментальной цепочки харнессы в стиле DeepEval сделали оценку выходов рутинной в масштабе. Можно прогнать набор кейсов, прикрепить метрики и получить долю прохождений. Чего такие харнессы не могут сделать сами по себе — это локализовать причину сбоя: нулевая оценка на кейсе говорит, что ответ был неверным, но не говорит, какой шаг траектории внёс ошибку. Разрыв между трассировкой в стиле Concordance и оценкой в стиле DeepEval — это не разрыв в проектировании метрик. Это разрыв в захвате контекста. Инструмент трассировки может объяснить расхождение, потому что хранит входные данные; харнесс оценки сообщает о расхождении, потому что отбрасывает их.
Источники скрытой вариативности
Решение агента — функция от многого, что далеко выходит за пределы сообщения пользователя. Между двумя прогонами, которые снаружи выглядят идентичными, может различаться всё следующее:

- Извлечённый контекст. Векторный поиск возвращает ранжированный набор, который смещается при обновлениях индекса, версиях модели эмбеддингов и разрешении ничьих. Два прогона могут извлечь пересекающиеся, но не идентичные документы, а модель рассуждает над тем, что ей дали.
- Ответы инструментов. API погоды, запрос к базе данных, вызов поиска — каждый возвращает живые данные. Временной метки в полезной нагрузке инструмента, курсора пагинации или переупорядоченного набора результатов достаточно, чтобы изменить следующий шаг.
- Порядок и временные метки. Порядок сообщений в длинной беседе, время по часам, внедрённое в системный промпт, и последовательность, в которой разрешаются параллельные вызовы инструментов, — всё это попадает в промпт.
- Параметры сэмплирования. Temperature, top-p, seed и max tokens часто задаются по среде и редко версионируются вместе с промптом, который от них зависит.
- Дрейф сборки промпта. Системные промпты собираются из шаблонов, few-shot примеров и внедрённого контекста. Деплой, меняющий один фрагмент, меняет эффективный вход для каждого запроса, и ничто в оценке выхода не фиксирует, что это произошло.
Неудобный вывод состоит в том, что многие «выглядящие идентичными входы» не идентичны, как только харнесс исследован. Агент ведёт себя детерминированно при своих входах; просто входы не удерживаются постоянными, не записываются и не сравниваются. Недавние материалы об оценке агентов постоянно возвращаются к этой мысли — что интересная вариативность живёт в конвейере вокруг модели, а не только в самой модели, — и практическое следствие в том, что одна лишь оценка выходов будет продолжать неверно приписывать причину.
Контракт воспроизведения
Решение — это контракт: каждое решение записывает достаточно контекста, чтобы быть воспроизведённым точно. Конкретно, запись трассировки должна нести:
{
"run_id": "...",
"model": { "name": "...", "version": "...", "params": { "temperature": 0.0, "top_p": 1.0, "seed": 42 } },
"prompt": { "template_hash": "...", "assembled": "...", "fragments": ["..."] },
"retrieval": [
{ "doc_id": "...", "content_hash": "...", "score": 0.81, "rank": 1 }
],
"steps": [
{
"index": 0,
"tool": "search",
"args": { "query": "..." },
"response": { "...": "..." },
"response_hash": "..."
}
],
"output": "..."
}
Собранный промпт хранится дословно вместе с хешами его фрагментов, так что изменение шаблона обнаруживается без сравнения мегабайтов текста. Набор извлечения несёт хеши документов, так что смещённый индекс виден, а не выводится косвенно. Аргументы и ответы инструментов захватываются на каждом шаге, что превращает траекторию в воспроизводимую последовательность, а не в терминальную строку.

С такой записью воспроизведение становится контролируемым экспериментом. Заморозьте входы — тот же промпт, тот же набор извлечения, те же ответы инструментов, та же версия модели — и любое оставшееся расхождение будет вариативностью модели. Разморозьте одно измерение за раз, и вы сможете приписать расхождение извлечению, инструменту или деплою. Оценка тогда переходит от терминального ответа к траектории: каждый шаг сравнивается, и первая точка расхождения — это место, с которого начинается расследование. В этом разница между знанием, что кейс провалился, и знанием, какое решение провалилось.
Компромисс реален. Полный захват контекста требователен к хранилищу, замедляет путь записи и навязывает дисциплину командам, которые сейчас относятся к промптам и конфигурациям извлечения как к переменным среды. Захват ответов инструментов может также захватывать чувствительные полезные нагрузки, что требует редактирования во время записи, а не во время анализа. Ничто из этого не бесплатно, и студия, внедряющая воспроизведение, должна ожидать инвестиций в политику хранения и управление схемой, прежде чем увидит отдачу. Альтернатива — оценка выходов, которые вы не можете воспроизвести, — дешевле на прогон и дороже на баг.
Что это даёт оператору
Провальный кейс становится воспроизводимым. Вместо скриншота и смутного воспоминания о том, что было спрошено, у оператора есть трассировка, которая воспроизводится к тому же неверному ответу, и diff, показывающий, какой шаг его внёс. Воспроизводимость — предпосылка исправления; без неё отладка — это догадки.
Стоимость оценки становится атрибутируемой. Прогон воспроизведения против замороженных входов проверяет логику решения без повторной выборки живых данных и без повторного запуска исследовательского извлечения. Это делает регрессионные наборы дешевле в запуске и проще для осмысления, потому что каждый прогон проверяет одну вещь, а не весь конвейер. Свежие исследовательские прогоны остаются ценными, но перестают быть единственным вариантом.
Согласованность становится измеримым свойством с базовой линией. Вместо того чтобы относиться к стабильности как к анекдоту — «вчера работало», — оператор может отслеживать частоту расхождений по шагам между деплоями и видеть, сдвинули ли их изменение промпта или обновление модели. Это тот сдвиг, к которому ветки Concordance и DeepEval ведут вместе: трассируйте контекст, воспроизводите его под контролем и оценивайте траекторию. Модель редко бывает загадкой. Загадка — недостающие входы.
