Back to Skills

openai-agents

jezweb
Updated Yesterday
44 views
33
4
33
View on GitHub
Metawordreactaimcpautomationdesign

About

This skill helps developers build AI applications using OpenAI's Agents SDK for JavaScript/TypeScript, covering both text and realtime voice agents. It provides comprehensive support for multi-agent workflows, tools with Zod schemas, structured outputs, streaming, and framework integrations like Next.js and Cloudflare Workers. The skill also prevents common errors including Zod schema issues, infinite loops, and tool call failures while offering templates and debugging strategies.

Quick Install

Claude Code

Recommended
Plugin CommandRecommended
/plugin add https://github.com/jezweb/claude-skills
Git CloneAlternative
git clone https://github.com/jezweb/claude-skills.git ~/.claude/skills/openai-agents

Copy and paste this command in Claude Code to install this skill

Documentation

OpenAI Agents SDK Skill

Complete skill for building AI applications with OpenAI Agents SDK (JavaScript/TypeScript), covering text agents, realtime voice agents, multi-agent workflows, and production deployment patterns.


Installation & Setup

Install required packages:

npm install @openai/agents zod@3
npm install @openai/agents-realtime  # For voice agents

Set environment variable:

export OPENAI_API_KEY="your-api-key"

Supported runtimes:

  • Node.js 22+
  • Deno
  • Bun
  • Cloudflare Workers (experimental)

Core Concepts

1. Agents

LLMs equipped with instructions and tools:

import { Agent } from '@openai/agents';

const agent = new Agent({
  name: 'Assistant',
  instructions: 'You are helpful.',
  tools: [myTool],
  model: 'gpt-4o-mini',
});

2. Tools

Functions agents can call, with automatic schema generation:

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

Multi-agent delegation:

const specialist = new Agent({ /* ... */ });

const triageAgent = Agent.create({
  name: 'Triage',
  instructions: 'Route to specialists',
  handoffs: [specialist],
});

4. Guardrails

Input/output validation for safety:

const agent = new Agent({
  inputGuardrails: [homeworkDetector],
  outputGuardrails: [piiFilter],
});

5. Structured Outputs

Type-safe responses with Zod:

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:

  • templates/text-agents/agent-basic.ts
  • templates/text-agents/agent-streaming.ts

Multi-Agent Handoffs

Create specialized agents and route between them:

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:

  • templates/text-agents/agent-handoffs.ts

References:

  • references/agent-patterns.md - LLM vs code orchestration

Guardrails

Input Guardrails

Validate input before processing:

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

Filter responses:

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:

  • templates/text-agents/agent-guardrails-input.ts
  • templates/text-agents/agent-guardrails-output.ts

Human-in-the-Loop

Require approval for specific actions:

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:

  • 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();

CRITICAL: Never send your main OPENAI_API_KEY to the browser! Generate ephemeral session tokens server-side.

Voice Agent Handoffs

Voice agents support handoffs with constraints:

  • 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:

  • templates/realtime-agents/realtime-agent-basic.ts
  • templates/realtime-agents/realtime-session-browser.tsx
  • templates/realtime-agents/realtime-handoffs.ts

References:

  • references/realtime-transports.md - WebRTC vs WebSocket

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' },
    });
  },
};

Limitations:

  • No realtime voice agents
  • CPU time limits (30s max)
  • Memory constraints (128MB)

Templates:

  • templates/cloudflare-workers/worker-text-agent.ts
  • templates/cloudflare-workers/worker-agent-hono.ts

References:

  • 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:

  • templates/nextjs/api-agent-route.ts
  • templates/nextjs/api-realtime-route.ts

Error Handling (9+ Errors Prevented)

1. Zod Schema Type Errors

Error: Type errors with tool parameters.

Workaround: Define schemas inline.

// ❌ Can cause type errors
parameters: mySchema

// ✅ Works reliably
parameters: z.object({ field: z.string() })

Source: GitHub #188

2. MCP Tracing Errors

Error: "No existing trace found" with MCP servers.

Workaround:

import { initializeTracing } from '@openai/agents/tracing';
await initializeTracing();

Source: GitHub #580

3. MaxTurnsExceededError

Error: Agent loops infinitely.

Solution: Increase maxTurns or improve instructions:

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

Error: Tool execution fails.

Solution: Retry with exponential backoff:

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

Error: Output doesn't match outputType.

Solution: Use stronger model or add validation instructions:

const agent = new Agent({
  model: 'gpt-4o', // More reliable than gpt-4o-mini
  instructions: 'CRITICAL: Return JSON matching schema exactly',
  outputType: mySchema,
});

All Errors: See references/common-errors.md

Template: templates/shared/error-handling.ts


Orchestration Patterns

LLM-Based

Agent decides routing autonomously:

const manager = Agent.create({
  instructions: 'Analyze request and route to appropriate agent',
  handoffs: [agent1, agent2, agent3],
});

