Loading...
Loading...
Build AI applications with OpenAI Agents SDK - text agents, voice agents, multi-agent handoffs, tools with Zod schemas, guardrails, and streaming. Prevents 11 documented errors. Use when: building agents with tools, voice agents with WebRTC, multi-agent workflows, or troubleshooting MaxTurnsExceededError, tool call failures, reasoning defaults, JSON output leaks.
npx skill4agent add jezweb/claude-skills openai-agentsnpm install @openai/agents zod@4 # v0.4.0+ requires Zod 4 (breaking change)
npm install @openai/agents-realtime # Voice agents
export OPENAI_API_KEY="your-key"zod@4import { Agent } from '@openai/agents';
const agent = new Agent({ name: 'Assistant', tools: [myTool], model: 'gpt-5-mini' });import { tool } from '@openai/agents';
import { z } from 'zod';
const weatherTool = tool({
name: 'get_weather',
parameters: z.object({ city: z.string() }),
execute: async ({ city }) => `Weather in ${city}: sunny`,
});const triageAgent = Agent.create({ handoffs: [specialist1, specialist2] });const agent = new Agent({ inputGuardrails: [detector], outputGuardrails: [filter] });const agent = new Agent({ outputType: z.object({ sentiment: z.enum(['positive', 'negative']) }) });const result = await run(agent, 'What is 2+2?')const stream = await run(agent, 'Tell me a story', { stream: true });
for await (const event of stream) {
if (event.type === 'raw_model_stream_event') process.stdout.write(event.data?.choices?.[0]?.delta?.content || '');
}const billingAgent = new Agent({ name: 'Billing', handoffDescription: 'For billing questions', tools: [refundTool] });
const techAgent = new Agent({ name: 'Technical', handoffDescription: 'For tech issues', tools: [ticketTool] });
const triageAgent = Agent.create({ name: 'Triage', handoffs: [billingAgent, techAgent] });agent.asTool()const helperTool = tool({
name: 'use_helper',
parameters: z.object({
query: z.string(),
context: z.string().optional(),
}),
execute: async ({ query, context }) => {
return await run(subAgent, `${context}\n\n${query}`);
},
});const guardrail: InputGuardrail = {
execute: async ({ input }) => ({ tripwireTriggered: detectHomework(input) })
};
const agent = new Agent({ inputGuardrails: [guardrail] });const refundTool = tool({ name: 'process_refund', requiresApproval: true, execute: async ({ amount }) => `Refunded $${amount}` });
let result = await runner.run(input);
while (result.interruption?.type === 'tool_approval') {
result = await promptUser(result.interruption) ? result.state.approve(result.interruption) : result.state.reject(result.interruption);
}stream: truerequiresApprovalconst stream = await run(agent, input, { stream: true });
let result = await stream.finalResult();
while (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);
}import { RealtimeAgent } from '@openai/agents-realtime';
const voiceAgent = new RealtimeAgent({
voice: 'alloy', // alloy, echo, fable, onyx, nova, shimmer
model: 'gpt-5-realtime',
tools: [weatherTool],
});import { RealtimeSession } from '@openai/agents-realtime';
const session = new RealtimeSession(voiceAgent, { apiKey: sessionApiKey, transport: 'webrtc' });
await session.connect();templates/realtime-agents/realtime-agent-basic.tstemplates/realtime-agents/realtime-session-browser.tsxtemplates/realtime-agents/realtime-handoffs.tsreferences/realtime-transports.mdexport default {
async fetch(request: Request, env: Env) {
// Disable tracing or use startTracingExportLoop()
process.env.OTEL_SDK_DISABLED = 'true';
process.env.OPENAI_API_KEY = env.OPENAI_API_KEY;
const agent = new Agent({ name: 'Assistant', model: 'gpt-5-mini' });
const result = await run(agent, (await request.json()).message);
return Response.json({ response: result.finalOutput, tokens: result.usage.totalTokens });
}
};OTEL_SDK_DISABLED=truestartTracingExportLoop()app/api/agent/route.tsPOSTrun(agent, message)cloudflare-workers/nextjs/// ❌ Can cause type errors
parameters: mySchema
// ✅ Works reliably
parameters: z.object({ field: z.string() })import { initializeTracing } from '@openai/agents/tracing';
await initializeTracing();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.`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;
}
}outputTypeconst agent = new Agent({
model: 'gpt-5', // More reliable than gpt-5-mini
instructions: 'CRITICAL: Return JSON matching schema exactly',
outputType: mySchema,
});"low""none"// v0.4.0+ - default is now "none"
const agent = new Agent({
model: 'gpt-5.1',
reasoning: { effort: 'low' }, // Explicitly set if needed: 'low', 'medium', 'high'
});response_reasoningoutputTyperesponse_reasoningconst result = await run(agent, input);
const { response_reasoning, ...cleanOutput } = result.finalOutput;
return cleanOutput;references/common-errors.mdtemplates/shared/error-handling.tsPromise.all([run(agent1, text), run(agent2, text)])process.env.DEBUG = '@openai/agents:*'; // Verbose logging
const result = await run(agent, input);
console.log(result.usage.totalTokens, result.history.length, result.currentAgent?.name);openai-apiOPENAI_API_KEYmaxTurnsgpt-5-mini| 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% |
agent-basic.tsagent-handoffs.tsagent-structured-output.tsagent-streaming.tsagent-guardrails-input.tsagent-guardrails-output.tsagent-human-approval.tsagent-parallel.tsrealtime-agent-basic.tsrealtime-session-browser.tsxrealtime-handoffs.tsworker-text-agent.tsworker-agent-hono.tsapi-agent-route.tsapi-realtime-route.tserror-handling.tstracing-setup.tsagent-patterns.mdcommon-errors.mdrealtime-transports.mdcloudflare-integration.mdofficial-links.md