Назад в блог

AI для новичковИнструкция

Проверка промпта на 20 примерах: точное совпадение в Python

Соберите набор из 20 примеров, оцените промпт точным совпадением коротким скриптом на Python и узнайте, помогла ли правка на самом деле.

Автор: CheapTokens TeamОпубликовано 6 мин чтения

Обложка: фрагмент кода, который сравнивает ответ модели с эталонной меткой, заголовок «Проверка промпта на 20 примерах»
Содержание
  1. Соберите набор: 20 сообщений и ответ, который вы ждёте
  2. Скрипт: отправить каждый случай, сверить, вывести промахи
  3. Меняйте одно, запускайте снова
  4. Тот же набор, другая модель: держится ли счёт?
  5. Где точное совпадение перестаёт работать

Промпт сработал на двух сообщениях, которые вы попробовали. Значит ли это, что он работает? Пока нет. Прогоните его через 20 настоящих сообщений с известными ответами, посчитайте, сколько он угадал, и прочитайте те, где ошибся. Считает короткий скрипт на Python, а когда вы поменяете промпт, тот же скрипт покажет, помогла ли правка, — и не придётся полагаться на ощущения.

Документация Anthropic про критерии успеха и оценочные тесты (проверено 7 ноября 2026 года) говорит то же самое: тесты должны быть про вашу задачу, в них нужны неудобные случаи, а много проверок, которые считает код, лучше, чем несколько, которые вы оцениваете вручную. Ниже — самая маленькая версия такого подхода, которую можно запустить сегодня.

Четыре шага: 20 примеров идут к модели, ответы сверяются по точному совпадению, на выходе точность и список промахов
Весь метод: примеры на входе, одно число и список промахов на выходе

Соберите набор: 20 сообщений и ответ, который вы ждёте#

Допустим, вы раскладываете сообщения клиентов по трём кучкам: positive, negative или mixed. Создайте файл cases.csv и запишите 20 сообщений, которые вам действительно могут прийти, а рядом — метку, которую поставили бы вы сами. Метки пишите до первого запуска. Если брать за «правильные» ответы самой модели, тест сможет только соглашаться с ней.

csv
text,label
"Arrived a day early and works perfectly. Thank you!",positive
"The charger stopped working after two days.",negative
"Great screen, but the battery barely lasts until lunch.",mixed
"Support answered in five minutes and fixed it.",positive
"I waited three weeks and nobody replied.",negative
"Oh great, another update that deletes my settings.",negative
"Nice design. Pity about the price.",mixed
"Exactly what I ordered.",positive
"The box was crushed, but the headphones inside are fine and sound great.",mixed
"Refund took 10 days. Never again.",negative
"Love it!!",positive
"Cheaply made, but honestly it does the job for the price.",mixed
"Worst purchase of the year.",negative
"Five stars. Would buy again.",positive
"Fast delivery, wrong colour.",mixed
"It's fine. Not amazing, not terrible.",mixed
"Zero issues in six months of daily use.",positive
"The app crashes every time I open the camera.",negative
"Thanks for nothing.",negative
"Setup was a pain, but once it ran, it's been rock solid.",mixed

