Documentation Index
Fetch the complete documentation index at: https://docs.uselemma.ai/llms.txt
Use this file to discover all available pages before exploring further.
Add business metadata where Langfuse creates or enriches your observations. For greenfield apps, prefer framework telemetry metadata or Langfuse SDK propagation.
Recommended keys
user.id (or enduser.id) for user identity
session.id for runtime session correlation
deployment.environment.name for environment
service.version for release tracking
gen_ai.agent.name for agent identity; use snake_case, CamelCase, or kebab-case
app.tenant.id and app.outcome for app-specific metadata
lemma.thread_id only for Lemma thread grouping
Use consistent key names across services so filtering stays reliable.
By semantic convention, gen_ai.agent.name values should be formatted as snake_case, CamelCase, or kebab-case (for example support_agent, SupportAgent, or support-agent).
Langfuse framework telemetry
When a Langfuse framework integration exposes telemetry metadata, put Lemma and semantic-convention attributes there. For the Vercel AI SDK:
import { streamText } from "ai";
await streamText({
model: "openai/gpt-4o-mini",
messages,
experimental_telemetry: {
isEnabled: true,
functionId: "support-agent",
metadata: {
"gen_ai.agent.name": "planwise-support-agent",
"lemma.thread_id": threadId,
"user.id": userId,
"session.id": sessionId,
"deployment.environment.name": process.env.NODE_ENV,
"service.version": process.env.APP_VERSION,
"app.tenant.id": tenantId,
"app.outcome": outcome,
},
},
});
Langfuse SDK propagation
Use Langfuse propagation when you want user, session, version, and business metadata to follow child observations created inside a scope.
import {
observe,
propagateAttributes,
} from "@langfuse/tracing";
const runSupportAgent = observe(
async (input: {
messages: unknown[];
threadId: string;
userId: string;
sessionId: string;
tenantId: string;
outcome?: string;
}) => {
return await propagateAttributes(
{
userId: input.userId,
sessionId: input.sessionId,
version: process.env.APP_VERSION,
metadata: {
tenantId: input.tenantId,
outcome: input.outcome,
threadId: input.threadId,
lemmaThreadId: input.threadId,
environment: process.env.NODE_ENV,
},
},
async () => {
// Run your framework/model call here.
},
);
},
{ name: "support-agent" },
);
import os
from langfuse import observe, propagate_attributes
@observe(name="support-agent")
def run_support_agent(
messages,
thread_id: str,
user_id: str,
session_id: str,
tenant_id: str,
outcome: str | None = None,
):
with propagate_attributes(
user_id=user_id,
session_id=session_id,
version=os.getenv("APP_VERSION"),
metadata={
"tenantId": tenant_id,
"outcome": outcome,
"threadId": thread_id,
"lemmaThreadId": thread_id,
"environment": os.getenv("ENVIRONMENT"),
},
):
# Run your framework/model call here.
pass
Use OpenTelemetry semantic-convention keys in framework telemetry hooks that accept OTel-style metadata. Langfuse SDK metadata keys are Langfuse metadata fields; keep them stable and mirror the same values there for Langfuse filtering.