Skip to content

Instantly share code, notes, and snippets.

@valmat
Created April 10, 2025 13:15
Show Gist options
  • Save valmat/83b05710be4598a087573c63500ff9a5 to your computer and use it in GitHub Desktop.
Save valmat/83b05710be4598a087573c63500ff9a5 to your computer and use it in GitHub Desktop.

Prompt Engineering

Автор: Lee Boonstra

Благодарности

Содержание предоставили:

  • Michael Sherman
  • Yuan Cao
  • Erick Armbrust
  • Anant Nawalgaria
  • Antonio Gulli
  • Simone Cammel

Кураторы и редакторы:

  • Antonio Gulli
  • Anant Nawalgaria
  • Grace Mollison

Технический писатель:

  • Joey Haymaker

Дизайнер:

  • Michael Lanning

Содержание

  1. Введение
  2. Инженерия подсказок
  3. Конфигурация вывода LLM
  4. One-shot и Few-shot
  5. Цепочка мыслей (CoT)
  6. Самосогласованность
  7. Дерево мыслей (ToT)
  8. ReAct (размышление и действие)
  9. Автоматический инжиниринг подсказок
  10. Запросы для кода
  11. Что насчет мультимодальных запросов?
  12. Лучшие практики
  13. Резюме
  14. Примечания

Введение

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

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

Когда вы общаетесь с чат-ботом Gemini, вы, по сути, пишете подсказки, однако этот документ сосредоточен на написании подсказок для модели Gemini в рамках Vertex AI или с использованием API, поскольку при прямом взаимодействии с моделью у вас будет доступ к конфигурации, такой как температура и т.д.

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

Инженерия подсказок

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

Когда вы пишете подсказку, вы пытаетесь настроить LLM для предсказания правильной последовательности токенов. Инженерия подсказок — это процесс разработки высококачественных подсказок, которые направляют LLM для создания точных выводов. Этот процесс включает в себя настройку для нахождения лучшей подсказки, оптимизацию длины подсказки и оценку стиля и структуры подсказки в зависимости от задачи. В контексте обработки естественного языка и LLM подсказка — это ввод, предоставленный модели для генерации ответа или предсказания.

Эти подсказки могут использоваться для достижения различных задач понимания и генерации, таких как суммирование текста, извлечение информации, вопросы и ответы, классификация текста, перевод языка или кода, генерация кода и документация или рассуждение.

Пожалуйста, не стесняйтесь обращаться к руководствам по подсказкам от Google с простыми и эффективными примерами подсказок.

При инженерии подсказок вы начнете с выбора модели. Подсказки могут потребовать оптимизации для вашей конкретной модели, независимо от того, используете ли вы языковые модели Gemini в Vertex AI, GPT, Claude или открытую модель, такую как Gemma или LLaMA.

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

Конфигурация вывода LLM

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

Длина вывода

Важной настройкой конфигурации является количество токенов, которые нужно сгенерировать в ответе. Генерация большего количества токенов требует больше вычислений от LLM, что приводит к большему потреблению энергии, потенциально более медленным временам отклика и более высоким затратам.

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

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

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

Контроль выборки

LLM не формально предсказывают один токен. Скорее, LLM предсказывают вероятности для того, каким может быть следующий токен, при этом каждый токен в словаре LLM получает вероятность. Эти вероятности токенов затем выбираются для определения того, каким будет следующий производимый токен. Температура, top-K и top-P — это наиболее распространенные настройки конфигурации, которые определяют, как обрабатываются предсказанные вероятности токенов для выбора одного выходного токена.

Температура

Температура контролирует степень случайности при выборе токенов. Более низкие температуры подходят для подсказок, которые ожидают более детерминированного ответа, в то время как более высокие температуры могут привести к более разнообразным или неожиданным результатам. Температура 0 (жадное декодирование) является детерминированной: всегда выбирается токен с наивысшей вероятностью (хотя обратите внимание, что если два токена имеют одинаковую наивысшую предсказанную вероятность, в зависимости от того, как реализована разбивка ничьей, вы можете не всегда получать одинаковый вывод при температуре 0).

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

Контроль температуры в Gemini можно понять аналогично функции softmax, используемой в машинном обучении. Низкая настройка температуры отражает низкую температуру softmax (T), подчеркивая одну предпочтительную температуру с высокой уверенностью. Более высокая настройка температуры Gemini подобна высокой температуре softmax, делая более широкий диапазон температур вокруг выбранной настройки более приемлемым. Это увеличенная неопределенность подходит для сценариев, где строгая, точная температура может быть не обязательной, например, при экспериментах с творческими выводами.

One-shot и Few-shot

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

One-shot подсказка предоставляет один пример, отсюда и название one-shot. Идея заключается в том, что у модели есть пример, который она может имитировать для наилучшего выполнения задачи.

Few-shot подсказка предоставляет модели несколько примеров. Этот подход показывает модели шаблон, которому она должна следовать. Идея аналогична one-shot, но несколько примеров желаемого шаблона увеличивают вероятность того, что модель будет следовать этому шаблону.

Количество примеров, необходимых для few-shot подсказок, зависит от нескольких факторов, включая сложность задачи, качество примеров и возможности используемой вами модели генеративного ИИ (gen AI). В качестве общего правила, следует использовать как минимум три-пять примеров для few-shot подсказок. Однако, возможно, потребуется использовать больше примеров для более сложных задач, или меньше из-за ограничения длины ввода вашей модели.

Пример few-shot подсказки

Цель Разобрать заказы на пиццу в формат JSON
Модель gemini-pro
Температура 0.1
Лимит токенов 250
Top-K N/A
Top-P 1

Подсказка: Разберите заказ клиента на пиццу в валидный JSON:

Пример:

Я хочу маленькую пиццу с сыром, томатным соусом и пепперони.
JSON Ответ:
{
  "size": "small",
  "type": "normal",
  "ingredients": [["cheese", "tomato sauce", "pepperoni"]]
}

Продолжение:

Пример:
Могу ли я получить большую пиццу с томатным соусом, базиликом и моцареллой?
JSON Ответ:
{
  "size": "large",
  "type": "normal",
  "ingredients": [["tomato sauce", "basil", "mozzarella"]]
}

Теперь я хотел бы большую пиццу, с первой половиной сыра и моцареллы. А другая половина с томатным соусом, ветчиной и ананасом.

JSON Ответ:

{
  "size": "large",
  "type": "half-half",
  "ingredients": [["cheese", "mozzarella"], ["tomato sauce", "ham", "pineapple"]]
}

