| Use when writing, modifying, or debugging tests for an LLMObs plugin in "assertLlmObsSpanEvent", "useLlmObs", "getEvents", any MOCK_* matcher ("MOCK_STRING" / "MOCK_NOT_NULLISH" / "MOCK_NUMBER" / "MOCK_OBJECT"),
npx skills add https://github.com/DataDog/dd-trace-js --skill llmobs-testing
That choice picks the response source and test setup — cassettes for a workflow record nothing, while
pure-function tests for a provider-backed call miss the network surface entirely. The operation independently
determines its span kind and fields. These are working categories for reasoning; none exists as a code constant.
anthropic, genai, ai, langchain): VCR cassettes or a canned fetch.
drive nodes with plain return values.
and client over its in-memory transport.
fetch instead of a cassette — where the spec supplies the responses itself: google-cloud-vertexaiswaps global.fetch per test and stubs Google auth, openai-agents and some ai providers pass a fetch option
to the client they construct.
See references/category-strategies.md for the forbidden-vs-required matrix per
strategy.
LLMObs tests use special helpers to validate span events.
Key components:
useLlmObs() - Initializes LLMObs test environmentgetEvents() - Retrieves captured span eventsassertLlmObsSpanEvent() - Validates span structure with flexible matchersBasic test flow:
useLlmObs({ plugin: 'name' })getEvents()assertLlmObsSpanEvent()See references/test-structure.md for complete test file templates.
Provider traffic is recorded once and replayed afterwards. Clients reach the proxy at
http://127.0.0.1:9126/vcr/{provider}; the category block above decides which categories use it at all.
Two facts block every first run:
docker compose up -d testagent.Without it every call fails with ECONNREFUSED 127.0.0.1:9126, which reads like a provider outage.
packages/dd-trace/test/llmobs/cassettes/{provider}/, withgenerated names, rather than beside the spec.
See references/vcr-cassettes.md for recording, provider mapping, body
normalizers, and the commands to run a single integration.
The block at the top maps response source to test strategy. The operation maps independently to a span kind:
http://127.0.0.1:9126/vcr/{provider} or a canned fetch. Chat and generation emit llm; LangChain and ai
also expose operations with other kinds.
'workflow' or 'agent', never 'llm' — the orchestrator coordinates libraries thatcall providers rather than calling them itself. Nodes return plain values, so the test exercises graph execution
instead of a provider API.
validation, no VCR.
See references/category-strategies.md for the patterns per shape.
assertLlmObsSpanEvent(actual, expected)
Validates span structure with flexible matchers for non-deterministic values.
Available matchers: each one is a typeof or nullish check, not a value check.
MOCK_STRING - any string, '' included (use for output text)MOCK_NOT_NULLISH - anything but null / undefined, so 0 and '' pass (use for token counts)MOCK_NUMBER - any numberMOCK_OBJECT - anything with typeof 'object', null included (opaque schema / metadata payloads, ora whole output message whose shape varies, as the ai specs do)
Required fields: span, spanKind, name, tags. A missing tags throws
TypeError: Cannot read properties of undefined (reading 'ml_app') instead of failing an assertion, and every
plugin span carries at least { ml_app: 'test', integration: '<integration>' }.
Optional fields: modelName, modelProvider, inputMessages, outputMessages, inputDocuments,
outputDocuments, inputValue, outputValue, metrics, metadata, toolDefinitions, error, parentId,
sessionId, traceId. Omitting a field asserts its absence rather than ignoring it: no model fields, no input, no
output, no metadata, no tool definitions, metrics of {}, status: 'ok', and the root parent id. traceId is
the exception: omission defaults to MOCK_STRING because every event has one. See
references/assertion-helpers.md for the patterns.
Location: packages/dd-trace/test/llmobs/plugins/{integration}/index.spec.js. One file per
major-version surface when the SDK's shape changed across majors, named after it rather than kept in
one file — openaiv3.spec.js / openaiv4.spec.js, index.spec.js / index.v7.spec.js.
Structure:
'../../util'useLlmObs() installs the tracer, then recreate mutable clients per testdescribe('chat completions', ...))Standard imports:
useLlmObs, assertLlmObsSpanEvent, MOCK_STRING, MOCK_NOT_NULLISH, MOCK_NUMBER, MOCK_OBJECT
See references/test-structure.md for complete template.
SPAN_KINDS in packages/dd-trace/src/llmobs/constants/tags.js is the list the public SDK validates against:
llm (chat / completions), workflow, agent, task (a unit of work inside a workflow), tool, embedding,
retrieval. Plugins set the kind directly and skip that validation, so kinds outside the list exist — ai v7
and claude-agent-sdk both emit step.
Pinning a field the kind never emits asserts metadata production does not produce:
llm — modelName, modelProvider, inputMessages / outputMessages, and any emitted token metrics /metadata
embedding — modelName, modelProvider, inputDocuments, outputValue, sometimes metricsretrieval — inputValue, outputDocumentsworkflow / agent / task / step / tool — kind-specific inputValue / outputValue, sometimesmetadata, never
model fields or token metrics
Cover every instrumented method, and a multi-turn conversation where the surface takes one.
On errors the span is still submitted. Match the plugin's output contract: OpenAI and GenAI carry
outputMessages: [{ content: '', role: '' }], while Anthropic and non-llm integrations may omit output.
Pass a truthy marker to expect an error:
error: {},
The option decides only whether the expected event carries status: 'error' — assertLlmObsSpanEvent
copies the three error fields out of the span it is checking, so the marker does not pin the throw.
A call that resolves still fails on that status. Pin which error was thrown on the APM span the LLMObs
span was built from:
assert.strictEqual(apmSpans[0].meta['error.message'], error.message)
Toolkit for interacting with and testing local web applications using Playwright. Supports verifying frontend functionality, debugging UI behavior, capturing browser screenshots, and viewing browser logs.
Use when implementation is complete, all tests pass, and you need to decide how to integrate the work - guides completion of development work by presenting structured options for merge, PR, or cleanup
Use when implementing any feature or bugfix, before writing implementation code
Use when encountering any bug, test failure, or unexpected behavior, before proposing fixes
Use when about to claim work is complete, fixed, or passing, before committing or creating PRs - requires running verification commands and confirming output before making any success claims; evidence before assertions always
Expert guidance for systematic backtesting of trading strategies. Use when developing, testing, stress-testing, or validating quantitative trading strategies. Covers "beating ideas to death" methodology, parameter robustness testing, slippage modeling, bias prevention, and interpreting backtest results. Applicable when user asks about backtesting, strategy validation, robustness testing, avoiding overfitting, or systematic trading development.
Cloud laboratory platform for automated protein testing and validation. Use when designing proteins and needing experimental validation including binding assays, expression testing, thermostability measurements, enzyme activity assays, or protein sequence optimization. Also use for submitting experiments via API, tracking experiment status, downloading results, optimizing protein sequences for better expression using computational tools (NetSolP, SoluProt, SolubleMPNN, ESM), or managing protein design workflows with wet-lab validation.
This skill should be used for time series machine learning tasks including classification, regression, clustering, forecasting, anomaly detection, segmentation, and similarity search. Use when working with temporal data, sequential patterns, or time-indexed observations requiring specialized algorithms beyond standard ML approaches. Particularly suited for univariate and multivariate time series analysis with scikit-learn compatible APIs.
Take datadog/llmobs-testing from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.