Конвертер документов

Конвертер документов LangChain в основном функционирует для сегментации содержимого текста, разбивая большую статью на несколько более мелких фрагментов. Это делается потому, что у больших моделей обычно есть ограничения на длину подсказок и невозможно передать всё содержимое искусственному интеллекту. Даже если некоторые большие модели позволяют очень большую длину подсказки, с точки зрения затрат, передача такого длинного содержимого искусственному интеллекту непрактична. Ведь чем длиннее содержимое, тем выше затраты на вызов API (даже для моделей с открытым исходным кодом, развернутых локально, более длинное содержимое требует больше памяти GPU и замедляет вывод). Разумным подходом является объединение соответствующих фрагментов в качестве фоновой информации и подсказок при запросе модели искусственного интеллекта.

У LangChain есть много встроенных конвертеров документов, которые могут легко разбивать, объединять и фильтровать содержимое документов.

Разделитель текста

При работе с большими блоками текста необходимо разделить текст на части. Хотя это звучит просто, здесь могут возникнуть множество потенциальных сложностей. В идеале, вы хотите, чтобы семантически связанные сегменты текста оставались вместе. Термин "семантически связанный" здесь может зависеть от типа текста.

На высоком уровне разделитель текста работает следующим образом:

  1. Делит текст на маленькие, семантически значимые блоки (как правило, предложения).
  2. Начинает объединять эти маленькие блоки в более крупные до достижения определенного размера (измеряемого какой-либо функцией).
  3. Как только этот размер достигается, обрабатывает блок как собственный текстовый сегмент и начинает создавать новый текстовый блок с некоторым перекрытием (для сохранения контекста между блоками).

Это означает, что вы можете настраивать разделитель текста по двум различным осям:

  1. Как разделять текст
  2. Как измерять размер блоков

Пример

Рекомендуемый разделитель текста по умолчанию - 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, мы можем выполнять операции, такие как перевод документов с одного языка на другой, извлечение необходимых свойств и добавление их в метаданные, а также преобразование разговоров в набор вопросов и ответов.