12 LLM-Objekte in LangChain: Von der Abstraktion zur Instanz

12.1 Die Schnittstelle verstehen

LangChain behandelt große Sprachmodelle nicht als monolithische Blackboxes, sondern als austauschbare Komponenten mit einheitlicher Programmierschnittstelle. Das klingt abstrakt, hat aber weitreichende praktische Konsequenzen: Ein LLM-Objekt in LangChain ist eine Python-Instanz mit definierten Methoden – unabhängig davon, ob das Modell auf OpenAI-Servern läuft, lokal via Ollama bereitgestellt wird oder über HuggingFace Hub bezogen wird.

Diese Entkopplung folgt einem bewährten Prinzip der Softwarearchitektur. Statt den Code fest an einen bestimmten Anbieter zu binden, definiert LangChain eine gemeinsame Schnittstelle. Das zugrundeliegende Modell lässt sich austauschen, ohne dass die nachgelagerte Verarbeitungslogik angepasst werden muss. Ein LLM-Objekt implementiert immer die gleichen Kernmethoden – etwa invoke() für synchrone Anfragen oder ainvoke() für asynchrone Aufrufe.

Was bedeutet das konkret? Jedes LLM-Objekt nimmt Text entgegen und gibt Text zurück. Die interne Verarbeitung – ob API-Call zu OpenAI, Netzwerkanfrage an Anthropic oder lokaler Inferenzlauf – bleibt hinter der Schnittstelle verborgen. Diese Abstraktion ermöglicht es, verschiedene Modelle zu testen, zwischen Cloud- und On-Premise-Lösungen zu wechseln oder unterschiedliche Anbieter für verschiedene Teile einer Anwendung einzusetzen.

Dabei geht es nicht nur um Flexibilität. Die einheitliche Schnittstelle erleichtert auch das Testen. Ein produktiver Code-Pfad, der GPT-4 verwendet, lässt sich in der Entwicklungsumgebung gegen ein schnelleres, günstigeres Modell austauschen – ohne dass sich an der Aufrufstruktur etwas ändert. Für Entwickler bedeutet das: weniger Boilerplate, weniger Vendor Lock-in, mehr Kontrolle über die Architektur.

Die zentrale Frage lautet also nicht mehr “Wie rufe ich OpenAI auf?” oder “Wie funktioniert die Claude-API?”, sondern: “Wie instanziiere ich ein LLM-Objekt?” Die Antwort darauf hat sich mit neueren LangChain-Versionen weiter vereinfacht.

12.2 Die moderne Initialisierung mit init_chat_model

LangChain hat über die Zeit verschiedene Ansätze zur Modell-Initialisierung entwickelt. Früher musste man für jedes Modell die entsprechende Provider-spezifische Klasse importieren – ChatOpenAI für OpenAI, ChatAnthropic für Claude, und so weiter. Das funktioniert noch immer, ist aber zunehmend durch eine elegantere Alternative ergänzt worden: die Funktion init_chat_model.

Diese Funktion abstrahiert die Initialisierung auf eine weitere Ebene. Statt verschiedene Klassen zu kennen und zu importieren, übergibt man der Funktion lediglich den Modellnamen und optional den Provider. LangChain kümmert sich intern um den Rest – das richtige Paket wird geladen, die entsprechende Klasse instanziiert, Parameter werden weitergereicht.

Ein minimaler Aufruf sieht so aus:

from langchain.chat_models import init_chat_model

llm = init_chat_model("openai:gpt-4o", temperature=0.7)

Die Notation "openai:gpt-4o" verbindet Provider und Modellname in einem String. LangChain erkennt den Provider automatisch und initialisiert intern ein ChatOpenAI-Objekt. Die Funktion unterstützt eine Vielzahl von Providern – von den Cloud-Giganten wie OpenAI, Anthropic und Google bis hin zu spezialisierten Anbietern wie Fireworks, Together oder Groq.

Interessant wird es bei der Inferenz des Providers. Wenn der Modellname einem bekannten Schema folgt, kann man den Provider-Prefix weglassen:

llm = init_chat_model("gpt-4o", temperature=0.7)  # Provider wird automatisch erkannt

