Структурированное хранение и разбор вывода LLM с использованием языка Python

Организация структурированного хранения и разбор вывода LLM с использованием Python

Введение

Генеративное искусственное интеллекта в настоящее время широко используется по всему миру. Возможность больших языковых моделей понимать предоставленный текст и создавать текст на его основе привела к многочисленным применениям, от чат-ботов до анализаторов текста. Но часто эти большие языковые модели генерируют текст в своей первоначальной форме, но неструктурированно. Иногда мы хотим, чтобы вывод, сгенерированный ЯММ, был в структурированном формате, скажем, в формате JSON (JavaScript Object Notation). Предположим, мы анализируем сообщение в социальных сетях с помощью LL-моделей , и нам нужен вывод, сгенерированный LL-моделями, внутри кода в формате JSON / переменной Python, чтобы выполнить какую-то другую задачу. Для этого можно использовать технологию Prompt Engineering, но при этом требуется много времени, чтобы настроить подсказки. Для решения этой проблемы LangChain представили Output Parses, с помощью которых можно преобразовать вывод LL-моделей в структурированный формат.

Цели обучения

  • Толкование вывода, созданного большими языковыми моделями
  • Создание пользовательских структур данных с использованием Pydantic
  • Понимание важности шаблонов запросов и их форматирования для вывода ЯММ
  • Узнайте, как создать инструкции формата для вывода ЯММ с помощью LangChain
  • Увидеть, как мы можем разбирать данные JSON в объект Pydantic

Эта статья была опубликована в рамках Блогона Data Science.

Что такое LangChain и Output Parsing?

LangChain – это библиотека Python, которая позволяет вам создавать приложения с использованием больших языковых моделей за короткое время. Он поддерживает широкий спектр моделей, включая LLM OpenAI GPT, PaLM от Google, а также открытые модели, доступные на Hugging Face, такие как Falcon, Llama и многие другие. С помощью LangChain настройка запросов для больших языковых моделей – это легко, и она также поставляется с хранилищем векторов, которое может хранить векторные представления входных и выходных данных. Это позволяет создавать приложения, которые могут запрашивать любые документы в течение нескольких минут.

LangChain позволяет большим языковым моделям получать информацию из Интернета через агентов. Он также предлагает output parsers, которые позволяют структурировать данные, полученные от больших языковых моделей. LangChain поставляется с различными Output Parses, такими как List Parser, Datetime Parser, Enum Parser и т. Д. В этой статье мы рассмотрим JSON парсер, который позволяет разбирать вывод, сгенерированный ЯММ, в формат JSON. Ниже мы можем увидеть типичный порядок разбора вывода ЯММ до объекта Pydantic, создавая готовые к использованию данные в переменных Python.

Начало работы – настройка модели

В этом разделе мы настроим модель с помощью LangChain. Мы будем использовать PaLM в качестве большой языковой модели в течение всей статьи. Мы будем использовать Google Colab для нашей среды. Вы можете заменить PaLM на любую другую большую языковую модель. Мы начнем с импорта необходимых модулей.

!pip install google-generativeai langchain
  • Это загрузит библиотеку LangChain и библиотеку google-generativeai для работы с моделью PaLM.
  • Для создания пользовательских запросов и разбора вывода, сгенерированного большими языковыми моделями, требуется библиотека langchain.
  • Библиотека google-generativeai позволит нам взаимодействовать с моделью PaLM от Google.

Ключ API PaLM

Для работы с PaLM нам понадобится ключ API, который мы можем получить, зарегистрировавшись на сайте MakerSuite. Затем мы импортируем все необходимые библиотеки и передаем ключ API, чтобы создать экземпляр модели PaLM.

import osimport google.generativeai as palmfrom langchain.embeddings import GooglePalmEmbeddingsfrom langchain.llms import GooglePalmos.environ['GOOGLE_API_KEY']= 'YOUR API KEY'palm.configure(api_key=os.environ['GOOGLE_API_KEY'])llm = GooglePalm()llm.temperature = 0.1prompts = ["Name 5 planets and line about them"]llm_result = llm._generate(prompts)print(llm_result.generations[0][0].text)
  • Здесь мы сначала создали экземпляр Google PaLM (Pathways Language Model) и присвоили его переменной llm
  • В следующем шаге мы устанавливаем температуру нашей модели на 0.1, устанавливая ее низкой, потому что нам не нужно, чтобы модель фантазировала
  • Затем мы создаем промпт в виде списка и передаем его переменной prompts
  • Чтобы передать промпт в PaLM, мы вызываем метод ._generate() и затем передаем список промптов и результаты сохраняются в переменной llm_result
  • Наконец, мы выводим результат в последнем шаге, вызывая .generations и преобразовывая его в текст, вызывая метод .text

Вывод для этой команды можно увидеть ниже

