openai-agents
Use this skill when building AI applications with OpenAI Agents SDK for JavaScript/TypeScript. The skill covers both text-based agents and realtime voice agents, including multi-agent workflows (handoffs), tools with Zod schemas, input/output guardrails, structured outputs, streaming, human-in-the-loop patterns, and framework integrations for Cloudflare Workers, Next.js, and React. It prevents 9+ common errors including Zod schema type errors, MCP tracing failures, infinite loops, tool call failures, and schema mismatches. The skill includes comprehensive templates for all agent types, error handling patterns, and debugging strategies. Keywords: OpenAI Agents SDK, @openai/agents, @openai/agents-realtime, openai agents javascript, openai agents typescript, text agents, voice agents, realtime agents, multi-agent workflows, agent handoffs, agent tools, zod schemas agents, structured outputs agents, agent streaming, agent guardrails, input guardrails, output guardrails, human-in-the-loop, cloudflare workers agents, nextjs openai agents, react openai agents, hono agents, agent debugging, Zod schema type error, MCP tracing failure, agent infinite loop, tool call failures, schema mismatch agents
NPX Install
npx skill4agent add jackspace/claudeskillz openai-agentsTags
Translated version includes tags in frontmatterSKILL.md Content
View Translation Comparison →OpenAI Agents SDK Skill
Installation & Setup
npm install @openai/agents zod@3
npm install @openai/agents-realtime # For voice agentsexport OPENAI_API_KEY="your-api-key"- Node.js 22+
- Deno
- Bun
- Cloudflare Workers (experimental)
Core Concepts
1. Agents
import { Agent } from '@openai/agents';
const agent = new Agent({
name: 'Assistant',
instructions: 'You are helpful.',
tools: [myTool],
model: 'gpt-4o-mini',
});2. Tools
import { tool } from '@openai/agents';
import { z } from 'zod';
const weatherTool = tool({
name: 'get_weather',
description: 'Get weather for a city',
parameters: z.object({
city: z.string(),
}),
execute: async ({ city }) => {
return `Weather in ${city}: sunny`;
},
});3. Handoffs
const specialist = new Agent({ /* ... */ });
const triageAgent = Agent.create({
name: 'Triage',
instructions: 'Route to specialists',
handoffs: [specialist],
});4. Guardrails
const agent = new Agent({
inputGuardrails: [homeworkDetector],
outputGuardrails: [piiFilter],
});5. Structured Outputs
const agent = new Agent({
outputType: z.object({
sentiment: z.enum(['positive', 'negative', 'neutral']),
confidence: z.number(),
}),
});Text Agents
Basic Usage
import { run } from '@openai/agents';
const result = await run(agent, 'What is 2+2?');
console.log(result.finalOutput);
console.log(result.usage.totalTokens);Streaming
const stream = await run(agent, 'Tell me a story', {
stream: true,
});
for await (const event of stream) {
if (event.type === 'raw_model_stream_event') {
const chunk = event.data?.choices?.[0]?.delta?.content || '';
process.stdout.write(chunk);
}
}templates/text-agents/agent-basic.tstemplates/text-agents/agent-streaming.ts
Multi-Agent Handoffs
const billingAgent = new Agent({
name: 'Billing',
handoffDescription: 'For billing and payment questions',
tools: [processRefundTool],
});
const techAgent = new Agent({
name: 'Technical',
handoffDescription: 'For technical issues',
tools: [createTicketTool],
});
const triageAgent = Agent.create({
name: 'Triage',
instructions: 'Route customers to the right specialist',
handoffs: [billingAgent, techAgent],
});templates/text-agents/agent-handoffs.ts
- - LLM vs code orchestration
references/agent-patterns.md
Guardrails
Input Guardrails
const homeworkGuardrail: InputGuardrail = {
name: 'Homework Detection',
execute: async ({ input, context }) => {
const result = await run(guardrailAgent, input);
return {
tripwireTriggered: result.finalOutput.isHomework,
outputInfo: result.finalOutput,
};
},
};
const agent = new Agent({
inputGuardrails: [homeworkGuardrail],
});Output Guardrails
const piiGuardrail: OutputGuardrail = {
name: 'PII Detection',
execute: async ({ agentOutput }) => {
const phoneRegex = /\b\d{3}[-. ]?\d{3}[-. ]?\d{4}\b/;
return {
tripwireTriggered: phoneRegex.test(agentOutput as string),
outputInfo: { detected: 'phone_number' },
};
},
};templates/text-agents/agent-guardrails-input.tstemplates/text-agents/agent-guardrails-output.ts
Human-in-the-Loop
const refundTool = tool({
name: 'process_refund',
requiresApproval: true, // ← Requires human approval
execute: async ({ amount }) => {
return `Refunded $${amount}`;
},
});
// Handle approval requests
let result = await runner.run(input);
while (result.interruption) {
if (result.interruption.type === 'tool_approval') {
const approved = await promptUser(result.interruption);
result = approved
? await result.state.approve(result.interruption)
: await result.state.reject(result.interruption);
}
}templates/text-agents/agent-human-approval.ts
Realtime Voice Agents
Creating Voice Agents
import { RealtimeAgent, tool } from '@openai/agents-realtime';
const voiceAgent = new RealtimeAgent({
name: 'Voice Assistant',
instructions: 'Keep responses concise for voice',
tools: [weatherTool],
voice: 'alloy', // alloy, echo, fable, onyx, nova, shimmer
model: 'gpt-4o-realtime-preview',
});Browser Session (React)
import { RealtimeSession } from '@openai/agents-realtime';
const session = new RealtimeSession(voiceAgent, {
apiKey: sessionApiKey, // From your backend!
transport: 'webrtc', // or 'websocket'
});
session.on('connected', () => console.log('Connected'));
session.on('audio.transcription.completed', (e) => console.log('User:', e.transcript));
session.on('agent.audio.done', (e) => console.log('Agent:', e.transcript));
await session.connect();Voice Agent Handoffs
- Cannot change voice during handoff
- Cannot change model during handoff
- Conversation history automatically passed
const specialist = new RealtimeAgent({
voice: 'nova', // Must match parent
/* ... */
});
const triageAgent = new RealtimeAgent({
voice: 'nova',
handoffs: [specialist],
});templates/realtime-agents/realtime-agent-basic.tstemplates/realtime-agents/realtime-session-browser.tsxtemplates/realtime-agents/realtime-handoffs.ts
- - WebRTC vs WebSocket
references/realtime-transports.md
Framework Integration
Cloudflare Workers (Experimental)
import { Agent, run } from '@openai/agents';
export default {
async fetch(request: Request, env: Env) {
const { message } = await request.json();
process.env.OPENAI_API_KEY = env.OPENAI_API_KEY;
const agent = new Agent({
name: 'Assistant',
instructions: 'Be helpful and concise',
model: 'gpt-4o-mini',
});
const result = await run(agent, message, {
maxTurns: 5,
});
return new Response(JSON.stringify({
response: result.finalOutput,
tokens: result.usage.totalTokens,
}), {
headers: { 'Content-Type': 'application/json' },
});
},
};- No realtime voice agents
- CPU time limits (30s max)
- Memory constraints (128MB)
templates/cloudflare-workers/worker-text-agent.tstemplates/cloudflare-workers/worker-agent-hono.ts
references/cloudflare-integration.md
Next.js App Router
// app/api/agent/route.ts
import { NextRequest, NextResponse } from 'next/server';
import { Agent, run } from '@openai/agents';
export async function POST(request: NextRequest) {
const { message } = await request.json();
const agent = new Agent({
name: 'Assistant',
instructions: 'Be helpful',
});
const result = await run(agent, message);
return NextResponse.json({
response: result.finalOutput,
});
}templates/nextjs/api-agent-route.tstemplates/nextjs/api-realtime-route.ts
Error Handling (9+ Errors Prevented)
1. Zod Schema Type Errors
// ❌ Can cause type errors
parameters: mySchema
// ✅ Works reliably
parameters: z.object({ field: z.string() })2. MCP Tracing Errors
import { initializeTracing } from '@openai/agents/tracing';
await initializeTracing();3. MaxTurnsExceededError
const result = await run(agent, input, {
maxTurns: 20, // Increase limit
});
// Or improve instructions
instructions: `After using tools, provide a final answer.
Do not loop endlessly.`4. ToolCallError
for (let attempt = 1; attempt <= 3; attempt++) {
try {
return await run(agent, input);
} catch (error) {
if (error instanceof ToolCallError && attempt < 3) {
await sleep(1000 * Math.pow(2, attempt - 1));
continue;
}
throw error;
}
}5. Schema Mismatch
outputTypeconst agent = new Agent({
model: 'gpt-4o', // More reliable than gpt-4o-mini
instructions: 'CRITICAL: Return JSON matching schema exactly',
outputType: mySchema,
});references/common-errors.mdtemplates/shared/error-handling.tsOrchestration Patterns
LLM-Based
const manager = Agent.create({
instructions: 'Analyze request and route to appropriate agent',
handoffs: [agent1, agent2, agent3],
});Code-Based
const summary = await run(summarizerAgent, text);
const sentiment = await run(sentimentAgent, summary.finalOutput);
if (sentiment.finalOutput.score < 0.3) {
await run(escalationAgent, text);
}Parallel
const [summary, keywords, entities] = await Promise.all([
run(summarizerAgent, text),
run(keywordAgent, text),
run(entityAgent, text),
]);templates/text-agents/agent-parallel.tsreferences/agent-patterns.mdDebugging & Tracing
process.env.DEBUG = '@openai/agents:*';const result = await run(agent, input);
console.log('Tokens:', result.usage.totalTokens);
console.log('Turns:', result.history.length);
console.log('Current Agent:', result.currentAgent?.name);templates/shared/tracing-setup.tsWhen to Use This Skill
- Building multi-agent workflows
- Creating voice AI applications
- Implementing tool-calling patterns
- Requiring input/output validation (guardrails)
- Needing human approval gates
- Orchestrating complex AI tasks
- Deploying to Cloudflare Workers or Next.js
- Simple OpenAI API calls (use skill instead)
openai-api - Non-OpenAI models exclusively
- Production voice at massive scale (consider LiveKit Agents)
Production Checklist
- Set as environment secret
OPENAI_API_KEY - Implement error handling for all agent calls
- Add guardrails for safety-critical applications
- Enable tracing for debugging
- Set reasonable to prevent runaway costs
maxTurns - Use where possible for cost efficiency
gpt-4o-mini - Implement rate limiting
- Log token usage for cost monitoring
- Test handoff flows thoroughly
- Never expose API keys to browsers (use session tokens)
Token Efficiency
| Task | Without Skill | With Skill | Savings |
|---|---|---|---|
| Multi-agent setup | ~12k tokens | ~5k tokens | 58% |
| Voice agent | ~10k tokens | ~4k tokens | 60% |
| Error debugging | ~8k tokens | ~3k tokens | 63% |
| Average | ~10k | ~4k | ~60% |
Templates Index
- - Simple agent with tools
agent-basic.ts - - Multi-agent triage
agent-handoffs.ts - - Zod schemas
agent-structured-output.ts - - Real-time events
agent-streaming.ts - - Input validation
agent-guardrails-input.ts - - Output filtering
agent-guardrails-output.ts - - HITL pattern
agent-human-approval.ts - - Concurrent execution
agent-parallel.ts
realtime-agent-basic.tsrealtime-session-browser.tsxrealtime-handoffs.tsworker-text-agent.tsworker-agent-hono.tsapi-agent-route.tsapi-realtime-route.tserror-handling.tstracing-setup.tsReferences
- - Orchestration strategies
agent-patterns.md - - 9 errors with workarounds
common-errors.md - - WebRTC vs WebSocket
realtime-transports.md - - Workers limitations
cloudflare-integration.md - - Documentation links
official-links.md
Official Resources
- Docs: https://openai.github.io/openai-agents-js/
- GitHub: https://github.com/openai/openai-agents-js
- npm: https://www.npmjs.com/package/@openai/agents
- Issues: https://github.com/openai/openai-agents-js/issues