Системные, контекстуальные и ролевые подсказки

Системные, контекстуальные и ролевые подсказки — это техники, используемые для управления тем, как LLM генерирует текст, но они фокусируются на разных аспектах:

  • Системные подсказки устанавливают общий контекст и цель для языковой модели. Они определяют «общую картину» того, что должна делать модель, например, переводить язык, классифицировать отзыв и т.д.
  • Контекстуальные подсказки предоставляют конкретные детали или фоновую информацию, относящуюся к текущему разговору или задаче. Они помогают модели понять нюансы того, что запрашивается, и адаптировать ответ соответственно.
  • Ролевые подсказки назначают языковой модели определенный характер или идентичность. Это помогает модели генерировать ответы, которые соответствуют назначенной роли и связанным с ней знаниям и поведению.

Каждый тип подсказки служит немного другой основной цели:

  • Системная подсказка: Определяет фундаментальные возможности модели и ее общую цель.
  • Контекстуальная подсказка: Предоставляет немедленную, специфичную для задачи информацию для управления ответом. Она высоко специфична для текущей задачи или ввода, который является динамичным.
  • Ролевая подсказка: Формирует стиль и голос вывода модели. Она добавляет уровень специфичности и индивидуальности.

Системные подсказки

Пример системной подсказки, где я указываю дополнительную информацию о том, как возвращать вывод. Я увеличил температуру, чтобы получить более высокий уровень креативности, и указал более высокий лимит токенов. Однако, благодаря моим четким инструкциям о том, как возвращать вывод, модель не вернула лишний текст.

Цель Классифицировать отзывы о фильмах как положительные, нейтральные или отрицательные.
Модель gemini-pro
Температура 1
Лимит токенов 5
Top-K 40
Top-P 0.

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

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

Вывод: NEGATIVE

Ролевые подсказки

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

Например, вы можете назначить модели gen AI роль книжного редактора, учителя детского сада или мотивационного спикера. После того, как модели назначена роль, вы можете дать ей подсказки, специфичные для этой роли. Например, вы можете попросить учителя создать план урока, который они затем могут просмотреть.

Пример, где модель принимает на себя роль гида по путешествиям:

Цель Действовать как гид и предоставить 3 предложения для путешествий
Модель gemini-pro
Температура 1
Лимит токенов 1024
Top-K 40
Top-P 0.8

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

Мое предложение: "Я в Амстердаме и хочу посетить только музеи."

Предложения для путешествий:

  1. Рейксмузей: Всемирно известный музей, известный голландскими шедеврами, такими как "Ночной дозор" Рембрандта. Не пропустите невероятную коллекцию картин и артефактов, демонстрирующих голландское искусство и историю.
  2. Музей Ван Гога: Погрузитесь в захватывающие работы Винсента ван Гога. Музей хранит крупнейшую коллекцию его картин и рисунков, включая "Звездную ночь" и "Подсолнухи".
  3. Стеделийк музей Амстердама: Откройте для себя современное и современное искусство со всего мира. Коллекция музея включает работы Пикассо, Кандинского и Ритвельда, размещенные в впечатляющем современном здании.

Контекстуальные подсказки

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

Пример:

Цель Предложить статьи для блога о ретро-играх
Модель gemini-pro
Температура 1
Лимит токенов 1024
Top-K 40
Top-P 0.8

Подсказка: Контекст: Вы пишете для блога о ретро-аркадных видеоиграх 80-х годов. Предложите 3 темы для написания статьи с несколькими строками описания, что эта статья должна содержать.

Вывод:

  1. Эволюция дизайна аркадных кабинетов: Эта статья исследует эволюцию дизайна аркадных кабинетов, от ранних деревянных и металлических кабинетов 1970-х годов до гладких, неоновых дизайнов 1980-х и далее.
  2. Взрыв из прошлого: Знаковые аркадные игры 80-х: Эта статья предлагает взгляд на историю, влияние и наследие некоторых из самых знаковых и влиятельных аркадных игр 1980-х годов, подчеркивая их инновации, популярные механики и неизменное очарование.
  3. Восход и ретро-возрождение пиксельного искусства: Эта статья исследует эволюцию пиксельного искусства как определяющего визуального стиля ранних аркадных игр, прослеживая его корни, исследуя его техники и обсуждая возрождение пиксельного искусства в современных играх и цифровом искусстве.

Step-back подсказки

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

Пример традиционной подсказки:

Цель Написать сюжетную линию для уровня шутера от первого лица
Модель gemini-pro
Температура 1
Лимит токенов 1024
Top-K 40
Top-P 0.8

Подсказка: Напишите один абзац сюжетной линии для нового уровня шутера от первого лица, который будет сложным и увлекательным.

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

Теперь давайте применим step-back подсказку:

Подсказка: На основе популярных шутеров от первого лица, какие 5 вымышленных ключевых настроек способствуют созданию сложной и увлекательной сюжетной линии уровня в шутере от первого лица?

Вывод:

  1. Заброшенная военная база: Обширный, постапокалиптический военный комплекс, кишащий мутированными солдатами и сбежавшими роботами, идеальный для сложных боев с огнестрельным оружием.
  2. Киберпанк-город: Неоново освещенная, футуристическая городская среда с возвышающимися небоскребами и густыми переулками, с кибернетически улучшенными врагами и механиками взлома.
  3. Космический корабль пришельцев: Огромный инопланетный корабль, застрявший на Земле, с жуткими коридорами, секциями с нулевой гравитацией и встречами с внеземными существами.
  4. Город, зараженный зомби: Заброшенный город, захваченный ордами агрессивных зомби, с интенсивными боями в ближнем бою и решением головоломок для поиска безопасного пути.
  5. Подводная исследовательская база: Глубоководная лаборатория, затопленная водой, наполненная мутировавшими морскими существами, требующая скрытности и навыков подводного исследования для выживания.

Теперь вернемся к оригинальной подсказке, но на этот раз включим ответ на step-back в качестве контекста и посмотрим, что получится.

Подсказка: Контекст: 5 увлекательных тем для шутера от первого лица:

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

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

Цепочка мыслей (CoT)

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

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

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

Чтобы объяснить следующий пример в Таблице 11, давайте сначала попробуем создать подсказку, которая не использует CoT, чтобы продемонстрировать недостатки большой языковой модели.

