Was ist LangSmith?

18.10.2023
Von 
Martin Heller schreibt als freier Autor für die Schwesterpublikation InfoWorld.
LangSmith ist essenziell, um LLM-Anwendungen zu debuggen, zu testen, zu evaluieren und zu überwachen.
LangSmith unterstützt Sie dabei, produktionsreife LLM-Applikationen zu generieren.
LangSmith unterstützt Sie dabei, produktionsreife LLM-Applikationen zu generieren.
Foto: Creative Bird - shutterstock.com

In meinem Grundlagenartikel zu LangChain habe ich das Thema LangSmith nur kurz angeschnitten. In diesem Artikel werden wir uns näher mit dieser Plattform befassen, die auch im Tandem mit anderen Large-Language-Model (LLM)-Frameworks funktioniert.

LangSmith definiert

LangSmith ist - in aller Kürze - ein Tool, um LLM-Applikationen und intelligente Agenten zu tracen, zu evaluieren und vom Prototypenstatus in die Produktion zu überführen.

Oder, wie es die LangSmith-Dokumentation ausdrückt: "LangSmith ist eine Plattform, um produktionsreife LLM-Anwendungen zu erstellen. Sie ermöglicht es, Chains und intelligente Agenten - die auf einem beliebigen LLM-Framework aufgebaut sind - zu debuggen, zu testen, zu bewerten und zu überwachen. LangSmith lässt sich dabei nahtlos mit dem führenden Open-Source-Framework LangChain integrieren."

Wie das konkret vonstattengeht, erfahren Sie in diesem Artikel. Anmerkung: Aktuell ist LangChain in drei Implementierungen verfügbar: Python, JavaScript und Go. Wir verwenden für alle genannten Beispiel die erstgenannte.

LangSmith mit LangChain nutzen

Nachdem Sie Ihr LangSmith-Konto eingerichtet, API-Schlüssel erstellt, die LangChain-Installation mit pip aktualisiert und die Shell-Umgebungsvariablen eingerichtet haben, können Sie die Python-Quickstart-Applikation ausführen:

from langchain.chat_models import ChatOpenAI

llm = ChatOpenAI()

llm.predict("Hello, world!")

Bevor wir die Ergebnisse betrachten, ein Blick auf den LangSmith-Hub:

Der LangSmith-Hub fungiert als Repository für Prompts, Modelle, Use Cases und andere LLM-Artefakte.
Der LangSmith-Hub fungiert als Repository für Prompts, Modelle, Use Cases und andere LLM-Artefakte.
Foto: IDG

Auf der nächsten Registerkarte finden Sie die Trace-Liste des Default-Projekts:

Die Trace-Liste des Python-Projekts zeugt von fünf gescheiterten Versuchen, Quickstart zu nutzen. Das lag laut Output an einem Timeout seitens OpenAI.
Die Trace-Liste des Python-Projekts zeugt von fünf gescheiterten Versuchen, Quickstart zu nutzen. Das lag laut Output an einem Timeout seitens OpenAI.
Foto: IDG

Erst nachdem ich meinen OpenAI-API-Tarif entsprechend angepasst respektive konfiguriert hatte, lief das Python-Programm bis zum Ende durch. Ein Blick auf die Ergebnisse:

Ein erfolgreicher Prediction-Run. Beachten Sie den "Playground"-Button rechts oben im Screen.
Ein erfolgreicher Prediction-Run. Beachten Sie den "Playground"-Button rechts oben im Screen.
Foto: IDG

Ein Blick auf die zugehörige Metadaten-Registerkarte verriet mir, dass der "Hello, World!"-Prompt mit dem gpt-3.5-turbo-Modell mit einer Sampling Temperature von 0,7 ausgeführt wurde. Die Skala reicht hier von 0 bis 1, wobei 1 die willkürlichste Einstellung ist und 0 das Modell auffordert, die Temperatur automatisch einzustellen.

Die Metadaten für den erfolgreichen Prediction-Run. Neben dem YAML- gibt es auch einen JSON-Block mit identischen Informationen.
Die Metadaten für den erfolgreichen Prediction-Run. Neben dem YAML- gibt es auch einen JSON-Block mit identischen Informationen.
Foto: IDG

Wie LangSmith funktioniert

LangSmith protokolliert sämtliche LLM-, Chain-, Agent-, Tool- und Retriever-Calls in einer LangChain - oder einem anderen LLM-Programm. Das kann Sie dabei unterstützen,

  • unerwartete Endergebnisse zu debuggen,

  • festzustellen, warum ein Agent "loopt",

  • herauszufinden, warum eine Chain langsamer als erwartet ist und

  • zu ermitteln, wie viele Token ein Agent verwendet hat.

