LLM Trace Review Interface
ai-evals-course/evals-skills
Builds a browser-based annotation page for reviewing LLM traces one at a time with pass/fail labels, notes and saved results, tailored to your data.
Find out what is going wrong in LLM or agent traffic by reading sampled Phoenix traces, spans, or sessions, writing free-form notes (open coding), then grouping the notes into a few narrow…
$ npx skills add Arize-ai/phoenix --skill phoenix-error-analysis -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install Arize-ai/phoenix phoenix-error-analysis --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/Arize-ai/phoenix.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/phoenix-error-analysis .claude/skills/phoenix-error-analysis && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "phoenix-error-analysis" agent skill from https://github.com/Arize-ai/phoenix/tree/main/.agents/skills/phoenix-error-analysis into .claude/skills/phoenix-error-analysis/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "phoenix-error-analysis", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/Arize-ai/phoenix/tree/main/.agents/skills/phoenix-error-analysisType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add Arize-ai/phoenix --skill phoenix-error-analysis -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install Arize-ai/phoenix phoenix-error-analysis --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/Arize-ai/phoenix.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.agents/skills/phoenix-error-analysis .agents/skills/phoenix-error-analysis && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "phoenix-error-analysis" agent skill from https://github.com/Arize-ai/phoenix/tree/main/.agents/skills/phoenix-error-analysis into .agents/skills/phoenix-error-analysis/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "phoenix-error-analysis", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add Arize-ai/phoenix --skill phoenix-error-analysis -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install Arize-ai/phoenix phoenix-error-analysis --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/Arize-ai/phoenix.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.agents/skills/phoenix-error-analysis .cursor/skills/phoenix-error-analysis && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "phoenix-error-analysis" agent skill from https://github.com/Arize-ai/phoenix/tree/main/.agents/skills/phoenix-error-analysis into .cursor/skills/phoenix-error-analysis/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "phoenix-error-analysis", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/Arize-ai/phoenix.git --path .agents/skills/phoenix-error-analysis--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add Arize-ai/phoenix --skill phoenix-error-analysis -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install Arize-ai/phoenix phoenix-error-analysis --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/Arize-ai/phoenix.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.agents/skills/phoenix-error-analysis .gemini/skills/phoenix-error-analysis && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "phoenix-error-analysis" agent skill from https://github.com/Arize-ai/phoenix/tree/main/.agents/skills/phoenix-error-analysis into .gemini/skills/phoenix-error-analysis/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "phoenix-error-analysis", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install Arize-ai/phoenix phoenix-error-analysisInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add Arize-ai/phoenix --skill phoenix-error-analysis -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/Arize-ai/phoenix.git skills-src && mkdir -p .github/skills && cp -r skills-src/.agents/skills/phoenix-error-analysis .github/skills/phoenix-error-analysis && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "phoenix-error-analysis" agent skill from https://github.com/Arize-ai/phoenix/tree/main/.agents/skills/phoenix-error-analysis into .github/skills/phoenix-error-analysis/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "phoenix-error-analysis", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add Arize-ai/phoenix --skill phoenix-error-analysis -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install Arize-ai/phoenix phoenix-error-analysis --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/Arize-ai/phoenix.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.agents/skills/phoenix-error-analysis .opencode/skills/phoenix-error-analysis && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "phoenix-error-analysis" agent skill from https://github.com/Arize-ai/phoenix/tree/main/.agents/skills/phoenix-error-analysis into .opencode/skills/phoenix-error-analysis/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "phoenix-error-analysis", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
phoenix-error-analysisFind out what is going wrong in LLM or agent traffic by reading sampled Phoenix traces, spans, or sessions, writing free-form notes (open coding), then grouping the notes into a few narrow…
Phoenix Error Analysis is an agent skill from Arize-ai/phoenix. Find out what is going wrong in LLM or agent traffic by reading sampled Phoenix traces, spans, or sessions, writing free-form notes (open coding), then grouping the notes into a few narrow annotations, one per failure dimension with a small label set and counts, that pick eval targets and fix priorities (axial coding). Use for "what's going wrong with this agent", "I just instrumented my app, where do I start", "review these traces", "the chatbot keeps losing context", "what kinds of mistakes is the model…
Its SKILL.md is about 6.4k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
It sits in AI & LLM Engineering, covering LLM observability and LLM evaluation. The repository describes itself as: AI Observability & Evaluation. The licence is Apache-2.0.
2 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit 3383f07. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
No scripts in the folder and no shell commands in SKILL.md (its code samples are json, bash and yaml).
From the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Phoenix Error Analysis loads about 6.4k tokens when it runs. Until then it costs about 207 tokens; SKILL.md has 3,282 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from Arize-ai/phoenix at commit 3383f07, republished under its Apache-2.0 licence (© Arize-ai). 3,282 words, ~6,392 tokens.
.claude/skills/phoenix-error-analysis/SKILL.md (or your agent's skills folder).Two phases against sampled traces, spans, or sessions. Open coding reads each sampled entity and writes a short, specific note on what went wrong. Axial coding groups those notes into a few narrow annotations, each judging one dimension of the entity with a small label set, and counts the labels to feed eval design and fix prioritization. Open coding always comes first: dimensions and labels that are not grounded in notes are invented top-down, which is the failure this workflow exists to avoid. Axial coding can also start from any existing set of open-ended observations.
Recorded notes are the deliverable. Open coding ends with one note per problematic entity written to the server and mirrored in the local sidecar, not with a summary in chat. Reading traces and reporting what you noticed without recording anything is a read-only diagnosis, the top-down shortcut this workflow exists to replace. A project-wide question such as "find any issues", "what's going wrong", or "any errors here" is a request for phase 1: pick the identifier, pick the unit, record a note for each problem as you find it, then summarize. A project with no annotation names yet is the normal starting state, not a reason to hold off writing.
Pick trace, span, or session deliberately before recording — the choice determines what every note and annotation below targets, and a wrong default is expensive to undo mid-run. The unit is where the failure modes you're investigating actually live:
session.id. Multi-turn agents where the failure is a trajectory — context loss across turns, goal drift, forgotten preferences — that exists only across traces.Three signals to read:
User framing. "Conversation", "agent forgot", "drift", "across turns" → session. "This trace", "wrong output" → trace. "Exception", "malformed", "the retrieval failed" → span.
Session wiring. The session id lives at the root span's session.id attribute (not a top-level trace field); "" means absent. List ~200 recent traces and compute how many carry a non-empty session id, how many distinct session ids appear, and the median traces per session. No session ids or median 1 → trace or span level; median 2+ → session level is plausibly right.
Turn structure. Open one recent trace's root-span input.value (it may be large — filter rather than reading wholesale). A single user message → one shot; a message array ([{role: user}, {role: assistant}, ...]) → a turn of a dialogue that lives at the session level.
State the chosen unit explicitly before recording any note. It can shift if the data demands it — trace-level notes that keep surfacing "the agent never remembers earlier turns" should pivot the next batch to session. The unit is a starting hypothesis, not a contract.
Every artifact this workflow produces — open-coding notes, axial-coding labels, and the local sidecar files — is tagged with one coding annotation identifier so the run is queryable and revertible as a unit. Pick a descriptive, unique value before recording, e.g. coding-run:chatbot-context-loss-2026-05-06. (The coding-run: prefix is a naming convention; the value is not a Phoenix session id.)
Pass the identifier explicitly on every server write. A shell variable is fine for readability, but do not rely on shell inheritance — many agent harnesses spawn each command in a fresh subshell.
The local sidecars live at .px/coding/<sanitized-identifier>.jsonl (open-coding notes) and .px/coding/<sanitized-identifier>-axial.jsonl (axial labels), CWD-relative; sanitization replaces every character outside [a-zA-Z0-9_-] with -. Uniqueness is a local file check, not a server query:
CODING_ANNOTATION_IDENTIFIER="coding-run:chatbot-context-loss-2026-05-06"
SLUG=$(echo -n "$CODING_ANNOTATION_IDENTIFIER" | sed 's/[^a-zA-Z0-9_-]/-/g')
NOTES_SIDECAR=".px/coding/${SLUG}.jsonl"
AXIAL_SIDECAR=".px/coding/${SLUG}-axial.jsonl"
test ! -f "$NOTES_SIDECAR" || { echo "Sidecar already exists at $NOTES_SIDECAR — pick a new identifier or delete the file"; exit 1; }
mkdir -p .px/codingIf $NOTES_SIDECAR already exists, append a disambiguator (-v2, -dustin, etc.) and re-check.
Resuming a run — the two phases may run in independent invocations. When axial coding starts in a fresh shell, set the identifier to the same value chosen during open coding (recoverable from the wrap-up UI URL or by listing .px/coding/*.jsonl), skip the uniqueness check, and re-derive the sidecar paths from it. Never mint a new identifier mid-run.
The steps below name operations, not commands. Two surfaces implement them; use whichever the harness gives you. The phoenix-cli skill documents the px flags, and the phoenix-graphql skill's references (project-spans-traces.md, sessions.md, annotations.md) document the GraphQL fields and mutation inputs. This skill ships no reference files of its own.
| Operation | Phoenix CLI (px) | GraphQL (phoenix-gql or any client) |
|---|---|---|
| Sample, expand, drill | px trace list, px trace get <trace-id>, px span get <span-id>, px session get <session-id> | Project.spans(filterCondition: "parent_span is None"), getTraceByOtelId, getSpanByOtelId, node(id:) on a session |
| Check existing notes | --include-notes on get/list | Span.spanNotes; Trace.traceAnnotations / ProjectSession.sessionAnnotations where name == "note" |
| Write a note | px trace add-note <trace-id> --text "..." --identifier "$CODING_ANNOTATION_IDENTIFIER" (also px span add-note, px session add-note) | createTraceNotes, createSpanNotes, createProjectSessionNotes — each takes { note, annotatorKind: LLM, source: API, identifier } plus an entity reference by OTel id ({ otelId }) or node id ({ id }) |
| Write an axial annotation | px trace annotate <trace-id> --name <annotation-name> --label <label> --identifier "$CODING_ANNOTATION_IDENTIFIER" (also span, session) | createTraceAnnotations, createSpanAnnotations, createProjectSessionAnnotations — Phoenix node ids only, plus name, label, explanation, annotatorKind: LLM, source: API, metadata: {}, identifier |
| Annotation config | px annotation-config list, create, update <identifier> | createAnnotationConfig, updateAnnotationConfig, addAnnotationConfigToProject |
| Discard the run | px trace-annotations delete --identifier "$CODING_ANNOTATION_IDENTIFIER" --all -y (also span-annotations, session-annotations) | No identifier-filtered sweep: collect the run's annotation node ids, then deleteTraceAnnotations, deleteSpanAnnotations, deleteProjectSessionAnnotations |
Note and annotation writes are synchronous and upsert on (entity, name, identifier). Where the harness gates mutations behind an approval step, describe the write each command makes and keep every mutation in its own call.
Free-form note-writing. Write what you saw, not the category you think it belongs to — categorization is phase 2.
Don't sample by span status
ERROR. OTel'sstatus_codeonly flips toERRORwhen an instrumentor catches a raised exception. Hallucinations, wrong tone, retrieval misses, and bad tool selection all complete cleanly asOKorUNSET— filtering to error status excludes the population this workflow exists to surface.
A checklist, not a taxonomy — categories come later. Note the first thing that goes wrong; a downstream symptom gets its own note only if it has an independent cause.
Treat existing evals and annotations as one input among many. Read content, not status: a success status can hide an error in the attributes, and an exception can be expected behavior.
Whatever the tooling, the fetches are: sample recent traces (trace id, root span name, status, root-span input.value / output.value); expand one trace into its spans ordered by start time; drill into a single span by id when the unit is the span; and check existing notes on entities you are about to review — notes are stored server-side as annotations with the reserved name note. As always, be aware that the data may be verbose, so take care not to blow up the context.
For each session, trace, or span you inspect, submit a note to the server (see Where the writes go) and also save a local copy. Every write should carry the note text and an explicit identifier set to the coding annotation identifier. Record as you go, entity by entity — do not batch the notes into a closing summary.
After every successful note write to the server, append one JSONL line to $NOTES_SIDECAR — the sidecar is what axial coding reads, with no server round-trip:
{"entity_kind":"trace","entity_id":"<trace-id>","note":"<text>","identifier":"<original identifier value, unsanitized>","ts":"<ISO-8601 UTC>"}| Weak note | Good note |
|---|---|
| "Wrong answer" | "Said the store closes at 6pm but policy is 9pm" |
| "Retrieval issue" | "Retrieved docs about shipping when the question was about returns" |
Stop when observations stop being new: the last 10–15 entities repeat failures you've already seen, you catch yourself paraphrasing earlier notes, or skips outnumber notes. Resist grouping into categories while still collecting. You do not need to annotate every trace — annotating correct ones dilutes signal.
At saturation, decide whether to continue into axial coding:
Turn the open-coding notes into a small set of annotations, each judging one dimension of the entity: one question about its behavior, answered with a few labels. An entity carries one annotation per dimension its note touches, so a trace can end up with two or three. The output is several narrow annotations with two to four labels each — not one wide <app>_failure_mode annotation whose labels span unrelated concerns. A wide annotation cannot be aggregated per dimension, cannot be reused by an eval that judges one thing, and forces one label onto entities that failed in two ways.
$NOTES_SIDECAR. An absent file means open coding hasn't run for this identifier in this CWD — stop and run phase 1 first. The newest ts per entity wins; fix or drop a malformed line without touching its neighbors. To include notes from other reviewers or earlier runs, fetch them from the server (annotations with the reserved name note).tool_selection, answer_faithfulness) and choose its labels: the failure outcomes the notes describe, plus one passing value so an eval can later apply the same annotation to entities that pass. Labels within a dimension are mutually exclusive; if two labels could both be true of one entity, they belong to different dimensions.$AXIAL_SIDECAR: group the current rows by (annotation_name, axial_label), newest ts per (entity, annotation_name) wins. No server query — the sidecar holds exactly the labels this run wrote.tool_selection), the label is the answer (hallucinated_tool). Judging tool choice and harness stability at once means two annotations.retrieval or tool_use is a dimension name, not a label. If a label reads as a noun for a part of the system, promote it to its own annotation and describe its outcomes as the labels.Axial coding inherits open coding's unit by default, but an annotation can live at a different level than the note that informed it, in any direction: trace-level "answered shipping when asked about returns" notes can produce a span-level retrieval_relevance label on the retrieval span once retrieval emerges as the consistent culprit; trace-level single-turn-confusion notes can produce a session-level context_tracking label once the pattern is "doesn't track context across turns"; a session-level drift note can attribute to one specific turn and produce a trace-level label. Write each annotation at the level its dimension actually implicates — different dimensions in one run may live at different levels.
Categorize the entities you took notes on: $NOTES_SIDECAR is the source of candidates, and labels are written only after reading the note text and surrounding context. Do not select entities by error status — that captures only raised exceptions and excludes most failure modes (hallucination, wrong tone, retrieval miss).
Once the dimensions have stabilized — after Group and Define, not per-write — register one categorical annotation config per dimension before recording:
tool_selection, answer_faithfulness); that is how Phoenix links them. Never a generic category, and never one config that bundles every dimension.Annotations write fine without a config, but the config is what makes a dimension first-class in the Phoenix UI: human annotators get its labels as a dropdown instead of free text, and later runs inherit a shared vocabulary instead of drifting. If a new label emerges mid-recording, add it to that dimension's config before writing with it.
An annotation is useful later only if it is filterable, aggregatable, and auditable. So:
tool_selection = hallucinated_tool, not hallucinated_tool = true, and not failure_mode = hallucinated_tool._v2 suffixes, and no borrowing another project's config because the name fits.For each entity and each dimension its note touches, write one annotation with:
retrieval_relevanceoff_topicLLM for your own judgment, HUMAN only for one the user gave youThe server also accepts an optional score. Writes upsert on (entity_id, name, identifier), so the same entity can carry several annotations under one identifier as long as their names differ. The server's default write mode enqueues asynchronously — prefer a synchronous mode where the tooling offers one, so the row is applied before continuing.
After each write, append one JSONL row to $AXIAL_SIDECAR — one row per annotation, so an entity labelled on two dimensions gets two rows:
{"entity_kind":"trace","entity_id":"<trace-id>","annotation_name":"<annotation-name>","axial_label":"<label>","explanation":"<optional explanation>","identifier":"<original identifier value, unsanitized>","ts":"<ISO-8601 UTC>"}entity_kind ("trace", "span", or "session") matches the level the annotation was written at; identifier is the original unsanitized value — the sanitized form lives only in the filename. To revise a label, replace the row or append a newer one: the newest ts per (entity_kind, entity_id, annotation_name) is current, matching the server upsert.
Each key is an annotation name; its values are that annotation's labels. A run produces a few of these, not a tree.
tool_selection: [correct, wrong_tool, hallucinated_tool, unnecessary_call]
retrieval_relevance: [relevant, off_topic, nothing_retrieved]
answer_faithfulness: [grounded, invented_fact, invented_citation]
context_tracking: [kept, ignored_preference, goal_drift]
task_completion: [completed, partial, abandoned]Applies whether the run ends after phase 1 or phase 2.
If axial coding ran, list the dimensions you wrote and say for each whether you reused, extended, or created its annotation config — the rubric is the user's to weigh in on. Link the dimensions to the project's configuration page, <endpoint>/projects/<project-node-id>/config, which lists that project's annotation configs next to its annotations — not the instance-wide annotation settings page, which mixes in every other project's configs.
Share Phoenix UI links with the user: one per level — span, trace, session — that actually carries this run's notes or annotations, filtered to the run's work. Skip levels with none. Each tab reads its filter from its own search param; an unrecognized or misspelled param is silently dropped, leaving an unfiltered table.
Filter on the coding annotation identifier — annotation accessors expose .identifier alongside .label, .score, and .explanation — so each link shows exactly this run's notes and axial annotations. Add one <annotation-name> clause per dimension written at that level, joined with or; drop them if axial coding did not run:
| Level annotated | Tab and search param | Filter expression |
|---|---|---|
| span | /spans?spanFilterCondition= | annotations['note'].identifier == '<id>' or annotations['<annotation-name>'].identifier == '<id>' |
| trace | /traces?traceFilterCondition= | trace_annotations['note'].identifier == '<id>' or trace_annotations['<annotation-name>'].identifier == '<id>' |
| session | /sessions?sessionFilterCondition= | session_annotations['note'].identifier == '<id>' or session_annotations['<annotation-name>'].identifier == '<id>' |
URL-encode each expression into its tab's param:
<endpoint>/projects/<project-node-id>/<tab>?<param>=<encoded-expression>When citing an individual finding, link directly to the annotated entity as well as sharing the filtered tables. For a trace, use <endpoint>/projects/<project-node-id>/traces/<otel-trace-id>. For a span, use that trace URL with selectedSpanNodeId=<span-node-id> so the annotated span opens selected. Resolve the span's Relay node ID and containing OpenTelemetry trace ID from the fetched data; the selection parameter does not accept an OpenTelemetry span ID. Preserve existing search parameters such as timeRangeKey=30d and URL-encode the added value.
Discarding the run — only with the user's explicit confirmation, since it is destructive. For each of trace, span, and session, delete the project's annotations filtered to the coding annotation identifier; this removes every dimension's labels at once, since they share the identifier. The server requires an explicit delete-all flag (or a time bound) to authorize the sweep; the identifier filter narrows but never authorizes on its own. Then remove $NOTES_SIDECAR and $AXIAL_SIDECAR. Each per-kind delete removes notes and axial annotations together because they share the underlying annotation table.
© Arize-ai, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in .agents/skills/phoenix-error-analysis of Arize-ai/phoenix.
Open the folder on GitHubat commit 3383f07
Phoenix Error Analysis next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Phoenix Error Analysis this skillArize-ai/phoenix | 12k | — | ~6.4k | Automated safety check: Pass | Apache-2.0 | |
| LLM Trace Review Interfaceai-evals-course/evals-skills | 1.5k | — | ~1.4k | Automated safety check: Pass | Apache-2.0 | |
| Phoenix LLM ObservabilityOrchestra-Research/AI-Research-SKILLs | 13k | 2 repos | ~2.9k | Automated safety check: Pass | MIT | |
| Phoenix CLIgithub/awesome-copilot | 40k | 1 repos | ~4k | Automated safety check: Pass | Apache-2.0 | |
| Error Analysisyonatangross/orchestkit | 288 | — | ~3.6k | Automated safety check: Notes | MIT | |
| Failproof AI SDK IntegrationFailproofAI/failproofai | 5.3k | — | ~6k | Automated safety check: Pass | Custom licence |
ai-evals-course/evals-skills
Builds a browser-based annotation page for reviewing LLM traces one at a time with pass/fail labels, notes and saved results, tailored to your data.
Orchestra-Research/AI-Research-SKILLs
Sets up Arize Phoenix to trace, evaluate and monitor LLM applications, with instrumentation for OpenAI, LangChain and LlamaIndex and a self-hosted server.
github/awesome-copilot
Debug LLM applications using the Phoenix CLI. An agent skill from github/awesome-copilot.
yonatangross/orchestkit
Evals-first error analysis for LLM apps: clusters real Langfuse or JSONL traces into a human-confirmed failure taxonomy with counts, then recommends binary pass/fail evals for recurring named modes.
FailproofAI/failproofai
Helps instrument a custom Python or TypeScript agent to record events for Failproof AI, verify what gets written, and run an evaluator worker that scores the runs.
github/awesome-copilot
Build and run evaluators for AI/LLM applications using Phoenix.
Arize-ai/phoenix
A skill your agent uses when working with Harbor's harbor exec CLI workflow: compiling files, directories, or globs into Harbor tasks; running map jobs; configuring artifacts and existence-only…
Arize-ai/phoenix
Build and maintain documentation sites with Mintlify. An agent skill from Arize-ai/phoenix.
Arize-ai/phoenix
Frontend development guidelines for the Phoenix AI observability platform.
Arize-ai/phoenix
Write efficient GraphQL queries against the Phoenix API. An agent skill from Arize-ai/phoenix.
Arize-ai/phoenix
Backend development guide for the Phoenix AI observability platform (Strawberry GraphQL, SQLAlchemy async, FastAPI).
Arize-ai/phoenix
Conventions for creating, modifying, and reviewing production-faithful Storybook stories in the Phoenix frontend (js/app/stories, js/app/.storybook).
Categories
Find out what is going wrong in LLM or agent traffic by reading sampled Phoenix traces, spans, or sessions, writing free-form notes (open coding), then grouping the notes into a few narrow…. Phoenix Error Analysis is an agent skill from Arize-ai/phoenix. Find out what is going wrong in LLM or agent traffic by reading sampled Phoenix traces, spans, or sessions, writing free-form notes (open coding), then grouping the notes into a few narrow annotations, one per failure dimension with a small label set and counts, that pick eval targets and fix priorities (axial coding).
Phoenix Error Analysis fits situations like: whats going wrong with this agent; I just instrumented my app; where do I start; review these traces.
Run `npx skills add Arize-ai/phoenix --skill phoenix-error-analysis -a claude-code`. Or copy the skill folder (.agents/skills/phoenix-error-analysis in Arize-ai/phoenix) into .claude/skills/phoenix-error-analysis in your project. Claude Code loads it when a task matches its description.
Run `npx skills add Arize-ai/phoenix --skill phoenix-error-analysis -a codex`. Or copy the skill folder (.agents/skills/phoenix-error-analysis in Arize-ai/phoenix) into .agents/skills/phoenix-error-analysis in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add Arize-ai/phoenix --skill phoenix-error-analysis -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/phoenix-error-analysis, .gemini/skills/phoenix-error-analysis, .github/skills/phoenix-error-analysis and .opencode/skills/phoenix-error-analysis in your project.
SKILL.md names no scripts, command-line tools or credentials: Phoenix Error Analysis is instructions for the agent only.
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Phoenix Error Analysis is published under the Apache-2.0 licence (declared in SKILL.md). It allows redistribution, so the full SKILL.md is shown on this page.
About 6.4k tokens (SKILL.md is roughly 26k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Phoenix Error Analysis: LLM Trace Review Interface (ai-evals-course/evals-skills, 1.5k stars), Phoenix LLM Observability (Orchestra-Research/AI-Research-SKILLs, 13k stars), Phoenix CLI (github/awesome-copilot, 40k stars) and Error Analysis (yonatangross/orchestkit, 288 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
Arize-ai (a GitHub organization) maintains it in Arize-ai/phoenix, which has 11,738 GitHub stars. The repository holds 39 skills in this directory. The repository was last updated on October 7, 2026.
Source: Arize-ai/phoenix on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.