Подсказка: Когда мне было 3 года, моему партнеру было в 3 раза больше лет. Сейчас мне 20 лет. Сколько лет моему партнеру?
Вывод: 63 года
Таблица 11. Пример подсказки, которая пытается решить математическую задачу

Упс. Это явно неправильный ответ. На самом деле, LLM часто сталкиваются с трудностями при решении математических задач и могут давать неверные ответы — даже для такой простой задачи, как умножение двух чисел. Это связано с тем, что они обучены на больших объемах текста, а математика может требовать другого подхода. Давайте посмотрим, улучшат ли промежуточные шаги рассуждений вывод.

Подсказка: Когда мне было 3 года, моему партнеру было в 3 раза больше лет. Сейчас мне 20 лет. Сколько лет моему партнеру? Давайте подумаем шаг за шагом.
Вывод:

  1. Предположим, что мой текущий возраст "x" лет. Когда мне было 3 года, мой возраст был 3 года. Возраст моего партнера в то время был в 3 раза больше моего возраста, что означает, что возраст моего партнера был 3 * 3 = 9 лет. Сейчас мне 20 лет, что означает, что мой возраст увеличился на 20 - 3 = 17 лет с тех пор, как мне было 3 года. Поскольку возраст моего партнера был 9 лет, когда мне было 3 года, и мой возраст увеличился на 17 лет, возраст моего партнера также должен был увеличиться на 17 лет. Таким образом, текущий возраст моего партнера составляет 9 + 17 = 26 лет. Итак, моему партнеру 26 лет.
    Таблица 12. Пример подсказки с цепочкой мыслей

Теперь окончательный ответ правильный. Это потому, что мы четко указали LLM объяснить каждый шаг вместо того, чтобы просто вернуть ответ. Интересно видеть, что модель складывает 17 увеличенных лет. В моей голове я бы взял разницу в годах между моим партнером и мной и добавил бы их. (20+(9-3)). Давайте поможем модели думать немного больше, как я.

Таблица 12 — это пример 'без контекста' цепочки мыслей. Цепочка мыслей может быть очень мощной, когда она комбинируется с одноразовыми или многократными примерами, как вы можете видеть в Таблице 13:

Подсказка: Вопрос: Когда моему брату было 2 года, я был вдвое старше его. Сейчас мне 40 лет. Сколько лет моему брату? Давайте подумаем шаг за шагом.
Ответ: Когда моему брату было 2 года, мне было 2 * 2 = 4 года. Это разница в возрасте в 2 года, и я старше. Сейчас мне 40 лет, так что моему брату 40 - 2 = 38 лет. Ответ: 38.
Вопрос: Когда мне было 3 года, моему партнеру было в 3 раза больше лет. Сейчас мне 20 лет. Сколько лет моему партнеру? Давайте подумаем шаг за шагом.
Вывод: Когда мне было 3 года, моему партнеру было 3 * 3 = 9 лет. Это разница в возрасте в 6 лет, и мой партнер старше. Сейчас мне 20 лет, так что моему партнеру 20 + 6 = 26 лет. Ответ: 26.
Таблица 13. Пример цепочки мыслей с одноразовым примером

Цепочка мыслей может быть полезна для различных случаев использования. Подумайте о генерации кода, о разбиении запроса на несколько шагов и сопоставлении их с конкретными строками кода. Или для создания синтетических данных, когда у вас есть какой-то начальный элемент, например, "Продукт называется XYZ, напишите описание, направляя модель через предположения, которые вы бы сделали на основе данного названия продукта." В общем, любая задача, которую можно решить, "разговаривая", является хорошим кандидатом для цепочки мыслей. Если вы можете объяснить шаги для решения проблемы, попробуйте цепочку мыслей.

Пожалуйста, обратитесь к ноутбуку, размещенному в репозитории GoogleCloudPlatform на GitHub, который подробно объясняет CoT.

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

Самосогласованность

Хотя большие языковые модели показали впечатляющий успех в различных задачах NLP, их способность к рассуждению часто рассматривается как ограничение, которое нельзя преодолеть только за счет увеличения размера модели. Как мы узнали в предыдущем разделе о цепочке мыслей, модель можно настроить на генерацию шагов рассуждений, как человек, решающий проблему. Однако CoT использует простую стратегию "жадного декодирования", что ограничивает ее эффективность. Самосогласованность сочетает выборку и голосование большинства для генерации различных путей рассуждений и выбора наиболее согласованного ответа. Это улучшает точность и согласованность ответов, генерируемых LLM.

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

Она следует следующим шагам:

  1. Генерация различных путей рассуждений: LLM предоставляется с той же подсказкой несколько раз. Высокая настройка температуры побуждает модель генерировать разные пути рассуждений и перспективы на проблему.
  2. Извлечение ответа из каждого сгенерированного ответа.
  3. Выбор наиболее распространенного ответа.

Давайте рассмотрим пример системы классификации электронной почты, которая классифицирует электронное письмо как ВАЖНОЕ или НЕ ВАЖНОЕ. Подсказка цепочки мыслей без контекста будет отправлена LLM несколько раз, чтобы увидеть, отличаются ли ответы после каждого отправления. Обратите внимание на дружелюбный тон, выбор слов и сарказм, использованные в письме. Все это может обмануть LLM.

Подсказка: EMAIL:

Привет,
Я заметил, что вы используете WordPress для вашего сайта. Отличная система управления контентом с открытым исходным кодом. Я тоже использовал ее в прошлом. Она поставляется с множеством отличных пользовательских плагинов. И ее довольно легко настроить.
Я заметил ошибку в контактной форме, которая происходит, когда вы выбираете поле имени. См. прикрепленный скриншот, на котором я ввожу текст в поле имени. Обратите внимание на JavaScript-алерт, который я вызвал.
Но в остальном это отличный сайт. Мне нравится его читать. Не стесняйтесь оставлять ошибку на сайте, потому что это дает мне больше интересных вещей для чтения.
С уважением,
Гарри Хакер.
Классифицируйте вышеуказанное письмо как ВАЖНОЕ или НЕ ВАЖНОЕ. Давайте подумаем шаг за шагом и объясним почему.

Вывод:
Попытка 1

