1. Введение
Последнее обновление: 05.02.2024
Что такое генеративный искусственный интеллект?
Генеративный ИИ, или генеративный искусственный интеллект, — это использование ИИ для создания нового контента, такого как текст, изображения, музыка, аудио и видео.
Генеративный ИИ основан на базовых моделях (больших моделях ИИ), которые могут выполнять многозадачные операции и осваивать готовые решения, включая суммаризацию, ответы на вопросы, классификацию и многое другое. Кроме того, благодаря минимальному объему необходимого обучения, базовые модели могут быть адаптированы для целевых задач с очень небольшим количеством примеров данных.
Как работает генеративный искусственный интеллект?
Генеративный ИИ работает, используя модель машинного обучения (ML) для изучения закономерностей и взаимосвязей в наборе данных, созданном людьми. Затем он использует изученные закономерности для генерации нового контента.
Наиболее распространенный способ обучения модели генеративного ИИ — это использование обучения с учителем: модели предоставляется набор созданного человеком контента и соответствующие метки. Затем она учится генерировать контент, похожий на созданный человеком контент и помеченный теми же метками.
Какие существуют распространенные области применения генеративного искусственного интеллекта?
Генеративный ИИ обрабатывает огромные объемы контента, создавая аналитические данные и ответы на основе текста, изображений и удобных для пользователя форматов. Генеративный ИИ может использоваться для:
- Улучшите взаимодействие с клиентами за счет усовершенствованных функций чата и поиска.
- Изучайте огромные массивы неструктурированных данных с помощью диалоговых интерфейсов и кратких обзоров.
- Оказание помощи в выполнении рутинных задач, таких как ответы на запросы предложений (RFP), локализация маркетингового контента на пять языков, проверка договоров с клиентами на соответствие требованиям и многое другое.
Какие решения в области генеративного искусственного интеллекта предлагает Google Cloud?
С Vertex AI вы можете взаимодействовать с базовыми моделями, настраивать их и встраивать в свои приложения — при этом практически не требуется никаких знаний в области машинного обучения. Получайте доступ к базовым моделям в Model Garden , настраивайте модели с помощью простого пользовательского интерфейса в Generative AI Studio или используйте модели в блокноте для анализа данных.
Vertex AI Search and Conversation предлагает разработчикам самый быстрый способ создания поисковых систем и чат-ботов на основе генеративного искусственного интеллекта.
А Duet AI — это ваш помощник на основе искусственного интеллекта, доступный в Google Cloud и IDE, который поможет вам быстрее и эффективнее выполнять больше задач.
На чём сосредоточено внимание в этом практическом занятии?
Данный практический семинар посвящен модели PaLM 2 Large Language Model (LLM), размещенной на платформе Google Cloud Vertex AI и включающей в себя все продукты и услуги машинного обучения.
Вы будете использовать Java для взаимодействия с API PaLM в сочетании с оркестратором фреймворка LangChain4J LLM. Вы рассмотрите различные конкретные примеры, чтобы использовать преимущества LLM для ответов на вопросы, генерации идей, извлечения сущностей и структурированного контента, а также для составления резюме.
Расскажите подробнее о фреймворке LangChain4J!
Фреймворк LangChain4J — это библиотека с открытым исходным кодом для интеграции больших языковых моделей в ваши Java-приложения, которая объединяет различные компоненты, такие как сама LLM, а также другие инструменты, например, векторные базы данных (для семантического поиска), загрузчики и разделители документов (для анализа документов и обучения на их основе), парсеры выходных данных и многое другое.

Что вы узнаете
- Как настроить Java-проект для использования PaLM и LangChain4J
- Как извлечь полезную информацию из неструктурированного контента (извлечение сущностей или ключевых слов, вывод в формате JSON)
- Как создать диалог с пользователями
- Как использовать модель чата для задавания вопросов по собственной документации
Что вам понадобится
- Знание языка программирования Java.
- Проект Google Cloud
- Браузер, например Chrome или Firefox.
2. Настройка и требования
Настройка среды для самостоятельного обучения
- Войдите в консоль Google Cloud и создайте новый проект или используйте существующий. Если у вас еще нет учетной записи Gmail или Google Workspace, вам необходимо ее создать .



