Книжная полка: Промт‑инжиниринг для LLM
Скажу честно, чтение этой книги далось мне нелегко, и отношение к ней у меня неоднозначное. Но я рад, что решил её прочитать, и считаю, что это было не напрасно потраченное время, хотя и смог осилить её только за три подхода.
Общие впечатления
Читая книгу, меня не покидала мысль, что мы живём в момент технологической революции, когда привычные действия перескакивают на принципиально другой уровень — и это происходит прямо на наших глазах. Для большинства всего этого ещё не существовало каких-то пять лет назад, а в 2024 году, когда, как я понимаю, по большей части и была написана эта книга, случился настоящий прорыв. Теперь же всё это семимильными шагами становится обыденностью.
И основная ценность этой книги в том, что она позволяет читателю приоткрыть завесу тайны и осознать, что LLM, GPT, чат-боты и ИИ-агенты — это никакое не волшебство, а результат больших вычислений, которые предсказывают вероятность появления следующего слова.
Книга хорошо структурирована: она логично разбита на три части — от основ к техникам, а затем к навыкам для экспертов. Каждый раздел развивает предыдущие, давая всестороннюю картину создания приложений на основе ИИ. При этом книга довольно тяжела для чтения, особенно для неподготовленного читателя. Но, как я понимаю, авторы это осознавали и поэтому каждую главу завершали резюме, чтобы читатель мог освежить и систематизировать полученную информацию.
И вас не должно вводить в заблуждение упоминание слова "промт" в названии. Эта книга не про то, как писать пользовательские промты для решения прикладных задач, а про то, как наш пользовательский запрос превращается в запрос к языковой модели — той самой LLM, — как она его обрабатывает и даёт ответ. И это понимание позволяет не только заглянуть под капот этой "машины" и осознать её возможности и ограничения, но и по-другому взглянуть на то, что ты пишешь Алисе.
О чём книга
Если кратко, «Промт-инжиниринг для LLM» — это своего рода путеводитель по тому, как устроена современная работа с языковыми моделями. Авторы шаг за шагом, начиная с истории и базового понимания устройства LLM, разбирают, как пользовательский запрос превращается в осмысленный ответ, от чего зависит получившийся результат и как разработчик такого приложения может на него повлиять.
При этом это не учебник по машинному обучению или архитектуре нейросетей, а руководство по созданию приложений, использующих готовые LLM для решения практических задач.
Что я забрал с собой
Большие языковые модели (LLM) — это не волшебство, а решение, позволяющее предсказывать вероятность появления следующего слова. Но это не должно обесценивать LLM в ваших глазах. Во-первых, сами эти модели — это по-настоящему революционные технологии, ставшие доступными широкой общественности совсем недавно. Во-вторых, результат этого предсказания зависит от огромного количества факторов: какая это модель, на каких данных она была обучена, как запрос пользователя был преобразован перед тем, как он попал в саму модель, и как ответ был представлен потом пользователю.
Основы
Текущий прорыв LLM связан с развитием генеративного предварительно обученного трансформера (GPT). Не смогу углубиться в подробности, но предложенная архитектура трансформера позволила перейти от настройки моделей под конкретные задачи к обучению на гигантском объеме информации универсальных моделей, способных решать конкретные задачи зачастую лучше, чем самые продвинутые алгоритмы прошлого поколения, специально заточенные под эти задачи.
При работе с текстом модель работает не со словами целиком, а с токенами, разбивая слова на отдельные части (токены), и присваивает каждому уникальный ID в своем Словаре. Эти токены — не обязательно буквы, слоги или слова целиком. Все зависит от конкретного слова, как оно записано в этом Словаре. Упрощённо можно сказать: при токенизации слова разбиваются на куски, имеющие смысл. Это позволяет экономить ресурсы и не хранить в словаре отдельно все варианты слов со всеми склонениями, спряжениями для единственного и множественного числа.
Нам как пользователям нужно учитывать два нюанса. Во-первых, каждая опечатка в промте приводит к использованию лишних токенов, так как модели приходится дробить непонятные куски слова на отдельные части. Во-вторых, из-за особенностей русского языка слова, как правило, разбиваются на большее количество токенов. И пусть современные модели ограничивают нас уже не так строго, но лучше это держать в уме и учитывать в работе, особенно с маломощными моделями.
Дальше происходит эмбеддинг — модель заменяет ID токена на вектор, указывающий, где этот токен находится в ее "сознании". У этого вектора огромное количество координат-параметров, и их количество — это еще один критерий оценки мощности модели. Определение значений этих параметров, наряду с внутренними весами, связывающими токены в единую нейросеть, по факту, и есть результат обучения модели. Это и позволяет модели как раз-таки "угадать" следующее слово: когда мы напишем «Усы + Кошкин», она ответит «Кошкин хвост», а на «Стихотворение + Кошкин» — «Кошкин дом». Все из-за того, что у этих понятий значения определенных параметров будут близкими друг другу. Наверное, тут и скрывается основная "магия" LLM, которая на самом деле просто является очень сложными вычислениями.
Мы все знаем, что бывают нестандартно мыслящие люди, которые на стандартные вопросы дают, может быть, даже абсолютно корректные, но нестандартные ответы. Так вот, LLM тоже так может, и за степень ее креативности отвечает температура. Стандартно значение около 0 дает статистически самый вероятный ответ. Обычно, в зависимости от задач, разработчик приложений на основе LLM работает с диапазоном от 0 до 1, где 1 — это уже достаточно незаурядные ответы. Авторы книги сравнивают влияние температуры на модель с алкоголем для человека. Это функция API для разработчиков, и мы как пользователи обычно не можем задавать ее в явном виде, просто указав 0.5, но мы можем повлиять на нее, задав стиль ответов словами, и приложение подрегулирует температуру ответа под наш запрос.
Я не буду пытаться пересказать архитектуру трансформера (GPT), но важно понимать, что модель определяет по одному следующему токену за раз без возможности вернуться и прочитать или отредактировать предыдущий. Именно поэтому в промте лучше ставить задачу перед обрабатываемыми данными, чтобы модель сразу анализировала текст с учетом контекста. Опять-таки, тут идет речь о прямом системном запросе к LLM. За нашим пользовательским промтом может скрываться несколько скрытых обращений к модели. Но это уже будет зависеть больше от особенностей самого приложения, а не от базовых принципов работы LLM.
Мы как пользователи обычно и не видим всех этих технических аспектов, так как, как правило, работаем с LLM через чат. В нем приложение перед тем, как отправить наш запрос модели — который мы гордо называем промтом, — дополняет его огромным объемом информации, превращая его в настоящий промт для LLM. Иногда для его формирования привлекают даже саму модель с помощью скрытых системных запросов.
Для чатов используют специально дообученные на основе обратной связи человека модели (RLHF) — оказывается, у LLM тоже есть фидбек. Кроме нюансов при формировании ответов (что ответ должен быть честным, полезным и безвредным), такое обучение в целом дает понять модели, что от нее требуется поддерживать диалог и отвечать на запросы, а не просто генерировать их продолжение.
При этом сама непринужденная беседа между конечным пользователем и LLM превращается в театральную пьесу, где промт-инженер выступает драматургом, расписывающим сценарий по ролям пользователя и ассистента. И помогает в этом ChatML — специальный технический язык разметки промтов. Разработчик приложения передает структурированную информацию (текст пьесы) через API, параллельно задавая через него дополнительные параметры, определяющие ход всей этой "постановки" — например, температуру ответов, о которой мы говорили выше. А само приложение уже переписывает ее в строгом ChatML-формате диалога для нейросети.
Но при всей кажущейся всесильности даже современные модели легко сбить с пути. Авторы называют это принципом Красной Шапочки, которая, несмотря на все наставления матери, свернула не на ту тропинку. При проектировании сложных промтов нужно не отклоняться далеко от пути, по которому обучалась эта модель, чтобы она не заблудилась и в результате дала ожидаемый и логичный ответ. На практике это означает: если вы попросите модель дать вам шаблон для предоставления данных для анализа и потом предоставите их в этом формате, то ваши шансы на успех будут выше, чем если вы придумаете известный только вам подход.
При этом промт должен включать в себя всю информацию, относящуюся к задаче. Иногда для этого достаточно текста в самом запросе от пользователя — если он просит, например, проверить орфографию в его статье. Но если он попросит проверить свой авторский стиль, то в системный промт нужно будет добавить соответствующие примеры. Решение будет зависеть от контекста, и от того, насколько качественно получится передать его модели, будет напрямую зависеть результат ее генерации. Поэтому важно не просто извлечь контекст, но и ранжировать получившуюся информацию, ограничив ее объем. И пусть жесткие технические ограничения по ее объему уже во многом в прошлом, но помните про Красную Шапочку — мы должны помочь ей найти дорогу к бабушке, а не сбить её с пути лишними данными.
Даже самые лучшие модели не знают всех ответов. Что-то произошло уже после их обучения, но главное — коммерческие модели не могли обучаться на закрытых внутренних документах. И тогда встает вопрос: дообучать модель на этих данных (fine-tune) или же дать ей эту информацию, используя технологию расширенного поиска (RAG). В основе последней лежит дополнение промта контекстом, взятым из таких "закрытых" источников. Альтернативой может выступить подход, когда у самой LLM есть доступ к инструментам, в частности к поиску, и она самостоятельно получает информацию. Вариант, когда эти инструменты могут не только считывать, но еще и менять информацию в реальном мире, превращает приложение в ИИ-агента, о котором мы поговорим отдельно.
Еще промт-инженер не должен забывать, что, работая с системными промтами, он должен подталкивать LLM к генерации решений задач пользователя, а не просто вести беседу на заданную тему, а начав решение — вовремя остановиться. Также важно помнить, что все предложенные моделью решения имеют вероятностную природу. Поэтому необходимо оценивать качество таких решений: для каких-то ответов достаточно онлайн-оценки пользователя в виде пальца вверх или вниз в чатах Алисы или Gemini, но для каких-то результатов требуются серьезные инструменты. Где-то помогут специализированные программы, а что-то можно поручить оценить и самой LLM.
Основные техники
Во второй части книги авторы подробнее раскрывают механики. Я не буду подробно пересказывать их все, а постараюсь привести примеры, которые либо помогут лучше понять внутренний мир работы с моделями, либо можно применить при написании обычных пользовательских запросов.
Явные инструкции — если вы что-то хотите или не хотите получить в ответе от вашей модели, не поленитесь указать это в явном виде. При создании инструкций авторы рекомендуют: использовать положительные формулировки, а не отрицания; подкреплять команду причиной; стараться избегать абсолютных выражений. В общем, всё как у людей.
Few-shot-промтинг — техника добавления в промт примеров. Примеры тоже помогают не только людям, но и LLM — не только лучше понять контекст, но и увидеть, в каком виде вы ожидаете получить ответ. Это хороший пример подхода, который хорошо работает как при создании системного промта, так и при написании пользовательского запроса. Такой подход позволит сэкономить вам время и силы на проработку и формализацию инструкций, но может натолкнуть модель на ложные паттерны, плохо подходит для сложных случаев, когда модель может просто запутаться в большом объёме похожей информации.
Задав общий, или как он называется в книге, статический контекст (например, как нужно рекомендовать пользователю книгу на вечер), нужно определить ещё и динамический контекст, который отвечает за нюансы конкретного пользователя, чтобы сделать ответ более персонализированным. Фактически, именно за это мы и ценим ИИ-помощников — они дают не просто шаблонные ответы, а учитывают наши потребности.
Одним из способов является дополнение промта поисковыми данными (RAG), который я уже упоминал в первой части этой статьи. Это позволяет дать модели доступ к информации, которой не было в обучающей выборке. В приведённом примере с рекомендациями книг — получить данные о предыдущих действиях пользователей (комментариях, лайках и т.п.). Кстати, это отличная иллюстрация того, как ИИ зависит от классической автоматизации процессов: чтобы применение ИИ было по-настоящему эффективным, должен быть цифровой след, с которым ваше приложение сможет работать и на основании него давать ценные рекомендации. И тогда это уже будет пусть и не тривиальная, но сугубо техническая задача — как из всего этого многообразия данных выделить релевантную информацию, будь то классический поиск на основании лексики или поиск на основе эмбеддингов, когда информация связывается по смыслу.
Собрав всю необходимую информацию, её важно упаковать в правильный промт. Так как модели в основном обучаются на артефактах, созданных людьми, то и задания они "любят" получать в формате, который понятен и привычен для большинства людей.
Введение — задаёт у модели понимание, что ей предстоит делать, и настраивает на нужный лад. Далее идёт основная часть с основной информацией. Эта часть может быть достаточно объёмной, и авторы рекомендуют учитывать, что из-за особенностей обучения у большинства моделей, чем ближе фрагмент информации к концу промта, тем больше влияния он оказывает на модель. Кроме того, модели страдают феноменом "утраченной середины" — по большей части игнорируя информацию в этой части промта. Чем больше информации, тем сильнее влияние этих факторов, так что лучше это учитывать и минимизировать размещение важной информации в этих участках.
Когда контекст определён, нужно напомнить модели об основном вопросе и сфокусировать её на проблеме. Техника "сэндвича" — это задание, затем контекст и повторение задачи для фокусировки. После этого нужен чёткий переход к решению, чтобы модель действительно решила задачу, а не прислала в ответ свои рассуждения на заданную тему.
В этом может помочь информация в каком формате вы хотите получить решения: в виде диалога, аналитического отчета или структурированного документа. На всех этих типах данных обучались модели и они им хорошо известны и понятны.
При создании итогового промта нужно решить задачу оптимизации и выбрать, какие элементы нужно включить в промт для максимизации его ценности. И пусть технические ограничения становятся всё менее жёсткими, но всё равно остаются вопросы стоимости использования модели и ценности информации для самого промта: помогает ли она в решении основной задачи или, наоборот, сбивает его с верного пути.
В книге есть раздел, посвящённый выбору модели. Конкретные рекомендации, очевидно, быстро устаревают, а общие советы вроде ориентации на стоимость, простоту использования и функциональность — слишком банальны. Но мне запомнилась рекомендация: не нужно бояться проектировать свои приложения под чуть более мощные модели, которые слегка выходят за рамки текущих возможностей. С учётом скорости развития этого рынка крайне вероятно, что пока вы будете разрабатывать своё приложение, искомая модель если и не устареет, то точно станет доступнее, а ваше приложение уже будет оптимизировано для работы с более эффективной моделью.
А выбрав локальную модель, нужно решить, способна ли она решать ваши задачи прямо "из коробки" или требуется её настройка. А если настройка всё-таки нужна, есть ли у вас возможность (объём информации и ресурсы) для её полноценной тонкой настройки (fine-tune), настройки параметров (PeFT), когда не меняются параметры основной модели, а создаётся дополнительная матрица, которая участвует в определении итоговых весов, или вы просто будете задавать важный для вас контекст в рамках системных промтов.
Навыки эксперта
В последней части авторы стараются раскрыть фишечки, которые должны вывести ваши приложения с использованием ИИ на новый уровень — с помощью тонкой настройки мышления модели, внимания к деталям и развития инструментария.
Агентность — это возможность модели взаимодействовать с окружающим миром: получать дополнительную информацию, использовать внешние инструменты или даже вносить изменения в реальность. Это открывает перед нами огромные возможности, но, как говорил дядя Бен из «Человека-паука»: «С большой силой приходит и большая ответственность». Здесь эта фраза как нельзя кстати. Ведь от доступа к конфиденциальной информации до риска спустить все накопления на любимые ириски — всё это реальные угрозы при необдуманном использовании агентов. А вопросы морально-этического применения ИИ-агентов в военной сфере уже стали реальностью. Чтобы ваше приложение не пугало пользователя, особенно пока люди не привыкли к самостоятельности агентов, авторы предлагают делать процесс использования инструментов максимально прозрачным для пользователя: показывать, когда и какие инструменты используются, а все критичные изменения подтверждать у пользователя в явном виде.
Рассуждения — по своей природе LLM не склонны к рассуждениям, они просто предсказывают следующий токен, но это не значит, что её нельзя к этому подтолкнуть. Это можно сделать, например, с помощью примеров: включив в промт пример рассуждения на схожую тему или просто указав на необходимость рассуждать пошагово в явном виде. И тогда, генерируя его, модель невольно сама придёт к ответу на основании этого рассуждения. Логичным развитием этого подхода стало ReAct: интерактивное рассуждение и действие, когда модель не просто рассуждает, а на основании этого определяет и выполняет определённые действия — например, ищет информацию, а потом с её учётом сама определяет следующий шаг. Также добавляются техники, когда модель не сразу, пусть и поэтапно, приступает к решению задачи, а сначала формирует план решения и только потом приступает к его выполнению. А добавление этапа рефлексии позволяет улучшать решения при следующих запросах.
Рабочие потоки — хотя LLM прекрасно справляются с отдельными задачами по запросу, сами по себе они не умеют выстраивать сложные сценарии из нескольких шагов и удерживать при этом своё внимание на результате. Однако при правильной организации можно превратить модель в часть сложного бизнес-процесса: разбив большую задачу на цепочку последовательных и независимых шагов и связывая их между собой через промежуточные результаты.
Ключевая идея — не надеяться, что LLM “догадается сама”, а чётко описывать процесс: что именно происходит на каждом этапе, какие данные нужны и какие действия допустимы. Или хотя бы дать в явном виде задание сделать это модели самой. Эффективный рабочий поток строится вокруг простого принципа: на каждом этапе моделировать явно поставленную задачу (и для себя, и для ИИ), контролировать переходы между этапами и давать возможность для проверки и корректировки хода исполнения. Такой подход не только повышает устойчивость решения, но и позволяет гибко подключать к процессу человека, внешние инструменты или другие модели — делая процесс применения LLM максимально прозрачным и управляемым.
Агенты, хранящие состояние, позволяют не просто брать каждый раз на вход новую информацию и выдавать результат, но и быть постоянно связанными с конкретным набором данных и изменять его состояние при необходимости.
Скилы — это термин, который появился относительно недавно, поэтому я его не встречал в книге, но по факту это актуальное название инструментов для ИИ-агентов. По сути, скилл — это небольшая внешняя функция, которую агент может вызвать, чтобы что-то сделать "в реальном мире": от чтения корпоративных данных или управления почтой до обновления CRM или запуска автоматических процедур. На практике процесс устроен так: разработчик описывает функции и параметры каждого скилла (обычно на понятном человеку языке и в формате, удобном для машины), а затем эти функции становятся доступны модели через специальный протокол. Дальше агент сам, исходя из смысла диалога, выбирает нужный скилл, передаёт параметры из общения и использует получившийся результат в своей логике решения задачи.
MCP — актуальный способ реализации связи ИИ с внешними инструментами. Это специальный протокол, который формализует взаимодействие между моделью и скилами: помогает агенту видеть список доступных функций, их назначение, входные и выходные параметры и корректно вызывать нужное по ситуации. Благодаря MCP разработчик может не только чётко описывать возможности функций, но и делать их понятными машинами — чтобы агент мог действовать автономно и прозрачно. Сервер MCP обычно берёт на себя выполнение API-вызовов к внешним приложениям, а также обработку всех внутренних шагов: авторизацию, проверку прав доступа и безопасность взаимодействий.
Поскольку ответы модели — это всегда результат вероятностной генерации, а не жёстких алгоритмов, для таких приложений особенно важно продумать стратегию оценки качества. Авторы подчёркивают, что универсального подхода здесь нет. В одних случаях подойдет сравнение вывода с эталоном, в других — функциональное тестирование или подключение самой LLM для автоматической проверки. Ещё один важный путь — онлайн-оценка реальными пользователями: люди отмечают полезность или ошибки ответа, и эта информация напрямую влияет на доработку промтов и архитектуры приложения. Для проверки изменений отлично работает A/B-тестирование: можно показывать разные промты или версии модели разным группам пользователей и анализировать, что реально работает лучше.
Вместо вывода
Ещё до прочтения книги, общаясь с ИИ-ботами, меня не покидала мысль, что я разговариваю с эрудированным ребёнком с СДВГ. В книге же приводится другая аналогия — не слишком сообразительный механический друг, который, тем не менее, прочитал всё содержимое интернета.
В любом случае LLM требует от пользователя определённой эмпатии при общении с ней. Нужно понимать, что модель легко отвлекается, поэтому не стоит перегружать её лишней информацией. LLM должна понимать ваш промт: если вы сами толком не понимаете, что написали, то и она, скорее всего, не сможет понять. Модель не умеет читать мысли; если она начнёт их додумывать, легко “свалится” в галлюцинации. Поэтому важно не только давать ей всю необходимую информацию, но и направлять её, формулируя чёткие инструкции.
Если придерживаться этих нехитрых рекомендаций, которые, по сути, применимы и в обычном общении с людьми, подчинёнными или коллегами, модель действительно становится надёжным и уже незаменимым помощником.
Но при всей мощности и скоростях развития ИИ не стоит пытаться внедрять его везде, где только можно и нельзя. Если задачу можно решить без ИИ — делайте без него, это часто окажется проще, дешевле и предсказуемее. Но если задача реально требует гибкости, а не просто желания “хайпануть”, то LLM — это ключевая технология нашего времени.
А меня в продолжение темы уже ждет на полке книга "Разработка приложений на базе GPT-4". Очевидно, что издатели не успевают за скоростью выхода моделей.
Если оценивать эту, то:
Простота чтения: 3 из 10
Плотность: 7 из 10
Полезность: 7 из 10
Подписывайтесь, комментируйте — продолжение обязательно будет
Чтобы не пропустить новые статьи, подписывайтесь на мой канал в telegram: