Учёт экспериментов с моделями без Excel-хаоса в команде
Учёт экспериментов с моделями помогает не терять промпты, версии датасетов и evals. Разберём простую схему хранения, поиска и сверки.

Почему через полгода уже ничего не понятно
Через полгода подводит не память сама по себе, а связь между фактами. В таблице обычно остается только кусок истории: имя запуска, пара метрик и чья-то пометка "норм". Сам промпт лежит в чате, датасет уже успели поправить, а модель кто-то сменил между тестами и не записал это рядом с результатом.
Из-за этого учет экспериментов с моделями быстро превращается в архив без смысла. Цифры есть, но непонятно, к чему они относятся. Один и тот же score может выглядеть отлично или слабо, если его получили на другой выборке, с другим системным промптом или на новой версии модели.
Excel плохо держит связку между тремя вещами: что именно спросили, на чем проверяли и чем запускали. Если эти данные живут в разных местах, команда начинает гадать. А гадание почти всегда дороже нормальной записи.
Отдельная беда - названия файлов и запусков вроде final_v7, final_v7_fix, final_v7_real. В моменте кажется, что все понятно. Через несколько месяцев никто уже не помнит, чем real отличался от fix и почему после final появился еще один final.
Чаты и скриншоты тоже не спасают. Скриншот удачного ответа полезен пару дней, потом он только мешает. Он не показывает полный промпт, параметры запуска, срез датасета и причину, по которой команда выбрала именно этот вариант. В чате часто остается только фраза "берем этот", а логика выбора исчезает.
Проблема всплывает в самый неудобный момент: когда нужно повторить старый результат перед релизом, объяснить клиенту просадку качества, передать задачу новой команде или понять, почему метрика осенью не сходится с весенней.
Представьте обычную задачу. Команда тестировала классификацию обращений в поддержку. В апреле нашла удачный промпт, в мае сменила модель, в июне обновила датасет после ручной разметки. Осенью кажется, что апрельский вариант был лучше. Но проверить это уже нельзя: нет точной версии промпта, нет снимка датасета, нет записи, на какой модели шел тот запуск.
Так и теряются хорошие решения. Не потому что они были сложными, а потому что их не зафиксировали как один целый эксперимент.
Что хранить у каждого запуска
У каждого запуска должна быть одна запись, по которой другой человек сможет повторить его без догадок. Если через полгода вы видите только таблицу с метрикой 0.78, это не история эксперимента, а обрывок.
Минимальный набор выглядит так:
- полный текст промпта и короткий ID, например
pmt-023 - точное имя модели, провайдера, дату запуска и параметры вроде temperature, max tokens и system message
- версию датасета и короткое описание того, как его собрали
- eval-набор, метрики и заметки по ручной проверке
- итог решения: оставили запуск, откатили или отправили на доработку, и почему
Промпт храните целиком, даже если изменилась одна строка. Короткий идентификатор нужен для скорости: его удобно писать в чате, в задаче и в названии отчета. Но ID без текста бесполезен.
С моделью команды ошибаются чаще всего. Они пишут "GPT-4" или "Qwen", а потом уже не помнят ни провайдера, ни точную версию, ни параметры. Если вы ходите в модели через шлюз, записывайте и маршрут запроса. Для RU LLM это особенно важно: один и тот же OpenAI-совместимый endpoint не означает, что запуск был одинаковым. Нужны точные модель и провайдер.
С датасетом работает то же правило. Названия вроде финальный_новый_2 не помогают. Лучше хранить номер версии, дату сборки и короткую заметку: "12 400 диалогов из саппорта, убрали дубли, анонимизировали телефоны, вручную проверили 300 примеров".
Eval без заметок тоже быстро теряет смысл. Метрика показывает направление, но не объясняет, почему запуск плохой. Запишите хотя бы пару наблюдений: модель стала отвечать короче, чаще пропускает юридические оговорки или путает валюты в 7 из 50 ручных проверок.
Есть простой тест. Сможет ли новый инженер открыть карточку запуска и за 15 минут понять, что именно вы проверяли, на каких данных и почему не пустили результат дальше? Если нет, запись нужно упростить и сделать точнее.
Как собрать карточку эксперимента
Карточка эксперимента нужна не для отчета, а для памяти команды. Если собрать ее сразу после запуска, через полгода будет ясно, что именно проверяли, на чем получили результат и стоит ли повторять этот ход.
Сначала задайте короткое имя по одной схеме и не меняйте ее. Подойдет что-то вроде task-model-prompt-dataset-date или usecase-vNN. Главное - не писать "новый", "финал" и "точно финал". Когда у всех запусков единый формат, нужный вариант ищется за минуту.
Дальше запишите цель одной фразой. Не "улучшить качество", а "снизить число ложных отказов в ответах на обращения по возвратам" или "поднять точность извлечения суммы из договора". Такая формулировка сразу показывает, какой метрикой потом мерить успех.
Промпт храните рядом с параметрами запуска, а не в чате, заметках и голове автора. В карточке должны лежать system prompt, user template, model, температура, top_p, наличие tools, число few-shot примеров и любые постобработки. Если команда работает через единый OpenAI-совместимый endpoint, это все равно нужно фиксировать. Одинаковый base_url не делает два запуска одинаковыми.
Отдельно привяжите точную версию данных. Для обучающего или тестового набора нужен не "датасет из папки апрель", а конкретный снапшот: commit, hash, дата выгрузки или номер версии. То же касается eval-набора. Иначе через месяц кто-то обновит 30 примеров, и старый результат уже нельзя будет честно сравнить с новым.
После прогона не откладывайте вывод на потом. Сразу пишите, что получилось: accuracy 0.81 -> 0.86, "стоимость выросла на 18%", "ответ стал короче, но чаще пропускает номер договора". Рядом добавьте одну причину обычным языком: "сработал более жесткий system prompt" или "новый eval-set оказался сложнее".
Хорошая карточка помещается на один экран. Если инженер открывает ее и за 30 секунд понимает цель, входные данные, настройки и вывод, значит формат работает.
Как вести версии датасетов без путаницы
Если команда правит один и тот же CSV на месте, учет экспериментов ломается очень быстро. Через месяц уже никто не помнит, почему метрика выросла: модель стала лучше или из набора просто убрали сложные примеры.
У датасета должно быть простое правило: после публикации версия не меняется. Любое заметное изменение создает новый снимок. Даже если вы всего лишь удалили 50 дублей или поправили часть меток.
Что сохранять у каждой версии
Одного имени файла мало. У версии должен быть короткий паспорт, иначе потом ее нельзя воспроизвести. Достаточно зафиксировать источник данных, фильтры или SQL-запрос выгрузки, дату выгрузки, версию инструкции по разметке и сколько строк добавили, убрали или переразметили.
Этого уже хватает, чтобы понять, что именно сравнивают люди. Если в данных есть персональные данные, запишите и способ маскирования PII. Для команд под 152-ФЗ это обычная часть процесса, а не формальность.
Полезно хранить и нормальный дифф между версиями. Не "что-то обновили", а по делу: добавили 1 200 новых диалогов, удалили 180 пустых строк, переразметили 240 жалоб после смены правил. Тогда видно, почему новая версия могла повлиять на результаты.
Если вы меняете саму логику разметки, меняйте не только номер версии, но и описание. Старые и новые метки часто выглядят одинаково по названию, но значат разное. В таком случае сравнение метрик без пометки о новой схеме только запутает команду.
Отдельно держите стабильный eval-набор
Обучающий набор может расти хоть каждую неделю. Маленький eval-набор лучше заморозить и не трогать, пока вы хотите честно сравнивать запуски между собой.
На практике удобно держать два набора: рабочий, который пополняется, и стабильный eval, где состав почти не меняется. Например, 300 вручную проверенных примеров из реальных обращений. Если править и его, история экспериментов быстро распадается.
Когда правила разметки все же меняются, создайте новую версию eval-набора и прямо отметьте разрыв сравнимости. Тогда команда не будет спорить, почему модель "просела" на 6%, если на деле вы просто начали считать иначе.
Хорошая версия датасета отвечает на два вопроса без переписки в чате: откуда взялись эти строки и чем этот набор отличается от прошлого.
Как записывать результаты evals
Цифра сама по себе почти ничего не значит. Если сегодня у вас 84% точности, а через месяц 87%, это еще не повод радоваться. Сначала проверьте, что обе цифры получили по одной и той же формуле, на одной версии датасета и при одинаковых правилах подсчета.
Частая ошибка проста: одна команда считает ответ верным после нормализации текста, другая сравнивает строку как есть. В таблице оба результата выглядят одинаково аккуратно, но сравнивать их нельзя. Формула расчета должна лежать рядом с результатом, а не в чьей-то памяти или в старом сообщении в чате.
Для каждого прогона полезно сохранять один и тот же набор полей: ID эксперимента и дату запуска, версию датасета и версию промпта, точную формулу метрики или имя eval-скрипта, итоговые метрики, стоимость, задержку и долю ошибок ответа, а также путь к сырым ответам на примерах.
Отдельно храните сырые ответы на спорных кейсах. Не на всех подряд, а хотя бы на тех, где модель ошиблась, ответила неоднозначно или сломала формат. Через полгода именно эти примеры помогут понять, модель стала хуже или вы просто поменяли правила оценки.
Если в eval есть ручная проверка, записывайте не только итоговый балл. Нужны имя проверяющего, дата и версия правил, по которым он смотрел ответы. Иначе один человек поставит "нормально", другой - "не прошло", а спорить вы будете уже без контекста.
Сравнивайте новый прогон только с близкой базой. Если вы сменили датасет, укоротили промпт, подняли температуру и заодно перешли на другую модель, прошлый результат уже не база, а другой эксперимент. Для LLM в продакшене это особенно неприятно: метрика может чуть вырасти, а стоимость удвоится, или задержка выйдет за пределы SLA.
Результаты удобно записывать как маленькую карточку решения, а не как одну строку с accuracy. Например: "на датасете support_v12 промпт p7 дал 86.4%, медианную задержку 2.1 с, стоимость 410 рублей за 10 тысяч запросов, 1.8% ответов сломали JSON". Это уже можно обсуждать и сравнивать.
Такой учет экономит не минуты, а недели. Когда снова возникнет вопрос "почему мы отказались от той версии", ответ будет в записи, а не в памяти команды.
Пример из обычной рабочей задачи
Команда поддержки настраивает автоответы на обращения клиентов. Цель простая: меньше ручной работы и меньше пустых ответов вроде "мы передали запрос коллегам". Менеджер просит сделать ответы точнее и короче.
Инженер меняет промпт: добавляет правило сначала кратко отвечать по сути, а потом предлагать следующий шаг. Первый прогон выглядит удачно. Доля полезных ответов растет с 71% до 82%, но появляется новый минус: средняя длина ответа почти удваивается. Операторам это не нравится. Клиенты получают слишком длинные сообщения там, где хватило бы двух фраз.
Если команда ведет записи аккуратно, это видно сразу. В карточке запуска есть не только итоговая метрика, но и сам промпт, версия модели, температура, выборка для eval, дата запуска и заметка о том, зачем вообще меняли поведение.
Через пару дней делают второй прогон. Ответы стали короче, но инженер заодно берет другую выборку: только обращения по доставке за последние две недели. Цифры снова меняются, и сравнение ломается. Уже нельзя честно сказать, что сработало лучше: новый промпт или просто более легкий набор диалогов.
Вот здесь карточка эксперимента и экономит время. В ней сразу видно, что поменяли не один параметр, а два: текст промпта и датасет для проверки. Значит, этот запуск нельзя сравнивать с первым как следующую версию. Его стоит пометить как отдельную ветку.
Через шесть месяцев возникает похожая задача: снизить нагрузку на поддержку перед сезонным пиком. Команда не роется в чатах и старых таблицах. Она открывает историю, находит запуск, где точность выросла без лишней длины, берет тот же промпт, ту же выборку и те же правила оценки. Если запросы шли через RU LLM, имеет смысл хранить и точную модель, и провайдера, и маршрут вызова. Тогда удачный вариант можно повторить за час, а не восстанавливать по памяти всю неделю.
Ошибки, которые ломают историю экспериментов
Самая частая поломка выглядит скучно: промпт лежит в рабочем чате, метрики - в таблице, версия датасета - где-то в папке аналитика, а вывод о результате вообще никто не записал. Через полгода такой запуск уже нельзя проверить. Его можно только пересказать по памяти, а память в таких задачах подводит быстро.
Даже аккуратный процесс разваливается, если команда хранит части одного прогона в разных местах. Один человек помнит, что тестировали новую системную инструкцию. Другой уверен, что качество выросло из-за другой модели. Третий менял температуру, но нигде это не отметил. В итоге все смотрят на одно число и спорят, откуда оно взялось.
Обычно картину портят четыре ошибки: в одном запуске меняют и промпт, и модель, и параметры; сравнивают результаты на разных выборках; не записывают цель прогона простыми словами; оставляют решение в голове автора, без короткого вывода для команды.
Ошибка с несколькими изменениями сразу кажется безобидной, но она ломает причинно-следственную связь. Если ответ стал лучше, вы уже не знаете, что сработало: новый промпт, другая модель или более строгий парсер. Когда таких запусков набирается десять, история превращается в набор догадок.
С выборками та же проблема. В марте команда проверяла извлечение полей на 800 обращениях клиентов, а в апреле взяла другие 200, потому что их было проще собрать. Метрика выросла, но сравнение уже нечестное. Модель могла стать лучше, а могла просто получить более удобные примеры.
Отдельно мешает отсутствие цели. Если в карточке запуска не написано "проверяем, снизит ли новый промпт число пропусков в паспортах", потом любой результат можно трактовать как угодно. Один скажет, что эксперимент неудачный, другой решит, что он нормальный, потому что стиль ответа стал чище.
Еще один тихий сбой - устное решение. Автор прогона ушел в отпуск или сменил проект, и никто не понимает, почему выбрали именно эту версию. Это особенно больно в продакшене, где модель идет дальше в API, отчеты и внутренние сервисы. Даже если команда работает через один endpoint, порядок в доступе к моделям не заменяет порядок в записях.
Если у запуска нет одной понятной карточки с целью, входными данными, точной версией промпта и коротким выводом, такого запуска почти нет.
Быстрая проверка перед новым запуском
Перед новым прогоном стоит потратить две минуты на сверку. Эти две минуты часто экономят полдня, когда через месяц кто-то пытается понять, почему новый вариант оказался лучше, а старый уже нельзя повторить.
У каждого запуска должны быть три простые метки: понятное имя, дата и владелец. Имя вроде support-faq-v12-qwen3-temp02 говорит намного больше, чем test-final-3. Дата помогает связать запуск с релизом, правкой промпта или заменой набора данных.
Если у промпта, датасета и eval-набора нет версий, запуск почти бесполезен. Тогда команда сравнивает не два варианта, а два неизвестных состояния системы.
Чек-лист на 2 минуты
- у запуска есть имя, дата, владелец и короткая цель
- у промпта записана версия и параметры вызова модели
- у датасета и eval-набора есть версии, а не просто папка
latest - метрики качества, стоимость и задержка лежат в одной карточке
- в карточке есть решение команды: приняли, отложили или отклонили, с короткой причиной
Хорошая карточка позволяет повторить прогон без автора. Если инженер ушел в отпуск, другой человек должен открыть запись и получить тот же результат или быстро понять, почему он отличается. Для этого мало хранить только текст промпта. Нужны модель, провайдер, system prompt, temperature, seed, если вы его задаете, и точная версия входных наборов.
Если команда работает через один OpenAI-совместимый endpoint, ошибиться еще проще. Base URL не меняется, а модель или провайдер уже другие. Это тоже нужно фиксировать, иначе сравнение будет нечестным.
Стоимость и задержку часто вспоминают слишком поздно. Потом все спорят только о качестве ответа. В продакшене так не работает: вариант с чуть худшей метрикой, но в два раза дешевле и быстрее, нередко лучше для бизнеса.
Записывайте и само решение. Например: "Отклонили. На клиентских диалогах качество выросло на 4%, но задержка увеличилась с 1.8 до 4.6 секунды". Через полгода такая строка помогает лучше любого скриншота.
Что сделать на этой неделе
Не пытайтесь сразу навести порядок во всем архиве. Обычно это заканчивается тем, что команда спорит о будущем процессе и ничего не переносит. Проще взять один шаблон карточки эксперимента, выбрать одно место хранения и начать с последних запусков.
Подойдет простая схема: одна папка в репозитории или один рабочий каталог, где у каждого запуска есть карточка с датой, владельцем, моделью, промптом, датасетом и итогом eval. Если у вас уже есть таблица, не выбрасывайте ее сразу. Оставьте ее как временный вход, но источником правды сделайте одно место.
На старте хватит четырех шагов:
- создать один шаблон карточки эксперимента
- перенести в него последние 10-20 запусков
- назначить человека, который следит за версиями промптов и данных
- договориться, как команда называет файлы, теги и запуски
Не тяните весь архив за два года. Старые записи часто неполные, а время команды дороже. Последние 10-20 запусков быстро покажут, где у вас дырки: нет версии датасета, потерялся промпт, не записан провайдер, метрики лежат в чужом ноутбуке.
Ответственный нужен не для бюрократии. Он просто держит дисциплину: не дает сохранять промпты как final_v2_new, следит, чтобы датасеты получали понятные версии, и возвращает запуск на доработку, если карточка пустая.
Если команда гоняет одну и ту же задачу через нескольких провайдеров, не разносите историю по разным кабинетам и логам. Проще вести запросы через один endpoint и собирать общий журнал. Так легче сравнивать ответы, цену, задержку и итоговые метрики без ручной склейки. В таком сценарии RU LLM может быть удобным вариантом: команда меняет base_url на api.rullm.com, продолжает использовать свои SDK, код и промпты без изменений и держит маршрутизацию запросов в одном месте.
Хороший результат на конец недели выглядит просто: по любому свежему запуску команда за минуту отвечает, кто его сделал, на чем запускал, какой промпт взял, какой датасет проверял и что показали evals.
Часто задаваемые вопросы
Почему Excel и чаты быстро ломают историю экспериментов?
Потому что таблица обычно хранит только число и короткую пометку, а сам контекст живет в чате, файлах и чужой памяти. Через несколько месяцев уже неясно, какой был промпт, на какой выборке считали метрику и какую модель брали.
Что минимум хранить у каждого запуска?
Храните одну карточку на запуск. В ней нужны полный промпт, ID промпта, точная модель и провайдер, дата, параметры вызова, версия датасета, версия eval-набора, метрики, стоимость, задержка и короткий вывод команды.
Как лучше называть запуски и файлы?
Выберите одну схему и не отходите от нее. Подойдут имена вроде support-qwen3-p07-v12-2025-04-18: по ним сразу видно задачу, модель, промпт, датасет и дату, а не только очередной final_v7.
Нужно ли сохранять полный промпт, если изменили только одну строку?
Да, храните полный текст каждый раз. Даже одна новая строка в system prompt или few-shot примерах может заметно поменять ответ, и потом вы уже не восстановите разницу по памяти.
Как вести версии датасетов без путаницы?
Не правьте опубликованную версию на месте. Любое заметное изменение оформляйте как новый снимок и записывайте дату выгрузки, источник, способ фильтрации, правила разметки и что именно вы добавили, убрали или переразметили.
Зачем держать отдельный стабильный eval-набор?
Заморозьте небольшой набор и сравнивайте на нем все близкие запуски. Если вы постоянно меняете eval, метрика начинает отражать не качество модели, а состав примеров.
Можно ли сравнивать запуски, если я поменял и модель, и промпт?
Нет, такой прогон лучше считать отдельной веткой. Если вы сменили сразу промпт, модель и данные, вы не поймете, что дало эффект и что стоит повторять.
Что писать в результатах eval, кроме одной метрики?
Записывайте не только итоговую цифру. Полезно сохранить формулу расчета или имя eval-скрипта, сырые ответы на спорных кейсах, долю поломок формата, стоимость, задержку и пару заметок по ручной проверке.
Зачем записывать точную модель, провайдера и маршрут через единый endpoint?
Потому что одинаковый base_url не значит одинаковый запуск. Если вы работаете через RU LLM или другой шлюз, фиксируйте точную модель, провайдера и маршрут запроса, иначе позже сравнение окажется ложным.
С чего начать, если в команде уже накопился бардак?
Не пытайтесь разобрать весь архив сразу. Возьмите один шаблон карточки, перенесите в него последние 10–20 запусков и договоритесь об именах, версиях и одном месте хранения; этого уже хватит, чтобы прекратить хаос.