Практический гайд · воспроизводимость

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

Как воспроизвести benchmark памяти агентов и проверить его упаковку результатов
Temporary fallback cover; replace in editorial pass.
12 минут чтения Уровень: продвинутый Обновляемый материал
Самое важное из мира AI — в канале MAX AgentLabОтдельные разборы, инструменты и практические схемы Читайте Agent Lab в Telegram Разборы, кейсы и новости о практических AI-агентах без лишней воды.

Сравнение систем памяти агентов ломается не только из-за ошибок в коде. На результат влияют версия раннера, порядок эпизодов, формат транскриптов, правила подсчёта метрик и даже то, какие файлы попали в submission-архив. Поэтому воспроизведение benchmark — это не повторный запуск одной команды, а проверяемая цепочка от входных данных до опубликованного артефакта.

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

Что именно нужно воспроизвести

Перед запуском разделите эксперимент на четыре слоя. Это помогает не смешивать ошибку агента с ошибкой инфраструктуры.

  1. Спецификация. Версия сценариев, схема событий, лимиты контекста, число эпизодов и правила остановки.
  2. Раннер. Код, который подаёт события агенту, сохраняет ответы и применяет ограничения.
  3. Оценивание. Скрипты или правила, превращающие транскрипты в метрики.
  4. Упаковка. Набор файлов, структура каталогов и проверки, через которые проходит 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. Изучите контракт входа и выхода

Не начинайте с запуска. Сначала найдите документацию раннера, пример конфигурации и код сериализации результата. Вам нужно ответить на вопросы:

Практический минимум — найти все места, где создаются транскрипты и итоговые метрики:

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 рассчитан на несколько запусков, храните каждый прогон отдельно и агрегируйте результаты только после независимой проверки транскриптов.

В журнале эксперимента зафиксируйте как минимум:

Шаг 6. Проверьте транскрипты до расчёта метрик

Метрики не должны быть первым сигналом о проблеме. Сначала проверьте саму форму данных. Даже если формат 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 там, где он поддерживается, исходные транскрипты, правила исключения и контрольные суммы. Тогда другой исследователь сможет проверить не только итоговую цифру, но и путь, которым она получена.

Дополнительные практические материалы собраны в разделе гайдов, а определения терминов — в глоссарии.