Ihr KI-Agent leistet beim Testen hervorragende Arbeit. Dann verschicken Sie es und etwas geht irgendwie kaputt. Ein Instrument namens Loops läuft ewig, als würde es nie lernen. Ein Abrufschritt bringt Müll zurück und die Kosten steigen. Sie haben überhaupt keine Ahnung, warum.

Das ist das Downside der Agentenbeobachtbarkeit. Und wenn Sie mit LLMs bauen, müssen Sie das Downside vor der Produktion lösen, nicht danach. In diesem Beitrag werden drei der am häufigsten verwendeten Observability-Instruments näher erläutert: LangSmith, Langfuse Und Arize. Wir richten jeden einzelnen ein, verfolgen denselben Agenten und vergleichen, was Sie tatsächlich erhalten.

Was ist Agent Observability?

Die herkömmliche Anwendungsüberwachung verfolgt Anfragen, Fehler und Latenz, aber das reicht für Agenten nicht aus.

Ein Agent kann mehrere Instruments nacheinander aufrufen, wobei jeder LLM-Schritt seine eigene Eingabeaufforderung, Token-Nutzung, Latenz und potenzielle Fehlerstelle hat. Ein einzelner fehlgeschlagener Abruf oder Instrument-Aufruf kann zu einer falschen Endantwort führen.

Beobachtbarkeit des Agenten erfasst das vollständige Ausführungsdiagramm: jeden Schritt, jede Entscheidung, jede LLM-Eingabe und -Ausgabe, jeden Instrument-Aufruf, Argumente, Ergebnisse, Token-Nutzung, Latenz und Bewertungsergebnis. Ohne diese Sichtbarkeit wird das Verhalten des Debug-Agenten zur Vermutung.

Einrichten des Testagenten

Wir werden einen sehr einfachen LangChain-Agenten verwenden, um sie zu vergleichen. Der Agent empfängt eine Frage des Benutzers, ruft den relevanten Kontext ab und antwortet mithilfe eines oder mehrerer Instruments, um eine Antwort bereitzustellen.

Zunächst müssen Sie den Testagenten erstellen und dafür alle erforderlichen Bibliotheken installieren.

Liste der Abhängigkeiten

Schauen wir uns den Basisagenten mit zwei Methoden an (search_docs Und get_order_status). Dies dient als Grundlage für den Vergleich mit den drei Observability-Instruments.

"""
Base agent used throughout all three observability demos.

Swap the OPENAI_API_KEY env var or name build_agent() from any demo file.
"""

import os

from dotenv import load_dotenv
from langchain.brokers import AgentExecutor, create_openai_tools_agent
from langchain.instruments import device
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_openai import ChatOpenAI

load_dotenv()


@device
def search_docs(question: str) -> str:
    """Search inside docs for related data."""
    # Simulated retrieval — swap together with your precise vector retailer
    docs = {
        "refund": (
            "Refunds are processed inside 5-7 enterprise days. "
            "Gadgets should be returned inside 30 days."
        ),
        "transport": (
            "Commonplace transport takes 3-5 enterprise days. "
            "Specific is 1-2 days."
        ),
        "account": (
            "You possibly can reset your password by way of the login web page. "
            "Contact assist for account points."
        ),
    }

    for key phrase, content material in docs.gadgets():
        if key phrase in question.decrease():
            return content material

    return f"Discovered basic docs associated to: {question}"


@device
def get_order_status(order_id: str) -> str:
    """Lookup the standing of an order by ID."""
    # Simulated order lookup
    statuses = {
        "ORD-001": "Shipped — anticipated supply 2026-05-30",
        "ORD-002": "Processing — not but shipped",
        "ORD-003": "Delivered on 2026-05-25",
    }

    return statuses.get(
        order_id,
        f"Order {order_id} not discovered within the system.",
    )


def build_agent() -> AgentExecutor:
    llm = ChatOpenAI(
        mannequin="gpt-4o",
        temperature=0,
        api_key=os.environ("OPENAI_API_KEY"),
    )

    instruments = (search_docs, get_order_status)

    immediate = ChatPromptTemplate.from_messages(
        (
            (
                "system",
                "You're a useful buyer assist assistant. "
                "Use instruments when wanted.",
            ),
            ("person", "{enter}"),
            MessagesPlaceholder(variable_name="agent_scratchpad"),
        )
    )

    agent = create_openai_tools_agent(llm, instruments, immediate)

    return AgentExecutor(
        agent=agent,
        instruments=instruments,
        verbose=False,
    )


