Der LLM Graph Transformer arbeitet in zwei unterschiedlichen Modi, die jeweils darauf ausgelegt sind, mithilfe eines LLM in unterschiedlichen Szenarien Diagramme aus Dokumenten zu generieren.

  1. Werkzeugbasierter Modus (Customary): Wenn das LLM strukturierte Ausgaben oder Funktionsaufrufe unterstützt, nutzt dieser Modus die LLM ist integriert with_structured_outputWerkzeuge zu benutzen. Die Device-Spezifikation definiert das Ausgabeformat und stellt sicher, dass Entitäten und Beziehungen auf strukturierte, vordefinierte Weise extrahiert werden. Dies ist auf der linken Seite des Bildes dargestellt, wo Code für die Klassen Node und Relationship angezeigt wird.
  2. Aufforderungsbasierter Modus (Fallback): In Situationen, in denen das LLM keine Instruments oder Funktionsaufrufe unterstützt, greift der LLM Graph Transformer auf einen rein auf Eingabeaufforderungen basierenden Ansatz zurück. In diesem Modus wird das Ausgabeformat mithilfe von Few-Shot-Prompts definiert, wodurch der LLM angeleitet wird, Entitäten und Beziehungen auf textbasierte Weise zu extrahieren. Die Ergebnisse werden dann durch eine benutzerdefinierte Funktion analysiert, die die Ausgabe des LLM in ein JSON-Format konvertiert. Dieser JSON wird zum Auffüllen von Knoten und Beziehungen verwendet, genau wie im Device-basierten Modus, aber hier wird das LLM vollständig durch Eingabeaufforderungen und nicht durch strukturierte Instruments gesteuert. Dies wird auf der rechten Seite des Bildes angezeigt, wo eine Beispielaufforderung und die resultierende JSON-Ausgabe bereitgestellt werden.

Diese beiden Modi stellen sicher, dass der LLM Graph Transformer an verschiedene LLMs anpassbar ist, sodass er Diagramme entweder direkt mithilfe von Instruments oder durch Parsen der Ausgabe einer textbasierten Eingabeaufforderung erstellen kann.

Beachten Sie, dass Sie die aufforderungsbasierte Extraktion auch bei Modellen verwenden können, die Instruments/Funktionen unterstützen, indem Sie das Attribut festlegen ignore_tools_usage=True.

Werkzeugbasierte Extraktion

Wir haben uns zunächst für einen Device-basierten Ansatz zur Extraktion entschieden, da dadurch der Bedarf an umfangreichen Immediate-Engineering- und benutzerdefinierten Parsing-Funktionen minimiert wurde. In LangChain ist die with_structured_output Mit der Methode können Sie Informationen mithilfe von Instruments oder Funktionen extrahieren, wobei die Ausgabe entweder über eine JSON-Struktur oder ein Pydantic-Objekt definiert wird. Persönlich finde ich Pydantic-Objekte klarer, deshalb haben wir uns dafür entschieden.

Wir beginnen mit der Definition von a Node Klasse.

class Node(BaseNode):
id: str = Area(..., description="Identify or human-readable distinctive identifier")
label: str = Area(..., description=f"Out there choices are {enum_values}")
properties: Elective(Record(Property))

Jeder Knoten hat eine idA labelund non-compulsory properties. Der Kürze halber habe ich hier keine vollständigen Beschreibungen eingefügt. Die Beschreibung von IDs als für Menschen lesbare eindeutige Kennungen ist wichtig, da einige LLMs dazu neigen, ID-Eigenschaften auf traditionellere Weise wie Zufallszeichenfolgen oder inkrementelle Ganzzahlen zu verstehen. Stattdessen möchten wir, dass der Identify von Entitäten als ID-Eigenschaft verwendet wird. Wir schränken auch die verfügbaren Etikettentypen ein, indem wir sie einfach im auflisten labelBeschreibung. Darüber hinaus unterstützen LLMs wie OpenAI eine enum Parameter, den wir auch verwenden.

Als nächstes werfen wir einen Blick auf die Relationship Klasse

class Relationship(BaseRelationship):
source_node_id: str
source_node_label: str = Area(..., description=f"Out there choices are {enum_values}")
target_node_id: str
target_node_label: str = Area(..., description=f"Out there choices are {enum_values}")
sort: str = Area(..., description=f"Out there choices are {enum_values}")
properties: Elective(Record(Property))

Dies ist die zweite Iteration des Relationship Klasse. Anfangs haben wir eine verschachtelte Methode verwendet Node Objekt für die Quell- und Zielknoten, aber wir stellten schnell fest, dass verschachtelte Objekte die Genauigkeit und Qualität des Extraktionsprozesses beeinträchtigten. Deshalb haben wir beschlossen, die Quell- und Zielknoten in separate Felder zusammenzufassen – zum Beispiel: source_node_id Und source_node_labelzusammen mit target_node_id Und target_node_label. Darüber hinaus definieren wir die zulässigen Werte in den Beschreibungen für Knotenbezeichnungen und Beziehungstypen, um sicherzustellen, dass die LLMs dem angegebenen Diagrammschema entsprechen.

