MarkdownHeaderTextSplitter

モチベーション

多くのチャットやQ&Aアプリケーションでは、埋め込みやベクトル化する前に入力ドキュメントをチャンク化することがよくあります。テキストをチャンク化した後は、類似のトピックを持つテキストフラグメントをグループ化することがしばしば望ましいです。

例えば、Markdownファイルはh1、h2、h3などの多層ヘッダーで構成されています。Markdownのヘッダーに基づいて、同じヘッディングを持つテキストフラグメントを整理することができます。

このチャプターでは、MarkdownHeaderTextSplitterテキストスプリッターを使用して、Markdownヘッダーに基づいてテキストコンテンツを分割する方法を紹介します。

例えば、次のような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のヘッダーに基づいています:

[("#", "Header 1"),("##", "Header 2")]

次の例は、ヘッディングに基づいてコンテンツを分割したもので、メタデータフィールドには現在のコンテンツフラグメントがどのヘッディングに属するかが記録されています:

{'content': 'Hi this is Jim  \nHi this is Joe', 'metadata': {'Header 1': 'Foo', 'Header 2': 'Bar'}}
{'content': 'Hi this is Molly', 'metadata': {'Header 1': 'Foo', 'Header 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]は、プレーンテキストエディタを使用してフォーマットされたテキストを作成するための軽量なマークアップ言語です。John Gruberは、Markdownを人間の読者に訴求力のあるソースコード形式で作成したマークアップ言語として2004年に作成しました。[9] \n\n Markdownは、ブログ、インスタントメッセージング、オンラインフォーラム、共同作業ソフトウェア、ドキュメントページ、およびREADMEファイルで広く使用されています。\n\n ## 成長と分岐\n\n Markdownの人気が急速に高まるにつれて、多くのMarkdownの実装が登場しました。これは主に表、脚注、定義リスト、[注釈1]およびHTMLブロック内のMarkdownなどの追加機能の必要性によるものです。\n\n #### 標準化\n\n 2012年から、Jeff AtwoodとJohn MacFarlaneを含む一群の人々が、Atwoodが標準化の努力と表現したものを開始しました。\n\n ## 実装\n\n Markdownの実装は12以上のプログラミング言語で利用可能です。"

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]は、プレーンテキストエディタを使用してフォーマットされたテキストを作成するための軽量なマークアップ言語です。John Gruberは、Markdownを人間の読者に訴求力のあるソースコード形式で作成したマークアップ言語として2004年に作成しました。[9]', metadata={'ヘッダー 1': 'イントロ', 'ヘッダー 2': '歴史'}),
     Document(page_content='Markdownは、ブログ、インスタントメッセージング、オンラインフォーラム、共同作業ソフトウェア、ドキュメントページ、およびREADMEファイルで広く使用されています。', metadata={'ヘッダー 1': 'イントロ', 'ヘッダー 2': '歴史'}),
     Document(page_content='Markdownの人気が急速に高まるにつれて、多くのMarkdownの実装が登場しました。これは主に表、脚注、定義リスト、[注釈1]およびHTMLブロック内のMarkdownなどの追加機能の必要性によるものです。  \n#### 標準化', metadata={'ヘッダー 1': 'イントロ', 'ヘッダー 2': '成長と分岐'}),
     Document(page_content='#### 標準化  \n2012年から、Jeff AtwoodとJohn MacFarlaneを含む一群の人々が、Atwoodが標準化の努力と表現したものを開始しました。', metadata={'ヘッダー 1': 'イントロ', 'ヘッダー 2': '成長と分岐'}),
     Document(page_content='Markdownの実装は12以上のプログラミング言語で利用可能です。', metadata={'ヘッダー 1': 'イントロ', 'ヘッダー 2': '実装'})]