Шаг 1: Определите цель письма.
Цель письма — сообщить получателю об ошибке в контактной форме на их сайте. Отправитель также упоминает, что ему нравится читать сайт и что он оставляет ошибку на месте на данный момент.
Шаг 2: Оцените потенциальное влияние ошибки.
Ошибка в контактной форме может позволить злоумышленнику выполнять произвольный JavaScript-код на сайте. Это может привести к тому, что злоумышленник сможет захватить контроль над сайтом, украсть конфиденциальную информацию или испортить сайт.
Шаг 3: Учитывайте надежность отправителя.
Отправитель письма утверждает, что он хакер по имени Гарри. Однако нет возможности проверить личность отправителя. Возможно, отправитель является легитимным хакером, который пытается помочь получателю, но также возможно, что отправитель является злонамеренным лицом, пытающимся обмануть получателя, чтобы тот кликнул на злонамеренную ссылку или загрузил злонамеренный файл.
Заключение: ВАЖНОЕ
На основе потенциального влияния ошибки и надежности отправителя письмо следует классифицировать как ВАЖНОЕ. Получатель должен немедленно предпринять действия для исправления ошибки и защиты своего сайта от атаки.

Вывод:
Попытка 2

Объяснение:
Отсутствие срочности: Письмо не передает никакого чувства срочности или временной чувствительности. Оно начинается с неформального приветствия и представляет информацию в фактическом тоне.
Некритический отчет об ошибке: Ошибка, о которой сообщается в контактной форме, описывается как интересная, но не критическая. Отправитель письма даже предлагает владельцу сайта оставить ошибку на месте.
Отсутствие личного воздействия: Письмо не указывает на какое-либо прямое или личное воздействие на владельца сайта. Оно просто упоминает, что отправителю нравится читать сайт.
Отсутствие запроса на действие: Письмо не содержит явного запроса на действие от владельца сайта. Оно не просит исправить ошибку или предоставить какие-либо конкретные предложения по улучшению.
Намерение отправителя: Намерение отправителя, похоже, больше сосредоточено на том, чтобы поделиться наблюдением и выразить интерес к сайту, а не поднять серьезную проблему или запросить помощь.
Заключение: НЕ ВАЖНОЕ

Вывод:
Попытка 3

Шаг 1: Определите цель письма.
Цель письма — сообщить получателю об ошибке в контактной форме на их сайте. Отправитель также упоминает, что ему нравится читать сайт и что он оставляет ошибку на месте на данный момент.
Шаг 2: Оцените потенциальное влияние ошибки.
Ошибка в контактной форме может позволить злоумышленнику выполнять произвольный JavaScript-код на сайте. Это может привести к тому, что злоумышленник сможет захватить контроль над сайтом, украсть конфиденциальную информацию или испортить сайт.
Шаг 3: Учитывайте надежность отправителя.
Отправитель письма утверждает, что он хакер по имени Гарри. Однако нет возможности проверить личность отправителя. Возможно, отправитель является легитимным хакером, который пытается помочь получателю, но также возможно, что отправитель является злонамеренным лицом, пытающимся использовать ошибку в своих целях.
Заключение:
На основе вышеуказанных факторов письмо следует классифицировать как ВАЖНОЕ. Ошибка в контактной форме представляет собой серьезный риск для безопасности, и надежность отправителя неизвестна. Получатель должен немедленно предпринять действия для исправления ошибки и расследовать утверждения отправителя.

Таблица 14. Пример подсказки для самосогласованности

Вы можете использовать приведенную выше подсказку и попробовать посмотреть, возвращает ли она согласованную классификацию. В зависимости от модели, которую вы используете, и конфигурации температуры, она может вернуть "ВАЖНОЕ" или "НЕ ВАЖНОЕ".

Генерируя множество цепочек мыслей и выбирая наиболее часто встречающийся ответ ("ВАЖНОЕ"), мы можем получить более последовательно правильный ответ от LLM.

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

Дерево мыслей (ToT)

Теперь, когда мы знакомы с цепочкой мыслей и самосогласованностью, давайте рассмотрим Дерево мыслей (ToT). Оно обобщает концепцию CoT, потому что позволяет LLM исследовать несколько различных путей рассуждений одновременно, а не просто следовать одной линейной цепочке мыслей. Это изображено на Рисунке 1.

Рисунок 1. Визуализация цепочки мыслей слева против. Дерева мыслей справа

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

Существует отличный ноутбук, который более подробно показывает Дерево мыслей (ToT), основанный на статье 'Large Language Model Guided Tree-of-Thought'.

ReAct (размышление и действие)

Размышление и действие (ReAct) — это парадигма, позволяющая LLM решать сложные задачи, используя рассуждения на естественном языке в сочетании с внешними инструментами (поиск, интерпретатор кода и т. д.), позволяя LLM выполнять определенные действия, такие как взаимодействие с внешними API для получения информации, что является первым шагом к моделированию агентов.

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

Подсказка ReAct работает, объединяя размышления и действия в цикл мыслей-действий. LLM сначала размышляет о проблеме и генерирует план действий. Затем он выполняет действия в плане и наблюдает результаты. LLM затем использует наблюдения для обновления своих рассуждений и генерации нового плана действий. Этот процесс продолжается до тех пор, пока LLM не найдет решение проблемы.

Чтобы увидеть это в действии, вам нужно написать код. В коде Snippet 1 я использую фреймворк langchain для Python вместе с VertexAI (google-cloud-aiplatform) и пакетом google-search-results pip.

Чтобы запустить этот пример, вы должны создать (бесплатный) ключ SerpAPI с https://serpapi.com/manage-api-key и установить переменную окружения SERPAPI_API_KEY.

Далее давайте напишем немного кода на Python, с задачей для LLM выяснить: Сколько детей у знаменитого отца, который выступает в группе Metallica.

from langchain.agents import load_tools
from langchain.agents import initialize_agent
from langchain.agents import AgentType
from langchain.llms import VertexAI

prompt = "How many kids do the band members of Metallica have?"
llm = VertexAI(temperature=0.1)
tools = load_tools(["serpapi"], llm=llm)
agent = initialize_agent(tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)
agent.run(prompt)

Snippet 1. Создание агента ReAct с LangChain и VertexAI

Код Snippet 2 показывает результат. Обратите внимание, что ReAct выполняет цепочку из пяти поисков. Фактически, LLM сканирует результаты поиска Google, чтобы выяснить имена участников группы. Затем он перечисляет результаты как наблюдения и связывает мысль для следующего поиска.

