RAG için, belgenin bölümlerini izleyen parçalar istediğinizde PDF’leri Markdown’a dönüştürün: her başlık bir bölme noktası olur ve bir parçanın üstündeki başlıklar ona meta veri olarak eşlik eder. İndekslemeden önce başlıkları, tabloları ve OCR metnini kontrol edin, ardından geri getirmeyi yanıtlarını önceden bildiğiniz sorularla test edin.

Bu rehber, özel belgeler üzerinde geri getirme sistemi kuran geliştiriciler içindir: politikalar, kılavuzlar, sözleşmeler, araştırmalar. Aklınızda zaten bir gömme modeli ve bir vektör deposu olduğunu varsayar.

Yanında bir dizüstü bilgisayar bulunan, biri lila şeritle bağlanmış çizgili fiş yığınları ve kâğıt şeritler.
Belgenin bölümlerini izleyen parçalar.

Başlıklar neden daha iyi parçalar sağlar

Sabit boyutlu bir bölücü metni, kesim nereye denk gelirse gelsin, belirli uzunlukta parçalara keser. Bir parça bir bölümün ortasında başlayabilir ve neyle ilgili olduğunu söyleyen başlığı kaybedebilir. “İstekler dakikada 100 ile sınırlıdır” ifadesi “Sandbox” altında bir anlama, “Production” altında başka bir anlama gelir. Başlık olmadan ne geri getirici ne de model hangisi olduğunu söyleyemez.

Markdown, belgenin ana hatlarını #, ## ve ### ile başlayan satırlar olarak tutar. Başlığa dayalı bir bölücü bu satırlarda keser; böylece her parça tek bir bölümü kapsar ve parçanın üstündeki başlıkları, yani bölüm yolunu kaydeder. LangChain’in Markdown bölme rehberi aynı fikri anlatır: metni ait olduğu başlıklarla birlikte tutun.

Bölümlerin uzunluğu değişir; bu yüzden uzun bir bölüm yine de boyuta göre ikinci bir bölmeye ihtiyaç duyar. Bölüm yolu, onun her parçası için geçerlidir.

PDF’leri dönüştürün ve başlıkları kontrol edin

MD Factory’de PDF’lerinizin bulunduğu klasörü ekleyin. Her Markdown dosyası, görselleri yanındaki bir klasörde olacak şekilde, PDF’sinin yanına aynı adla kaydedilir. Taranmış PDF’ler bilgisayarınızda OCR’dan geçer. Klasördeki Word dosyaları ve diğer biçimler de aynı şekilde dönüştürülür.

Herhangi bir bölme kodu yazmadan önce birkaç sonucu açın:

  • Bölümlerin, alt bölümlerin ve alt alt bölümlerin #, ## ve ### olarak çıktığından emin olun. Bir PDF çoğu zaman bir başlığı yalnızca daha büyük veya daha kalın bir yazı tipiyle belirtir; bu yüzden her dönüştürücü, bölümlerin nerede başladığını ve nasıl iç içe geçtiğini çıkarım yoluyla bulmak zorundadır. Düzeylerin yanlış olduğu yerleri düzeltin.
  • Word dosyalarında başlıklar, yazar Word’ün Başlık stillerini kullandıysa aktarılır. Yalnızca kalın veya büyük olan metin sıradan bir paragraf olarak kalır.
  • Metnin ortasında yinelenen üst bilgiler, alt bilgiler ve sayfa numaraları olup olmadığına bakın.
  • Neye bakılacağını görmek için bir dosyanın yanındaki İnceleme gerekiyor’a tıklayın. Bir PDF için liste, OCR’nin metnin bir kısmını okuyamadığı veya hiç metin bulamadığı sayfaları içerebilir.

Sorunları indekslemeden önce Markdown dosyasında düzeltin. Her parça bunları devralır.

Kodla başlıklara göre bölün

LangChain’in MarkdownHeaderTextSplitter sınıfı sizin listelediğiniz başlık düzeylerinde böler ve her başlığı parçanın meta verisine koyar. İkinci bir bölücü her bölümün içindeki boyutu sınırlar:

from pathlib import Path
from langchain_text_splitters import (
    MarkdownHeaderTextSplitter,
    RecursiveCharacterTextSplitter,
)

corpus = Path("corpus")
by_heading = MarkdownHeaderTextSplitter(
    [("#", "h1"), ("##", "h2"), ("###", "h3")], strip_headers=False
)
by_size = RecursiveCharacterTextSplitter(chunk_size=1500, chunk_overlap=150)

chunks = []
for path in sorted(corpus.rglob("*.md")):
    sections = by_heading.split_text(path.read_text(encoding="utf-8"))
    for chunk in by_size.split_documents(sections):
        chunk.metadata["source"] = path.relative_to(corpus).as_posix()
        chunk.metadata["section"] = " > ".join(
            chunk.metadata[h] for h in ("h1", "h2", "h3") if h in chunk.metadata
        )
        chunks.append(chunk)

Buradaki parça boyutu ve örtüşme bir başlangıç noktasıdır; bunları gömme modelinize göre ayarlayın. Başlık satırlarını parça metninde tutmak için, böylece gömdüğünüz metin kendi bölümünün adını da taşısın, örnek şunu ayarlar: strip_headers=False.

LlamaIndex’in MarkdownNodeParser sınıfı aynı başlık bölmesini yapar. Dosyaları SimpleDirectoryReader ile yüklediğinizde her düğüm dosya adını da taşır:

