2단계 분석 및 구현 프로세스를 통해 LLM 애플리케이션에 Arize AX 트레이싱을 추가합니다.
- GitHub 스타
- 41,038
- 파일
- 2
- 마지막 커밋
- 2026년 11월 11일
- 라이선스
- MIT
- 허용된 도구
- —
arize-instrumentation skill은 무엇을 하나요?
arize-instrumentation은(는) agent skill입니다. 2단계 분석 및 구현 프로세스를 통해 LLM 애플리케이션에 Arize AX 트레이싱을 추가합니다.
skill의 SKILL.md에서 생성된 요약입니다.
arize-instrumentation skill 정보
이 SKILL은 관측 가능성을 확보하려는 개발자가 LLM 애플리케이션에 Arize AX 트레이싱을 추가할 수 있도록 지원합니다. 프로세스는 구조화된 2단계 방식을 따르며, 먼저 코드베이스를 읽기 전용으로 분석하여 프로그래밍 언어, 패키지 매니저 및 기존 프레임워크를 식별합니다. 이 초기 단계는 에이전트가 실제 수정 작업을 수행하기 전에 LangChain 기반 Python이나 Vercel AI SDK 기반 TypeScript와 같은 기술 스택을 정확히 이해하도록 보장합니다.
사용자가 분석 내용을 확인하면 SKILL은 구현 단계로 넘어갑니다. openinference-instrumentation 또는 OpenTelemetry SDK와 같은 필수 패키지 설치를 자동화하고 올바른 트레이싱 설정을 적용합니다. 이 프로세스는 기존 비즈니스 로직을 변경하지 않고 관측 가능성만 추가하는 방식으로 설계되었습니다. Python, TypeScript, JavaScript, Java, Go 등 다양한 언어를 지원하며, API key와 같은 민감한 자격 증명이 소스 파일에 하드코딩되지 않고 환경 변수를 통해 처리되도록 보장합니다.
agent가 수행할 수 있는 작업
- 1Python LLM 애플리케이션 계측특정 openinference 패키지를 사용하여 Python 프로젝트에 자동 계측을 추가합니다.
- 2Go에서 수동 트레이싱 설정OpenTelemetry SDK를 사용하여 Go 애플리케이션에 수동 OpenInference span을 구성합니다.
- 3API 자격 증명의 안전한 관리모든 트레이싱 설정이 실제 비밀 값을 대신하여 환경 변수를 사용하도록 보장합니다.
skill의 SKILL.md를 기반으로 작성되었습니다. 모든 사용 사례는 해당 문서의 인용구와 대조 확인되었습니다.
arize-instrumentation skill 설치 방법
각 명령은 skill 폴더를 클라이언트의 skills 디렉터리에 복사합니다. 클라이언트를 재시작하거나 새 세션을 시작하여 로드하세요.Claude Code에 arize-instrumentation skill 설치
~/.claude/skills/arize-instrumentation/SKILL.md
$ npx degit github/awesome-copilot/skills/arize-instrumentation ~/.claude/skills/arize-instrumentationClaude Code (project)에 arize-instrumentation skill 설치
.claude/skills/arize-instrumentation/SKILL.md
$ npx degit github/awesome-copilot/skills/arize-instrumentation .claude/skills/arize-instrumentationCodex에 arize-instrumentation skill 설치
~/.agents/skills/arize-instrumentation/SKILL.md
$ npx degit github/awesome-copilot/skills/arize-instrumentation ~/.agents/skills/arize-instrumentationGemini CLI에 arize-instrumentation skill 설치
~/.gemini/skills/arize-instrumentation/SKILL.md
$ npx degit github/awesome-copilot/skills/arize-instrumentation ~/.gemini/skills/arize-instrumentationClaude.ai에 arize-instrumentation skill 설치
npx degit github/awesome-copilot/skills/arize-instrumentation arize-instrumentation && zip -r arize-instrumentation.zip arize-instrumentation # claude.ai → Customize → Skills → + → Create skill → Upload a skill → arize-instrumentation.zip
자동 검사
2026년 11월 15일에 실행됨전체 보고서 →자동 검사를 통과했습니다. 보안 감사는 아닙니다. 에이전트가 실행하기 전에 스크립트를 읽어 보세요. 검사 방식
- 소스 저장소 연결 및 접근 가능github/awesome-copilot/skills/arize-instrumentation is public and reachablegithub.com/github/awesome-copilot/tree/HEAD/skills/arize-ins ↗통과
- 오픈 소스 라이선스 (OSI)MITspdx.org/licenses/MIT.html ↗통과
- 최근 1년 내 커밋 또는 릴리스Last commit 2026-11-11github.com/github/awesome-copilot/commits ↗통과
- 스크립트에 다운로드 후 실행이나 자격 증명 탈취가 없음No scripts in the skill folder통과
- SKILL.md에 숨겨진 지침 없음No override phrases, safeguard switches, credential requests or hidden charactersgithub.com/github/awesome-copilot/blob/HEAD/skills/arize-ins ↗통과
- 사전 허용 도구가 제한됨No pre-approved tools; the agent asks before using onegithub.com/github/awesome-copilot/blob/HEAD/skills/arize-ins ↗통과
- SKILL.md가 Agent Skills 형식을 따름Valid name and description; says when to use it; 310 linesgithub.com/github/awesome-copilot/blob/HEAD/skills/arize-ins ↗통과
SKILL.md
GitHub에서 보기Arize Instrumentation Skill
Use 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 and the Arize AX Tracing — Agent Setup Prompt.
Quick start (for the user)
If the user asks you to "set up tracing" or "instrument my app with Arize", you can start with:
Follow the instructions from https://arize.com/docs/PROMPT.md and ask me questions as needed.
Then execute the two phases below.
Core principles
- 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.
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
axwill be needed for post-change verification
- Do NOT proactively check
axinstallation or version. Ifaxis 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.
Steps
-
Check dependency manifests to detect stack:
- Python:
pyproject.toml,requirements.txt,setup.py,Pipfile - TypeScript/JavaScript:
package.json - Java:
pom.xml,build.gradle,build.gradle.kts - Go:
go.mod
- Python:
-
Scan import statements in source files to confirm what is actually used.
-
Check for existing tracing/OTel — look for
TracerProvider,register(),opentelemetryimports,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).
Phase 1 output
Return a concise summary:
- Detected language, package manager, providers, frameworks
- 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.
- LLM providers: OpenAI, Anthropic, LiteLLM, Google Gen AI, Bedrock, Ollama, Groq, MistralAI, OpenRouter, VertexAI.
- Python frameworks: LangChain, LangGraph, LlamaIndex, CrewAI, DSPy, AutoGen, Semantic Kernel, Pydantic AI, Haystack, Guardrails AI, Hugging Face Smolagents, Instructor, Agno, Google ADK, MCP, Portkey, Together AI, BeeAI, AWS Bedrock Agents.
- TypeScript/JavaScript: LangChain JS, Mastra, Vercel AI SDK, BeeAI JS.
- Java: LangChain4j, Spring AI, Arconia.
- Go: No first-party auto-instrumentation packages today — use the OpenTelemetry Go SDK with manual OpenInference attributes per Manual instrumentation.
- Platforms (UI-based): LangFlow, Flowise, Dify, Prompt flow.
- Fallback: Manual instrumentation, All integrations.
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.mdandarize.com/docs/llms.txtare 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-otelplusopeninference-instrumentation-{name}(hyphens in package name; underscores in import, e.g.openinference.instrumentation.llama_index). - TypeScript/JavaScript:
@opentelemetry/sdk-trace-nodeplus 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 withotlptracehttp.WithEndpoint("otlp.arize.com")(US) orotlptracehttp.WithEndpoint("otlp.eu-west-1a.arize.com")(EU) — pass the bare hostname, nohttps://scheme — andotlptracehttp.WithHeaders(map[string]string{"space_id": ..., "api_key": ...}). Recent OTel Go modules require Go ≥ 1.23 —go mod tidymay bump the toolchain.
- Python:
- Credentials — User needs an Arize API Key and Space ID. Check existing
axprofiles forARIZE_API_KEYandARIZE_SPACE— never read.envfiles:- Run
ax profiles showto check for an existing profile. - If no profile exists, guide the user to run
ax profiles createwhich 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), oros.Getenv("ARIZE_API_KEY")(Go). - See references/ax-profiles.md for full profile setup and troubleshooting.
- Run
- 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).
- Import order: register tracer → attach instrumentors → then create LLM clients.
- Project name attribute (required): Arize rejects spans with HTTP 500 if the project name is missing —
service.namealone 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, useset_routing_context(space_id=..., project_name=...)fromarize.otel. - TypeScript: Arize accepts both
"model_id"(shown in the official TS quickstart) and"openinference.project.name"viaSEMRESATTRS_PROJECT_NAMEfrom@arizeai/openinference-semantic-conventions(shown in the manual instrumentation docs) — both work. - Go: Pass
attribute.String("openinference.project.name", "my-app")toresource.New(...)and apply viasdktrace.WithResource(res). The Go SDK has no helper for this, so it must be set manually on every TracerProvider.
- Python:
- CLI/script apps — flush before exit:
provider.shutdown()(TS) /provider.force_flush()thenprovider.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 yourrun_tool()or the actual tool output. The next API call (sending the tool result back) is just anothermessages.createspan — 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(...)afterregister()):- CHAIN span — Wrap the full agent run (e.g.
run_agent): setopeninference.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).
- CHAIN span — Wrap the full agent run (e.g.
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.Exitafter a span has started — they skip the deferredtp.Shutdown(ctx)and the in-flight CHAIN/LLM spans never flush. Uselog.Printf+returnfrommaininstead, and keeptp.Shutdown(ctx)deferred at the top ofmain.
import (
"context"
"encoding/json"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
)
var tracer = otel.Tracer("my-app")
func runAgent(ctx context.Context, userMessage string) string {
ctx, chainSpan := tracer.Start(ctx, "run_agent")
defer chainSpan.End()
chainSpan.SetAttributes(
attribute.String("openinference.span.kind", "CHAIN"),
attribute.String("input.value", userMessage),
)
// ... LLM call ...
for _, toolUse := range toolUses {
ctx, toolSpan := tracer.Start(ctx, toolUse.Name)
argsJSON, err := json.Marshal(toolUse.Input)
if err != nil {
toolSpan.RecordError(err)
}
toolSpan.SetAttributes(
attribute.String("openinference.span.kind", "TOOL"),
attribute.String("input.value", string(argsJSON)),
)
result := runTool(toolUse.Name, toolUse.Input)
toolSpan.SetAttributes(attribute.String("output.value", result))
toolSpan.End()
// ... append tool result to messages, call LLM again ...
}
chainSpan.SetAttributes(attribute.String("output.value", finalReply))
return finalReply
}
See Manual instrumentation for more span kinds and attributes.
Verification
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-traceskill to confirm traces arrived. If empty, retry shortly. Verify spans have expectedopeninference.span.kind,input.value/output.value, and parent-child relationships. - If no traces: verify
ARIZE_SPACEandARIZE_API_KEY, ensure tracer is initialized before instrumentors and clients, check connectivity tootlp.arize.com:443, and inspect app/runtime exporter logs so you can tell whether spans are being emitted locally but rejected remotely. For debug setGRPC_VERBOSITY=debugor passlog_to_console=Truetoregister(). Common gotchas: (a) missing project name resource attribute causes HTTP 500 rejections —service.namealone is not enough; Python: passproject_nametoregister(); TypeScript: set"model_id"orSEMRESATTRS_PROJECT_NAMEon the resource; Go: addattribute.String("openinference.project.name", "my-app")toresource.New(...); (b) CLI/script processes exit before OTLP exports flush — callprovider.force_flush()thenprovider.shutdown()(Python/TS) ortp.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.valueso 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:
"arize-tracing-assistant": { "command": "uvx", "args": ["arize-tracing-assistant@latest"] } - Arize AX Docs MCP — searchable docs. In Cursor:
"arize-ax-docs": { "url": "https://arize.com/docs/mcp" }
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 the full setup at Agent-Assisted Tracing Setup.
이 스킬의 파일
2arize-instrumentation skill 질문
Claude Code에 arize-instrumentation skill을 어떻게 설치하나요?
npx degit github/awesome-copilot/skills/arize-instrumentation ~/.claude/skills/arize-instrumentation를 실행합니다. Claude Code는 ~/.claude/skills(모든 프로젝트) 또는 .claude/skills(한 프로젝트)에서 skills를 로드하며, 설명이 작업과 일치할 때 skill을 사용합니다.
arize-instrumentation skill을 사용할 수 있는 클라이언트는 무엇인가요?
Agent Skills 형식을 읽는 모든 클라이언트(Claude Code, Codex, Gemini CLI, claude.ai(ZIP으로 업로드))가 사용할 수 있습니다. skill 내 스크립트는 클라이언트가 코드 실행을 허용하는 경우에만 실행됩니다.
계측 프로세스는 어떻게 작동하나요?
이 SKILL은 에이전트가 지원하는 2단계 흐름을 따릅니다. 먼저 코드베이스를 읽기 전용으로 분석하여 언어와 프레임워크를 감지한 다음, 사용자의 확인을 거쳐 계측을 구현합니다.
Arize 계측을 지원하는 프로그래밍 언어는 무엇인가요?
자동 계측 패키지를 사용하는 Python 및 TypeScript/JavaScript를 지원하며, OpenTelemetry SDK와 수동 OpenInference span을 사용하는 Java 및 Go도 지원합니다.
설정 시 API key와 Space ID는 어떻게 처리해야 하나요?
코드에 실제 자격 증명을 직접 포함해서는 안 되며, 대신 환경 변수를 사용해야 합니다. 'ax profiles create' 명령어를 사용하면 대화형 위저드를 통해 자격 증명을 설정할 수 있습니다.