> Entering new AgentExecutor chain...
Metallica has 4 members.
Action: Search
Action Input: How many kids does James Hetfield have?
Observation: three children
Thought: 1/4 Metallica band members have 3 children
Action: Search
Action Input: How many kids does Lars Ulrich have?
Observation: 3
Thought: 2/4 Metallica band members have 6 children
Action: Search
Action Input: How many kids does Kirk Hammett have?
Observation: Hammett has been married to his second wife Lani since 1998. They have two sons, Angel (b. September 29, 2006) and Vincenzo (b. June 28, 2008).
Thought: 3/4 Metallica band members have 8 children
Action: Search
Action Input: How many kids does Robert Trujillo have?
Observation: 2
Thought: 4/4 Metallica band members have 10 children
Final Answer: 10

Snippet 2. Выполнение агента ReAct в терминале

Код Snippet 2 выясняет, что в группе Metallica четыре участника. Затем он ищет каждого участника группы, чтобы запросить общее количество детей и сложить итог. Наконец, он возвращает общее количество детей как окончательный ответ.

Практическое использование подсказки ReAct требует понимания того, что вам нужно постоянно пересылать предыдущие подсказки/ответы (и обрезать лишний сгенерированный контент), а также настраивать модель с соответствующими примерами/инструкциями. Пожалуйста, обратитесь к ноутбуку, размещенному в репозитории GoogleCloudPlatform на GitHub, который более подробно показывает фактические входные и выходные данные LLM с более сложным примером.

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

На этом этапе вы могли заметить, что написание подсказки может быть сложным. Не было бы здорово автоматизировать это (написать подсказку для написания подсказок)? Ну, есть метод: Автоматический инжиниринг подсказок (APE). Этот метод не только облегчает необходимость в человеческом вводе, но и улучшает производительность модели в различных задачах.

Вы будете подсказывать модели генерировать больше подсказок. Оценивать их, возможно, изменять хорошие. И повторять.

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

Напишите подсказку, которая будет генерировать варианты вывода. В этом примере я использую gemini-pro для генерации 10 инструкций. См. Таблицу 15:

Подсказка: У нас есть интернет-магазин футболок с мерчем группы, и для обучения чат-бота нам нужны различные способы заказа: "Одна футболка Metallica размера S". Сгенерируйте 10 вариантов с теми же семантиками, но сохраните то же значение.
Вывод:

  1. Я бы хотел купить футболку Metallica размера small.
  2. Могу ли я заказать футболку Metallica размера small?
  3. Я бы хотел купить одну футболку Metallica размера small.
  4. Одна футболка Metallica, размер small, пожалуйста.
  5. Я хочу одну футболку Metallica размера small.
  6. Я бы хотел сделать заказ на одну футболку Metallica размера small.
  7. Маленькая футболка Metallica, одну, пожалуйста.
  8. Я ищу одну футболку Metallica размера small.
  9. Можете ли вы принести мне одну футболку Metallica размера small?
  10. Одна маленькая футболка Metallica, пожалуйста.

Таблица 15. Использование LLM для генерации подсказок

Оцените всех кандидатов на инструкцию, оценивая кандидатов на основе выбранной метрики. Например, вы можете использовать BLEU (Bilingual Evaluation Understudy) или ROUGE (Recall-Oriented Understudy for Gisting Evaluation). Выберите кандидата на инструкцию с наивысшей оценкой. Этот кандидат станет окончательной подсказкой, которую вы можете использовать в своем программном приложении или чат-боте. Вы также можете изменить выбранную подсказку и оценить снова.

Запросы для кода

Gemini в основном сосредоточен на текстовых запросах, включая запросы для написания кода. Давайте перейдем в Vertex AI Studio и протестируем эти запросы, чтобы рассмотреть некоторые примеры кода.

Запросы для написания кода

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

Представьте себе папку на вашем компьютере с сотнями файлов, которые нужно переименовать. Переименование каждого файла займет много времени. Вы немного знакомы с Bash и могли бы написать скрипт для автоматизации этого процесса, но это тоже может занять некоторое время. Давайте напишем запрос. Вы можете написать запрос в общедоступном чат-боте Gemini, или, если вы более обеспокоены конфиденциальностью, вы можете написать эти запросы в своей учетной записи Google Cloud и открыть Vertex AI Studio. Преимущество Vertex AI Studio заключается в том, что вы можете настроить температуру и другие параметры.

Название: 1_bash_rename_files_in_folder
Цель: Написать запрос для написания кода на Bash для переименования файлов в папке.
Модель: gemini-pro
Температура: 0.1
Лимит токенов: 1024
Top-K: N/A
Top-P: 1

Запрос: Напишите фрагмент кода на Bash, который запрашивает имя папки. Затем он берет содержимое папки и переименовывает все файлы внутри, добавляя имя "draft" к имени файла.

Вывод:

#!/bin/bash
# Запрос имени папки
echo "Введите имя папки: "
read folder_name
# Проверка существования папки
if [ ! -d "$folder_name" ]; then
  echo "Папка не существует."
  exit 1