Der werkzeugbasierte Extraktionsansatz ermöglicht es uns, Eigenschaften sowohl für Knoten als auch für Beziehungen zu definieren. Nachfolgend finden Sie die Klasse, mit der wir sie definiert haben.

class Property(BaseModel):
"""A single property consisting of key and worth"""
key: str = Area(..., description=f"Out there choices are {enum_values}")
worth: str

Jede Property ist als Schlüssel-Wert-Paar definiert. Obwohl dieser Ansatz flexibel ist, hat er seine Grenzen. Wir können beispielsweise nicht für jede Eigenschaft eine eindeutige Beschreibung bereitstellen oder bestimmte Eigenschaften als obligatorisch und andere non-compulsory festlegen, sodass alle Eigenschaften als non-compulsory definiert sind. Darüber hinaus werden Eigenschaften nicht für jeden Knoten oder Beziehungstyp einzeln definiert, sondern werden stattdessen von allen gemeinsam genutzt.

Wir haben auch eine implementiert detaillierte Systemaufforderung um die Extraktion zu leiten. Meiner Erfahrung nach haben jedoch die Funktions- und Argumentbeschreibungen tendenziell eine größere Auswirkung als die Systemmeldung.

Leider gibt es derzeit keine einfache Möglichkeit, Funktions- oder Argumentbeschreibungen in LLM Graph Transformer anzupassen.

Immediate-basierte Extraktion

Da nur wenige kommerzielle LLMs und LLaMA 3 native Instruments unterstützen, haben wir einen Fallback für Modelle ohne Device-Unterstützung implementiert. Sie können auch einstellen ignore_tool_usage=True um zu einem auf Eingabeaufforderungen basierenden Ansatz zu wechseln, auch wenn ein Modell verwendet wird, das Instruments unterstützt.

Die meisten Immediate-Engineering-Beispiele und Beispiele für den Immediate-basierten Ansatz wurden von beigesteuert Geraldus Wilsen.

Beim Immediate-basierten Ansatz müssen wir die Ausgabestruktur direkt im Immediate definieren. Sie finden die ganze Eingabeaufforderung hier. In diesem Blogbeitrag geben wir lediglich einen allgemeinen Überblick. Wir beginnen mit der Definition der Systemeingabeaufforderung.

You're a top-tier algorithm designed for extracting info in structured codecs to construct a information graph. Your process is to determine the entities and relations specified within the consumer immediate from a given textual content and produce the output in JSON format. This output must be a listing of JSON objects, with every object containing the next keys:

- **"head"**: The textual content of the extracted entity, which should match one of many sorts specified within the consumer immediate.
- **"head_type"**: The kind of the extracted head entity, chosen from the desired record of sorts.
- **"relation"**: The kind of relation between the "head" and the "tail," chosen from the record of allowed relations.
- **"tail"**: The textual content of the entity representing the tail of the relation.
- **"tail_type"**: The kind of the tail entity, additionally chosen from the supplied record of sorts.

Extract as many entities and relationships as potential.

**Entity Consistency**: Guarantee consistency in entity illustration. If an entity, like "John Doe," seems a number of occasions within the textual content below completely different names or pronouns (e.g., "Joe," "he"), use probably the most full identifier persistently. This consistency is important for making a coherent and simply comprehensible information graph.

**Essential Notes**:
- Don't add any additional explanations or textual content.

Beim auf Eingabeaufforderungen basierenden Ansatz besteht ein wesentlicher Unterschied darin, dass wir den LLM bitten, nur Beziehungen und keine einzelnen Knoten zu extrahieren. Das heißt, wir werden keine haben isolierte Knotenanders als beim werkzeugbasierten Ansatz. Da Modelle ohne native Toolunterstützung in der Regel eine schlechtere Leistung erbringen, erlauben wir außerdem keine Extraktion von Eigenschaften – weder für Knoten noch für Beziehungen –, um die Extraktionsausgabe einfacher zu halten.

Als Nächstes fügen wir dem Modell einige wenige Beispiele hinzu.

examples = (
{
"textual content": (
"Adam is a software program engineer in Microsoft since 2009, "
"and final 12 months he received an award because the Finest Expertise"
),
"head": "Adam",
"head_type": "Individual",
"relation": "WORKS_FOR",
"tail": "Microsoft",
"tail_type": "Firm",
},
{
"textual content": (
"Adam is a software program engineer in Microsoft since 2009, "
"and final 12 months he received an award because the Finest Expertise"
),
"head": "Adam",
"head_type": "Individual",
"relation": "HAS_AWARD",
"tail": "Finest Expertise",
"tail_type": "Award",
},
...
)

Bei diesem Ansatz gibt es derzeit keine Unterstützung für das Hinzufügen benutzerdefinierter Beispiele für wenige Aufnahmen oder zusätzlicher Anweisungen. Die einzige Möglichkeit zur Anpassung besteht darin, die gesamte Eingabeaufforderung über zu ändern immediateAttribut. Wir denken aktiv darüber nach, die Anpassungsmöglichkeiten zu erweitern.

