Урок 2. Эвалы в Workbench без единой строчки кода

В первом уроке мы договорились: эвал — это способ перестать спорить о промптах на вкус и начать мерить. Самый дешёвый вход в эту привычку — Anthropic Workbench. Никакого кода, никакого датасета в репозитории: пишете промпт, добавляете несколько входов, жмёте прогон, ставите оценки руками — и уже видите, стало лучше или хуже.

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

Всё в этом уроке повторяется в браузере на console.anthropic.com/workbench. Нужен аккаунт Anthropic Console и немного кредитов — прогоны платные по обычным тарифам API. Для примеров хватит claude-haiku-4-5.

Промпт и переменные

Представим задачу: делаем сервис, который переводит код с любого языка на Python. Открываем Workbench — слева поле, куда пишется промпт (системная часть и пользовательское сообщение). Пишем первую версию:

Ты опытный программист. Твоя задача — перевести код с одного языка
программирования на Python. Цель — точный и идиоматичный перевод.

Вот исходный код:

<source_code>
{{SOURCE_CODE}}
</source_code>

Исходный код написан на языке:

<source_language>
{{SOURCE_LANGUAGE}}
</source_language>

Переведи этот код на Python

Ключевая деталь — двойные фигурные скобки: {{SOURCE_CODE}} и {{SOURCE_LANGUAGE}}. Workbench распознаёт такую запись как переменные промпта: это дырки, куда потом подставятся конкретные значения. Без переменных промпт остаётся одноразовым — прогнать его на десяти разных входах уже не получится.

После того как переменные появились в тексте, в интерфейсе открывается панель со значениями переменных — вызывается кнопкой с фигурными скобками { } над полем промпта. Туда вписываем тестовые значения, например:

  • SOURCE_LANGUAGEJavaScript
  • SOURCE_CODEconst chickenCount = 99;

Запускаем прогон — справа появляется ответ модели. Пока это ровно то же, что чат: один вход, один выход. Полезно, чтобы убедиться, что промпт вообще работает, но выводов о качестве отсюда не сделать.

Квиз 1

Зачем в промпте писать {{SOURCE_CODE}} вместо самого кода?

Режим оценки: таблица тест-кейсов

Проверять по одному входу — начало, но не эвал. В Workbench есть встроенный инструмент оценки: наверху переключатель между режимом промпта и режимом Evaluate. Переключаемся на Evaluate.

Открывается таблица. Каждая строка — один тест-кейс: столбцы под переменные промпта (SOURCE_CODE, SOURCE_LANGUAGE), столбец с ответом модели и столбец с оценкой. Первая строка уже заполнена — это значения, которые мы вводили в режиме промпта.

Дальше добавляем строки — в таблице есть кнопка добавления строки, каждая просит значения тех же переменных. Добавим два новых кейса: кусок Ruby и кусок C#. Например, Ruby-класс Person с методами initialize, birthday! и introduce, и любой небольшой C#-фрагмент. Смысл в разнообразии: если все тест-кейсы однотипные, эвал будет хвалить промпт за то, что тот умеет ровно одну вещь.

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

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

Оценки руками

Теперь самое важное и самое скучное: читать выводы и ставить оценки. В правом столбце каждой строки выставляется балл — по умолчанию шкала до 5.

Смотрим, что вернул промпт v1 на JavaScript-кейсе:

assistant

Вот перевод предоставленного JavaScript-кода на Python:

chicken_count = 99

В Python: 1) нет ключевого слова const — константы по соглашению пишут заглавными, но язык этого не требует; 2) переменные объявляются без let и var; 3) имя уже в snake_case… Если хотите подчеркнуть, что это константа, можно написать CHICKEN_COUNT = 99. Оба варианта корректны.

А вот Ruby-кейс: модель выдала аккуратный класс Person — и следом девять пунктов объяснений о том, что initialize стал __init__, восклицательный знак из birthday! убран, интерполяция строк заменена на f-строки, и так далее.

