Цепочка внедрения проверки с использованием языка выражений LangChain и LLM

Использование языка выражений LangChain и LLM для улучшения процесса проверки

Введение

Непрерывный поиск точности и надежности в области искусственного интеллекта (ИИ) привнес в игру революционные инновации. Эти стратегии являются критическими для ведущих генеративных моделей, чтобы предлагать соответствующие ответы на широкий спектр вопросов. Одним из самых больших преград к использованию генеративного ИИ в различных сложных приложениях является галлюцинация. Недавняя статья, опубликованная Meta AI Research под названием «Цепочка верификации снижает галлюцинацию в больших языковых моделях», обсуждает простую технику прямого снижения галлюцинации при генерации текста.

В этой статье мы узнаем о проблемах галлюцинации и изучим концепции CoVe, упомянутые в статье, и о том, как реализовать их с использованием LLMs, фреймворка LangChain и языка выражений LangChain (LCEL) для создания пользовательских цепочек.

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

  • Понять проблему галлюцинации в LLMs.
  • Узнать о механизме Цепочки верификации (CoVe) для смягчения галлюцинации.
  • Знать о достоинствах и недостатках CoVe.
  • Научиться реализовывать CoVe с использованием LangChain и понять язык выражений LangChain.

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

В чем заключается проблема галлюцинации в LLMs?

Давайте сначала попытаемся разобраться с проблемой галлюцинации в LLM. Используя метод авторегрессивной генерации, модель LLM предсказывает следующее слово на основе предыдущего контекста. Для часто встречающихся тем модель видела достаточное количество примеров, чтобы с уверенностью присваивать высокую вероятность правильным токенам. Однако, поскольку модель не была обучена на необычных или незнакомых темах, она может выдавать неверные токены с высокой уверенностью. Это приводит к галлюцинациям правдоподобно звучащей, но неправильной информации.

Ниже приведен один из примеров галлюцинации в ChatGPT от Open AI, где я спросил о книге “Экономика малых вещей”, выпущенной в 2020 году индийским автором, но модель спутала ее с книгой другого лауреата Нобелевской премии, Абхиджита Банерджи, под названием “Бедная экономика”.

Метод цепи верификации (CoVe)

Механизм CoVe объединяет подсказку и проверку согласованности для создания самоверификационной системы для LLMs. Ниже перечислены основные шаги, описанные в статье. Мы попытаемся понять каждый шаг подробно поочередно.

Обзор процесса цепочки

  1. Создание базового ответа: При заданном запросе создаем ответ с использованием LLM.
  2. Планирование верификации: Исходя из запроса и базового ответа, создаем список вопросов верификации, которые помогут самоанализироваться, если в исходном ответе есть ошибки.
  3. Выполнение верификации: Поочередно отвечаем на каждый вопрос верификации и проверяем ответ по сравнению с исходным, чтобы выявить несогласованности или ошибки.
  4. Создание окончательного верифицированного ответа: Исходя из обнаруженных несогласованностей (если таковые есть), создаем исправленный ответ, учитывая результаты верификации.

Понимание процесса цепочки с помощью подробного примера

Создание начального ответа

Сначала мы передаем наш запрос в LLM без особых подсказок для создания начального ответа. Это служит отправной точкой для процесса CoVe. Поскольку базовые реакции часто подвержены галлюцинациям, техника CoVe стремится обнаружить и исправить эти ошибки на более поздних этапах.

Пример – “Какова основная причина мексикано-американской войны?”

Ответ бота – Мексикано-американская война была вооруженным конфликтом между США и Мексикой с 1846 по 1848 год. Она последовала за присоединением Техаса к США в 1845 году, который считался частью его территории, несмотря на его фактическое отделение в результате Техасской революции 1835 года.

План верификации

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

Пример – Когда началась и закончилась Мексикано-американская война? Когда США присоединили Техас? Когда Техас отделился от Мексики?

Выполнение верификации

После того, как мы спланировали вопросы верификации, мы можем отвечать на каждый вопрос отдельно. В статье рассматриваются 4 различных метода выполнения верификации:

1. Объединенный: В данном случае планирование и выполнение вопросов верификации осуществляются в одном запросе. Вопросы и ответы на них предоставляются в одном запросе LLM. Этот метод обычно не рекомендуется, так как ответы на верификацию могут быть искусственными.

2. 2-шаговый: Планирование и выполнение выполняются отдельно в двух шагах с использованием отдельных запросов LLM. Сначала мы генерируем вопросы верификации, а затем отвечаем на эти вопросы.

3. Факторный: Здесь каждый вопрос верификации отвечается независимо, а не в одном большом ответе, и базовый ответ не включается. Это может помочь избежать путаницы между разными вопросами верификации и также может обработать большее количество вопросов.

4. Факторный + Пересмотр: В этом методе добавляется дополнительный шаг. После каждого ответа на вопрос верификации механизм CoVe проверяет, соответствуют ли ответы исходному базовому ответу. Это делается в отдельном шаге с использованием дополнительного запроса.

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