Мы видим, что модель Large Language Model сгенерировала хороший результат, и LLM также пытался добавить некоторую структуру, добавив некоторые строки. Но что если я хочу сохранить информацию для каждой модели в отдельной переменной? Что, если я хочу сохранить имя планеты, период орбиты и расстояние от Солнца отдельно в переменной? Результат, сгенерированный моделью, в его текущей форме не может быть использован напрямую для достижения этой цели. Так возникает необходимость в Output Parses.

Создание Pydantic Output Parser and Prompt Template

В этом разделе мы обсудим вывод парсера pydantic из langchain. В предыдущем примере вывод был представлен в неструктурированном формате. Рассмотрим, как можно сохранить информацию, сгенерированную Large Language Model, в структурированном формате.

Реализация кода

Давайте начнем с рассмотрения следующего кода:

from pydantic import BaseModel, Field, validatorfrom langchain.output_parsers import PydanticOutputParserclass PlanetData(BaseModel):    planet: str = Field(description="This is the name of the planet")    orbital_period: float = Field(description="This is the orbital period     in the number of earth days")    distance_from_sun: float = Field(description="This is a float indicating distance     from sun in million kilometers")    interesting_fact: str = Field(description="This is about an interesting fact of     the planet")
  • Здесь мы импортируем пакет Pydantic для создания структуры данных. В этой структуре данных мы будем сохранять вывод, разбирая его из LLM.
  • Здесь мы создали структуру данных, используя Pydantic, называемую PlanetData, которая хранит следующие данные
  • Planet: Это имя планеты, которое мы будем указывать в качестве входных данных для модели
  • Orbit Period: Это значение с плавающей запятой, которое содержит орбитальный период в днях Земли для определенной планеты.
  • Distance from Sun: Это значение с плавающей запятой, указывающее расстояние от планеты до Солнца
  • Interesting Fact: Это строка, содержащая один интересный факт о планете

Теперь мы хотим запрашивать у Large Language Model информацию о планете и хранить все эти данные в структуре данных PlanetData путем разбора вывода из LLM. Для разбора вывода LLM в структуру данных Pydantic LangChain предлагает парсер под названием PydanticOutputParser. Мы передаем класс PlanetData этому парсеру, который может быть определен следующим образом:

planet_parser = PydanticOutputParser(pydantic_object=PlanetData)

Мы сохраняем парсер в переменную с именем planet_parser. У объекта парсера есть метод с названием get_format_instructions(), который указывает LLM, как сгенерировать вывод. Давайте попробуем его вывести:

from pprint import pppp(planet_parser.get_format_instructions())

В приведенном выше примере видно, что в формате указана информация о том, как форматировать вывод, сгенерированный LLM. Он указывает LLM на вывод данных в формате JSON-схемы, чтобы этот JSON мог быть разобран в структуру данных Pydantic. Он также предоставляет пример схемы вывода. Затем мы создадим шаблон запроса.

Шаблон запроса

from langchain import PromptTemplate, LLMChaintemplate_string = """Вы являетесь экспертом, когда речь заходит о ответах на вопросы о планетах. 
Вы будете получать название планеты, и вам нужно будет вывести название планеты, ее орбитальный период в днях, а также ее расстояние от Солнца в миллионах километров и интересный факт.```{planet_name}```{format_instructions}"""planet_prompt = PromptTemplate(    template=template_string,    input_variables=["planet_name"],    partial_variables={"format_instructions": planet_parser.get_format_instructions()})
  • В нашем шаблоне запроса мы указываем, что мы будем предоставлять название планеты в качестве входных данных, и LLM должен сгенерировать вывод, который содержит информацию, такую как период орбиты, расстояние от Солнца и интересный факт о планете
  • Затем мы присваиваем этот шаблон PromptTemplate() и затем указываем имя переменной в качестве входных данных для параметра input_variables, в нашем случае это planet_name
  • Мы также предоставляем инструкции форматирования, которые мы видели ранее, и которые указывают LLM, как сгенерировать вывод в формате JSON

Давайте попробуем ввести название планеты и посмотрим, как выглядит запрос перед отправкой его в большую языковую модель

input_prompt = planet_prompt.format_prompt(planet_name='mercury')pp(input_prompt.to_string())

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

Тестирование большой языковой модели

В этом разделе мы отправим наш ввод в LLM и будем наблюдать за сгенерированными данными. В предыдущем разделе смотрим, каким будет наш вводной строка при отправке в LLM.

input_prompt = planet_prompt.format_prompt(planet_name='mercury')output = llm(input_prompt.to_string())pp(output)

Мы видим вывод, сгенерированный большой языковой моделью. Выходной формат действительно генерируется в формате JSON. JSON-данные содержат все ключи, которые мы определили в структуре данных PlanetData. И каждый ключ имеет значение, которое мы ожидаем.