TEST_QUESTIONS = (
    "What are the refund insurance policies?",
    "What's the standing of order ORD-002?",
    "How lengthy does transport take?",
)


if __name__ == "__main__":
    executor = build_agent()

    for query in TEST_QUESTIONS:
        print(f"nQ: {query}")

        outcome = executor.invoke({"enter": query})

        print(f"A: {outcome('output')}")

Dadurch wird ein Kandidatenagent erstellt, der auch mit jedem der Instruments verwendet werden kann. Das erste Instrument, das wir untersuchen werden, wird das von LangSmith bereitgestellte sein.

LangSmith: Native Langchain-Tracing

Das LangChain-Group hat sich weiterentwickelt LangSmith. Wenn Sie LangChain verwenden, erfolgt die Integration schnell und einfach.

"""
LangSmith observability demo.

Setup:

pip set up langsmith

Set LANGCHAIN_API_KEY in your .env file.

The way it works:

LangSmith hooks into LangChain's callback system by way of env vars, so no code
modifications are wanted past the 2 os.environ traces beneath.
"""

import os

from dotenv import load_dotenv

from agent_base import TEST_QUESTIONS, build_agent

load_dotenv()

# Allow LangSmith tracing. These two vars are all you want.
os.environ("LANGCHAIN_TRACING_V2") = "true"
os.environ("LANGCHAIN_PROJECT") = "agent-observability-demo"

# LANGCHAIN_API_KEY should be set in your .env or setting.


def run_with_metadata(
    executor,
    query: str,
    user_id: str = "demo-user",
):
    """Run the agent and fix per-run metadata by way of config."""
    return executor.invoke(
        {"enter": query},
        config={
            "metadata": {
                "user_id": user_id,
                "supply": "langsmith_demo",
            },
            # Optionally available: tag runs for filtering within the dashboard.
            "tags": ("observability-blog", "demo"),
        },
    )


def predominant():
    print("=== LangSmith Demo ===")
    print("Traces will seem at: https://smith.langchain.com")
    print(f"Venture: {os.environ('LANGCHAIN_PROJECT')}n")

    executor = build_agent()

    for query in TEST_QUESTIONS:
        print(f"Q: {query}")

        outcome = run_with_metadata(executor, query)

        print(f"A: {outcome('output')}n")

    print("Carried out. Open LangSmith to examine the complete hint tree for every run.")


if __name__ == "__main__":
    predominant()

LangSmith stellt automatisch eine Verbindung zum Rückrufsystem von LangChain her, ohne dass Dekorateure oder Wrapper erforderlich sind, um jede Ausführung in Ihrem Projekt-Dashboard anzuzeigen.

Was Sie auf dem Dashboard sehen werden:

Die Hint-Ansicht von LangSmith zeigt den vollständigen Agentenausführungsbaum, vom ersten Aufruf über die Instrument-Nutzung, LLM-Antworten bis hin zur endgültigen Ausgabe. Jeder Knoten umfasst Eingaben, Ausgaben und Latenz.

Sie können Läufe mit Tags versehen, Metadaten hinzufügen, nach Ergebnissen filtern, Läufe als Datensätze speichern und Auswertungen durchführen. Dies ist nützlich, wenn Sie Eingabeaufforderungen oder die Abruflogik verbessern.

Der prompte Spielplatz ist ein weiteres starkes Merkmal. Sie können eine beliebige Ablaufverfolgung öffnen, die Eingabeaufforderung inline bearbeiten und sie erneut ausführen, um eine schlechte LLM-Leistung zu beheben.

Die Einschränkungen von LangSmith zeigen sich im großen Maßstab. Für das kostenlose Kontingent gelten Obergrenzen und die Integration erfordert mehr Aufwand, wenn Sie LangChain nicht verwenden, obwohl OpenTelemetry unterstützt wird.

Langfuse: Open Supply und Framework-Agnostiker