Als Nächstes werfen wir einen Blick auf die Definition des Diagrammschemas.

Wenn Sie den LLM Graph Transformer zur Informationsextraktion verwenden, ist die Definition eines Diagrammschemas von entscheidender Bedeutung, um das Modell bei der Erstellung aussagekräftiger und strukturierter Wissensdarstellungen zu unterstützen. Ein wohldefiniertes Diagrammschema gibt die zu extrahierenden Knoten- und Beziehungstypen sowie alle damit verbundenen Attribute an. Dieses Schema dient als Blaupause und stellt sicher, dass das LLM relevante Informationen konsistent auf eine Weise extrahiert, die mit der gewünschten Struktur des Wissensgraphen übereinstimmt.

In diesem Blogbeitrag verwenden wir den ersten Absatz von Wikipedia-Seite von Marie Curie zum Testen mit einem zusätzlichen Satz am Ende über Robin Williams.

from langchain_core.paperwork import Doc

textual content = """
Marie Curie, 7 November 1867 – 4 July 1934, was a Polish and naturalised-French physicist and chemist who performed pioneering analysis on radioactivity.
She was the primary lady to win a Nobel Prize, the primary particular person to win a Nobel Prize twice, and the one particular person to win a Nobel Prize in two scientific fields.
Her husband, Pierre Curie, was a co-winner of her first Nobel Prize, making them the first-ever married couple to win the Nobel Prize and launching the Curie household legacy of 5 Nobel Prizes.
She was, in 1906, the primary lady to grow to be a professor on the College of Paris.
Additionally, Robin Williams.
"""
paperwork = (Doc(page_content=textual content))

Wir werden in allen Beispielen auch GPT-4o verwenden.

from langchain_openai import ChatOpenAI
import getpass
import os

os.environ("OPENAI_API_KEY") = getpass.getpass("OpenAI api key")

llm = ChatOpenAI(mannequin='gpt-4o')

Lassen Sie uns zunächst untersuchen, wie der Extraktionsprozess funktioniert, ohne ein Diagrammschema zu definieren.

from langchain_experimental.graph_transformers import LLMGraphTransformer

no_schema = LLMGraphTransformer(llm=llm)

Jetzt können wir die Dokumente mit dem bearbeiten aconvert_to_graph_documents Funktion, die asynchron ist. Die Verwendung von Async mit LLM-Extraktion wird empfohlen, da dadurch die parallele Verarbeitung mehrerer Dokumente ermöglicht wird. Dieser Ansatz kann Wartezeiten erheblich verkürzen und den Durchsatz verbessern, insbesondere bei der Bearbeitung mehrerer Dokumente.

knowledge = await no_schema.aconvert_to_graph_documents(paperwork)

Die Antwort des LLM Graph Transformer ist ein Diagrammdokument mit der folgenden Struktur:

(
GraphDocument(
nodes=(
Node(id="Marie Curie", sort="Individual", properties={}),
Node(id="Pierre Curie", sort="Individual", properties={}),
Node(id="Nobel Prize", sort="Award", properties={}),
Node(id="College Of Paris", sort="Group", properties={}),
Node(id="Robin Williams", sort="Individual", properties={}),
),
relationships=(
Relationship(
supply=Node(id="Marie Curie", sort="Individual", properties={}),
goal=Node(id="Nobel Prize", sort="Award", properties={}),
sort="WON",
properties={},
),
Relationship(
supply=Node(id="Marie Curie", sort="Individual", properties={}),
goal=Node(id="Nobel Prize", sort="Award", properties={}),
sort="WON",
properties={},
),
Relationship(
supply=Node(id="Marie Curie", sort="Individual", properties={}),
goal=Node(
id="College Of Paris", sort="Group", properties={}
),
sort="PROFESSOR",
properties={},
),
Relationship(
supply=Node(id="Pierre Curie", sort="Individual", properties={}),
goal=Node(id="Nobel Prize", sort="Award", properties={}),
sort="WON",
properties={},
),
),
supply=Doc(
metadata={"id": "de3c93515e135ac0e47ca82a4f9b82d8"},
page_content="nMarie Curie, 7 November 1867 – 4 July 1934, was a Polish and naturalised-French physicist and chemist who performed pioneering analysis on radioactivity.nShe was the primary lady to win a Nobel Prize, the primary particular person to win a Nobel Prize twice, and the one particular person to win a Nobel Prize in two scientific fields.nHer husband, Pierre Curie, was a co-winner of her first Nobel Prize, making them the first-ever married couple to win the Nobel Prize and launching the Curie household legacy of 5 Nobel Prizes.nShe was, in 1906, the primary lady to grow to be a professor on the College of Paris.nAlso, Robin Williams!n",
),
)
)

Das Diagrammdokument beschreibt extrahiert nodes Und relationships . Zusätzlich wird das Quelldokument der Extraktion unter hinzugefügt supply Schlüssel.

Wir können den Neo4j-Browser verwenden, um die Ausgaben zu visualisieren und so ein klareres und intuitiveres Verständnis der Daten zu ermöglichen.

Von admin

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert