Adds Arize AX tracing to an LLM application for the first time. Use when the user wants to instrument their app, add tracing from scratch, set up LLM observability, integrate OpenTelemetry or OpenInference, or get started with Arize tracing.
Add Arize AX tracing to an LLM application by first analyzing the repository, then implementing additive OpenTelemetry/OpenInference instrumentation after scope is clear, preserving business logic and verifying real spans.
When to invoke
"Instrument this app with Arize AX."
"Set up LLM observability from scratch."
"Add OpenTelemetry or OpenInference tracing to this agent."
"Get started with Arize tracing for Python, TypeScript, Java, or Go."
"Why are my Arize traces sparse or missing tool spans?"
Prefer inspection over mutation — understand the codebase before changing it.
Do not change business logic — tracing is purely additive.
Use auto-instrumentation where available — add manual spans only for custom logic not covered by integrations.
Follow existing code style and project conventions.
Keep output concise and production-focused — do not generate extra documentation or summary files.
NEVER embed literal credential values in generated code — always reference environment variables (e.g., os.environ["ARIZE_API_KEY"], process.env.ARIZE_API_KEY). This includes API keys, space IDs, and any other secrets. The user sets these in their own environment; the agent must never output raw secret values.
Procedure
Run Phase 0 environment preflight before changing code.
Run Phase 1 analysis as read-only inspection.
Continue to Phase 2 implementation only when the user already requested direct instrumentation and scope is clear, or after user confirmation.
Verify build/typecheck, startup, at least one real LLM call, and Arize-side trace arrival or a precise blocker.
Phase 0: Environment preflight
Before changing code:
Confirm the repo/service scope is clear. For monorepos, do not assume the whole repo should be instrumented.
Identify the local runtime surface you will need for verification:
package manager and app start command
whether the app is long-running, server-based, or a short-lived CLI/script
whether ax will be needed for post-change verification
Do NOT proactively check ax installation or version. If ax is needed for verification later, just run it when the time comes. If it fails, see references/ax-profiles.md.
Never silently replace a user-provided space ID, project name, or project ID. If the CLI, collector, and user input disagree, surface that mismatch as a concrete blocker.
Phase 1: Analysis (read-only)
Do not write any code or create any files during this phase.
Scan import statements in source files to confirm what is actually used.
Check for existing tracing/OTel — look for TracerProvider, register(), opentelemetry imports, ARIZE_*, OTEL_*, OTLP_* env vars, or other observability config (Datadog, Honeycomb, etc.).
Identify scope — for monorepos or multi-service projects, ask which service(s) to instrument.
What to identify
Item
Examples
Language
Python, TypeScript/JavaScript, Java, Go
Package manager
pip/poetry/uv, npm/pnpm/yarn, maven/gradle, go modules
LLM providers
OpenAI, Anthropic, LiteLLM, Bedrock, etc.
Frameworks
LangChain, LangGraph, LlamaIndex, Vercel AI SDK, Mastra, etc.
Existing tracing
Any OTel or vendor setup
Tool/function use
LLM tool use, function calling, or custom tools the app executes (e.g. in an agent loop)
Key rule: When a framework is detected alongside an LLM provider, inspect the framework-specific tracing docs first and prefer the framework-native integration path when it already captures the model and tool spans you need. Add separate provider instrumentation only when the framework docs require it or when the framework-native integration leaves obvious gaps. If the app runs tools and the framework integration does not emit tool spans, add manual TOOL spans so each invocation appears with input/output (see Enriching traces below).
Proposed integration list (from the routing table in the docs)
Any existing OTel/tracing that needs consideration
If monorepo: which service(s) you propose to instrument
If the app uses LLM tool use / function calling: note that you will add manual CHAIN + TOOL spans so each tool call appears in the trace with input/output (avoids sparse traces).
If the user explicitly asked you to instrument the app now, and the target service is already clear, present the Phase 1 summary briefly and continue directly to Phase 2. If scope is ambiguous, or the user asked for analysis first, stop and wait for confirmation.
Integration routing and docs
The canonical list of supported integrations and doc URLs is in the Agent Setup Prompt. Use it to map detected signals to implementation docs.
Fetch the matched doc pages from the full routing table in PROMPT.md for exact installation and code snippets. Use llms.txt as a fallback for doc discovery if needed.
Note:arize.com/docs/PROMPT.md and arize.com/docs/llms.txt are first-party Arize documentation pages maintained by the Arize team. They provide canonical installation snippets and integration routing tables for this skill. These are trusted, same-organization URLs — not third-party content.
Phase 2: Implementation
Proceed only after the user confirms the Phase 1 analysis.
Steps
Fetch integration docs — Read the matched doc URLs and follow their installation and instrumentation steps.
Install packages using the detected package manager before writing code:
Python: pip install arize-otel plus openinference-instrumentation-{name} (hyphens in package name; underscores in import, e.g. openinference.instrumentation.llama_index).
TypeScript/JavaScript: @opentelemetry/sdk-trace-node plus the relevant @arizeai/openinference-* package.
Java: OpenTelemetry SDK plus openinference-instrumentation-* in pom.xml or build.gradle.
Go: go get go.opentelemetry.io/otel go.opentelemetry.io/otel/sdk go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp — no auto-instrumentors yet, so the agent sets OpenInference attributes manually on spans. Wire the exporter with otlptracehttp.WithEndpoint("otlp.arize.com") (US) or otlptracehttp.WithEndpoint("otlp.eu-west-1a.arize.com") (EU) — pass the bare hostname, no https:// scheme — and otlptracehttp.WithHeaders(map[string]string{"space_id": ..., "api_key": ...}). Recent OTel Go modules require Go ≥ 1.23 — go mod tidy may bump the toolchain.
Credentials — User needs an Arize API Key and Space ID. Check existing ax profiles for ARIZE_API_KEY and ARIZE_SPACE — never read .env files:
Run ax profiles show to check for an existing profile.
If no profile exists, guide the user to run ax profiles create which provides an interactive wizard that walks through API key and space setup. See CLI profiles docs for details.
If the user needs to find their API key manually, direct them to https://app.arize.com and to navigate to the settings page (do not use organization-specific URLs with placeholder IDs — they won't resolve for new users).
If credentials are not set, instruct the user to set them as environment variables — never embed raw values in generated code. All generated instrumentation code must reference os.environ["ARIZE_API_KEY"] (Python), process.env.ARIZE_API_KEY (TypeScript/JavaScript), or os.Getenv("ARIZE_API_KEY") (Go).
See references/ax-profiles.md for full profile setup and troubleshooting.
Centralized instrumentation — Create a single module (e.g. instrumentation.py, instrumentation.ts, instrumentation.go) and initialize tracing before any LLM client is created.
Existing OTel — If there is already a TracerProvider, add Arize as an additional exporter (e.g. BatchSpanProcessor with Arize OTLP). Do not replace existing setup unless the user asks.
Implementation rules
Use auto-instrumentation first; manual spans only when needed.
Prefer the repo's native integration surface before adding generic OpenTelemetry plumbing. If the framework ships an exporter or observability package, use that first unless there is a documented gap.
Fail gracefully if env vars are missing (warn, do not crash).
Project name attribute (required): Arize rejects spans with HTTP 500 if the project name is missing — service.name alone is not accepted. Set it as a resource attribute on the TracerProvider (recommended — one place, applies to all spans):
Python:register(project_name="my-app") handles it automatically (sets "openinference.project.name" on the resource). For routing spans to different projects, use set_routing_context(space_id=..., project_name=...) from arize.otel.
TypeScript: Arize accepts both "model_id" (shown in the official TS quickstart) and "openinference.project.name" via SEMRESATTRS_PROJECT_NAME from @arizeai/openinference-semantic-conventions (shown in the manual instrumentation docs) — both work.
Go: Pass attribute.String("openinference.project.name", "my-app") to resource.New(...) and apply via sdktrace.WithResource(res). The Go SDK has no helper for this, so it must be set manually on every TracerProvider.
CLI/script apps — flush before exit:provider.shutdown() (TS) / provider.force_flush() then provider.shutdown() (Python) / tp.Shutdown(ctx) (Go) must be called before the process exits, otherwise async OTLP exports are dropped and no traces appear.
When the app has tool/function execution: add manual CHAIN + TOOL spans (see Enriching traces below) so the trace tree shows each tool call and its result — otherwise traces will look sparse (only LLM API spans, no tool input/output).
Enriching traces: manual spans for tool use and agent loops
Why doesn't the auto-instrumentor do this?
Provider instrumentors (Anthropic, OpenAI, etc.) only wrap the LLM client — the code that sends HTTP requests and receives responses. They see:
One span per API call: request (messages, system prompt, tools) and response (text, tool_use blocks, etc.).
They cannot see what happens inside your application after the response:
Tool execution — Your code parses the response, calls run_tool("check_loan_eligibility", {...}), and gets a result. That runs in your process; the instrumentor has no hook into your run_tool() or the actual tool output. The next API call (sending the tool result back) is just another messages.create span — the instrumentor doesn't know that the message content is a tool result or what the tool returned.
Agent/chain boundary — The idea of "one user turn → multiple LLM calls + tool calls" is an application-level concept. The instrumentor only sees separate API calls; it doesn't know they belong to the same logical "run_agent" run.
So TOOL and CHAIN spans have to be added manually (or by a framework instrumentor like LangChain/LangGraph that knows about tools and chains). Once you add them, they appear in the same trace as the LLM spans because they use the same TracerProvider.
To avoid sparse traces where tool inputs/outputs are missing:
Detect agent/tool patterns: a loop that calls the LLM, then runs one or more tools (by name + arguments), then calls the LLM again with tool results.
Add manual spans using the same TracerProvider (e.g. opentelemetry.trace.get_tracer(...) after register()):
CHAIN span — Wrap the full agent run (e.g. run_agent): set openinference.span.kind = "CHAIN", input.value = user message, output.value = final reply.
TOOL span — Wrap each tool invocation: set openinference.span.kind = "TOOL", input.value = JSON of arguments, output.value = JSON of result. Use the tool name as the span name (e.g. check_loan_eligibility).
OpenInference attributes (use these so Arize shows spans correctly):
Attribute
Use
openinference.span.kind
Pick the right value: "LLM" for raw provider API calls (OpenAI, Anthropic, etc.); "CHAIN" for orchestration / agent-loop boundaries; "TOOL" for tool/function execution; "RETRIEVER" for vector-store / search lookups; "EMBEDDING" for embedding API calls; "AGENT" for an autonomous sub-agent run nested inside a larger chain; "RERANKER" for rerank API calls; "GUARDRAIL" for guardrail/policy checks; "EVALUATOR" for online eval calls.
input.value
string (e.g. user message or JSON of tool args)
output.value
string (e.g. final reply or JSON of tool result)
LLM-span attributes (set these in addition to the three above when the span is an actual LLM call):
Attribute
Use
llm.model_name
model identifier (e.g. "gpt-4o-mini")
llm.provider / llm.system
provider name (e.g. "openai", "anthropic")
llm.input_messages.{i}.message.role
"system" / "user" / "assistant" / "tool" for the i-th input message
llm.input_messages.{i}.message.content
text content of the i-th input message
llm.output_messages.{i}.message.role
role of the i-th output message
llm.output_messages.{i}.message.content
text content of the i-th output message
llm.token_count.prompt
int — prompt/input tokens
llm.token_count.completion
int — completion/output tokens
llm.token_count.total
int — total tokens
In Python and TypeScript these names are exposed via openinference-semantic-conventions packages; in Go they must be hand-typed as the strings above.
Python pattern: Get the global tracer (same provider as Arize), then use context managers so tool spans are children of the CHAIN span and appear in the same trace as the LLM spans:
from opentelemetry.trace import get_tracer
tracer = get_tracer("my-app", "1.0.0")
# In your agent entrypoint:
with tracer.start_as_current_span("run_agent") as chain_span:
chain_span.set_attribute("openinference.span.kind", "CHAIN")
chain_span.set_attribute("input.value", user_message)
# ... LLM call ...
for tool_use in tool_uses:
with tracer.start_as_current_span(tool_use["name"]) as tool_span:
tool_span.set_attribute("openinference.span.kind", "TOOL")
tool_span.set_attribute("input.value", json.dumps(tool_use["input"]))
result = run_tool(tool_use["name"], tool_use["input"])
tool_span.set_attribute("output.value", result)
# ... append tool result to messages, call LLM again ...
chain_span.set_attribute("output.value", final_reply)
Go pattern: Get a tracer from the global TracerProvider (registered via otel.SetTracerProvider), then nest spans with tracer.Start so tool spans become children of the CHAIN span.
Critical for short-lived processes: never call log.Fatalf / os.Exit after a span has started — they skip the deferred tp.Shutdown(ctx) and the in-flight CHAIN/LLM spans never flush. Use log.Printf + return from main instead, and keep tp.Shutdown(ctx) deferred at the top of main.
Treat instrumentation as complete only when all of the following are true:
The app still builds or typechecks after the tracing change.
The app starts successfully with the new tracing configuration.
You trigger at least one real request or run that should produce spans.
You either verify the resulting trace in Arize, or you provide a precise blocker that distinguishes app-side success from Arize-side failure.
After implementation:
Run the application and trigger at least one LLM call.
Use the arize-trace skill to confirm traces arrived. If empty, retry shortly. Verify spans have expected openinference.span.kind, input.value/output.value, and parent-child relationships.
If no traces: verify ARIZE_SPACE and ARIZE_API_KEY, ensure tracer is initialized before instrumentors and clients, check connectivity to otlp.arize.com:443, and inspect app/runtime exporter logs so you can tell whether spans are being emitted locally but rejected remotely. For debug set GRPC_VERBOSITY=debug or pass log_to_console=True to register(). Common gotchas: (a) missing project name resource attribute causes HTTP 500 rejections — service.name alone is not enough; Python: pass project_name to register(); TypeScript: set "model_id" or SEMRESATTRS_PROJECT_NAME on the resource; Go: add attribute.String("openinference.project.name", "my-app") to resource.New(...); (b) CLI/script processes exit before OTLP exports flush — call provider.force_flush() then provider.shutdown() (Python/TS) or tp.Shutdown(ctx) (Go) before exit; (c) CLI-visible spaces/projects can disagree with a collector-targeted space ID — report the mismatch instead of silently rewriting credentials.
If the app uses tools: confirm CHAIN and TOOL spans appear with input.value / output.value so tool calls and results are visible.
When verification is blocked by CLI or account issues, end with a concrete status:
app instrumentation status
latest local trace ID or run ID
whether exporter logs show local span emission
whether the failure is credential, space/project resolution, network, or collector rejection
Leveraging the Tracing Assistant (MCP)
For deeper instrumentation guidance inside the IDE, the user can enable:
Arize AX Tracing Assistant MCP — instrumentation guides, framework examples, and support. In Cursor: Settings → MCP → Add and use:
Then the user can ask things like: "Instrument this app using Arize AX", "Can you use manual instrumentation so I have more control over my traces?", "How can I redact sensitive information from my spans?"
See references/ax-profiles.md § Save Credentials for Future Use.
Progressive disclosure and bundled resources
Read bundled references only when the corresponding issue appears.
references/ax-profiles.md: ax profiles show, ax profiles create, credential storage, profile mismatch, and CLI troubleshooting for ARIZE_API_KEY and ARIZE_SPACE.
Output template
## Arize instrumentation result
**Status:** analyzed | instrumented | blocked
**Scope:** `<service/package/path>`
**Language/runtime:** `<Python | TypeScript/JavaScript | Java | Go>`
**Package manager:** `<pip | poetry | uv | npm | pnpm | yarn | maven | gradle | go modules>`
### Detected signals
| Area | Evidence | Decision |
| --- | --- | --- |
| LLM providers | `<imports/files>` | `<OpenAI/Anthropic/etc.>` |
| Frameworks | `<imports/files>` | `<LangChain/LangGraph/etc.>` |
| Existing tracing | `<TracerProvider/register/opentelemetry/ARIZE_/OTEL_/OTLP_>` | `<reuse/add exporter>` |
| Tools/function calling | `<agent loop evidence>` | `<manual CHAIN + TOOL spans>` |
### Changes
- `<dependency or file changed>`: <why>
### Verification
- Build/typecheck: pass | fail | not run because <reason>
- App start: pass | fail | not run because <reason>
- LLM request triggered: pass | fail | not run because <reason>
- Arize trace check: pass | blocked by credential | blocked by project/space mismatch | blocked by network | blocked by collector rejection
- Latest local trace/run ID: `<id or none>`
Quality gate
Phase 1 inspected manifests, imports, existing tracing, environment variable names, and monorepo scope before code changes.
Instrumentation is additive and does not alter business logic.
Integration docs were fetched for the detected provider/framework path before implementation.
Dependencies were installed with the detected package manager before code was written.
Generated code references environment variables such as ARIZE_API_KEY, ARIZE_SPACE, os.environ["ARIZE_API_KEY"], process.env.ARIZE_API_KEY, or os.Getenv("ARIZE_API_KEY"); it never embeds raw secret values.
TracerProvider setup includes project routing through project_name, openinference.project.name, model_id, SEMRESATTRS_PROJECT_NAME, or set_routing_context(...) as appropriate.
Short-lived CLI/script apps flush and shut down providers before exit.
Tool/function execution emits manual CHAIN and TOOL spans with input.value and output.value when framework instrumentation does not cover them.
Verification distinguishes app-side success from credential, ARIZE_SPACE/project mismatch, network, or collector rejection failures.
1---2name: arize-instrumentation3description: Adds Arize AX tracing to an LLM application for the first time. Use when the user wants to instrument their app, add tracing from scratch, set up LLM observability, integrate OpenTelemetry or OpenInference, or get started with Arize tracing.4---56<!-- Generated from harness/github-copilot/skills/arize-instrumentation/SKILL.md by harness/claude-code/scripts/convert_from_copilot.py. Edit the source, not this file. -->78# Arize instrumentation910Add Arize AX tracing to an LLM application by first analyzing the repository, then implementing additive OpenTelemetry/OpenInference instrumentation after scope is clear, preserving business logic and verifying real spans.1112## When to invoke1314- "Instrument this app with Arize AX."15- "Set up LLM observability from scratch."16- "Add OpenTelemetry or OpenInference tracing to this agent."17- "Get started with Arize tracing for Python, TypeScript, Java, or Go."18- "Why are my Arize traces sparse or missing tool spans?"1920## Invocation context2122Use this skill when the user wants to **add Arize AX tracing** to their application. Follow the **two-phase, agent-assisted flow** from the [Agent-Assisted Tracing Setup](https://arize.com/docs/ax/alyx/tracing-assistant) and the [Arize AX Tracing — Agent Setup Prompt](https://arize.com/docs/PROMPT.md).2324## Quick start2526If the user asks you to "set up tracing" or "instrument my app with Arize", you can start with:2728> Follow the instructions from https://arize.com/docs/PROMPT.md and ask me questions as needed.2930Then execute the two phases below.3132## Criteria3334- **Prefer inspection over mutation** — understand the codebase before changing it.35- **Do not change business logic** — tracing is purely additive.36- **Use auto-instrumentation where available** — add manual spans only for custom logic not covered by integrations.37- **Follow existing code style** and project conventions.38- **Keep output concise and production-focused** — do not generate extra documentation or summary files.39- **NEVER embed literal credential values in generated code** — always reference environment variables (e.g., `os.environ["ARIZE_API_KEY"]`, `process.env.ARIZE_API_KEY`). This includes API keys, space IDs, and any other secrets. The user sets these in their own environment; the agent must never output raw secret values.4041## Procedure42431. Run Phase 0 environment preflight before changing code.442. Run Phase 1 analysis as read-only inspection.453. Continue to Phase 2 implementation only when the user already requested direct instrumentation and scope is clear, or after user confirmation.464. Verify build/typecheck, startup, at least one real LLM call, and Arize-side trace arrival or a precise blocker.4748## Phase 0: Environment preflight4950Before changing code:51521. Confirm the repo/service scope is clear. For monorepos, do not assume the whole repo should be instrumented.532. Identify the local runtime surface you will need for verification:54 - package manager and app start command55 - whether the app is long-running, server-based, or a short-lived CLI/script56 - whether `ax` will be needed for post-change verification573. Do NOT proactively check `ax` installation or version. If `ax` is needed for verification later, just run it when the time comes. If it fails, see references/ax-profiles.md.584. Never silently replace a user-provided space ID, project name, or project ID. If the CLI, collector, and user input disagree, surface that mismatch as a concrete blocker.5960## Phase 1: Analysis (read-only)6162**Do not write any code or create any files during this phase.**6364### Steps65661. **Check dependency manifests** to detect stack:67 - Python: `pyproject.toml`, `requirements.txt`, `setup.py`, `Pipfile`68 - TypeScript/JavaScript: `package.json`69 - Java: `pom.xml`, `build.gradle`, `build.gradle.kts`70 - Go: `go.mod`71722. **Scan import statements** in source files to confirm what is actually used.73743. **Check for existing tracing/OTel** — look for `TracerProvider`, `register()`, `opentelemetry` imports, `ARIZE_*`, `OTEL_*`, `OTLP_*` env vars, or other observability config (Datadog, Honeycomb, etc.).75764. **Identify scope** — for monorepos or multi-service projects, ask which service(s) to instrument.7778### What to identify7980| Item | Examples |81|------|----------|82| Language | Python, TypeScript/JavaScript, Java, Go |83| Package manager | pip/poetry/uv, npm/pnpm/yarn, maven/gradle, go modules |84| LLM providers | OpenAI, Anthropic, LiteLLM, Bedrock, etc. |85| Frameworks | LangChain, LangGraph, LlamaIndex, Vercel AI SDK, Mastra, etc. |86| Existing tracing | Any OTel or vendor setup |87| Tool/function use | LLM tool use, function calling, or custom tools the app executes (e.g. in an agent loop) |8889**Key rule:** When a framework is detected alongside an LLM provider, inspect the framework-specific tracing docs first and prefer the framework-native integration path when it already captures the model and tool spans you need. Add separate provider instrumentation only when the framework docs require it or when the framework-native integration leaves obvious gaps. If the app runs tools and the framework integration does not emit tool spans, add manual TOOL spans so each invocation appears with input/output (see **Enriching traces** below).9091### Phase 1 output9293Return a concise summary:9495- Detected language, package manager, providers, frameworks96- Proposed integration list (from the routing table in the docs)97- Any existing OTel/tracing that needs consideration98- If monorepo: which service(s) you propose to instrument99- **If the app uses LLM tool use / function calling:** note that you will add manual CHAIN + TOOL spans so each tool call appears in the trace with input/output (avoids sparse traces).100101If the user explicitly asked you to instrument the app now, and the target service is already clear, present the Phase 1 summary briefly and continue directly to Phase 2. If scope is ambiguous, or the user asked for analysis first, stop and wait for confirmation.102103## Integration routing and docs104105The **canonical list** of supported integrations and doc URLs is in the [Agent Setup Prompt](https://arize.com/docs/PROMPT.md). Use it to map detected signals to implementation docs.106107- **LLM providers:** [OpenAI](https://arize.com/docs/ax/integrations/llm-providers/openai), [Anthropic](https://arize.com/docs/ax/integrations/llm-providers/anthropic), [LiteLLM](https://arize.com/docs/ax/integrations/llm-providers/litellm), [Google Gen AI](https://arize.com/docs/ax/integrations/llm-providers/google-gen-ai), [Bedrock](https://arize.com/docs/ax/integrations/llm-providers/amazon-bedrock), [Ollama](https://arize.com/docs/ax/integrations/llm-providers/llama), [Groq](https://arize.com/docs/ax/integrations/llm-providers/groq), [MistralAI](https://arize.com/docs/ax/integrations/llm-providers/mistralai), [OpenRouter](https://arize.com/docs/ax/integrations/llm-providers/openrouter), [VertexAI](https://arize.com/docs/ax/integrations/llm-providers/vertexai).108- **Python frameworks:** [LangChain](https://arize.com/docs/ax/integrations/python-agent-frameworks/langchain), [LangGraph](https://arize.com/docs/ax/integrations/python-agent-frameworks/langgraph), [LlamaIndex](https://arize.com/docs/ax/integrations/python-agent-frameworks/llamaindex), [CrewAI](https://arize.com/docs/ax/integrations/python-agent-frameworks/crewai), [DSPy](https://arize.com/docs/ax/integrations/python-agent-frameworks/dspy), [AutoGen](https://arize.com/docs/ax/integrations/python-agent-frameworks/autogen), [Semantic Kernel](https://arize.com/docs/ax/integrations/python-agent-frameworks/semantic-kernel), [Pydantic AI](https://arize.com/docs/ax/integrations/python-agent-frameworks/pydantic), [Haystack](https://arize.com/docs/ax/integrations/python-agent-frameworks/haystack), [Guardrails AI](https://arize.com/docs/ax/integrations/python-agent-frameworks/guardrails-ai), [Hugging Face Smolagents](https://arize.com/docs/ax/integrations/python-agent-frameworks/hugging-face-smolagents), [Instructor](https://arize.com/docs/ax/integrations/python-agent-frameworks/instructor), [Agno](https://arize.com/docs/ax/integrations/python-agent-frameworks/agno), [Google ADK](https://arize.com/docs/ax/integrations/python-agent-frameworks/google-adk), [MCP](https://arize.com/docs/ax/integrations/python-agent-frameworks/model-context-protocol), [Portkey](https://arize.com/docs/ax/integrations/python-agent-frameworks/portkey), [Together AI](https://arize.com/docs/ax/integrations/python-agent-frameworks/together-ai), [BeeAI](https://arize.com/docs/ax/integrations/python-agent-frameworks/beeai), [AWS Bedrock Agents](https://arize.com/docs/ax/integrations/python-agent-frameworks/aws).109- **TypeScript/JavaScript:** [LangChain JS](https://arize.com/docs/ax/integrations/ts-js-agent-frameworks/langchain), [Mastra](https://arize.com/docs/ax/integrations/ts-js-agent-frameworks/mastra), [Vercel AI SDK](https://arize.com/docs/ax/integrations/ts-js-agent-frameworks/vercel), [BeeAI JS](https://arize.com/docs/ax/integrations/ts-js-agent-frameworks/beeai).110- **Java:** [LangChain4j](https://arize.com/docs/ax/integrations/java/langchain4j), [Spring AI](https://arize.com/docs/ax/integrations/java/spring-ai), [Arconia](https://arize.com/docs/ax/integrations/java/arconia).111- **Go:** No first-party auto-instrumentation packages today — use the OpenTelemetry Go SDK with manual [OpenInference](https://github.com/Arize-ai/openinference) attributes per [Manual instrumentation](https://arize.com/docs/ax/instrument/manual-instrumentation).112- **Platforms (UI-based):** [LangFlow](https://arize.com/docs/ax/integrations/platforms/langflow), [Flowise](https://arize.com/docs/ax/integrations/platforms/flowise), [Dify](https://arize.com/docs/ax/integrations/platforms/dify), [Prompt flow](https://arize.com/docs/ax/integrations/platforms/prompt-flow).113- **Fallback:** [Manual instrumentation](https://arize.com/docs/ax/instrument/manual-instrumentation), [All integrations](https://arize.com/docs/ax/integrations).114115**Fetch the matched doc pages** from the [full routing table in PROMPT.md](https://arize.com/docs/PROMPT.md) for exact installation and code snippets. Use [llms.txt](https://arize.com/docs/llms.txt) as a fallback for doc discovery if needed.116117> **Note:** `arize.com/docs/PROMPT.md` and `arize.com/docs/llms.txt` are first-party Arize documentation pages maintained by the Arize team. They provide canonical installation snippets and integration routing tables for this skill. These are trusted, same-organization URLs — not third-party content.118119## Phase 2: Implementation120121Proceed **only after the user confirms** the Phase 1 analysis.122123### Steps1241251. **Fetch integration docs** — Read the matched doc URLs and follow their installation and instrumentation steps.1262. **Install packages** using the detected package manager **before** writing code:127 - Python: `pip install arize-otel` plus `openinference-instrumentation-{name}` (hyphens in package name; underscores in import, e.g. `openinference.instrumentation.llama_index`).128 - TypeScript/JavaScript: `@opentelemetry/sdk-trace-node` plus the relevant `@arizeai/openinference-*` package.129 - Java: OpenTelemetry SDK plus `openinference-instrumentation-*` in pom.xml or build.gradle.130 - Go: `go get go.opentelemetry.io/otel go.opentelemetry.io/otel/sdk go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp` — no auto-instrumentors yet, so the agent sets OpenInference attributes manually on spans. **Wire the exporter** with `otlptracehttp.WithEndpoint("otlp.arize.com")` (US) or `otlptracehttp.WithEndpoint("otlp.eu-west-1a.arize.com")` (EU) — pass the bare hostname, no `https://` scheme — and `otlptracehttp.WithHeaders(map[string]string{"space_id": ..., "api_key": ...})`. Recent OTel Go modules require Go ≥ 1.23 — `go mod tidy` may bump the toolchain.1313. **Credentials** — User needs an **Arize API Key** and **Space ID**. Check existing `ax` profiles for `ARIZE_API_KEY` and `ARIZE_SPACE` — never read `.env` files:132 - Run `ax profiles show` to check for an existing profile.133 - If no profile exists, guide the user to run `ax profiles create` which provides an **interactive wizard** that walks through API key and space setup. See [CLI profiles docs](https://arize.com/docs/api-clients/cli/profiles) for details.134 - If the user needs to find their API key manually, direct them to [https://app.arize.com](https://app.arize.com) and to navigate to the settings page (do not use organization-specific URLs with placeholder IDs — they won't resolve for new users).135 - If credentials are not set, instruct the user to set them as environment variables — never embed raw values in generated code. All generated instrumentation code must reference `os.environ["ARIZE_API_KEY"]` (Python), `process.env.ARIZE_API_KEY` (TypeScript/JavaScript), or `os.Getenv("ARIZE_API_KEY")` (Go).136 - See references/ax-profiles.md for full profile setup and troubleshooting.1374. **Centralized instrumentation** — Create a single module (e.g. `instrumentation.py`, `instrumentation.ts`, `instrumentation.go`) and initialize tracing **before** any LLM client is created.1385. **Existing OTel** — If there is already a TracerProvider, add Arize as an **additional** exporter (e.g. BatchSpanProcessor with Arize OTLP). Do not replace existing setup unless the user asks.139140### Implementation rules141142- Use **auto-instrumentation first**; manual spans only when needed.143- Prefer the repo's native integration surface before adding generic OpenTelemetry plumbing. If the framework ships an exporter or observability package, use that first unless there is a documented gap.144- **Fail gracefully** if env vars are missing (warn, do not crash).145- **Import order:** register tracer → attach instrumentors → then create LLM clients.146- **Project name attribute (required):** Arize rejects spans with HTTP 500 if the project name is missing — `service.name` alone is not accepted. Set it as a **resource attribute** on the TracerProvider (recommended — one place, applies to all spans):147 - **Python:** `register(project_name="my-app")` handles it automatically (sets `"openinference.project.name"` on the resource). For routing spans to different projects, use `set_routing_context(space_id=..., project_name=...)` from `arize.otel`.148 - **TypeScript:** Arize accepts both `"model_id"` (shown in the official TS quickstart) and `"openinference.project.name"` via `SEMRESATTRS_PROJECT_NAME` from `@arizeai/openinference-semantic-conventions` (shown in the manual instrumentation docs) — both work.149 - **Go:** Pass `attribute.String("openinference.project.name", "my-app")` to `resource.New(...)` and apply via `sdktrace.WithResource(res)`. The Go SDK has no helper for this, so it must be set manually on every TracerProvider.150- **CLI/script apps — flush before exit:** `provider.shutdown()` (TS) / `provider.force_flush()` then `provider.shutdown()` (Python) / `tp.Shutdown(ctx)` (Go) must be called before the process exits, otherwise async OTLP exports are dropped and no traces appear.151- **When the app has tool/function execution:** add manual CHAIN + TOOL spans (see **Enriching traces** below) so the trace tree shows each tool call and its result — otherwise traces will look sparse (only LLM API spans, no tool input/output).152153## Enriching traces: manual spans for tool use and agent loops154155### Why doesn't the auto-instrumentor do this?156157**Provider instrumentors (Anthropic, OpenAI, etc.) only wrap the LLM *client* — the code that sends HTTP requests and receives responses.** They see:158159- One span per API call: request (messages, system prompt, tools) and response (text, tool_use blocks, etc.).160161They **cannot** see what happens *inside your application* after the response:162163- **Tool execution** — Your code parses the response, calls `run_tool("check_loan_eligibility", {...})`, and gets a result. That runs in your process; the instrumentor has no hook into your `run_tool()` or the actual tool output. The *next* API call (sending the tool result back) is just another `messages.create` span — the instrumentor doesn't know that the message content is a tool result or what the tool returned.164- **Agent/chain boundary** — The idea of "one user turn → multiple LLM calls + tool calls" is an *application-level* concept. The instrumentor only sees separate API calls; it doesn't know they belong to the same logical "run_agent" run.165166So TOOL and CHAIN spans have to be added **manually** (or by a *framework* instrumentor like LangChain/LangGraph that knows about tools and chains). Once you add them, they appear in the same trace as the LLM spans because they use the same TracerProvider.167168---169170To avoid sparse traces where tool inputs/outputs are missing:1711721. **Detect** agent/tool patterns: a loop that calls the LLM, then runs one or more tools (by name + arguments), then calls the LLM again with tool results.1732. **Add manual spans** using the same TracerProvider (e.g. `opentelemetry.trace.get_tracer(...)` after `register()`):174 - **CHAIN span** — Wrap the full agent run (e.g. `run_agent`): set `openinference.span.kind` = `"CHAIN"`, `input.value` = user message, `output.value` = final reply.175 - **TOOL span** — Wrap each tool invocation: set `openinference.span.kind` = `"TOOL"`, `input.value` = JSON of arguments, `output.value` = JSON of result. Use the tool name as the span name (e.g. `check_loan_eligibility`).176177**OpenInference attributes (use these so Arize shows spans correctly):**178179| Attribute | Use |180|-----------|-----|181| `openinference.span.kind` | Pick the right value: `"LLM"` for raw provider API calls (OpenAI, Anthropic, etc.); `"CHAIN"` for orchestration / agent-loop boundaries; `"TOOL"` for tool/function execution; `"RETRIEVER"` for vector-store / search lookups; `"EMBEDDING"` for embedding API calls; `"AGENT"` for an autonomous sub-agent run nested inside a larger chain; `"RERANKER"` for rerank API calls; `"GUARDRAIL"` for guardrail/policy checks; `"EVALUATOR"` for online eval calls. |182| `input.value` | string (e.g. user message or JSON of tool args) |183| `output.value` | string (e.g. final reply or JSON of tool result) |184185**LLM-span attributes (set these in addition to the three above when the span is an actual LLM call):**186187| Attribute | Use |188|-----------|-----|189| `llm.model_name` | model identifier (e.g. `"gpt-4o-mini"`) |190| `llm.provider` / `llm.system` | provider name (e.g. `"openai"`, `"anthropic"`) |191| `llm.input_messages.{i}.message.role` | `"system"` / `"user"` / `"assistant"` / `"tool"` for the i-th input message |192| `llm.input_messages.{i}.message.content` | text content of the i-th input message |193| `llm.output_messages.{i}.message.role` | role of the i-th output message |194| `llm.output_messages.{i}.message.content` | text content of the i-th output message |195| `llm.token_count.prompt` | int — prompt/input tokens |196| `llm.token_count.completion` | int — completion/output tokens |197| `llm.token_count.total` | int — total tokens |198199In Python and TypeScript these names are exposed via `openinference-semantic-conventions` packages; in Go they must be hand-typed as the strings above.200201**Python pattern:** Get the global tracer (same provider as Arize), then use context managers so tool spans are children of the CHAIN span and appear in the same trace as the LLM spans:202203```python204from opentelemetry.trace import get_tracer205206tracer = get_tracer("my-app", "1.0.0")207208 # In your agent entrypoint:209with tracer.start_as_current_span("run_agent") as chain_span:210 chain_span.set_attribute("openinference.span.kind", "CHAIN")211 chain_span.set_attribute("input.value", user_message)212 # ... LLM call ...213 for tool_use in tool_uses:214 with tracer.start_as_current_span(tool_use["name"]) as tool_span:215 tool_span.set_attribute("openinference.span.kind", "TOOL")216 tool_span.set_attribute("input.value", json.dumps(tool_use["input"]))217 result = run_tool(tool_use["name"], tool_use["input"])218 tool_span.set_attribute("output.value", result)219 # ... append tool result to messages, call LLM again ...220 chain_span.set_attribute("output.value", final_reply)221```222223**Go pattern:** Get a tracer from the global TracerProvider (registered via `otel.SetTracerProvider`), then nest spans with `tracer.Start` so tool spans become children of the CHAIN span.224225> **Critical for short-lived processes:** never call `log.Fatalf` / `os.Exit` after a span has started — they skip the deferred `tp.Shutdown(ctx)` and the in-flight CHAIN/LLM spans never flush. Use `log.Printf` + `return` from `main` instead, and keep `tp.Shutdown(ctx)` deferred at the top of `main`.226227```go228import (229 "context"230 "encoding/json"231 "go.opentelemetry.io/otel"232 "go.opentelemetry.io/otel/attribute"233)234235var tracer = otel.Tracer("my-app")236237func runAgent(ctx context.Context, userMessage string) string {238 ctx, chainSpan := tracer.Start(ctx, "run_agent")239 defer chainSpan.End()240 chainSpan.SetAttributes(241 attribute.String("openinference.span.kind", "CHAIN"),242 attribute.String("input.value", userMessage),243 )244245 // ... LLM call ...246 for _, toolUse := range toolUses {247 ctx, toolSpan := tracer.Start(ctx, toolUse.Name)248 argsJSON, err := json.Marshal(toolUse.Input)249 if err != nil {250 toolSpan.RecordError(err)251 }252 toolSpan.SetAttributes(253 attribute.String("openinference.span.kind", "TOOL"),254 attribute.String("input.value", string(argsJSON)),255 )256 result := runTool(toolUse.Name, toolUse.Input)257 toolSpan.SetAttributes(attribute.String("output.value", result))258 toolSpan.End()259 // ... append tool result to messages, call LLM again ...260 }261262 chainSpan.SetAttributes(attribute.String("output.value", finalReply))263 return finalReply264}265```266267See [Manual instrumentation](https://arize.com/docs/ax/instrument/manual-instrumentation) for more span kinds and attributes.268269## Verification270271Treat instrumentation as complete only when all of the following are true:2722731. The app still builds or typechecks after the tracing change.2742. The app starts successfully with the new tracing configuration.2753. You trigger at least one real request or run that should produce spans.2764. You either verify the resulting trace in Arize, or you provide a precise blocker that distinguishes app-side success from Arize-side failure.277278After implementation:2792801. Run the application and trigger at least one LLM call.2812. **Use the `arize-trace` skill** to confirm traces arrived. If empty, retry shortly. Verify spans have expected `openinference.span.kind`, `input.value`/`output.value`, and parent-child relationships.2823. If no traces: verify `ARIZE_SPACE` and `ARIZE_API_KEY`, ensure tracer is initialized before instrumentors and clients, check connectivity to `otlp.arize.com:443`, and inspect app/runtime exporter logs so you can tell whether spans are being emitted locally but rejected remotely. For debug set `GRPC_VERBOSITY=debug` or pass `log_to_console=True` to `register()`. Common gotchas: (a) missing project name resource attribute causes HTTP 500 rejections — `service.name` alone is not enough; Python: pass `project_name` to `register()`; TypeScript: set `"model_id"` or `SEMRESATTRS_PROJECT_NAME` on the resource; Go: add `attribute.String("openinference.project.name", "my-app")` to `resource.New(...)`; (b) CLI/script processes exit before OTLP exports flush — call `provider.force_flush()` then `provider.shutdown()` (Python/TS) or `tp.Shutdown(ctx)` (Go) before exit; (c) CLI-visible spaces/projects can disagree with a collector-targeted space ID — report the mismatch instead of silently rewriting credentials.2834. If the app uses tools: confirm CHAIN and TOOL spans appear with `input.value` / `output.value` so tool calls and results are visible.284285When verification is blocked by CLI or account issues, end with a concrete status:286287- app instrumentation status288- latest local trace ID or run ID289- whether exporter logs show local span emission290- whether the failure is credential, space/project resolution, network, or collector rejection291292## Leveraging the Tracing Assistant (MCP)293294For deeper instrumentation guidance inside the IDE, the user can enable:295296- **Arize AX Tracing Assistant MCP** — instrumentation guides, framework examples, and support. In Cursor: **Settings → MCP → Add** and use:297 ```json298 "arize-tracing-assistant": {299 "command": "uvx",300 "args": ["arize-tracing-assistant@latest"]301 }302 ```303- **Arize AX Docs MCP** — searchable docs. In Cursor:304 ```json305 "arize-ax-docs": {306 "url": "https://arize.com/docs/mcp"307 }308 ```309310Then the user can ask things like: *"Instrument this app using Arize AX"*, *"Can you use manual instrumentation so I have more control over my traces?"*, *"How can I redact sensitive information from my spans?"*311312See the full setup at [Agent-Assisted Tracing Setup](https://arize.com/docs/ax/alyx/tracing-assistant).313314## Reference link catalog315316| Resource | URL |317|----------|-----|318| Agent-Assisted Tracing Setup | https://arize.com/docs/ax/alyx/tracing-assistant |319| Agent Setup Prompt (full routing + phases) | https://arize.com/docs/PROMPT.md |320| Arize AX Docs | https://arize.com/docs/ax |321| Full integration list | https://arize.com/docs/ax/integrations |322| Doc index (llms.txt) | https://arize.com/docs/llms.txt |323324## Save Credentials for Future Use325326See references/ax-profiles.md § Save Credentials for Future Use.327328## Progressive disclosure and bundled resources329330Read bundled references only when the corresponding issue appears.331332- `references/ax-profiles.md`: `ax profiles show`, `ax profiles create`, credential storage, profile mismatch, and CLI troubleshooting for `ARIZE_API_KEY` and `ARIZE_SPACE`.333334## Output template335336```markdown337## Arize instrumentation result338339**Status:** analyzed | instrumented | blocked340**Scope:** `<service/package/path>`341**Language/runtime:** `<Python | TypeScript/JavaScript | Java | Go>`342**Package manager:** `<pip | poetry | uv | npm | pnpm | yarn | maven | gradle | go modules>`343344### Detected signals345| Area | Evidence | Decision |346| --- | --- | --- |347| LLM providers | `<imports/files>` | `<OpenAI/Anthropic/etc.>` |348| Frameworks | `<imports/files>` | `<LangChain/LangGraph/etc.>` |349| Existing tracing | `<TracerProvider/register/opentelemetry/ARIZE_/OTEL_/OTLP_>` | `<reuse/add exporter>` |350| Tools/function calling | `<agent loop evidence>` | `<manual CHAIN + TOOL spans>` |351352### Changes353- `<dependency or file changed>`: <why>354355### Verification356- Build/typecheck: pass | fail | not run because <reason>357- App start: pass | fail | not run because <reason>358- LLM request triggered: pass | fail | not run because <reason>359- Arize trace check: pass | blocked by credential | blocked by project/space mismatch | blocked by network | blocked by collector rejection360- Latest local trace/run ID: `<id or none>`361```362363## Quality gate364365- [ ] Phase 1 inspected manifests, imports, existing tracing, environment variable names, and monorepo scope before code changes.366- [ ] Instrumentation is additive and does not alter business logic.367- [ ] Integration docs were fetched for the detected provider/framework path before implementation.368- [ ] Dependencies were installed with the detected package manager before code was written.369- [ ] Generated code references environment variables such as `ARIZE_API_KEY`, `ARIZE_SPACE`, `os.environ["ARIZE_API_KEY"]`, `process.env.ARIZE_API_KEY`, or `os.Getenv("ARIZE_API_KEY")`; it never embeds raw secret values.370- [ ] TracerProvider setup includes project routing through `project_name`, `openinference.project.name`, `model_id`, `SEMRESATTRS_PROJECT_NAME`, or `set_routing_context(...)` as appropriate.371- [ ] Short-lived CLI/script apps flush and shut down providers before exit.372- [ ] Tool/function execution emits manual CHAIN and TOOL spans with `input.value` and `output.value` when framework instrumentation does not cover them.373- [ ] Verification distinguishes app-side success from credential, `ARIZE_SPACE`/project mismatch, network, or collector rejection failures.374375## References376377- [Agent-Assisted Tracing Setup](https://arize.com/docs/ax/alyx/tracing-assistant)378- [Agent Setup Prompt](https://arize.com/docs/PROMPT.md)379- [Arize AX Docs](https://arize.com/docs/ax)380- [Full integration list](https://arize.com/docs/ax/integrations)381- [Manual instrumentation](https://arize.com/docs/ax/instrument/manual-instrumentation)382- [OpenInference](https://github.com/Arize-ai/openinference)383- [CLI profiles docs](https://arize.com/docs/api-clients/cli/profiles)384- [Arize app](https://app.arize.com)385- [Doc index](https://arize.com/docs/llms.txt)386- [Arize Docs MCP](https://arize.com/docs/mcp)387- [OpenAI integration](https://arize.com/docs/ax/integrations/llm-providers/openai)388- [Anthropic integration](https://arize.com/docs/ax/integrations/llm-providers/anthropic)389- [LiteLLM integration](https://arize.com/docs/ax/integrations/llm-providers/litellm)390- [Google Gen AI integration](https://arize.com/docs/ax/integrations/llm-providers/google-gen-ai)391- [Amazon Bedrock integration](https://arize.com/docs/ax/integrations/llm-providers/amazon-bedrock)392- [Ollama integration](https://arize.com/docs/ax/integrations/llm-providers/llama)393- [Groq integration](https://arize.com/docs/ax/integrations/llm-providers/groq)394- [MistralAI integration](https://arize.com/docs/ax/integrations/llm-providers/mistralai)395- [OpenRouter integration](https://arize.com/docs/ax/integrations/llm-providers/openrouter)396- [VertexAI integration](https://arize.com/docs/ax/integrations/llm-providers/vertexai)397- [LangChain](https://arize.com/docs/ax/integrations/python-agent-frameworks/langchain)398- [LangGraph](https://arize.com/docs/ax/integrations/python-agent-frameworks/langgraph)399- [LlamaIndex](https://arize.com/docs/ax/integrations/python-agent-frameworks/llamaindex)400- [CrewAI](https://arize.com/docs/ax/integrations/python-agent-frameworks/crewai)401- [DSPy](https://arize.com/docs/ax/integrations/python-agent-frameworks/dspy)402- [AutoGen](https://arize.com/docs/ax/integrations/python-agent-frameworks/autogen)403- [Semantic Kernel](https://arize.com/docs/ax/integrations/python-agent-frameworks/semantic-kernel)404- [Pydantic AI](https://arize.com/docs/ax/integrations/python-agent-frameworks/pydantic)405- [Haystack](https://arize.com/docs/ax/integrations/python-agent-frameworks/haystack)406- [Guardrails AI](https://arize.com/docs/ax/integrations/python-agent-frameworks/guardrails-ai)407- [Hugging Face Smolagents](https://arize.com/docs/ax/integrations/python-agent-frameworks/hugging-face-smolagents)408- [Instructor](https://arize.com/docs/ax/integrations/python-agent-frameworks/instructor)409- [Agno](https://arize.com/docs/ax/integrations/python-agent-frameworks/agno)410- [Google ADK](https://arize.com/docs/ax/integrations/python-agent-frameworks/google-adk)411- [MCP](https://arize.com/docs/ax/integrations/python-agent-frameworks/model-context-protocol)412- [Portkey](https://arize.com/docs/ax/integrations/python-agent-frameworks/portkey)413- [Together AI](https://arize.com/docs/ax/integrations/python-agent-frameworks/together-ai)414- [BeeAI](https://arize.com/docs/ax/integrations/python-agent-frameworks/beeai)415- [AWS Bedrock Agents](https://arize.com/docs/ax/integrations/python-agent-frameworks/aws)416- [LangChain JS](https://arize.com/docs/ax/integrations/ts-js-agent-frameworks/langchain)417- [Mastra](https://arize.com/docs/ax/integrations/ts-js-agent-frameworks/mastra)418- [Vercel AI SDK](https://arize.com/docs/ax/integrations/ts-js-agent-frameworks/vercel)419- [BeeAI JS](https://arize.com/docs/ax/integrations/ts-js-agent-frameworks/beeai)420- [LangChain4j](https://arize.com/docs/ax/integrations/java/langchain4j)421- [Spring AI](https://arize.com/docs/ax/integrations/java/spring-ai)422- [Arconia](https://arize.com/docs/ax/integrations/java/arconia)423- [LangFlow](https://arize.com/docs/ax/integrations/platforms/langflow)424- [Flowise](https://arize.com/docs/ax/integrations/platforms/flowise)425- [Dify](https://arize.com/docs/ax/integrations/platforms/dify)426- [Prompt flow](https://arize.com/docs/ax/integrations/platforms/prompt-flow)
Run npx skillmds@latest add paulasilvatech/arize-instrumentation in your terminal (requires Node.js), paste this page's agent-chat prompt into Claude, Cursor, or any MCP-connected agent, or download the SKILL.md file and copy it into your agent's skills directory.
Adds Arize AX tracing to an LLM application for the first time. Use when the user wants to instrument their app, add tracing from scratch, set up LLM observability, integrate OpenTelemetry or OpenInference, or get started with Arize tracing. It is listed under AI & ML on SkillMD.
This skill has not completed SkillMD's automated safety review yet. SkillMD never runs a skill's scripts for you; review the SKILL.md before installing.
This skill is tagged as working with Claude Code, Claude.ai, OpenAI Codex. SKILL.md is an open format, so most agents that read a skills directory can load it too.
Yes. Installing skills from SkillMD is free, and the skill stays under its author's original license.
paulasilvatech (@paulasilvatech) published this skill. Their other Agent Skills are listed on their SkillMD profile.