Langfuse ist hier die Open-Supply-Various. Sie können es entweder auf Ihrem Server hosten oder deren Cloud-Dienst nutzen. Es lässt sich auch in alle Frameworks wie LangChain, LlamaIndex, rohe OpenAI-APIs usw. integrieren.

# Learn this Doc-string for putting in the dependencies and their setup 
"""
Langfuse observability demo.

Setup:

pip set up langfuse

Set LANGFUSE_PUBLIC_KEY, LANGFUSE_SECRET_KEY in your .env file.

LANGFUSE_HOST defaults to https://cloud.langfuse.com; override for self-hosted.

Key variations from LangSmith:

- Callback handler is handed per-invoke for extra express management.
- Native session grouping for multi-turn conversations.
- You possibly can rating any hint after the very fact by way of the Langfuse consumer.
"""

import os

from dotenv import load_dotenv
from langfuse import Langfuse
from langfuse.callback import CallbackHandler

from agent_base import TEST_QUESTIONS, build_agent

load_dotenv()


def build_handler(
    session_id: str,
    user_id: str = "demo-user",
) -> CallbackHandler:
    return CallbackHandler(
        public_key=os.environ("LANGFUSE_PUBLIC_KEY"),
        secret_key=os.environ("LANGFUSE_SECRET_KEY"),
        host=os.getenv("LANGFUSE_HOST", "https://cloud.langfuse.com"),
        session_id=session_id,
        user_id=user_id,
        metadata={"supply": "langfuse_demo"},
        tags=("observability-blog", "demo"),
    )


def score_trace(
    trace_id: str,
    rating: float,
    remark: str = "",
):
    """Add a correctness rating to a hint after reviewing the output."""
    lf = Langfuse(
        public_key=os.environ("LANGFUSE_PUBLIC_KEY"),
        secret_key=os.environ("LANGFUSE_SECRET_KEY"),
        host=os.getenv("LANGFUSE_HOST", "https://cloud.langfuse.com"),
    )

    lf.rating(
        trace_id=trace_id,
        title="correctness",
        worth=rating,
        remark=remark,
    )

    lf.flush()

    print(f"Scored hint {trace_id}: {rating}")


def run_single_session(
    executor,
    session_id: str,
):
    """Run all check questions in a single session so that they're linked within the UI."""
    handler = build_handler(session_id=session_id)
    trace_ids = ()

    for query in TEST_QUESTIONS:
        print(f"Q: {query}")

        outcome = executor.invoke(
            {"enter": query},
            config={"callbacks": (handler)},
        )

        print(f"A: {outcome('output')}n")

        # handler.get_trace_id() returns the hint ID for the final run.
        trace_ids.append(handler.get_trace_id())

    # Flush ensures traces are despatched earlier than the method exits.
    # That is essential in batch jobs.
    handler.flush()

    return trace_ids


def predominant():
    print("=== Langfuse Demo ===")
    print(f"Dashboard: {os.getenv('LANGFUSE_HOST', 'https://cloud.langfuse.com')}n")

    executor = build_agent()
    session_id = "demo-session-001"

    trace_ids = run_single_session(executor, session_id)

    # Instance: programmatically rating the primary hint.
    if trace_ids and trace_ids(0):
        print("nScoring first hint for example:")
        score_trace(trace_ids(0), rating=0.9, remark="Reply was correct")

    print(f"nDone. Discover all runs beneath session '{session_id}' in your Langfuse dashboard.")


if __name__ == "__main__":
    predominant()

Sie können bei jedem Lauf Callback-Handler übergeben, was etwas expliziter ist als bei LangSmith, aber mehr Flexibilität bietet, da Sie beim Aufruf Benutzer-IDs, Sitzungs-IDs und benutzerdefinierte Metadaten zuweisen können.

Bewertungsworkflow

Langfuse verfügt auch über einen wirklich guten Bewertungsworkflow; Sie können Punkte hinzufügen, nachdem die Verfolgung abgeschlossen ist.

from langfuse import Langfuse

lf = Langfuse()

# Rating a particular hint by ID.
lf.rating(
    trace_id="trace-abc123",
    title="correctness",
    worth=0.9,
    remark="Reply was correct however barely verbose",
)

