Setup Sentry AI Agent Monitoring in any project. Use this when asked to add AI monitoring, track LLM calls, monitor AI agents, or instrument OpenAI/Anthropic/Vercel AI/LangChain/Google GenAI. Automatically detects installed AI SDKs and configures the appropriate Sentry integration.
Automatically detects installed AI SDKs (OpenAI, Anthropic, Vercel AI, LangChain, Google GenAI) and configures Sentry's AI Agent Monitoring to track LLM calls, token usage, and agent executions. Use when asked to add AI monitoring, track LLM costs, or instrument AI agents.
/plugin marketplace add troykelly/claude-skills/plugin install issue-driven-development@troykelly-skillsThis skill is limited to using the following tools:
This skill helps configure Sentry's AI Agent Monitoring to track LLM calls, agent executions, tool usage, and token consumption.
Invoke this skill when:
ALWAYS detect installed AI SDKs before suggesting configuration. Do not assume which AI library the user is using.
Run these commands to detect installed AI packages:
# Check package.json for AI SDKs
grep -E '"(openai|@anthropic-ai/sdk|ai|@langchain|@google/genai|@langchain/langgraph)"' package.json
Supported JavaScript AI SDKs:
| Package | Sentry Integration | Min SDK Version | Package Version |
|---|---|---|---|
openai | openAIIntegration | 10.2.0 | >=4.0.0 <7 |
@anthropic-ai/sdk | anthropicAIIntegration | 10.12.0 | >=0.19.2 <1 |
ai (Vercel AI SDK) | vercelAIIntegration | 10.6.0 | >=3.0.0 <6 |
@langchain/* | langChainIntegration | 10.22.0 | >=0.1.0 <1 |
@google/genai | googleGenAIIntegration | 10.14.0 | >=0.10.0 <2 |
@langchain/langgraph | langGraphIntegration | 10.25.0 | >=0.2.0 <1 |
# Check requirements.txt or pyproject.toml
grep -E '(openai|anthropic|langchain|huggingface)' requirements.txt pyproject.toml 2>/dev/null
Supported Python AI SDKs:
| Package | Sentry Extra | Min SDK Version | Package Version |
|---|---|---|---|
openai | sentry-sdk[openai] | 2.41.0 | >=1.0.0 |
anthropic | sentry-sdk[anthropic] | 2.x | >=0.16.0 |
langchain | sentry-sdk[langchain] | 2.x | >=0.1.11 |
huggingface_hub | sentry-sdk[huggingface_hub] | 2.x | >=0.22.0 |
grep -E '"@sentry/(nextjs|react|node)"' package.json
Check version meets minimum for detected AI SDK (see table above).
Upgrade if needed:
npm install @sentry/nextjs@latest # or appropriate package
pip show sentry-sdk | grep Version
Upgrade if needed:
pip install --upgrade "sentry-sdk[openai]" # include detected extras
AI Agent Monitoring requires tracing. Check that tracesSampleRate is set in Sentry.init().
If not enabled, inform the user:
AI Agent Monitoring requires tracing to be enabled. I'll add tracesSampleRate to your Sentry configuration.
Before configuring, tell the user what you found:
I detected the following AI SDK(s) in your project:
- [SDK NAME] (version X.X.X)
Sentry has automatic integration support for this SDK. I'll configure the appropriate integration.
If no supported SDK is detected:
I didn't detect any AI SDKs with automatic Sentry integration support in your project.
Your options:
1. Manual Instrumentation - I can help you set up custom spans for your AI calls
2. Install a supported SDK - If you're planning to add one of the supported SDKs
Would you like to proceed with manual instrumentation? If so, please describe where your AI/LLM calls are located.
Automatic - Enabled by default in SDK 10.2.0+
Explicit configuration (to enable input/output recording):
import * as Sentry from "@sentry/nextjs"; // or @sentry/node, @sentry/react
Sentry.init({
dsn: "YOUR_DSN_HERE",
tracesSampleRate: 1.0,
integrations: [
Sentry.openAIIntegration({
recordInputs: true, // Capture prompts/messages
recordOutputs: true, // Capture responses
}),
],
});
Supported methods (auto-instrumented):
chat.completions.create()responses.create()Example usage (no changes needed):
import OpenAI from "openai";
const openai = new OpenAI();
const response = await openai.chat.completions.create({
model: "gpt-4o",
messages: [{ role: "user", content: "Hello!" }],
});
// Automatically captured by Sentry
Automatic - Enabled by default in SDK 10.12.0+
Explicit configuration:
import * as Sentry from "@sentry/nextjs";
Sentry.init({
dsn: "YOUR_DSN_HERE",
tracesSampleRate: 1.0,
integrations: [
Sentry.anthropicAIIntegration({
recordInputs: true,
recordOutputs: true,
}),
],
});
Supported methods (auto-instrumented):
messages.create() / messages.stream()messages.countTokens()completions.create()beta.messages.create()Automatic in Node runtime - Enabled by default in SDK 10.6.0+
For Edge runtime (Next.js) - Must be explicitly enabled in sentry.edge.config.ts:
import * as Sentry from "@sentry/nextjs";
Sentry.init({
dsn: "YOUR_DSN_HERE",
tracesSampleRate: 1.0,
integrations: [Sentry.vercelAIIntegration()],
});
IMPORTANT: Telemetry must be enabled per-call:
import { generateText } from "ai";
import { openai } from "@ai-sdk/openai";
const result = await generateText({
model: openai("gpt-4o"),
prompt: "Hello!",
experimental_telemetry: {
isEnabled: true,
recordInputs: true,
recordOutputs: true,
functionId: "my-generation", // Optional but recommended
},
});
Configuration options:
Sentry.vercelAIIntegration({
recordInputs: true,
recordOutputs: true,
force: false, // Force enable even if AI module not detected
})
Requires explicit integration in SDK 10.22.0+
import * as Sentry from "@sentry/nextjs";
Sentry.init({
dsn: "YOUR_DSN_HERE",
tracesSampleRate: 1.0,
integrations: [
Sentry.langChainIntegration({
recordInputs: true,
recordOutputs: true,
}),
],
});
Auto-instrumented operations:
gen_ai.request)gen_ai.pipeline)gen_ai.invoke_agent)gen_ai.execute_tool)invoke(), stream(), batch() methodsRequires explicit integration in SDK 10.25.0+
import * as Sentry from "@sentry/nextjs";
Sentry.init({
dsn: "YOUR_DSN_HERE",
tracesSampleRate: 1.0,
integrations: [
Sentry.langGraphIntegration({
recordInputs: true,
recordOutputs: true,
}),
],
});
Auto-instrumented:
invoke() method)Automatic - Enabled by default in SDK 10.14.0+
Explicit configuration:
import * as Sentry from "@sentry/nextjs";
Sentry.init({
dsn: "YOUR_DSN_HERE",
tracesSampleRate: 1.0,
integrations: [
Sentry.googleGenAIIntegration({
recordInputs: true,
recordOutputs: true,
}),
],
});
Supported methods:
models.generateContent() / models.generateContentStream()chats.create()sendMessage() / sendMessageStream()Install with extra:
pip install "sentry-sdk[openai]"
Configuration:
import sentry_sdk
from sentry_sdk.integrations.openai import OpenAIIntegration
sentry_sdk.init(
dsn="YOUR_DSN_HERE",
traces_sample_rate=1.0,
send_default_pii=True, # Required for input/output capture
integrations=[
OpenAIIntegration(
include_prompts=True, # Capture inputs/outputs
tiktoken_encoding_name="cl100k_base", # For streaming token count
),
],
)
Usage (auto-instrumented):
from openai import OpenAI
client = OpenAI()
with sentry_sdk.start_transaction(name="AI inference"):
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Hello!"}]
)
Install with extra:
pip install "sentry-sdk[anthropic]"
Configuration:
import sentry_sdk
from sentry_sdk.integrations.anthropic import AnthropicIntegration
sentry_sdk.init(
dsn="YOUR_DSN_HERE",
traces_sample_rate=1.0,
send_default_pii=True,
integrations=[
AnthropicIntegration(
include_prompts=True,
),
],
)
Usage:
from anthropic import Anthropic
client = Anthropic()
with sentry_sdk.start_transaction(name="Claude inference"):
response = client.messages.create(
model="claude-3-5-sonnet-20240620",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello!"}]
)
Install with extra:
pip install "sentry-sdk[langchain]"
Configuration:
import sentry_sdk
from sentry_sdk.integrations.langchain import LangchainIntegration
sentry_sdk.init(
dsn="YOUR_DSN_HERE",
traces_sample_rate=1.0,
send_default_pii=True, # Required for LLM input/output capture
integrations=[
LangchainIntegration(
include_prompts=True,
),
],
)
Usage:
with sentry_sdk.start_transaction(name="LangChain agent"):
agent_executor = AgentExecutor(agent=agent, tools=tools)
result = agent_executor.invoke({"input": "your prompt"})
Install with extra:
pip install "sentry-sdk[huggingface_hub]"
Configuration:
import sentry_sdk
from sentry_sdk.integrations.huggingface_hub import HuggingfaceHubIntegration
sentry_sdk.init(
dsn="YOUR_DSN_HERE",
traces_sample_rate=1.0,
send_default_pii=True,
integrations=[
HuggingfaceHubIntegration(
include_prompts=True,
),
],
)
IMPORTANT: Only use manual instrumentation when:
I'll help you set up manual AI instrumentation. To do this effectively, I need to know:
1. Where are your AI/LLM calls located? (file paths)
2. What AI provider/model are you using?
3. What operations do you want to track?
- LLM requests (prompts, completions)
- Agent executions
- Tool calls
- Agent handoffs
Four span types are required for AI Agents Insights:
gen_ai.request)Tracks individual LLM calls:
import * as Sentry from "@sentry/nextjs";
async function callLLM(prompt, model = "custom-model") {
return await Sentry.startSpan(
{
op: "gen_ai.request",
name: `LLM request ${model}`,
attributes: {
"gen_ai.request.model": model,
"gen_ai.request.temperature": 0.7,
"gen_ai.request.max_tokens": 1000,
},
},
async (span) => {
// Record input messages
span.setAttribute(
"gen_ai.request.messages",
JSON.stringify([{ role: "user", content: prompt }])
);
const startTime = performance.now();
// Your actual LLM call here
const result = await yourLLMClient.complete(prompt);
// Record output and metrics
span.setAttribute("gen_ai.response.text", result.text);
span.setAttribute("gen_ai.usage.input_tokens", result.inputTokens || 0);
span.setAttribute("gen_ai.usage.output_tokens", result.outputTokens || 0);
return result;
}
);
}
gen_ai.invoke_agent)Tracks full agent execution lifecycle:
async function runAgent(task) {
return await Sentry.startSpan(
{
op: "gen_ai.invoke_agent",
name: "Execute AI Agent",
attributes: {
"gen_ai.agent.name": "my-agent",
"gen_ai.agent.available_tools": JSON.stringify(["search", "calculate"]),
},
},
async (span) => {
span.setAttribute("gen_ai.agent.input", task);
// Agent execution logic (may include multiple LLM calls and tool uses)
const result = await agent.execute(task);
span.setAttribute("gen_ai.agent.output", JSON.stringify(result));
span.setAttribute("gen_ai.usage.total_tokens", result.totalTokens || 0);
return result;
}
);
}
gen_ai.execute_tool)Tracks tool/function calls:
async function executeTool(toolName, toolInput) {
return await Sentry.startSpan(
{
op: "gen_ai.execute_tool",
name: `Tool: ${toolName}`,
attributes: {
"gen_ai.tool.name": toolName,
"gen_ai.tool.description": getToolDescription(toolName),
},
},
async (span) => {
span.setAttribute("gen_ai.tool.input", JSON.stringify(toolInput));
const result = await tools[toolName](toolInput);
span.setAttribute("gen_ai.tool.output", JSON.stringify(result));
return result;
}
);
}
gen_ai.handoff)Tracks agent-to-agent control transitions:
async function handoffToAgent(fromAgent, toAgent, context) {
return await Sentry.startSpan(
{
op: "gen_ai.handoff",
name: `Handoff: ${fromAgent} -> ${toAgent}`,
attributes: {
"gen_ai.handoff.from_agent": fromAgent,
"gen_ai.handoff.to_agent": toAgent,
},
},
async (span) => {
span.setAttribute("gen_ai.handoff.context", JSON.stringify(context));
// Perform handoff
const result = await agents[toAgent].receive(context);
return result;
}
);
}
import sentry_sdk
import json
def call_llm(prompt, model="custom-model"):
with sentry_sdk.start_span(
op="gen_ai.request",
name=f"LLM request {model}",
) as span:
span.set_data("gen_ai.request.model", model)
span.set_data("gen_ai.request.messages", json.dumps([
{"role": "user", "content": prompt}
]))
# Your actual LLM call
result = your_llm_client.complete(prompt)
span.set_data("gen_ai.response.text", result.text)
span.set_data("gen_ai.usage.input_tokens", result.input_tokens)
span.set_data("gen_ai.usage.output_tokens", result.output_tokens)
return result
| Attribute | Description |
|---|---|
gen_ai.request.model | AI model identifier (e.g., "gpt-4o", "claude-3") |
| Attribute | Description |
|---|---|
gen_ai.usage.input_tokens | Tokens in prompt/input |
gen_ai.usage.output_tokens | Tokens in response/output |
gen_ai.usage.total_tokens | Total tokens used |
| Attribute | Description |
|---|---|
gen_ai.request.messages | JSON string of input messages |
gen_ai.request.temperature | Temperature setting |
gen_ai.request.max_tokens | Max tokens limit |
gen_ai.request.top_p | Top-p sampling value |
| Attribute | Description |
|---|---|
gen_ai.response.text | Generated text response |
gen_ai.response.tool_calls | JSON string of tool calls |
| Attribute | Description |
|---|---|
gen_ai.agent.name | Agent identifier |
gen_ai.agent.available_tools | JSON array of tool names |
gen_ai.agent.input | Agent input/task |
gen_ai.agent.output | Agent output/result |
| Attribute | Description |
|---|---|
gen_ai.tool.name | Tool identifier |
gen_ai.tool.description | Tool description |
gen_ai.tool.input | JSON string of tool input |
gen_ai.tool.output | JSON string of tool output |
Note: All complex data must be JSON stringified. Span attributes only allow primitive types.
instrumentation-client.ts, sentry.server.config.ts, sentry.edge.config.tsPrompts and outputs are considered PII. To capture them:
Sentry.init({
sendDefaultPii: true,
// OR configure per-integration:
integrations: [
Sentry.openAIIntegration({
recordInputs: true,
recordOutputs: true,
}),
],
});
sentry_sdk.init(
send_default_pii=True,
# OR configure per-integration:
integrations=[
OpenAIIntegration(include_prompts=True),
],
)
To exclude prompts/outputs:
recordInputs: false / recordOutputs: false (JS)include_prompts=False (Python)After setup, verify AI monitoring is working:
// Trigger a test LLM call
const response = await openai.chat.completions.create({
model: "gpt-4o-mini",
messages: [{ role: "user", content: "Say 'Sentry test successful'" }],
});
console.log("Test complete:", response.choices[0].message.content);
with sentry_sdk.start_transaction(name="AI Test"):
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "Say 'Sentry test'"}]
)
print("Test complete:", response.choices[0].message.content)
Check in Sentry:
gen_ai.* operationsSolutions:
tracesSampleRate > 0)experimental_telemetry.isEnabled: trueSolutions:
tiktokenSolutions:
sendDefaultPii: true or per-integration recordingrecordInputs/recordOutputs or include_prompts settingsSolutions:
force: true option if module detection fails## Sentry AI Agent Monitoring Setup Complete
### Detection Results:
- [ ] AI SDK(s) detected: [LIST DETECTED SDKS]
- [ ] Sentry SDK version verified
- [ ] Tracing enabled
### Configuration Applied:
- [ ] Integration(s) added to Sentry.init()
- [ ] Input/output recording configured
- [ ] PII settings reviewed
### For Vercel AI SDK (if applicable):
- [ ] Edge runtime integration added
- [ ] experimental_telemetry enabled in function calls
### Next Steps:
1. Make an AI/LLM call to verify
2. Check Sentry > Traces > AI Spans
3. Review AI Agents Dashboard for metrics
| AI SDK | JS Integration | Python Extra |
|---|---|---|
| OpenAI | openAIIntegration() | sentry-sdk[openai] |
| Anthropic | anthropicAIIntegration() | sentry-sdk[anthropic] |
| Vercel AI | vercelAIIntegration() | N/A |
| LangChain | langChainIntegration() | sentry-sdk[langchain] |
| LangGraph | langGraphIntegration() | N/A |
| Google GenAI | googleGenAIIntegration() | N/A |
| Hugging Face | N/A | sentry-sdk[huggingface_hub] |
This skill should be used when the user asks to "create a slash command", "add a command", "write a custom command", "define command arguments", "use command frontmatter", "organize commands", "create command with file references", "interactive command", "use AskUserQuestion in command", or needs guidance on slash command structure, YAML frontmatter fields, dynamic arguments, bash execution in commands, user interaction patterns, or command development best practices for Claude Code.
This skill should be used when the user asks to "create an agent", "add an agent", "write a subagent", "agent frontmatter", "when to use description", "agent examples", "agent tools", "agent colors", "autonomous agent", or needs guidance on agent structure, system prompts, triggering conditions, or agent development best practices for Claude Code plugins.
This skill should be used when the user asks to "create a hook", "add a PreToolUse/PostToolUse/Stop hook", "validate tool use", "implement prompt-based hooks", "use ${CLAUDE_PLUGIN_ROOT}", "set up event-driven automation", "block dangerous commands", or mentions hook events (PreToolUse, PostToolUse, Stop, SubagentStop, SessionStart, SessionEnd, UserPromptSubmit, PreCompact, Notification). Provides comprehensive guidance for creating and implementing Claude Code plugin hooks with focus on advanced prompt-based hooks API.