Analyse der Daten

LLMs, die gut auf prompte Anweisungen reagieren können, können damit beauftragt werden, Informationen in einem bestimmten Format auszugeben.

Dieser Ansatz basiert darauf, gute prompte zu entwerfen und dann die Ausgabe der LLMs zu parsen, um Informationen gut zu extrahieren.

Hier verwenden wir Claude, der gut darin ist, Anweisungen zu befolgen! Siehe Anthropic models.

from langchain_anthropic.chat_models import ChatAnthropic

model = ChatAnthropic(model_name="claude-3-sonnet-20240229", temperature=0)

Tipp: Für den Parsen-Ansatz gelten dieselben Überlegungen zur Extraktionsqualität. Lesen Sie die Richtlinien zur Extraktionsqualität durch.

Dieses Tutorial soll einfach sein, sollte aber im Allgemeinen wirklich Referenzbeispiele enthalten, um die Leistung zu maximieren!

Verwendung von PydanticOutputParser

Im folgenden Beispiel wird der integrierte PydanticOutputParser verwendet, um die Ausgabe eines Chat-Modells zu parsen.

from typing import List, Optional

from langchain.output_parsers import PydanticOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.pydantic_v1 import BaseModel, Field, validator


class Person(BaseModel):
    """Informationen über eine Person."""

    name: str = Field(..., description="Der Name der Person")
    height_in_meters: float = Field(
        ..., description="Die Größe der Person in Metern ausgedrückt."
    )


class People(BaseModel):
    """Identifizierungsinformationen über alle Personen in einem Text."""

    people: List[Person]


parser = PydanticOutputParser(pydantic_object=People)

prompt = ChatPromptTemplate.from_messages(
    [
        (
            "system",
            "Beantworte die Benutzerabfrage. Verpacke die Ausgabe in `json` Tags\n{format_instructions}",
        ),
        ("human", "{query}"),
    ]
).partial(format_instructions=parser.get_format_instructions())

Lassen Sie uns einen Blick darauf werfen, welche Informationen an das Modell gesendet werden.

query = "Anna ist 23 Jahre alt und 1,83 Meter groß"
print(prompt.format_prompt(query=query).to_string())
System: Beantworte die Benutzerabfrage. Verpacke die Ausgabe in `json` Tags
Die Ausgabe sollte als JSON-Instanz formatiert sein, die dem folgenden JSON-Schema entspricht.

Beispielsweise ist für das Schema {"properties": {"foo": {"title": "Foo", "description": "a list of strings", "type": "array", "items": {"type": "string"}}}, "required": ["foo"]}
das Objekt {"foo": ["bar", "baz"]} eine gut formatierte Instanz des Schemas. Das Objekt {"properties": {"foo": ["bar", "baz"]}} ist nicht gut formatiert.

Hier ist das Ausgabeschema:
{"description": "Identifizierungsinformationen über alle Personen in einem Text.", "properties": {"people": {"title": "People", "type": "array", "items": {"$ref": "#/definitions/Person"}}}, "required": ["people"], "definitions": {"Person": {"title": "Person", "description": "Informationen über eine Person.", "type": "object", "properties": {"name": {"title": "Name", "description": "Der Name der Person", "type": "string"}, "height_in_meters": {"title": "Höhe in Metern", "description": "Die Größe der Person in Metern ausgedrückt.", "type": "number"}}, "required": ["name", "height_in_meters"]}}}

Mensch: Anna ist 23 Jahre alt und 1,83 Meter groß
chain = prompt | model | parser
chain.invoke({"query": query})
People(people=[Person(name='Anna', height_in_meters=1.83)])

Benutzerdefiniertes Parsen

Es ist einfach, mit LangChain und LCEL eine benutzerdefinierte Eingabeaufforderung und Parser zu erstellen.

Sie können eine einfache Funktion verwenden, um die Ausgabe des Modells zu analysieren!

import json
import re
from typing import List, Optional

from langchain_anthropic.chat_models import ChatAnthropic
from langchain_core.messages import AIMessage
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.pydantic_v1 import BaseModel, Field, validator


class Person(BaseModel):
    """Informationen über eine Person."""

    name: str = Field(..., description="Der Name der Person")
    height_in_meters: float = Field(
        ..., description="Die Höhe der Person ausgedrückt in Metern."
    )


class People(BaseModel):
    """Identifizierungsinformationen über alle Personen in einem Text."""

    people: List[Person]


prompt = ChatPromptTemplate.from_messages(
    [
        (
            "system",
            "Beantworten Sie die Benutzerabfrage. Geben Sie Ihre Antwort als JSON aus, das dem angegebenen Schema entspricht: ```json\n{schema}\n```. "
            "Stellen Sie sicher, dass Sie die Antwort in ```json und ``` Tags einwickeln",
        ),
        ("human", "{query}"),
    ]
).partial(schema=People.schema())


def extract_json(message: AIMessage) -> List[dict]:
    """Extrahiert JSON-Inhalte aus einem String, in dem JSON zwischen den ```json und ``` Tags eingebettet ist.

    Parameter:
        text (str): Der Text, der den JSON-Inhalt enthält.

    Rückgabe:
        list: Eine Liste von extrahierten JSON-Strings.
    """
    text = message.content
    pattern = r"```json(.*?)```"

    matches = re.findall(pattern, text, re.DOTALL)

    try:
        return [json.loads(match.strip()) for match in matches]
    except Exception:
        raise ValueError(f"Parsing fehlgeschlagen: {message}")
query = "Anna ist 23 Jahre alt und 1,83 Meter groß"
print(prompt.format_prompt(query=query).to_string())
System: Beantworten Sie die Benutzerabfrage. Geben Sie Ihre Antwort als JSON aus, das dem angegebenen Schema entspricht: \`\`\`json
{'title': 'People', 'description': 'Identifizierungsinformationen über alle Personen in einem Text.', 'type': 'object', 'properties': {'people': {'title': 'People', 'type': 'array', 'items': {'$ref': '#/definitions/Person'}}}, 'required': ['people'], 'definitions': {'Person': {'title': 'Person', 'description': 'Informationen über eine Person.', 'type': 'object', 'properties': {'name': {'title': 'Name', 'description': 'Der Name der Person', 'type': 'string'}, 'height_in_meters': {'title': 'Höhe in Metern', 'description': 'Die Höhe der Person ausgedrückt in Metern.', 'type': 'number'}}, 'required': ['name', 'height_in_meters']}}}
\`\`\`. Stellen Sie sicher, dass Sie die Antwort in \`\`\`json und \`\`\` Tags einwickeln
Human: Anna ist 23 Jahre alt und 1,83 Meter groß
chain = prompt | model | extract_json
chain.invoke({"query": query})
[{'people': [{'name': 'Anna', 'height_in_meters': 1.83}]}]

Andere Bibliotheken

Wenn Sie eine Parsing-Technik zur Extrahierung betrachten, schauen Sie sich die Kor Bibliothek an. Sie wurde von einem der LangChain Maintainer geschrieben und hilft dabei, eine Eingabeaufforderung zu erstellen, die Beispiele berücksichtigt, das Format kontrolliert (z. B. JSON oder CSV) und das Schema in TypeScript ausdrückt. Es scheint ziemlich gut zu funktionieren!