Dies funktioniert in Verbindung mit menschlichen Überprüfungen der von Ihrem Group erzielten Antworten, sodass Sie im Laufe der Zeit aggregierte Bewertungsmetriken erhalten.

Benutzer können ihre Sitzungen organisieren, indem sie sie verbinden, sodass Agenten Gespräche über mehrere Runden hinweg problemlos verfolgen können. Alle Spuren einer einzelnen Benutzersitzung werden in der Anwendung verknüpft, sodass Sie ein gesamtes Gespräch an einem Ort verfolgen können.

Arize: ML-Beobachtbarkeit auf Produktionsniveau

Arize wurde ursprünglich als Plattform zur Überwachung herkömmlicher Modelle des maschinellen Lernens entwickelt und ist nun in der Lage, sowohl Sprachmodelle als auch Agenten zu beobachten. Die Tatsache, dass es ursprünglich entwickelt wurde, um Groups bei der maßstabsgetreuen Bereitstellung von Modellen in der Produktion zu unterstützen, ist bis heute erhalten geblieben.

Nutzung von OpenInference

Zusätzlich zur Verwendung des OpenInference-Requirements als Messschema lässt sich Arize zur Instrumentierung in OpenTelemetry integrieren. Die Konfiguration von Arize ist komplizierter als bei den meisten Anbietern.

# Learn this Doc-string for putting in the dependencies and their setup 
"""
Arize observability demo.

Setup:

pip set up arize-otel openinference-instrumentation-langchain

Set ARIZE_SPACE_ID and ARIZE_API_KEY in your .env file.

Key variations from the others:

- Makes use of OpenTelemetry beneath the hood, so it integrates with present OTel stacks.
- Instrumentation is international like LangSmith, not per-invoke like Langfuse.
- Greatest-in-class manufacturing monitoring: drift detection, cohort evaluation, alerting.
- Phoenix, arize-phoenix, is the free native sibling for growth use.
"""

import os

from arize.otel import register
from dotenv import load_dotenv
from openinference.instrumentation.langchain import LangChainInstrumentor

from agent_base import TEST_QUESTIONS, build_agent

load_dotenv()


def setup_arize_tracing():
    """Register Arize because the OTel tracer supplier and instrument LangChain globally."""
    tracer_provider = register(
        space_id=os.environ("ARIZE_SPACE_ID"),
        api_key=os.environ("ARIZE_API_KEY"),
        project_name="agent-observability-demo",
    )

    LangChainInstrumentor().instrument(tracer_provider=tracer_provider)

    return tracer_provider


def run_with_attributes(
    executor,
    query: str,
    user_segment: str = "commonplace",
):
    """Run the agent and fix span attributes for cohort evaluation in Arize."""
    from opentelemetry import hint

    tracer = hint.get_tracer(__name__)

    with tracer.start_as_current_span("agent_run") as span:
        span.set_attribute("person.phase", user_segment)
        span.set_attribute("question.textual content", query)
        span.set_attribute("demo.supply", "arize_demo")

        outcome = executor.invoke({"enter": query})

        span.set_attribute("response.textual content", outcome("output"))

        return outcome


def predominant():
    print("=== Arize Demo ===")
    print("Traces will seem at: https://app.arize.com")
    print("Venture: agent-observability-demon")

    setup_arize_tracing()

    executor = build_agent()

    # Simulate two person segments to reveal cohort evaluation in Arize.
    segments = ("premium", "commonplace", "commonplace")

    for query, phase in zip(TEST_QUESTIONS, segments):
        print(f"Q: {query} (phase={phase})")

        outcome = run_with_attributes(
            executor,
            query,
            user_segment=phase,
        )

        print(f"A: {outcome('output')}n")

    print("Carried out. In Arize, use the cohort filter to check premium vs commonplace responses.")
    print("Arrange screens on the Arize dashboard to alert on response high quality drift.")


if __name__ == "__main__":
    predominant()

Die Instrumentierung ist international wie die von LangSmith, wird jedoch zu einem Bestandteil des gesamten Messrahmens von OpenTelemetry. Daher kann Arize den vorhandenen Observability Stack Ihrer Organisation nutzen, unabhängig vom tatsächlich verwendeten Framework (z. B. Jaeger, Grafana usw.).

