Konwerter dokumentów

Konwerter dokumentów firmy LangChain głównie służy do segmentowania treści tekstu poprzez podział dużego artykułu na kilka mniejszych fragmentów treści. Robi się to, ponieważ duże modele zazwyczaj mają ograniczenia dotyczące długości zapytań i nie można przekazywać całej treści do sztucznej inteligencji. Nawet jeśli niektóre duże modele pozwalają na bardzo długą długość zapytania, z perspektywy kosztów nie jest praktyczne przekazywanie tak długiej treści do SI. Przecież im dłuższa treść, tym wyższy koszt wywołań interfejsu API (nawet dla modeli open-source wdrażanych lokalnie, dłuższa treść wymaga więcej pamięci GPU i spowalnia wnioskowanie). Rozsądnym podejściem jest łączenie odpowiednich fragmentów treści jako informacje tła i zapytania podczas żądania modelu SI.

LangChain posiada wiele wbudowanych konwerterów dokumentów, które mogą łatwo dzielić, łączyć i filtrować treści dokumentów.

Dzielnik tekstu

Podczas pracy z dużymi blokami tekstu należy podzielić tekst na fragmenty. Chociaż brzmi to prosto, istnieje wiele potencjalnych złożoności. Idealnie chcesz trzymać razem semantycznie powiązane segmenty tekstu. Termin "semantycznie powiązane" może tutaj zależeć od rodzaju tekstu.

Na wysokim poziomie, dzielnik tekstu działa następująco:

  1. Dziel tekst na małe, semantycznie znaczące bloki (zwykle zdania).
  2. Zacznij łączyć te małe bloki w większe, aż do osiągnięcia określonego rozmiaru (mierzonego jakąś funkcją).
  3. Gdy osiągnięty będzie ten rozmiar, potraktuj blok jako swój własny segment tekstu i zacznij tworzyć nowy blok tekstu z pewnym nakładaniem (aby zachować kontekst między blokami).

Oznacza to, że możesz dostosować dzielnik tekstu wzdłuż dwóch różnych osi:

  1. Jak podzielić tekst
  2. Jak zmierzyć rozmiar bloków

Przykład

Domyślnie zalecanym dzielnikiem tekstu jest RecursiveCharacterTextSplitter. Ten dzielnik tekstu akceptuje listę znaków. Próbuje tworzyć bloki na podstawie pierwszego znaku, ale jeśli którykolwiek blok jest zbyt duży, będzie kontynuował przechodzenie do następnego znaku i tak dalej. Domyślnie znakami, którymi próbuje podzielić, są ["\\\\n\\\\n", "\\\\n", " ", ""].

Oprócz kontroli, jakie znaki można podzielić, można także kontrolować kilka innych kwestii:

  • length_function: Jak obliczyć długość bloku. Domyślnie liczy się tylko liczba znaków, ale tutaj często przekazywane są liczniki tokenów.
  • chunk_size: Maksymalny rozmiar Twoich bloków (zmierzony funkcją długości).
  • chunk_overlap: Maksymalne nakładanie się między blokami. Zachowanie pewnego nakładania może pomóc zachować ciągłość między blokami (np. wykonywanie okna przesuwnego).
  • add_start_index: Czy dołączyć pozycję początkową każdego bloku w oryginalnym dokumencie do metadanych.
with open('../../state_of_the_union.txt') as f:
    state_of_the_union = f.read()
from langchain.text_splitter import RecursiveCharacterTextSplitter
text_splitter = RecursiveCharacterTextSplitter(
    chunk_size = 100,
    chunk_overlap  = 20,
    length_function = len,
    add_start_index = True,
)
texts = text_splitter.create_documents([state_of_the_union])
print(texts[0])
print(texts[1])
page_content='..ignorowany tekst..' metadata={'start_index': 0}
    page_content='..ignorowany tekst..' metadata={'start_index': 82}

Inne transformacje:

Filtracja zbędnych dokumentów, tłumaczenie dokumentów, wyodrębnianie metadanych i inne

Oprócz dzielenia dokumentów, możemy również wykonywać inne transformacje na zawartości dokumentów. Korzystając z EmbeddingsRedundantFilter, możemy zidentyfikować podobne dokumenty i odfiltrować zbędną treść. Dzięki integracjom takim jak doctran, możemy wykonywać operacje takie jak tłumaczenie dokumentów z jednego języka na inny, wyodrębnianie wymaganych właściwości i dodawanie ich do metadanych, oraz konwertowanie rozmów na zestaw sformatowanych pytań i odpowiedzi.