Посмотрите на состав: 6 positive, 7 negative, 7 mixed. Саркастические строки («Oh great, another update…», «Thanks for nothing.») и пограничная («It's fine. Not amazing, not terrible.») тут специально. Набор из одних очевидных сообщений даст 100% и ничему не научит. Берите настоящие — из своей почты, тикетов или выгрузки чата; сложные случаи вы и так знаете, они вас раздражают. Сообщения здесь на английском, потому что и промпт английский; у вас они могут быть на любом языке.

Почему 20? Это стартовый размер, а не число из документации (в её примере 1000 твитов). Двадцать примеров можно вписать руками за полчаса, и при этом одна случайная удача не решает итог.

Скрипт: отправить каждый случай, сверить, вывести промахи#

План из четырёх шагов, код идёт строго по нему.

Расставьте по порядку

Расставьте шаги проверки по порядку

  1. Загрузить 20 примеров из CSV
  2. Отправить каждое сообщение модели вместе с промптом
  3. Сверить ответ с вашей меткой
  4. Вывести точность и случаи, где модель ошиблась

Цикл работает, только если метки есть до первого вызова модели, а промахи идут последними, потому что именно их вы читаете и разбираете.

Установите SDK командой pip install openai и положите ключ в переменную окружения CHEAPTOKENS_API_KEY. Любой OpenAI-совместимый API работает так же; здесь скрипт обращается к CheapTokens и модели GLM-5.3-Flash (подключение описано в документации).

python
import csv
import os
from openai import OpenAI

client = OpenAI(
    base_url='https://api.cheaptokens.dev/v1',
    api_key=os.environ['CHEAPTOKENS_API_KEY'],
)
MODEL = 'zai-org/GLM-5.3-Flash'

PROMPT = (
    'Classify the customer message as positive, negative or mixed. '
    'Answer with one word only.'
)


def ask(text):
    r = client.chat.completions.create(
        model=MODEL,
        temperature=0,
        max_tokens=100,
        messages=[
            {'role': 'system', 'content': PROMPT},
            {'role': 'user', 'content': text},
        ],
    )
    return r.choices[0].message.content or ''


with open('cases.csv', newline='', encoding='utf-8') as f:
    cases = list(csv.DictReader(f))

correct, failed = 0, []
for case in cases:
    got = ask(case['text'])
    ok = got.strip().strip('.').lower() == case['label']
    correct += ok
    if not ok:
        failed.append((case['text'], case['label'], got.strip()))

print(f'Accuracy: {correct}/{len(cases)} = {correct / len(cases):.0%}')
for text, want, got in failed:
    print(f'- {text!r}: expected {want}, got {got!r}')

На три детали стоит взглянуть ещё раз.

  • temperature=0 делает ответы максимально ровными, так что изменение счёта идёт от вашего промпта, а не от случайности.
  • max_tokens=100 намного больше, чем нужно метке из одного слова. Если ответ вдруг пустой или обрезан, посмотрите finish_reason; разбор finish_reason "length" покажет, что увеличить.
  • Строка проверки — рецепт из документации: strip().lower() и сравнение с верным ответом, плюс одно добавление: она ещё отбрасывает точку в конце, потому что «Negative.» и «negative» для вас один и тот же ответ.

Что вы увидите при запуске? Одну строку с точностью и по строке на каждый промах. Допустим, первый запуск выводит такое:

text
Accuracy: 14/20 = 70%
- 'Oh great, another update that deletes my settings.': expected negative, got 'positive'
- "It's fine. Not amazing, not terrible.": expected mixed, got 'positive'
…

(Числа здесь — допущение, чтобы показать вид вывода; у вас будут другие.) Сарказм и пограничные формулировки — как раз то, что короткий промпт любит пропускать. Главное, что вы больше не гадаете: у вас есть список.

Меняйте одно, запускайте снова#

Теперь самое полезное. Прочитайте промахи, выберите причину, поменяйте промпт в одном месте и запустите заново. Правка за раз, иначе не поймёте, какая из них сдвинула счёт.

Сравнение

Промпт v1 → v2: добавили правило и два примера

v1

text
Classify the customer message as positive, negative or mixed.
Answer with one word only.

v2

text
Classify the customer message as positive, negative or mixed.
Sarcasm counts as negative. Praise plus a complaint is mixed.
Answer with one word only.

Message: Lovely colour, but it arrived with a scratch.
Answer: mixed

Message: Sure, thanks a lot. Now my order is lost.
Answer: negative

Два примера придуманы нарочно. Не вставляйте в промпт сообщение из cases.csv: тогда модель проверяют на ответе, который вы ей же и подсказали, и счёт получится завышенным. Это few-shot, а тестовый набор показывает, окупился ли он. Если же v1 у вас пока расплывчатый, начните с материала как написать хороший промпт, а уже потом измеряйте.

Вставьте v2 в PROMPT (для нескольких строк подойдут тройные кавычки) и запустите скрипт ещё раз. Допустим, он печатает Accuracy: 17/20 = 85%. Ещё три случая верны, значит, v2 выглядит лучше. Насколько этому верить? В наборе из 20 случаев каждый стоит 5 пунктов, так что 70% → 85% — это три сообщения. Хороший намёк, но не доказательство. А если счёт упал, вы узнали не менее ценное и не выкатили промпт хуже прежнего.

Тот же набор, другая модель: держится ли счёт?#

Тот же файл отвечает на второй вопрос: не платите ли вы за больше модели, чем нужно этой задаче? Поменяйте одну строку и запустите снова:

python
MODEL = 'deepseek-ai/DeepSeek-V4-Flash-0731'

Если точность на ваших 20 примерах та же, для этой задачи ответ готов — по вашим данным, а не по таблице лидеров. Если упала, посмотрите, какие сообщения сломались, прежде чем что-то решать.

Сколько это стоит? Возьмём около 150 входных токенов на случай (инструкция плюс сообщение) и около 5 выходных на метку из одного слова. Это 3000 входных и 100 выходных токенов на прогон из 20 случаев — $0.000064 на GLM-5.3-Flash. Десять перезапусков набора — 200 запросов; таблица ниже показывает эту нагрузку для каждой модели, рядом с OpenRouter. На этой нагрузке в сумме, с учётом входа и выхода, каждая модель из таблицы стоит меньше референсной цены OpenRouter.

Модель За запрос 200 запросов OpenRouter, 200 запросов
GLM-5.3-Flash $0.0000032 $0.00064 $0.0011
DeepSeek-V4-Flash $0.0000028 $0.00055 $0.0022
MiniMax-M2.7 $0.0000083 $0.0017 $0.0198

150 входных и 5 выходных токенов на запрос. Цены за 1M токенов актуальны и меняются вместе с нашими тарифами; столбец OpenRouter показывает справочные цены для той же нагрузки.

В статье мы используем две из них. У GLM-5.3-Flash контекст 390K и до 8192 токенов в ответе; у DeepSeek-V4-Flash контекст 380K, до 32 768 токенов в ответе, одна цена в любое время суток и общий баланс со всеми остальными моделями. Актуальные цены — на странице цен, полный список — в моделях.

Где точное совпадение перестаёт работать#

Точное совпадение работает потому, что верный ответ — одно слово из фиксированного списка. Для открытого текста — пересказов, переписанных абзацев, объяснений — одной строки для сравнения нет. Документация описывает другой путь, оценку моделью, и советует брать в судьи не ту модель, что писала ответ. Всё равно начните с точного совпадения: там, где можно заставить модель отвечать коротко и по списку, это самый дешёвый и понятный тест. Правило из документации: много проверок, которые считает код, лучше, чем мало ручных.

Ещё одна привычка: когда v2 перестаёт улучшаться, не полируйте дальше на тех же 20 сообщениях. Добавьте 5–10 новых, лучше всего — настоящие промахи из работы, и запустите снова.

Быстрая проверка

v2 набрал 17/20, а v1 — 15/20 на тех же примерах. Какой вывод самый осторожный?

Показать ответ

Ответ: v2 выглядит лучше, но разница в два случая из 20 мала: добавьте новые примеры и запустите снова

Каждый случай — 5 пунктов, поэтому разрыв в два случая — повод присмотреться, а не приговор. Следующая проверка — новые примеры, которых v2 ещё не видел.