Переводы, если честно, приличные. Но как продукт это плохо, и по трём конкретным причинам:

  • Преамбулы. «Конечно! Вот перевод предоставленного Ruby-кода» — вежливо и бесполезно. Это оплаченные токены на выходе, которые никто не читает.
  • Формат не парсится. Как программно вытащить именно код? Резать по тройным обратным кавычкам и надеяться, что модель не передумает? Ответ не имеет предсказуемой структуры.
  • Простыня объяснений. Для нашего сценария она не нужна вообще: сервису нужен код, а не урок по Python.

Ставим всем трём кейсам по 3 из 5. Не двойка — переводы верные; не пятёрка — использовать это в проде нельзя.

Ставя баллы, держите в голове одно правило: критерий должен быть один и тот же для всех строк. Если для первого кейса «3» означает «есть преамбула», а для третьего — «мне не нравится стиль», сравнивать версии промпта потом будет бессмысленно. Проще всего заранее выписать себе словами, что такое 5, что такое 3 и что такое 1.
Квиз 2

Что сильнее всего обесценивает ручные оценки в Workbench?

Правим промпт и гоняем заново

У нас есть три сформулированные претензии — значит, есть что чинить. Возвращаемся в режим промпта и дописываем в конец требования к формату:

Ты опытный программист. Твоя задача — перевести код с одного языка
программирования на Python. Цель — точный и идиоматичный перевод.

Вот исходный код:

<source_code>
{{SOURCE_CODE}}
</source_code>

Исходный код написан на языке:

<source_language>
{{SOURCE_LANGUAGE}}
</source_language>

Переведи этот код на Python.
Оформи ответ так:

<python_code>
Здесь перевод на Python
</python_code>

Выведи только теги <python_code> без какого-либо другого текста

Изменение маленькое: мы задали жёсткую обёртку <python_code> и прямо запретили всё остальное. Workbench подсвечивает добавленный кусок, так что видно, чем v2 отличается от v1.

Запускаем — и получаем ровно то, чего хотели: никаких «Конечно!», никакого разбора отличий Ruby от Python, только теги с кодом внутри. Такой ответ уже режется регуляркой в одну строку.

Теперь возвращаемся в режим оценки. Обратите внимание на пометку версии — в левом верхнем углу появляется v2. Workbench хранит историю версий промпта, и это именно то, что превращает баловство в эвал: у результатов есть адрес.

Жмём прогон оставшихся кейсов. Все три ответа приходят в едином формате — и здесь мы честно ставим 5 из 5 по тому же критерию, что применяли к v1.

Сравнение версий колонками

Финальный шаг — увидеть разницу, а не вспоминать её. В правом верхнем углу режима оценки есть добавление сравнения: выбираем предыдущую версию промпта (v1), и таблица показывает обе версии рядом — вход, ответ v1, оценка v1, ответ v2, оценка v2.

Картина становится буквальной: 3–3–3 против 5–5–5 на одних и тех же входах. Это уже не «мне кажется, стало лучше», а результат, который можно показать коллеге и который переживёт вашу забывчивость через неделю.

Квиз 3

Вы сравниваете v1 и v2 своего промпта. Что обязательно должно остаться неизменным?

Где у Workbench потолок

Workbench прекрасен ровно до определённого размера. Дальше начинают мешать три вещи:

  • Человек не масштабируется. Пятнадцать строк вы прочитаете. Триста — нет, и на сотой строке ваш критерий поедет сам собой.
  • Оценки не воспроизводятся. Тот же вывод завтра вы оцените иначе. Кодовый эвал даст одинаковый ответ всегда.
  • Это не встроить в CI. Ручной прогон в браузере невозможно повесить на каждый пулл-реквест или на смену версии модели.

