Umgang mit langen Texten
Bei der Arbeit mit Dateien wie PDFs kann es vorkommen, dass der Text den Kontextbereich Ihres Sprachmodells überschreitet. Um diesen Text zu verarbeiten, sollten Sie die folgenden Strategien in Betracht ziehen:
- LLM ändern Wählen Sie einen anderen LLM, der einen größeren Kontextbereich unterstützt.
- Brute Force Teilen Sie das Dokument in Abschnitte auf und extrahieren Sie den Inhalt aus jedem Abschnitt.
- RAG Teilen Sie das Dokument in Abschnitte auf, indizieren Sie die Abschnitte und extrahieren Sie den Inhalt nur aus einem Teil der Abschnitte, die "relevant" aussehen.
Denken Sie daran, dass diese Strategien unterschiedliche Kompromisse haben und die beste Strategie wahrscheinlich von der Anwendung abhängt, die Sie entwerfen!
Einrichten
Wir brauchen einige Beispieldaten! Laden wir einen Artikel über Autos von Wikipedia herunter und laden ihn als LangChain Dokument
.
import re
import requests
from langchain_community.document_loaders import BSHTMLLoader
response = requests.get("https://en.wikipedia.org/wiki/Car")
with open("car.html", "w", encoding="utf-8") as f:
f.write(response.text)
loader = BSHTMLLoader("car.html")
document = loader.load()[0]
document.page_content = re.sub("\n\n+", "\n", document.page_content)
print(len(document.page_content))
78967
Schema definieren
Hier werden wir das Schema definieren, um wichtige Entwicklungen aus dem Text zu extrahieren.
from typing import List, Optional
from langchain.chains import create_structured_output_runnable
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.pydantic_v1 import BaseModel, Field
from langchain_openai import ChatOpenAI
class KeyDevelopment(BaseModel):
"""Informationen über eine Entwicklung in der Geschichte der Autos."""
year: int = Field(
..., description="Das Jahr, in dem eine wichtige historische Entwicklung stattfand."
)
description: str = Field(
..., description="Was ist in diesem Jahr passiert? Was war die Entwicklung?"
)
evidence: str = Field(
...,
description="Wiederholen Sie wörtlich die Sätze, aus denen die Informationen zum Jahr und zur Beschreibung extrahiert wurden",
)
class ExtractionData(BaseModel):
"""Extrahierte Informationen über wichtige Entwicklungen in der Geschichte der Autos."""
key_developments: List[KeyDevelopment]
prompt = ChatPromptTemplate.from_messages(
[
(
"system",
"Sie sind ein Experte darin, wichtige historische Entwicklungen im Text zu identifizieren. "
"Extrahieren Sie nur wichtige historische Entwicklungen. Extrahieren Sie nichts, wenn keine wichtigen Informationen im Text gefunden werden können.",
),
("human", "{text}"),
]
)
llm = ChatOpenAI(
model="gpt-4-0125-preview",
temperature=0,
)
extractor = prompt | llm.with_structured_output(
schema=ExtractionData,
method="function_calling",
include_raw=False,
)
/home/eugene/.pyenv/versions/3.11.2/envs/langchain_3_11/lib/python3.11/site-packages/langchain_core/_api/beta_decorator.py:86: LangChainBetaWarning: Die Funktion `with_structured_output` befindet sich in der Betaphase. Sie wird aktiv weiterentwickelt, daher kann sich die API ändern.
warn_beta(
Brute-Force-Ansatz
Teilen Sie die Dokumente in Abschnitte auf, sodass jeder Abschnitt in den Kontextbereich der LLMs passt.
from langchain_text_splitters import TokenTextSplitter
text_splitter = TokenTextSplitter(
chunk_size=2000,
chunk_overlap=20,
)
texts = text_splitter.split_text(document.page_content)
Nutzen Sie die .batch
-Funktionalität, um die Extraktion in parallelen Prozessen für jeden Abschnitt durchzuführen!
Tipp
Oft können Sie .batch() verwenden, um die Extraktionen parallel auszuführen! batch
verwendet unter der Oberfläche einen Threadpool, um Workloads zu parallelisieren.
Wenn Ihr Modell über eine API verfügbar ist, wird dies wahrscheinlich den Extraktionsfluss beschleunigen!
first_few = texts[:3]
extractions = extractor.batch(
[{"text": text} for text in first_few],
{"max_concurrency": 5}, # Begrenzen Sie die Parallelität durch Angabe der maximalen Anzahl gleichzeitiger Vorgänge!
)
Ergebnisse zusammenführen
Nachdem wir die Daten aus den Chunks extrahiert haben, möchten wir die Extraktionen zusammenführen.
key_developments = []
for extraction in extractions:
key_developments.extend(extraction.key_developments)
key_developments[:20]
[KeyDevelopment(year=1966, description="The Toyota Corolla began production, recognized as the world's best-selling automobile.", evidence="The Toyota Corolla has been in production since 1966 and is recognized as the world's best-selling automobile."),
KeyDevelopment(year=1769, description='Nicolas-Joseph Cugnot built the first steam-powered road vehicle.', evidence='French inventor Nicolas-Joseph Cugnot built the first steam-powered road vehicle in 1769.'),
KeyDevelopment(year=1808, description='François Isaac de Rivaz designed and constructed the first internal combustion-powered automobile.', evidence='French-born Swiss inventor François Isaac de Rivaz designed and constructed the first internal combustion-powered automobile in 1808.'),
KeyDevelopment(year=1886, description='Carl Benz patented his Benz Patent-Motorwagen, inventing the modern car.', evidence='The modern car—a practical, marketable automobile for everyday use—was invented in 1886, when German inventor Carl Benz patented his Benz Patent-Motorwagen.'),
KeyDevelopment(year=1908, description='The 1908 Model T, an affordable car for the masses, was manufactured by the Ford Motor Company.', evidence='One of the first cars affordable by the masses was the 1908 Model T, an American car manufactured by the Ford Motor Company.'),
KeyDevelopment(year=1881, description='Gustave Trouvé demonstrated a three-wheeled car powered by electricity.', evidence='In November 1881, French inventor Gustave Trouvé demonstrated a three-wheeled car powered by electricity at the International Exposition of Electricity.'),
KeyDevelopment(year=1888, description="Bertha Benz undertook the first road trip by car to prove the road-worthiness of her husband's invention.", evidence="In August 1888, Bertha Benz, the wife of Carl Benz, undertook the first road trip by car, to prove the road-worthiness of her husband's invention."),
KeyDevelopment(year=1896, description='Benz designed and patented the first internal-combustion flat engine, called boxermotor.', evidence='In 1896, Benz designed and patented the first internal-combustion flat engine, called boxermotor.'),
KeyDevelopment(year=1897, description='Nesselsdorfer Wagenbau produced the Präsident automobil, one of the first factory-made cars in the world.', evidence='The first motor car in central Europe and one of the first factory-made cars in the world, was produced by Czech company Nesselsdorfer Wagenbau (later renamed to Tatra) in 1897, the Präsident automobil.'),
KeyDevelopment(year=1890, description='Daimler Motoren Gesellschaft (DMG) was founded by Daimler and Maybach in Cannstatt.', evidence='Daimler and Maybach founded Daimler Motoren Gesellschaft (DMG) in Cannstatt in 1890.'),
KeyDevelopment(year=1902, description='A new model DMG car was produced and named Mercedes after the Maybach engine.', evidence='Two years later, in 1902, a new model DMG car was produced and the model was named Mercedes after the Maybach engine, which generated 35 hp.'),
KeyDevelopment(year=1891, description='Auguste Doriot and Louis Rigoulot completed the longest trip by a petrol-driven vehicle using a Daimler powered Peugeot Type 3.', evidence='In 1891, Auguste Doriot and his Peugeot colleague Louis Rigoulot completed the longest trip by a petrol-driven vehicle when their self-designed and built Daimler powered Peugeot Type 3 completed 2,100 kilometres (1,300 mi) from Valentigney to Paris and Brest and back again.'),
KeyDevelopment(year=1895, description='George Selden was granted a US patent for a two-stroke car engine.', evidence='After a delay of 16 years and a series of attachments to his application, on 5 November 1895, Selden was granted a US patent (U.S. patent 549,160) for a two-stroke car engine.'),
KeyDevelopment(year=1893, description='The first running, petrol-driven American car was built and road-tested by the Duryea brothers.', evidence='In 1893, the first running, petrol-driven American car was built and road-tested by the Duryea brothers of Springfield, Massachusetts.'),
KeyDevelopment(year=1897, description='Rudolf Diesel built the first diesel engine.', evidence='In 1897, he built the first diesel engine.'),
KeyDevelopment(year=1901, description='Ransom Olds started large-scale, production-line manufacturing of affordable cars at his Oldsmobile factory.', evidence='Large-scale, production-line manufacturing of affordable cars was started by Ransom Olds in 1901 at his Oldsmobile factory in Lansing, Michigan.'),
KeyDevelopment(year=1913, description="Henry Ford began the world's first moving assembly line for cars at the Highland Park Ford Plant.", evidence="This concept was greatly expanded by Henry Ford, beginning in 1913 with the world's first moving assembly line for cars at the Highland Park Ford Plant."),
KeyDevelopment(year=1914, description="Ford's assembly line worker could buy a Model T with four months' pay.", evidence="In 1914, an assembly line worker could buy a Model T with four months' pay."),
KeyDevelopment(year=1926, description='Fast-drying Duco lacquer was developed, allowing for a variety of car colors.', evidence='Only Japan black would dry fast enough, forcing the company to drop the variety of colours available before 1913, until fast-drying Duco lacquer was developed in 1926.')]
Thank you for considering my response. I will now proceed with the translation. If you have any specific material that requires translation, please feel free to share it with me.
RAG-basierte Methode
Eine weitere einfache Idee ist, den Text in Abschnitte zu unterteilen, aber anstatt Informationen aus jedem Abschnitt zu extrahieren, sich nur auf die relevantesten Abschnitte zu konzentrieren.
Vorsicht
Es kann schwierig sein, festzustellen, welche Abschnitte relevant sind.
Zum Beispiel enthält der Artikel über Autos
, den wir hier verwenden, die meisten wichtigen Entwicklungsdaten. Daher werden wir durch die Verwendung von RAG wahrscheinlich viele relevante Informationen verwerfen.
Wir empfehlen, mit Ihrem Anwendungsfall zu experimentieren und zu bestimmen, ob dieser Ansatz funktioniert oder nicht.
Hier ist ein einfaches Beispiel, das auf dem FAISS
Vectorstore basiert.
from langchain_community.vectorstores import FAISS
from langchain_core.documents import Document
from langchain_core.runnables import RunnableLambda
from langchain_openai import OpenAIEmbeddings
from langchain_text_splitters import CharacterTextSplitter
texts = text_splitter.split_text(document.page_content)
vectorstore = FAISS.from_texts(texts, embedding=OpenAIEmbeddings())
retriever = vectorstore.as_retriever(
search_kwargs={"k": 1}
) # Nur aus dem ersten Dokument extrahieren
In diesem Fall betrachtet der RAG-Extractor nur das oberste Dokument.
rag_extractor = {
"text": retriever | (lambda docs: docs[0].page_content) # Inhalt des obersten Dokuments abrufen
} | extractor
results = rag_extractor.invoke("Schlüsselentwicklungen im Zusammenhang mit Autos")
for key_development in results.key_developments:
print(key_development)
jahr=1924 beschreibung="Deutschlands erster seriengefertigter Wagen, der Opel 4PS Laubfrosch, wurde hergestellt und machte Opel mit 37,5 % Marktanteil zum führenden Autohersteller in Deutschland." beweis="Deutschlands erster seriengefertigter Wagen, der Opel 4PS Laubfrosch, rollte 1924 in Rüsselsheim vom Band und machte Opel bald zum führenden Autohersteller in Deutschland, mit 37,5 Prozent Marktanteil."
jahr=1925 beschreibung='Morris hatte einen Anteil von 41 % an der Gesamtproduktion britischer Autos und dominierte den Markt.' beweis='1925 hatte Morris einen Anteil von 41 Prozent an der Gesamtproduktion britischer Autos.'
jahr=1925 beschreibung='Citroën, Renault und Peugeot produzierten 550.000 Autos in Frankreich und dominierten den Markt.' beweis="Citroën tat dasselbe in Frankreich und kam bereits 1919 zum Automobil; zusammen mit anderen günstigen Autos wie Renaults 10CV und Peugeots 5CV produzierten sie 1925 insgesamt 550.000 Autos."
jahr=2017 beschreibung='Die Produktion von benzinbetriebenen Autos erreichte ihren Höhepunkt.' beweis='Die Produktion von benzinbetriebenen Autos erreichte 2017 ihren Höhepunkt.'
Häufige Probleme
Verschiedene Methoden haben ihre eigenen Vor- und Nachteile in Bezug auf Kosten, Geschwindigkeit und Genauigkeit.
Achten Sie auf diese Probleme:
- Das Unterteilen des Inhalts bedeutet, dass der LLM möglicherweise keine Informationen extrahieren kann, wenn die Informationen über mehrere Abschnitte verteilt sind.
- Eine große Überlappung von Abschnitten kann dazu führen, dass dieselben Informationen zweimal extrahiert werden, seien Sie also auf Duplikate vorbereitet!
- LLMs können Daten erfinden. Wenn Sie nach einer einzelnen Tatsache in einem großen Text suchen und einen brachialen Ansatz verwenden, erhalten Sie möglicherweise mehr erfundene Daten.