Окончательный проверенный ответ

На этом последнем этапе генерируется улучшенный и проверенный ответ. Используется несколько промптов в системе набора данных, и весь предыдущий контекст базового ответа и ответы на вопросы верификации включаются. Если использовался метод «Фактор + Пересмотр», то также предоставляется результат проверки на противоречия.

Ограничения методики CoVe

Хотя методика Chain of Verification представляет собой простую, но эффективную технику, она имеет некоторые ограничения:

  1. Не полностью исключает галлюцинации: Она не гарантирует полное исключение галлюцинаций из ответа и, следовательно, может предоставлять вводящую в заблуждение информацию.
  2. Вычислительно интенсивный: Генерация и выполнение верификации вместе с генерацией ответа могут увеличить вычислительные нагрузки и затраты. Таким образом, они могут замедлить процесс или увеличить вычислительные издержки.
  3. Ограничение модели: Успех метода CoVe во многом зависит от возможностей модели и ее способности определять и исправлять свои ошибки.

Реализация LangChain CoVe

Основное описание алгоритма

Здесь мы будем использовать 4 разных шаблона запросов для каждого из 4 шагов в CoVe, и на каждом шаге вывод предыдущего шага является входными данными для следующего шага. Кроме того, мы придерживаемся факторного подхода к выполнению вопросов верификации. Мы используем внешний поисковый инструмент в Интернете для генерации ответов на наши вопросы верификации.

Шаг 1: Установка и загрузка библиотек

!pip install langchain duckduckgo-search

Шаг 2: Создание и инициализация экземпляра LLM

Здесь я использую Google Palm LLM в LangChain, так как он бесплатно доступен. Вы можете сгенерировать API-ключ для Google Palm, используя эту ссылку и войти в систему, используя свою учетную запись Google.

from langchain import PromptTemplatefrom langchain.llms import GooglePalmfrom langchain.schema.output_parser import StrOutputParserfrom langchain.schema.runnable import RunnablePassthrough, RunnableLambdaAPI_KEY = 'Сгенерированный API-ключ'llm = GooglePalm(google_api_key=API_KEY)llm.temperature = 0.4llm.model_name = 'models/text-bison-001'llm.max_output_tokens = 2048

Шаг 3: Генерация начального базового ответа

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

LLM цепочка будет использовать язык выражений LangChain для составления цепочки. Здесь мы предоставляем шаблон промпта, связанный (|) с моделью LLM, и, наконец, с выходным парсером.

BASELINE_PROMPT = """Answer the below question which is asking for a concise factual answer. NO ADDITIONAL DETAILS.Question: {query}Answer:"""# Цепочка для генерации начального ответаbaseline_response_prompt_template = PromptTemplate.from_template(BASELINE_PROMPT)baseline_response_chain = baseline_response_prompt_template | llm | StrOutputParser()

Шаг 4: Генерация шаблона вопроса для верификационного вопроса

Теперь мы создадим шаблон верификационного вопроса, который затем поможет в генерации верификационных вопросов на следующем шаге.

VERIFICATION_QUESTION_TEMPLATE = """Your task is to create a verification question based on the below question provided.Example Question: Who wrote the book 'God of Small Things' ?Example Verification Question: Was book [God of Small Things] written by [writer]? If not who wrote [God of Small Things] ? Explanation: In the above example the verification question focused only on the ANSWER_ENTITY (name of the writer) and QUESTION_ENTITY (book name).Similarly you need to focus on the ANSWER_ENTITY and QUESTION_ENTITY from the actual question and generate verification question.Actual Question: {query}Final Verification Question:"""# Цепочка для генерации шаблона вопроса для верификационных ответовverification_question_template_prompt_template = PromptTemplate.from_template(VERIFICATION_QUESTION_TEMPLATE)verification_question_template_chain = verification_question_template_prompt_template | llm | StrOutputParser()

Шаг 5: Генерация верификационного вопроса

Теперь мы сгенерируем верификационные вопросы, используя определенный выше шаблон верификационного вопроса:

VERIFICATION_QUESTION_PROMPT= """Your task is to create a series of verification questions based on the below question, the verfication question template and baseline response.Example Question: Who wrote the book 'God of Small Things' ?Example Verification Question Template: Was book [God of Small Things] written by [writer]? If not who wrote [God of Small Things]?Example Baseline Response: Jhumpa LahiriExample Verification Question: 1. Was God of Small Things written by Jhumpa Lahiri? If not who wrote God of Small Things ?Explanation: In the above example the verification questions focused only on the ANSWER_ENTITY (name of the writer) and QUESTION_ENTITY (name of book) based on the template and substitutes entity values from the baseline response.Similarly you need to focus on the ANSWER_ENTITY and QUESTION_ENTITY from the actual question and substitute the entity values from the baseline response to generate verification questions.Actual Question: {query}Baseline Response: {base_response}Verification Question Template: {verification_question_template}Final Verification Questions:"""# Цепочка для генерации верификационных вопросовverification_question_generation_prompt_template = PromptTemplate.from_template(VERIFICATION_QUESTION_PROMPT)verification_question_generation_chain = verification_question_generation_prompt_template | llm | StrOutputParser()