Dabei bietet LangSmith eine unkomplizierte Visualisierung der genauen In- und Outputs aller LLM-Calls. Wenn Sie jetzt denken, die Input-Seite wäre trivial, irren Sie: Zusätzlich zu den Eingabevariablen (Prompt) verwendet ein LLM-Call ein Template und oft auch Hilfsfunktionen, die den Kontext für das Sprachmodell festlegen - etwa Informationen aus dem Web abrufen oder Dateien hochladen.

Ganz allgemeinen empfehle ich Ihnen, LangSmith für alle Arbeiten mit LangChain eingeschaltet zu lassen - die Protokolle müssen Sie lediglich dann einsehen, wenn es relevant ist. Sollte ein Prompt dabei nicht die gewünschten Ergebnisse liefern, haben Sie die Möglichkeit, diesen in den "Playground" zu verfrachten:

Der LangSmith-Playground erlaubt Ihnen, Ihren Input, das Modell und die Temperature interaktiv zu editieren beziehungsweise zu konfigurieren. Auch andere Parameter zusätzliche Funktions-Calls oder Messages lassen sich anpassen.
Der LangSmith-Playground erlaubt Ihnen, Ihren Input, das Modell und die Temperature interaktiv zu editieren beziehungsweise zu konfigurieren. Auch andere Parameter zusätzliche Funktions-Calls oder Messages lassen sich anpassen.
Foto: IDG

Vergessen Sie dabei nicht, Ihre API-Keys über die entsprechende Schaltfläche "Secrets & API Keys" hinzuzufügen.

LangSmith LLMChain-Beispiel

In meiner LangChain-Einführung habe ich das Beispiel einer LLMChain genutzt, die einen ChatOpenAI-Call mit einem einfachen Parser für kommagetrennte Listen kombiniert. Ein Blick auf das LangSmith-Protokoll für diesen Python-Code hilft zu verstehen, was in dem Programm passiert.

Der Parser ist eine Unterklasse von BaseOutputParser. Das System Message Template für den ChatOpenAI-Aufruf ist relativ einfaches Prompt Engineering.

from langchain.chat_models import ChatOpenAI

from langchain.prompts.chat import (

ChatPromptTemplate,

SystemMessagePromptTemplate,

HumanMessagePromptTemplate,

)

from langchain.chains import LLMChain

from langchain.schema import BaseOutputParser

class CommaSeparatedListOutputParser(BaseOutputParser):

"""Parse the output of an LLM call to a comma-separated list."""

def parse(self, text: str):

"""Parse the output of an LLM call."""

return text.strip().split(", ")

template = """You are a helpful assistant who generates comma separated lists.

A user will pass in a category, and you should generate 5 objects in that category in a comma separated list.

ONLY return a comma separated list, and nothing more."""

system_message_prompt = SystemMessagePromptTemplate.from_template(template)

human_template = "{text}"

human_message_prompt = HumanMessagePromptTemplate.from_template(human_template)

chat_prompt = ChatPromptTemplate.from_messages([system_message_prompt, human_message_prompt])

chain = LLMChain(

llm=ChatOpenAI(),

prompt=chat_prompt,

output_parser=CommaSeparatedListOutputParser()

)

chain.run("colors")

Das "Run"-Tab gibt Aufschluss über menschlichen Input, geparsten Output, Latenz, benutzte Token sowie Zeitstempel und Call-Status.
Das "Run"-Tab gibt Aufschluss über menschlichen Input, geparsten Output, Latenz, benutzte Token sowie Zeitstempel und Call-Status.
Foto: IDG
Auf LLM-Ebene ist der System Input und -Oupt zu sehen, der vom LLM vor dem Parsing produziert wurde.
Auf LLM-Ebene ist der System Input und -Oupt zu sehen, der vom LLM vor dem Parsing produziert wurde.
Foto: IDG
Die Metadaten für den ChatOpenAI-Call verraten das genutzte Modell, die Sampling Temperature und die Versionsnummern der Runtime.
Die Metadaten für den ChatOpenAI-Call verraten das genutzte Modell, die Sampling Temperature und die Versionsnummern der Runtime.
Foto: IDG

Mit LangSmith evaluieren

