Skip to main content

Best Practices

Production-ready patterns for implementing Langfuse observability in your applications.

Naming Conventions

Use consistent, descriptive names for easy filtering and analysis.

# Use prefixes to categorize operations
@observe(name="agent:plan_task")
@observe(name="tool:search_documents")
@observe(name="rag:retrieve_context")
@observe(name="llm:generate_response")
PrefixUse Case
agent:Agent orchestration and reasoning
tool:Tool/function executions
rag:Retrieval-augmented generation steps
llm:Direct LLM calls
api:External API interactions

User & Session Tracking

Always Track Users

from caip_agents_sdk.observability import observe, propagate_attributes

@observe(name="api:handle_request")
async def handle_request(request: Request):
with propagate_attributes(
user_id=request.user.id,
session_id=request.headers.get("X-Session-ID")
):
return await process(request)

Benefits

FeatureBenefit
User IDDebug specific user issues
Session IDView complete conversations
FilteringAnalyze usage patterns

Metadata Strategy

What to Include

from caip_agents_sdk.observability import observe, get_client

@observe(
name="rag:search",
metadata={
"index_name": "products",
"search_type": "hybrid"
}
)
async def search(query: str) -> list:
results = await vector_store.search(query)

# Update span with dynamic metadata
client = get_client()
if client:
client.update_current_span(
metadata={
"result_count": len(results),
"top_score": results[0].score if results else 0
}
)
return results

Metadata Guidelines

✅ Do❌ Don't
Index namesPII (emails, names)
Search typesFull request bodies
Result countsAPI keys or secrets
Feature flagsLarge data payloads
Model versionsSensitive user data

Error Handling

Capture Errors with Context

from caip_agents_sdk.observability import observe, get_client

@observe(name="llm:generate")
async def generate(prompt: str) -> str:
try:
return await llm.complete(prompt)
except Exception as e:
client = get_client()
if client:
client.update_current_span(
metadata={
"error": str(e),
"error_type": type(e).__name__
}
)
raise

Performance Optimization

Graceful Shutdown

import atexit
from caip_agents_sdk.observability import flush

atexit.register(flush)

Production Checklist

Before Deployment

  • Environment variables configured
  • User/session tracking implemented
  • Consistent naming conventions
  • No PII in metadata
  • Graceful shutdown with flush
  • Error handling with context

Monitoring

CheckFrequency
Trace volumeDaily
Error ratesReal-time alerts
Latency P95Daily
Token costsWeekly

Quick Reference

SDK Functions

FunctionPurpose
@observe(name="...")Wrap functions for tracing
propagate_attributes()Set user/session IDs
get_client()Get Langfuse client for advanced operations
client.update_current_span()Add dynamic metadata
flush()Force send pending traces

Environment Variables

LANGFUSE_SECRET_KEY=sk-lf-...
LANGFUSE_PUBLIC_KEY=pk-lf-...
# ROW
LANGFUSE_HOST=https://langfuse.caip.bmw.cloud
# CN
# LANGFUSE_HOST=https://langfuse.caip.bmwchina.cloud
LANGFUSE_ENV=production
LANGFUSE_DEBUG=true # Enable verbose trace logging (development only)
# Optional: disable Langfuse observability
# CAIP_LANGFUSE_OBSERVABILITY=false

SDK Auto-Generated Names

When using the CAIP Agents SDK, LLM calls are automatically named using the pattern caip.{framework}.{method}:

Auto NameMeaning
caip.pydantic_ai.runPydanticAI synchronous call
caip.pydantic_ai.streamPydanticAI streaming call
caip.pydantic_ai.iterPydanticAI iterative call
caip.langchain.runLangChain invoke call
caip.langchain.streamLangChain streaming call
caip.tool.{name}Tool invocation
caip.api.{endpoint}CAIP API call

These names are set automatically — you do not need to configure them. Use the @observe naming conventions (above) for your own custom instrumentation.

Summary

Key Takeaways
  1. Name consistently — Use prefixes for categories
  2. Track users — Enable debugging and analytics
  3. Metadata wisely — Include context, exclude PII
  4. Handle errors — Capture context for debugging
  5. Flush on exit — Ensure all traces are sent

Next Steps