Поэтому маршрут курса такой: ручной эвал в Workbench → эвал, проверяемый кодом (урок 3) → эвал с моделью-судьёй. И почти всегда всё начинается именно здесь: тридцать минут в Workbench показывают, что вообще стоит проверять автоматом.

Упражнения

Открывайте Workbench — теория тут заканчивается быстро.

Упражнение 2.1 — Свой первый прогон на трёх входах

Возьмите любую свою рабочую задачу (суммаризация письма, извлечение полей из текста, классификация обращения). Напишите промпт минимум с одной переменной в двойных фигурных скобках, добавьте в режиме оценки три разных тест-кейса, прогоните все разом и поставьте баллы. До прогона выпишите себе словами, что значит 5, что значит 3 и что значит 1.

Решение упражненияСначала попробуйте сами — потом сверьтесь

Пример для задачи «вытащить из письма клиента тему обращения»:

Ты классифицируешь обращения в поддержку.

Вот письмо клиента:

<email>
{{EMAIL}}
</email>

Определи категорию обращения: оплата, доставка, качество товара,
техническая проблема или другое.

Три тест-кейса подберите намеренно разными: очевидное письмо про оплату, письмо на стыке двух категорий и письмо, где категории нет вовсе. Критерий, записанный заранее, может выглядеть так:

  • 5 — верная категория, ответ одним словом, ничего лишнего.
  • 3 — категория верная, но вокруг неё рассуждения и оговорки.
  • 1 — категория неверная либо ответ не разобрать.

Скорее всего, вы поймаете ту же болезнь, что и в уроке: содержательно верно, а формат непригоден для программы. Это и есть находка — эвал сработал.

Упражнение 2.2 — v2 и честное сравнение

По итогам прогона выпишите конкретные претензии к выводу (не «плохо», а «есть вступление», «нет фиксированного формата»). Почините промпт под эти претензии, прогоните те же самые тест-кейсы, поставьте оценки по тому же самому критерию и включите сравнение с предыдущей версией.

Решение упражненияСначала попробуйте сами — потом сверьтесь

Правка к промпту из предыдущего упражнения:

Оформи ответ так:

<category>
одно из: оплата | доставка | качество | техническая | другое
</category>

Выведи только тег <category> без какого-либо другого текста

Дальше — режим оценки, прогон оставшихся кейсов, оценки, добавление сравнения с v1. В таблице колонками вы увидите, где именно v2 выиграл, а где нет.

Отдельно посмотрите на пограничный кейс. Часто оказывается, что жёсткий формат его не спасает: если письмо действительно на стыке категорий, оценка останется невысокой и в v2. Это тоже результат — он говорит, что следующая правка должна быть не про формат, а про правила выбора категории. Эвал не только показывает прогресс, он показывает, куда копать дальше.

Что запомнить

  • Workbench в режиме оценки — таблица: строка = тест-кейс, столбцы = переменные промпта, ответ и балл.
  • Переменные в двойных фигурных скобках — то, что превращает одноразовый промпт в набор тест-кейсов.
  • Кейсы можно писать руками или сгенерировать, но сгенерированные обязательно просматривать глазами.
  • Ручные баллы работают, только если критерий записан заранее и один для всех строк и всех версий.
  • Версии промпта нумеруются (v1, v2…), и сравнение показывает их результаты рядом на одних и тех же входах.
  • Потолок подхода — человек: он не прочитает триста строк, не повторит оценку завтра и не встроится в CI. Отсюда дорога к кодовым и модельным эвалам.

Дочитали и сделали упражнения? Зафиксируйте прогресс — отметка сохранится в вашем браузере.

Перевод и адаптация урока «Workbench Evals» курса Prompt Evaluations © Anthropic, лицензия CC BY-NC 4.0. Перевод: Дарья Воронкина (@aishipuchka). Материал изменён: переведён на русский, скриншоты интерфейса заменены пошаговым описанием, примеры и названия моделей актуализированы, добавлены квизы. Используется некоммерчески.