fi
# Получение списка файлов в папке
files=( "$folder_name"/* )
# Переименование каждого файла, добавляя "draft" к имени файла
for file in "${files[@]}"; do
  new_file_name="draft_$(basename "$file")"
  mv "$file" "$new_file_name"
done
echo "Файлы успешно переименованы."

Таблица 16. Использование Gemini для программирования кода

Это кажется хорошим кодом — он даже задокументирован! Однако, поскольку LLM не могут рассуждать и повторять обучающие данные, важно сначала прочитать и протестировать ваш код.

Момент, которого мы все ждали, действительно ли это работает?

Давайте сначала попробуем его с тестовой папкой, в которой всего несколько файлов, которые нужно переименовать из filename.txt в draft_filename.txt.

  1. Скопируйте вывод из Таблицы 16 (без обертки текста bash), и вставьте его в новый файл с именем: rename_files.sh.
  2. Откройте окно терминала и введите: ./rename_files.sh. Он попросит ввести имя папки, например, test, и нажмите Enter.
  3. Скрипт, кажется, работает нормально. Вы увидите сообщение: "Файлы успешно переименованы." Когда вы заглянете в тестовую папку, обратите внимание, что все файлы были идеально переименованы в draft_filename.txt.

Это сработало!

Запросы для объяснения кода

Как разработчик, когда вы работаете в команде, вам приходится читать код других людей. Gemini может помочь вам и в этом. Давайте возьмем код из Таблицы 16, удалим комментарии и попросим модель объяснить, что происходит. Смотрите Таблицу 17:

Название: 1_bash_explain_the_code
Цель: Написать запрос для объяснения кода на Bash
Модель: gemini-pro
Температура: 0.1
Лимит токенов: 1024
Top-K: N/A
Top-P: 1

Запрос: Объясните мне следующий код на Bash:

#!/bin/bash
echo "Введите имя папки: "
read folder_name
if [ ! -d "$folder_name" ]; then
  echo "Папка не существует."
  exit 1
fi
files=( "$folder_name"/* )
for file in "${files[@]}"; do
  new_file_name="draft_$(basename "$file")"
  mv "$file" "$new_file_name"
done
echo "Файлы успешно переименованы."

Вывод: Этот скрипт на Bash выполняет следующие задачи:

  1. Ввод пользователя:
    • Он запрашивает у пользователя ввод имени папки с помощью команд echo и read. Введенное имя папки сохраняется в переменной folder_name.
  2. Проверка существования папки:
    • Он проверяет, существует ли папка с указанным именем, используя условие [ ! -d "$folder_name" ]. Если папка не существует, он отображает сообщение об ошибке ("Папка не существует.") и завершает скрипт с кодом выхода 1.
  3. Список файлов:
    • Он перечисляет все файлы внутри указанной папки с помощью команды files=( "$folder_name"/* ). Это создает массив files, содержащий пути ко всем файлам в папке.
  4. Переименование файлов:
    • Он перебирает каждый файл в массиве files с помощью цикла for.
    • Для каждого файла он генерирует новое имя файла с помощью команды new_file_name="draft_$(basename "$file")". Это новое имя файла создается путем добавления строки "draft_" к оригинальному имени файла.
    • Затем он переименовывает файл с помощью команды mv "$file" "$new_file_name", которая перемещает файл к новому имени.
  5. Сообщение об успешном выполнении:
    • После переименования всех файлов он отображает сообщение об успешном выполнении ("Файлы успешно переименованы.") для указания, что операция переименования прошла успешно.

Таблица 17. Запрос для объяснения кода

Запросы для перевода кода

Код на Bash из Таблицы 16, кажется, работает нормально. Однако этот скрипт действительно может быть более универсальным, если он будет запрашивать имена файлов, желательно, чтобы он работал как отдельное приложение с пользовательским интерфейсом. В качестве отправной точки Python был бы лучшим языком для (веб) приложения, чем Bash. LLM могут помочь с переводом кода с одного языка на другой. Смотрите пример в Таблице 18:

Название: 1_python_rename_files
Цель: Написать запрос для перевода кода с Bash на Python
Модель: gemini-pro
Температура: 0.1
Лимит токенов: 1024
Top-K: N/A
Top-P: 1

Запрос: Переведите следующий код на Bash в фрагмент кода на Python.

#!/bin/bash
echo "Введите имя папки: "
read folder_name
if [ ! -d "$folder_name" ]; then
  echo "Папка не существует."
  exit 1
fi
files=( "$folder_name"/* )
for file in "${files[@]}"; do
  new_file_name="draft_$(basename "$file")"
  mv "$file" "$new_file_name"
done
echo "Файлы успешно переименованы."

Вывод:

import os
import shutil

# Получение имени папки от пользователя
folder_name = input("Введите имя папки: ")

# Проверка существования папки
if not os.path.isdir(folder_name):
    print("Папка не существует.")
    exit(1)

# Получение списка всех файлов в папке
files = os.listdir(folder_name)

# Перебор файлов
for file in files:
    # Создание нового имени файла с префиксом "draft_"
    new_file_name = f"draft_{file}"
    # Перемещение файла к новому имени
    shutil.move(os.path.join(folder_name, file), os.path.join(folder_name, new_file_name))

# Печать сообщения об успешном выполнении
print("Файлы успешно переименованы.")

Таблица 18. Запрос для перевода кода с Bash на Python

Прочитайте и проверьте код. Скопируйте вывод из запроса и вставьте его в новый файл: file_renamer.py. Проверьте код, открыв окно терминала и выполнив следующую команду: python file_renamer.py.

ПРИМЕЧАНИЕ: При запросе кода (Python) в Language Studio в Vertex AI, вам нужно будет нажать кнопку 'Markdown'. В противном случае вы получите обычный текст, в котором отсутствует правильная индентация строк, что важно для выполнения кода на Python.

Запросы для отладки и рецензирования кода

Давайте вручную внесем некоторые изменения в код из Таблицы 18. Он должен запрашивать у пользователя префикс имени файла и записывать этот префикс заглавными буквами. Смотрите пример кода в Сниппете 3, но какая неудача. Теперь он возвращает ошибки Python!

import os
import shutil

folder_name = input("Введите имя папки: ")
prefix = input("Введите строку для добавления к имени файла: ")
text = toUpperCase(prefix)

if not os.path.isdir(folder_name):
    print("Папка не существует.")
    exit(1)

files = os.listdir(folder_name)

for file in files:
    new_filename = f"{text}_{file}"
    shutil.move(os.path.join(folder_name, file), os.path.join(folder_name, new_file_name))

print("Файлы успешно переименованы.")

Сниппет 3. Сломанный скрипт на Python

Ой! Это похоже на ошибку:

Ниже приведенный код на Python выдает ошибку:

Traceback (most recent call last):
  File "/Users/leeboonstra/Documents/test_folder/rename_files.py", line 7, in <module>
    text = toUpperCase(prefix)
NameError: name 'toUpperCase' is not defined

Сниппет 4. Я сломал код на Python

Давайте посмотрим, можем ли мы попросить большую языковую модель отладить и рецензировать код. Посмотрите Таблицу 19:

Название: 1_python_debug_code
Цель: Написать запрос для отладки и рецензирования кода на Python.
Модель: gemini-pro
Температура: 0.1
Лимит токенов: 1024
Top-K: N/A
Top-P: 1

Запрос: Ниже приведенный код на Python выдает ошибку:

Traceback (most recent call last):
  File "/Users/leeboonstra/Documents/test_folder/rename_files.py", line 7, in <module>
    text = toUpperCase(prefix)
NameError: name 'toUpperCase' is not defined

Отладьте, что не так, и объясните, как я могу улучшить код.

import os
import shutil

# Получение имени папки от пользователя
folder_name = input("Введите имя папки: ")
prefix = input("Введите строку для добавления к имени файла: ")
text = toUpperCase(prefix)

# Проверка существования папки
if not os.path.isdir(folder_name):
    print("Папка не существует.")
    exit(1)

# Получение списка всех файлов в папке
files = os.listdir(folder_name)

# Перебор файлов
for file in files:
    new_filename = f"{text}_{file}"
    shutil.move(os.path.join(folder_name, file), os.path.join(folder_name, new_file_name))

print("Файлы успешно переименованы.")

Вывод: Код вызывает функцию toUpperCase для преобразования prefix в верхний регистр, но эта функция не определена. Чтобы исправить эту проблему, вы можете использовать метод upper() класса строк, который преобразует данную строку в верхний регистр. Измененный код показан ниже:

import os
import shutil

# Получение имени папки от пользователя
folder_name = input("Введите имя папки: ")
prefix = input("Введите строку для добавления к имени файла: ")
text = prefix.upper()

# Проверка существования папки
if not os.path.isdir(folder_name):
    print("Папка не существует.")
    exit(1)

# Получение списка всех файлов в папке
files = os.listdir(folder_name)

# Перебор файлов
for file in files:
    new_filename = f"{text}_{file}"
    shutil.move(os.path.join(folder_name, file), os.path.join(folder_name, new_filename))

print("Файлы успешно переименованы.")

Кроме того, есть несколько других улучшений, которые можно внести в код:

  • Расширение файла новых имен файлов не сохраняется. Лучше извлечь расширение из оригинального имени файла и добавить его к новому имени файла.
  • Код предполагает, что в имени папки нет пробелов. Однако, лучше обрабатывать пробелы, заменяя их на подчеркивания или дефисы.
  • Использование синтаксиса f-строк для интерполяции строк более читаемо и лаконично, чем традиционный оператор +.
  • Код не обрабатывает ошибки, которые могут возникнуть в процессе переименования. Лучше обернуть вызов shutil.move в блок try...except, чтобы поймать любые потенциальные ошибки.

Вот улучшенный код с этими предложениями:

import os
import shutil

# Получение имени папки от пользователя
folder_name = input("Введите имя папки: ")
prefix = input("Введите строку для добавления к имени файла: ")

# Проверка существования папки
if not os.path.isdir(folder_name):
    print("Папка не существует.")
    exit(1)

# Получение списка всех файлов в папке
files = os.listdir(folder_name)

# Перебор файлов
for file in files:
    # Получение расширения файла
    ext = os.path.splitext(file)[1]

    # Создание нового имени файла с префиксом и расширением файла
    new_filename = f"{prefix}_{os.path.splitext(file)[0]}{ext}"

    # Построение полных путей для оригинальных и новых файлов
    old_path = os.path.join(folder_name, file)
    new_path = os.path.join(folder_name, new_filename)

    # Попытка переместить файл
    try:
        shutil.move(old_path, new_path)
    except Exception as e:
        print(f"Произошла ошибка при перемещении файла {file}: {e}")

# Печать сообщения об успешном выполнении
print("Файлы успешно переименованы.")

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

Таблица 19. Запрос для отладки и рецензирования кода на Python

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

Что насчет мультимодальных запросов?

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

Лучшие практики

Найти правильный запрос требует экспериментов. Language Studio в Vertex AI — идеальное место для экспериментов с вашими запросами, с возможностью тестирования на различных моделях.

Используйте следующие лучшие практики, чтобы стать профессионалом в инженерии запросов.

Предоставляйте примеры

Самая важная практика — предоставление (one-shot / few-shot) примеров в запросе. Это очень эффективно, поскольку действует как мощный инструмент обучения. Эти примеры демонстрируют желаемые выводы или аналогичные ответы, позволяя модели учиться на них и адаптировать свое собственное поколение соответственно. Это похоже на предоставление модели точки отсчета или цели, что улучшает точность, стиль и тон её ответа, чтобы лучше соответствовать вашим ожиданиям.

Дизайн с простотой

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

Примеры:

До:

Я сейчас в Нью-Йорке, и хотел бы узнать больше о замечательных местах. Я с двумя детьми 3 лет. Куда нам пойти во время отпуска?

После переписывания:

Выступите в роли туристического гида. Опишите замечательные места для посещения в Нью-Йорке Манхэттене с трехлетним ребенком.

Попробуйте использовать глаголы, описывающие действие. Вот набор примеров:

  • Act, Analyze, Categorize, Classify, Contrast, Compare, Create, Describe, Define, Evaluate, Extract, Find, Generate, Identify, List, Measure, Organize, Parse, Pick, Predict, Provide, Rank, Recommend, Return, Retrieve, Rewrite, Select, Show, Sort, Summarize, Translate, Write.

Будьте конкретны в отношении вывода

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

Примеры:

Делайте:

Создайте 3 абзаца блога о топ-5 игровых консолях. Блог должен быть информативным и увлекательным, написанным в разговорном стиле.

Не делайте:

Создайте блог о игровых консолях.

Используйте инструкции вместо ограничений

Инструкции и ограничения используются в запросах для управления выводом LLM.

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

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

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

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

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

Делайте:

Создайте 1 абзац блога о топ-5 игровых консолях. Обсудите только консоль, компанию, которая её сделала, год и общие продажи.

Не делайте:

Создайте 1 абзац блога о топ-5 игровых консолях. Не перечисляйте названия видеоигр.

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

Контролируйте максимальную длину токенов

Чтобы контролировать длину сгенерированного ответа LLM, вы можете либо установить максимальный лимит токенов в конфигурации, либо явно запросить определенную длину в вашем запросе. Например:

"Объясните квантовую физику в сообщении длиной твита."

Используйте переменные в запросах

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

Запрос с переменными:

{city} = "Амстердам"

Запрос:

Вы туристический гид. Расскажите мне факт о городе: {city}

Вывод:

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

Таблица 20. Использование переменных в запросах.

Экспериментируйте с форматами ввода и стилями письма

Различные модели, конфигурации моделей, форматы подсказок, выбор слов и отправки могут давать разные результаты. Поэтому важно экспериментировать с атрибутами подсказок, такими как стиль, выбор слов и тип подсказки (zero shot, few shot, системная подсказка).

Например, подсказка с целью сгенерировать текст о революционной игровой консоли Sega Dreamcast может быть сформулирована как вопрос, утверждение или инструкция, что приведет к различным выводам:

  • Вопрос: What was the Sega Dreamcast and why was it such a revolutionary console?
  • Утверждение: The Sega Dreamcast was a sixth-generation video game console released by Sega in 1999. It...
  • Инструкция: Write a single paragraph that describes the Sega Dreamcast console and explains why it was so revolutionary.

Для few-shot подсказок с задачами классификации перемешивайте классы

Как правило, порядок ваших примеров few-shot не должен сильно влиять на результат. Однако при выполнении задач классификации убедитесь, что вы перемешиваете возможные классы ответов в примерах few-shot. Это связано с тем, что в противном случае вы можете переобучиться на конкретный порядок примеров. Перемешивая возможные классы ответов, вы можете гарантировать, что модель учится идентифицировать ключевые особенности каждого класса, а не просто запоминать порядок примеров. Это приведет к более надежной и обобщаемой производительности на невидимых данных.

Хорошее правило: начните с 6 примеров few-shot и начните тестировать точность с этого момента.

Адаптация к обновлениям модели

Важно быть в курсе изменений архитектуры модели, добавленных данных и возможностей. Пробуйте новые версии моделей и корректируйте свои подсказки, чтобы лучше использовать новые функции модели. Инструменты, такие как Vertex AI Studio, отлично подходят для хранения, тестирования и документирования различных версий ваших подсказок.

Экспериментируйте с форматами вывода

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

Есть несколько преимуществ в возвращении JSON-объектов из подсказки, которая извлекает данные. В реальном приложении мне не нужно вручную создавать этот JSON-формат, я уже могу вернуть данные в отсортированном порядке (очень удобно при работе с объектами datetime), но, что более важно, запрашивая формат JSON, это заставляет модель создать структуру и ограничить галлюцинации.

Вкратце, преимущества использования JSON для вашего вывода:

  • Всегда возвращается в одном стиле
  • Фокусируется на данных, которые вы хотите получить
  • Меньше шансов на галлюцинации
  • Осознает отношения
  • Получаете типы данных
  • Можно сортировать

Таблица 4 в разделе few-shot подсказок показывает пример того, как вернуть структурированный вывод.

Ремонт JSON

Хотя возврат данных в формате JSON предлагает множество преимуществ, он не лишен недостатков. Структурированная природа JSON, хотя и полезна для разбора и использования в приложениях, требует значительно больше токенов, чем простой текст, что приводит к увеличению времени обработки и более высоким затратам. Более того, многословность JSON может легко потреблять все окно вывода, что становится особенно проблематичным, когда генерация внезапно обрывается из-за ограничений токенов. Это усечение часто приводит к недействительному JSON, отсутствию важных закрывающих скобок или фигурных скобок, что делает вывод непригодным для использования. К счастью, такие инструменты, как библиотека json-repair (доступна на PyPI), могут быть бесценны в этих ситуациях. Эта библиотека интеллектуально пытается автоматически исправить неполные или поврежденные JSON-объекты, делая её важным союзником при работе с JSON, сгенерированным LLM, особенно при решении потенциальных проблем с усечением.

Работа с схемами

Использование структурированного JSON в качестве вывода — отличное решение, как мы видели несколько раз в этом документе. Но как насчет ввода? Хотя JSON отлично подходит для структурирования вывода, который генерирует LLM, он также может быть невероятно полезен для структурирования ввода, который вы предоставляете. Здесь на помощь приходят схемы JSON. Схема JSON определяет ожидаемую структуру и типы данных вашего JSON-ввода. Предоставляя схему, вы даете LLM четкий план данных, которые он должен ожидать, помогая ему сосредоточить внимание на соответствующей информации и снижая риск неправильного толкования ввода. Более того, схемы могут помочь установить отношения между различными частями данных и даже сделать LLM "временнó осведомленным", включая поля даты или временной метки с конкретными форматами.

Простой пример:

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

{
  "type": "object",
  "properties": {
    "name": { "type": "string", "description": "Product name" },
    "category": { "type": "string", "description": "Product category" },
    "price": { "type": "number", "format": "float", "description": "Product price" },
    "features": {
      "type": "array",
      "items": { "type": "string" },
      "description": "Key features of the product"
    },
    "release_date": { "type": "string", "format": "date", "description": "Date the product was released" }
  }
}

Затем вы можете предоставить фактические данные о продукте в виде JSON-объекта, который соответствует этой схеме:

{
  "name": "Wireless Headphones",
  "category": "Electronics",
  "price": 99.99,
  "features": ["Noise cancellation", "Bluetooth 5.0", "20-hour battery life"],
  "release_date": "2023-10-27"
}

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

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

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

Лучшие практики CoT

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

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

Для CoT-подсказок установите температуру на 0.

Цепочка размышлений основана на жадной декодировке, предсказывая следующее слово в последовательности на основе самой высокой вероятности, назначенной языковой моделью. Как правило, при использовании рассуждений для получения окончательного ответа, вероятно, есть один единственный правильный ответ. Поэтому температура всегда должна быть установлена на 0.

Документируйте различные попытки создания подсказок

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

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

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

Помимо полей в этой таблице, также полезно отслеживать версию подсказки (итерацию), поле для фиксации, если результат был OK/NOT OK/SOMETIMES OK, и поле для фиксации обратной связи. Если вам повезло использовать Vertex AI Studio, сохраняйте ваши подсказки (используя то же имя и версию, что указаны в вашей документации) и отслеживайте гиперссылку на сохраненную подсказку в таблице. Таким образом, вы всегда в одном клике от повторного запуска ваших подсказок.

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

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

Инженерия подсказок — это итеративный процесс. Создавайте и тестируйте различные подсказки, анализируйте и документируйте результаты. Улучшайте вашу подсказку на основе производительности модели. Продолжайте экспериментировать, пока не достигнете желаемого вывода. Когда вы меняете модель или конфигурацию модели, возвращайтесь и продолжайте экспериментировать с ранее использованными подсказками.

Name [name and version of your prompt]
Goal [One sentence explanation of the goal of this attempt]
Model [name and version of the used model]
Temperature [value between 0 - 1]
Token Limit [number]
Top - K [number]
Top - P [number]
Prompt [Write all the full prompt]
Output [Write out the output or multiple outputs]

Таблица 21. Шаблон для документирования подсказок

Резюме

Этот документ обсуждает инженерию подсказок. Мы изучили различные техники создания подсказок, такие как:

  • Zero prompting
  • Few shot prompting
  • System prompting
  • Role prompting
  • Contextual prompting
  • Step-back prompting
  • Chain of thought
  • Self consistency
  • Tree of thoughts
  • ReAct

Мы даже рассмотрели способы автоматизации ваших подсказок.

Документ затем обсуждает проблемы генеративного ИИ, такие как проблемы, которые могут возникнуть, когда ваши подсказки недостаточны. Мы завершили лучшими практиками, как стать лучшим инженером подсказок.

Примечания

Это офлайн-инструмент, ваши данные остаются локально и не отправляются на сервер!

Обратная связь и отчёты об ошибках.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment