Конвертер документов
Конвертер документов LangChain в основном функционирует для сегментации содержимого текста, разбивая большую статью на несколько более мелких фрагментов. Это делается потому, что у больших моделей обычно есть ограничения на длину подсказок и невозможно передать всё содержимое искусственному интеллекту. Даже если некоторые большие модели позволяют очень большую длину подсказки, с точки зрения затрат, передача такого длинного содержимого искусственному интеллекту непрактична. Ведь чем длиннее содержимое, тем выше затраты на вызов API (даже для моделей с открытым исходным кодом, развернутых локально, более длинное содержимое требует больше памяти GPU и замедляет вывод). Разумным подходом является объединение соответствующих фрагментов в качестве фоновой информации и подсказок при запросе модели искусственного интеллекта.
У LangChain есть много встроенных конвертеров документов, которые могут легко разбивать, объединять и фильтровать содержимое документов.
Разделитель текста
При работе с большими блоками текста необходимо разделить текст на части. Хотя это звучит просто, здесь могут возникнуть множество потенциальных сложностей. В идеале, вы хотите, чтобы семантически связанные сегменты текста оставались вместе. Термин "семантически связанный" здесь может зависеть от типа текста.
На высоком уровне разделитель текста работает следующим образом:
- Делит текст на маленькие, семантически значимые блоки (как правило, предложения).
- Начинает объединять эти маленькие блоки в более крупные до достижения определенного размера (измеряемого какой-либо функцией).
- Как только этот размер достигается, обрабатывает блок как собственный текстовый сегмент и начинает создавать новый текстовый блок с некоторым перекрытием (для сохранения контекста между блоками).
Это означает, что вы можете настраивать разделитель текста по двум различным осям:
- Как разделять текст
- Как измерять размер блоков
Пример
Рекомендуемый разделитель текста по умолчанию - RecursiveCharacterTextSplitter. Этот разделитель текста принимает список символов. Он пытается создавать блоки на основе первого символа, но если какой-либо блок слишком большой, он будет продолжать двигаться к следующему символу, и так далее. По умолчанию символы, на которых он пытается разделить, - ["\\\\n\\\\n", "\\\\n", " ", ""]
.
Помимо управления тем, какие символы можно разделять, можно также контролировать несколько других вопросов:
-
length_function
: Как рассчитывать длину блока. По умолчанию здесь чаще всего передаются только количество символов, но здесь часто передаются также токенные счётчики. -
chunk_size
: Максимальный размер ваших блоков (измеряемый функцией длины). -
chunk_overlap
: Максимальное перекрытие между блоками. Сохранение некоторого перекрытия может помочь сохранить непрерывность между блоками (например, выполняя скользящее окно). -
add_start_index
: Включать ли начальную позицию каждого блока в исходном документе в метаданные.
with open('../../state_of_the_union.txt') as f:
state_of_the_union = f.read()
from langchain.text_splitter import RecursiveCharacterTextSplitter
text_splitter = RecursiveCharacterTextSplitter(
chunk_size = 100,
chunk_overlap = 20,
length_function = len,
add_start_index = True,
)
texts = text_splitter.create_documents([state_of_the_union])
print(texts[0])
print(texts[1])
page_content = '..ignored text..' metadata={'start_index': 0}
page_content = '..ignored text..' metadata={'start_index': 82}
Другие преобразования
Фильтрация избыточных документов, перевод документов, извлечение метаданных и многое другое
Помимо разделения документов, мы также можем выполнить другие преобразования в содержимом документов. С помощью EmbeddingsRedundantFilter
мы можем идентифицировать похожие документы и фильтровать избыточное содержимое. Через интеграции, такие как doctran, мы можем выполнять операции, такие как перевод документов с одного языка на другой, извлечение необходимых свойств и добавление их в метаданные, а также преобразование разговоров в набор вопросов и ответов.