Agent skill

Agent Observability Trace Rca

by datadog-labs in datadog-labs/agent-skills

Root cause analysis on production LLM traces. An agent skill from datadog-labs/agent-skills.

MITAuto-check passedDevelopment

Install Agent Observability Trace Rca

skills CLI
$ npx skills add datadog-labs/agent-skills --skill agent-observability-trace-rca -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install datadog-labs/agent-skills agent-observability-trace-rca --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/datadog-labs/agent-skills.git skills-src && mkdir -p .claude/skills && cp -r skills-src/agent-observability/agent-observability-trace-rca .claude/skills/agent-observability-trace-rca && rm -rf skills-src

Use ~/.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/

Facts

Skill name
agent-observability-trace-rca
GitHub stars
177
Token cost
~10k tokens
SKILL.md length
4,343 words
Files
7
Skills in repo
38
Repo updated
First seen
Licence
MIT

At a glance

Root cause analysis on production LLM traces. An agent skill from datadog-labs/agent-skills.

  • Works in 9 steps: Resolve Inputs & Infer Mode → Find Problematic Spans → 5: Determine App Profile & Where the… → …
  • User says whats wrong with my app
  • SKILL.md covers Backend, Methodology, Usage and Inputs, plus 5 more sections
  • Runs Python scripts from its folder; calls claude; reaches mcp.datadoghq.com

What it does

Agent Observability Trace Rca is an agent skill from datadog-labs/agent-skills. Root cause analysis on production LLM traces. Diagnoses why an LLM application is failing — works from eval judge verdicts, runtime errors, or structural anomalies depending on what signals are present. Walks the span tree from symptom to root cause. Use when user says "what's wrong with my app", "why is my eval failing", "analyze errors", "root cause analysis", "diagnose failures", or wants to understand production failure patterns.

Its SKILL.md is about 10k tokens, which your agent loads only when the skill is triggered. The skill folder holds 9 other files (for example `evals/__init__.py`, `evals/data/llm_obs_trace_rca_v1.json` and `evals/evaluator.py`).

It sits in Development, covering Root cause analysis and Observability. It works with Model Context Protocol, Bash and Datadog. The repository describes itself as: Public repository for Datadog Agent Skills. The licence is MIT.

When your agent uses it

  • User says whats wrong with my app
  • Why is my eval failing
  • Root cause analysis
  • Diagnose failures

Example prompts

  • “s wrong with my app”
  • “why is my eval failing”
  • “analyze errors”
  • “/agent-observability-trace-rca”

Requirements

  • Python 3

Workflow steps

9 steps, taken from the step headings in SKILL.md.

  1. Resolve Inputs & Infer Mode
  2. Find Problematic Spans
  3. 5: Determine App Profile & Where the Root Cause Lives
  4. Open Coding — Initial Failure Categorization
  5. Axial Coding — Refine Failure Taxonomy
  6. Root Cause Analysis — Navigate from Symptom to Root Cause
  7. Generate Recommendations
  8. Compile RCA Report
  9. Post-Analysis Actions

What it can do on your machine

Read from SKILL.md and the folder at commit 5b40c73. It shows what the files ask for, not the result of running them.

  • Tool permissions

    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.

  • Runs code

    Ships script files (Python), which the agent can run.

    Shell commands in SKILL.md call:

    • claude

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    Hosts in commands or code, which the agent is likely to contact:

    • mcp.datadoghq.com

    Also links to:

    • docs.datadoghq.com

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Agent Observability Trace Rca loads about 10k tokens when it runs. Until then it costs about 117 tokens; SKILL.md has 4,343 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~117
When it runs · the whole SKILL.md, loaded when a task matches
~10k

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.

Safety

Auto-check passed

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.

SKILL.md

The full file from datadog-labs/agent-skills at commit 5b40c73, republished under its MIT licence (© datadog-labs). 4,343 words, ~10,208 tokens.