- Название проекта — это отображаемое имя участников данного проекта. Это строка символов, не используемая API Google. Вы всегда можете его изменить.
- Идентификатор проекта уникален для всех проектов Google Cloud и является неизменяемым (его нельзя изменить после установки). Консоль Cloud автоматически генерирует уникальную строку; обычно вам неважно, какая она. В большинстве практических заданий вам потребуется указать идентификатор вашего проекта (обычно обозначается как
PROJECT_ID). Если сгенерированный идентификатор вас не устраивает, вы можете сгенерировать другой случайный идентификатор. В качестве альтернативы вы можете попробовать свой собственный и посмотреть, доступен ли он. После этого шага его нельзя изменить, и он сохраняется на протяжении всего проекта. - К вашему сведению, существует третье значение — номер проекта , которое используется некоторыми API. Подробнее обо всех трех значениях можно узнать в документации .
- Далее вам потребуется включить оплату в консоли Cloud для использования ресурсов/API Cloud. Выполнение этого практического задания не потребует больших затрат, если вообще потребует. Чтобы отключить ресурсы и избежать дополнительных расходов после завершения этого урока, вы можете удалить созданные ресурсы или удалить проект. Новые пользователи Google Cloud имеют право на бесплатную пробную версию стоимостью 300 долларов США .
Запустить Cloud Shell
Хотя Google Cloud можно управлять удаленно с ноутбука, в этом практическом занятии вы будете использовать Cloud Shell — среду командной строки, работающую в облаке.
Активировать Cloud Shell
- В консоли Cloud нажмите «Активировать Cloud Shell» .
.

Если вы запускаете Cloud Shell впервые, вам будет показан промежуточный экран с описанием его возможностей. Если вам был показан промежуточный экран, нажмите «Продолжить» .

Подготовка и подключение к Cloud Shell займут всего несколько минут.