LangChain schaut sich den String an, erkennt das gpt--Präfix und wählt den OpenAI-Provider. Gleiches gilt für claude-... (Anthropic), gemini-... (Google Vertex AI) oder command-... (Cohere). Diese Konvention reduziert Boilerplate und macht den Code lesbarer.

Aber was, wenn man zur Laufzeit zwischen Modellen wechseln möchte?

12.3 Konfigurierbare Modelle: Zur Laufzeit entscheiden

Die Funktion init_chat_model bietet eine weitere mächtige Funktion: konfigurierbare Felder. Statt ein Modell hart zu kodieren, lässt sich die Initialisierung so gestalten, dass zentrale Parameter – etwa das Modell selbst oder die Temperatur – zur Laufzeit über einen Config-Dictionary gesetzt werden.

Das ist besonders relevant für Anwendungen, die verschiedene Modelle je nach Kontext einsetzen wollen. Ein einfacher Chatbot nutzt vielleicht ein günstiges Modell für Standard-Anfragen, greift aber bei komplexen Fragen auf ein leistungsfähigeres Modell zurück. Oder eine Anwendung soll in der Entwicklung ein lokales Modell verwenden, in der Produktion aber auf einen Cloud-Provider zurückgreifen.

Die Umsetzung geschieht über den Parameter configurable_fields. Setzt man diesen auf "any", werden alle Parameter zur Laufzeit konfigurierbar. Vorsicht: Das öffnet auch sensible Felder wie api_key oder base_url. Für produktive Systeme empfiehlt es sich, die konfigurierbaren Felder explizit zu benennen:

from langchain.chat_models import init_chat_model

llm = init_chat_model(
    "gpt-4o",
    configurable_fields=("model", "model_provider", "temperature"),
    temperature=0.5
)

# Standardaufruf mit initialem Modell
response = llm.invoke("Was ist LangChain?")

# Zur Laufzeit auf ein anderes Modell wechseln
response = llm.invoke(
    "Was ist LangChain?",
    config={
        "configurable": {
            "model": "claude-sonnet-4-5-20250929",
            "temperature": 0.8
        }
    }
)

Das LLM-Objekt bleibt dasselbe, die Implementierung wechselt im Hintergrund. LangChain kümmert sich um die Details – die richtige Provider-Klasse, die korrekte Parameterweitergabe, die Verbindungsdetails. Für den aufrufenden Code ändert sich nichts.

Diese Flexibilität hat ihren Preis: Die Initialisierung des eigentlichen Modells erfolgt erst beim ersten invoke-Aufruf. Das kann zu einer leichten Verzögerung führen, ist aber in den meisten Anwendungsfällen vernachlässigbar.

12.4 Cloud-Modelle: OpenAI und Anthropic

Beginnen wir mit den naheliegendsten Kandidaten: den Cloud-basierten Modellen von OpenAI und Anthropic. Beide Provider bieten leistungsstarke Modelle über REST-APIs an. LangChain kapselt den API-Zugriff und bietet eine pythonische Schnittstelle.

Für OpenAI-Modelle benötigt man zunächst das Paket langchain-openai:

pip install langchain-openai

Die Initialisierung über init_chat_model erfordert lediglich den Modellnamen. Der API-Key wird standardmäßig aus der Umgebungsvariable OPENAI_API_KEY gelesen:

import os
from langchain.chat_models import init_chat_model

# API-Key wird aus der Umgebungsvariable geladen
os.environ["OPENAI_API_KEY"] = "sk-..."

# Modell initialisieren
llm = init_chat_model("openai:gpt-4o", temperature=0.7, max_tokens=2048)

# Einfacher Aufruf
response = llm.invoke("Erkläre den Unterschied zwischen Lists und Tuples in Python.")
print(response.content)

Die Methode invoke() gibt nicht direkt einen String zurück, sondern ein AIMessage-Objekt. Der eigentliche Text findet sich im Attribut content. Diese Struktur mag zunächst umständlich wirken, ergibt aber Sinn: LangChain arbeitet mit strukturierten Nachrichten, die neben dem Text auch Metadaten, Tool-Calls oder andere Informationen enthalten können.

Für Anthropic-Modelle läuft der Prozess analog. Das benötigte Paket heißt langchain-anthropic, der API-Key wird aus ANTHROPIC_API_KEY gelesen:

import os
from langchain.chat_models import init_chat_model