Pros: Adaptive, handles complexity Cons: Less predictable, higher tokens

Code-Based

Explicit control flow:

const summary = await run(summarizerAgent, text);
const sentiment = await run(sentimentAgent, summary.finalOutput);

if (sentiment.finalOutput.score < 0.3) {
  await run(escalationAgent, text);
}

Pros: Predictable, lower cost Cons: Less flexible

Parallel

Run multiple agents concurrently:

const [summary, keywords, entities] = await Promise.all([
  run(summarizerAgent, text),
  run(keywordAgent, text),
  run(entityAgent, text),
]);

Template: templates/text-agents/agent-parallel.ts

References: references/agent-patterns.md


Debugging & Tracing

Enable verbose logging:

process.env.DEBUG = '@openai/agents:*';

Access execution details:

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);

Template: templates/shared/tracing-setup.ts


When to Use This Skill

Use when:

  • 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

Don't use when:

  • Simple OpenAI API calls (use openai-api skill instead)
  • Non-OpenAI models exclusively
  • Production voice at massive scale (consider LiveKit Agents)

Production Checklist

  • Set OPENAI_API_KEY as environment secret
  • Implement error handling for all agent calls
  • Add guardrails for safety-critical applications
  • Enable tracing for debugging
  • Set reasonable maxTurns to prevent runaway costs
  • Use gpt-4o-mini where possible for cost efficiency
  • Implement rate limiting
  • Log token usage for cost monitoring
  • Test handoff flows thoroughly
  • Never expose API keys to browsers (use session tokens)

Token Efficiency

Estimated Savings: ~60%

TaskWithout SkillWith SkillSavings
Multi-agent setup~12k tokens~5k tokens58%
Voice agent~10k tokens~4k tokens60%
Error debugging~8k tokens~3k tokens63%
Average~10k~4k~60%

Errors Prevented: 9 documented issues = 100% error prevention


Templates Index

Text Agents (8):

  1. agent-basic.ts - Simple agent with tools
  2. agent-handoffs.ts - Multi-agent triage
  3. agent-structured-output.ts - Zod schemas
  4. agent-streaming.ts - Real-time events
  5. agent-guardrails-input.ts - Input validation
  6. agent-guardrails-output.ts - Output filtering
  7. agent-human-approval.ts - HITL pattern
  8. agent-parallel.ts - Concurrent execution

Realtime Agents (3): 9. realtime-agent-basic.ts - Voice setup 10. realtime-session-browser.tsx - React client 11. realtime-handoffs.ts - Voice delegation

Framework Integration (4): 12. worker-text-agent.ts - Cloudflare Workers 13. worker-agent-hono.ts - Hono framework 14. api-agent-route.ts - Next.js API 15. api-realtime-route.ts - Next.js voice

Utilities (2): 16. error-handling.ts - Comprehensive errors 17. tracing-setup.ts - Debugging


References

  1. agent-patterns.md - Orchestration strategies
  2. common-errors.md - 9 errors with workarounds
  3. realtime-transports.md - WebRTC vs WebSocket
  4. cloudflare-integration.md - Workers limitations
  5. official-links.md - Documentation links

Official Resources


Version: SDK v0.2.1 Last Verified: 2025-10-26 Skill Author: Jeremy Dawes (Jezweb) Production Tested: Yes

GitHub Repository

jezweb/claude-skills
Path: skills/openai-agents
aiautomationclaude-codeclaude-skillscloudflarereact

Related Skills

sglang

Meta

SGLang is a high-performance LLM serving framework that specializes in fast, structured generation for JSON, regex, and agentic workflows using its RadixAttention prefix caching. It delivers significantly faster inference, especially for tasks with repeated prefixes, making it ideal for complex, structured outputs and multi-turn conversations. Choose SGLang over alternatives like vLLM when you need constrained decoding or are building applications with extensive prefix sharing.

View skill

evaluating-llms-harness

Testing

This Claude Skill runs the lm-evaluation-harness to benchmark LLMs across 60+ standardized academic tasks like MMLU and GSM8K. It's designed for developers to compare model quality, track training progress, or report academic results. The tool supports various backends including HuggingFace and vLLM models.

View skill

llamaguard

Other

LlamaGuard is Meta's 7-8B parameter model for moderating LLM inputs and outputs across six safety categories like violence and hate speech. It offers 94-95% accuracy and can be deployed using vLLM, Hugging Face, or Amazon SageMaker. Use this skill to easily integrate content filtering and safety guardrails into your AI applications.

View skill

langchain

Meta

LangChain is a framework for building LLM applications using agents, chains, and RAG pipelines. It supports multiple LLM providers, offers 500+ integrations, and includes features like tool calling and memory management. Use it for rapid prototyping and deploying production systems like chatbots, autonomous agents, and question-answering services.

View skill