Skip to main content

Observability for Claude Agent SDK with Langfuse

还没翻译译自英文(langfuse.com)本页 40 段都还没译

Integrate Langfuse with Claude Agent SDK

Python JS/TS

This notebook demonstrates how to capture detailed traces from the Claude Agent SDK with Langfuse using OpenTelemetry.

What is Claude Agent SDK?
The Claude Agent SDK is Anthropic's open-source framework for building AI agents. It provides a clean API for creating tool-using agents, including native support for MCP.

What is Langfuse?
Langfuse is the open source AI engineering platform. It provides detailed tracing, monitoring, and analytics for every prompt, model response, and tool call in your agent, making it easy to debug, evaluate, and iterate on LLM applications. Use Langfuse Cloud (hosted by Langfuse, free tier, no infrastructure to run) or self-host it.

Step 1: Install Dependencies

%pip install langfuse claude-agent-sdk openinference-instrumentation-claude-agent-sdk -q

Step 2: Set Up Environment Variables

Set up your Langfuse API keys (Langfuse Cloud or self-hosted) and your Anthropic API key (Anthropic Console).

import os

# Get keys for your project from the project settings page: https://cloud.langfuse.com
os.environ.setdefault("LANGFUSE_PUBLIC_KEY", "pk-lf-***");
os.environ.setdefault("LANGFUSE_SECRET_KEY", "sk-lf-***");
os.environ.setdefault("LANGFUSE_BASE_URL", "https://cloud.langfuse.com"); # 🇪🇺 EU region
# Other Langfuse data regions include 🇺🇸 US: https://us.cloud.langfuse.com, 🇯🇵 Japan: https://jp.cloud.langfuse.com and ⚕️ HIPAA: https://hipaa.cloud.langfuse.com

# Your Anthropic API key
os.environ.setdefault("ANTHROPIC_API_KEY", "sk-ant-***");

With the environment variables set, we can now initialize the Langfuse client. get_client() initializes the Langfuse client using the credentials provided in the environment variables.

from langfuse import get_client

langfuse = get_client()

# Verify connection
if langfuse.auth_check():
    print("Langfuse client is authenticated and ready!")
else:
    print("Authentication failed. Please check your credentials and host.")

Step 3: OpenTelemetry Instrumentation

Use OpenInference's Claude Agent SDK instrumentation library to instrument the agent SDK and send OpenTelemetry spans to Langfuse.

from openinference.instrumentation.claude_agent_sdk import ClaudeAgentSDKInstrumentor

ClaudeAgentSDKInstrumentor().instrument()

Step 4: Build a Hello World Agent

Every tool call and model completion is captured as an OpenTelemetry span and forwarded to Langfuse.

import asyncio
from claude_agent_sdk import (
    ClaudeAgentOptions,
    ClaudeSDKClient,
    tool,
    create_sdk_mcp_server,
)
from typing import Any

@tool(
    "get_weather",
    "Gets the current weather for a given city",
    {
        "city": str,
    },
)
async def get_weather(args: dict[str, Any]) -> dict[str, Any]:
    """Simulated weather lookup tool"""
    city = args["city"]

    # Simulated weather data
    weather_data = {
        "Berlin": "Cloudy, 59°F",
        "New York": "Sunny, 75°F",
    }

    weather = weather_data.get(city, "Weather data not available")
    return {"content": [{"type": "text", "text": f"Weather in {city}: {weather}"}]}


async def main():
    # Create SDK MCP server with the weather tool
    weather_server = create_sdk_mcp_server(
        name="weather",
        version="1.0.0",
        tools=[get_weather],
    )

    options = ClaudeAgentOptions(
        model="claude-sonnet-4-5-20250929",
        system_prompt="You are a friendly travel assistant who helps with weather information.",
        mcp_servers={"weather": weather_server},
        allowed_tools=["mcp__weather__get_weather"],
    )

    async with ClaudeSDKClient(options=options) as client:
        await client.query("What's the weather like in Berlin and New York?")

        async for message in client.receive_response():
            print(message)


await main()

Step 5: View the Trace in Langfuse

Head over to your Langfuse dashboard → Traces. You should see traces including all tool calls and model inputs/outputs.

Claude Agent SDK example trace in Langfuse

Link to trace in Langfuse

Interoperability with the Python SDK

You can use this integration together with the Langfuse SDKs to add additional attributes to the observation.

DecoratorContext Manager

The @observe() decorator provides a convenient way to automatically wrap your instrumented code and add additional attributes to the observation.

from langfuse import observe, propagate_attributes, get_client

langfuse = get_client()

@observe()
def my_llm_pipeline(input):
    # Add additional attributes (user_id, session_id, metadata, version, tags) to all spans created within this execution scope
    with propagate_attributes(
        user_id="user_123",
        session_id="session_abc",
        tags=["agent", "my-observation"],
        metadata={"email": "user@langfuse.com"},
        version="1.0.0"
    ):

        # YOUR APPLICATION CODE HERE
        result = call_llm(input)

        return result

# Run the function
my_llm_pipeline("Hi")

Learn more about using the Decorator in the Langfuse SDK instrumentation docs.

Troubleshooting

No observations appearing

Unwanted observations in Langfuse

Missing attributes

Next Steps

Once you have instrumented your code, you can manage, evaluate and debug your application:

Manage prompts in Langfuse Add evaluation scores Run LLM-as-a-judge Evaluators Create datasets Create custom dashboards Test queries in the Playground