newsmode
search
Меню
arrow_back Назад

Prompting Fundamentals and How to Apply them Effectively

auto_awesomeКраткое саммари

Статья описывает ключевые принципы и приёмы промптинга для эффективной работы с большими языковыми моделями. Рассматривается ментальная модель промптов как обусловливания вероятностной модели, а также конкретные техники: назначение ролей, структурированный ввод/вывод с помощью XML-тегов, предзаполнение ответов, n-shot промптинг, Chain-of-Thought и разбиение сложных промптов на несколько шагов. Автор подчёркивает, что для n-shot промптинга нужно не менее дюжины примеров, репрезентативных для продакшн-данных, а CoT значительно эффективнее при использовании структурированного «черновика» и проверки промежуточных результатов. Приводятся практические советы по размещению контекста, выбору температуры (рекомендуется начинать с 0.8), борьбе с галлюцинациями и использованию стоп-последовательностей. Отмечается, что вежливые формулировки и угрозы/чаевые не влияют на качество ответов современных моделей.

Основы промптинга и как применять их эффективно

[ llm production 🔥 ] · 17 мин. чтения

Написание хороших промптов — самый простой способ извлечь пользу из больших языковых моделей (LLM). Тем не менее важно понимать основы, даже когда мы применяем продвинутые техники и инструменты оптимизации промптов. Например, Chain-of-Thought (CoT) — это гораздо больше, чем просто добавить «думай шаг за шагом». Здесь мы обсудим ряд основ промптинга, которые помогут вам получить максимум от LLM.

Отступление: к настоящему моменту мы должны понимать, что перед серьёзной работой над промптами нужны надёжные эвалюации. Без эвалюаций как мы будем измерять улучшения или регрессии? Мой обычный рабочий процесс: (i) вручную разметить ~100 примеров для оценки, (ii) написать начальный промпт, (iii) запустить эвалюацию и итеративно дорабатывать промпт и эвалюации, (iv) провести оценку на отложенной тестовой выборке перед деплоем. Вот материалы по теме: практические эвалюации для ключевых задач и как строить эвалюации с разбором кейса.

В примерах промптов и кода ниже мы будем использовать Claude Messages API. Промпты намеренно оставлены простыми и могут быть дополнительно оптимизированы. API предоставляет отдельные роли для пользователя и ассистента, а также системный промпт.

import anthropic message = anthropic.Anthropic().beta.messages.create( model="claude-3-sonnet-20240229", max_tokens=1024, system="Today is 26th May 2024.", messages = [ {"role": "user", "content": "Hello there."}, {"role": "assistant", "content": "Hi, I'm Claude. How can I help?"}, {"role": "user", "content": "What is prompt engineering?"}, ] )

Ментальная модель: промпты как обусловливание

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

Таким образом, по своей сути промпт-инжиниринг — это обусловливание вероятностной модели для генерации нужного нам результата. Каждая дополнительная инструкция или фрагмент контекста может рассматриваться как условие, направляющее генерацию модели в определённую сторону. Эта ментальная модель применима и к генерации изображений.

Рассмотрим промпты ниже. Первый, скорее всего, сгенерирует ответ о компании Apple. Второй опишет фрукт. А третий объяснит идиому.

# Промпт 1 Tell me about: Apple # Промпт 2 Tell me about: Apple fruit # Промпт 3 Tell me about: Apple of my eye

Просто добавив несколько токенов, мы обусловили модель отвечать по-разному. По аналогии, техники промптинга — n-shot промптинг, структурированный ввод и вывод, CoT и т. д. — это просто более изощрённые способы обусловливания LLM.

Назначение ролей и обязанностей

Один из способов обусловить вывод модели — назначить ей конкретную роль или обязанность. Это даёт модели контекст, который направляет её ответы с точки зрения содержания, тона, стиля и т. д.

Рассмотрим промпты ниже: поскольку назначенные роли различаются, можно ожидать совершенно разных ответов. Воспитатель детского сада, вероятно, ответит простым языком с аналогиями, тогда как профессор NLP может погрузиться в технические детали механизмов внимания.

# Промпт 1 You are a preschool teacher. Explain how attention in LLMs works. # Промпт 2 You are an NLP professor. Explain how attention in LLMs works.

Роли и обязанности также могут повысить точность в большинстве задач. Представьте, что мы строим систему для фильтрации NSFW-промптов генерации изображений. Хотя базовый промпт вроде промпта 1 может сработать, мы можем улучшить точность модели, задав ей роль (промпт 2) или обязанность (промпт 3). Дополнительный контекст в промптах 2 и 3 побуждает LLM тщательнее анализировать входные данные, тем самым повышая полноту обнаружения более тонких проблем.

