Я экспериментировал с локальными LLM внутри Salesforce и хотел бы рассказать вам о компоненте, который я разработал в результате. Он имеет уже знакомый интерфейс чата, который использует записи Salesforce для контекста. Он работает локально на вашем компьютере, поэтому обработанные данные не отправляются ни в какой сторонний сервис.
Появление Agentforce повлияло на меня в разработке компонента. Agentforce использует агентов — системы, которые могут принимать решения и выполнять различные действия. Помощники, напротив, обрабатывают информацию только реактивно. Хотя я считаю, что можно создать локального агента с помощью Pico LLM, это потребует огромных усилий. Поэтому я решил разработать помощника.
Функции
Как и ожидалось от LLM, он генерирует ответы по любой теме, поскольку он предварительно обучен на большом наборе данных. Более того, он может использовать записи Salesforce для дополнительного контекста. Возможности компонента:
- Поддерживает несколько моделей. Можно использовать любую модель с открытым исходным кодом с сайта Pico, например Gemma, Llama или Phi. Единственное ограничение — объем оперативной памяти вашего компьютера. Чем больше весит модель, тем больше оперативной памяти она потребляет.
- Работает с одной записью. Когда компонент размещен на странице записи, он может получить доступ к записи для контекста. Например, находясь на странице сведений о записи учетной записи, он может сгенерировать ответ на основе значений своих полей.
- Поддерживает связанные записи. Когда запись имеет связанные записи, компонент может запрашивать и включать их в ответы.
- Настраиваемый. Компонент можно настроить на лету, используя всплывающее окно конфигурации. Он позволяет изменять параметры генерации, такие как предел маркера завершения, температуру и верхний P.
Как это работает
С точки зрения конечного пользователя процесс прост. Вы загружаете модель, выбираете системный запрос, выбираете записи, пишете запрос пользователю и смотрите на полученный результат.
Что такое Pico LLM?
Запуск LLM в браузере — ресурсоемкая задача из-за размера модели, требований к пропускной способности и оперативной памяти. Поэтому команда Pico разработала свою технику сжатия picoLLM, которая делает локальное использование LLM гораздо более эффективным для компьютеров. Они предоставили picoLLM Inference Engine в виде JavaScript SDK, чтобы позволить разработчикам интерфейса запускать LLM локально в разных браузерах. Он поддерживает все современные браузеры, включая Chrome, Safari, Edge, Firefox и Opera. Чтобы узнать больше о том, как работает picoLLM Inference Engine, вы можете прочитать их статью .
Часть LWC
Компонент служит мостом между пользователем и интерфейсом PicoLLM. В основе компонента лежит страница Visualforce, встроенная в iframe. Страница загружает PicoLLM SDK и взаимодействует с LWC, позволяя последнему использовать SDK через сообщения post. Вся комбинация элементов обрабатывает следующее:
- Загрузка модели. В LWC есть кнопка, которая позволяет вам загрузить модель по вашему выбору. Она запускает элемент ввода файла, скрытый внутри iframe. После загрузки модели Pico SDK создает веб-воркеров, и компонент готов к обработке пользовательского ввода.
- Установка системного приглашения. Вам не нужно писать системное приглашение каждый раз, легко выбрать любую сохраненную запись объекта
System_Prompt__c
. После нажатия кнопки отображается всплывающее окно с существующими системными приглашениями для выбора. - Прием пользовательского ввода. Для сбора пользовательского ввода имеется текстовая область с изменяемым размером. После сбора данные отправляются в iframe в качестве полезной нагрузки и добавляются в историю разговоров.
- Доступ к записям Salesforce. Есть две кнопки: Select Fields и Select Related Records. Первая собирает значения полей записи на странице записи, на которой находится LWC. Вторая позволяет выбрать связанный объект и запросить его записи вместе с выбранными значениями полей. Эта информация также отправляется в iframe в качестве полезной нагрузки.
- Изменение параметров генерации. При желании можно изменить предел маркера завершения, температуру и верхние параметры P с помощью специальной кнопки в компоненте. Эта информация также отправляется в качестве полезной нагрузки в iframe.
- Генерация результата. Когда iframe получает полезную нагрузку, он использует Pico SDK для использования загруженной модели и генерации результата. Если были предоставлены параметры генерации, они учитываются. Кроме того, диалоговое окно обновляется каждый раз, поэтому LLM запомнит его историю.
- Отображение сообщений чата. LWC может отображать исходящие сообщения, которые предоставляет пользователь. Входящие сообщения, содержащие сгенерированный ответ, отображаются динамически, как только компоненту нужно что-то сказать пользователю. Например, сгенерированные результаты или информация и сообщения об ошибках.
Немного кода Apex
На стороне бэкенда нет ничего необычного. Код Apex делает всю тяжелую работу, связанную с обнаружением связей между объектами, используя идентификатор записи со страницы записи. Кроме того, он выполняет несколько запросов SOQL, и, таким образом, его задача здесь выполнена.
Проблемы развития
Веб-работники
Ранее я использовал инструмент unpkg для выполнения кода из модуля узла в компоненте LWC. Этот подход привел к дополнительным шагам настройки и был менее безопасным способом заставить его работать. На этот раз я хотел выполнить модуль PicoLLM напрямую из Salesforce и не только с сайта Experience Cloud, как я делал ранее, но и из интерфейса Lightning Experience.
Под капотом PicoLLM использует веб-воркеров для параллельной обработки, и это было главной проблемой, потому что запускать их из LWC не разрешалось. К счастью, никто не запретил нам запускать веб-воркеров со страницы visualforce, и это был подход, который я использовал.
Я загрузил исходный код PicoLLM и добавил его как статический ресурс на страницу visualforce. В LWC я использовал iframe, содержащий страницу visualforce. Связь между LWC и страницей внутри iframe позволила мне использовать веб-воркеры. Страница запускает код, связанный с PicoLLM, из веб-компонента lightning.
Использование записей Salesforce для контекста
Копируйте и вставляйте записи Salesforce в формате JSON или CSV, загружайте в любой онлайн-LLM и смотрите. Он будет использовать записи, использовать их для дополнительного контекста и генерировать ответ. Оказалось, что это не так просто при использовании сжатых моделей для локальной обработки.
Сначала я просто помещал записи в формате JSON прямо в приглашение пользователя. Затем я ожидал, что эта штука будет достаточно умной, чтобы отличить само приглашение от дополнительного контекста, который я предоставил. Я использовал разные модели разных размеров и не понимал, почему она не использует JSON для генерации ответов. В основном это были отказы отвечать на мое приглашение или генерация вымышленных данных, не связанных с тем, что я просил ее сделать. Я начал экспериментировать с разными форматами данных контекста: с использованием CSV, с использованием JSON, с использованием разделителей приглашений для строгого отделения приглашения от контекста — ничего не помогало.
Я почти отказался от этой идеи, потому что ключевая функция не работала. Через пару месяцев меня внезапно осенило до глупости. Что, если я просто поменяю порядок частей подсказки? От подсказки пользователя, которая идет первой, и контекста, идущего вторым, к контексту, идущему первым, и подсказке, идущему вторым. К моему удивлению, это сработало, и любая модель, которую я использовал, немедленно начала понимать записи Salesforce как контекст.
Производительность
Функциональность компонента была протестирована на следующих машинах:
- ПК с процессором AMD Ryzen 9 9900X и 32 ГБ оперативной памяти (5600 МТ/с).
- Ноутбук Microsoft Surface 7 на базе процессора Snapdragon X-Elite ARM с 16 ГБ оперативной памяти (8448 МТ/с).
Скорость загрузки модели — все дело в памяти
Самая трудоемкая часть использования компонента — начальная загрузка модели. Вы могли бы ожидать, что 9900X легко превзойдет Snapdragon X-Elite, но вы ошибаетесь. К моему удивлению, последний быстрее. Поскольку у него более быстрая память, я предполагаю, что чем быстрее ваша оперативная память, тем быстрее загружается модель. Вот сравнительная таблица скорости загрузки моделей для справки:
Скорость генерации ответа
Та же история со скоростью генерации ответа. Насколько я понимаю, для максимально быстрой генерации нужно иметь быстрое сочетание ЦП и ОЗУ. Поскольку генерация ответа меняется в зависимости от одного и того же запроса, я не проводил точных тестов скорости. Тем не менее, скорость генерации чрезвычайно высокая, почти такая же, как у онлайн-альтернатив.
А как насчет использования графического процессора?
Действительно, использование GPU для генерации ответов было бы намного эффективнее. Хотя возможно использовать GPU с PicoLLM, я сам не тестировал эту конфигурацию. Для этого есть несколько причин. Во-первых, я считаю, что он использует функцию WebGPU, которая по умолчанию не включена в большинстве браузеров (кроме Edge). Во-вторых, для загрузки модели, вероятно, требуется несколько гигабайт VRAM, которой у меня нет.
Заключение
Разработка этого помощника стала увлекательным путешествием исследований. От борьбы с ограничениями веб-работника до открытия решающей роли быстрого заказа в предоставлении контекста, задачи были и стимулирующими, и полезными. Результатом стал компонент Lightning Web, который предлагает уникальный подход к использованию мощи больших языковых моделей в экосистеме Salesforce.
Хотя начальное время загрузки модели может быть важным фактором, особенно для более крупных моделей, возможность локальной обработки данных дает значительные преимущества с точки зрения безопасности данных, оперативности и экономической эффективности. Потенциальные варианты использования, от автоматизации генерации контента до предоставления интеллектуальной помощи, обширны и ждут своего изучения.
Ознакомьтесь с репозиторием GitHub .