Skip to content
Back to skills

Opik Instrument

ASecurity

Add Opik tracing to an existing app and verify a real trace lands. Installs the Opik package, detects the language and LLM framework, adds the minimum tracing, runs a safe representative path, confirms a trace in Opik, and returns the trace link. Use for "instrument my code", "add opik tracing", "add observability", "trace my agent". Not for building a new app from scratch, or a review-only pass with no code changes.

  • 221 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 23, 2026
ai-agentstypescriptpythongobashapibackend

Works with

  • claude code
  • cursor
  • cli
  • api
  • mcp

Security analysis

A100/100

Pro scans all 13 files and shows the line behind each finding

Scanned September 29, 2026

npx -y skills add comet-ml/opik-mcp --skill opik-instrument --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Opik Instrument?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Opik Instrument
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/comet-ml-opik-instrument/badge)](https://www.skillsdirectory.com/skills/comet-ml-opik-instrument)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: opik-instrument
description: Add Opik tracing to an existing app and verify a real trace lands. Installs the Opik package, detects the language and LLM framework, adds the minimum tracing, runs a safe representative path, confirms a trace in Opik, and returns the trace link. Use for "instrument my code", "add opik tracing", "add observability", "trace my agent". Not for building a new app from scratch, or a review-only pass with no code changes.
compatibility: Tested with Claude Code; works with any Agent Skills-compatible host (Cursor, VS Code Copilot, Codex). Requires a Python or TypeScript project. Install the `opik` skill alongside this one — it holds the shared SDK and integration references; without it, this skill falls back to the public docs.
allowed-tools:
  - Read
  - Edit
  - Write
  - Grep
  - Glob
  - Bash
metadata:
  last_updated: "2026-09-10"
  source_commit: "2.0.0"
  argument-hint: "[optional: file or directory path]"
---

# Instrument — Add Opik Tracing and Verify a Real Trace

**Definition of done:** a representative, safely-executed path produces a trace that is confirmed in Opik and a direct trace link is returned. If verification can't be completed safely or autonomously, stop at the **first** genuine blocker and return **exactly one** concrete next step. Code edits alone are not success.

Operate: **opinionated in execution, conservative in code changes, automatic in routine decisions, uncompromising about verifying value — but never by running something unsafe.**

## Inputs

The entry point is just `/opik-instrument` (optionally `/opik-instrument <path>`). Infer everything else; treat these only as **optional overrides** the user may pass, never as required setup:

- target path (default: project root) · project name (default: inferred from the repo) · run command (default: an inferred safe path) · `migrate_prompts` (default: **false**).

Never turn inference into a questionnaire. Ask only when you hit a genuine, non-inferable blocker (see **Blockers**).

## Activation — the only in-scope work

### 1. Configure Opik (one source of truth)
- If `~/.opik.config` exists or `OPIK_API_KEY` is set, use it as-is.
- Otherwise run the official flow: `opik configure` (Python) / `npx opik-ts configure` (TypeScript).
- **Verify the config before instrumenting:** run `opik healthcheck` — it validates the config, the install, and backend/workspace reachability. If it fails, stop at that Blocker and fix config or connectivity before adding any tracing.
- Only add project-local `.env` vars if the project **already** uses that pattern. Never introduce a second config mechanism; never copy secret values between mechanisms.

### 2. Detect language & framework
Python (`*.py`, `pyproject.toml`) or TypeScript (`*.ts`, `package.json`). Identify the LLM framework from imports and pick its integration:

| Import | Integration |
|---|---|
| `openai` / `anthropic` | `track_openai` / `track_anthropic` |
| `langchain` / `langgraph` | `OpikTracer` callback |
| `crewai` / `dspy` / google-genai / bedrock / `llama_index` / `litellm` | `track_crewai` / `OpikCallback` / `track_genai` / `track_bedrock` / `LlamaIndexCallbackHandler` / `OpikLogger` |
| TS: `opik-openai` / `opik-vercel` / `opik-langchain` | `trackOpenAI` / `OpikExporter` / `OpikCallbackHandler` |

Full list: read `../opik/references/integrations.md` (the `opik` skill, installed beside this one). If that file isn't there, read <https://www.comet.com/docs/opik/integrations/overview> — never settle for manual spans on a framework that has a native integration just because the reference was unreachable. If the project is **already instrumented**, audit and add only what's missing — do not re-instrument.

### 3. Add the minimum tracing
Decision policy, in order:
1. Prefer the **framework-native integration** for provider LLM spans.
2. Add manual `@opik.track` spans only for orchestration/tools the integration doesn't cover (`type="tool"` / `"llm"` / `"guardrail"`). A bare `@opik.track` produces the default span type, **`general`** — the right choice for an entrypoint/orchestrator.
3. Never instrument the same operation twice (no `@opik.track(type="llm")` on top of `track_openai`).
4. Mark **one entrypoint per independently-runnable agent/service** — not necessarily one per repo.
5. Decorator order relative to framework decorators (e.g. `@app.route`) is **framework-dependent** — verify per framework; do not assume a universal order.
6. Scripts: flush at the end (`opik.flush_tracker()` / `await client.flush()`). LiteLLM inside `@opik.track`: pass `metadata={"opik": {"current_span_data": get_current_span_data()}}` or traces orphan.

Make the **smallest change** that lets one representative path emit a trace.

### 4. Install the Opik package (by default)
Add **only** the required Opik package(s) via the repo's detected package manager (pip / uv / poetry / npm / pnpm / yarn), through normal project conventions. **Preserve the lockfile**; do not run generic upgrades; do not install globally; treat unusual lifecycle scripts cautiously. Surface it as a change (e.g. "added `opik` to `pyproject.toml`"). If the environment blocks installation → **Blocker** with the one exact command.

### 5. Run a safe representative path
Infer a safe command — prefer an existing **test, example, or dev script**, then a bounded single-request entrypoint. **Never** run anything that looks like production or does irreversible/expensive work (writes, emails, purchases, mass API calls). If no safe path is inferable → **Blocker** ("which dev command safely exercises this agent?"). Print the command, then run it.

If the run needs an **LLM provider credential** (e.g. `OPENAI_API_KEY`) and it's absent, that's a Blocker — the app can't produce a trace. Note some SDK clients raise at **construction** (module load), before any span runs, so there is **no partial trace** to wait on: return blocked with the one next step, don't wait on a flush that never happened.

### 6. Verify ingestion
Confirm a trace actually arrived — don't assume. **Prefer the SDK for verification**: it's already installed as part of instrumenting (zero extra moving parts), whereas the Opik MCP is optional and may not be connected.

The SDK read of one trace and its spans: `references/verify-ingestion.md` (**SDK check**).

To find the newest trace instead of using a known id, use the client's trace search (e.g. `search_traces`) scoped to the project. Optionally, if the Opik MCP is connected, `list` recent traces then `read` the newest.

Traces are asynchronous — allow a few seconds after the run and make sure the flush ran.

**Verify coverage, not just arrival.** A trace arriving is necessary but not sufficient — batching can silently drop or truncate spans, so a trace can land *incomplete* and still look fine. Before reporting `verified`:
- **Count vs. expected.** Compare `len(spans)` (the `search_spans` call in `references/verify-ingestion.md`, `project_name` included) against the call sites you instrumented on the path you ran (entrypoint + each traced tool/LLM). Fewer spans than expected means spans were dropped — do not report `verified`.
- **Every span is well-formed.** Each span has a non-empty `name` and `type`; LLM spans carry input/output (and usage where the integration provides it). A span returned with an empty `name`/`type` is the batching-race symptom in `references/verify-ingestion.md`, not a real span.

**With the Opik MCP connected, verify there instead.** `read(entity_type="trace", id=tid)` returns `{trace, spans, spansTruncated}` with the span tree inlined (up to 200 spans), so both checks above run over that one call, no script needed: count the spans against the instrumented call sites, and confirm each has a `name`/`type` and the LLM spans carry input/output. If `spansTruncated` is true, count with the SDK instead. The SDK stays the default because it is already installed; the MCP is the shortcut when it is there.

If the trace is empty, partial, or has unnamed spans, check `references/verify-ingestion.md` (**Common ingestion traps**) before changing the instrumentation.

### 7. Report
Return a short human result + the trace link (see **Output**), then make the single expansion offer.

## Blockers

When you genuinely can't proceed, stop at the **earliest** blocker and return **exactly one** next step — never a checklist — and still report the changes already made (`blocked` carries `changes`). An unsupported language or shape is `unsupported` and modifies nothing. Examples:
- "Run `opik configure`, then rerun `/opik-instrument`."
- "Install dependencies with `uv sync`, then rerun `/opik-instrument`."
- "Which dev command safely exercises this agent?"
- "Instrumented and installed, but the run needs a provider credential — set `OPENAI_API_KEY` (or the relevant provider key) and rerun."
- "Instrumented and ran, but this environment can't query Opik — open the project and confirm trace `<id>` arrived."

## Expansion — after the trace lands (one offer, not a funnel)

Do **not** migrate prompts, add threading, or broaden spans during activation. After verification, make a **single consolidated offer** of what you found, e.g.:

> Tracing is verified. I also found ways to deepen it: 3 Prompt Library candidates, missing conversation threading, and 2 untraced tools. Expand?

## Output

**User-facing:** a short human message — what was instrumented, the trace link, and the one expansion offer (or, if blocked, the single next step plus what changed). Not raw JSON.

**Underneath** (for composition / evals), a small state model, with its invariants: `references/output-shape.md`.

## Examples

Worked runs (no LLM framework, OpenAI, already instrumented): `references/examples.md`.

## Anti-patterns
Double-wrapping (integration + manual span on the same call); orphaned LiteLLM traces (missing `current_span_data`); missing flush in scripts; overwriting or duplicating config; **running an unsafe/production path just to force a trace**; broad dependency upgrades when only `opik` is needed; migrating prompts during activation.

## References

SDK detail lives in the `opik` skill, installed beside this one. Read the files directly — paths are relative to this file: `../opik/references/tracing-python.md`, `../opik/references/tracing-typescript.md`, `../opik/references/integrations.md`, `../opik/references/observability.md`. If your host lays skills out differently, locate the `opik` skill's `references/` directory.

If the `opik` skill isn't installed, say so in the report and use <https://www.comet.com/docs/opik/> rather than working from memory.

Files in this skill

  • SKILL.md10.8 KB
  • evals/.gitignore26 B
  • evals/HARNESS.md4.2 KB
  • evals/cases.yaml2.2 KB
  • evals/fixtures/clean/app.py1.5 KB
  • evals/fixtures/clean/expected.json274 B
  • evals/fixtures/clean/pyproject.toml203 B
  • evals/fixtures/missing_flush/app.py2 KB
  • evals/fixtures/missing_flush/expected.json374 B
  • evals/fixtures/missing_flush/pyproject.toml249 B
  • evals/grader.py5.9 KB
  • evals/metrics.py2.6 KB
  • evals/run_evals.py7 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.