LangChain-Nachrichtentypen

In LangChain werden alle Konversationen durch Message-Objekte geleitet. Das Verständnis des Zwecks der verschiedenen Nachrichtentypen ist die Grundlage für das Schreiben von Agenten.


Vier Kern-Nachrichtentypen

LangChain definiert vier Kern-Nachrichtentypen, die unterschiedlichen Rollen in einer Konversation entsprechen:

TypeRolleBeschreibungTypischer Inhalt
HumanMessageBenutzerVom Benutzer gesendete Nachricht"Wie ist das Wetter heute?"
AIMessageKI-AssistentAntwort des Modells, kann tool_calls enthalten"Heute ist es sonnig in Hangzhou, 25°C"
SystemMessageSystemSystemanweisung, die die Rolle und die Verhaltensregeln der KI definiert"Du bist ein professioneller Wetterassistent"
ToolMessageToolErgebnis nach der Tool-Ausführung zurückgeben"Sonnig, 25°C, Luftfeuchtigkeit 60%"

HumanMessage — Benutzernachricht

HumanMessage stellt eine vom Benutzer an die KI gesendete Nachricht dar. Sie ist der häufigste Nachrichtentyp und der Ausgangspunkt einer Konversation.

Beispiel

from langchain.messages import HumanMessage
from langchain.chat_models import init_chat_model

# Eine Benutzernachricht erstellen
msg = HumanMessage(content="Was ist Python?")

print(f"Typ: {msg.type}")        # human
print(f"Inhalt: {msg.content}")      # Was ist Python?
print(f"Rolle: {msg.role}")         # user

# Nachrichtenliste erstellen (repräsentiert den Verlauf einer mehrstufigen Konversation)
messages = [
    HumanMessage(content="Hallo"),
    HumanMessage(content="Welche Kurse bietet Example an?"),
    HumanMessage(content="Ist der Python-Kurs für Anfänger ohne Vorkenntnisse geeignet?"),
]