Welches sollten Sie für die Beobachtbarkeit von Agenten auswählen?

Um ganz offen zu sein: Es gibt kein einziges richtiges Instrument für alle Anwendungsfälle. Es hängt alles davon ab, wo Sie sich im Entwicklungszyklus befinden und was Ihr Group braucht.

Besonderheit LangSmith Langfuse Arize
Komplexität der Einrichtung Minimal (2 Umgebungsvariablen) Niedrig (Callback-Handler) Die meisten Boilerplate
Framework-Unterstützung LangChain-nativ; andere über OTel Jeder Rahmen Beliebiges Framework über OTel
Selbsthosting Beschränkt Erstklassig (Docker Compose) Nur Phoenix (lokaler Entwickler)
Hint-Visualisierung Ausgezeichnete Baumansicht Intestine, sitzungsgebunden Intestine, OTel-Commonplace
Bewertung / Wertung Datensatz + Spielplatz Menschliche Bewertungen auf Sitzungsebene Rubrikenbasierte Bewertungen
Produktionsüberwachung Primary Primary Drift, Alarmierung, Kohorten
Multi-Flip / Sitzungen Thread-Ebene Native Sitzungsgruppierung Nur auf Hint-Ebene
Open Supply Proprietär Vollständig Open Supply Phoenix ist OSS; Plattform nicht
Kostenloses Kontingent Begrenzte Spuren/Monat Großzügig (Selbstgastgeber = unbegrenzt) Beschränkt
Am besten für LangChain-Entwicklung und -Iteration Dateneigentum + beliebiges Framework Überwachung im Produktionsmaßstab
  • Verwenden LangSmith wenn Sie mit LangChain erstellen und die schnellste Einrichtung für schnelles Debuggen und Iteration wünschen.
  • Verwenden Langfuse wenn Sie Selbsthosting, stärkeres Dateneigentum, Multi-Framework-Unterstützung oder Monitoring auf Sitzungsebene für Konversationsagenten benötigen.
  • Verwenden Arize wenn Ihr Agent in die Produktion übergeht und Sie Überwachung, Abweichungserkennung, Kohorten und Warnungen benötigen.

Abschluss

Die Beobachtbarkeit von Agenten gehört zu den Dingen, die Sie nur dann bereuen, wenn in der Produktion ein Fehler auftritt. Das Nachverfolgen einer Agentenausführung ohne jegliche Instrumentierung ist wie das Debuggen eines verteilten Programs mit Druckanweisungen.

Alle drei hier behandelten Werkzeuge sind produktionsbereit. Sie haben jeweils einen freien Zugang. Und die Integration mit einem LangChain-Agenten dauert jeweils weniger als 30 Minuten. Es gibt keinen guten Grund mehr, einen unbeobachtbaren Agenten zu entsenden.

Wählen Sie das Werkzeug, das zu Ihrer aktuellen Section passt. Fügen Sie frühzeitig Punkte hinzu, auch informell. Und wenn Ihr Agent um 2 Uhr morgens anfängt, etwas Seltsames zu tun, werden Sie es nicht bereuen.

Information Science Trainee bei Analytics Vidhya
Derzeit arbeite ich als Information Science Trainee bei Analytics Vidhya, wo ich mich auf die Entwicklung datengesteuerter Lösungen und die Anwendung von KI/ML-Techniken zur Lösung realer Geschäftsprobleme konzentriere. Meine Arbeit ermöglicht es mir, fortschrittliche Analysen, maschinelles Lernen und KI-Anwendungen zu erforschen, die es Unternehmen ermöglichen, intelligentere, evidenzbasierte Entscheidungen zu treffen.
Mit einem starken Fundament in den Bereichen Informatik, Softwareentwicklung und Datenanalyse ist es mir eine Leidenschaft, KI zu nutzen, um wirkungsvolle, skalierbare Lösungen zu schaffen, die die Lücke zwischen Technologie und Geschäft schließen.
📩 Du kannst mich auch erreichen unter (electronic mail protected)

Melden Sie sich an, um weiterzulesen und von Experten kuratierte Inhalte zu genießen.

Von admin

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert