openai-agents by jezweb/claude-skills
npx skills add https://github.com/jezweb/claude-skills --skill openai-agents使用文本智能体、语音智能体(实时)、多智能体工作流、工具、防护栏和人机协同模式构建 AI 应用。
npm install @openai/agents zod@4 # v0.4.0+ 需要 Zod 4(破坏性变更)
npm install @openai/agents-realtime # 语音智能体
export OPENAI_API_KEY="your-key"
破坏性变更 (v0.4.0) : 不再支持 Zod 3。请升级到 zod@4。
运行时环境 : Node.js 22+、Deno、Bun、Cloudflare Workers(实验性)
智能体 : 具备指令和工具的大语言模型
import { Agent } from '@openai/agents';
const agent = new Agent({ name: 'Assistant', tools: [myTool], model: 'gpt-5-mini' });
工具 : 带有 Zod 模式的函数
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`,
});
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
移交 : 多智能体委托
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}`);
},
});
来源 : Issue #806
输入防护栏 : 在处理前进行验证
const guardrail: InputGuardrail = {
execute: async ({ input }) => ({ tripwireTriggered: detectHomework(input) })
};
const agent = new Agent({ inputGuardrails: [guardrail] });
输出防护栏 : 过滤响应(PII检测、内容安全)
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: true 和 requiresApproval 时,必须显式检查中断:
const 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();
关键 : 切勿将 OPENAI_API_KEY 发送到浏览器!应在服务器端生成临时会话令牌。
语音移交 : 语音/模型必须在智能体之间匹配(移交过程中不能更改)
限制 :
模板 :
templates/realtime-agents/realtime-agent-basic.tstemplates/realtime-agents/realtime-session-browser.tsxtemplates/realtime-agents/realtime-handoffs.ts参考资料 :
references/realtime-transports.md - WebRTC 与 WebSocket 对比Cloudflare Workers (实验性):
export default {
async fetch(request: Request, env: Env) {
// 禁用追踪或使用 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=true 或调用 startTracingExportLoop() (Issue #16)Next.js : app/api/agent/route.ts → 带有 run(agent, message) 的 POST 处理程序
模板 : cloudflare-workers/、nextjs/
错误 : 工具参数的类型错误。
变通方案 : 内联定义模式。
// ❌ 可能导致类型错误
parameters: mySchema
// ✅ 可靠工作
parameters: z.object({ field: z.string() })
注意 : 从 v0.4.1 开始,工具调用参数中的无效 JSON 会被优雅处理(之前会导致 SyntaxError 崩溃)。(PR #887)
来源 : GitHub #188
错误 : 使用 MCP 服务器时出现“未找到现有追踪”。
变通方案 :
import { initializeTracing } from '@openai/agents/tracing';
await initializeTracing();
来源 : GitHub #580
错误 : 智能体无限循环。
解决方案 : 增加 maxTurns 或改进指令:
const result = await run(agent, input, {
maxTurns: 20, // 增加限制
});
// 或改进指令
instructions: `使用工具后,提供最终答案。
不要无休止地循环。`
错误 : 工具执行失败。
解决方案 : 使用指数退避重试:
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;
}
}
错误 : 输出与 outputType 不匹配。
解决方案 : 使用更强的模型或添加验证指令:
const agent = new Agent({
model: 'gpt-5', // 比 gpt-5-mini 更可靠
instructions: '关键:返回完全匹配模式的 JSON',
outputType: mySchema,
});
错误 : 升级到 v0.4.0 后出现意外的推理行为。
原因 : 在 v0.4.0 中,gpt-5.1/5.2 的默认推理努力从 "low" 更改为 "none"。
预防措施 : 如果需要推理努力,请显式设置。
// v0.4.0+ - 默认值现在是 "none"
const agent = new Agent({
model: 'gpt-5.1',
reasoning: { effort: 'low' }, // 如果需要,显式设置:'low', 'medium', 'high'
});
来源 : Release v0.4.0 | PR #876
错误 : response_reasoning 字段意外出现在结构化输出中。
原因 : 使用 outputType 和推理模型时的模型端点问题(非 SDK 错误)。
变通方案 : 从输出中过滤掉 response_reasoning。
const result = await run(agent, input);
const { response_reasoning, ...cleanOutput } = result.finalOutput;
return cleanOutput;
来源 : Issue #844 状态 : 模型端问题,正在与 OpenAI 团队协调
所有错误 : 参见 references/common-errors.md
模板 : templates/shared/error-handling.ts
基于 LLM 的编排 : 智能体自主决定路由(自适应,消耗更多令牌) 基于代码的编排 : 使用条件语句的显式控制流(可预测,成本更低) 并行编排 : Promise.all([run(agent1, text), run(agent2, text)])(并发执行)
process.env.DEBUG = '@openai/agents:*'; // 详细日志记录
const result = await run(agent, input);
console.log(result.usage.totalTokens, result.history.length, result.currentAgent?.name);
❌ 不适用场景 :
openai-api 技能)OPENAI_API_KEY 设置为环境密钥maxTurns 以防止成本失控gpt-5-mini 以提高成本效益预计节省 : ~60%
| 任务 | 不使用技能 | 使用技能 | 节省 |
|---|---|---|---|
| 多智能体设置 | ~12k 令牌 | ~5k 令牌 | 58% |
| 语音智能体 | ~10k 令牌 | ~4k 令牌 | 60% |
| 错误调试 | ~8k 令牌 | ~3k 令牌 | 63% |
| 平均 | ~10k | ~4k | ~60% |
已预防的错误 : 11 个已记录问题 = 100% 错误预防
文本智能体 (8):
agent-basic.ts - 带工具的简单智能体agent-handoffs.ts - 多智能体分流agent-structured-output.ts - Zod 模式agent-streaming.ts - 实时事件agent-guardrails-input.ts - 输入验证agent-guardrails-output.ts - 输出过滤agent-human-approval.ts - 人机协同模式agent-parallel.ts - 并发执行实时智能体 (3): 9. realtime-agent-basic.ts - 语音设置 10. realtime-session-browser.tsx - React 客户端 11. realtime-handoffs.ts - 语音委托
框架集成 (4): 12. worker-text-agent.ts - Cloudflare Workers 13. worker-agent-hono.ts - Hono 框架 14. api-agent-route.ts - Next.js API 15. api-realtime-route.ts - Next.js 语音
实用工具 (2): 16. error-handling.ts - 综合错误处理 17. tracing-setup.ts - 调试
agent-patterns.md - 编排策略common-errors.md - 9 个错误及变通方案realtime-transports.md - WebRTC 与 WebSocket 对比cloudflare-integration.md - Workers 限制official-links.md - 官方文档链接版本 : SDK v0.4.1 最后验证 : 2026-01-21 技能作者 : Jeremy Dawes (Jezweb) 生产环境测试 : 是 变更 : 添加了 v0.4.0 破坏性变更(Zod 4、推理默认值)、无效 JSON 处理(v0.4.1)、推理输出泄露、流式传输人机协同模式、智能体作为工具的上下文隔离、视频限制、Cloudflare 追踪设置
每周安装量
359
代码仓库
GitHub 星标
656
首次出现
2026年1月20日
安全审计
安装于
claude-code290
opencode242
gemini-cli240
codex213
cursor212
antigravity209
Build AI applications with text agents, voice agents (realtime), multi-agent workflows, tools, guardrails, and human-in-the-loop patterns.
npm 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"
Breaking Change (v0.4.0) : Zod 3 no longer supported. Upgrade to zod@4.
Runtimes : Node.js 22+, Deno, Bun, Cloudflare Workers (experimental)
Agents : LLMs with instructions + tools
import { Agent } from '@openai/agents';
const agent = new Agent({ name: 'Assistant', tools: [myTool], model: 'gpt-5-mini' });
Tools : Functions with Zod schemas
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`,
});
Handoffs : Multi-agent delegation
const triageAgent = Agent.create({ handoffs: [specialist1, specialist2] });
Guardrails : Input/output validation
const agent = new Agent({ inputGuardrails: [detector], outputGuardrails: [filter] });
Structured Outputs : Type-safe responses
const agent = new Agent({ outputType: z.object({ sentiment: z.enum(['positive', 'negative']) }) });
Basic : const result = await run(agent, 'What is 2+2?')
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') 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-as-Tool Context Isolation : When using agent.asTool(), sub-agents do NOT share parent conversation history (intentional design to simplify debugging).
Workaround : Pass context via tool parameters:
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}`);
},
});
Source : Issue #806
Input : Validate before processing
const guardrail: InputGuardrail = {
execute: async ({ input }) => ({ tripwireTriggered: detectHomework(input) })
};
const agent = new Agent({ inputGuardrails: [guardrail] });
Output : Filter responses (PII detection, content safety)
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);
}
Streaming HITL : When using stream: true with requiresApproval, must explicitly check interruptions:
const 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);
}
Example : human-in-the-loop-stream.ts
Create :
import { RealtimeAgent } from '@openai/agents-realtime';
const voiceAgent = new RealtimeAgent({
voice: 'alloy', // alloy, echo, fable, onyx, nova, shimmer
model: 'gpt-5-realtime',
tools: [weatherTool],
});
Browser Session :
import { RealtimeSession } from '@openai/agents-realtime';
const session = new RealtimeSession(voiceAgent, { apiKey: sessionApiKey, transport: 'webrtc' });
await session.connect();
CRITICAL : Never send OPENAI_API_KEY to browser! Generate ephemeral session tokens server-side.
Voice Handoffs : Voice/model must match across agents (cannot change during handoff)
Limitations :
Templates :
templates/realtime-agents/realtime-agent-basic.tstemplates/realtime-agents/realtime-session-browser.tsxtemplates/realtime-agents/realtime-handoffs.tsReferences :
references/realtime-transports.md - WebRTC vs WebSocketCloudflare Workers (experimental):
export 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 });
}
};
Limitations :
OTEL_SDK_DISABLED=true or call startTracingExportLoop() (Issue #16)Next.js : app/api/agent/route.ts → POST handler with run(agent, message)
Templates : cloudflare-workers/, nextjs/
Error : Type errors with tool parameters.
Workaround : Define schemas inline.
// ❌ Can cause type errors
parameters: mySchema
// ✅ Works reliably
parameters: z.object({ field: z.string() })
Note : As of v0.4.1, invalid JSON in tool call arguments is handled gracefully (previously caused SyntaxError crashes). (PR #887)
Source : GitHub #188
Error : "No existing trace found" with MCP servers.
Workaround :
import { initializeTracing } from '@openai/agents/tracing';
await initializeTracing();
Source : GitHub #580
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.`
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;
}
}
Error : Output doesn't match outputType.
Solution : Use stronger model or add validation instructions:
const agent = new Agent({
model: 'gpt-5', // More reliable than gpt-5-mini
instructions: 'CRITICAL: Return JSON matching schema exactly',
outputType: mySchema,
});
Error : Unexpected reasoning behavior after upgrading to v0.4.0.
Why It Happens : Default reasoning effort for gpt-5.1/5.2 changed from "low" to "none" in v0.4.0.
Prevention : Explicitly set reasoning effort if you need it.
// 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'
});
Source : Release v0.4.0 | PR #876
Error : response_reasoning field appears in structured output unexpectedly.
Why It Happens : Model endpoint issue (not SDK bug) when using outputType with reasoning models.
Workaround : Filter out response_reasoning from output.
const result = await run(agent, input);
const { response_reasoning, ...cleanOutput } = result.finalOutput;
return cleanOutput;
Source : Issue #844 Status : Model-side issue, coordinating with OpenAI teams
All Errors : See references/common-errors.md
Template : templates/shared/error-handling.ts
LLM-Based : Agent decides routing autonomously (adaptive, higher tokens) Code-Based : Explicit control flow with conditionals (predictable, lower cost) Parallel : Promise.all([run(agent1, text), run(agent2, text)]) (concurrent execution)
process.env.DEBUG = '@openai/agents:*'; // Verbose logging
const result = await run(agent, input);
console.log(result.usage.totalTokens, result.history.length, result.currentAgent?.name);
❌ Don't use when :
openai-api skill instead)OPENAI_API_KEY as environment secretmaxTurns to prevent runaway costsgpt-5-mini where possible for cost efficiencyEstimated Savings : ~60%
| 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% |
Errors Prevented : 11 documented issues = 100% error prevention
Text Agents (8):
agent-basic.ts - Simple agent with toolsagent-handoffs.ts - Multi-agent triageagent-structured-output.ts - Zod schemasagent-streaming.ts - Real-time eventsagent-guardrails-input.ts - Input validationagent-guardrails-output.ts - Output filteringagent-human-approval.ts - HITL patternagent-parallel.ts - Concurrent executionRealtime 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
agent-patterns.md - Orchestration strategiescommon-errors.md - 9 errors with workaroundsrealtime-transports.md - WebRTC vs WebSocketcloudflare-integration.md - Workers limitationsofficial-links.md - Documentation linksVersion : SDK v0.4.1 Last Verified : 2026-01-21 Skill Author : Jeremy Dawes (Jezweb) Production Tested : Yes Changes : Added v0.4.0 breaking changes (Zod 4, reasoning defaults), invalid JSON handling (v0.4.1), reasoning output leaks, streaming HITL pattern, agent-as-tool context isolation, video limitations, Cloudflare tracing setup
Weekly Installs
359
Repository
GitHub Stars
656
First Seen
Jan 20, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
claude-code290
opencode242
gemini-cli240
codex213
cursor212
antigravity209
AI Elements:基于shadcn/ui的AI原生应用组件库,快速构建对话界面
54,900 周安装
Rust调用关系图生成器 - 可视化函数调用层次结构,提升代码分析效率
539 周安装
parallel-web-extract:并行网页内容提取工具,高效抓取网页数据
595 周安装
腾讯云CloudBase AI模型Web技能:前端调用混元/DeepSeek模型,实现流式文本生成
560 周安装
Apollo Connectors 模式助手:GraphQL API 连接器开发与集成指南
565 周安装
GitHub Trending 趋势分析工具:实时发现热门项目、技术洞察与开源机会
556 周安装
GSAP React 集成教程:useGSAP Hook 动画库与 React 组件开发指南
546 周安装