Практическое применение RAG для создания полезных систем Spring AI и OpenAI GPT на основе ваших собственных документов
Практическое использование RAG для создания полезных систем Spring AI и OpenAI GPT на основе ваших собственных документов
Проект AIDocumentLibraryChat использует проект Spring AI с OpenAI для поиска ответов на вопросы в библиотеке документов. Для этого используется Retrieval Augmented Generation на документах.
Retrieval Augmented Generation
Процесс выглядит следующим образом:
Процесс выглядит следующим образом:
- Загрузить документ
- Сохранить документ в базе данных Postgresql.
- Разделить документ для создания вложений.
- Создать вложения с использованием вызова модели вложения OpenAI.
- Сохранить вложения документа в базе данных Postgresql Vector.
Поиск документов:
- Почти все, что вам нужно знать о размере раздела Dask Dataframes
- Метод оптимизации роя частиц процедура поиска, визуализированная
- Руководство по Sklearn Модуль 3
- Создать поисковое подсказку
- Создать вложение поисковой подсказки с использованием вызова модели вложения OpenAI.
- Запросить базу данных Postgresql Vector для документов с наиболее близкими расстояниями вложений.
- Запросить базу данных Postgresql для документа.
- Создать запрос с поисковой подсказкой и фрагментом текста документа.
- Запросить ответ от модели GPT и показать ответ на основе поисковой подсказки и фрагмента текста документа.
Загрузка документа
Загруженный документ хранится в базе данных для нахождения источника ответа. Текст документа должен быть разделен на фрагменты для создания вложений на каждый фрагмент. Вложения создаются моделью вложения OpenAI и представляют собой векторы с более чем 1500 измерениями для представления фрагмента текста. Вложение сохраняется в AI-документе с текстом фрагмента и идентификатором исходного документа в базе данных векторов.
Поиск документов
Поиск документов принимает поисковую подсказку и использует модель вложения Open AI для преобразования ее во вложение. Вложение используется для поиска наиболее близкого вектора в базе данных векторов. Это означает, что ищутся вложения поисковой подсказки и фрагмента текста, которые имеют наибольшую схожесть. Идентификатор в AIDocument используется для чтения документа из реляционной базы данных. С помощью поисковой подсказки и фрагмента текста AIDocument создается запрос. Затем вызывается модель OpenAI GPT с запросом для создания ответа на основе поисковой подсказки и контекста документа. Это позволяет модели создавать ответы, которые тесно основаны на предоставленных документах и улучшают точность. Ответ модели GPT возвращается и отображается с ссылкой на документ для предоставления источника ответа.
Архитектура
Архитектура проекта построена вокруг Spring Boot с использованием Spring AI. Angular UI обеспечивает пользовательский интерфейс для отображения списка документов, загрузки документов и предоставления поисковой подсказки с ответом и исходным документом. Он взаимодействует с бэкэндом Spring Boot через REST-интерфейс. Бэкэнд Spring Boot предоставляет контроллеры REST для фронтенда и использует Spring AI для взаимодействия с моделями OpenAI и базой данных векторов Postgresql. Документы хранятся с использованием Jpa в реляционной базе данных Postgresql. База данных Postgresql используется, потому что она объединяет реляционную базу данных и базу данных векторов в Docker-образе.
Реализация
Фронтенд
Фронтенд основан на лениво загружаемых автономных компонентах, созданных с помощью Angular. Ленивно загружаемые автономные компоненты настраиваются в app.config.ts:
Конфигурация устанавливает маршруты и включает HTTP-клиент и анимации.
Ленивно загружаемые маршруты определены в app.routes.ts:
В ‘loadChildren’ ‘import(“…”).then((mod) => mod.XXX)’ ленивно загружает маршрут из указанного пути и устанавливает экспортируемые маршруты, определенные в константе ‘mod.XXX’.
Ленивно загружаемый маршрут ‘docsearch’ имеет index.ts для экспорта константы:
Который экспортирует doc-search.routes.ts:
Он определяет маршрутизацию до ‘DocSearchComponent’.
Компонент ‘fileupload’ можно найти в DocImportComponent с шаблоном doc-import.component.html:
Загрузка файла происходит с использованием тега ‘<input type=”file” (change)=”onFileInputChange($event)”>’. Он предоставляет возможность загрузки и вызывает метод ‘onFileInputChange(…)’ после каждой загрузки.
Кнопка ‘Upload’ вызывает метод ‘upload()’ для отправки файла на сервер при щелчке.
doc-import.component.ts содержит методы для шаблона:
Это независимый компонент со своими импортами модулей и внедренным ‘DestroyRef’.
Метод ‘onFileInputChange(…)’ принимает параметр события и сохраняет его свойство ‘files’ в константу ‘files’. Затем он проверяет первый файл и сохраняет его в свойстве компонента ‘file’.
Метод ‘upload()’ проверяет свойство ‘file’ и создает ‘FormData()’ для загрузки файла. Константа ‘formData’ имеет тип данных (‘file’), содержимое (‘this.file’) и добавленное имя файла (‘this.file.name’). Затем используется ‘documentService’ для отправки объекта ‘FormData()’ на сервер. Функция ‘takeUntilDestroyed(this.destroyRef)’ отписывается от потока Rxjs после уничтожения компонента. Это делает отписку от потоков очень удобной в Angular.
Backend
Backend – это приложение Spring Boot с использованием фреймворка Spring AI. Spring AI управляет запросами к моделям OpenAI и запросами к векторной базе данных.
Настройка базы данных Liquibase
Настройка базы данных выполняется с помощью Liquibase, и скрипт можно найти в db.changelog-1.xml:
В changeset 4 создается таблица для сущности Jpa документа с первичным ключом ‘id’. Тип/размер содержимого неизвестен и поэтому установлен как ‘blob’. В changeset 5 создается последовательность для сущности Jpa с помощью стандартных свойств Hibernate 6 последовательностей, используемых Spring Boot 3.x.
В changeset 6 создается таблица ‘vector_store’ с первичным ключом ‘id’ типа ‘uuid’, созданным расширением ‘uuid-ossp’. Столбец ‘content’ имеет тип ‘text’ (‘clob’ в других базах данных) и имеет гибкий размер. Столбец ‘metadata’ хранит метаданные для AIDocuments в формате ‘json’. Столбец ’embedding’ хранит вектор вложений с указанием числа измерений OpenAI.
В changeset 7 устанавливается индекс для быстрого поиска столбца ’embeddings’. Из-за ограниченных параметров ‘<createIndex …>’ Liquibase используется переход к созданию индекса с помощью ‘<sql>’.
Реализация Spring Boot / Spring AI
Для фронтенда DocumentController выглядит следующим образом:
‘handleDocumentUpload(…)’ обрабатывает загруженный файл с помощью ‘documentService’ по пути ‘/rest/document/upload’.
‘getDocumentList()’ обрабатывает запросы на получение списка документов и удаляет содержимое документа, чтобы сохранить размер ответа.
‘getDocumentContent(…)’ обрабатывает запросы на получение содержимого документа. Он загружает документ с помощью ‘documentService’ и отображает ‘DocumentType’ в ‘MediaType’. Затем возвращает содержимое, тип содержимого, и браузер открывает содержимое на основе типа содержимого.
Метод ‘postDocumentSearch(…)’ помещает содержимое запроса в объект ‘SearchDto’ и возвращает результат, сгенерированный с помощью искусственного интеллекта в вызове ‘documentService.queryDocuments(…)’.
Метод ‘storeDocument(…)’ DocumentService выглядит следующим образом:
Метод ‘storeDocument(…)’ сохраняет документ в реляционной базе данных. Затем документ преобразуется в ‘ByteArrayResource’ и читается с помощью ‘TikaDocumentReader’ Spring AI, чтобы превратить его в список AIDocument. Затем список AIDocument разбивается на части с помощью метода ‘splitToTokenLimit(…)’, а затем эти части преобразуются в новые AIDocuments с ‘id’ сохраненного документа в карте Metadata. ‘id’ в Metadata позволяет загружать соответствующую документу сущность для AIDocuments. Затем добавляются векторы для AIDocuments неявно с вызовами метода ‘documentVsRepository.add(…)’, который вызывает модель векторного вложения OpenAI и сохраняет AIDocuments с векторами в базе данных векторов. Затем результат возвращается.
Метод ‘queryDocument(…)’ выглядит следующим образом:
В первую очередь метод загружает документы, наиболее подходящие для ‘searchDto.getSearchString()’ из базы данных векторов. Для этого вызывается модель векторного вложения OpenAI, чтобы преобразовать поисковую строку в вложение, и с помощью этого вложения обращаются к базе данных векторов для получения AIDocuments с наименьшим расстоянием (расстояние между векторами поискового вложения и вложениями базы данных). Затем AIDocuments с наименьшим расстоянием сохраняются в переменной ‘mostSimilar’. Затем все AIDocuments частей документа собираются путем сопоставления идентификатора сущности документа из их Metadata ‘id’. ‘systemMessage’ создается с содержимым ‘documentChunks’ или ‘mostSimilar’. Метод ‘getSystemMessage(…)’ берет их и обрезает ‘contentChunks’ до размера, который модели OpenAI GPT могут обработать, и возвращает ‘Message’. Затем ‘systemMessage’ и ‘userMessage’ преобразуются в ‘prompt’, который отправляется с помощью ‘aiClient.generate (prompt)’ модели OpenAi GPT. После этого ответ искусственного интеллекта доступен, и для загрузки сущности документа загружается идентификатор метаданных AIDocument ‘mostSimilar’. Создается ‘AiResult’ с поисковой строкой, ответом GPT, сущностью документа и возвращается.
Репозиторий базы данных векторов DocumentVsRepositoryBean с использованием Spring AI ‘VectorStore’ выглядит следующим образом:
Репозиторий имеет свойство ‘vectorStore’, которое используется для доступа к базе данных векторов. Оно создается в конструкторе с помощью внедряемых параметров при вызове ‘new PgVectorStore(…)’. Класс PgVectorStore представляет расширение векторной базы данных Postgresql. Он имеет ’embeddingClient’, чтобы использовать модель векторного вложения OpenAI, и ‘jdbcTemplate’ для доступа к базе данных.
Метод ‘add(…)’ вызывает модель векторного вложения OpenAI и добавляет AIDocuments в базу данных векторов.
Методы ‘retrieve(…)’ запрашивают базу данных векторов для получения вложений с наименьшими расстояниями.
Заключение
Angular сделал создание фронтенда легким. Стандалонные компоненты с ленивой загрузкой сделали начальную загрузку небольшой. Компоненты Angular Material очень помогли с реализацией и просты в использовании.
Spring Boot с Spring AI сделал использование моделей большого языка удобным. Spring AI предоставляет инструментарий для скрытия создания вложений и предоставляет простой интерфейс для сохранения AIDocuments в базе данных векторов (поддерживается несколько). Создание вложения для поисковой строки для загрузки ближайших AIDocuments также выполняется за вас, и интерфейс базы данных векторов прост. Классы Spring AI prompt также упрощают создание запроса для модели OpenAI GPT. Вызов модели выполняется с помощью внедряемого ‘aiClient’, и результаты возвращаются.
Spring AI – очень хороший фреймворк от команды Spring. Не было никаких проблем с экспериментальной версией.
Благодаря Spring AI использование моделей большого языка на собственных документах стало легким.