opik
Reference for the Opik SDK — tracing, span types, framework integrations, threads, and the prompt library (Python, TypeScript, REST). Use for "what span types exist", "how do I flush", "track_openai", "add OpikTracer", "version a prompt". To instrument a repo end to end, use the `opik-instrument` sk
By comet-ml · 468 installs
npx skills add comet-ml/opik-skills --skill opik
Source repository · Upstream listing
Opik SDK Reference
Opik is an open source LLM observability platform. This skill is a reference
for the SDK. To instrument a codebase step by step (detect frameworks, add
config, emit and verify a trace), use the task shaped opik instrument skill.
Core concepts
A trace is one execution path (one request → one response). Spans are the
operations inside it and form a hierarchy.
Span types — the ONLY valid values
Type Use for
general orchestration, agent entry points
llm model calls
tool tools, retrieval, API / DB calls
guardrail safety / validation checks
Do NOT use retrieval or any other value.
Python — tracing
TypeScript — tracing
Framework integrations
Prefer an integration over manual @opik.track — integrations capture tokens,
model, and cost automatically. Patterns (full list in
references/integrations.md ):
wrap the client — track openai(OpenAI()) , track anthropic(...)
global enable — track crewai(crew=crew)
callback — dspy.configure(callbacks=[OpikCallback()])
tracer — OpikTracer() for LangChain / LangGraph / LlamaIndex
agent specific — track adk agent recursive(agent, OpikTracer())
LiteLLM inside @opik.track (common trap)
If code uses litellm and you add @opik.track , pass current span data
via metadata on every completion call — otherwise OpikLogger emits orphaned
top level traces instead of nesting under your span.
Threads (conversations)
Group turns with thread id — one turn = one trace, shared thread id = one
thread. Use for chat / multi turn; skip for single shot.
Prompt library
Version prompts with client.get prompt / create prompt (chat variants:
get chat prompt / create chat prompt ). Store model + temperature in the
prompt metadata so they version with the text. Call get prompt inside a
@opik.track function so the version links to the trace.
How a project is doing
With the MCP connected, start at the project, not at its traces:
One call returns the last 7 days against the 7 before — trace count, error
rate, average duration, total cost, SDK traffic only, which is what the Logs
page's four cards show — plus the score names and usage keys the project
actually records, and the freshest experiment, dataset, prompt version and
optimization run in it. since / until pick another window; since="30d" is
what the UI opens on. A rate or an average over a window with no traces comes
back null rather than 0 , because a rate over no samples is undefined and
"0% errors" is advice someone may act on.
Then attribute the change rather than restating it:
Rows are time buckets, not records — interval is hourly / daily / weekly /
total , and page / size / sort do not apply. schema("list.project metric")
is the metric list, what each is about, and which groupings each accepts; seven
of them accept none. The score names the overview returned are the ones worth
filtering on, and list("score name", project name=…) has the rest.
Searching traces
One filter grammar, OQL, serves both the hosted MCP's list tool and the
SDK's search traces / search spans / search threads :
Strings in double quotes, numbers bare, duration in milliseconds , dates as
ISO 8601 instants with a timezone ( "2026 09 08T10:00:00Z" ). Scores and
dictionaries take a key: feedback scores.accuracy < 0.5 ,
metadata.environment = "prod" . AND is the only connector.
With the MCP connected, prefer list — it also sorts ( sort="duration desc" ),
windows ( since="1h" , "7d" ), and searches free text ( search="order 42" ):
Trace, span and thread lists add source = "sdk" unless you name source , so
evaluator, playground and experiment traces stay out of the way. A rejected
filter comes back with what fixes it; schema("list.trace") (or list.span ,
list.thread , list.experiment ) is the full field and operator reference.
Without the MCP, the same string goes to the SDK:
Anti patterns
Anti pattern Fix
span type retrieval / custom use tool (or general )
get prompt outside @opik.track fetch inside — else no trace link
deprecated opik.Prompt / opik.Config use client.get prompt / config file
litellm without current span data pass it — else orphaned traces
no flush in scripts opik.flush tracker() / await client.flush()
References
Topic File
Python SDK (async, distributed, context) references/tracing python.md
TypeScript SDK references/tracing typescript.md
REST API references/tracing rest api.md
All integrations references/integrations.md
Core concepts (traces, spans, threads) references/observability.md
Best practices (lifecycle, monitoring, anti patterns) references/best practices.md
Agent architecture, reliability, security references/agent patterns.md
Production monitoring, alerts, guardrails references/production.md
Evaluation datasets & test suites (reference) references/evaluation datasets.md , references/evaluation test suites.md
To build and run an evaluation, use the opik evaluate skill. For repo instrumentation and config, use the opik instrument skill.