Суммирование текста на языке Python с использованием LangChain
Различные большие языковые модели (Large Language Models, LLM) имеют разные ограничения на длину входных слов в запросе. Если нам нужно сжать большую статью, но длина статьи превышает максимальный предельный лимит модели, мы не можем напрямую передавать всю статью модели искусственного интеллекта. В таких сценариях LangChain предоставляет стратегии и инкапсуляцию для решения этой проблемы. В этой главе в основном рассматривается, как LangChain решает задачу суммирования текста.
Предварительная обработка данных
Сначала подготавливаем тестовые данные. В этом примере мы загружаем длинный документ, а затем разбиваем его на несколько небольших фрагментов документа.
- Примечание: Загрузка локальных данных файлов здесь приведена только для иллюстрации. В реальных бизнес-сценариях вы можете загружать данные документа из своей собственной базы данных.
from langchain import OpenAI, PromptTemplate, LLMChain
from langchain.text_splitter import CharacterTextSplitter
from langchain.chains.mapreduce import MapReduceChain
from langchain.prompts import PromptTemplate
llm = OpenAI(temperature=0)
text_splitter = CharacterTextSplitter()
with open("../../state_of_the_union.txt") as f:
state_of_the_union = f.read()
texts = text_splitter.split_text(state_of_the_union)
from langchain.docstore.document import Document
docs = [Document(page_content=t) for t in texts[:3]]
Начало работы
Самый простой способ сжать длинный текст - использовать задачу load_summarize_chain
, предоставляемую LangChain, для выполнения задачи суммирования текста.
from langchain.chains.summarize import load_summarize_chain
chain = load_summarize_chain(llm, chain_type="map_reduce")
chain.run(docs)
Использование инкапсулированной цепочки суммирования текста, предоставленной LangChain, просто. Однако, если вам нужно настроить некоторые параметры, обратитесь к следующему содержимому. Например, в приведенном выше примере используется встроенный шаблон слов-подсказок, который может быть неудобен для русского языка. Вы можете изменить его на свой собственный шаблон слов-подсказок и т. д.
Объяснение параметра chain_type
LangChain разработала 4 метода обработки случая, когда подсказочное слово задачи Chain превышает длину токена LLM.
4 типа chain_type
следующие:
- stuff
- map_reduce
- refine
- map_rerank
Тип stuff
Это тип по умолчанию в LangChain, который отправляет весь содержимый документа в модель LLM для суммирования сразу. Поэтому его называют режим упаковки. Если содержимое документа слишком длинное, оно определенно превысит предел токенов LLM.
Тип map_reduce
Этот метод сначала отправляет каждый фрагмент документа в модель LLM для индивидуального суммирования, затем объединяет все суммарные данные и, наконец, предоставляет общее резюме для искусственного интеллекта, что аналогично концепции библиотек функций map-reduce во многих языках программирования.
Тип refine
Этот метод генерирует текстовое резюме путем суммирования. Сначала он отправляет содержимое первого документа в модель llm для суммирования, затем отправляет содержание резюме первого документа + содержание второго документа в модель llm для суммирования и так далее, чтобы получить окончательное резюме для длинного текста.
Тип map_rerank
Это используется в задачах вопросно-ответного формата. Он выбирает фрагменты документа с высокой релевантностью к вопросу, а затем отправляет их в модель llm для ответа на вопрос.
Пример задачи stuff
Вот пример сжатия статьи с использованием типа stuff
, который подходит для статей, не превышающих ограничение по количеству токенов LLM:
chain = load_summarize_chain(llm, chain_type="stuff")
chain.run(docs)
Пользовательские слова-подсказки
Для типа stuff
вот пример пользоватских слов-подсказок:
prompt_template = """Сжать следующее содержание:
{text}
Резюме:"""
PROMPT = PromptTemplate(template=prompt_template, input_variables=["text"])
chain = load_summarize_chain(llm, chain_type="stuff", prompt=PROMPT)
chain.run(docs)
Пример задачи map_reduce
map_reduce
подводит итоги статьи, и, конечно же, данный метод приведет к нескольким вызовам моделей искусственного интеллекта.
chain = load_summarize_chain(llm, chain_type="map_reduce")
chain.run(docs)
Пользовательские слова-подсказки для задачи map_reduce
prompt_template = """Подведите итог следующего содержания:
{text}
Итог:"""
PROMPT = PromptTemplate(template=prompt_template, input_variables=["text"])
chain = load_summarize_chain(OpenAI(temperature=0), chain_type="map_reduce", return_intermediate_steps=True, map_prompt=PROMPT, combine_prompt=PROMPT)
chain({"input_documents": docs}, return_only_outputs=True)
Пример задачи refine
Просто измените параметр chain_type
на refine
.
chain = load_summarize_chain(llm, chain_type="refine")
chain.run(docs)
Шаблон пользовательских слов-подсказок для задачи refine
Вот пример пользовательских слов-подсказок для задачи refine
:
prompt_template = """Подведите итог следующего содержания:
{text}
Итог:"""
PROMPT = PromptTemplate(template=prompt_template, input_variables=["text"])
refine_template = (
"Ваша задача - создать окончательное текстовое резюме\n"
"Вот существующая информация о резюме: {existing_answer}\n"
"Улучшите существующее резюме на основе новой информации\n"
"Фоновая информация следующая\n"
"------------\n"
"{text}\n"
"------------\n"
"Основываясь на фоновой информации, улучшите существующее резюме\n"
"Верните существующую информацию о резюме, если фоновая информация не является полезной."
)
refine_prompt = PromptTemplate(
input_variables=["existing_answer", "text"],
template=refine_template,
)
chain = load_summarize_chain(OpenAI(temperature=0), chain_type="refine", return_intermediate_steps=True, question_prompt=PROMPT, refine_prompt=refine_prompt)
chain({"input_documents": docs}, return_only_outputs=True)