10 паттернов разработки надежных LLM приложений.
Начинаю серию публикаций по LLM System Design.
Если осилите все 10 паттернов - сможете разрабатывать надежные LLM-приложения, которые не сломаются от наплыва счастливых пользователей.
Поехали.
Паттерн 1. LLM приложение это просто граф
Считайте, что вы разрабатываете обычный софт. Используете микросервисную архитектуру. Сервис 1 ждет ответа от Сервиса 2, если ответ = X, то идет в Сервис 3 и тд.
Только теперь у вас некоторые сервисы это не просто код. Может быть вызов LLM-классификатора, в зависимости от вердикта вызываться какой-то другой код. Или вызов LLM-суммаризатора, ответ которого запишется в NOSQL базу данных.
Получается такой недетерминированный граф, который может решать поразительные задачи. Которые не мог решать обычный софт.
Перечислим часто используемые элементы в этом графе:
- Код бизнес логики. Не пытайтесь отдать это на LLM. Читайте про это статью. Туда же я отношу другие элементы разработки - реляционные базы данных, очереди сообщений и тд.
- Вызов LLM. Они могут соединяться различным образом: идти последовательно, параллельно, при выполнении условия и тд. Строго читать статью
- Внешние инструменты. Например, поисковый движок. Похоже на код, но инструменты не делают бизнес логики. Результат инструментов подается на вход в LLM. Разберем в "Паттерн 3. Все есть инструмент".
- Внешняя база знаний. Так делается RAG. Лучший способ заложить внешние знания в LLM. Подробнее обсудим в "Паттерн 4. Всегда используйте in context learning" и "Паттерн 5. Не переусложняйте RAG".
- Не-LLM модели. Обычно это берты/сверточные сети или бустинги над деревьями. Очень быстры и дешевы. Как правило, обучаются дистилляцией. Поговорим про это в "Паттерн 10. Дистилируйте."
- Guardrails. Модели, которая оценивает качество ответа. Если качество плохое, лучше такое никому не показывать. Обсудим в "Паттерн 8. Human-in-the-loop"
- Человек. У него нужно уточнить, когда непонятно, что делать дальше. У него нужно спросить, когда хотим сделать рискованное действие. Подробнее в "Паттерн 8. Human-in-the-loop"
- Автономные агенты. Редкий зверь, но будет чаще встречаться. Почему редкий. Обсудим в "Паттерн 9. Когда нужны автономные агенты."
Литература для изучения
- Строго mustread пост от Anthropic
- Подробная схема LLM-приложений от Chip Huyen
- Пост, почему надо разделять LLM и бизнес логику
- 500 реальных кейсов LLM-приложений
- Подробный гайд с большим числом деталей
- Принципы проектирования агентов (многое можно почерпнуть и для неагентов)
Как обычно, любые вопросы жду в комментариях. Все разберем.
#llm_system_design
Начинаю серию публикаций по LLM System Design.
Если осилите все 10 паттернов - сможете разрабатывать надежные LLM-приложения, которые не сломаются от наплыва счастливых пользователей.
Поехали.
Паттерн 1. LLM приложение это просто граф
Считайте, что вы разрабатываете обычный софт. Используете микросервисную архитектуру. Сервис 1 ждет ответа от Сервиса 2, если ответ = X, то идет в Сервис 3 и тд.
Только теперь у вас некоторые сервисы это не просто код. Может быть вызов LLM-классификатора, в зависимости от вердикта вызываться какой-то другой код. Или вызов LLM-суммаризатора, ответ которого запишется в NOSQL базу данных.
Получается такой недетерминированный граф, который может решать поразительные задачи. Которые не мог решать обычный софт.
Перечислим часто используемые элементы в этом графе:
- Код бизнес логики. Не пытайтесь отдать это на LLM. Читайте про это статью. Туда же я отношу другие элементы разработки - реляционные базы данных, очереди сообщений и тд.
- Вызов LLM. Они могут соединяться различным образом: идти последовательно, параллельно, при выполнении условия и тд. Строго читать статью
- Внешние инструменты. Например, поисковый движок. Похоже на код, но инструменты не делают бизнес логики. Результат инструментов подается на вход в LLM. Разберем в "Паттерн 3. Все есть инструмент".
- Внешняя база знаний. Так делается RAG. Лучший способ заложить внешние знания в LLM. Подробнее обсудим в "Паттерн 4. Всегда используйте in context learning" и "Паттерн 5. Не переусложняйте RAG".
- Не-LLM модели. Обычно это берты/сверточные сети или бустинги над деревьями. Очень быстры и дешевы. Как правило, обучаются дистилляцией. Поговорим про это в "Паттерн 10. Дистилируйте."
- Guardrails. Модели, которая оценивает качество ответа. Если качество плохое, лучше такое никому не показывать. Обсудим в "Паттерн 8. Human-in-the-loop"
- Человек. У него нужно уточнить, когда непонятно, что делать дальше. У него нужно спросить, когда хотим сделать рискованное действие. Подробнее в "Паттерн 8. Human-in-the-loop"
- Автономные агенты. Редкий зверь, но будет чаще встречаться. Почему редкий. Обсудим в "Паттерн 9. Когда нужны автономные агенты."
Литература для изучения
- Строго mustread пост от Anthropic
- Подробная схема LLM-приложений от Chip Huyen
- Пост, почему надо разделять LLM и бизнес логику
- 500 реальных кейсов LLM-приложений
- Подробный гайд с большим числом деталей
- Принципы проектирования агентов (многое можно почерпнуть и для неагентов)
Как обычно, любые вопросы жду в комментариях. Все разберем.
#llm_system_design
10🔥43👍18❤11🤔2🐳2❤🔥1
Надеюсь, я не отбил у вас желание разбираться с LLM System Design. Если нет, то продолжаем.
Второй паттерн. Structured output
Вы выдаете желаемую JSON-схему ответа, LLM не может ее нарушить. Работает благодаря 2-м вещам:
1) Ваш формат конвертируется в грамматику. Генерация каждого следующего токена жестко ограничена этой грамматикой. Считайте, что работает регулярка на выходе модели.
2) Базовая модель дообучалась, чтобы понимать по схеме, что вообще от нее хотят.
Удобно задавать через библиотеку Pydantic. Вы просто программируете классы, Pydantic генерирует нужный json. Пример, когда LLM извлекает поля научной статьи:
Optional объясняет, что keywords может быть не у каждой статьи.
Почему важно
- Убирает боль неверных форматов. При условии, что мы все идем к тулам и агентам (подробнее в 3 паттерне), это супер важно.
- Улучшает прозрачность. Все понятно, что модель нашла , а что найти не смогла (там будет None)
- Самодокументация. Вы сами наложили спецификацию на формат данных, потом всем сильно проще будет разобраться в этом коде.
Structured Output и Reasoning
Никто не мешает вам совмещать Structured Output (SO) с рассуждающими моделями. Пусть они выводят свои рассуждения в отдельное (первое) поле:
Есть статьи, которые говорят, что это ломает рассуждающие способности. Решение: пробуйте 2 раза. Сначала рассуждайте без SO, потом извлейкайте ответ с SO (более простой моделью, конечно)
Литература для изучения
- Документация от OpenAI
- Волшебный доклад про Pydantic
- Подробнее про двойной подход в SO + Reasoning
- Туториал по SO для Langchain
Как обычно, любые вопросы жду в комментариях. Все полезные материалы буду помечать хештегом.
#llm_system_design
Второй паттерн. Structured output
Вы выдаете желаемую JSON-схему ответа, LLM не может ее нарушить. Работает благодаря 2-м вещам:
1) Ваш формат конвертируется в грамматику. Генерация каждого следующего токена жестко ограничена этой грамматикой. Считайте, что работает регулярка на выходе модели.
2) Базовая модель дообучалась, чтобы понимать по схеме, что вообще от нее хотят.
Удобно задавать через библиотеку Pydantic. Вы просто программируете классы, Pydantic генерирует нужный json. Пример, когда LLM извлекает поля научной статьи:
from pydantic import BaseModel
class ResearchPaperExtraction(BaseModel):
title: str
authors: list[str]
keywords: Optional[list[str]]
response = client.responses.parse(
model="gpt-4o-2024-08-06",
input=[...],
text_format=ResearchPaperExtraction,
)
Optional объясняет, что keywords может быть не у каждой статьи.
Почему важно
- Убирает боль неверных форматов. При условии, что мы все идем к тулам и агентам (подробнее в 3 паттерне), это супер важно.
- Улучшает прозрачность. Все понятно, что модель нашла , а что найти не смогла (там будет None)
- Самодокументация. Вы сами наложили спецификацию на формат данных, потом всем сильно проще будет разобраться в этом коде.
Structured Output и Reasoning
Никто не мешает вам совмещать Structured Output (SO) с рассуждающими моделями. Пусть они выводят свои рассуждения в отдельное (первое) поле:
class Step(BaseModel):
explanation: str
output: str
Есть статьи, которые говорят, что это ломает рассуждающие способности. Решение: пробуйте 2 раза. Сначала рассуждайте без SO, потом извлейкайте ответ с SO (более простой моделью, конечно)
Литература для изучения
- Документация от OpenAI
- Волшебный доклад про Pydantic
- Подробнее про двойной подход в SO + Reasoning
- Туториал по SO для Langchain
Как обычно, любые вопросы жду в комментариях. Все полезные материалы буду помечать хештегом.
#llm_system_design
10🔥42👍18❤10🙏2❤🔥1🤔1🐳1
Продолжаем серию публикаций по LLM System Design. Сегодня говорим про важность внешних инструментов.
Паттерн 3. Дайте LLM правильные инструменты
Самый частый паттерн применения LLM — модель переводит запросы с человеческого языка в вызов нужных инструментов. Вы просите узнать баланс на карте, LLM отправляет запрос в нужный сервис, указывая идентификатор карты в параметрах. Вы говорите, что хотите найти в данных, LLM пишет SQL-запрос к правильной таблице.
Очень важно: любую детермированную логику выполнять кодом, а не LLM. Если нужно понять, можно ли дать этому клиенту скидку, пускай это решит детерминированный алгоритм, а LLM его правильно вызовет. Если нужно отсортировать документы по релевантности, пускай LLM выдаст релевантность, а отсортируете вы результат кодом. Более подробно про это читайте тут.
В дизайне системы очень удобно считать tool-ом любой другой элемент: внешний код, база данных (RAG), другие LLM и т.д. Вызов инструментов требует правильного заполнения всех аргументов, поэтому крайне удачно, что мы прошли Structured Output в Втором паттерне. Не забывайте его использовать.
Код — ваш лучший инструмент
Код это самый мощный tool, который вы только можете дать LLM (но риски кратно возрастают). LLM может персонально под задачу генерировать программу.
Пример. Делаем парсер, который не ломается, когда верстка сайта меняется. LLM сначала анализирует разметку сайта. Дальше по этой аналитике пишет код, который работает конкретно для этого сайта. Смотрите похожий кейс компании Ramp.
Код может быть не только tool-ом, но и управлять работой агента с другими tool-ами.
Вместо того, чтобы писать логику вызова tool-ов текстом, можно ее всю завернуть в программный код. Почему это удобно отлично написано тут.
На этой идеи построена библиотека smalagents от HuggingFace. Технические подробности в статье CodeAct.
Как научить LLM использовать инструменты
От самого простого к самому сложному:
1) Подключиться к MCP-серверу, если такой есть, и взять оттуда этот tool.
2) Самим сделать tool на базе каких-то API (не забываем про разницу MCP и API), напихать все в промпт
3) Самим сделать tool, зафайнтюнить LLM правильно этот tool использовать. Про это есть классическая статья.
Обязательная литература
- Объяснение, почему важно разделять LLM и tools
- Аналогичное правило, но для ИИ агентов
- Пост, чем дизайн tool для LLM отличается от просто API
- Статья, как важно Structured Output для tools
Любые вопросы обязательно пишите в комментарии.
Если нужно обсудить конкретно ваш случай - пишите вопрос в личные сообщения.
#llm_system_design
Паттерн 3. Дайте LLM правильные инструменты
Самый частый паттерн применения LLM — модель переводит запросы с человеческого языка в вызов нужных инструментов. Вы просите узнать баланс на карте, LLM отправляет запрос в нужный сервис, указывая идентификатор карты в параметрах. Вы говорите, что хотите найти в данных, LLM пишет SQL-запрос к правильной таблице.
Очень важно: любую детермированную логику выполнять кодом, а не LLM. Если нужно понять, можно ли дать этому клиенту скидку, пускай это решит детерминированный алгоритм, а LLM его правильно вызовет. Если нужно отсортировать документы по релевантности, пускай LLM выдаст релевантность, а отсортируете вы результат кодом. Более подробно про это читайте тут.
В дизайне системы очень удобно считать tool-ом любой другой элемент: внешний код, база данных (RAG), другие LLM и т.д. Вызов инструментов требует правильного заполнения всех аргументов, поэтому крайне удачно, что мы прошли Structured Output в Втором паттерне. Не забывайте его использовать.
Код — ваш лучший инструмент
Код это самый мощный tool, который вы только можете дать LLM (но риски кратно возрастают). LLM может персонально под задачу генерировать программу.
Пример. Делаем парсер, который не ломается, когда верстка сайта меняется. LLM сначала анализирует разметку сайта. Дальше по этой аналитике пишет код, который работает конкретно для этого сайта. Смотрите похожий кейс компании Ramp.
Код может быть не только tool-ом, но и управлять работой агента с другими tool-ами.
Вместо того, чтобы писать логику вызова tool-ов текстом, можно ее всю завернуть в программный код. Почему это удобно отлично написано тут.
На этой идеи построена библиотека smalagents от HuggingFace. Технические подробности в статье CodeAct.
Как научить LLM использовать инструменты
От самого простого к самому сложному:
1) Подключиться к MCP-серверу, если такой есть, и взять оттуда этот tool.
2) Самим сделать tool на базе каких-то API (не забываем про разницу MCP и API), напихать все в промпт
3) Самим сделать tool, зафайнтюнить LLM правильно этот tool использовать. Про это есть классическая статья.
Обязательная литература
- Объяснение, почему важно разделять LLM и tools
- Аналогичное правило, но для ИИ агентов
- Пост, чем дизайн tool для LLM отличается от просто API
- Статья, как важно Structured Output для tools
Любые вопросы обязательно пишите в комментарии.
Если нужно обсудить конкретно ваш случай - пишите вопрос в личные сообщения.
#llm_system_design
10👍23❤17🔥12🤩2😁1🤔1🐳1
Продолжаем изучать архитектуру LLM-систем. Сегодня говорим про работу с внешней информацией.
Паттерн 4. Зашивайте все ваши знания в промпт
Базовой LLM нужно много чего знать о вашей задаче, чтобы ее решить. Факты о вашем продукте, какие есть тулы, как зовут пользователя, с которым LLM говорит и тд и тп. Все это надо отправить в промпт. Часто его называют контекстное окно.
Это контекстное окно можно представлять как оперативную память компьютера. В нем могут содержаться не только статичная информация, но и результаты вызовов tool-ов, прошлые действия системы, критика сторонних моделей и тд.
Несмотря на то, что модели умеют все лучше и лучше работать с длинными последовательностями, вам нужно думать о размере контекстного окна. Чем длиннее окно, тем сложнее модели понять, что происходит, поэтому важно контекст эффективно записывать. Даже Google с своим Gemini вынужден делать хаки с контекстом, чтобы их агент смог играть в Покемон-Го. Подробнее про эти хаки читайте тут и берите на вооружение.
Часто мы даже точно не знаем, какую именно информацию нужно засунуть в окно, чтобы задача решилась. Тогда возникает архитектура RAG.
RAG
Название пришло из статьи 2020 года, в которой авторы присоединили retrieval систему к seq2seq-генератору. Дада, я использую слова из 2020 года, без всяких LLM. Фишка статьи, что они обучали обе эти модели вместе. Сейчас под RAG-ом подразумевают все, когда к LLM присобачивают какой-то поиск.
А присобачивать поиск оказалось довольно удобно. Человечество до эры LLM много лет занималось поиском. Вдруг оказалось, что поверх всех этих знаний можно вставить LLM, и оно просто заработает.
Fine-tuning
Одна из частых ошибок — файнтюнить LLM, чтобы научить ее какой-то новой информации. Это очень плохая идея.
1) Вы скорее всего сломаете базовый алайнмент модели. Это как вскрыть айфон — гарантия производителя перестает действовать. Веса модели меняются, уже никто не гарантирует, что модель не сломается на каком-то out of domain запросе. Такое же мнение написано тут.
2) Вы нарветесь на галлюцинации. Пытаясь вшить знания, которых модель не видела в претрейне, вы научите ее придумывать ответы на вопросы. Подробно проблема изложена в статье.
3) Не факт, что побьете RAG по качеству на вашем тесте. Почитайте просто форум. Посмотрите статью, где бенчили RAG против дообучения. Хорошо дообучать это сложно.
Файнтюнить точно можно и нужно, но для других задач. Тогда, когда модель перестает вас слушаться в промпте, вам нужна сильно более тонкая настройка. Более подробно про кейсы дообучения читайте в этом посте.
Я вам строго рекомендую RAG, чтобы дать LLM внешнюю инфу, а файнтюнинг оставить для другого. Об этом, кстати, говорят и OpenAI в своем курсе (ссылка ниже).
Литература для обязательного изучения
- Статья, как важно контролировать контекстное окно
- Доходчиво, почему fine-tuning для внедрения информации, это трата времени
- Видос про это же
- Часовой урок по fine-tuning от OpenAI (очень наглядно, когда надо дообучать)
- Объяснение, почему все состояние надо записывать в контекст
Как всегда, все вопросы пишите в комментарии или в личные сообщения.
#llm_system_design
Паттерн 4. Зашивайте все ваши знания в промпт
Базовой LLM нужно много чего знать о вашей задаче, чтобы ее решить. Факты о вашем продукте, какие есть тулы, как зовут пользователя, с которым LLM говорит и тд и тп. Все это надо отправить в промпт. Часто его называют контекстное окно.
Это контекстное окно можно представлять как оперативную память компьютера. В нем могут содержаться не только статичная информация, но и результаты вызовов tool-ов, прошлые действия системы, критика сторонних моделей и тд.
Несмотря на то, что модели умеют все лучше и лучше работать с длинными последовательностями, вам нужно думать о размере контекстного окна. Чем длиннее окно, тем сложнее модели понять, что происходит, поэтому важно контекст эффективно записывать. Даже Google с своим Gemini вынужден делать хаки с контекстом, чтобы их агент смог играть в Покемон-Го. Подробнее про эти хаки читайте тут и берите на вооружение.
Часто мы даже точно не знаем, какую именно информацию нужно засунуть в окно, чтобы задача решилась. Тогда возникает архитектура RAG.
RAG
Название пришло из статьи 2020 года, в которой авторы присоединили retrieval систему к seq2seq-генератору. Дада, я использую слова из 2020 года, без всяких LLM. Фишка статьи, что они обучали обе эти модели вместе. Сейчас под RAG-ом подразумевают все, когда к LLM присобачивают какой-то поиск.
А присобачивать поиск оказалось довольно удобно. Человечество до эры LLM много лет занималось поиском. Вдруг оказалось, что поверх всех этих знаний можно вставить LLM, и оно просто заработает.
Fine-tuning
Одна из частых ошибок — файнтюнить LLM, чтобы научить ее какой-то новой информации. Это очень плохая идея.
1) Вы скорее всего сломаете базовый алайнмент модели. Это как вскрыть айфон — гарантия производителя перестает действовать. Веса модели меняются, уже никто не гарантирует, что модель не сломается на каком-то out of domain запросе. Такое же мнение написано тут.
2) Вы нарветесь на галлюцинации. Пытаясь вшить знания, которых модель не видела в претрейне, вы научите ее придумывать ответы на вопросы. Подробно проблема изложена в статье.
3) Не факт, что побьете RAG по качеству на вашем тесте. Почитайте просто форум. Посмотрите статью, где бенчили RAG против дообучения. Хорошо дообучать это сложно.
Файнтюнить точно можно и нужно, но для других задач. Тогда, когда модель перестает вас слушаться в промпте, вам нужна сильно более тонкая настройка. Более подробно про кейсы дообучения читайте в этом посте.
Я вам строго рекомендую RAG, чтобы дать LLM внешнюю инфу, а файнтюнинг оставить для другого. Об этом, кстати, говорят и OpenAI в своем курсе (ссылка ниже).
Литература для обязательного изучения
- Статья, как важно контролировать контекстное окно
- Доходчиво, почему fine-tuning для внедрения информации, это трата времени
- Видос про это же
- Часовой урок по fine-tuning от OpenAI (очень наглядно, когда надо дообучать)
- Объяснение, почему все состояние надо записывать в контекст
Как всегда, все вопросы пишите в комментарии или в личные сообщения.
#llm_system_design
11👍32❤11🔥10🤩2🏆2❤🔥1🐳1
Мы тут иногда архитектуру LLM-систем изучаем. Продолжаем этот опус.
Паттерн 5. Архитектура надежных RAG-систем
В Паттерне 4 мы поняли, как удобно, когда вся информация, нужная для ответа, находится у LLM в контексте.
Часто эта информация зависит от текущего состояния системы. Тогда возникает RAG.
RAG это синтез двух очень больших и очень разных миров: Поиска и Генерации. Разберем каждый.
Поиск
Основная сложность в Поиске — огромное число кандидатов, с которых можно написать ответ.
Если у вас их десятки, сотни тысяч документов, то уже проблема. Нужно придумывать инженерные трюки, которые позволят быстро находить перспективных кандидатов. Благо за десятки лет их придумали много штук. Перечислим некоторые:
- Эмбеддинги и быстрый векторный поиск. Это то, о чем все думают, когда представляют RAG. Они хороши, что позволяют искать семантически похожие тексты. Но у них есть принципиальные ограничения: не могут найти точные совпадения, не могут выделить дату, не понимают структуру документа
- Текстовый матчинг. Точное совпадение кусков текста. Можно считать по буквам, словам, n-граммам. Работают формулы TF-IDF, BM25 и тд. Не способны ловить семантику
- Графы знаний. Задают структуру ваших данных. Например, что эти документы из одной категории. Или, что тот документ идет после вот этого. Можно делать с помощью LLM, рассказывал про cocoindex в дайджесте.
Можно и нужно генерировать кандидатов разными методами, а затем их ранжировать более тяжелыми формулами. Бертами, LLM или даже ансамблем деревьев решений. Про выбор модели читайте тут.
Генерация
Основная сложность в Генерации - опираться только на найденные Поиском документы. Ничего не выдумывать, не галлюцинировать.
Для решения есть такие опции, от простого к сложному:
- Промптинг.
Попросить, дорогой генератор, ответь только по тому, что у тебя в контексте. Не выдумывать. Для простого RAG, где небольшой контекст и простые вопросы — метод рабочий, можно использовать.
- SFT-дообучение.
Когда промптинга мало, модель все равно галлюцинирует. Собираем датасет троек (запрос, контекст, правильный ответ). Учим на этом генератор. Не забывайте в "правильный ответ" записать "Не могу ответить, ничего не нашла", когда по контексту невозможно ответить. Работает для средней сложности задач.
- RLHF.
Когда даже SFT не справляется. Делаем reward модель, которая оценивает качества ответа. Дальше делаем итерацию PPO/DPO/GRPO, обновляем reward, делаем новую итерацию, потворять до готовности.
Агентность в RAG
В RAG идеально вписываются элементы архитектуры агентов. От простого к сложному:
1) Отдельная модель, которая генерирует удобные запросы.
Позволяет формулировать правильные запросы, снимать омонимию.
2) Итеративные походы в Поиск.
Если в первый раз не нашли, давайте сходим снова. Понять, что не нашли, можно эвристиками или рассуждениями.
3) Настоящий DeepResearch.
Объединение первых двух. Агент рассуждает, ходит итеративно в Поиск с правильными запросами.
Это все можно промтировать, SFT-шить, или через RL. Последнее можно глянуть в статье.
Литература для обязательного изучения
- Глава 1 отсюда. Понятно про архитектуру RAG.
- Видос по основам RAG. Во многом дублируется с постом
- Туториал по оценку RAG-а через LLM-as-a-judge (важная тема, не влезла в пост)
- Статья большой обзор кучи подходов к RAG. Все читать не обязательно, просто посмотрите, что вообще есть
Как всегда, все вопросы пишите в комментарии или в личные сообщения.
#llm_system_design
Паттерн 5. Архитектура надежных RAG-систем
В Паттерне 4 мы поняли, как удобно, когда вся информация, нужная для ответа, находится у LLM в контексте.
Часто эта информация зависит от текущего состояния системы. Тогда возникает RAG.
RAG это синтез двух очень больших и очень разных миров: Поиска и Генерации. Разберем каждый.
Поиск
Основная сложность в Поиске — огромное число кандидатов, с которых можно написать ответ.
Если у вас их десятки, сотни тысяч документов, то уже проблема. Нужно придумывать инженерные трюки, которые позволят быстро находить перспективных кандидатов. Благо за десятки лет их придумали много штук. Перечислим некоторые:
- Эмбеддинги и быстрый векторный поиск. Это то, о чем все думают, когда представляют RAG. Они хороши, что позволяют искать семантически похожие тексты. Но у них есть принципиальные ограничения: не могут найти точные совпадения, не могут выделить дату, не понимают структуру документа
- Текстовый матчинг. Точное совпадение кусков текста. Можно считать по буквам, словам, n-граммам. Работают формулы TF-IDF, BM25 и тд. Не способны ловить семантику
- Графы знаний. Задают структуру ваших данных. Например, что эти документы из одной категории. Или, что тот документ идет после вот этого. Можно делать с помощью LLM, рассказывал про cocoindex в дайджесте.
Можно и нужно генерировать кандидатов разными методами, а затем их ранжировать более тяжелыми формулами. Бертами, LLM или даже ансамблем деревьев решений. Про выбор модели читайте тут.
Генерация
Основная сложность в Генерации - опираться только на найденные Поиском документы. Ничего не выдумывать, не галлюцинировать.
Для решения есть такие опции, от простого к сложному:
- Промптинг.
Попросить, дорогой генератор, ответь только по тому, что у тебя в контексте. Не выдумывать. Для простого RAG, где небольшой контекст и простые вопросы — метод рабочий, можно использовать.
- SFT-дообучение.
Когда промптинга мало, модель все равно галлюцинирует. Собираем датасет троек (запрос, контекст, правильный ответ). Учим на этом генератор. Не забывайте в "правильный ответ" записать "Не могу ответить, ничего не нашла", когда по контексту невозможно ответить. Работает для средней сложности задач.
- RLHF.
Когда даже SFT не справляется. Делаем reward модель, которая оценивает качества ответа. Дальше делаем итерацию PPO/DPO/GRPO, обновляем reward, делаем новую итерацию, потворять до готовности.
Агентность в RAG
В RAG идеально вписываются элементы архитектуры агентов. От простого к сложному:
1) Отдельная модель, которая генерирует удобные запросы.
Позволяет формулировать правильные запросы, снимать омонимию.
2) Итеративные походы в Поиск.
Если в первый раз не нашли, давайте сходим снова. Понять, что не нашли, можно эвристиками или рассуждениями.
3) Настоящий DeepResearch.
Объединение первых двух. Агент рассуждает, ходит итеративно в Поиск с правильными запросами.
Это все можно промтировать, SFT-шить, или через RL. Последнее можно глянуть в статье.
Литература для обязательного изучения
- Глава 1 отсюда. Понятно про архитектуру RAG.
- Видос по основам RAG. Во многом дублируется с постом
- Туториал по оценку RAG-а через LLM-as-a-judge (важная тема, не влезла в пост)
- Статья большой обзор кучи подходов к RAG. Все читать не обязательно, просто посмотрите, что вообще есть
Как всегда, все вопросы пишите в комментарии или в личные сообщения.
#llm_system_design
4❤26👍16🔥12🤔2❤🔥1🐳1
Продолжаем грызть науку LLM-строения.
В прошлых 5 публикациях мы поняли, из каких кубиков состоит LLM-система. Сейчас пришло время из них что-то собирать.
А как собирать?
Тема 6. Этапы LLM-проекта
Я делю разработку на 4 этапа:
1) Бизнес постановка
2) Создание прототипа
3) Упрощение протототипа
4) Деплой системы и мониторинг качества
Бизнес постановка
Нам нужны частотные и дорогие задачи. Важно, чтобы была толерантность к ошибкам — близкое к 100% качество у LLM бывает разве что в простой классификации. Классические примеры:
- Бот поддержки клиентов — большой объем, средняя толерантность, средняя стоимость операции
- Copilot для разработчика — средний объем, высокая толерантность (copilot же), высокая стоимость операции
- Автоматизация документооборота— средний объем, средняя толерантность, средняя стоимость операции
Создание прототипа
Проблема подавляющего большинства ИИ-проектов: когда начинается плотная разработка никто не понимает, что надо сделать. И начинают выдумывать на ходу, когда надо не выдумывать, а надо уже делать. Подумать надо было заранее. И все ваше подумывание отразить в прототипе.
Цель прототипа: получить продуктовый ориентир, что наша система должна уметь. При этом там могут быть какие угодно большие модели, он может работать час на запрос и ломаться от промпт-инъекций. Не ругайте его. Он исправится на следующем этапе. Признак успеха этого этапа: человек, который делал бизнес постановку скажет: "вот сделайте такое, только быстро, и я буду счастлив".
Важно: прототип могут и должны собирать люди, которые участвовали в этапе бизнес постановки. Иначе у вас получится опять сферическая LLM в вакууме. Про это читайте пост.
Упрощение протототипа
Здесь сильные технические люди крутят-вертят LLM. Чтобы прототип не стоил, как запуск ракеты Илона Маска.
Большое разнообразие различных вариантов:
1) Дистилляция. Большие модели нужно сжать в модели поменьше. Качество может теряться, но если мы решаем конкретную узкую задачу, должно упасть не сильно. Вот тут подробный разбор метода.
2) Дообучение. Можно не дистиллировать, а просто взять модель поменьше. Но тогда придется их покрутить, так как они справляться будут хуже. Здесь приходит на помощь дообучение (особенно Reinforcement Learning). Вот тут много примеров по дообучению разных LLM разными методами.
3) Работа с контекстом окном. Убирание лишнего из контекста, суммаризация (я пока не устал шутить про контекст-инженера)
4) Оптимизации. Тут отдельный мир: размер батча/квантизация/спекулятивный декодинг. Про это есть отдельная методичка в этом посте.
И еще куча-куча всего. Тут живет мощная LLM-инженерия.
Деплой и мониторинг качества
Здесь происходит классическая разработка. Пишется сервис, в котором работает наша эффективная система. Самое важное: нам нужно контролировать качество этого сервиса. При чем не разово, а постоянно. Зачем?
Во-первых, мы могли где-то набагать при написании сервиса. Во-вторых, мы можем набагать попозже. И еще есть distribution shift, когда пользователи по-другому начинаются пользоваться системой, и она начинает хуже работать. Про это неплохо написано в моем любимом учебнике по DL.
Литература для обязательного изучения
- Довольно понятная (мне) моя статья. Часть материала пересекается с постом.
- Гайд, как быстро улучшать AI-продукты
- Очень крутая статья про мониторинг и distribution shift
Как всегда, жду вопросы в комментариях или в личных сообщениях.
Дальше будем разбирать методы оценки качества для LLM, готовьтесь.
#llm_system_design
В прошлых 5 публикациях мы поняли, из каких кубиков состоит LLM-система. Сейчас пришло время из них что-то собирать.
А как собирать?
Тема 6. Этапы LLM-проекта
Я делю разработку на 4 этапа:
1) Бизнес постановка
2) Создание прототипа
3) Упрощение протототипа
4) Деплой системы и мониторинг качества
Бизнес постановка
Нам нужны частотные и дорогие задачи. Важно, чтобы была толерантность к ошибкам — близкое к 100% качество у LLM бывает разве что в простой классификации. Классические примеры:
- Бот поддержки клиентов — большой объем, средняя толерантность, средняя стоимость операции
- Copilot для разработчика — средний объем, высокая толерантность (copilot же), высокая стоимость операции
- Автоматизация документооборота— средний объем, средняя толерантность, средняя стоимость операции
Создание прототипа
Проблема подавляющего большинства ИИ-проектов: когда начинается плотная разработка никто не понимает, что надо сделать. И начинают выдумывать на ходу, когда надо не выдумывать, а надо уже делать. Подумать надо было заранее. И все ваше подумывание отразить в прототипе.
Цель прототипа: получить продуктовый ориентир, что наша система должна уметь. При этом там могут быть какие угодно большие модели, он может работать час на запрос и ломаться от промпт-инъекций. Не ругайте его. Он исправится на следующем этапе. Признак успеха этого этапа: человек, который делал бизнес постановку скажет: "вот сделайте такое, только быстро, и я буду счастлив".
Важно: прототип могут и должны собирать люди, которые участвовали в этапе бизнес постановки. Иначе у вас получится опять сферическая LLM в вакууме. Про это читайте пост.
Упрощение протототипа
Здесь сильные технические люди крутят-вертят LLM. Чтобы прототип не стоил, как запуск ракеты Илона Маска.
Большое разнообразие различных вариантов:
1) Дистилляция. Большие модели нужно сжать в модели поменьше. Качество может теряться, но если мы решаем конкретную узкую задачу, должно упасть не сильно. Вот тут подробный разбор метода.
2) Дообучение. Можно не дистиллировать, а просто взять модель поменьше. Но тогда придется их покрутить, так как они справляться будут хуже. Здесь приходит на помощь дообучение (особенно Reinforcement Learning). Вот тут много примеров по дообучению разных LLM разными методами.
3) Работа с контекстом окном. Убирание лишнего из контекста, суммаризация (я пока не устал шутить про контекст-инженера)
4) Оптимизации. Тут отдельный мир: размер батча/квантизация/спекулятивный декодинг. Про это есть отдельная методичка в этом посте.
И еще куча-куча всего. Тут живет мощная LLM-инженерия.
Деплой и мониторинг качества
Здесь происходит классическая разработка. Пишется сервис, в котором работает наша эффективная система. Самое важное: нам нужно контролировать качество этого сервиса. При чем не разово, а постоянно. Зачем?
Во-первых, мы могли где-то набагать при написании сервиса. Во-вторых, мы можем набагать попозже. И еще есть distribution shift, когда пользователи по-другому начинаются пользоваться системой, и она начинает хуже работать. Про это неплохо написано в моем любимом учебнике по DL.
Литература для обязательного изучения
- Довольно понятная (мне) моя статья. Часть материала пересекается с постом.
- Гайд, как быстро улучшать AI-продукты
- Очень крутая статья про мониторинг и distribution shift
Как всегда, жду вопросы в комментариях или в личных сообщениях.
Дальше будем разбирать методы оценки качества для LLM, готовьтесь.
#llm_system_design
4👍26🔥21❤12🙏4❤🔥3🥰1🤩1🐳1
Продолжаем серию о создании надежных LLM-продуктов. Сегодня наконец говорим про метрики качества.
Тема 7. Оцениваем качество LLM
Зачем нам нужно оценивать качество? Не для того, чтобы запустить самый модный алгоритм Reinforcement Learning. Не для того, чтобы запихнуть ошибки в промпт, слезно просив LLM больше так не делать. И даже не для слайдов в презентации.
Хорошие метрики качества == быстрые итерации. В ИИ-разработке, как и в обычной продуктовой разработке, успех зависит от того, как быстро вы умеете итерироваться. В разработке есть тестирование. А у нас есть метрики качества.
Понятно, что вас скорее всего волнуют пользовательские онлайн метрики. Желательно, деньги. Ну или retention пользователей. К сожалению, их долго мерить. Для быстрых итераций нам нужны оффлайн метрики качества, которые как-то аппроксимируют ваш целевой онлайн. Мы верим, что улучшая оффлайн метрики, в итоге наши пользователи будут нам благодарны.
Почему LLM сложно оценивать?
В ИИ есть 3 класса задач. В них по-разному делаются метрики качества.
1) Задачи, в которых есть точный ответ.
Тогда все ваши метрики качества это сравнение ответа модели с эталоном. Например, классификация, где вы сравниваете с правильным классом. Сравнивать можно не обязательно точным совпадением с эталоном. Можно, например, текстовыми метриками (BLEU, WER) или пускай сравнивает отдельная модель, например BERT (bert_score). В этом классе обычно проблем нет.
2) Задачи, в которых ответ можно проверить.
Ну тогда возьмите и проверьте :) Это, в первую очередь, код, который можно прогнать на тестах. Это математика, в которой можно проверить формальное доказательство. В этом классе раньше были проблемы, сейчас современный RL тут всех унижает. Посмотрите сколько компаний выигрывают одну и ту же олимпиаду по математике. Я уже сбился со счета.
3) Задачи, в которых правильный ответ хрен пойми какой.
С этим обычно самые трудности (интересно, блин, почему?)
Делаем RAG-ассистента, человек задает вопрос, мы что-то ответили. Ответить можно миллионом способов, верифицировать нельзя. Здесь обычно делают так:
а) Вырабатывают продуктовые критерии "а что такое хороший ответ"? Наш RAG-ответ должен быть релевантный, достоверный, актуальный.... Записывают эти критерии в виде инструкции.
б) Учат кого-то размечать ответы по этим критерии. Кого можно учить?
Размечаем людьми
Кто-то называет их ИИ-тренерами или асессорами. Популярно объясняете им ваши продуктовые критерии. Это объяснение может быть немного длинным: посмотрите пример 180-страничной инструкции оценки качества поиска Гугла. Дальше показываете им (запрос, ответ) и пускай пробуют разметить.
Важно: контроль качественной разметки это сложная операционная задача. Кто-то может халтурить, читерить, забывать правила. Вам нужно будет отвечать на их вопросы, проводить экзамены, находить плохих разметчиков. И так постоянно.
LLM-as-a-judge
У нас нет денег/времени работать с людьми. Делаем LLM, которая оценивает ответы другой LLM. Критиковать чужой труд всегда проще :)
Обычно делается в несколько этапов
1) Собираем датасет правильных оценок. Это когда у разных ответов LLM проставлены метки: релевантный ли там ответ, достоверный ли ответ и тд. Здесь важно получить не очень большой, (можно 100 примеров) но чистый набор данных.
2) Записываем все наши продуктовые критерии в виде промпта. Он может быть очень длинным, нестрашно.
3) Итеративно меняем модель, промпт, метод генерации и тд, чтобы сделать максимальную точность на датасете 1) Обычно используют максимально большие рассуждающие модели.
Для несложных разметок завести LLM-as-a-judge обычно получается. Для чего-то супер сложного/экспертного, лучше обращаться за помощью к людям.
Литература для обязательного изучения
- Подробный гайд методи оценки качества в LLM
- Наглядная статья с примерами кода для LLM-as-a-judge
- Туториал, как делать LLM-as-a-judge
Правильные метрики — залог вашей счастливой и активной LLM-разработки. Отнеситесь очень внимательно. А если в чем-то сомневаетесь — пишите в комментарии или в личные сообщения @seva_batareika
#llm_system_design
Тема 7. Оцениваем качество LLM
Зачем нам нужно оценивать качество? Не для того, чтобы запустить самый модный алгоритм Reinforcement Learning. Не для того, чтобы запихнуть ошибки в промпт, слезно просив LLM больше так не делать. И даже не для слайдов в презентации.
Хорошие метрики качества == быстрые итерации. В ИИ-разработке, как и в обычной продуктовой разработке, успех зависит от того, как быстро вы умеете итерироваться. В разработке есть тестирование. А у нас есть метрики качества.
Понятно, что вас скорее всего волнуют пользовательские онлайн метрики. Желательно, деньги. Ну или retention пользователей. К сожалению, их долго мерить. Для быстрых итераций нам нужны оффлайн метрики качества, которые как-то аппроксимируют ваш целевой онлайн. Мы верим, что улучшая оффлайн метрики, в итоге наши пользователи будут нам благодарны.
Почему LLM сложно оценивать?
В ИИ есть 3 класса задач. В них по-разному делаются метрики качества.
1) Задачи, в которых есть точный ответ.
Тогда все ваши метрики качества это сравнение ответа модели с эталоном. Например, классификация, где вы сравниваете с правильным классом. Сравнивать можно не обязательно точным совпадением с эталоном. Можно, например, текстовыми метриками (BLEU, WER) или пускай сравнивает отдельная модель, например BERT (bert_score). В этом классе обычно проблем нет.
2) Задачи, в которых ответ можно проверить.
Ну тогда возьмите и проверьте :) Это, в первую очередь, код, который можно прогнать на тестах. Это математика, в которой можно проверить формальное доказательство. В этом классе раньше были проблемы, сейчас современный RL тут всех унижает. Посмотрите сколько компаний выигрывают одну и ту же олимпиаду по математике. Я уже сбился со счета.
3) Задачи, в которых правильный ответ хрен пойми какой.
С этим обычно самые трудности (интересно, блин, почему?)
Делаем RAG-ассистента, человек задает вопрос, мы что-то ответили. Ответить можно миллионом способов, верифицировать нельзя. Здесь обычно делают так:
а) Вырабатывают продуктовые критерии "а что такое хороший ответ"? Наш RAG-ответ должен быть релевантный, достоверный, актуальный.... Записывают эти критерии в виде инструкции.
б) Учат кого-то размечать ответы по этим критерии. Кого можно учить?
Размечаем людьми
Кто-то называет их ИИ-тренерами или асессорами. Популярно объясняете им ваши продуктовые критерии. Это объяснение может быть немного длинным: посмотрите пример 180-страничной инструкции оценки качества поиска Гугла. Дальше показываете им (запрос, ответ) и пускай пробуют разметить.
Важно: контроль качественной разметки это сложная операционная задача. Кто-то может халтурить, читерить, забывать правила. Вам нужно будет отвечать на их вопросы, проводить экзамены, находить плохих разметчиков. И так постоянно.
LLM-as-a-judge
У нас нет денег/времени работать с людьми. Делаем LLM, которая оценивает ответы другой LLM. Критиковать чужой труд всегда проще :)
Обычно делается в несколько этапов
1) Собираем датасет правильных оценок. Это когда у разных ответов LLM проставлены метки: релевантный ли там ответ, достоверный ли ответ и тд. Здесь важно получить не очень большой, (можно 100 примеров) но чистый набор данных.
2) Записываем все наши продуктовые критерии в виде промпта. Он может быть очень длинным, нестрашно.
3) Итеративно меняем модель, промпт, метод генерации и тд, чтобы сделать максимальную точность на датасете 1) Обычно используют максимально большие рассуждающие модели.
Для несложных разметок завести LLM-as-a-judge обычно получается. Для чего-то супер сложного/экспертного, лучше обращаться за помощью к людям.
Литература для обязательного изучения
- Подробный гайд методи оценки качества в LLM
- Наглядная статья с примерами кода для LLM-as-a-judge
- Туториал, как делать LLM-as-a-judge
Правильные метрики — залог вашей счастливой и активной LLM-разработки. Отнеситесь очень внимательно. А если в чем-то сомневаетесь — пишите в комментарии или в личные сообщения @seva_batareika
#llm_system_design
3👍37❤8🔥7🤔2🐳2💯1💘1
Сегодняшнее правило LLM-разработки сэкономит не только месяцы жизни, но и несчетное число нервных клеток. Мне точно сэкономило, хотя, может я просто нервный.
Правило 8. Сначала делайте прототип
Как делают обычно: придумали, как с помощь ИИ увеличить бизнес-метрику. И сразу пошли раздавать задачи инженерам: идите данные собирать да модели обучать. Чтобы метрика побольше стала.
Почему нельзя сразу в бой
1) В ИИ сложно спрогнозировать достижимость эффекта. Легко может оказаться, что текущими технологиями ваша задача не решается с нужным качеством. Но узнаете вы это спустя полгода, когда инженеры вам принесут модель.
2) В ИИ куча краевых случаев. Заранее прописать весь список в техническом задании невозможно. Но спустя полгода вы можете очень удивиться, что модель работает не так, как предполагалось.
Что такое прототип
Это система, которая имеет необходимое качество, но которую нельзя использовать по другим причинам. Например, очень долго работает. Или не проходит по требованиям безопасности. Главное — вам должен нравиться тот результат, который она дает.
Прототип обычно создается на какой-то удобной платформе, типа n8n. Там мы используем самые мощные модели, чтобы получить как можно быстрее ожидаемое качество.
Когда мы сделали прототип, мы переходим на следующий этап. Техническая команда, сохраняя его качество, снимает все другие ограничения. Например, ускоряет модели.
Как создать прототип по шагам
1) Выделенная команда. В ней точно должен быть продакт-менеджер, который понимает, что хочет, бекенд разработчик и специалист, который уже собирал ИИ-системы.
2) Тестовая выборка. В ней для всех входных в систему запросов вся команда точно понимает, какой правильный результат. Команде нужно до этого договориться.
3) Метрики качества на тестовой выборке. Подробнее в прошлом правиле.
4) Итерации на этой выборке, которые максимизируют качество. Итерации вида:
- Взяли самые большие и дорогие модели.
- Провели анализ проблем по выборке. Записали их в эксельку
- Подумали, как это чинить. Покрутить промпт, разбить на подзадачи, добавить RAG и тд.
По этой методике реально собрать рабочий прототип за несколько недель.
Литература для обязательного изучения
- Статья известнейшего специалиста (моя), в ней про это раздел.
- Гайд по быстрым итерациями. Это все нужно использовать на прототипе.
Тема нераспиаренная, но очень важная, полезного контента мало. Если остались вопросы — пишите в комментарии или в личные сообщения.
#llm_system_design
Правило 8. Сначала делайте прототип
Как делают обычно: придумали, как с помощь ИИ увеличить бизнес-метрику. И сразу пошли раздавать задачи инженерам: идите данные собирать да модели обучать. Чтобы метрика побольше стала.
Почему нельзя сразу в бой
1) В ИИ сложно спрогнозировать достижимость эффекта. Легко может оказаться, что текущими технологиями ваша задача не решается с нужным качеством. Но узнаете вы это спустя полгода, когда инженеры вам принесут модель.
2) В ИИ куча краевых случаев. Заранее прописать весь список в техническом задании невозможно. Но спустя полгода вы можете очень удивиться, что модель работает не так, как предполагалось.
Что такое прототип
Это система, которая имеет необходимое качество, но которую нельзя использовать по другим причинам. Например, очень долго работает. Или не проходит по требованиям безопасности. Главное — вам должен нравиться тот результат, который она дает.
Прототип обычно создается на какой-то удобной платформе, типа n8n. Там мы используем самые мощные модели, чтобы получить как можно быстрее ожидаемое качество.
Когда мы сделали прототип, мы переходим на следующий этап. Техническая команда, сохраняя его качество, снимает все другие ограничения. Например, ускоряет модели.
Как создать прототип по шагам
1) Выделенная команда. В ней точно должен быть продакт-менеджер, который понимает, что хочет, бекенд разработчик и специалист, который уже собирал ИИ-системы.
2) Тестовая выборка. В ней для всех входных в систему запросов вся команда точно понимает, какой правильный результат. Команде нужно до этого договориться.
3) Метрики качества на тестовой выборке. Подробнее в прошлом правиле.
4) Итерации на этой выборке, которые максимизируют качество. Итерации вида:
- Взяли самые большие и дорогие модели.
- Провели анализ проблем по выборке. Записали их в эксельку
- Подумали, как это чинить. Покрутить промпт, разбить на подзадачи, добавить RAG и тд.
По этой методике реально собрать рабочий прототип за несколько недель.
Литература для обязательного изучения
- Статья известнейшего специалиста (моя), в ней про это раздел.
- Гайд по быстрым итерациями. Это все нужно использовать на прототипе.
Тема нераспиаренная, но очень важная, полезного контента мало. Если остались вопросы — пишите в комментарии или в личные сообщения.
#llm_system_design
4❤35🔥13👍8❤🔥3✍2🙏1💯1