Разбивка текста по заголовкам Markdown
Мотивация
Многие приложения чата или вопросно-ответные приложения включают разделение входных документов перед их встраиванием и векторизацией. После разделения текста часто желательно группировать текстовые фрагменты с похожими темами вместе.
Например, файл Markdown организован с многоуровневыми заголовками, такими как h1, h2 и h3. Мы можем организовать текстовые фрагменты с тем же заголовком на основе заголовков Markdown.
Эта глава представляет, как LangChain разбивает содержимое текста на основе заголовков Markdown, используя разделитель текста MarkdownHeaderTextSplitter
.
Например, если мы хотим разбить этот Markdown:
md = '# Foo\\n\\n ## Bar\\n\\nHi this is Jim \\nHi this is Joe\\n\\n ## Baz\\n\\n Hi this is Molly'
Установим правила заголовков для разделения, на основе заголовков уровня 1 и уровня 2:
[("#", "Заголовок 1"),("##", "Заголовок 2")]
Вот пример разделенного содержимого на основе заголовков, где поле метаданных записывает, к какому заголовку принадлежит текущий фрагмент содержимого:
{'content': 'Hi this is Jim \nHi this is Joe', 'metadata': {'Заголовок 1': 'Foo', 'Заголовок 2': 'Bar'}}
{'content': 'Hi this is Molly', 'metadata': {'Заголовок 1': 'Foo', 'Заголовок 2': 'Baz'}}
Теперь давайте посмотрим, как написать код.
Установите зависимости:
%pip install -qU langchain-text-splitters
from langchain_text_splitters import MarkdownHeaderTextSplitter
Справочник API:
- Создание разделителя текста с использованием MarkdownHeaderTextSplitter
markdown_document = "# Foo\n\n ## Bar\n\nПривет, это Джим\n\nПривет, это Джо\n\n ### Boo \n\n Привет, это Лэнс \n\n ## Baz\n\n Привет, это Молли"
headers_to_split_on = [
("#", "Заголовок 1"),
("##", "Заголовок 2"),
("###", "Заголовок 3"),
]
markdown_splitter = MarkdownHeaderTextSplitter(headers_to_split_on=headers_to_split_on)
md_header_splits = markdown_splitter.split_text(markdown_document)
md_header_splits
[Document(page_content='Привет, это Джим \nПривет, это Джо', metadata={'Заголовок 1': 'Foo', 'Заголовок 2': 'Bar'}),
Document(page_content='Привет, это Лэнс', metadata={'Заголовок 1': 'Foo', 'Заголовок 2': 'Bar', 'Заголовок 3': 'Boo'}),
Document(page_content='Привет, это Молли', metadata={'Заголовок 1': 'Foo', 'Заголовок 2': 'Baz'})]
type(md_header_splits[0])
langchain.schema.Document
В каждой группе Markdown мы можем применить любой текстовый разделитель.
markdown_document = "# Вступление \n\n ## История \n\n Markdown[9] - это легкий язык разметки для создания форматированного текста с использованием редактора обычного текста. Джон Грубер создал Markdown в 2004 году как язык разметки, привлекательный для читателей в исходном коде.[9] \n\n Markdown широко используется в блогах, мгновенных сообщениях, онлайн-форумах, совместном программном обеспечении, страницах документации и файлы readme. \n\n ## Рост и расхождение \n\n Поскольку популярность Markdown быстро росла, появилось множество его реализаций, вызванных в основном потребностью в \n\n дополнительных возможностях, таких как таблицы, сноски, списки определений,[прим 1] и Markdown внутри HTML-блоков. \n\n #### Стандартизация \n\n С 2012 года группа людей, включая Джеффа Атвуда и Джона МакФарлейна, начала то, что Атвуд охарактеризовал как усилие стандартизации. \n\n ## Реализации \n\n Реализации Markdown доступны для более чем десятка языков программирования."
headers_to_split_on = [
("#", "Заголовок 1"),
("##", "Заголовок 2"),
]
markdown_splitter = MarkdownHeaderTextSplitter(headers_to_split_on=headers_to_split_on)
md_header_splits = markdown_splitter.split_text(markdown_document)
from langchain.text_splitter import RecursiveCharacterTextSplitter
chunk_size = 250
chunk_overlap = 30
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=chunk_size, chunk_overlap=chunk_overlap
)
splits = text_splitter.split_documents(md_header_splits)
splits
Результаты:
[Document(page_content='Markdown[9] - это легкий язык разметки для создания форматированного текста с использованием редактора обычного текста. Джон Грубер создал Markdown в 2004 году как язык разметки, привлекательный для читателей в исходном коде.[9]', metadata={'Заголовок 1': 'Вступление', 'Заголовок 2': 'История'}),
Document(page_content='Markdown широко используется в блогах, мгновенных сообщениях, онлайн-форумах, совместном программном обеспечении, страницах документации и файлы readme.', metadata={'Заголовок 1': 'Вступление', 'Заголовок 2': 'История'}),
Document(page_content='Поскольку популярность Markdown быстро росла, появилось множество его реализаций, вызванных в основном потребностью в \nдополнительных возможностях, таких как таблицы, сноски, списки определений,[прим 1] и Markdown внутри HTML-блоков. \n#### Стандартизация', metadata={'Заголовок 1': 'Вступление', 'Заголовок 2': 'Рост и расхождение'}),
Document(page_content='#### Стандартизация \nС 2012 года группа людей, включая Джеффа Атвуда и Джона МакФарлейна, начала то, что Атвуд охарактеризовал как усилие стандартизации.', metadata={'Заголовок 1': 'Вступление', 'Заголовок 2': 'Рост и расхождение'}),
Document(page_content='Реализации Markdown доступны для более чем десятка языков программирования.', metadata={'Заголовок 1': 'Вступление', 'Заголовок 2': 'Реализации'})]