Output Parser

Das LLM-Sprachmodell gibt Inhalte im Textformat aus, aber bei der Entwicklung von KI-Anwendungen möchten wir formatierte Inhalte erhalten, z. B. indem die Ergebnisse in Zielobjekte, Arrays usw. umgewandelt werden, um die Programmverarbeitung zu erleichtern. Hierfür ist der von LangChain bereitgestellte Output-Parser erforderlich, um den vom Modell zurückgegebenen Inhalt zu formatieren.

Die Funktion des Output-Parsers besteht darin, die von dem Sprachmodell zurückgegebenen Ergebnisse zu formatieren. Ein Output-Parser muss zwei notwendige Methoden implementieren:

  • "get_format_instructions": Gibt einen String mit Anweisungen zurück, in welchem Format das Sprachmodell die Ausgabe zurückgeben soll.
  • "parse": Parst den vom Modell zurückgegebenen Inhalt in das Zielformat.

Lassen Sie uns nun einen Blick auf die integrierten Output-Parser in LangChain werfen.

Pydantic Parser

Im Folgenden ist der Kern-Output-Parser PydanticOutputParser aufgeführt, der von LangChain abstrahiert ist. Dieser Parser basiert auf der Python-Bibliothek pydantic und wird verwendet, um das Ausgabeergebnis des Modells in Python-Objekte umzuwandeln.

from langchain.output_parsers import PydanticOutputParser
from langchain.prompts import PromptTemplate
from langchain_core.pydantic_v1 import BaseModel, Field, validator
from langchain_openai import OpenAI

model = OpenAI(model_name="gpt-3.5-turbo-instruct", temperature=0.0)

class Joke(BaseModel):
    setup: str = Field(description="Frage, um einen Witz aufzubauen")
    punchline: str = Field(description="Antwort, um den Witz aufzulösen")

    @validator("setup")
    def question_ends_with_question_mark(cls, field):
        if field[-1] != "?":
            raise ValueError("Schlecht formulierte Frage!")
        return field

parser = PydanticOutputParser(pydantic_object=Joke)

prompt = PromptTemplate(
    template="Beantworte die Benutzeranfrage.\n{format_instructions}\n{query}\n",
    input_variables=["query"],
    partial_variables={"format_instructions": parser.get_format_instructions()},
)

prompt_and_model = prompt | model
output = prompt_and_model.invoke({"query": "Erzähl mir einen Witz."})
parser.invoke(output)

Beispielrückgabe:

Joke(setup='Warum ist das Huhn über die Straße gegangen?', punchline='Um auf die andere Seite zu kommen!')

LCEL-Schnittstelle

Ausführbare Schnittstelle

Der Output-Parser implementiert die Runnable-Schnittstelle, die eine der grundlegenden Bausteine der LangChain Expression Language (LCEL) ist. Sie unterstützt Aufrufmethoden wie invoke, ainvoke, stream, astream, batch, abatch, astream_log usw.

Anwendung von Output-Parsern in LCEL

Der Output-Parser kann einen String oder BaseMessage als Eingabe akzeptieren und strukturierte Daten beliebigen Typs zurückgeben. Wir können eine Parserkette erstellen und aufrufen, indem wir den Parser zu einer Runnable-Sequenz hinzufügen.

chain = prompt | model | parser
chain.invoke({"query": "Erzähl mir einen Witz."})

Gibt zurück

Joke(setup='Warum ist das Huhn über die Straße gegangen?', punchline='Um auf die andere Seite zu kommen!')

Einige Parser können teilweise Parsobjekte streamen, wie z. B. SimpleJsonOutputParser, während andere keinen Stream unterstützen. Die endgültige Ausgabe hängt davon ab, ob der Parser teilweise Parsobjekte erstellen kann.

from langchain.output_parsers.json import SimpleJsonOutputParser

json_prompt = PromptTemplate.from_template(
    "Gib ein JSON-Objekt mit einem `answer`-Schlüssel zurück, das die folgende Frage beantwortet: {question}"
)
json_parser = SimpleJsonOutputParser()
json_chain = json_prompt | model | json_parser
list(json_chain.stream({"question": "Wer hat das Mikroskop erfunden?"}))
[{},
 {'answer': ''},
 {'answer': 'Ameise'},
 {'answer': 'Anton'},
 {'answer': 'Antonie'},
 {'answer': 'Antonie van'},
 {'answer': 'Antonie van Lee'},
 {'answer': 'Antonie van Leeu'},
 {'answer': 'Antonie van Leeuwen'},
 {'answer': 'Antonie van Leeuwenho'},
 {'answer': 'Antonie van Leeuwenhoek'}]

In LCEL können wir komplexe Datenverarbeitungsabläufe aufbauen, indem wir verschiedene Parser kombinieren, um verschiedenen Anforderungen zu entsprechen.