Теперь нам нужно разобрать эти JSON-данные в структуру данных, которую мы определили ранее. Это можно легко сделать с помощью ранее определенного парсера PydanticOutputParser. Давайте посмотрим на этот код:

parsed_output = planet_parser.parse(output)print("Планета: ",parsed_output.planet)print("Орбитальный период: ",parsed_output.orbital_period)print("Расстояние от Солнца (в миллионах километров): ",parsed_output.distance_from_sun)print("Интересный факт: ",parsed_output.interesting_fact)

Вызов метода parse() для planet_parser примет вывод, разберет его и преобразует в объект Pydantic, в нашем случае – это объект PlanetData. Таким образом, вывод, то есть сгенерированный JSON большой языковой моделью, разбирается в структуру данных PlannetData, и теперь мы можем получить доступ к отдельным данным из него. Результат для приведенного выше кода будет:

Мы видим, что ключ-значение из данных JSON были правильно разобраны на данные Pydantic. Давайте попробуем с другой планетой и наблюдать результат

input_prompt = planet_prompt.format_prompt(planet_name='venus')output = llm(input_prompt.to_string())parsed_output = planet_parser.parse(output)print("Планета: ",parsed_output.planet)print("Орбитальный период: ",parsed_output.orbital_period)print("Расстояние от Солнца: ",parsed_output.distance_from_sun)print("Интересный факт: ",parsed_output.interesting_fact)

Мы видим, что для ввода “Венера” LLM смог сгенерировать JSON в качестве вывода, который успешно разобран на данные Pydantic. Таким образом, через разбор вывода мы можем напрямую использовать информацию, созданную большими языковыми моделями

Потенциальные применения и примеры использования

В этом разделе мы рассмотрим некоторые потенциальные приложения/примеры использования в реальном мире, где мы можем использовать эти техники разбора вывода. Используйте разбор при извлечении/после извлечения, когда мы извлекаем любой тип данных, мы хотим разобрать его, чтобы извлеченная информация могла быть использована другими приложениями. Некоторые из применений включают:

  • Извлечение и анализ жалоб на продукты: Когда новый бренд приходит на рынок и выпускает новые продукты, первое, что он хочет сделать, – это проверить, как продукт выполняется, и один из лучших способов оценить это – проанализировать сообщения в социальных медиа от потребителей, использующих эти продукты. Разбор вывода и LLM позволяют извлекать информацию, такую как бренд и названия продуктов, а также жалобы из отзывов потребителей в социальных медиа. Большие языковые модели хранят эти данные в структурированных переменных Pythonic через разбор вывода, что позволяет использовать их для визуализации данных.
  • Поддержка клиентов: При создании чат-ботов с использованием Больших языковых моделей для поддержки клиентов одной из ключевых задач будет извлечение информации из истории чата клиента. Эта информация содержит основные детали о том, с какими проблемами сталкиваются потребители в отношении продукта/услуги. Вы легко можете извлечь эти сведения с использованием разборщиков вывода LangChain, вместо того чтобы создавать специальный код для извлечения этой информации.
  • Информация о вакансиях: При разработке платформ поиска работы, таких как Indeed, LinkedIn и т.д., мы можем использовать Большие языковые модели для извлечения информации из объявлений о вакансиях, включая названия вакансий, названия компаний, годы опыта и описания вакансий. Разбор вывода может сохранять эти данные в структурированном виде JSON для сопоставления и рекомендаций вакансий. Разбор этой информации из вывода LLM непосредственно с помощью разборщиков вывода LangChain устраняет необходимость в множестве повторяющегося кода, необходимого для выполнения этой отдельной операции разбора.

Заключение

Большие языковые модели отличны, поскольку они могут буквально подходить для каждого случая использования благодаря своим экстраординарным способностям генерировать текст. Но часто они не справляются с использованием сгенерированного вывода, где нам приходится тратить значительное количество времени на разбор вывода. В этой статье мы рассмотрели эту проблему и как мы можем решить ее с помощью разборщиков вывода от LangChain, особенно разборщика JSON, который может разобрать данные JSON, сгенерированные с помощью Больших языковых моделей, и преобразовать их в объект Pydantic.

Основные выводы

Некоторые из основных выводов из этой статьи включают:

  • LangChain – это библиотека Python, которая позволяет создавать приложения с использованием имеющихся Больших языковых моделей.
  • LangChain предоставляет разборщики вывода, которые позволяют нам разбирать вывод, сгенерированный Большими языковыми моделями.
  • Pydantic позволяет нам определять пользовательские структуры данных, которые можно использовать при разборе вывода из Больших языковых моделей.
  • Помимо разборщика Pydantic JSON, LangChain также предоставляет различные разборщики вывода, такие как разборщик списка, разборщик даты и времени, разборщик Enum и т.д.

Часто задаваемые вопросы

Изображения, показанные в этой статье, не принадлежат Analytics Vidhya и используются по усмотрению автора.