os.environ["ANTHROPIC_API_KEY"] = "sk-ant-..."

llm = init_chat_model(
    "anthropic:claude-sonnet-4-5-20250929",
    temperature=0.5,
    max_tokens=4096
)

response = llm.invoke("Was sind die Vor- und Nachteile von Mikroservices?")
print(response.content)

Die Schnittstelle bleibt identisch. Das ist der Kern der Abstraktion: Der Code unterscheidet sich nur in der Modellangabe, die restliche Logik bleibt unverändert. Wer zwischen OpenAI und Anthropic wechseln möchte, ändert eine Zeile.

Beide Provider bieten unterschiedliche Modelle mit verschiedenen Eigenschaften – Geschwindigkeit, Kontext-Länge, Kosten. Die Wahl des Modells hängt vom Anwendungsfall ab. Für schnelle, einfache Aufgaben eignet sich etwa gpt-4o-mini, für komplexe Reasoning-Tasks greift man zu o1 oder Claude Opus. Die Initialisierung bleibt in allen Fällen dieselbe.

12.5 Lokale Modelle mit Ollama

Cloud-Modelle sind bequem, aber nicht immer die beste Wahl. Datenschutzanforderungen, Latenz-Überlegungen oder schlicht der Wunsch nach voller Kontrolle sprechen für lokale Modelle. Hier kommt Ollama ins Spiel – ein Tool, das es ermöglicht, Open-Source-Modelle wie Llama, Mistral oder Phi lokal auszuführen.

Ollama läuft als lokaler Server, der über eine OpenAI-kompatible API angesprochen werden kann. LangChain unterstützt Ollama direkt über das Paket langchain-ollama:

pip install langchain-ollama

Die Verwendung ist denkbar einfach:

from langchain_ollama import OllamaLLM

llm = OllamaLLM(model="llama3.2", temperature=0.5)

response = llm.invoke("Beschreibe den Unterschied zwischen synchronem und asynchronem I/O.")
print(response)

Hier fällt etwas auf: Im Gegensatz zu den Cloud-Providern gibt invoke() direkt einen String zurück, kein AIMessage-Objekt. Das liegt daran, dass OllamaLLM eine etwas ältere Schnittstelle implementiert. Für Chat-basierte Modelle sollte man stattdessen ChatOllama verwenden, das die moderne Message-Struktur unterstützt:

from langchain_ollama import ChatOllama

llm = ChatOllama(model="llama3.2", temperature=0.5)

response = llm.invoke("Beschreibe den Unterschied zwischen synchronem und asynchronem I/O.")
print(response.content)

Jetzt verhält sich das Objekt konsistent zu den Cloud-Providern. Die Schnittstelle ist einheitlich, der Code portabel.

Ollama bietet eine breite Palette von Modellen – von kompakten 3B-Parameter-Modellen bis hin zu großen 70B-Varianten. Die Installation erfolgt über die Ollama-CLI:

ollama pull llama3.2
ollama pull mistral
ollama pull phi3

Danach stehen die Modelle lokal zur Verfügung. LangChain kommuniziert über HTTP mit dem Ollama-Server, der standardmäßig auf localhost:11434 lauscht. Die Inferenz findet vollständig lokal statt – keine API-Keys, keine externen Abhängigkeiten.

Das hat Konsequenzen für die Performance. Lokale Modelle sind deutlich langsamer als Cloud-APIs, besonders ohne GPU-Beschleunigung. Für Entwicklung und Experimente sind sie ideal, für produktive High-Throughput-Szenarien weniger. Die Entscheidung hängt von den konkreten Anforderungen ab.

12.6 Parameter und ihre Bedeutung

Alle LLM-Objekte akzeptieren eine Reihe von Parametern, die das Verhalten des Modells steuern. Die beiden wichtigsten sind temperature und max_tokens.

Die Temperature kontrolliert die Zufälligkeit der Ausgabe. Ein Wert von 0 führt zu deterministischen, vorhersehbaren Antworten – das Modell wählt immer die wahrscheinlichste Fortsetzung. Höhere Werte (typisch bis 1.0, manchmal bis 2.0) erhöhen die Kreativität und Variabilität. Für faktische Antworten oder Code-Generierung empfiehlt sich eine niedrige Temperature, für kreative Texte eine höhere.

