Langfuse Workflow Patterns: Complete Implementation Guide
Langfuse Workflow Patterns: Complete Implementation Guide
🎯 Overview
This guide documents the correct event sequences for common LLM application patterns.
🔄 1. RAG (Retrieval-Augmented Generation) Pipeline
Event Sequence:
1. Trace Creation
2. Document Retrieval Span
3. LLM Generation with Context
4. Final Response Event
Expected Langfuse Structure:
{
"batch": [
{
"type": "trace-create",
"body": {
"id": "rag-trace-001",
"name": "RAG Query Processing",
"input": "What is the capital of France?",
"userId": "user-123",
"tags": ["rag", "qa"]
}
},
{
"type": "span-create",
"body": {
"id": "retrieval-span",
"traceId": "rag-trace-001",
"name": "Document Retrieval",
"input": {"query": "capital France", "top_k": 5},
"output": {"documents": [...], "scores": [0.95, 0.87]}
}
},
{
"type": "generation-create",
"body": {
"id": "rag-generation",
"traceId": "rag-trace-001",
"name": "RAG Generation",
"model": "gpt-4",
"input": [
{"role": "system", "content": "Answer based on context"},
{"role": "user", "content": "Context: [retrieved docs]\n\nQuestion: What is the capital of France?"}
],
"output": {
"role": "assistant",
"content": "Based on the context, the capital of France is Paris."
}
}
}
]
}
LLM4S Implementation:
// This is automatically handled by the fixed LangfuseTracing.scala
// When you run an agent with RAG capabilities:
val agent = new Agent(client)
val query = "What is the capital of France?"
agent.run(
query = query,
tools = ragToolRegistry,
traceLogPath = Some("rag-example.md")
) match {
case Right(finalState) =>
// The fixed tracing will automatically create:
// 1. Trace with query as input and final answer as output
// 2. Generation events with proper conversation context
// 3. Tool execution spans for document retrieval
// 4. Proper hierarchical structure
}
💬 2. Chat Conversation Flow
Event Sequence:
1. Trace Creation (Session-level)
2. User Input Event
3. LLM Generation
4. Assistant Response Event
5. [Repeat for conversation turns]
Expected Langfuse Structure:
{
"batch": [
{
"type": "trace-create",
"body": {
"id": "chat-session-001",
"name": "Customer Support Chat",
"input": "Initial user message",
"sessionId": "session-456",
"userId": "user-123",
"tags": ["chat", "support"]
}
},
{
"type": "event-create",
"body": {
"id": "user-input-1",
"traceId": "chat-session-001",
"name": "User Input",
"input": {"role": "user", "content": "I need help with my order"}
}
},
{
"type": "generation-create",
"body": {
"id": "chat-response-1",
"traceId": "chat-session-001",
"name": "Support Response",
"model": "gpt-4",
"input": [
{"role": "system", "content": "You are a helpful support agent"},
{"role": "user", "content": "I need help with my order"}
],
"output": {
"role": "assistant",
"content": "I'd be happy to help you with your order. Could you please provide your order number?"
}
}
}
]
}
LLM4S Implementation:
// For multi-turn conversations, the fixed implementation handles this automatically
val conversation = Conversation(Seq(
SystemMessage("You are a helpful support agent"),
UserMessage("I need help with my order"),
AssistantMessage("I'd be happy to help. What's your order number?"),
UserMessage("Order #12345")
))
// The tracing will capture:
// - Each message as appropriately typed events/generations
// - Full conversation context in generation inputs
// - Complete responses in generation outputs
🤖 3. Agentic Loop with Tool Calling
Event Sequence:
1. Trace Creation
2. Initial Planning Generation (with tool_calls)
3. Tool Execution Spans (parallel or sequential)
4. Synthesis Generation (with tool results)
5. Final Response
Expected Langfuse Structure:
{
"batch": [
{
"type": "trace-create",
"body": {
"id": "agent-trace-001",
"name": "Travel Assistant Task",
"input": "Book a flight to Paris and check weather",
"tags": ["agent", "multi-tool"]
}
},
{
"type": "generation-create",
"body": {
"id": "planning-gen",
"traceId": "agent-trace-001",
"name": "Agent Planning",
"model": "gpt-4",
"input": [
{"role": "system", "content": "You are a travel assistant with tools"},
{"role": "user", "content": "Book a flight to Paris and check weather"}
],
"output": {
"role": "assistant",
"content": "I'll help you with both tasks. Let me check the weather and search for flights.",
"tool_calls": [
{"id": "call_1", "function": {"name": "get_weather", "arguments": "{\"city\": \"Paris\"}"}},
{"id": "call_2", "function": {"name": "search_flights", "arguments": "{\"destination\": \"Paris\"}"}}
]
}
}
},
{
"type": "span-create",
"body": {
"id": "weather-span",
"traceId": "agent-trace-001",
"parentObservationId": "planning-gen",
"name": "Tool: get_weather",
"input": {"toolName": "get_weather", "arguments": {"city": "Paris"}},
"output": {"result": "Paris weather: 15°C, partly cloudy"}
}
},
{
"type": "span-create",
"body": {
"id": "flight-span",
"traceId": "agent-trace-001",
"parentObservationId": "planning-gen",
"name": "Tool: search_flights",
"input": {"toolName": "search_flights", "arguments": {"destination": "Paris"}},
"output": {"result": "Found 3 flights: $299, $315, $289"}
}
},
{
"type": "generation-create",
"body": {
"id": "synthesis-gen",
"traceId": "agent-trace-001",
"name": "Final Response",
"model": "gpt-4",
"input": [
{"role": "system", "content": "You are a travel assistant..."},
{"role": "user", "content": "Book a flight to Paris and check weather"},
{"role": "assistant", "content": "I'll help you...", "tool_calls": [...]},
{"role": "tool", "content": "Paris weather: 15°C...", "tool_call_id": "call_1"},
{"role": "tool", "content": "Found 3 flights...", "tool_call_id": "call_2"}
],
"output": {
"role": "assistant",
"content": "Great! Here's what I found:\n\n**Weather:** Paris is 15°C and partly cloudy.\n\n**Flights:** I found 3 options with prices from $289-$315. Would you like me to help you book one?"
}
}
}
]
}
LLM4S Implementation:
// The fixed implementation automatically handles this complex flow
val toolRegistry = new ToolRegistry(Seq(WeatherTool.tool, FlightTool.tool))
val agent = new Agent(client)
agent.run(
query = "Book a flight to Paris and check weather",
tools = toolRegistry,
maxSteps = Some(5),
traceLogPath = Some("agent-example.md")
) match {
case Right(finalState) =>
// Automatically creates:
// 1. Trace with initial query and final response
// 2. Generation for initial planning with tool_calls in output
// 3. Spans for each tool execution with proper parent-child relationships
// 4. Generation for synthesis with full conversation context
// 5. Proper hierarchical structure throughout
}
🧠4. Multi-Step Reasoning Chain
Event Sequence:
1. Trace Creation
2. Problem Analysis Generation
3. Step-by-Step Reasoning Spans
4. Synthesis Generation
5. Verification Event (optional)
Expected Langfuse Structure:
{
"batch": [
{
"type": "trace-create",
"body": {
"id": "reasoning-trace-001",
"name": "Math Problem Solving",
"input": "If I have 15 apples and give away 1/3, then buy 8 more, how many do I have?",
"tags": ["reasoning", "math"]
}
},
{
"type": "generation-create",
"body": {
"id": "analysis-gen",
"traceId": "reasoning-trace-001",
"name": "Problem Analysis",
"model": "gpt-4",
"input": [
{"role": "system", "content": "Solve step by step"},
{"role": "user", "content": "If I have 15 apples and give away 1/3, then buy 8 more, how many do I have?"}
],
"output": {
"role": "assistant",
"content": "I need to solve this step by step:\n1. Start with 15 apples\n2. Give away 1/3 of them\n3. Buy 8 more\n\nLet me calculate each step."
}
}
},
{
"type": "span-create",
"body": {
"id": "step1-span",
"traceId": "reasoning-trace-001",
"name": "Calculate 1/3 of 15",
"input": {"calculation": "15 ÷ 3"},
"output": {"result": "5 apples to give away"}
}
},
{
"type": "span-create",
"body": {
"id": "step2-span",
"traceId": "reasoning-trace-001",
"name": "Remaining after giving away",
"input": {"calculation": "15 - 5"},
"output": {"result": "10 apples remaining"}
}
},
{
"type": "span-create",
"body": {
"id": "step3-span",
"traceId": "reasoning-trace-001",
"name": "Add purchased apples",
"input": {"calculation": "10 + 8"},
"output": {"result": "18 apples total"}
}
},
{
"type": "generation-create",
"body": {
"id": "final-answer-gen",
"traceId": "reasoning-trace-001",
"name": "Final Answer",
"model": "gpt-4",
"input": [
{"role": "system", "content": "Provide the final answer based on calculations"},
{"role": "user", "content": "Based on the steps: 15 - 5 + 8 = ?"}
],
"output": {
"role": "assistant",
"content": "You will have 18 apples total.\n\nBreakdown:\n- Started with: 15 apples\n- Gave away 1/3 (5 apples): 15 - 5 = 10 apples\n- Bought 8 more: 10 + 8 = 18 apples"
}
}
}
]
}
🔧 5. Error Handling and Recovery
Event Sequence with Errors:
1. Trace Creation
2. Initial Generation (fails)
3. Error Event
4. Retry Span
5. Successful Generation
6. Recovery Event
Expected Langfuse Structure:
{
"batch": [
{
"type": "trace-create",
"body": {
"id": "error-recovery-trace",
"name": "API Call with Retry",
"input": "Get user profile for user-123",
"tags": ["api", "retry", "error-handling"]
}
},
{
"type": "generation-create",
"body": {
"id": "initial-attempt",
"traceId": "error-recovery-trace",
"name": "Initial API Call",
"model": "gpt-4",
"input": [{"role": "user", "content": "Get user profile for user-123"}],
"output": {
"role": "assistant",
"content": "I'll retrieve the user profile.",
"tool_calls": [{"id": "call_1", "function": {"name": "get_user", "arguments": "{\"user_id\": \"user-123\"}"}}]
}
}
},
{
"type": "event-create",
"body": {
"id": "error-event",
"traceId": "error-recovery-trace",
"name": "API Error",
"level": "ERROR",
"statusMessage": "Connection timeout",
"input": {"error": "Connection timeout after 30s"},
"metadata": {
"errorType": "TimeoutException",
"attempt": 1,
"willRetry": true
}
}
},
{
"type": "span-create",
"body": {
"id": "retry-span",
"traceId": "error-recovery-trace",
"name": "Retry Attempt",
"input": {"attempt": 2, "backoff": "2s"},
"output": {"status": "success", "data": {"user": "profile data"}}
}
},
{
"type": "event-create",
"body": {
"id": "recovery-event",
"traceId": "error-recovery-trace",
"name": "Recovery Success",
"input": {"message": "Successfully recovered after 1 retry"},
"metadata": {"totalAttempts": 2, "recoveryTime": "2.1s"}
}
}
]
}