add-ai-integration
โดย sentry
เพิ่มการรวมผู้ให้บริการ AI ใหม่เข้าไปใน Sentry JavaScript SDK ใช้เมื่อมีส่วนร่วมในการสร้างเครื่องมือวัด AI ใหม่ (OpenAI, Anthropic, Vercel AI, LangChain ฯลฯ)…
npx skills add https://github.com/getsentry/sentry-javascript --skill add-ai-integrationAdding a New AI Integration
Conventions First
Span ops and attributes are specified outside this repo. Never invent or hardcode either:
- gen_ai attributes and gen_ai ops — normative; import from
@sentry/conventions/attributesand@sentry/conventions/op - RFC 0153 — why Sentry's gen-AI conventions diverge from the OTel gen-ai semconv
Derive the op with getGenAiSpanOp() from ai/core/utils.ts rather than picking one by hand. ai/core/gen-ai-attributes.ts is for gap-fillers only — keys with no @sentry/conventions equivalent — so check it last, not first.
Which Pattern
Does the SDK publish its own `diagnostics_channel` telemetry?
|- YES (ai >= 7) -> Pattern 1: Native tracing channel
+- NO -> Does the SDK expose callback/exporter hooks?
|- YES (LangChain, Mastra) -> Pattern 3: Callback/Exporter
+- NO (OpenAI, Anthropic, Google GenAI, ai < 7) -> Pattern 2: Orchestrion-injected channels
| Pattern | Use when | Reference |
|---|---|---|
| 1 — Native tracing channel | the SDK publishes to diagnostics_channel | integrations/vercel-ai/vercel-ai-dc-subscriber.ts |
| 2 — Orchestrion channels | the SDK has no telemetry of its own | integrations/openai.ts + orchestrion/config/openai.ts |
| 3 — Callback/exporter | the SDK exposes hooks or an exporter | ai/langchain/, ai/mastra/ (exporter-shaped agent framework) |
What the reference files won't tell you:
- A provider can need two patterns at once:
vercelAIIntegrationsubscribes to nativeai:telemetryforai>= 7 and runs orchestrion injection for v4-v6. - Pattern 1 subscribers are safe to register unconditionally — subscribing is a no-op on SDK versions that never publish.
Where The Code Goes
- Instrumentation ->
packages/server-utils/src/ai/{provider}/ - Integration ->
packages/server-utils/src/integrations/{provider}.ts - Runtime packages (
node,cloudflare,bun, ...) re-export from@sentry/server-utils— they never define their own - Exception: Workers AI is client-wrapped in
packages/cloudflare/src/instrumentations/worker/instrumentEnv.ts
Gotchas
- Detect streaming from the result shape — an async-iterable or the SDK's stream object — not from
params.stream. Only the manualinstrument{Provider}Client()API keys offparams.stream === true. - Never set streamed response attributes by hand. Accumulate into a
StreamResponseStateand callendStreamSpan()(ai/openai/streaming.tsfor an async generator,ai/anthropic-ai/streaming.tsfor a listener-based stream). - Never truncate message payloads. Truncation was removed in v11 (#23045) and nothing downstream caps them; size limiting is server-side.
- Never roll child token usage up onto parent spans. Tree totals are computed product-side from the full span tree.
- Never read
dataCollection.genAIdirectly. Gate input/output recording onresolveAIRecordingOptions(). - LangChain must be registered first in
getTracingIntegrations(), so it can disable the provider integrations before they instrument. - Set
SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN = 'auto.ai.{provider}'(alphanumerics,_,.only).
Checklist
- Instrumentation in
src/ai/, integration insrc/integrations/, registered ingetTracingIntegrations()(LangChain first) - Exported from
packages/server-utils/src/index.ts, re-exported from the supported runtime packages - E2E tests in
dev-packages/node-integration-tests/suites/tracing/{provider}/(andcloudflare-integration-tests/if supported) - Ops and attributes from
@sentry/conventions, op derived viagetGenAiSpanOp() - Recording gated on
resolveAIRecordingOptions(); no truncation, no token rollup - JSDoc names the channels subscribed to, the supported SDK versions, and — for Pattern 2 — that it requires the Sentry runtime hook or bundler plugin
- Patching happens only once the target package is imported (zero cost if unused)
When in doubt, follow the pattern of the most similar existing integration.