Dieser Quickstart-Walkthrough evaluiert eine Chain unter Einsatz eines beispielhaften Datensatzes. Ist das Dataset erstellt, wird ein LLM, eine Chain oder ein Agent für die Evaluierung definiert. Ist der Vorgang abgeschlossen, werden die Traces und das Feedback innerhalb von LangSmith überprüft.

from langsmith import Client

example_inputs = [

"a rap battle between Atticus Finch and Cicero",

"a rap battle between Barbie and Oppenheimer",

"a Pythonic rap battle between two swallows: one European and one African",

"a rap battle between Aubrey Plaza and Stephen Colbert",

]

client = Client()

dataset_name = "Rap Battle Dataset"

# Storing inputs in a dataset lets us

# run chains and LLMs over a shared set of examples.

dataset = client.create_dataset(

dataset_name=dataset_name, description="Rap battle prompts.",

)

for input_prompt in example_inputs:

# Each example must be unique and have inputs defined.

# Outputs are optional

client.create_example(

inputs={"question": input_prompt},

outputs=None,

dataset_id=dataset.id,

)

from langchain.chat_models import ChatOpenAI

from langchain.chains import LLMChain

# Since chains and agents can be stateful (they can have memory),

# create a constructor to pass in to the run_on_dataset method.

def create_chain():

llm = ChatOpenAI(temperature=0)

return LLMChain.from_string(llm, "Spit some bars about {input}.")

from langchain.smith import RunEvalConfig, run_on_dataset

eval_config = RunEvalConfig(

evaluators=[

# You can specify an evaluator by name/enum.

# In this case, the default criterion is "helpfulness"

"criteria",

# Or you can configure the evaluator

RunEvalConfig.Criteria("harmfulness"),

RunEvalConfig.Criteria(

{"cliche": "Are the lyrics cliche?"

" Respond Y if they are, N if they're entirely unique."}

)

]

)

run_on_dataset(

client=client,

dataset_name=dataset_name,

llm_or_chain_factory=create_chain,

evaluation=eval_config,

verbose=True,

project_name="llmchain-test-1",

)

Bei diesem Beispiel gibt es wesentlich mehr zu beachten. Der obenstehende Code verwendet einen Datensatz, führt das Modell gegen vier Prompts aus dem Datensatz aus und führt mehrere Evaluierungen jedes erzeugten Rap-Battle-Ergebnisses.

Hier die zugehörigen Statistiken, die während des Laufs über das Terminal ausgegeben wurden:

Eval quantiles:

0.25 0.5 0.75 mean mode

harmfulness 0.00 0.0 0.0 0.00 0.0

helpfulness 0.75 1.0 1.0 0.75 1.0

cliche 1.00 1.0 1.0 1.00 1.0

Wie der nachfolgende Datensatz zeigt, hatte jemand Spaß daran, die Rap-Battle-Prompts aufzusetzen:

Der Key-Value-Datensatz, der durch client.create_dataset()call generiert wurde.
Der Key-Value-Datensatz, der durch client.create_dataset()call generiert wurde.
Foto: IDG

Der Code verwendet einen eigenen Projektnamen - llmchain-test-1 - daher sind dort auch die Ergebnisse zu finden:

Die jeweils erste Zeile bildet das LLMChain-Ergebnis ab, die zweite das jeweilige LLM-Ergebnis.
Die jeweils erste Zeile bildet das LLMChain-Ergebnis ab, die zweite das jeweilige LLM-Ergebnis.
Foto: IDG

Im Folgenden das "Barbie vs. Oppenheimer" Rap-Battle, wie es von gpt-3.5-turbo generiert wurde:

Ob diese Lines in einem Battle zum Sieg gereichen würden, darf bezweifelt werden.
Ob diese Lines in einem Battle zum Sieg gereichen würden, darf bezweifelt werden.
Foto: IDG

Das LangSmith Cookbook

Die Standarddokumentation von LangSmith deckt alle Grundlagen der Plattform ab. In gängige Patterns und Anwendungsfälle aus der echten Welt dürfen Sie hingegen mit dem LangSmith Cookbook abtauchen (um den Code auszuführen, sollten Sie das Repository clonen oder forken).

Das Cookbook deckt dabei folgende Bereiche ab:

  • Code-Tracing mit LangChain;

  • Prompts mit LangChain Hub entdecken und teilen;

  • Testing und Benchmarking für LLM-Systeme;

  • Applikationen mit Hilfe von User Feedback optimieren, monitoren und personalisieren;

  • Daten exportieren zu Feintuning-Zwecken;

  • explorative Datenanalysen.

Dieser Beitrag basiert auf einem Artikel unserer US-Schwesterpublikation Infoworld.