ตัวแยกข้อความบนหัวข้อของ 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'}}

ตอนนี้เรามาดูวิธีเขียนโค้ดกัน

ติดตั้ง dependencies:

%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 ### บู \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 group เราสามารถใช้ text splitter อะไรก็ได้

markdown_document = "# บทนำ \n\n    ## ประวัติ \n\n Markdown[9] เป็นภาษามาร์กอัปเบาะแบบสำหรับสร้างข้อความที่มีรูปแบบโดยใช้ตัวแก้ไขข้อความธรรมดา จอห์น กรูเบอร์ สร้าง Markdown เมื่อปี 2004 เป็นภาษามาร์กอัปที่น่าสนใจสำหรับผู้อ่านมนุษย์ในรูปแบบรหัสที่มาจากแหล่งข้อมูล [9] \n\n Markdown นิยมใช้งานอย่างแพร่หลายในการเขียนบล็อก การสื่อสารทันเร่ง, ฟอรั่มออนไลน์, ซอฟต์แวร์ที่ทำงานร่วมกัน, หน้าเอกสาร และแฟ้ม readme \n\n ## การเติบโตและการแตกต่าง \n\n เมื่อ Markdown มีความนิยมเพิ่มขึ้นอย่างรวดเร็ว มีการพัฒนา Markdown หลายรูปแบบ โดยมากอย่างไรก็ดีเพื่อความต้องการเพิ่มเติม เช่น ตาราง, ตารางเชิงอรรถ, รายการกำหนด [หมายเหตุ 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 มีความนิยมเพิ่มขึ้นอย่างรวดเร็ว มีการพัฒนา Markdown หลายรูปแบบ โดยมากอย่างไรก็ดีเพื่อความต้องการเพิ่มเติม เช่น ตาราง, ตารางเชิงอรรถ, รายการกำหนด [หมายเหตุ 1] และ Markdown ภายในบล็อก HTML  \n#### มาตรฐาน', metadata={'หัวข้อ 1': 'บทนำ', 'หัวข้อ 2': 'การเติบโตและการแตกต่าง'}),
     Document(page_content='#### มาตรฐาน  \nเริ่มตั้งแต่ปี 2012, มีกลุ่มคนหลายคนรวมถึงเจฟ แอตวู้ด และจอห์น แมคฟาเลน เริ่มการทำมาตรฐาน', metadata={'หัวข้อ 1': 'บทนำ', 'หัวข้อ 2': 'การเติบโตและการแตกต่าง'}),
     Document(page_content='การปฏิบัติของ Markdown มีการใช้งานได้สำหรับภาษาโปรแกรมมิงอื่นหลายภาษา', metadata={'หัวข้อ 1': 'บทนำ', 'หัวข้อ 2': 'การปฏิบัติ'})]