Эта виртуальная машина оснащена всеми необходимыми инструментами разработки. Она предоставляет постоянный домашний каталог объемом 5 ГБ и работает в облаке Google, что значительно повышает производительность сети и аутентификацию. Большая часть, если не вся, ваша работа в этом практическом задании может быть выполнена с помощью браузера.
После подключения к Cloud Shell вы увидите, что прошли аутентификацию и что проект настроен на ваш идентификатор проекта.
- Выполните следующую команду в Cloud Shell, чтобы подтвердить свою аутентификацию:
gcloud auth list
вывод команды
Credentialed Accounts
ACTIVE ACCOUNT
* <my_account>@<my_domain.com>
To set the active account, run:
$ gcloud config set account `ACCOUNT`
- Выполните следующую команду в Cloud Shell, чтобы убедиться, что команда gcloud знает о вашем проекте:
gcloud config list project
вывод команды
[core] project = <PROJECT_ID>
Если это не так, вы можете установить это с помощью следующей команды:
gcloud config set project <PROJECT_ID>
вывод команды
Updated property [core/project].
3. Подготовка среды разработки
В этом практическом занятии вы будете использовать терминал Cloud Shell и редактор кода для разработки своих программ на Java.
Включите API Vertex AI
- В консоли Google Cloud убедитесь, что название вашего проекта отображается в верхней части окна . Если это не так, нажмите «Выбрать проект» , чтобы открыть окно выбора проекта , и выберите нужный проект.
- Если вы не находитесь в разделе Vertex AI консоли Google Cloud, выполните следующие действия:
- В поле «Поиск» введите Vertex AI, затем нажмите Enter.
- В результатах поиска нажмите на Vertex AI. Откроется панель управления Vertex AI.
- На панели управления Vertex AI нажмите «Включить все рекомендуемые API» .
Это позволит активировать несколько API, но наиболее важным для практического занятия является aiplatform.googleapis.com , который также можно включить в командной строке терминала Cloud Shell, выполнив следующую команду:
$ gcloud services enable aiplatform.googleapis.com
Создание структуры проекта с помощью Gradle
Для сборки примеров кода на Java вам понадобится инструмент сборки Gradle и версия Java 17. Чтобы настроить проект с помощью Gradle, в терминале Cloud Shell создайте каталог (в данном случае palm-workshop ) и выполните команду gradle init в этом каталоге:
$ mkdir palm-workshop $ cd palm-workshop $ gradle init Select type of project to generate: 1: basic 2: application 3: library 4: Gradle plugin Enter selection (default: basic) [1..4] 2 Select implementation language: 1: C++ 2: Groovy 3: Java 4: Kotlin 5: Scala 6: Swift Enter selection (default: Java) [1..6] 3 Split functionality across multiple subprojects?: 1: no - only one application project 2: yes - application and library projects Enter selection (default: no - only one application project) [1..2] 1 Select build script DSL: 1: Groovy 2: Kotlin Enter selection (default: Groovy) [1..2] 1 Generate build using new APIs and behavior (some features may change in the next minor release)? (default: no) [yes, no] Select test framework: 1: JUnit 4 2: TestNG 3: Spock 4: JUnit Jupiter Enter selection (default: JUnit Jupiter) [1..4] 4 Project name (default: palm-workshop): Source package (default: palm.workshop): > Task :init Get more help with your project: https://docs.gradle.org/7.4/samples/sample_building_java_applications.html BUILD SUCCESSFUL in 51s 2 actionable tasks: 2 executed
Вы будете создавать приложение (вариант 2), используя язык Java (вариант 3), без использования подпроектов (вариант 1), используя синтаксис Groovy для файла сборки (вариант 1), не используя новые функции сборки (вариант нет), генерируя тесты с помощью JUnit Jupiter (вариант 4), а в качестве имени проекта можно использовать palm-workshop , и аналогично для исходного пакета можно использовать palm.workshop .
Структура проекта будет выглядеть следующим образом:
├── gradle
│ └── ...
├── gradlew
├── gradlew.bat
├── settings.gradle
└── app
├── build.gradle
└── src
├── main
│ └── java
│ └── palm
│ └── workshop
│ └── App.java
└── test
└── ...
Давайте обновим файл app/build.gradle , добавив необходимые зависимости. Вы можете удалить зависимость guava , если она присутствует, и заменить её зависимостями проекта LangChain4J и библиотеки логирования, чтобы избежать назойливых сообщений об отсутствии логгера:
dependencies {
// Use JUnit Jupiter for testing.
testImplementation 'org.junit.jupiter:junit-jupiter:5.8.1'
// Logging library
implementation 'org.slf4j:slf4j-jdk14:2.0.9'
// This dependency is used by the application.
implementation 'dev.langchain4j:langchain4j-vertex-ai:0.24.0'
implementation 'dev.langchain4j:langchain4j:0.24.0'
}
Для LangChain4J существует 2 зависимости:
- один из основных проектов,
- и еще один для специализированного модуля Vertex AI.
Для использования Java 17 при компиляции и запуске наших программ добавьте следующий блок после блока plugins {} `:
java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}
Ещё одно изменение: обновить блок application в файле app/build.gradle , чтобы пользователи могли переопределять основной класс для запуска из командной строки при вызове инструмента сборки:
application {
mainClass = providers.systemProperty('javaMainClass')
.orElse('palm.workshop.App')
}
Чтобы убедиться, что ваш файл сборки готов к запуску приложения, вы можете запустить основной класс по умолчанию, который выводит простое сообщение Hello World! :
$ ./gradlew run -DjavaMainClass=palm.workshop.App > Task :app:run Hello World! BUILD SUCCESSFUL in 3s 2 actionable tasks: 2 executed
Теперь вы готовы программировать с использованием текстовой модели большого языка PaLM, применяя проект LangChain4J!
Для справки, вот как теперь должен выглядеть полный файл сборки app/build.gradle :
plugins {
// Apply the application plugin to add support for building a CLI application in Java.
id 'application'
}
java {
toolchain {
// Ensure we compile and run on Java 17
languageVersion = JavaLanguageVersion.of(17)
}
}
repositories {
// Use Maven Central for resolving dependencies.
mavenCentral()
}
dependencies {
// Use JUnit Jupiter for testing.
testImplementation 'org.junit.jupiter:junit-jupiter:5.8.1'
// This dependency is used by the application.
implementation 'dev.langchain4j:langchain4j-vertex-ai:0.24.0'
implementation 'dev.langchain4j:langchain4j:0.24.0'
implementation 'org.slf4j:slf4j-jdk14:2.0.9'
}
application {
mainClass = providers.systemProperty('javaMainClass').orElse('palm.workshop.App')
}
tasks.named('test') {
// Use JUnit Platform for unit tests.
useJUnitPlatform()
}
4. Совершение первого звонка в чат-модель PaLM.
Теперь, когда проект должным образом настроен, пришло время обратиться к API PaLM.
Создайте новый класс с именем ChatPrompts.java в каталоге app/src/main/java/palm/workshop (рядом со стандартным классом App.java ) и введите следующее содержимое:
package palm.workshop;
import dev.langchain4j.model.vertexai.VertexAiChatModel;
import dev.langchain4j.chain.ConversationalChain;
public class ChatPrompts {
public static void main(String[] args) {
VertexAiChatModel model = VertexAiChatModel.builder()
.endpoint("us-central1-aiplatform.googleapis.com:443")
.project("YOUR_PROJECT_ID")
.location("us-central1")
.publisher("google")
.modelName("chat-bison@001")
.maxOutputTokens(400)
.maxRetries(3)
.build();
ConversationalChain chain = ConversationalChain.builder()
.chatLanguageModel(model)
.build();
String message = "What are large language models?";
String answer = chain.execute(message);
System.out.println(answer);
System.out.println("---------------------------");
message = "What can you do with them?";
answer = chain.execute(message);
System.out.println(answer);
System.out.println("---------------------------");
message = "Can you name some of them?";
answer = chain.execute(message);
System.out.println(answer);
}
}
В первом примере вам необходимо импортировать класс VertexAiChatModel и класс LangChain4J ConversationalChain , чтобы упростить обработку многоходового аспекта диалогов.
Далее, в main методе, вы настроите языковую модель чата, используя построитель для VertexAiChatModel , чтобы указать:
- конечная точка,
- проект,
- регион,
- издатель,
- и название модели (
chat-bison@001).
Теперь, когда языковая модель готова, вы можете подготовить ConversationalChain . Это абстракция более высокого уровня, предлагаемая LangChain4J, позволяющая настраивать различные компоненты для обработки диалога, например, саму языковую модель чата, а также, возможно, другие компоненты для обработки истории диалога или для подключения других инструментов, таких как средства получения информации из векторных баз данных. Но не волнуйтесь, мы вернемся к этому позже в этом практическом занятии.
Затем вы будете вести многоходовую беседу с моделью чата, задавая несколько взаимосвязанных вопросов. Сначала вы интересуетесь программами магистратуры в области прикладных наук (LLM), затем спрашиваете, что с ними можно делать и какие есть примеры их применения. Обратите внимание, что вам не нужно повторяться, программа LLM понимает, что «они» в контексте этой беседы означает программы LLM.
Чтобы обработать многоэтапный диалог, достаточно вызвать метод execute() в цепочке, он добавит его в контекст разговора, модель чата сгенерирует ответ и добавит его в историю чата.
Для запуска этого занятия выполните следующую команду в терминале Cloud Shell:
./gradlew run -DjavaMainClass=palm.workshop.ChatPrompts
Вы должны увидеть результат, похожий на этот:
$ ./gradlew run -DjavaMainClass=palm.workshop.ChatPrompts Starting a Gradle Daemon, 2 incompatible and 2 stopped Daemons could not be reused, use --status for details > Task :app:run Large language models (LLMs) are artificial neural networks that are trained on massive datasets of text and code. They are designed to understand and generate human language, and they can be used for a variety of tasks, such as machine translation, question answering, and text summarization. --------------------------- LLMs can be used for a variety of tasks, such as: * Machine translation: LLMs can be used to translate text from one language to another. * Question answering: LLMs can be used to answer questions posed in natural language. * Text summarization: LLMs can be used to summarize text into a shorter, more concise form. * Code generation: LLMs can be used to generate code, such as Python or Java code. * Creative writing: LLMs can be used to generate creative text, such as poems, stories, and scripts. LLMs are still under development, but they have the potential to revolutionize a wide range of industries. For example, LLMs could be used to improve customer service, create more personalized marketing campaigns, and develop new products and services. --------------------------- Some of the most well-known LLMs include: * GPT-3: Developed by OpenAI, GPT-3 is a large language model that can generate text, translate languages, write different kinds of creative content, and answer your questions in an informative way. * LaMDA: Developed by Google, LaMDA is a large language model that can chat with you in an open-ended way, answering your questions, telling stories, and providing different kinds of creative content. * PaLM 2: Developed by Google, PaLM 2 is a large language model that can perform a wide range of tasks, including machine translation, question answering, and text summarization. * T5: Developed by Google, T5 is a large language model that can be used for a variety of tasks, including text summarization, question answering, and code generation. These are just a few examples of the many LLMs that are currently being developed. As LLMs continue to improve, they are likely to play an increasingly important role in our lives. BUILD SUCCESSFUL in 25s 2 actionable tasks: 2 executed
PaLM ответил на ваши 3 связанных вопроса!
Конструктор VertexAIChatModel позволяет определять необязательные параметры, для которых уже существуют значения по умолчанию, которые можно переопределить. Вот несколько примеров:
-
.temperature(0.2)— определяет, насколько креативным вы хотите получить ответ (0 означает низкую креативность и, как правило, более фактологический ответ, а 1 — более креативный). -
.maxOutputTokens(50)— в примере было запрошено 400 токенов (3 токена примерно эквивалентны 4 словам), в зависимости от того, какой длины должен быть сгенерированный ответ. -
.topK(20)— случайным образом выбрать слово из максимального числа вероятных слов для завершения текста (от 1 до 40) -
.topP(0.95)— выбирает возможные слова, сумма вероятностей которых равна этому числу с плавающей запятой (от 0 до 1). -
.maxRetries(3)— если вы превышаете квоту запросов за раз, вы можете, например, заставить модель повторить вызов 3 раза.
5. Полезный чат-бот с индивидуальностью!
В предыдущем разделе вы сразу же начали задавать вопросы чат-боту LLM, не предоставляя ему никакого конкретного контекста. Но вы можете специализировать такого чат-бота, чтобы он стал экспертом в определенной задаче или по определенной теме.
Как это сделать? Подготовив почву: объяснив LLM задачу, контекст, возможно, приведя несколько примеров того, что он должен делать, какой у него должен быть профиль, в каком формате вы хотели бы получать ответы и, возможно, тон, если вы хотите, чтобы чат-бот вел себя определенным образом.
В этой статье о создании подсказок этот подход хорошо иллюстрируется следующей графической схемой:

https://medium.com/@eldatero/master-the-perfect-chatgpt-prompt-formula-c776adae8f19
Чтобы проиллюстрировать это, давайте вдохновимся сайтом prompts.chat , где представлено множество замечательных и интересных идей для создания чат-ботов, которые будут выполнять следующие функции:
- Переводчик эмодзи — для перевода сообщений пользователей в эмодзи.
- Улучшение подсказок — для создания более качественных подсказок
- рецензент для научных журналов — для помощи в рецензировании научных статей.
- Персональный стилист — для получения рекомендаций по стилю одежды.
Вот один пример того, как превратить чат-бота, имеющего степень магистра права, в шахматиста ! Давайте это реализуем!
Обновите класс ChatPrompts следующим образом:
package palm.workshop;
import dev.langchain4j.chain.ConversationalChain;
import dev.langchain4j.data.message.SystemMessage;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.model.vertexai.VertexAiChatModel;
import dev.langchain4j.store.memory.chat.InMemoryChatMemoryStore;
public class ChatPrompts {
public static void main(String[] args) {
VertexAiChatModel model = VertexAiChatModel.builder()
.endpoint("us-central1-aiplatform.googleapis.com:443")
.project("YOUR_PROJECT_ID")
.location("us-central1")
.publisher("google")
.modelName("chat-bison@001")
.maxOutputTokens(7)
.maxRetries(3)
.build();
InMemoryChatMemoryStore chatMemoryStore = new InMemoryChatMemoryStore();
MessageWindowChatMemory chatMemory = MessageWindowChatMemory.builder()
.chatMemoryStore(chatMemoryStore)
.maxMessages(200)
.build();
chatMemory.add(SystemMessage.from("""
You're an expert chess player with a high ELO ranking.
Use the PGN chess notation to reply with the best next possible move.
"""
));
ConversationalChain chain = ConversationalChain.builder()
.chatLanguageModel(model)
.chatMemory(chatMemory)
.build();
String pgn = "";
String[] whiteMoves = { "Nf3", "c4", "Nc3", "e3", "Dc2", "Cd5"};
for (int i = 0; i < whiteMoves.length; i++) {
pgn += " " + (i+1) + ". " + whiteMoves[i];
System.out.println("Playing " + whiteMoves[i]);
pgn = chain.execute(pgn);
System.out.println(pgn);
}
}
}
Давайте разберем это шаг за шагом:
- Для управления памятью чата необходимы новые импорты.
- Вы создаете экземпляр модели чата, но с небольшим максимальным количеством токенов (здесь 7), поскольку нам нужно только сгенерировать следующий ход, а не целую диссертацию о шахматах!
- Далее вы создаете хранилище памяти чата для сохранения переписки.
- Вы создаёте оконную память чата, чтобы сохранить последние ходы.
- В память чата вы добавляете «системное» сообщение, которое указывает модели чата, кем она должна быть (например, опытным шахматистом). «Системное» сообщение добавляет некоторый контекст, тогда как сообщения «пользователя» и «ИИ» представляют собой собственно обсуждение.
- Вы создаёте цепочку диалогов, которая объединяет модель памяти и модель чата.
- Затем у нас есть список ходов белых, по которому вы перебираете варианты. Цепочка каждый раз выполняется следующим ходом белых, и модель чата отвечает следующим наилучшим ходом.
При запуске этого класса с указанными действиями вы должны увидеть следующий результат:
$ ./gradlew run -DjavaMainClass=palm.workshop.ChatPrompts Starting a Gradle Daemon (subsequent builds will be faster) > Task :app:run Playing Nf3 1... e5 Playing c4 2... Nc6 Playing Nc3 3... Nf6 Playing e3 4... Bb4 Playing Dc2 5... O-O Playing Cd5 6... exd5
Ух ты! PaLM умеет играть в шахматы? Ну, не совсем, но во время обучения модель, должно быть, видела комментарии к шахматным партиям или даже файлы PGN (Portable Game Notation) прошлых игр. Однако этот чат-бот, скорее всего, не выиграет у AlphaZero (ИИ, который побеждает лучших игроков в го, сёги и шахматы), и разговор может зайти в тупик, поскольку модель не будет помнить фактическое состояние игры.
Модели чата очень мощные и позволяют создавать насыщенные взаимодействия с пользователями, а также обрабатывать различные контекстные задачи. В следующем разделе мы рассмотрим полезную задачу: извлечение структурированных данных из текста .
6. Извлечение информации из неструктурированного текста
В предыдущем разделе вы создавали диалоги между пользователем и языковой моделью чата. Но с помощью LangChain4J вы также можете использовать модель чата для извлечения структурированной информации из неструктурированного текста.
Допустим, вам нужно извлечь имя и возраст человека, имея биографию или описание этого человека. Вы можете указать большой языковой модели сгенерировать структуры данных JSON с помощью грамотно настроенного запроса (это обычно называется «инженерным проектированием запросов» ).
Вам необходимо обновить класс ChatPrompts следующим образом:
package palm.workshop;
import dev.langchain4j.model.vertexai.VertexAiChatModel;
import dev.langchain4j.service.AiServices;
import dev.langchain4j.service.UserMessage;
public class ChatPrompts {
static class Person {
String name;
int age;
}
interface PersonExtractor {
@UserMessage("""
Extract the name and age of the person described below.
Return a JSON document with a "name" and an "age" property, \
following this structure: {"name": "John Doe", "age": 34}
Return only JSON, without any markdown markup surrounding it.
Here is the document describing the person:
---
{{it}}
---
JSON:
""")
Person extractPerson(String text);
}
public static void main(String[] args) {
VertexAiChatModel model = VertexAiChatModel.builder()
.endpoint("us-central1-aiplatform.googleapis.com:443")
.project("YOUR_PROJECT_ID")
.location("us-central1")
.publisher("google")
.modelName("chat-bison@001")
.maxOutputTokens(300)
.build();
PersonExtractor extractor = AiServices.create(PersonExtractor.class, model);
Person person = extractor.extractPerson("""
Anna is a 23 year old artist based in Brooklyn, New York. She was born and
raised in the suburbs of Chicago, where she developed a love for art at a
young age. She attended the School of the Art Institute of Chicago, where
she studied painting and drawing. After graduating, she moved to New York
City to pursue her art career. Anna's work is inspired by her personal
experiences and observations of the world around her. She often uses bright
colors and bold lines to create vibrant and energetic paintings. Her work
has been exhibited in galleries and museums in New York City and Chicago.
"""
);
System.out.println(person.name);
System.out.println(person.age);
}
}
Давайте рассмотрим различные этапы, описанные в этом файле:
- Класс
Personпредназначен для представления подробных сведений о человеке (его имя и возраст). - Интерфейс
PersonExtractorсоздан с использованием метода, который, получив на вход неструктурированную текстовую строку, возвращает экземпляр объектаPerson. - Метод
extractPerson()аннотирован аннотацией@UserMessage, которая связывает с ним подсказку. Именно эту подсказку модель будет использовать для извлечения информации и возврата данных в виде JSON-документа, который будет проанализирован и десериализован в экземплярPerson.
Теперь давайте посмотрим на содержимое метода main() :
- Модель чата создана.
- Объект
PersonExtractorсоздается благодаря классуAiServicesиз библиотеки LangChain4J. - Затем вы можете просто вызвать метод
Person person = extractor.extractPerson(...)чтобы извлечь данные о человеке из неструктурированного текста и получить в ответ экземплярPersonс именем и возрастом.
Теперь запустите этот класс с помощью следующей команды:
$ ./gradlew run -DjavaMainClass=palm.workshop.ChatPrompts > Task :app:run Anna 23
Да! Это Анна, ей 23 года!
Особый интерес в этом подходе AiServices представляет то, что вы работаете со строго типизированными объектами. Вы не взаимодействуете напрямую с LLM чата. Вместо этого вы работаете с конкретными классами, такими как класс Person, представляющий извлеченную личную информацию, и у вас есть класс PersonExtractor с методом extractPerson() , который возвращает экземпляр Person. Понятие LLM абстрагировано, и как Java-разработчик, вы просто манипулируете обычными классами и объектами.
7. Расширенная генерация данных для поиска информации: общение с вашими врачами.
Вернемся к диалогам. На этот раз вы сможете задавать вопросы о своих документах. Вы создадите чат-бота, способного извлекать релевантную информацию из базы данных выдержек из ваших документов, и эта информация будет использоваться моделью для «обоснования» ответов, вместо того чтобы пытаться генерировать ответы, основанные на обучении. Этот подход называется RAG, или Retrieval Augmented Generation (генерация с расширенным извлечением ).
Вкратце, в методе расширенной генерации информации (Retrieval Augmented Generation) есть две фазы:
- Этап загрузки — Документы загружаются, разбиваются на более мелкие фрагменты, и их векторное представление ( «векторное встраивание» ) сохраняется в «векторной базе данных», способной выполнять семантический поиск.

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

Подготовка документов
В этой новой демонстрации вам предстоит задавать вопросы об архитектуре нейронной сети типа «трансформатор» , разработанной компанией Google, — именно так сегодня реализуются все современные модели обработки больших объемов данных.
Вы можете найти научную статью, описывающую эту архитектуру («Внимание — это все, что вам нужно»), загрузив PDF-файл из интернета с помощью команды wget :
wget -O attention-is-all-you-need.pdf \
https://proceedings.neurips.cc/paper_files/paper/2017/file/3f5ee243547dee91fbd053c1c4a845aa-Paper.pdf
Внедрение цепочки поиска информации в диалоге.
Давайте шаг за шагом рассмотрим, как построить двухэтапный подход, сначала с момента загрузки документа, а затем на этапе обработки запросов, когда пользователи задают вопросы о документе.
Загрузка документов
Первым шагом на этапе загрузки документа является поиск загружаемого PDF-файла и подготовка PdfParser для его чтения:
PdfDocumentParser pdfParser = new PdfDocumentParser();
Document document = pdfParser.parse(
new FileInputStream(new File("/home/YOUR_USER_NAME/palm-workshop/attention-is-all-you-need.pdf")));
Вместо создания обычной языковой модели чата, перед этим вы создадите экземпляр модели «встраивания» . Это особая модель и конечная точка, задача которой — создавать векторные представления фрагментов текста (слов, предложений или даже абзацев).
VertexAiEmbeddingModel embeddingModel = VertexAiEmbeddingModel.builder()
.endpoint("us-central1-aiplatform.googleapis.com:443")
.project("YOUR_PROJECT_ID")
.location("us-central1")
.publisher("google")
.modelName("textembedding-gecko@001")
.maxRetries(3)
.build();
Далее вам потребуется несколько классов для совместной работы, чтобы:
- Загрузите и разделите PDF-документ на части.
- Создайте векторные представления для всех этих фрагментов.
InMemoryEmbeddingStore<TextSegment> embeddingStore =
new InMemoryEmbeddingStore<>();
EmbeddingStoreIngestor storeIngestor = EmbeddingStoreIngestor.builder()
.documentSplitter(DocumentSplitters.recursive(500, 100))
.embeddingModel(embeddingModel)
.embeddingStore(embeddingStore)
.build();
storeIngestor.ingest(document);
EmbeddingStoreRetriever retriever = EmbeddingStoreRetriever.from(embeddingStore, embeddingModel);
Для хранения векторных представлений создается экземпляр InMemoryEmbeddingStore — базы данных векторов, хранящейся в оперативной памяти.
Благодаря классу DocumentSplitters документ разбивается на фрагменты. Он будет разбит на части по 500 символов с перекрытием в 100 символов (при этом следующий фрагмент будет разбит на части, чтобы избежать обрезки слов или предложений).
Хранилище "ingestor" связывает разделитель документов, модель встраивания для вычисления векторов и базу данных векторов в оперативной памяти. Затем метод ingest() позаботится об импорте данных.
Первый этап завершен: документ преобразован в текстовые фрагменты с соответствующими векторными представлениями и сохранен в векторной базе данных.
Задавая вопросы
Пора подготовиться к задаванию вопросов! Для начала разговора можно использовать обычную модель чата:
VertexAiChatModel model = VertexAiChatModel.builder()
.endpoint("us-central1-aiplatform.googleapis.com:443")
.project("YOUR_PROJECT_ID")
.location("us-central1")
.publisher("google")
.modelName("chat-bison@001")
.maxOutputTokens(1000)
.build();
Вам также понадобится класс «retriever» , который будет связывать базу данных векторов (в переменной embeddingStore ) и модель встраивания. Его задача — выполнять запросы к базе данных векторов, вычисляя векторное встраивание для запроса пользователя, чтобы найти похожие векторы в базе данных:
EmbeddingStoreRetriever retriever =
EmbeddingStoreRetriever.from(embeddingStore, embeddingModel);
На этом этапе вы можете создать экземпляр класса ConversationalRetrievalChain (это просто другое название для шаблона Retrieval Augmented Generation):
ConversationalRetrievalChain rag = ConversationalRetrievalChain.builder()
.chatLanguageModel(model)
.retriever(retriever)
.promptTemplate(PromptTemplate.from("""
Answer to the following query the best as you can: {{question}}
Base your answer on the information provided below:
{{information}}
"""
))
.build();
Эта «цепочка» связывает воедино:
- Языковая модель чата , которую вы настроили ранее.
- Программа для извлечения данных сравнивает запрос на векторное представление с векторами, хранящимися в базе данных.
- В шаблоне запроса явно указано, что модель чата должна отвечать, основываясь на предоставленной информации (т. е. на соответствующих фрагментах документации, векторное представление которых аналогично вектору вопроса пользователя).
И теперь вы наконец готовы задать свои вопросы!
String result = rag.execute("What neural network architecture can be used for language models?");
System.out.println(result);
System.out.println("------------");
result = rag.execute("What are the different components of a transformer neural network?");
System.out.println(result);
System.out.println("------------");
result = rag.execute("What is attention in large language models?");
System.out.println(result);
System.out.println("------------");
result = rag.execute("What is the name of the process that transforms text into vectors?");
System.out.println(result);
Запустите программу с помощью:
$ ./gradlew run -DjavaMainClass=palm.workshop.ChatPrompts
В результате вы должны увидеть ответы на ваши вопросы:
The Transformer is a neural network architecture that can be used for language models. It is based solely on attention mechanisms, dispensing with recurrence and convolutions. The Transformer has been shown to outperform recurrent neural networks and convolutional neural networks on a variety of language modeling tasks. ------------ The Transformer is a neural network architecture that can be used for language models. It is based solely on attention mechanisms, dispensing with recurrence and convolutions. The Transformer has been shown to outperform recurrent neural networks and convolutional neural networks on a variety of language modeling tasks. The Transformer consists of an encoder and a decoder. The encoder is responsible for encoding the input sequence into a fixed-length vector representation. The decoder is responsible for decoding the output sequence from the input sequence. The decoder uses the attention mechanism to attend to different parts of the input sequence when generating the output sequence. ------------ Attention is a mechanism that allows a neural network to focus on specific parts of an input sequence. In the context of large language models, attention is used to allow the model to focus on specific words or phrases in a sentence when generating output. This allows the model to generate more relevant and informative output. ------------ The process of transforming text into vectors is called word embedding. Word embedding is a technique that represents words as vectors in a high-dimensional space. The vectors are typically learned from a large corpus of text, and they capture the semantic and syntactic relationships between words. Word embedding has been shown to be effective for a variety of natural language processing tasks, such as machine translation, question answering, and sentiment analysis.
Полное решение
Для удобства копирования и вставки, вот полное содержимое класса ChatPrompts :
package palm.workshop;
import dev.langchain4j.chain.ConversationalRetrievalChain;
import dev.langchain4j.data.document.Document;
import dev.langchain4j.data.document.parser.PdfDocumentParser;
import dev.langchain4j.data.document.splitter.DocumentSplitters;
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.model.input.PromptTemplate;
import dev.langchain4j.model.vertexai.VertexAiChatModel;
import dev.langchain4j.model.vertexai.VertexAiEmbeddingModel;
import dev.langchain4j.retriever.EmbeddingStoreRetriever;
import dev.langchain4j.store.embedding.EmbeddingStoreIngestor;
import dev.langchain4j.store.embedding.inmemory.InMemoryEmbeddingStore;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class ChatPrompts {
public static void main(String[] args) throws IOException {
PdfDocumentParser pdfParser = new PdfDocumentParser();
Document document = pdfParser.parse(new FileInputStream(new File("/ABSOLUTE_PATH/attention-is-all-you-need.pdf")));
VertexAiEmbeddingModel embeddingModel = VertexAiEmbeddingModel.builder()
.endpoint("us-central1-aiplatform.googleapis.com:443")
.project("YOUR_PROJECT_ID")
.location("us-central1")
.publisher("google")
.modelName("textembedding-gecko@001")
.maxRetries(3)
.build();
InMemoryEmbeddingStore<TextSegment> embeddingStore =
new InMemoryEmbeddingStore<>();
EmbeddingStoreIngestor storeIngestor = EmbeddingStoreIngestor.builder()
.documentSplitter(DocumentSplitters.recursive(500, 100))
.embeddingModel(embeddingModel)
.embeddingStore(embeddingStore)
.build();
storeIngestor.ingest(document);
EmbeddingStoreRetriever retriever = EmbeddingStoreRetriever.from(embeddingStore, embeddingModel);
VertexAiChatModel model = VertexAiChatModel.builder()
.endpoint("us-central1-aiplatform.googleapis.com:443")
.project("genai-java-demos")
.location("us-central1")
.publisher("google")
.modelName("chat-bison@001")
.maxOutputTokens(1000)
.build();
ConversationalRetrievalChain rag = ConversationalRetrievalChain.builder()
.chatLanguageModel(model)
.retriever(retriever)
.promptTemplate(PromptTemplate.from("""
Answer to the following query the best as you can: {{question}}
Base your answer on the information provided below:
{{information}}
"""
))
.build();
String result = rag.execute("What neural network architecture can be used for language models?");
System.out.println(result);
System.out.println("------------");
result = rag.execute("What are the different components of a transformer neural network?");
System.out.println(result);
System.out.println("------------");
result = rag.execute("What is attention in large language models?");
System.out.println(result);
System.out.println("------------");
result = rag.execute("What is the name of the process that transforms text into vectors?");
System.out.println(result);
}
}
8. Поздравляем!
Поздравляем, вы успешно создали своё первое чат-приложение на основе генеративного ИИ на Java, используя LangChain4J и API PaLM! В процессе работы вы обнаружили, что большие языковые модели для чата довольно мощны и способны справляться с различными задачами, такими как вопросы и ответы, даже с вашей собственной документацией, извлечение данных, и в некоторой степени даже играть в шахматы!
Что дальше?
Ознакомьтесь с приведенными ниже примерами кода, чтобы глубже изучить PaLM в Java:
Дополнительная информация
- Типичные примеры использования генеративного ИИ
- Учебные материалы по генеративному искусственному интеллекту
- Взаимодействуйте с PaLM через студию генеративного искусственного интеллекта.
- Ответственный ИИ