Шаг 6: Выполнение верификационного вопроса

Здесь мы будем использовать внешний инструмент поиска для выполнения верификационного вопроса. Этот инструмент создается с использованием агента и модуля DuckDuckGo search в LangChain.

Примечание – При использовании поисковых агентов есть ограничения времени, поэтому необходимо осторожно использовать, так как множественные запросы могут вызвать ошибку из-за ограничений времени между запросами

from langchain.agents import ConversationalChatAgent, AgentExecutorfrom langchain.tools import DuckDuckGoSearchResults#create search agentsearch = DuckDuckGoSearchResults()tools = [search]custom_system_message = "Assistant assumes no knowledge & relies on internet search to answer user's queries."max_agent_iterations = 5max_execution_time = 10chat_agent = ConversationalChatAgent.from_llm_and_tools(    llm=llm, tools=tools, system_message=custom_system_message)search_executor = AgentExecutor.from_agent_and_tools(    agent=chat_agent,    tools=tools,    return_intermediate_steps=True,    handle_parsing_errors=True,    max_iterations=max_agent_iterations,    max_execution_time = max_execution_time)# цепочка для выполнения верификационных вопросовverification_chain = RunnablePassthrough.assign(    split_questions=lambda x: x['verification_questions'].split("\n"), # каждый верификационный вопрос передается по одному факторизованному подходу) | RunnablePassthrough.assign(    answers = (lambda x: [{"input": q,"chat_history": []} for q in x['split_questions']])| search_executor.map() # поиск выполняется для каждого вопроса независимо) | (lambda x: "\n".join(["Вопрос: {} Ответ: {}\n".format(question, answer['output']) for question, answer in zip(x['split_questions'], x['answers'])]))# Создание окончательного уточненного ответа

Шаг 7: Создать окончательный уточненный ответ

Теперь мы сгенерируем окончательный уточненный ответ, для которого определим шаблон запроса и цепочку llm.

FINAL_ANSWER_PROMPT= """На основе "Исходного запроса" и "Базового ответа" проанализируйте "Вопросы и ответы для проверки", чтобы наконец-то дать уточненный ответ. Исходный запрос: {query} Базовый ответ: {base_response} Вопросы и пары Вопрос-Ответы для проверки: {verification_answers} Окончательный уточненный ответ:""" # Цепочка для генерации конечного ответаfinal_answer_prompt_template = PromptTemplate.from_template(FINAL_ANSWER_PROMPT)final_answer_chain = final_answer_prompt_template | llm | StrOutputParser()

Шаг 8: Объединение всех цепей

Теперь мы объединяем все ранее определенные цепи, чтобы они выполнялись последовательно одновременно.

chain = RunnablePassthrough.assign(    base_response=baseline_response_chain) |  RunnablePassthrough.assign(    verification_question_template=verification_question_template_chain) | RunnablePassthrough.assign(    verification_questions=verification_question_generation_chain) | RunnablePassthrough.assign(    verification_answers=verification_chain) | RunnablePassthrough.assign(    final_answer=final_answer_chain)response = chain.invoke({"query": "Кто написал книгу 'Экономика маленьких вещей'?")})print(response)

# Ответ на запрос{'query': "Кто написал книгу 'Экономика маленьких вещей'?", 'base_response': 'Санджай Джайн', 'verification_question_template': 'Книгу [Экономика маленьких вещей] написал [автор]? Если нет, то кто написал [экономику маленьких вещей] ?', 'verification_questions': '1. Автором "Экономики маленьких вещей" является Санджай Джайн? Если нет, то кто написал "Экономику маленьких вещей" ?', 'verification_answers': 'Вопрос: 1. Автором "Экономики маленьких вещей" является Санджай Джайн? Если нет, то кто написал "Экономику маленьких вещей" ? Ответ: "Экономику маленьких вещей" написал Судипта Саранги \n', 'final_answer': 'Судипта Саранги'}

Изображение вывода:

Заключение

Предложенная в исследовании техника Chain-of-Verification (CoVe) является стратегией, нацеленной на создание больших языковых моделей, более критического рассмотрения их ответов и их корректировку в случае необходимости. Этот метод разбивает проверку на более мелкие, более управляемые запросы. Также было показано, что запрет модели проверять свои предыдущие ответы помогает избежать повторения ошибок или “галлюцинаций”. Просто требуя от модели дважды проверить свои ответы, улучшает их результаты значительно. Дать CoVe больше возможностей, таких как возможность черпать информацию из внешних источников, может быть одним из способов повысить ее эффективность.

Главные идеи

  • Процесс Chain – это полезный инструмент с различными комбинациями техник, позволяющий проверять разные части нашего ответа.
  • Помимо множества преимуществ, у процесса Chain также есть определенные ограничения, которые можно смягчить с помощью разных инструментов и механизмов.
  • Мы можем использовать пакет LangChain для реализации процесса CoVe.

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

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