
Большие языковые модели (LLM) способны автоматизировать значительное количество задач. С момента выпуска ChatGPT в 2022 году на рынке появляется все больше продуктов, созданных на основе искусственного интеллекта (ИИ) и использующих LLM. Однако многие методы применения LLM еще ждут своего улучшения. Например, использование оптимизатора LLM-промптов и применение кэшированных токенов — два простых метода, которые позволяют значительно повысить производительность LLM-приложения.
В этой статье я расскажу о нескольких методах, которые можно применять при разработке и структурировании промптов, чтобы сократить время отклика и затраты, а также повысить качество ответов. Моя цель — познакомить вас с этими методами, чтобы вы могли сразу же применить их в своем LLM-приложении.

Почему следует оптимизировать промпты
Во многих случаях ваши промпты, взаимодействуя с определенной LLM, дают адекватные результаты. Однако, не уделяя времени их оптимизации, вы не сможете реализовать весь потенциал модели.
Я убежден в том, что предлагаемые мной методы помогут вам улучшить качество результатов и снизить затраты без особых усилий. То, что промпт и LLM работают, не означает, что они работают оптимально. Во многих случаях можно добиться значительных улучшений с минимальными усилиями.
Методы оптимизации
В этом разделе я расскажу о методах, которые можно использовать для оптимизации промптов.
Всегда помещайте статический контент в начало
Первый метод заключается в размещении статического контента в начале промпта. Под статическим контентом я имею в виду контент, который остается неизменным при нескольких вызовах API.
Причина, по которой необходимо размещать статический контент в начале, заключается в том, что все крупные поставщики LLM, такие как Anthropic, Google и OpenAI, используют кэшированные токены. Кэшированными считаются токены, уже обработанные в предыдущем запросе API. Поэтому их обработка обходится дешевле и быстрее. Цена на кэшированные входные токены зависит от поставщика, но чаще всего она составляет около 10% от стоимости обычных входных токенов.
Кэшированные токены — это токены, которые уже были обработаны в предыдущем запросе API и которые можно обработать дешевле и быстрее, чем обычные токены.
Это означает, что если вы отправляете один и тот же запрос два раза подряд, входные токены второго запроса будут стоить только 1/10 от стоимости входных токенов первого запроса. Это работает потому, что поставщики LLM кэшируют обработку входных токенов, что делает обработку вашего нового запроса дешевле и быстрее.
На практике кэширование входных токенов осуществляется путем сохранения переменных в конце промпта.
Например, если у вас длинный системный промпт с вопросом, который меняется от запроса к запросу, следует сделать что-то вроде этого:
prompt = f"""
{long static system prompt}
{user prompt}
"""
Например:
prompt = f"""
You are a document expert ...
You should always reply in this format ...
If a user asks about ... you should answer ...
{user question}
"""
Здесь сначала размещаем статичный контент промпта, а затем — изменяемые данные (вопрос пользователя).
В некоторых сценариях может потребоваться передавать контент документов. При обработке множества разных документов следует поместить контент документа в конец промпта:
# При обработке разных документов:
prompt = f"""
{static system prompt}
{variable prompt instruction 1}
{document content}
{variable prompt instruction 2}
{user question}
"""
Однако при неоднократной обработке одного и того же документа следует добиться того, чтобы токены документа также кэшировались, заранее убедившись, что в промпт не введены никакие переменные:
# При неоднократной обработке одних и тех же документов:
prompt = f"""
{static system prompt}
{document content} # это должно идти перед инструкциями переменных
{variable prompt instruction 1}
{variable prompt instruction 2}
{user question}
"""
Отмечу, что кэшированные токены обычно активируются, только если первые 1024 токена в двух запросах совпадают.
Если же статичный системный промпт, как в приведенном выше примере, короче 1024 токенов, воспользоваться преимуществами кэшированных токенов не получится.
# Не делайте так:
prompt = f"""
{variable content} < --- this removes all usage of cached tokens
{static system prompt}
{document content}
{variable prompt instruction 1}
{variable prompt instruction 2}
{user question}
"""
Промпты всегда должны создаваться сначала из наиболее статичного контента (который наименее изменяется от запроса к запросу), а затем из наиболее динамичного контента (который наиболее изменяется от запроса к запросу).
- Длинный системный пользовательский промпт без переменных следует оставить в начале, а переменные добавить в конец промпта.
- При извлечении текста из документов и неоднократной обработке одного и того же документа необходимо разместить его содержимое в начале промпта.
Вопрос в конце промпта
Еще один метод, который стоит использовать для повышения эффективности работы с языковыми моделями, — размещение вопроса пользователя в самом конце промпта. В идеале, следует организовать его так: системный промпт содержит все общие инструкции, а пользовательский промпт состоит только из вопроса, как показано ниже:
system_prompt = "<general instructions>"
user_prompt = f"{user_question}"
В документации по инженерии промптов Anthropic указано, что размещение пользовательского промпта в конце может повысить производительность до 30%, особенно при работе с длинными контекстами. Размещение вопроса в конце позволяет модели точнее понять, какую именно задачу она должна выполнить, и во многих случаях приводит к лучшим результатам.
Использование оптимизатора промптов
Часто промпты, написанные людьми, получаются запутанными, непоследовательными, содержат избыточную информацию и не имеют четкой структуры. Поэтому всегда полезно пропускать их через оптимизатор промптов.
Самый простой оптимизатор промптов, который можно использовать, — попросить языковую модель улучшить этот промпт {текст промпта}. И она предоставит более структурированный промпт с меньшим количеством избыточной информации и прочими улучшениями.
Однако более эффективный подход — использовать специальный оптимизатор промптов, например, тот, что можно найти в консолях OpenAI или Anthropic. Эти оптимизаторы представляют собой языковые модели, специально настроенные и созданные для оптимизации промптов. Обычно они дают лучшие результаты. Используя оптимизатор, следует обязательно включить в промпт:
- детали задачи, которую надо решить;
- примеры задач, с которыми промпт справился, и соответствующие входные и выходные данные;
- примеры задач, с которыми промпт не справился, с соответствующими входными и выходными данными.
Предоставление этой дополнительной информации обычно приводит к значительно лучшим результатам. В итоге вы получите гораздо более качественный промпт. Во многих случаях нужно потратить всего около 10–15 минут, чтобы получить намного более эффективный промпт. Это делает использование оптимизатора промптов одним из самых простых способов повышения производительности языковых моделей.
Тестирование (бенчмаркинг) языковых моделей
Выбранная языковая модель также существенно влияет на производительность LLM-приложения. Разные модели хороши в решении разных задач, поэтому вам нужно опробовать различные модели в конкретной предметной области. Рекомендую настроить доступ хотя бы к крупнейшим поставщикам языковых моделей, таким как Google Gemini, OpenAI и Anthropic.
Сделать это довольно просто, а переключение между провайдерами занимает считанные минуты при наличии уже настроенных учетных данных. Кроме того, можно рассмотреть тестирование моделей с открытым исходным кодом, хотя это обычно требует больших усилий.
Чтобы понять, какая языковая модель работает лучше всего, нужно создать определенный тестовый набор (бенчмарк) для задачи, которую необходимо решить,
Дополнительно следует регулярно проверять производительность моделей, поскольку крупные поставщики периодически обновляют свои модели, не обязательно выпуская новые версии. Конечно, нужно быть готовым пробовать любые новые модели, выпускаемые крупными провайдерами
Заключение
Мы рассмотрели четыре метода, которые можно применить для повышения производительности LLM-приложения: использование кэшированных токенов, размещение вопроса в конце промпта, применение оптимизаторов промптов и создание специальных LLM-тестов. Все они относительно просты как в настройке, так и в выполнении и могут привести к значительному повышению производительности. Думаю, что существует много аналогичных простых методов и вам всегда следует пытаться их находить. Эти темы обычно описываются в различных блогах. Один из них, посвященный Anthropic, больше всего помог мне повысить производительность LLM.
Читайте также:
- Глубокое погружение в векторные базы данных
- Создание модели Mixture of Experts (MoE) с помощью MergeKit
- Создание приложения-чата с LangChain, большими языковыми моделями и Streamlit для взаимодействия со сложной базой данных SQL. Часть 2
Читайте нас в Telegram, VK и Дзен
Перевод статьи Eivind Kjosbakken: 4 Techniques to Optimize Your LLM Prompts for Cost, Latency, and Performance





