Skip to main content
langfuse-core-workflow-a Execute Langfuse primary workflow: Tracing LLM calls and spans.
Use when implementing LLM tracing, building traced AI features,
or adding observability to existing LLM applications.
Trigger with phrases like "langfuse tracing", "trace LLM calls",
"add langfuse to openai", "langfuse spans", "track llm requests".
跳到安装 Skills Marketplace 发现并探索由社区构建的 Agent Skills
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/jeremylongshore/claude-code-plugins-plus-skills --skill langfuse-core-workflow-a命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
下载 Zip 下载中... 同仓库更多 Skills Implement user sign-up and sign-in flows with Clerk.
Use when building authentication UI, customizing sign-in experience,
or implementing OAuth social login.
Trigger with phrases like "clerk sign-in", "clerk sign-up",
"clerk login flow", "clerk OAuth", "clerk social login".
Implement session management and middleware with Clerk.
Use when managing user sessions, configuring route protection,
or implementing token refresh and custom JWT templates.
Trigger with phrases like "clerk session", "clerk middleware",
"clerk route protection", "clerk token", "clerk JWT".
Configure enterprise SSO, role-based access control, and organization management.
Use when implementing SSO integration, configuring role-based permissions,
or setting up organization-level controls.
Trigger with phrases like "clerk SSO", "clerk RBAC",
"clerk enterprise", "clerk roles", "clerk permissions", "clerk organizations".
jeremylongshore
jeremylongshore/claude-code-plugins-plus-skills
打开 GitHub 仓库 name langfuse-core-workflow-a description Execute Langfuse primary workflow: Tracing LLM calls and spans.
Use when implementing LLM tracing, building traced AI features,
or adding observability to existing LLM applications.
Trigger with phrases like "langfuse tracing", "trace LLM calls",
"add langfuse to openai", "langfuse spans", "track llm requests".
allowed-tools Read, Write, Edit, Bash(npm:*), Grep version 1.12.0 license MIT author Jeremy Longshore <jeremy@intentsolutions.io> tags ["saas","langfuse","observability","llm","workflow"] compatibility Designed for Claude Code, also compatible with Codex and OpenClaw
Langfuse Core Workflow A: Tracing LLM Calls
Overview
End-to-end tracing of LLM calls, chains, and agents. Covers the OpenAI drop-in wrapper, manual tracing with startActiveObservation, RAG pipeline instrumentation, streaming response tracking, and LangChain integration.
Prerequisites
Completed langfuse-install-auth setup
OpenAI SDK installed (npm install openai)
For v4+: @langfuse/openai, @langfuse/tracing, @langfuse/otel, @opentelemetry/sdk-node
Instructions
Step 1: OpenAI Drop-In Wrapper (Zero-Code Tracing)
import OpenAI from "openai" ;
import { observeOpenAI } from "@langfuse/openai" ;
const openai = observeOpenAI (new OpenAI ());
const response = await openai.chat .completions .create ({
model : "gpt-4o" ,
messages : [
{ role : "system" , content : "You are a helpful assistant." },
{ role : "user" , content : "What is Langfuse?" },
],
});
const res = await observeOpenAI (new OpenAI (), {
: ,
: { : },
: ,
: ,
: [ , ],
}). . . ({
: ,
: [{ : , : }],
});
generationName
"product-description"
generationMetadata
feature
"onboarding"
sessionId
"session-abc"
userId
"user-123"
tags
"production"
"onboarding"
chat
completions
create
model
"gpt-4o-mini"
messages
role
"user"
content
"Describe this product"
Step 2: Manual Tracing -- RAG Pipeline (v4+ SDK) import { startActiveObservation, updateActiveObservation } from "@langfuse/tracing" ;
async function ragPipeline (query : string ) {
return await startActiveObservation ("rag-pipeline" , async () => {
updateActiveObservation ({ input : { query }, metadata : { pipeline : "rag-v2" } });
const embedding = await startActiveObservation ("embed-query" , async () => {
updateActiveObservation ({ input : { text : query } });
const vector = await embedText (query);
updateActiveObservation ({
output : { dimensions : vector.length },
metadata : { model : "text-embedding-3-small" },
});
return vector;
});
const documents = await startActiveObservation ("vector-search" , async () => {
updateActiveObservation ({ input : { dimensions : embedding.length } });
const docs = await searchVectorDB (embedding);
updateActiveObservation ({
output : { documentCount : docs.length , topScore : docs[0 ]?.score },
});
return docs;
});
const answer = await startActiveObservation (
{ name : "generate-answer" , asType : "generation" },
async () => {
updateActiveObservation ({
model : "gpt-4o" ,
input : { query, context : documents.map ((d ) => d.content ) },
});
const result = await generateAnswer (query, documents);
updateActiveObservation ({
output : result.content ,
usage : {
promptTokens : result.usage .prompt_tokens ,
completionTokens : result.usage .completion_tokens ,
},
});
return result.content ;
}
);
updateActiveObservation ({ output : { answer } });
return answer;
});
}
Step 3: Manual Tracing -- RAG Pipeline (v3 Legacy) import { Langfuse } from "langfuse" ;
const langfuse = new Langfuse ();
async function ragPipeline (query : string ) {
const trace = langfuse.trace ({
name : "rag-pipeline" ,
input : { query },
metadata : { pipeline : "rag-v1" },
});
const embedSpan = trace.span ({ name : "embed-query" , input : { text : query } });
const embedding = await embedText (query);
embedSpan.end ({ output : { dimensions : embedding.length } });
const searchSpan = trace.span ({ name : "vector-search" });
const documents = await searchVectorDB (embedding);
searchSpan.end ({ output : { count : documents.length , topScore : documents[0 ]?.score } });
const generation = trace.generation ({
name : "generate-answer" ,
model : "gpt-4o" ,
modelParameters : { temperature : 0.7 , maxTokens : 500 },
input : { query, context : documents.map ((d ) => d.content ) },
});
const answer = await generateAnswer (query, documents);
generation.end ({
output : answer.content ,
usage : {
promptTokens : answer.usage .prompt_tokens ,
completionTokens : answer.usage .completion_tokens ,
totalTokens : answer.usage .total_tokens ,
},
});
trace.update ({ output : { answer : answer.content } });
await langfuse.flushAsync ();
return answer.content ;
}
Step 4: Streaming Response Tracking import OpenAI from "openai" ;
import { observeOpenAI } from "@langfuse/openai" ;
const openai = observeOpenAI (new OpenAI ());
const stream = await openai.chat .completions .create ({
model : "gpt-4o" ,
messages : [{ role : "user" , content : "Tell me a story" }],
stream : true ,
stream_options : { include_usage : true },
});
let fullContent = "" ;
for await (const chunk of stream) {
const content = chunk.choices [0 ]?.delta ?.content || "" ;
fullContent += content;
process.stdout .write (content);
}
Step 5: Anthropic Claude Tracing (Manual) import Anthropic from "@anthropic-ai/sdk" ;
import { startActiveObservation, updateActiveObservation } from "@langfuse/tracing" ;
const anthropic = new Anthropic ();
async function callClaude (prompt : string ) {
return await startActiveObservation (
{ name : "claude-call" , asType : "generation" },
async () => {
updateActiveObservation ({
model : "claude-sonnet-4-20250514" ,
input : [{ role : "user" , content : prompt }],
});
const response = await anthropic.messages .create ({
model : "claude-sonnet-4-20250514" ,
max_tokens : 1024 ,
messages : [{ role : "user" , content : prompt }],
});
updateActiveObservation ({
output : response.content [0 ].text ,
usage : {
promptTokens : response.usage .input_tokens ,
completionTokens : response.usage .output_tokens ,
},
});
return response.content [0 ].text ;
}
);
}
Step 6: LangChain Integration (Python) from langfuse.callback import CallbackHandler
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
langfuse_handler = CallbackHandler()
llm = ChatOpenAI(model="gpt-4o" )
prompt = ChatPromptTemplate.from_messages([
("system" , "You are a helpful assistant." ),
("human" , "{input}" ),
])
chain = prompt | llm
result = chain.invoke(
{"input" : "What is Langfuse?" },
config={"callbacks" : [langfuse_handler]},
)
Error Handling Issue Cause Solution Missing generations OpenAI wrapper not applied Use observeOpenAI() from @langfuse/openai Orphaned spans Missing end or callback finish Use startActiveObservation (auto-ends) or .end() in finally No token usage on stream Stream usage not requested Add stream_options: { include_usage: true } Flat trace (no nesting) Missing OTel context Ensure NodeSDK is started with LangfuseSpanProcessor
Resources
Next Steps For evaluation and scoring workflows, see langfuse-core-workflow-b.