# Промпт 1 Is this image generation prompt safe? # Промпт 2 Claude, you are an expert content moderator who identifies harmful aspects in prompts. Is this image generation prompt safe? # Промпт 3 Claude, you are responsible for identifying harmful aspects in prompts. Is this image generation prompt safe?

Структурированный ввод и вывод

Структурированный ввод помогает LLM лучше понять задачу и входные данные, улучшая качество вывода. Структурированный вывод упрощает парсинг ответов и интеграцию с последующими системами. Для Claude особенно хорошо работают XML-теги, тогда как другие LLM могут предпочитать Markdown, JSON и т. д.

В этом примере мы просим Claude извлечь атрибуты из описания товара ().

The SmartHome Mini is a compact smart home assistant available in black or white for only $49.99. At just 5 inches wide, it lets you control lights, thermostats, and other connected devices via voice or app—no matter where you place it in your home. This affordable little hub brings convenient hands-free control to your smart devices. Extract the , , , and from this product .

Claude надёжно следует таким явным инструкциям и почти всегда генерирует вывод в запрошенном формате.

SmartHome Mini 5 inches wide $49.99 black or white

Это можно масштабировать для обработки нескольких документов одновременно. Вот пример, в котором мы передаём отзывы о товарах в виде массива словарей, а затем конвертируем их в XML. (Хотя в примере показаны только три документа, количество можно увеличить до десятков, а то и сотен документов).

from dicttoxml import dicttoxml from xml.dom.minidom import parseString def custom_item_func(item): return 'review' docs = { "reviews": [ { "id": 1, "text": "The SmartHome Mini is a compact, powerful, and user-friendly smart home hub. It offers great value for its price." }, { "id": 2, "text": "The SmartHome Mini is a decent entry-level smart home hub, but it has some connectivity issues and the app needs improvement." }, { "id": 3, "text": "Despite being affordable and compact, the SmartHome Mini's performance is disappointing, with poor voice command interpretation and unreliable device connections." } ] } # Convert the dictionary to XML xml_output = dicttoxml(docs, attr_type=False, root=False, item_func=custom_item_func) # Parse the XML string dom = parseString(xml_output) # Pretty-print the XML with indentation and spaces pretty_xml = dom.toprettyxml(indent=" ") # Print the pretty-printed XML print(pretty_xml)

Это даёт нам следующий XML с тегами .

1 The SmartHome Mini is a compact, powerful, and user-friendly smart home hub. It offers great value for its price. 2 The SmartHome Mini is a decent entry-level smart home hub, but it has some connectivity issues and the app needs improvement. 3 Despite being affordable and compact, the SmartHome Mini's performance is disappointing, with poor voice command interpretation and unreliable device connections.

Затем мы можем попросить Claude создать

по со ссылками на соответствующие теги , что даёт следующий результат.

The SmartHome Mini receives mixed reviews. 1 praises its compact size, power, user-friendliness, and value for money. However, 2 notes connectivity issues and room for app improvement, while 3 finds the performance disappointing due to poor voice command interpretation and unreliable device connections.

Мы также можем попросить модель извлечь , и соответствующий отзыва, что приводит к следующему результату:

compact size positive 1 power positive 1 connectivity negative 2 app negative 2 affordability positive 3 performance negative 3

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

Предзаполнение ответов Claude

Предзаполнение ответа LLM — это, по сути, «вкладывание слов ей в уста». Для Claude это гарантирует, что сгенерированный текст начнётся с указанных токенов (по крайней мере, по моему опыту на миллионах запросов).

Вот как это делается через Claude Messages API: мы предзаполняем ответ ассистента токенами . Это гарантирует, что Claude начнёт именно с этих токенов, а также упрощает парсинг на последующих этапах.