from llama_index.core import SimpleDirectoryReader
from llama_index.core.node_parser import MarkdownNodeParser

documents = SimpleDirectoryReader(
    "corpus", recursive=True, required_exts=[".md"]
).load_data()
nodes = MarkdownNodeParser().get_nodes_from_documents(documents)
print(nodes[0].metadata["file_name"], nodes[0].metadata["header_path"])

header_path bir düğümün üstündeki başlıkları listeler, örneğin /Employee handbook/Expenses/; düğümün kendi başlığı metninin ilk satırıdır.

Her parçayla birlikte kaynağı da saklayın

Her parçayla birlikte en az üç şeyi saklayın:

  • Dosya. Bir Markdown dosyası PDF’siyle aynı ada sahiptir; bu yüzden handbook.md içindeki bir parça handbook.pdf dosyasına geri götürür. Yolu derlem klasörüne göre saklayın, çünkü farklı klasörlerdeki terms.md adlı iki dosya farklı belgelerdir.
  • Bölüm yolu; böylece bir yanıt kullandığı bölümü belirtebilir ve okur doğrudan ilgili pasaja gidebilir.
  • Baskı veya tarih. Bir politika değiştiğinde iki sürümü birden sunmak yerine eski dosyanın parçalarını silip yenilerini indekslersiniz.

Farklı erişim haklarına sahip kişiler aynı indeksi sorgulayacaksa her belgeyi kimin okuyabileceğini de saklayın ve sorgu sırasında buna göre filtreleyin. Bir geri getirici, soruyla eşleşen her parçayı döndürür.

MD Factory’nin ürettiği Markdown’da sayfa numaraları yoktur. Yanıtlar sayfa göstermek zorundaysa pasajı orijinal PDF’de bulun.

Tabloları ve OCR metnini dikkatle ele alın

Bir Markdown tablosunun başlık satırı yalnızca bir kez, en üsttedir. Bir tablo parça boyutunuzdan uzunsa boyut bölücü onu keser ve sonraki parçalar sütun adları olmadan gelir. LangChain ile yaptığımız testte (langchain-text-splitters 1.1.3), 300 karakterlik parçalara bölünen 40 satırlık bir tablo dört parça verdi ve yalnızca ilkinde başlık satırı vardı.

Bunu düzeltmenin iki yolu: her tabloyu, diğerlerinden uzun olsa bile, tek bir parçada tutmak ya da başlık satırını her parçanın başında tekrarlamak.

Word ve Excel dosyaları için MD Factory, birleştirilmiş veya karmaşık hücreler basitleştirildiğinde belgeyi İnceleme gerekiyor olarak işaretler. PDF tablolarında böyle bir işaret yoktur; bu yüzden birkaçını, özellikle birleştirilmiş başlıklı tabloları, orijinalle karşılaştırın.

OCR metni kendi kontrolünü gerektirir. Yanlış okunmuş sayılar, adlar ve kodlar yanıtlara olduğu gibi girer ve parçada yanlış görünen hiçbir şey olmaz. Birkaç parçadaki rakamları taramayla karşılaştırın ve işaretlenen sayfaları siz düzeltene kadar indeksin dışında bırakın. Nelere bakılacağı şu rehberimizde anlatılıyor: taranmış PDF’lerde OCR kontrolü rehberi.

Geri getirmeyi gerçek sorularla test edin

İnsanların gerçekten soracağı soruları ve her biri için yanıtı barındıran dosya ile bölümü yazın. Bir ya da iki düzineyle başlayın.

  1. Her soruyu geri getiricinizden geçirin ve ilk sonuçlara bakın.
  2. Doğru bölümün aralarında olup olmadığını not edin.
  3. Her ıskalama için geri gelen parçaları, gelmesi gereken parçayla karşılaştırın. Tipik nedenler: yanlış bir başlık düzeyi, başlığından koparılmış bir tablo, anahtar terimde bir OCR hatası ya da yanıtın içinde gömülü kaldığı çok uzun bir bölüm.
  4. Parça boyutu, başlık düzeyleri veya tabloların bölünme biçimi gibi tek bir şeyi değiştirin ve aynı soruları yeniden çalıştırın.

Soruları derlemin yanındaki bir dosyada tutun ve belgeler ya da bölme kodu değiştiğinde yeniden çalıştırın.

MD Factory ne zaman, kütüphane ne zaman kullanılır

MD Factory, Windows için bir masaüstü uygulamasıdır. Kendi bilgisayarınızda dönüştürmek ve gözle kontrol etmek istediğiniz özel bir koleksiyona uygundur: bir klasör ekleyin, durumlara bakın, incelenmesi gereken dosyaları açın, düzeltin, ardından indeksleme betiğinizi klasöre yönlendirin.

MD Factory, dönüştürürken belgeleri bilgisayarınızda tutar. Parçaları daha sonra barındırılan bir gömme API’siyle gömerseniz ya da barındırılan bir modele gönderirseniz metinleri o sağlayıcıya gider. Belgeler ağınızdan çıkmamalıysa yerel bir model kullanın.

Belgeler sürekli geliyorsa, bir sunucuda yaşıyorsa ya da başında kimse yokken dönüştürülmesi gerekiyorsa bunun yerine kodunuzda bir dönüştürme kütüphanesi kullanın. Seçenekler için bkz. PDF’den Markdown’a dönüştürücülerin karşılaştırması.