Max Tokens begrenzt die Länge der Antwort. Nicht zu verwechseln mit der Kontext-Länge – diese bestimmt, wie viel Input das Modell verarbeiten kann, während max_tokens die Ausgabe limitiert. Cloud-Provider rechnen pro Token ab, daher kann eine Begrenzung die Kosten senken. Bei lokalen Modellen spielt das keine Rolle, aber die Begrenzung verhindert ungewollt lange Antworten.

Weitere Parameter wie top_p, frequency_penalty oder presence_penalty bieten feinere Kontrolle. In der Praxis reichen Temperature und max_tokens für die meisten Anwendungsfälle aus. Die restlichen Parameter lohnen sich erst bei speziellen Anforderungen – etwa wenn man repetitive Ausgaben vermeiden oder die Diversität gezielt erhöhen möchte.

12.7 Von der Initialisierung zur Anwendung

Ein LLM-Objekt allein macht noch keine Anwendung. Es ist der grundlegende Baustein, auf dem alles andere aufbaut. LangChain bietet eine Vielzahl von Abstraktionen – Chains, Agents, Tools – die alle auf LLM-Objekte zurückgreifen. Die Initialisierung ist der erste Schritt.

Wichtig zu verstehen: Das LLM-Objekt kapselt nicht nur das Modell, sondern auch die Verbindungslogik, Retry-Mechanismen, Rate-Limiting und Error-Handling. LangChain kümmert sich um transiente Fehler, wiederholt fehlgeschlagene Requests automatisch und implementiert exponentielles Backoff. Das alles geschieht transparent, ohne dass der aufrufende Code davon wissen muss.

Für produktive Anwendungen empfiehlt es sich, LLM-Objekte einmal zu initialisieren und wiederzuverwenden. Die Initialisierung ist nicht teuer, aber auch nicht kostenlos – Verbindungen werden aufgebaut, Authentifizierung erfolgt. Ein Singleton-Pattern oder Dependency Injection bieten sich an.

Die einheitliche Schnittstelle bedeutet auch: Code, der gegen ein LLM-Objekt entwickelt wurde, funktioniert mit jedem kompatiblen Provider. Das vereinfacht Testing erheblich. Entwicklungstests laufen gegen ein lokales Ollama-Modell, Integrationstests gegen eine günstige Cloud-API, Produktion nutzt das beste verfügbare Modell. Der Code bleibt unverändert, nur die Konfiguration wechselt.

Das ist die wahre Stärke der Abstraktion: Sie entkoppelt die Entscheidung “Welches Modell verwenden wir?” von der Frage “Wie bauen wir die Anwendung?”. Die Architektur bleibt flexibel, die Implementierung sauber, die Tests wartbar.

12.8 Die richtige Wahl treffen

Bleibt die Frage: Wann welches Modell? Die Antwort hängt von mehreren Faktoren ab.

Cloud-Modelle wie GPT-4 oder Claude Sonnet bieten die beste Qualität und höchste Geschwindigkeit. Sie sind ideal für produktive Anwendungen mit hohen Qualitätsanforderungen. Der Preis ist höher, aber die Ergebnisse rechtfertigen ihn oft. Kritisch sind Datenschutz-Überlegungen – Daten werden an externe Server übertragen.

Lokale Modelle via Ollama eignen sich für Entwicklung, Experimente oder Szenarien mit strikten Datenschutzanforderungen. Sie sind langsamer und qualitativ oft schwächer, aber vollständig unter eigener Kontrolle. Für viele Anwendungsfälle – einfache Klassifikation, Zusammenfassungen, strukturierte Datenextraktion – reichen sie völlig aus.

Die Initialisierung über init_chat_model macht den Wechsel trivial. Man kann mit einem lokalen Modell entwickeln, die Anwendung validieren, und dann auf ein Cloud-Modell umstellen, ohne eine Zeile Code zu ändern. Das ist die praktische Konsequenz einer gut durchdachten Abstraktion.

LangChain macht LLMs zu dem, was sie sein sollten: austauschbare, gut kapselte Komponenten mit klarer Schnittstelle. Die technische Komplexität bleibt hinter der API verborgen, die Flexibilität bleibt erhalten. Das ermöglicht es, sich auf das Wesentliche zu konzentrieren – die Anwendungslogik, nicht die Infrastruktur.