input = """ The SmartHome Mini is a compact smart home assistant available in black or white for only $49.99. At just 5 inches wide, it lets you control lights, thermostats, and other connected devices via voice or app—no matter where you place it in your home. This affordable little hub brings convenient hands-free control to your smart devices. Extract the , , , and from this product . Return the extracted attributes within . """ messages=[ { "role": "user", "content": input, }, { "role": "assistant", "content": "" # Prefilled response } ]

N-shot промптинг

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

Но n-shot промптинг — палка о двух концах. Если мы предоставим слишком мало примеров, скажем, три-пять, мы рискуем «переобучить» модель (через обучение в контексте) на этих примерах. В результате, если входные данные будут отличаться от узкого набора примеров, качество вывода может упасть.

Обычно я использую не менее дюжины примеров или больше. В большинстве академических эвалюаций используются промпты с 32 или 64 примерами. (Именно поэтому я стараюсь не называть эту технику few-shot промптингом, потому что слово «few» может вводить в заблуждение относительно того, сколько примеров нужно для надёжной работы.)

Также важно, чтобы наши n-shot примеры были репрезентативны для ожидаемых продакшн-данных. Если мы строим систему для извлечения аспектов и тональности из отзывов о товарах, нужно включить примеры из нескольких категорий: электроника, мода, продукты, медиа и т. д. Кроме того, следите за соответствием распределения примеров продакшн-данным. Если 80% аспектов в продакшне положительные, n-shot промпт должен это отражать.

input = """ The SmartHome Mini is a compact smart home assistant available in black or white for only $49.99. At just 5 inches wide, it lets you control lights, thermostats, and other connected devices via voice or app—no matter where you place it in your home. This affordable little hub brings convenient hands-free control to your smart devices. Extract the , , , and from this product . Here are some of and extracted : Introducing the sleek and powerful UltraBook Pro laptop ... (truncated) UltraBook Pro silver, space gray 14" display, 2.8lbs $1,299 Spark imagination and creativity with the Mega Blocks Construction Set ... (truncated) Mega Blocks Construction Set colorful 200 pieces $24.99 The perfect little black dress for any occasion ... (truncated) Little Black Sheath Dress black petite, regular, tall lengths, sizes 2-16 $89.99 Stay hydrated on the trail with the HydroFlow Water Bottle ... (truncated) HydroFlow Water Bottle 6 colors 24 oz $21.99 Achieve a flawless complexion with Glow Perfect Foundation ... (truncated) Glow Perfect Foundation 20 shades 1 fl oz $32 (... examples truncated) Return the , , , and within . """ messages=[ { "role": "user", "content": input, }, { "role": "assistant", "content": "" # Prefilled response } ]

Тем не менее необходимое количество примеров зависит от сложности задачи. Для более простых целей — таких как соблюдение формата/структуры вывода или тона ответа — может хватить и пяти примеров. В таких случаях достаточно предоставить только желаемый вывод в качестве примеров, без привычных пар «вход-выход».

Углублённый разбор Chain-of-Thought

Основная идея CoT — дать LLM «пространство для размышлений» перед генерацией финального результата. Промежуточные рассуждения позволяют модели разбить задачу на части и обусловить собственный ответ, что часто приводит к лучшим результатам, особенно если задача сложная.

Стандартный подход — просто добавить фразу «think step by step» (думай шаг за шагом).

Claude, you are responsible for accurately summarizing the meeting . {transcript} Think step by step and return a

of the .

Однако мы можем сделать больше для повышения эффективности CoT.

Одна из идей — поместить CoT-рассуждения в выделенный , а затем сгенерировать

на основе черновика. Это упрощает парсинг финального результата и позволяет при необходимости исключить CoT. Чтобы гарантировать начало с черновика, можно предзаполнить ответ Claude открывающим тегом .

Claude, you are responsible for accurately summarizing the meeting . {transcript} Think step by step on how to summarize the within the provided . Then, return a

based on the .

Другой способ улучшить CoT — дать более конкретные инструкции для процесса рассуждения. Например:

Claude, you are responsible for accurately summarizing the meeting . {transcript} Think step by step on how to summarize the within the provided . In the , return a list of , , and . Then, check that items are factually consistent with the . Finally, return a

based on the .

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

Разбивайте универсальные промпты на несколько мелких

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

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

# Промпт для извлечения атрибутов стенограммы через Haiku Claude, you are responsible for accurately extracting information from the . {transcript} From , extract a list of , , and . Return the list within .

Затем можно проверить, что извлечённые данные согласованы со стенограммой, с помощью Sonnet.

# Промпт для проверки извлечённых атрибутов через Sonnet Claude, you are responsible for checking against a . Here is the meeting transcript: {transcript} Here is the extracted information: {extracted_information} Think step by step and check that the is factually consistent with the within the . Then, return a list of factually consistent , , and within .

Наконец, можно использовать Haiku для форматирования извлечённой информации.

# Промпт для преобразования атрибутов стенограммы в буллиты через Haiku Claude, you are responsible for converting into bullet-point summaries. {confirmed_extracted_information} Rewrite the into bullets for either or , with the in parentheses.

Для примера, AlphaCodium показал, что переход от единственного прямого промпта к многоэтапному рабочему процессу повысил точность gpt-4 (pass@5) на CodeContests с 19% до 44%. Их процесс кодирования включал несколько этапов/промптов:

Рефлексия над задачей Рассуждение над публичными тестами Генерация возможных решений Ранжирование возможных решений Генерация синтетических тестов Итеративная доработка решения с публичными и синтетическими тестами

Оптимальное размещение контекста

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

Роль или обязанность (обычно кратко) Контекст/документ Конкретные инструкции Предзаполненный ответ

Это согласуется с паттерном «роль-контекст-задача», используемым во многих собственных примерах Anthropic.

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

Создание эффективных инструкций

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

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

Работа с галлюцинациями

Это непростая тема. Хотя некоторые техники помогают бороться с галлюцинациями, ни одна из них не является безотказной. Поэтому не предполагайте, что их применение полностью устранит галлюцинации.

Для задач, связанных с извлечением информации или ответами на вопросы, включите инструкцию, позволяющую LLM ответить «Я не знаю» или «Не применимо». Кроме того, попробуйте проинструктировать модель давать ответ только при высокой уверенности в его правильности. Вот пример:

Claude, answer the following question based on the provided . {context} If the question CANNOT be answered based on the , respond with "I don't know". Only provide an answer if you are highly confident it is factually correct. Question: {question} Answer:

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

Claude, you are responsible for summarizing meeting . {transcript} Think step by step on how to summarize the within the provided . In the , identify the , , and their . Then, check that the items are factually consistent with the . Finally, return a

based on the .

Использование стоп-последовательности

Параметр стоп-последовательности позволяет указать слова или фразы, сигнализирующие об окончании желаемого вывода. Это предотвращает появление лишнего текста, снижает задержку и упрощает парсинг ответов модели. При работе с Claude удобный вариант — использовать закрывающий XML-тег (например, ) в качестве стоп-последовательности.

input = """ The SmartHome Mini is a compact smart home assistant available in black or white for only $49.99. At just 5 inches wide, it lets you control lights, thermostats, and other connected devices via voice or app—no matter where you place it in your home. This affordable little hub brings convenient hands-free control to your smart devices. Extract the , , , and from this product . Return the extracted attributes within . """ message = anthropic.Anthropic().messages.create( model="claude-3-opus-20240229", max_tokens=1024, messages=[ { "role": "user", "content": input, }, { "role": "assistant", "content": "" } ], stop_sequences=[""] # Added the stop sequence here )

Выбор температуры

Параметр температуры контролирует «креативность» вывода модели. Он варьируется от 0.0 до 1.0: более высокие значения дают более разнообразные и непредсказуемые ответы, а более низкие — более сфокусированные и детерминированные. (Сбивает с толку, что API OpenAI позволяют устанавливать температуру вплоть до 2.0, но это не норма.)

Моё правило — начинать с температуры 0.8 и снижать по мере необходимости. Нам нужна максимальная температура, при которой результаты для конкретной задачи остаются хорошими.

Другая эвристика — использовать более низкие температуры (ближе к 0) для аналитических задач или задач с множественным выбором, и более высокие (ближе к 1) для творческих или открытых задач. Тем не менее я обнаружил, что слишком низкая температура снижает «интеллект» модели (поэтому я предпочитаю начинать с 0.8 и снижать только при необходимости). Также см. подтверждение Kyle Corbitt: это справедливо для gpt-4, но не для дообученной llama3-8b.

Что, похоже, не имеет значения

Есть несколько вещей, которые, по моему опыту и по отзывам коллег, не оказывают практического влияния на качество (по крайней мере, для современных моделей):

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

Конечно, нет ничего плохого в вежливости или шутливом тоне в промптах. Тем не менее полезно знать, что это не критично для получения хороших результатов.

• • •

По мере совершенствования LLM промпт-инжиниринг останется ценным навыком для извлечения максимума из языковых моделей (хотя, возможно, скоро мы перейдём к «обучению по словарю»). Какие ещё техники промптинга вы считаете полезными? Пишите в комментариях или свяжитесь со мной!

Если этот материал оказался полезен, пожалуйста, цитируйте его как:

Yan, Ziyou. (May 2024). Prompting Fundamentals and How to Apply them Effectively. eugeneyan.com. https://eugeneyan.com/writing/prompting/.

или

@article{yan2024prompting, title = {Prompting Fundamentals and How to Apply them Effectively}, author = {Yan, Ziyou}, journal = {eugeneyan.com}, year = {2024}, month = {May}, url = {https://eugeneyan.com/writing/prompting/} }



Присоединяйтесь к 11 800+ читателям, получающим обновления о машинном обучении, рекомендательных системах, LLM и инженерии.