Menu

Доработка промптов: как тестировать и улучшать

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

Каждый промпт на этой странице можно изменить и открыть в ChatGPT, Claude или другом ИИ-приложении.

Первая версия промпта: черновик. Часто она даёт что-то близкое к нужному, а разрыв между «близко» и «правильно» закрывается доработкой: вы намеренно меняете промпт, снова запускаете его на том же входе и проверяете, помогло ли изменение. Если делать это небрежно, доработка превращается в случайное перефразирование, пока один удачный ответ не покажется нормальным. Если делать это как небольшой эксперимент, вы получаете промпт, который работает на следующей сотне входов, а не только на том, что вы проверили.

В методе пять шагов: определить, как выглядит хороший ответ, держать постоянные тестовые входы, менять по одной вещи за раз, сравнивать ответы и знать, когда остановиться.

Определите, как выглядит хороший ответ

Прежде чем что-то править, запишите, что должен делать ответ, в виде проверок, на которые можно ответить «да» или «нет». «Хорошее сообщение коммита» проверить нельзя. А вот это можно:

  1. Строка темы короче 50 символов.
  2. Сообщение следует формату Conventional Commits (fix:, feat: и так далее).
  3. Тело объясняет, зачем понадобилось изменение, а не то, что уже видно в диффе.
  4. Упоминается номер задачи, если он есть.

Критерии делают две вещи. Они подсказывают, что добавить в промпт, потому что каждый критерий часто оказывается недостающей инструкцией. И они не дают оценивать ответы по тому, насколько приятно те звучат, а это самый простой способ принять уверенный, но неверный ответ.

Держите небольшой набор тестовых входов

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

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

Меняйте по одной вещи за раз

Если вы одновременно поменяли роль, формат и примеры и результат улучшился, вы не знаете, какое изменение помогло, и, возможно, сохраняете две бесполезные правки. Поменяйте одну вещь, запустите, сравните. Вкладки ниже: три версии одного промпта, каждая отличается от предыдущей одним изменением.

Напиши сообщение коммита для этого диффа.- if len(password) > 8: + if len(password) >= 8: return True
Try it
Example replyReplies vary between models and runs.

Обновление проверки длины пароля

Этот коммит обновляет логику проверки пароля, заменяя оператор сравнения > на >=. В результате пароли длиной ровно 8 символов теперь будут считаться допустимыми. Это изменение повышает точность проверки и улучшает опыт пользователей при создании аккаунтов.

Версия 1 не проходит критерии 2 и 3: у темы нет префикса типа, а тело пересказывает дифф большим количеством слов. Версия 2 добавляет требования к формату и проходит критерии 1 и 2, но её тело всё ещё описывает дифф. Очевидная следующая правка: ещё одна инструкция («объясни почему»), но модель не может объяснить причину, которую ей никогда не сообщали. Версия 3 вместо этого добавляет недостающий контекст, и тело вместе со ссылкой на задачу появляются без всякой просьбы. Это самый частый урок доработки: когда инструкция не исправляет ответ, промпту обычно не хватает информации, а не нажима.

Сравнивайте ответы бок о бок

Запускайте каждую версию на каждом тестовом входе, и каждую больше одного раза, потому что чат-модели сэмплируют слова, и два запуска одного промпта различаются. Ставьте ответы рядом и сверяйте их с критериями, а не с тем, как вы помните прошлый запуск.

Для точных критериев первый проход оценки может сделать второй вызов модели. Вставьте ответы в промпт для оценки с расписанными критериями:

Оценить ответы по фиксированным критериям
Fill in
Проверь каждый ответ ниже по критериям. По каждому критерию ответь «прошло» или «не прошло» с коротким обоснованием, цитирующим ответ. Оценивай только перечисленные критерии. Не поощряй длину или стиль. Критерии: 1. Строка темы короче 50 символов. 2. Следует Conventional Commits. 3. Тело объясняет, зачем понадобилось изменение, а не то, что видно в диффе. 4. Упоминается номер задачи. Ответ A: """ fix: принимать пароли ровно из 8 символов Проверка длины изменена с > на >=, чтобы пароли ровно из 8 символов проходили валидацию. """ Ответ B: """ fix: принимать пароли ровно из 8 символов Страница регистрации просит не меньше 8 символов, но проверка отклоняла пароли ровно такой длины, и пользователи, следовавшие инструкции, не могли зарегистрироваться. Fixes #412 """ Ответь таблицей, по одной строке на критерий.
Try it
Example replyReplies vary between models and runs.
КритерийОтвет AОтвет B
1. Тема короче 50 символовПрошло: в теме 41 символПрошло: та же тема, 41 символ
2. Conventional CommitsПрошло: начинается с «fix:»Прошло: начинается с «fix:»
3. Тело объясняет почемуНе прошло: «Проверка длины изменена с > на >=» пересказывает диффПрошло: «пользователи, следовавшие инструкции, не могли зарегистрироваться»
4. Упоминается задачаНе прошло: номера задачи нетПрошло: «Fixes #412»

