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.