Download SKILL.mdSave it as .claude/skills/agent-observability-trace-rca/SKILL.md (or your agent's skills folder). This skill also uses 6 other files; get the full folder from GitHub.
name
agent-observability-trace-rca
description
Root cause analysis on production LLM traces. Diagnoses why an LLM application is failing — works from eval judge verdicts, runtime errors, or structural anomalies depending on what signals are present. Walks the span tree from symptom to root cause. Use when user says "what's wrong with my app", "why is my eval failing", "analyze errors", "root cause analysis", "diagnose failures", or wants to understand production failure patterns.

Backend

Detection — At the start of every invocation, before taking any action, determine which backend to use:

  1. If the user passed --backend pup anywhere in their invocation → use pup mode immediately, regardless of whether MCP tools are present. Skip steps 2–4.
  2. Check whether MCP tools are present in your active tool list. The canonical signal is whether mcp__datadog-llmo-mcp__list_llmobs_evals appears in your available tools.
  3. If MCP tools are present → use MCP mode throughout. Call MCP tools exactly as named in this skill's workflow sections.
  4. If MCP tools are absent → check whether pup is executable: run pup --version via Bash. A JSON response containing "version" confirms pup is available.
  5. If pup responds → use pup mode throughout. Translate every MCP tool call to its pup equivalent using the Tool Reference appendix at the bottom of this file.
  6. If neither is available → stop and tell the user:

    "Neither the Datadog MCP server nor the pup CLI is available. Connect the MCP server (claude mcp add --scope user --transport http datadog-llmo-mcp 'https://mcp.datadoghq.com/api/unstable/mcp-server/mcp?toolsets=llmobs') or install pup."

--backend pup is accepted anywhere in the invocation arguments and is stripped before passing remaining args to the skill logic.

pup invocation rules:

  • Invoke via Bash: pup llm-obs <subcommand> [flags]
  • pup always outputs JSON. Parse directly — no content-block unwrapping (unlike MCP results, which may wrap JSON in [{"type": "text", "text": "<json>"}]).
  • If pup returns an auth error, tell the user to run pup auth login and stop.
  • Parallelization: issue multiple Bash tool calls in a single message (one pup command per call).
  • Time flags: pup accepts bare duration strings (1h, 7d, 30m) and RFC3339 timestamps. Do not use now--prefixed strings — strip the prefix when converting from a skill --timeframe argument: now-7d → 7d, now-24h → 24h, now-30d → 30d.
  • --summary on pup llm-obs spans search strips payload fields to essential metadata only. Use it in bulk/search phases where content is not needed.

Invocation ID: At the very start of each invocation, before any MCP tool call, generate an 8-character hex invocation ID (e.g., 3a9f1c2b). Keep it constant for the entire invocation.

Intent tagging: On every MCP tool call, prefix telemetry.intent with skill:agent-observability-trace-rca[<inv_id>] — followed by a description of why the tool is being called. On the first MCP tool call only, use skill:agent-observability-trace-rca:start[<inv_id>] — instead (note the :start suffix). Example first call: skill:agent-observability-trace-rca:start[3a9f1c2b] — Phase 0: discover configured evals for task-cruncher to infer analysis mode

Agent Observability Trace RCA — Root Cause Analysis from Production LLM Traces

Diagnose why an LLM application is failing by searching production traces and walking the span tree from symptom to root cause. The skill automatically selects the best analysis mode based on available signals:

ModeSignalWhen auto-selected
Eval SignalLLM judge verdicts and reasoning (pass/fail rates, scoring)Evaluators are configured for the app
Error SignalRuntime errors (@status:error, error types, stack traces)No evals configured, or user explicitly asks about errors/crashes
GenericStructural anomalies (latency, agent loops, retrieval misses)Explicit mode=generic override, or no strong signal found in Phase 1

The mode is announced (never asked) in the first user-facing output with a one-line override hint.

Methodology

Resolve → Search → Observe → Open Coding → Axial Coding → Root Cause Navigation → Recommendations

Usage

What's wrong with <ml_app> over the last <timeframe>
Why is <ml_app> failing today
Analyze eval failures for <eval_name> on <ml_app>
Look at the errors on <ml_app> over the last <timeframe>
Root-cause low scores on <eval_name>

Inputs

InputRequiredDefaultDescription
ml_appYes (or eval_name)—The application to analyze.
eval_nameNo—One or more evaluators to focus on. Implies Eval Signal mode. Pass a list for multi-eval analysis.
timeframeNonow-24hHow far back to look.
modeNoinferredExplicit mode override: eval, errors, generic. Skips inference entirely.
failure_filterNo—Narrowing scope: "errors" (routes to Error Signal path), "high latency" (post-fetch duration sort), "low scores on <eval>" (promotes to eval_name), a tool name or span name (@name:<x> query).

If neither ml_app nor eval_name is provided, ask the user.

Available Tools

Eval discovery & overview
ToolPurpose
list_llmobs_evalsDiscover all configured evals for an ml_app. Used in Phase 0 mode inference.
get_llmobs_eval_aggregate_statsPass/fail rate or score distribution for an eval over a time window.
get_llmobs_evaluatorFull evaluator config: prompt template, assessment criteria, span filter, sampling, provider. Use instead of the deprecated get_llmobs_eval_config.
Trace & span exploration
ToolPurpose
search_llmobs_spansFind spans by tags, span kind, status, query syntax. Paginate with cursor. Entry point for Phase 1.
get_llmobs_span_detailsMetadata, evaluations (scores, labels, reasoning), status, error fields, duration, and content_info map showing available fields + sizes.
get_llmobs_span_contentActual content for a span field. Supports JSONPath via path param for targeted extraction.
get_llmobs_traceFull trace hierarchy as span tree with span counts by kind.
find_llmobs_error_spansAll error spans in a trace with error type, message, stack, and propagation context.
expand_llmobs_spansLoad children of collapsed trace nodes.
get_llmobs_agent_loopChronological agent execution timeline (LLM calls, tool invocations, decisions). May return empty — see Phase 4b fallback.
Key get_llmobs_span_content patterns
FieldPathWhat you get
messages$.messages[0]System prompt (first message, usually system role)
messages$.messages[-1]Last assistant response
messages(no path)Full conversation including tool calls
input / output—Span I/O
documents—Retrieved documents (RAG apps)
metadata—Custom metadata (prompt versions, feature flags, user segments)
How to use search_llmobs_spans

Always include @ml_app:"<ml_app>" in the query string — the structured ml_app parameter is unreliable and can return spans from other apps. Do not rely on the structured parameter alone.

Useful query fragments — combine with space (AND):

GoalQuery
Errors only@status:error
Eval is present on the span@evaluations.custom.<eval_name>:* (presence only — pass/fail is read from get_llmobs_span_details, not the query)
A specific tool by name@name:<tool_name>

Dedicated params (span_kind, root_spans_only, ml_app) work alongside query, but query takes precedence over tags.

Parallelization rules
  1. get_llmobs_span_details: Group span_ids by trace_id, chunk each trace's span_ids into batches of at most 20. Issue ALL chunks for a page in a single message.
  2. get_llmobs_span_content: Each call is independent — always issue ALL in a single message.
  3. get_llmobs_trace / find_llmobs_error_spans / get_llmobs_agent_loop: Parallelize across different traces in a single message.
  4. Pipeline parallelism: Start get_llmobs_span_details for page 1 results immediately — don't wait to collect all pages.

Analysis Workflow

Output discipline: Phases 0–5 are internal analysis. The only user-facing outputs during these phases are the Phase 1 Signal Summary and the mandatory checkpoints at Phases 2 and 3. Do NOT narrate reasoning, summarize intermediate findings, or output Phase 4 deep-dive results as prose. All detailed findings go exclusively into the Phase 6 report.


Phase 0: Resolve Inputs & Infer Mode

First: check for classification context. Scan the conversation for a # Session Classification Summary header. If found → enter Step 0S below and skip all remaining Phase 0 steps and Phase 1 entirely.

Step 0S — Extract Failure Bucket from Classification Output

The canonical handoff format is the Per-Unit Details table inside the # Session Classification Summary section. Extract one row per unit:

FieldSource
trace_idLink URL in the ID column: parse the trace_id= or session_id= query parameter from the link href
verdictVerdict column
failure_modeFailure Mode column (none for passing rows)
detailReason column — use as the Phase 2 reasoning input (same role as eval judge reasoning or error messages)
app_typeFrom the # Session Classification Summary header line (e.g. Root span kind: agent) — default LLM if absent

Failure bucket = all rows where verdict is no or partial.

  • < 5 entries → note low confidence, proceed anyway.
  • Empty → report "No failures found in the classification output" and stop.

Present this overview before proceeding:

## Classification Overview (from agent-observability-session-classify)

**ml_app**: <from summary header>  |  **Classified**: N  |  **Failures (no+partial)**: F  |  **Pass rate**: X%

| Failure Mode | Count |
|---|---|
...

Proceeding to Phase 2 using F failure traces. Mode inference bypassed — classification verdict is the signal.

Then skip Phase 1 and jump directly to Phase 2. Carry forward:

  • Phase 2 reasoning input: (trace_id, span_id, detail) tuples — same structure as eval reasoning or error messages
  • Phase 4 navigation: use app_type from each trace block to choose the span navigation strategy
  • Phases 2–7: run completely unchanged — the failure bucket structure is identical regardless of source

Standard resolution (no classification context):

  1. If neither ml_app nor eval_name provided → ask the user. If eval_name is provided but ml_app is not → also ask for ml_app (eval names are not globally unique; without it, span searches return results from all apps sharing the eval name).
  2. If timeframe not provided → default to now-24h.
  3. Resolve failure_filter (before mode inference):
    • "errors" → force Error Signal mode
    • "low scores on <eval>" → treat as eval_name=<eval>, then continue inference
    • "high latency" → note for Phase 1 (sort by duration post-fetch); continue inference
    • Tool/span name → note as @name:<x> query fragment for Phase 1; continue inference
  4. Resolve mode (skip if mode was explicitly provided):
    • eval_name given → Eval Signal
    • User explicitly mentioned errors/exceptions/crashes → Error Signal
    • Otherwise → call list_llmobs_evals_by_ml_app(ml_app):
      • Evals returned → Eval Signal
      • No evals → Error Signal (announce auto-selection in Phase 1)
  5. When eval_name is multi-valued, note for Phase 1: run parallel per-eval searches and merge+dedup by (trace_id, span_id).

Phase 1: Find Problematic Spans

Three mode-specific paths. All end with a Signal Summary that labels the mode and includes a one-line override hint.

Mode switch handling: At any checkpoint, if the user says "switch to [error|eval|generic] mode", re-enter Phase 1 with the new mode. Phase 0 inputs do not re-resolve.

Auto-pivot: If the selected mode finds no data (0 evals configured, 0 error spans in timeframe), announce the pivot to Generic and proceed — do not stop and ask.


Eval Signal path
Step 1a: Eval overview (parallel)

For each eval, call both in a single parallel batch:

  • get_llmobs_eval_aggregate_stats(eval_name, from, to)
  • get_llmobs_evaluator(eval_name)

Interpret aggregate stats:

  • total_count == 0 → Note "no data." Skip this eval (or pivot to Generic if it's the only one).
  • Boolean pass_rate == 1.0 → Note "100% pass." Skip unless it's the only eval.
  • Boolean with failures → Note counts and pass_rate. Continue.
  • Score with assessment criteria → Note distribution and pass/fail counts. Continue.
  • Score WITHOUT assessment criteria → Infer failures: bottom quartile, or below median if bimodal. Label as "inferred failures" in report.
  • Categorical with assessment criteria → Note top_values and pass/fail. Continue.
  • Categorical WITHOUT assessment criteria → Infer from context (e.g., "error", "incomplete", "off_topic" are likely failures). Ask user if genuinely ambiguous.

Interpret eval config:

  • Config returned (custom) → Store prompt_template, assessment_criteria, parsing_type, output_schema.
  • Config nil (OOTB) → Note prompt is not inspectable.

Calibration cross-check: When two evals share a name prefix but differ in type (e.g. foo-boolean and foo-score), compare their pass rates on overlapping spans. A discrepancy >20% is an Evaluator Calibration Discrepancy — flag it in the report.

Step 1b: Collect failure spans

For each eval:

  1. search_llmobs_spans(query="@evaluations.custom.<eval_name>:*", from, limit=50). When multi-valued, issue one search per eval in parallel — merge result sets, dedup by (trace_id, span_id).
  2. Paginate until ≥15–20 failures OR no more pages. Cap at 200 spans total.
  3. get_llmobs_span_details per trace_id batch (follow Parallelization Rules).
  4. Extract per row: assessment, value, reasoning, span_id, trace_id, span_kind, content_info.
  5. Separate into pass/fail buckets using thresholds from Step 1a.

JSON-type eval fallback: If @evaluations.custom.<eval_name>:* returns 0 spans but get_llmobs_eval_aggregate_stats confirmed total_count > 0, the eval is JSON-type and scores are not indexed on this field. Fall back to: search by the span name or span kind that the eval targets (check get_llmobs_evaluator for the span filter), then inspect output payloads for JSON verdict fields via get_llmobs_span_content(field="output").

Step 1c: Signal Summary (Eval Signal)
## Signal Summary: `{ml_app}` · Eval Signal
(Inferred from {N} configured eval(s). Say `switch to error mode` or `switch to generic mode` to change.)

**Timeframe**: {from} → {to}

| Eval | Type | Total | Pass Rate | Status |
|------|------|------:|:---------:|--------|
| eval_1 | boolean | 4,891 | 37.3% | ⚠ Investigating |
| eval_2 | score | 1,200 | — (inferred threshold) | ⚠ Investigating |
| eval_3 | boolean | 500 | 99.2% | ✓ Healthy |

**Collected**: {pass_count} passing, {fail_count} failing.

For a single eval, collapse to a single-line header instead of a table.


Error Signal path
Step 1a: Sample error spans

search_llmobs_spans(query="@ml_app:\"<ml_app>\" @status:error", from=timeframe, limit=50). Paginate until ≥30 error spans or no more pages.

Step 1a.5: Soft error scan

MCP tool spans sometimes report @status:ok but carry "isError": true in their output payload — these are invisible to @status:error queries and can outnumber hard errors.

Call search_llmobs_spans(query="@ml_app:\"<ml_app>\" @status:ok", span_kind="tool", from=timeframe, limit=20). For a sample of 5–10 results, call get_llmobs_span_content(field="output") in parallel. If any payloads contain "isError": true, add MCP soft errors as a separate row in the error frequency table with the note: (status:ok but isError:true in payload — not queryable via @status:error).

Step 1b: Group by error type

Group spans by error_type tag → frequency table. If error_type tag is absent on some spans, supplement with the error.type field from get_llmobs_span_details (fetched in Step 1d).

Step 1c: Fetch stack traces (parallel)

For the top 3–4 error types by count, pick 2–3 representative trace IDs each. Call find_llmobs_error_spans(trace_id) in parallel across all selected traces. Extract:

  • Error message and stack trace
  • Origin span kind and name
  • Whether errors propagate from children to parents (cascade) or are isolated
Step 1d: Fetch span details

get_llmobs_span_details on representative spans for each error type (follow Parallelization Rules). Extract content_info, span_kind, duration.

Step 1e: Signal Summary (Error Signal)
## Signal Summary: `{ml_app}` · Error Signal
(No evals configured — analyzing runtime errors. Say `switch to eval mode` or `switch to generic mode` to change.)

**Timeframe**: {from} → {to}  |  **Total error spans sampled**: {N}

| Error Type | Spans | Cascade? | Origin Span Kind |
|------------|------:|:--------:|-----------------|
| TimeoutError | 42 | Yes | tool |
| APIError 429 | 18 | No | tool |
| ValueError | 7 | No | llm |
| MCP soft errors (isError:true) | 23 | No | tool |

Generic path
Step 1a: Eval health check (when evals are configured)

If list_llmobs_evals returned evals in Phase 0, call get_llmobs_eval_aggregate_stats for each enabled eval in parallel. Flag any enabled eval with total_count: 0 as Broken Eval Configuration — include in the Signal Summary anomaly table as a High severity row.

search_llmobs_spans(query="@ml_app:\"<ml_app>\"", root_spans_only=true, from=timeframe, limit=50). Apply failure_filter narrowing if present (tool/span name → @name:<x> query; "high latency" → sort result set by duration after Step 1c). Paginate until ≥30 spans.

Step 1c: Fetch span details

get_llmobs_span_details per trace_id batch.

Step 1d: Rank by structural anomalies

Partition spans using heuristics:

  • Top decile by duration (latency outliers)
  • Agent spans with >N tool/LLM iterations (long-running loops)
  • Retrieval spans returning 0 documents (RAG miss)
  • Workflow spans whose child set is missing an expected step (compare against median child layout)
  • Token efficiency: Check if non_cached_input_tokens ≈ input_tokens across LLM spans. If the app has stable system prompts (>1k tokens) and cache hit rate is 0%, flag as High severity — enabling cache_control: ephemeral on the system prompt would cut input token costs by 60–90%
Step 1e: Signal Summary (Generic)
## Signal Summary: `{ml_app}` · Generic
(Analyzing structural anomalies. Say `switch to eval mode` or `switch to error mode` to change.)

**Timeframe**: {from} → {to}  |  **Sampled**: {N} root spans

| Anomaly Type | Count |
|---|:---:|
| Latency outliers (>p90) | 12 |
| Long agent loops (>8 iterations) | 5 |
| RAG retrieval misses | 3 |
| Zero prompt cache utilization | All LLM spans |
| Broken eval configurations | 2 |

Phase 1.5: Determine App Profile & Where the Root Cause Lives

Inspect content_info and span_kind across collected spans. Drives Phase 4 strategy.

App profile (from content_info):

SignalApp profilePhase 4 strategy
content_info has messagesLLM/chat appExtract system prompt via messages[0], check conversation flow
content_info has documentsRAG appCheck retrieval quality alongside LLM output
Trace contains agent span kindAgent appTry get_llmobs_agent_loop first; if it returns empty use child-span reconstruction (see Phase 4b)
messages.count > 10Long conversationCheck for context overflow
content_info has metadataHas custom metadataCheck for clustering by metadata values (prompt version, feature flags)

LLM Experiments traces: If root spans have span_kind: experiment and carry input, output, and expected_output structured fields, you are looking at a Datadog LLM Experiments trace. Each span represents one dataset record run. Read quality signal from the root span's input/output/expected_output fields via get_llmobs_span_content — not from LLM sub-span messages, which may contain stub or placeholder content. Evaluations attached to experiment spans are computed by the Experiments framework at run time and may not be registered as online Datadog evaluators (get_llmobs_evaluator will return 404 for them).

Where the root cause likely lives — by symptom span kind:

Symptom span kindSymptom looks likeBut root cause is often in...
llmBad LLM response (eval flagged, wrong output)Parent agent (bad instructions), sibling retrieval (bad context), sibling tool (bad data)
agentBad orchestrationChild spans (wrong tool calls, bad routing), full agent loop
toolBad tool resultParent LLM (passed wrong parameters), tool implementation
workflowBad overall outputChild sub-spans (which step first deviated?)
retrievalBad retrievalQuery construction (parent), index/embedding config (outside trace)

Key insight: The signal — eval verdict, error message, latency outlier — flags one span in isolation. It's a symptom report, not a diagnosis. The root cause often lives in a different span: a parent that gave bad instructions, a sibling that provided bad context, or a child that made a wrong decision. Phase 4 navigates the tree to find it.


Show full SKILL.md (1,822 more words)Show less
Phase 2: Open Coding — Initial Failure Categorization

Goal: Read per-row evidence and propose initial, concrete failure categories. Pool all problematic rows together — categories should describe app behaviors, not which signal flagged them.

Per-row "reasoning input" by mode:

  • Eval Signal: judge assessment + reasoning from get_llmobs_span_details
  • Error Signal: error message + stack trace excerpt from find_llmobs_error_spans
  • Generic: one-line description of the structural anomaly that flagged the row

Shortcuts:

  • < 15 problematic rows: Combine Phases 2 and 3 into one pass. Still produce the checkpoint.
  • > 80% share the same reasoning/error/symptom: Skip to Phase 4 with the dominant pattern. Still output checkpoint.
  • > 50 problematic rows: Sample ~50, build taxonomy, then spot-check 10–15 more.
  1. Use per-row signal from Phase 1 — do NOT re-fetch. Only call get_llmobs_span_content(field="input"/"output") for spans where the reasoning is insufficient (generic, empty, or just a stack trace with no app context).

  2. If eval config is loaded (Eval Signal), distinguish early:

    • App failures: Output genuinely violates the eval's criteria
    • Eval failures: Output seems reasonable but eval criteria are too strict/ambiguous
  3. Each pattern must be specific: "Agent called search instead of calculator for price computation" — NOT "tool issue."

MANDATORY CHECKPOINT
**Open coding**: {N} problematic rows → {K} initial categories: {Category1} ({count}), {Category2} ({count}), ...

Phase 3: Axial Coding — Refine Failure Taxonomy

Goal: 3–8 final categories, ranked by impact.

  1. Merge: Categories with < 3 occurrences → parent category or drop as noise.
  2. Split: Categories with > 30% of failures → more specific sub-categories. Pull additional span content if needed.
  3. Validate: 2–3 representative examples per category confirm the label fits.
  4. Rank: priority = count × severity (severity: high / medium / low).
MANDATORY CHECKPOINT
**Axial coding**: {merges/splits/drops}. Final categories:
1. {Category} ({count}, {pct}%) — {severity}
2. ...

Phase 4: Root Cause Analysis — Navigate from Symptom to Root Cause

Goal: The signal flagged a span. That's the symptom. Navigate the trace tree to find the actual root cause — it's often in a different span.

For each of the top 3 categories, pick 2–3 representative traces:

Step 4a: Trace structure + errors (parallel)

For each representative trace, call in a single message:

  • get_llmobs_trace(trace_id) — span hierarchy; locate the symptom span and its parent/siblings/children
  • find_llmobs_error_spans(trace_id) — check for runtime errors anywhere in the trace

Runtime vs behavioral: If errors exist on or near the symptom span, the root cause may be a runtime failure rather than a behavioral one. Check this first.

Distributed trace fallback: If get_llmobs_trace returns "cannot find parent" or an empty span list (common in Ray-based or multi-process execution), reconstruct the trace manually using get_llmobs_span_details on the span_ids collected in Phase 1, sorted by start_ms.

Step 4b: Navigate to the root cause (parallel)

Use the symptom span kind (from Phase 1.5). Issue ALL calls in a single message.

If symptom is on an llm span (most common):

  • get_llmobs_span_content(field="messages", path="$.messages[0]") on symptom span — system prompt
  • get_llmobs_span_content(field="messages") on symptom span — full context received
  • get_llmobs_span_content(field="documents") on sibling retrieval spans (if any)
  • get_llmobs_span_content(field="input") on sibling tool spans (if any)
  • get_llmobs_span_content(field="messages", path="$.messages[0]") on parent agent/workflow span

If symptom is on an agent span:

  • get_llmobs_agent_loop(trace_id, span_id) — full decision timeline (try first; if it returns 0 iterations, use the fallback below)
  • get_llmobs_span_details on child spans — sort by start_ms to reconstruct the execution timeline
  • get_llmobs_span_content(field="input"/"output") on child spans that look wrong

Agent loop fallback (when get_llmobs_agent_loop returns 0 iterations): Reconstruct the timeline from get_llmobs_span_details results sorted by start_ms. Group by span_kind to identify LLM → tool → LLM sequences. This fallback is frequently needed — get_llmobs_agent_loop returns empty for many apps.

If symptom is on a tool span:

  • get_llmobs_span_content(field="input") on symptom span — what parameters was it called with?
  • get_llmobs_span_content(field="messages") on parent LLM span — did the LLM construct the call correctly?

If symptom is on a workflow span:

  • get_llmobs_span_details on all child spans — find which step first deviated
  • get_llmobs_span_content(field="input"/"output") on the deviating child

Always also fetch:

  • get_llmobs_span_content(field="metadata") on the symptom span — clustering signals (prompt version, feature flags)
Step 4c: Diagnose — from symptom to root cause

For each category, trace the causal chain:

  1. Symptom — what the signal flagged (eval reasoning, error message, anomaly note). The signal only saw one span in isolation — its reasoning may be shallow.
  2. Trace context — what surrounding spans reveal (parent instructions, sibling data, child decisions).
  3. Root cause — the specific span and decision point where the failure originated. Often NOT the symptom span itself.

For suspected eval issues (Eval Signal, if config loaded): Compare eval criteria against evidence. Is the prompt ambiguous? Criteria too strict?

Root cause categories:

CategoryDescription
System Prompt DeficiencyInstructions unclear, missing, or contradictory — in symptom span OR its parent
Tool GapNeeded tool doesn't exist or parameters too coarse
Tool MisuseWrong tool called or wrong parameters — often visible in agent loop or parent LLM
Routing/Handoff ErrorWrong sub-agent selected (multi-agent systems)
Retrieval FailureRAG returned irrelevant or missing context — check sibling retrieval spans
Context OverflowCritical info lost due to context length
Upstream Data IssueA sibling or parent span provided bad data that cascaded to the symptom span
Runtime ErrorTool/API failure, timeout, exception — from find_llmobs_error_spans
Evaluator MiscalibrationEval criteria produce false positives/negatives (Eval Signal mode only)

Phase 5: Generate Recommendations

Goal: Concrete, actionable recommendations grounded in trace evidence. Actual text/code changes with before/after quotes from the trace — not generic advice.

Recommendation types: System Prompt Edit (quote actual prompt, provide before/after), Tool Gap/Misuse (reference agent loop steps), Routing/Handoff Fix, Retrieval Fix (show retrieved vs needed), Evaluator Prompt Edit (flag that eval changes need re-validation; Eval Signal only), Other.

When run in Claude Code with codebase access: Search the codebase for system prompt, tool definitions, or routing logic. Propose specific diffs. Always ask before modifying files.


Phase 6: Compile RCA Report

Write the full report following the Output Format below. This is the primary deliverable — output it directly in the chat.


Phase 7: Post-Analysis Actions

Do NOT take any action automatically. After presenting the report, ask the user what they'd like to do next:

  1. Save the report to agent-observability-rca-{ml_app}-{date}.md
  2. Apply fixes (if codebase is available)
  3. Deeper investigation of remaining categories
  4. Export to a Datadog notebook — in pup mode, use pup notebooks create to create the notebook and pup notebooks edit NOTEBOOK_ID --file /tmp/nb_cells.json to append sections (see Tool Reference)
  5. Re-run on an expanded time range (e.g. now-7d if current window was now-24h)

If the user chooses option 4, follow the notebook creation fallback pattern:

  1. Call mcp__datadog-mcp-core__create_datadog_notebook with:

    • name: Agent Observability RCA: {ml_app} ({mode}) — YYYY-MM-DD
    • type: report
    • time_span: 1w
    • cells: one cell per section (see Notebook Cell Structure below)
  2. If the MCP call fails, inspect the error before giving up:

    • Auth / permission error (401, 403) → stop and tell the user.
    • Field validation error (error message names a specific field) → fix that field and retry the MCP call once.
    • Any other error (binding, serialization, unexpected response) → fall back to pup:
      • Write the notebook payload to /tmp/nb_rca_{ml_app}.json as a full API envelope: {"data": {"attributes": {"name": "...", "time": {...}, "cells": [...]}, "type": "notebooks"}}
      • Run pup notebooks create --file /tmp/nb_rca_{ml_app}.json
      • If pup is not available either, render the full notebook content as markdown in chat so the user has it.
  3. After successful creation by either method, output the URL on its own line: RCA report exported to notebook: <url>

Print the URL prominently — if /eval-bootstrap runs next in the same session, it will detect this URL and offer to append the evaluator suite to the same notebook.

Notebook Cell Structure
CellContent
1 — OverviewStructured header (see Overview cell format below — follow it exactly)
2 — Signal SummaryMode-specific health table
3 — Failure TaxonomyTaxonomy table
4…N — Failure ModesOne cell per failure mode
N+1 — Action Plan + LimitationsAction plan table + bullet list

Notebook formatting rules (apply to every cell):

  • No triple-backtick code blocks — use blockquotes (>) for prompts/rubrics, inline code (`) for short values
  • Evidence as tables — not bullet lists
  • Tool inputs as tables — Argument | Wrong value passed | Correct approach
  • Action plan as a table — Priority | Action | Confidence | Impact

Output Format


Overview cell (notebook Cell 1 / report header)

The Overview cell must follow this exact structure. No prose paragraphs. No inline-numbered findings. App description is one sentence maximum.

## `{ml_app}`  ·  {Eval Signal | Error Signal | Generic}  ·  {timeframe}
**Date**: {YYYY-MM-DD}  |  **Profile**: {short app profile}  |  **Model**: `{model(s)}`

{One sentence: what does this app do?}

| Metric | Value |
|--------|-------|
{mode-appropriate rows — see below}

### Findings

- **{Finding 1}** (~{pct}%): one-line root cause description
- **{Finding 2}** (~{pct}%): one-line root cause description
- **{Finding 3}** (if present): one-line root cause description

### Recommendations

- **{Recommendation 1}**: specific next step tied to Finding 1
- **{Recommendation 2}**: specific next step tied to Finding 2

*Sample: {N} spans analyzed. Confidence: High | Medium | Low — {one-line reason if Medium or Low}.*

Mode-appropriate metric rows:

Eval Signal:

| Eval | `{eval_name}` ({type}) |
| Spans evaluated | {total_count} |
| Pass rate | {pass_rate}% ({pass_count} pass / {fail_count} fail) |
| Top failure mode | {name} (~{pct}%) |
| Evals configured | {N} |

Error Signal:

| Error spans | {N} confirmed |
| Top error type | `{type}` ({pct}%) |
| Affected operation | `{span_name}` |
| Cascade pattern | Isolated / Cascading |
| Evals configured | {N} (none = no quality signal) |

Generic:

| Spans sampled | {N} root spans |
| Top anomaly | {type}: {count} spans |
| Error spans | {N} (0 = structurally healthy) |
| Evals configured | {N} (none = no quality signal) |

Signal Summary Table

When entering from Step 0S (classification context), replace the Signal Summary table with:

## Classification Signal Summary

**Source**: agent-observability-session-classify  |  **ml_app**: {app}  |  **Signal**: content-only | content+evals

| Metric | Value |
|--------|-------|
| Traces classified | N |
| Failures in corpus (no+partial) | F |
| Pass rate | X% |
| Failure modes | list |

*Root cause analysis is based on per-trace classification verdicts, not automated eval judge reasoning.*

Otherwise, mode-specific — pick the appropriate variant:

Eval Signal — one row per eval:

EvalTypeTotalPass RateStatus
eval_1boolean4,89137.3%⚠ Investigating

Error Signal — one row per error type:

Error TypeSpansCascade?Origin Span Kind
TimeoutError42Yestool

Generic — one row per anomaly type:

Anomaly TypeCount
Latency outliers (>p90)12

Failure Taxonomy
#Failure ModeTraces%SeverityRoot Cause
1.........%HighTool Misuse

Failure Mode Sections (one per top 3–5 modes)
## Failure Mode N: [Name]

**Count**: {n} spans, {t} traces  |  **Severity**: High/Medium/Low  |  **Root Cause**: [Category]

[3–5 sentences: what goes wrong, when, what triggers it, causal chain.]

**Evidence**

{Use the mode-appropriate column set:}

Eval Signal — Trace | Judge verdict | What the trace revealed:
| Trace | Judge verdict | What the trace revealed |
|---|---|---|
| [69de86a7...](https://app.datadoghq.com/llm/traces?query=trace_id:{full_id}) | fail | Parent agent has no date format instruction |

Error Signal — Trace | Behavior | Version:
| Trace | Behavior | Version |
|---|---|---|
| [69de86a7...](https://app.datadoghq.com/llm/traces?query=trace_id:{full_id}) | 7 parallel calls, all 400 | v107624932 |

Generic — Trace | Anomaly | Signal:
| Trace | Anomaly | Signal |
|---|---|---|
| [69de86a7...](https://app.datadoghq.com/llm/traces?query=trace_id:{full_id}) | 94s, 12 tool calls | Latency outlier |

{For tool misuse — add a tool inputs table:}
**Tool inputs (100% of sampled calls)**

| Argument | Value passed (wrong) | Correct approach |
|---|---|---|
| `query` | `"monitor_id:123 group_status:alert"` | `"monitor_id:123"` (name/tag only) |

{For Eval Signal — add judge reasoning as a blockquote:}
> "{quoted judge reasoning}"

**Root cause**: [WHY this happens — specific span, parameter, or prompt.]

**Fix**:
  BEFORE: [actual text from trace]
  AFTER:  [proposed replacement]

**Impact**: Eliminates ~{n} spans / {timeframe}.

Prioritized Action Plan
PriorityActionConfidenceImpact
1Fix monitor_groups_search schema — add group_states paramHighEliminates ~21 spans/7d

When mode is Generic and no evals are configured, always append as the final action plan row:

| N | Configure at least one evaluator | High | Enables Eval Signal mode for future RCAs — app currently has no ongoing quality signal |


Limitations & Follow-ups

Bullet list of what needs more data or follow-up action.


Operating Rules

  • Ground in evidence: Every claim references span IDs with clickable trace links: [Trace {first_8}...](https://app.datadoghq.com/llm/traces?query=trace_id:{full_32_char_id}).
  • Root cause over symptom: "System prompt doesn't specify date format" not "model gave wrong answer."
  • Show your math: "47 failures (34%)" not "many failures."
  • Honest about uncertainty: < 5 examples = tentative. Flag it.
  • Anonymize PII: No emails or names. User/org IDs are fine.
  • MCP result parsing safety: Before writing any script that iterates over MCP tool results, inspect the raw structure first — check top-level keys and whether the payload is nested inside a content block (e.g. [{'type': 'text', 'text': '<json>'}]). Extract and json.loads() the inner payload if needed. Never assume MCP results are bare dicts or lists.

Tool Reference

This appendix applies only in pup mode. In MCP mode, use the tool names in the workflow sections directly.

Spans and traces
MCP Toolpup Command
search_llmobs_spans(query, ml_app, from, to, limit, cursor, root_spans_only, span_kind, summary)pup llm-obs spans search --query "@ml_app:A [other_filters]" [--from F] [--to T] [--limit N] [--cursor C] [--root-spans-only] [--span-kind K] [--summary] — always use --query "@ml_app:A" to filter by ml_app; the --ml-app A flag is unreliable and silently returns spans from other apps.
get_llmobs_span_details(trace_id, span_ids, from, to)pup llm-obs spans get-details --trace-id T --span-ids S1,S2,...
get_llmobs_span_content(trace_id, span_id, field, path)pup llm-obs spans get-content --trace-id T --span-id S --field F [--path P]
get_llmobs_trace(trace_id, include_tree)pup llm-obs spans get-trace --trace-id T [--include-tree]
get_llmobs_agent_loop(trace_id, span_id)pup llm-obs spans get-agent-loop --trace-id T [--span-id S]
find_llmobs_error_spans(trace_id)pup llm-obs spans find-errors --trace-id T
expand_llmobs_spans(trace_id, span_ids, max_depth, filter_kind)pup llm-obs spans expand --trace-id T --span-ids S1,S2,... [--max-depth N] [--filter-kind K]
Evaluators
MCP Toolpup Command
list_llmobs_evals()pup llm-obs evals list (filter by ml_app client-side)
list_llmobs_evals_by_ml_app(ml_app)pup llm-obs evals list-by-ml-app --ml-app A
get_llmobs_evaluator(eval_name)pup llm-obs evals get-evaluator EVAL_NAME
get_llmobs_eval_aggregate_stats(eval_name, ml_app, from, to)pup llm-obs evals get-aggregate-stats EVAL_NAME [--ml-app A] [--from F] [--to T]
Notebooks
MCP Toolpup Command
create_datadog_notebook(name, cells, ...)pup notebooks create --title "TITLE" --file /tmp/nb_cells.json — confirm exact flags with pup notebooks create --help
edit_datadog_notebook(id, cells, append_only=true)pup notebooks edit NOTEBOOK_ID --file /tmp/nb_cells.json (fetches current notebook, appends provided cells, writes back)

The cells file is a JSON array of cell objects:

json
[{"attributes": {"definition": {"type": "markdown", "text": "## Section\n\nContent."}}, "type": "notebook_cells"}]

© datadog-labs, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 6 other files in agent-observability/agent-observability-trace-rca of datadog-labs/agent-skills.

  • SKILL.md
  • evals/__init__.py
  • evals/data/llm_obs_trace_rca_v1.json
  • evals/evaluator.py
  • evals/example_config.json
  • evals/executor.py
  • evals/prompts/judge_rubric.txt

Open the folder on GitHubat commit 5b40c73

Compare with similar skills

Agent Observability Trace Rca 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.

Agent Observability Trace Rca compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Agent Observability Trace Rca this skilldatadog-labs/agent-skills177—~10kAutomated safety check: PassMIT
Datadog AnalysisPackmindHub/packmind317—~1.6kAutomated safety check: PassApache-2.0
AI Operationsmajiayu000/claude-skill-registry6661 repos~1.4kAutomated safety check: PassApache-2.0
UModel Root Cause Analysisalibaba/UnifiedModel412—~1.9kAutomated safety check: PassCustom licence
Frontmcp Observabilityagentfront/frontmcp146—~4.6kAutomated safety check: PassApache-2.0
Monte Carlo Performance Diagnosissickn33/agentic-awesome-skills47k1 repos~2kAutomated safety check: PassApache-2.0

Similar skills

  • Datadog Analysis

    PackmindHub/packmind

    Analyze Datadog error logs for Packmind production services (api-proprietary, frontend-proprietary), group them into patterns, root-cause against the codebase, and produce a structured bug report.

    317 GitHub stars~1.6k tokensUpdated today
    DevelopmentAuto-check passed
  • AI Operations

    majiayu000/claude-skill-registry

    Configure Harness AI-powered operations (AIDA) via MCP. An agent skill from majiayu000/claude-skill-registry.

    666 GitHub starsUsed in 1 repo~1.4k tokens
    DevOps & CloudAuto-check passed
  • UModel Root Cause Analysis

    alibaba/UnifiedModel

    Investigates a service incident to its root cause by querying a UModel object graph alongside metrics, logs, topology and recent deployments.

    412 GitHub stars~1.9k tokensUpdated 14 days ago
    DevOps & CloudAuto-check passed
  • Frontmcp Observability

    agentfront/frontmcp

    A skill your agent uses when adding tracing, structured logging, metrics, or monitoring to a FrontMCP server.

    146 GitHub stars~4.6k tokensUpdated yesterday
    DevOps & CloudAuto-check passed
  • Monte Carlo Performance Diagnosis

    sickn33/agentic-awesome-skills

    Diagnoses pipeline performance issues -- slow jobs, expensive queries, latency trends -- using Monte Carlo's cross-platform observability.

    47k GitHub starsUsed in 1 repo~2k tokens
    Data & AnalyticsAuto-check passed
  • Official

    Digs into why code is shaped the way it is by checking git history, pull requests and connected tools in parallel, then reporting a cited read on the tradeoffs.

    10k GitHub starsUsed in 9 repos~2.6k tokens
    DevelopmentAuto-check passed

More from datadog-labs/agent-skills

All 38 skills in this repo
  • Bootstrap a reproducible LLM Observability experiment through the Python ddtrace SDK or the Node dd-trace SDK.

    177 GitHub stars~2.3k tokensUpdated today
    Auto-check passed
  • Dd Account Setup

    datadog-labs/agent-skills

    Ensure the user has an authenticated Datadog account with a valid DDAPIKEY on the right region before any Datadog setup or instrumentation.

    177 GitHub stars~4.4k tokensUpdated today
    Auto-check: notes
  • Dd Orchestrator

    datadog-labs/agent-skills

    Entry point for Datadog onboarding. An agent skill from datadog-labs/agent-skills.

    177 GitHub stars~6.7k tokensUpdated today
    Auto-check passed
  • Dd Apm

    datadog-labs/agent-skills

    APM - install, onboard, instrument, enable, set up, configure, traces, services, dependencies, performance analysis, Data Streams Monitoring (DSM), queue lag, pipeline latency.

    177 GitHub stars~2k tokensUpdated today
    Auto-check passed
  • Agent Install

    datadog-labs/agent-skills

    Install the Datadog Agent on Kubernetes using the Datadog Operator — required before enabling Single Step Instrumentation (SSI), which automatically instruments applications for APM without code…

    177 GitHub stars~2.1k tokensUpdated today
    Auto-check: warnings
  • Dd AWS Integration

    datadog-labs/agent-skills

    Set up the Datadog AWS integration with Terraform - creates the cross-account IAM role Datadog assumes (external ID, no stored credentials), attaches the permission policies Datadog publishes, and…

    177 GitHub stars~6.8k tokensUpdated today
    Auto-check: notes

Questions about Agent Observability Trace Rca

What does Agent Observability Trace Rca do?

Root cause analysis on production LLM traces. An agent skill from datadog-labs/agent-skills. Agent Observability Trace Rca is an agent skill from datadog-labs/agent-skills. Root cause analysis on production LLM traces.

When should I use Agent Observability Trace Rca?

Agent Observability Trace Rca fits situations like: user says whats wrong with my app; why is my eval failing; root cause analysis; diagnose failures.

How do I install Agent Observability Trace Rca in Claude Code?

Run `npx skills add datadog-labs/agent-skills --skill agent-observability-trace-rca -a claude-code`. Or copy the skill folder (agent-observability/agent-observability-trace-rca in datadog-labs/agent-skills) into .claude/skills/agent-observability-trace-rca in your project. Claude Code loads it when a task matches its description.

How do I install Agent Observability Trace Rca in Codex?

Run `npx skills add datadog-labs/agent-skills --skill agent-observability-trace-rca -a codex`. Or copy the skill folder (agent-observability/agent-observability-trace-rca in datadog-labs/agent-skills) into .agents/skills/agent-observability-trace-rca in your project. Codex loads it when a task matches its description.

Can I use Agent Observability Trace Rca in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add datadog-labs/agent-skills --skill agent-observability-trace-rca -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/agent-observability-trace-rca, .gemini/skills/agent-observability-trace-rca, .github/skills/agent-observability-trace-rca and .opencode/skills/agent-observability-trace-rca in your project.

What does Agent Observability Trace Rca need to run?

Going by SKILL.md and its folder, Agent Observability Trace Rca needs Python for the scripts in its folder and the command-line tools its instructions call (claude). Our summary lists: Python 3.

Does Agent Observability Trace Rca access the network?

SKILL.md names 2 domains. In commands or code: mcp.datadoghq.com; the agent is likely to contact it when it follows the instructions. As links in the text: docs.datadoghq.com. This is read from the text; nothing was executed.

Is Agent Observability Trace Rca safe to install?

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.

What licence does Agent Observability Trace Rca use?

Agent Observability Trace Rca is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Agent Observability Trace Rca use?

About 10k tokens (SKILL.md is roughly 41k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Agent Observability Trace Rca?

Skills that share tags, products or a category with Agent Observability Trace Rca: Datadog Analysis (PackmindHub/packmind, 317 stars), AI Operations (majiayu000/claude-skill-registry, 666 stars), UModel Root Cause Analysis (alibaba/UnifiedModel, 412 stars) and Frontmcp Observability (agentfront/frontmcp, 146 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Agent Observability Trace Rca?

datadog-labs (a GitHub organization) maintains it in datadog-labs/agent-skills, which has 177 GitHub stars. The repository holds 38 skills in this directory. The repository was last updated on October 7, 2026.

Source: datadog-labs/agent-skills on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.