Относитесь к модели-оценщику как к помощнику, а не к судье. Zheng et al. 2023, «Judging LLM-as-a-Judge with MT-Bench and Chatbot Arena», описали перекосы моделей-судей, в том числе предпочтение более длинных ответов и ответа на определённой позиции. Делайте критерии проверяемыми, просите цитаты в качестве доказательств, меняйте местами A и B, когда сравниваете два ответа, и часть ответов читайте сами. Проверки вроде подсчёта символов надёжнее делать строкой кода, чем суждением модели.

Исправляйте промпт, а не переписку

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

Храните старые версии с однострочной заметкой о том, что изменилось и что это исправило. Хватит обычного текстового файла. Когда более поздняя правка всё ухудшит, можно будет вернуться назад, а не вспоминать, что было в промпте раньше.

Сравнение в коде

Когда промпт запускается через API, короткий скрипт может собрать сравнение бок о бок для каждой версии и каждого тестового входа. Этот использует Python SDK от OpenAI и пишет markdown-файл, который можно прочитать сверху вниз.

from openai import OpenAI

client = OpenAI()
MODEL = "your-model-id"  # e.g. from your provider's model list

# each prompt file contains {input} where the test diff goes
PROMPTS = {
    "v2": open("prompts/commit_v2.txt").read(),
    "v3": open("prompts/commit_v3.txt").read(),
}
TESTS = [open(f"tests/diff_{i}.txt").read() for i in range(1, 6)]

with open("results.md", "w") as out:
    for i, test in enumerate(TESTS, 1):
        out.write(f"## Test {i}\n\n")
        for name, template in PROMPTS.items():
            for run in (1, 2):
                response = client.chat.completions.create(
                    model=MODEL,
                    messages=[{"role": "user", "content": template.replace("{input}", test)}],
                )
                out.write(f"### {name}, run {run}\n\n{response.choices[0].message.content}\n\n")

Когда остановиться

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

Останавливайтесь и тогда, когда изменения начинают обменивать одни провалы на другие: одна правка чинит тест 2 и ломает тест 4, следующая делает наоборот. Такая картина значит, что от промпта требуют того, что одна инструкция зафиксировать не может. Обычные выходы: показать формат парой примеров (few-shot промптинг), разбить работу на шаги с помощью цепочки промптов или перенести детерминированные части, например подсчёт символов или проверку формата, в код, который проверяет ответ. Если идеи закончились, может помочь мета-промптинг: дайте модели промпт, вход и плохой ответ и спросите, какая часть промпта, скорее всего, его вызвала.

Часто задаваемые вопросы

Как улучшить промпт, который даёт плохие ответы?

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

Сколько тестовых входов нужно, чтобы проверить промпт?

Для промпта, который вы будете использовать повторно, обычно хватает от трёх до десяти: несколько типичных случаев, один-два крайних (очень короткий, очень длинный, необычный) и один вход, на котором промпт раньше ошибался. Не меняйте их, пока дорабатываете промпт, чтобы изменение в выводе шло от промпта, а не от другого входа.

Почему при повторном запуске того же промпта ответ другой?

Чат-модели сэмплируют каждое слово из распределения вероятностей, поэтому выводы различаются от запуска к запуску. Когда сравниваете две версии промпта, запускайте каждую больше одного раза на тех же входах. Разница, которая видна в каждом запуске, скорее всего, реальна; разница, появившаяся в одном запуске, может быть случайностью. Через API можно также понизить температуру, чтобы уменьшить разброс.

Можно ли поручить ИИ оценивать ответы моего промпта?

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

Когда остановиться и перестать улучшать промпт?

Остановитесь, когда каждый критерий проходит на каждом тестовом входе в нескольких запусках или когда каждое новое изменение чинит один случай и ломает другой. В этот момент проблема обычно уже не в промпте: задаче могут быть нужны примеры, разбиение на шаги или проверка в коде.

Coddy programming languages illustration

Учитесь программировать с Coddy

НАЧАТЬ