Практический гайд · воспроизводимость
Как воспроизвести benchmark памяти агентов и проверить его упаковку результатов

Сравнение систем памяти агентов ломается не только из-за ошибок в коде. На результат влияют версия раннера, порядок эпизодов, формат транскриптов, правила подсчёта метрик и даже то, какие файлы попали в submission-архив. Поэтому воспроизведение benchmark — это не повторный запуск одной команды, а проверяемая цепочка от входных данных до опубликованного артефакта.
В этой статье benchmark означает зафиксированный набор сценариев, правил запуска и метрик, по которому можно сопоставлять системы. Ниже описан нейтральный процесс: он не предполагает конкретного провайдера модели, закрытого датасета или заранее известного значения метрик.
Что именно нужно воспроизвести
Перед запуском разделите эксперимент на четыре слоя. Это помогает не смешивать ошибку агента с ошибкой инфраструктуры.
- Спецификация. Версия сценариев, схема событий, лимиты контекста, число эпизодов и правила остановки.
- Раннер. Код, который подаёт события агенту, сохраняет ответы и применяет ограничения.
- Оценивание. Скрипты или правила, превращающие транскрипты в метрики.
- Упаковка. Набор файлов, структура каталогов и проверки, через которые проходит submission-архив.
Если один из слоёв не зафиксирован, результат следует считать условным. Например, одинаковый агент, запущенный с другой политикой обрезки истории, уже является другой экспериментальной конфигурацией.
Шаг 1. Зафиксируйте исходное состояние
Начните с отдельной рабочей директории и сохраните идентификатор версии раннера. Не редактируйте файлы benchmark непосредственно во время эксперимента: любые локальные изменения должны быть видны в журнале.
git clone <URL_репозитория> benchmark-repro
cd benchmark-repro
git rev-parse HEAD
git status --short
В этой статье адрес репозитория обозначен как <URL_репозитория>: его нужно заменить официальным адресом из задания benchmark. Если проект поставляется архивом, сохраните исходный архив и его контрольную сумму.
sha256sum <исходный-архив>
Зафиксируйте также версию интерпретатора, менеджера пакетов, операционной системы и доступные переменные окружения. Секреты, токены и полные значения ключей в журнал не записывайте.
python --version
python -m pip --version
uname -a
env | sort | sed -E 's/(TOKEN|KEY|SECRET|PASSWORD)=.*/\1=[REDACTED]/'
Безопасная практика: выполняйте команды в виртуальном окружении и перед публикацией просматривайте логи на наличие токенов, персональных данных и исходных промптов, если они не предназначены для публикации.
Шаг 2. Изучите контракт входа и выхода
Не начинайте с запуска. Сначала найдите документацию раннера, пример конфигурации и код сериализации результата. Вам нужно ответить на вопросы:
- какой файл или каталог содержит сценарии;
- какие поля обязательны у события и ответа;
- как обозначаются ошибки, тайм-ауты и пустые ответы;
- можно ли повторно запускать эпизод с тем же идентификатором;
- какие поля ожидает оценщик;
- какая структура требуется для submission-архива.
Практический минимум — найти все места, где создаются транскрипты и итоговые метрики:
rg -n "transcript|conversation|episode|metric|score|submission|manifest" .
Если контракт описан только в коде, составьте локальную таблицу полей. Для каждого поля укажите тип, обязательность и источник значения. Это не заменяет официальную спецификацию, но делает расхождения заметными до запуска.
Шаг 3. Соберите воспроизводимое окружение
Установите зависимости способом, который предусмотрен проектом. Не смешивайте системные пакеты и виртуальное окружение без явной причины.
python -m venv .venv
. .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install -r requirements.txt
Команды выше — шаблон. Используйте только те файлы и команды установки, которые указаны в документации конкретного раннера. После установки сохраните список версий:
python -m pip freeze > environment.freeze.txt
Отдельно зафиксируйте настройки, которые могут менять поведение агента: модель, параметры генерации, лимит токенов, тайм-аут, число повторов, seed и режим параллельного выполнения. Если параметр не поддерживается, не создавайте видимость детерминизма: укажите это в отчёте.
Шаг 4. Проведите контрольный запуск
До полного benchmark выполните самый маленький допустимый прогон. Его цель — проверить маршрутизацию, авторизацию, формат ответа и запись файлов, а не получить финальную оценку.
python -m <runner_module> \
--config <config-файл> \
--limit 1 \
--output runs/smoke
Сверьте код завершения процесса, наличие ожидаемых файлов и соответствие идентификаторов. Если контрольный запуск создаёт неполный транскрипт, сначала исправьте интеграцию или конфигурацию. Неполные данные нельзя молча включать в основной прогон.
Шаг 5. Запустите полный прогон с журналом
Для полного запуска используйте отдельный каталог с датой, версией кода и кратким описанием конфигурации. Не перезаписывайте предыдущий результат: повтор должен создавать новый артефакт.
RUN_ID="2026-11-06-runner-commit-config"
mkdir -p "runs/$RUN_ID"
python -m <runner_module> \
--config <config-файл> \
--output "runs/$RUN_ID" \
2> "runs/$RUN_ID/stderr.log" \
| tee "runs/$RUN_ID/stdout.log"
Если в команде есть случайный seed, сохраните его рядом с результатом. Если benchmark рассчитан на несколько запусков, храните каждый прогон отдельно и агрегируйте результаты только после независимой проверки транскриптов.
В журнале эксперимента зафиксируйте как минимум:
- commit или хеш исходного архива;
- версию окружения;
- конфигурацию модели и раннера;
- время старта и завершения;
- число запланированных, завершённых и ошибочных эпизодов;
- путь к транскриптам и контрольную сумму итогового набора.
Шаг 6. Проверьте транскрипты до расчёта метрик
Метрики не должны быть первым сигналом о проблеме. Сначала проверьте саму форму данных. Даже если формат JSON, это не гарантирует, что все события принадлежат правильному эпизоду и идут в допустимом порядке.
Базовая проверка должна выявлять:
- дубликаты идентификаторов эпизодов;
- пропущенные или лишние сценарии;
- пустые ответы и необработанные исключения;
- нарушение порядка событий;
- обрезанные файлы и некорректный JSON;
- отсутствующие обязательные поля;
- следы отладки, которые могли попасть в машинно читаемый вывод.
Пример безопасного чтения JSON-файлов без изменения данных:
python - <<'PY'
import json
from pathlib import Path
root = Path("runs") / "RUN_ID"
files = sorted(root.rglob("*.json"))
if not files:
raise SystemExit("JSON-транскрипты не найдены")
for path in files:
try:
with path.open(encoding="utf-8") as f:
json.load(f)
except Exception as exc:
raise SystemExit(f"Некорректный JSON: {path}: {exc}")
print(f"Проверено JSON-файлов: {len(files)}")
PY
Этот фрагмент проверяет только синтаксис JSON. Схемную проверку выполняйте штатным валидатором benchmark или отдельным скриптом, если он предоставлен. Не подменяйте отсутствующее поле пустой строкой: это скрывает дефект входных данных.
Шаг 7. Рассчитайте метрики и сохраните промежуточные данные
Запускайте официальный оценщик на неизменённых транскриптах. Сохраняйте не только итоговый score, но и промежуточную таблицу по эпизодам, если её выдаёт инструмент. Так можно отличить общую деградацию от нескольких проблемных сценариев.
python -m <evaluator_module> \
--input "runs/RUN_ID" \
--output "runs/RUN_ID/metrics"
Проверьте, что знаменатель метрики совпадает с числом валидных эпизодов. Если оценщик исключает ошибки или пропуски, это должно быть явно отражено в отчёте. Нельзя сравнивать два результата, если один score рассчитан по всем эпизодам, а другой — только по успешно завершённым.
Для каждой метрики зафиксируйте определение, единицу агрегации и правило округления. Значение, полученное после ручной фильтрации транскриптов, помечайте как производное, а не как официальный результат.
Шаг 8. Проверьте упаковку submission-архива
Архив — часть эксперимента. Он должен быть достаточным для проверки результата и не должен содержать лишние секреты, кэш или случайные локальные файлы.
Сначала соберите staging-каталог с явным списком файлов:
rm -rf submission-staging
mkdir -p submission-staging
cp -a runs/RUN_ID/metrics submission-staging/
cp -a runs/RUN_ID/transcripts submission-staging/
cp environment.freeze.txt submission-staging/
cp <manifest-файл> submission-staging/
Команда удаления здесь ограничена специально созданным каталогом submission-staging. Не заменяйте этот путь переменной с неизвестным значением и не запускайте рекурсивное удаление в корне проекта.
Перед архивацией просмотрите содержимое:
find submission-staging -type f -print | sort
rg -n -i "api[_-]?key|token|secret|password|authorization|bearer" submission-staging || true
Затем создайте архив и контрольную сумму:
tar -czf submission.tar.gz -C submission-staging .
tar -tzf submission.tar.gz
sha256sum submission.tar.gz
Сопоставьте список внутри архива с требованиями задания. Проверьте, что пути относительные, обязательные файлы лежат в ожидаемых каталогах, а имя архива и расширение соответствуют контракту. Если при распаковке появляется дополнительный верхний каталог, это может нарушить автоматическую проверку.
Финальный чек-лист проверки
- Версия раннера и зависимости записаны.
- Конфигурация эксперимента сохранена без секретов.
- Контрольный запуск завершился ожидаемым образом.
- Число эпизодов и их идентификаторы проверены.
- Транскрипты валидны синтаксически и схемно.
- Ошибки, тайм-ауты и пропуски отражены явно.
- Метрики рассчитаны официальным оценщиком на исходных данных.
- Промежуточные результаты сохранены.
- Архив содержит только разрешённые файлы.
- Архив можно перечислить и распаковать в чистую директорию.
- Контрольная сумма архива записана в отчёте.
Типовые ошибки
«Одинаковая команда» не означает одинаковый эксперимент
Разные версии библиотек, переменные окружения и настройки параллельности могут изменить порядок событий или поведение модели. Поэтому сравнивайте не команды, а полные конфигурации запусков.
Метрика считается по повреждённым данным
Если оценщик пропускает невалидные эпизоды, итоговое число может выглядеть корректно, хотя покрытие benchmark уменьшилось. Всегда публикуйте знаменатель и список исключённых эпизодов.
Локальный файл попал в архив
Частые причины — журналы отладки, кэш, дампы окружения и файлы с секретами. Решение — собирать архив из staging-каталога с явным составом, а не архивировать весь рабочий каталог.
Транскрипт визуально похож на правильный
Человек может не заметить дубликат события, неправильный идентификатор или смену роли сообщения. Машинная проверка схемы и инвариантов должна выполняться до ручного просмотра выборки.
Ограничения воспроизводимости
Даже тщательно упакованный результат не гарантирует побитовую идентичность. Внешняя модель может обновиться, сетевой сервис — изменить ответ, а распределённое выполнение — выбрать другой порядок завершения. Такие источники вариативности нужно перечислить отдельно и не маскировать округлением score.
Если детерминизм невозможен, повышайте прозрачность: храните конфигурацию, версии, seed там, где он поддерживается, исходные транскрипты, правила исключения и контрольные суммы. Тогда другой исследователь сможет проверить не только итоговую цифру, но и путь, которым она получена.
Дополнительные практические материалы собраны в разделе гайдов, а определения терминов — в глоссарии.