model = init_chat_model("deepseek:deepseek-v4-flash", temperature=0)
response = model.invoke(messages)
print(f"\n"Modellantwort: {response.content}")

Ausgabe:

Type: human
Content: What is Python?
Role: user

Model reply: Python is a high-level, interpreted programming language known for its clear and readable syntax, widely used across many fields.
Its rich ecosystem and beginner-friendly design make it an excellent choice for those starting from zero.

Schnelle Erstellungsmethoden für HumanMessage

Beim Erstellen von Nachrichtenlisten können Sie Tupel oder Dictionaries als Kurzformen verwenden:

Beispiel

from langchain.messages import HumanMessage

# Methode 1: Standardkonstruktion
msg1 = HumanMessage(content="Hello")

# Methode 2: Tupel-Kurzform (role, content)
msg2 = ("user", "Hello")
msg3 = ("human", "Hello")

# Methode 3: Dictionary-Kurzform
msg4 = {"role": "user", "content": "Hello"}

# Alle vier Methoden sind äquivalent und werden intern im Agent in HumanMessage umgewandelt.
print(type(msg1))  # <class 'langchain_core.messages.human.HumanMessage'>

AIMessage — KI-Antwort

AIMessage repräsentiert die Antwort des Modells. Anders als gewöhnlicher Text kann AIMessagetool_calls(Anfragen für Tool-Aufrufe) enthalten.

Beispiel

from langchain.messages import AIMessage

# Normale KI-Antwort (kein Tool-Aufruf)
ai_msg = AIMessage(content="Example is a programming learning platform")

# KI-Antwort, die einen Tool-Aufruf enthält
ai_with_tools = AIMessage(
    content="",  # Beim Aufrufen eines Tools ist content normalerweise leer
    tool_calls=[
        {
            "name": "get_weather",
            "args": {"city": "Hangzhou"},
            "id": "call_abc123",
            "type": "tool_call",
        }
    ]
)

print("=== Normale KI-Nachricht ===")
print(f"Inhalt: {ai_msg.content}")
print(f"Tool-Aufrufe: {ai_msg.tool_calls}")   # []

print("\n"=== KI-Nachricht mit Tool-Aufruf ===")
print(f"Inhalt: {ai_with_tools.content}")
print(f"Tool-Aufrufe: {ai_with_tools.tool_calls}")
# [{'name': 'get_weather', 'args': {'city': 'Hangzhou'}, ...}]

Zusätzliche Informationen für AIMessage

Beispiel

from langchain.chat_models import init_chat_model

model = init_chat_model("deepseek:deepseek-v4-flash")
response = model.invoke("Stelle Python vor")

# AIMessage enthält umfangreiche Metadaten
print(f"Inhalt: {response.content}")
print(f"Nachrichten-ID: {response.id}")
print(f"Modellname: {response.response_metadata.get('model_name')}")
print(f"Finish-Grund: {response.response_metadata.get('finish_reason')}")

# usage_metadata enthält Token-Nutzungsinformationen
if response.usage_metadata:
    print(f"Eingabe-Token: {response.usage_metadata.get('input_tokens')}")
    print(f"Ausgabe-Token: {response.usage_metadata.get('output_tokens')}")
    print(f"Gesamt-Token: {response.usage_metadata.get('total_tokens')}")

Ausgabe:

Content: Example is a free programming learning platform for beginners...
Message ID: msg_abc123def456
Model name: deepseek-v4-flash
Finish reason: stop
Input tokens: 19
Output tokens: 47
Total tokens: 66

SystemMessage — Systemanweisung

SystemMessage wird verwendet, um das Verhalten, die Rolle und die Einschränkungen der KI festzulegen. Sie wird am Anfang der Nachrichtenliste platziert und steuert, wie das Modell antwortet.

Beispiel

from langchain.messages import HumanMessage, SystemMessage
from langchain.chat_models import init_chat_model

model = init_chat_model("deepseek:deepseek-v4-flash", temperature=0.7)

# Antwort ohne Systemanweisung
messages_no_system = [HumanMessage(content="Stelle Python vor")]
response = model.invoke(messages_no_system)
print(f"Keine Systemanweisung: {response.content[:80]}...")

# Antwort mit einer Systemanweisung
messages_with_system = [
    SystemMessage(content="Du bist ein Blogger im Xiaohongshu-Stil; Antworten sollen lebhaft sein, Emojis verwenden und Themen-Tags enthalten."),
    HumanMessage(content="Stelle Python vor")
]
response = model.invoke(messages_with_system)
print(f"\n"Mit Systemanweisung: {response.content}")

Ausgabe:

Without system prompt: Example is an online programming learning platform for beginners, offering rich tutorials and examples...

With system prompt: Amazing site! Recommending Example to every beginner who wants to learn programming!
Comprehensive free tutorials covering everything from HTML to Python!
Plenty of examples and quick to get started - a perfect entry point for programming novices!
#ProgrammingLearning #FreeTutorials #ZeroBasics #Example

ToolMessage — Tool-Rückgabeergebnis

ToolMessage enthält das Ergebnis, das nach der Tool-Ausführung zurückgegeben wird. Es muss dem entsprechenden tool_call zugeordnet sein.

Beispiel

from langchain.messages import HumanMessage, AIMessage, ToolMessage
from langchain.chat_models import init_chat_model

# Simuliere eine vollständige Runde einer Tool-Aufruf-Konversation
messages = [
    HumanMessage(content="Wie ist das Wetter in Hangzhou?"),

    # Das Modell fordert den Aufruf eines Tools an
    AIMessage(
        content="",
        tool_calls=[
            {"name": "get_weather", "args": {"city": "Hangzhou"},
             "id": "call_abc", "type": "tool_call"}
        ]
    ),

    # Tool-Rückgabeergebnis (muss tool_call_id enthalten, die der obigen id entspricht)
    ToolMessage(
        content="Sonnig, 25°C, Luftfeuchtigkeit 60%",
        tool_call_id="call_abc",   # Entspricht der id von tool_call
        name="get_weather",        # Tool-Name
    ),
]

model = init_chat_model("deepseek:deepseek-v4-flash")
response = model.invoke(messages)
print(f"Modellantwort basierend auf Tool-Ergebnis: {response.content}")

Ausgabe:

Model reply based on tool result: Hangzhou is sunny today, 25 C, humidity 60%, great for outdoor activities.

ToolMessage's tool_call_id muss genau mit der id von tool_call in der AIMessage übereinstimmen. Wenn sie nicht übereinstimmen, kann das Modell das Tool-Ergebnis ignorieren oder verwirrendes Verhalten erzeugen.


AIMessageChunk — Nachrichten-Chunk für Streaming-Ausgabe

Wenn Sie stream() für Streaming-Ausgabe verwenden, ist jeder eintreffende Chunk ein AIMessageChunk und keine vollständige AIMessage:

Beispiel

from langchain.chat_models import init_chat_model

model = init_chat_model("deepseek:deepseek-v4-flash")

print("Streaming-Ausgabeprozess:")
# stream() gibt einen AIMessageChunk-Iterator zurück
for chunk in model.stream("Stelle Python in einem Satz vor"):
    # Jeder Chunk ist ein kleines Stück Text
    print(chunk.content, end="", flush=True)
print()  # Zeilenumbruch

Ausgabe:

Streaming output:
Example is a free online learning platform for programming beginners, offering rich tutorials and examples.

Schnellreferenztabelle für Nachrichtentypen

Nachrichtentyptype-Attributrole-AttributSchlüsselfelderWann zu verwenden
HumanMessagehumanusercontentBenutzereingabe
AIMessageaiassistantcontent, tool_calls, usage_metadataModellantwort
AIMessageChunkaiassistantcontent (Delta)Streaming-Ausgabe-Chunk
SystemMessagesystemsystemcontentKI-Rolle festlegen
ToolMessagetooltoolcontent, tool_call_id, nameTool-Ausführungsergebnis

ContentBlock — Strukturierter Nachrichteninhalt

Bisher waren die Nachrichteninhalte, die wir verwendet haben, einfache Zeichenketten. In Wirklichkeit kann der Inhalt jeder Nachricht jedoch aus mehrerenContentBlock(Inhaltsblöcken) bestehen, die eine Liste bilden.

Die drei häufigsten Arten von Inhaltsblöcken:

TypeBeschreibungZweck
PlainTextContentBlockReiner TextinhaltGewöhnliche Textnachricht
ImageContentBlockBildinhalt (base64 oder URL)Bildeingabe für multimodale Modelle
ToolCallTool-Aufruf-AnfrageKI-Anfragen zum Aufruf eines Tools

Beispiel

from langchain.messages import HumanMessage
from langchain.messages import PlainTextContentBlock, ImageContentBlock

# Nachrichten mit Inhaltsblöcken erstellen
# content kann eine einfache Zeichenkette sein (einfaches Szenario)
simple_msg = HumanMessage(content=Hallo)

# content kann auch eine Liste von ContentBlock sein (komplexes Szenario)
complex_msg = HumanMessage(content=[
    PlainTextContentBlock(text="Was ist auf diesem Bild?"),
    # Das Bild kann eine URL oder base64-Kodierung sein
    ImageContentBlock(
        url="https://example.com/photo.jpg"
    ),
])

print(f"Inhaltstyp der einfachen Nachricht: {type(simple_msg.content)}")
# Ausgabe: <class 'str'>

print(f"Inhaltstyp der komplexen Nachricht: {type(complex_msg.content)}")
# Ausgabe: <class 'list'>

print(f"Anzahl der Inhaltsblöcke: {len(complex_msg.content)}")
# Ausgabe: 2

Wenn Sie nur reinen Text senden müssen, können Sie direkt eine Zeichenkette übergeben, und LangChain verarbeitet sie automatisch. Nur wenn Sie Text und Bilder in einer einzigen Nachricht mischen müssen, müssen Sie manuell eine ContentBlock-Liste erstellen.


Multimodale Nachrichten — Das Modell Bilder "sehen" lassen

Wenn Ihr Modell multimodale Eingaben unterstützt (z. B. GPT-4o, Claude 3+), können Sie es Bildinhalte analysieren lassen:

Beispiel

import base64
from pathlib import Path
from langchain.messages import HumanMessage
from langchain.chat_models import init_chat_model

# Lokales Bild als Base64 kodieren
def encode_image(image_path: str) -> str:
    Bilddatei einlesen und in Base64-Kodierung umwandeln
    with open(image_path, "rb") as f:
        return base64.b64encode(f.read()).decode("utf-8")

# Ein multimodales Modell erstellen (muss Bildeingabe unterstützen)
model = init_chat_model("deepseek:deepseek-v4-flash")

# Eine Nachricht erstellen, die ein Bild enthält
# Hinweis: content verwendet Listenformat und enthält Textblöcke und Bildblöcke
image_data = encode_image("screenshot.png")
messages = [
    HumanMessage(content=[
        {"type": "text", "text": Bitte beschreiben Sie den Inhalt dieses Screenshots der offiziellen Python-Website.},
        {
            "type": "image_url",
            "image_url": {
                "url": f"data:image/png;base64,{image_data}",
                "detail": "auto"  # Optional: low, high, auto
            }
        }
    ])
]

response = model.invoke(messages)
print(fErgebnis der Bildanalyse: {response.content})

Wenn Ihre Nachricht nur ein Bild und keinen Text enthält, können Sie direkt Folgendes verwenden:

Beispiel

from langchain.chat_models import init_chat_model

model = init_chat_model("deepseek:deepseek-v4-flash")

# Verwenden Sie eine URL, um direkt auf ein Online-Bild zu verweisen
messages = [
    {
        "role": "user",
        "content": [
            {"type": "text", "text": Was zeigt dieses Bild?},
            {
                "type": "image_url",
                "image_url": {"url": "https://www.example.com/wp-content/uploads/2024/01/logo.png"}
            }
        ]
    }
]

response = model.invoke(messages)
print(response.content)

Nicht alle Modelle unterstützen multimodale Eingaben. Die GPT-4o-Serie von OpenAI, Claude 3+ von Anthropic und die Gemini-Serie von Google unterstützen sie. Wenn Sie ein Bild mit einem nicht unterstützten Modell senden, erhalten Sie einen Fehler.


ToolCall — Tool-Aufruf-Nachricht

Das Feld tool_calls in AIMessage ist eine Liste von ToolCall-Objekten, wobei jedes ToolCall eine Anfrage des Modells zum Aufrufen eines Tools darstellt:

Beispiel

from langchain.messages import AIMessage
from langchain.messages.tool import ToolCall

# ToolCall manuell erstellen
tool_call = ToolCall(
    name="get_weather",        # Tool-Name
    args={"city": Hangzhou},     # Aufrufargumente
    id="call_abc123",         # Eindeutige Kennung
    type="tool_call",         # Fester Wert
)

# AIMessage mit tool_calls erstellen
ai_message = AIMessage(
    content="",               # Wenn tool_calls vorhanden ist, ist content normalerweise leer
    tool_calls=[tool_call],
)

print(fWerkzeugname: {ai_message.tool_calls)
print(fAufrufparameter: {ai_message.tool_calls)
print(fAufruf-ID: {ai_message.tool_calls)

Prüfen, ob AIMessage Tool-Aufrufe enthält

Beispiel

from langchain.chat_models import init_chat_model

model = init_chat_model("deepseek:deepseek-v4-flash", temperature=0)

# Nach dem Binden von Tools kann das Modell tool_calls zurückgeben
tools = [{
    "type": "function",
    "function": {
        "name": "get_weather",
        "description": Wetter abfragen,
        "parameters": {
            "type": "object",
            "properties": {
                "city": {"type": "string", "description": Stadtname}
            },
            "required": ["city"]
        }
    }
}]

model_with_tools = model.bind_tools(tools)

# Frage, die einen Tool-Aufruf auslöst
response = model_with_tools.invoke(Wie ist das Wetter in Hangzhou?)

# Zwei Möglichkeiten, festzustellen, ob ein Tool-Aufruf vorliegt
# Methode 1: Prüfen, ob die tool_calls-Liste nicht leer ist
if response.tool_calls:
    print(Modell fordert einen Tool-Aufruf an)

# Methode 2: Prüfen, ob content leer ist
# (Bei den meisten Modellen ist content leer, wenn tool_calls vorhanden ist)
if not response.content:
    print(Der Inhalt des Modells ist leer, was bedeutet, dass es ein Tool aufrufen möchte, anstatt direkt zu antworten.)

trim_messages() — Nachrichtenverlauf kürzen

Wenn die Konversation länger wird, kann die Nachrichtenliste das Kontextfenster des Modells überschreiten.trim_messages()Die Funktion hilft Ihnen, den Nachrichtenverlauf intelligent zu kürzen.

Beispiel

from langchain.messages import (
    HumanMessage, AIMessage, SystemMessage, trim_messages
)
from langchain.chat_models import init_chat_model

# Simuliere einen langen Konversationsverlauf
messages = [
    SystemMessage(content=Du bist der KI-Assistent des EXAMPLE-Tutorials.),
    HumanMessage(content=Wie fange ich mit Python an?),
    AIMessage(content=Der Einstieg in Python kann mit Grundkenntnissen beginnen...),
    HumanMessage(content=Gibt es eine empfohlene IDE?),
    AIMessage(content=Ich empfehle VS Code oder PyCharm...),
    HumanMessage(content=Wie installiere ich Bibliotheken von Drittanbietern?),
    AIMessage(content=Verwende den Befehl pip install...),
    HumanMessage(content=Was ist NumPy?),
    AIMessage(content=NumPy ist eine Bibliothek für wissenschaftliches Rechnen...),
    HumanMessage(content=Was ist der Unterschied zwischen pandas und NumPy?),
]

model = init_chat_model("deepseek:deepseek-v4-flash")

# Nachrichten kürzen, damit sie in das Kontextfenster des Modells passen (höchstens 1000 Tokens)
# strategy="last" behält die letzte Systemnachricht und die aktuellste Konversation bei.
trimmed = trim_messages(
    messages,
    max_tokens=1000,           # Höchstens 1000 Token behalten
    strategy="last",           # Letzte Systemnachricht + neueste Konversation behalten
    token_counter=model,       # Token-Zählmethode des Modells verwenden
    include_system=True,       # SystemMessage immer behalten
    start_on="human",          # Nach dem Kürzen mit einer Human-Nachricht beginnen
)

print(fVor dem Kürzen: {len(messages)} Nachrichten)
print(fNach dem Kürzen: {len(trimmed)} Nachrichten)
for msg in trimmed:
    snippet = msg.content[:50] if isinstance(msg.content, str) else str(msg.content)[:50]
    print(f" [{msg.type}] {snippet}...")

Ausführungsergebnis:

Before trimming: 10 messages
After trimming: 5 messages
  [system] You are the AI assistant of Example...
  [human] How do I install third-party libraries?...
  [ai] Use the pip install command...
  [human] What is NumPy?...
  [ai] NumPy is a scientific computing library...
StrategieBeschreibungAnwendbare Szenarien
strategy="last"Systemnachricht + aktuellste Konversation beibehaltenIn langen Konversationen ist nur der aktuelle Kontext relevant
strategy="first"Systemnachricht + früheste Konversation beibehaltenSicherstellen, dass wichtiger Kontext nicht gekürzt wird

start_on="human" stellt sicher, dass die gekürzte Nachrichtenliste mit einer Benutzernachricht beginnt (statt mit einer KI-Nachricht), wodurch verhindert wird, dass das Modell eine Liste erhält, die mit einer isolierten KI-Antwort beginnt.


RemoveMessage — Löschen bestimmter Nachrichten

In einigen fortgeschrittenen Szenarien müssen Sie möglicherweise bestimmte Nachrichten aus dem Nachrichtenverlauf löschen (z. B. zum Bereinigen sensibler Inhalte, zum Neugenerieren von Antworten usw.):

Beispiel

from langchain.messages import HumanMessage, AIMessage, RemoveMessage

# Angenommen, es gibt eine Konversation
messages = [
    HumanMessage(content=Hallo, id="msg_1"),
    AIMessage(content=Hallo! Wie kann ich Ihnen helfen?, id="msg_2"),
    HumanMessage(content=Prüfe das Wetter für mich, id="msg_3"),
]

# RemoveMessage verwenden, um eine bestimmte Nachricht (anhand der ID) zu löschen
# RemoveMessage wird zusammen mit dem add_messages-Reducer verwendet
# Beim Aktualisieren des Agent-Status entfernt RemoveMessage die Nachricht mit der entsprechenden ID aus der Liste
removal = RemoveMessage(id="msg_3")

print(fZu löschende Nachrichten-ID: {removal.id})
print(fTyp: {removal.type})  # entfernen

RemoveMessage wird normalerweise zusammen mit dem add_messages-Reducer von AgentState verwendet. Das Zurückgeben von RemoveMessage in Middleware- oder after_model-Hooks kann den Nachrichtenverlauf dynamisch bereinigen.


Gängige Methoden für Nachrichteneigenschaften

Alle Nachrichtentypen erben von BaseMessage und teilen einige gemeinsame Methoden:

Beispiel

from langchain.messages import HumanMessage, AIMessage

msg = HumanMessage(content=Hallo, Beispiel)

# Grundlegende Attribute
print(f"content: {msg.content}")      # Nachrichteninhalt
print(f"type: {msg.type}")            # Nachrichtentyp (human/ai/system/tool)
print(f"id: {msg.id}")                # Automatisch generierte eindeutige ID

# text-Attribut: Wenn es sich um Textinhalt handelt, den Text zurückgeben; andernfalls "" zurückgeben
print(f"text: {msg.text}")

# pretty_repr(): formatierte Ausgabe, geeignet zum Debuggen
print(f"Formatierte Ausgabe:\n{msg.pretty_repr()}")

Ausführungsergebnis:

content: Hello, world
type: human
id: 00000000-0000-4000-8000-000000000000
text: Hello, world
Pretty output:
================================ Human Message =================================
Hello, world
Weitere Erweiterungen