Cloudflare Workers AI

Learn how Sentry instruments Cloudflare Workers AI to capture gen_ai spans.

Available since: v10.67.0

Sentry automatically instruments the Cloudflare Workers AI binding (env.AI). Calls to env.AI.run(...) create gen_ai spans that follow Sentry's Agent Tracing conventions, capturing the model, request parameters, and token usage.

No extra setup is required beyond the quick start. The AI binding on the env that your handler receives is instrumented for you:

Copied
export default {
  async fetch(request, env) {
    // env.AI is automatically instrumented
    const result = await env.AI.run("@cf/meta/llama-3.1-8b-instruct", {
      messages: [
        { role: "user", content: "What is the capital of France?" },
      ],
    });

    return new Response(JSON.stringify(result));
  },
} satisfies ExportedHandler<Env>;

That is enough for spans. The SDK records prompt and response content by default. To turn that off, set genAI: { inputs: false, outputs: false } in the dataCollection option.

Only env.AI.run is instrumented. Streaming spans end when the stream is fully read or cancelled. With returnRawResponse or websocket, response body fields are not recorded.

You can browse the full list of available models in the Cloudflare Workers AI models directory.

Available since: v11.7.0

Calls to TypeSafe's Jev model (typesafe/jev) through env.AI.run() are traced automatically. No additional integration or setup is needed:

Copied
export default {
  async fetch(request, env) {
    // env.AI is automatically instrumented
    const result = await env.AI.run("typesafe/jev", {
      state: "I was charged twice. Please refund the extra charge.",
      questions: {
        department: {
          type: "choice",
          instructions: "Which team should handle this?",
          criteria: {
            billing: "Charges and refunds",
            technical: "Bugs and outages",
          },
        },
      },
    });

    return new Response(JSON.stringify(result));
  },
} satisfies ExportedHandler<Env>;

The SDK traces calls to Cloudflare's Clef model (@cf/cloudflare/clef) the same way. Clef takes the same state and questions input as Jev:

Copied
const result = await env.AI.run("@cf/cloudflare/clef", {
  model: "clef",
  state: "Checkout has been failing for every customer for the last hour.",
  questions: {
    urgent: {
      type: "noul",
      instructions: "Is this support request urgent?",
    },
  },
});

Each call creates a gen_ai.decide span named decide <model>, with the response model (for example, jev-1.13.0 or clef), latency, and token usage. When recording is enabled, Sentry captures state and questions as input messages and answers as output messages, including probabilities and confidence values returned by the model. These spans have the same attributes as spans from the TypeSafe integration on other runtimes.

Decision state and answers can contain sensitive data. To stop recording them, set genAI: { inputs: false, outputs: false } in the dataCollection option.

Was this helpful?
Help improve this content
Our documentation is open source and available on GitHub. Your contributions are welcome, whether fixing a typo (drat!) or suggesting an update ("yeah, this would be better").