Interactive designer
Trace Span Designer
Drag the stages of your LLM pipeline into order. We prescribe the OpenTelemetry / OpenLLMetry span name and the required + recommended attributes for each, emit a fully annotated trace schema and a runnable Python instrumentation snippet, and tell you exactly what you'll be able to debug — and where your blind spots are.
Span names and attribute keys follow the OpenTelemetry GenAI semantic conventions plus OpenLLMetry extensions. See our guide to what belongs in a span (reviewed 2026-05-12).
Stage palette — click to add
Your pipeline — reorder with ◀ ▶, ✕ to remove
Add stages from the palette above to design your trace.
Prescribed spans
#1 Retrieval
retrieval.query · CLIENTOpenLLMetry alias: vector_db.query / db.vector.query
Embed the query and fetch candidate chunks from a vector store or search index.
Attributes
db.system = "pinecone" required Which store answered — separates a Pinecone outage from a Weaviate one.
db.vector.query.top_k = 20 required Recall ceiling; a low top_k is the most common silent cause of 'the answer wasn't in context'.
retrieval.query.text = "how do I rotate API keys" required The actual query embedded — without it you cannot reproduce a bad retrieval.
retrieval.documents.count = 8 required How many chunks actually came back (≠ top_k when the index is small or filtered).
retrieval.documents.ids = "[doc_42#3, doc_11#1]" recommended Lets you replay the exact context and diff it across versions.
retrieval.score.min = 0.71 recommended Score floor — a collapsing min score is an early drift signal for the index.
retrieval.filter = "tenant=acme" recommended Metadata filter applied; a wrong filter looks identical to 'no relevant docs'.
embedding.model = "text-embedding-3-large" recommended Query/index embedding mismatch is a classic invisible failure.
#2 Rerank
rerank.documents · CLIENTOpenLLMetry alias: reranker.rerank
Re-score retrieved candidates with a cross-encoder or LLM judge and keep the best N.
Attributes
rerank.model = "cohere-rerank-3" required Reranker identity — quality regressions usually track a model/version change.
rerank.input.count = 20 required Candidates in; with output.count it reveals how aggressive the cut was.
rerank.output.count = 5 required What actually reached the prompt — the real context budget.
rerank.top_score = 0.93 required Confidence of the kept set; a low top score after rerank means retrieval failed upstream.
rerank.order.changed = true recommended Did rerank actually reorder, or is it dead weight/latency?
rerank.dropped.ids = "[doc_11#1]" recommended Lets you audit a relevant doc the reranker wrongly discarded.
rerank.score.delta = 0.22 recommended Top-vs-cut score gap — a narrow gap means the ranking is barely meaningful.
#3 Prompt assembly
prompt.assemble · INTERNALOpenLLMetry alias: gen_ai.prompt (template stage)
Render the final prompt from a template, retrieved context, history, and variables.
Attributes
prompt.template.id = "rag_answer_v7" required Which template/version produced this prompt — the #1 thing to correlate quality changes against.
prompt.token_count = 3120 required Final assembled size; silent context truncation is a top cause of dropped answers.
prompt.context.truncated = false required Explicit truncation flag so a cut context is loud, not silent.
prompt.variables = "{user_role: admin}" required Injected variables — needed to reproduce the exact prompt deterministically.
prompt.context.doc_count = 5 recommended How many chunks survived into the prompt vs how many rerank emitted.
prompt.system.hash = "sha256:9f2a…" recommended Detects an unannounced system-prompt change across deploys.
prompt.history.turns = 4 recommended Conversation depth — long histories crowd out retrieved context.
#4 LLM call
gen_ai.chat · CLIENTOpenLLMetry alias: openai.chat / {provider}.chat
The model inference request itself — the canonical OpenTelemetry GenAI span.
Attributes
gen_ai.system = "openai" required Provider — first split for latency/error/cost dashboards.
gen_ai.request.model = "gpt-4.1" required Requested model; silent model swaps explain sudden quality/cost shifts.
gen_ai.response.model = "gpt-4.1-2026-04" required Model actually served — providers alias and roll versions under you.
gen_ai.usage.input_tokens = 3120 required Cost and context-pressure driver.
gen_ai.usage.output_tokens = 480 required Cost driver and a proxy for runaway/verbose generations.
gen_ai.response.finish_reason = "stop" required 'length' here = truncated answer; the single most actionable quality field.
gen_ai.request.temperature = 0.2 recommended Reproducibility and explaining nondeterministic regressions.
gen_ai.request.max_tokens = 512 recommended Too-low caps cause 'length' truncation — pair with finish_reason.
gen_ai.response.id = "chatcmpl-AbC123" recommended Provider request id for support tickets and dedup.
gen_ai.usage.cache_read_tokens = 2048 recommended Prompt-cache hit rate — large lever on cost and latency.
#5 Tool / function call
gen_ai.execute_tool · INTERNALOpenLLMetry alias: {tool_name}.tool / function.call
A model-requested tool/function invocation and its result, inside an agent loop.
Attributes
gen_ai.tool.name = "get_account_balance" required Which tool ran — agents fail at the tool boundary far more than in the model.
gen_ai.tool.call.arguments = "{account_id: 42}" required Args the model produced — most agent bugs are malformed/hallucinated arguments.
gen_ai.tool.call.status = "ok" required ok/error/timeout — separates a model mistake from a downstream failure.
gen_ai.tool.call.id = "call_7b2" required Correlates the request with the result message fed back to the model.
gen_ai.tool.result.truncated = true recommended A truncated tool result silently degrades the next model turn.
gen_ai.tool.call.retries = 1 recommended Retry loops are a top hidden latency and cost sink in agents.
gen_ai.agent.step = 3 recommended Position in the agent loop — pinpoints where a multi-step plan derailed.
gen_ai.tool.authority = "read_only" recommended Privilege of the call — flags an agent exceeding its intended scope.
#6 Output guard
guardrail.check · INTERNALOpenLLMetry alias: guardrails.validate
Post-generation validation: safety filters, schema/JSON validation, PII redaction, groundedness checks.
Attributes
guardrail.name = "json_schema+pii" required Which guards ran — a disabled guard is otherwise invisible.
guardrail.passed = false required Pass/fail outcome; the headline reliability signal for the stage.
guardrail.action = "block" required pass/block/redact/regenerate — what the user actually saw.
guardrail.violation.type = "pii_email" required Failure category — drives a violation-type dashboard, not just a count.
guardrail.score = 0.42 recommended Confidence/groundedness score for tuning the threshold instead of guessing.
guardrail.regenerate.count = 1 recommended Regeneration loops are a hidden cost and latency multiplier.
guardrail.latency_ms = 180 recommended Guards on the response path add user-visible latency.
guardrail.redacted.fields = "[email]" recommended Audit trail for what was scrubbed before the user saw it.
#7 Response / root
gen_ai.workflow · SERVEROpenLLMetry alias: traceloop.workflow / {service}.request
The root span that ties the whole request together and carries end-to-end, user-facing outcomes.
Attributes
gen_ai.workflow.name = "rag_support_answer" required Names the pipeline so traces are groupable by product flow, not endpoint.
session.id = "sess_9a1" required Stitches multi-turn conversations and reproduces a user's whole journey.
gen_ai.response.latency_ms = 2400 required The number the user feels — the SLO that matters.
gen_ai.workflow.status = "ok" required End-to-end success/failure independent of any single stage.
user.feedback = "thumbs_down" recommended The only direct quality label most prod systems get — attach it to the trace.
gen_ai.cost.usd = 0.013 recommended Rolled-up request cost for per-feature/per-tenant economics.
deployment.version = "2026.05.1" recommended Correlates a quality/cost shift to a specific release.
tenant.id = "acme" recommended Per-tenant SLOs, cost, and abuse isolation.
Attribute keys follow the OpenTelemetry GenAI semantic conventions (gen_ai.*) plus OpenLLMetry/Traceloop extensions where the spec is still incubating. Span kind is INTERNAL unless the stage crosses a process/network boundary (CLIENT).