2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

LangChain MarkdownHeaderTextSplitterのTips

Posted at

はじめに

  • 生成AIを使ったRAG(Retrieval-Augmented Generation)を行うための前処理の話
  • 目的は、langchainのMarkdownHeaderTextSplitterを使って、Markdownファイルをセクションごとに分割したかった
  • が、投入したMarkdownが全く分割されず、ハマったので共有したい

結論

  • 連続するセクションのタイトルが同じだと、一つのセクションとみなされるので、分割したい場合はちゃんと分けよう!

ハマった内容

どういうドキュメントをどのように分割したいか

  • セクションごとに分割したい
# セクション1
セクション1の内容です。

## サブセクション1-1
これは
サブセクション1-1の内容です。

## サブセクション1-2
これは
サブセクション1-2の内容です。

# セクション2
セクション2の内容です。

## サブセクション2-1
これは
サブセクション2-1の内容です。

# セクション3
セクション3の内容です。
  • 期待する分割結果
    • 以下のように3分割したい
合計で3個のテキストに分割されました:

分割 1:
# セクション1
セクション1の内容です。  
## サブセクション1-1
これは
サブセクション1-1の内容です。  
## サブセクション1-2
これは
サブセクション1-2の内容です。
--------------------
分割 2:
# セクション2
セクション2の内容です。  
## サブセクション2-1
これは
サブセクション2-1の内容です。
--------------------
分割 3:
# セクション3
セクション3の内容です。
--------------------

ハマった事例

# セクション
セクション1の内容です。

# セクション
セクション2の内容です。

# セクション
セクション3の内容です。

↓ 結果

合計で1個のテキストに分割されました:

分割 1:
# セクション
セクション1の内容です。  
# セクション
セクション2の内容です。  
# セクション
セクション3の内容です。

Tips:連続するセクションで異なっていればよい

  • 同じタイトルが存在すること自体は問題ないようだ
# セクション1
セクション1の内容です。

# セクション2
セクション2の内容です。

# セクション1
セクション3の内容です。

↓ 結果

合計で3個のテキストに分割されました:

分割 1:
# セクション1
セクション1の内容です。
--------------------
分割 2:
# セクション2
セクション2の内容です。
--------------------
分割 3:
# セクション1
セクション3の内容です。
--------------------

最後に

  • めっちゃ悩んで、文字コード変えたり、ファイルサイズ変えたり、日本語無くしてみたりしてもわからなかったので、危うくCharacterTextSplitterで力わざで実装しようとしかけたところで、ギリギリ気づけて命拾いしたw

参考コード

import os
from typing import List
from langchain.text_splitter import MarkdownHeaderTextSplitter

# Markdownファイルを読み込む関数
def read_markdown_file(file_path: str) -> str:
    """
    指定されたファイルパスからMarkdownファイルを読み込みます。
    
    :param file_path: Markdownファイルのパス
    :return: ファイルの内容
    """
    try:
        with open(file_path, 'r', encoding='utf-8') as file:
            content = file.read()
        return content
    except FileNotFoundError:
        print(f"エラー: ファイル '{file_path}' が見つかりません。")
        return ""
    except Exception as e:
        print(f"ファイルを読み込む際にエラーが発生しました: {e}")
        return ""

# Markdownテキストを「#'記号で分割する関数
def split_markdown_text(md_text: str) -> List[str]:
    """
    Markdownテキストを「#'記号で分割します。
    
    :param md_text: Markdown形式のテキスト
    :return: 分割されたテキストのリスト
    """
    headers_to_split_on = [("#", "H1")]
    markdown_splitter = MarkdownHeaderTextSplitter(headers_to_split_on=headers_to_split_on, strip_headers=False)
    md_header_splits = markdown_splitter.split_text(md_text)
    split_texts = [split_md.page_content for split_md in md_header_splits]
    return split_texts

# メイン関数
def main():
    # Markdownファイルのパスを定義
    markdown_file_path = 'data/easymarkdown.md'  # ここに正しいパスを設定してください
    
    # Markdownファイルを読み込む
    markdown_content = read_markdown_file(markdown_file_path)
    
    # ファイルの内容が読み込まれた場合にのみ処理を実行
    if markdown_content:
        # Markdownテキストを「#'記号で分割
        split_texts = split_markdown_text(markdown_content)
        
        # 分割されたテキストの総数を表示
        total_splits = len(split_texts)
        print(f"合計で{total_splits}個のテキストに分割されました:\n")
        
        # 分割されたテキストを表示
        for i, text in enumerate(split_texts):
            print(f"分割 {i+1}:")
            print(text)
            print("-" * 20)  # 分割されたテキストを視覚的に分けるために区切¥り線を表示
    else:
        print("Markdownファイルの読み込みに失敗しました。")

if __name__ == "__main__":
    main()
2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?