openai-agents
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseOpenAI Agents SDK
OpenAI Agents SDK
Build AI applications with text agents, voice agents (realtime), multi-agent workflows, tools, guardrails, and human-in-the-loop patterns.
使用文本Agent、实时语音Agent、多Agent工作流、工具、防护机制和人机协同模式构建AI应用程序。
Quick Start
快速开始
bash
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@4Runtimes: Node.js 22+, Deno, Bun, Cloudflare Workers (experimental)
bash
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"重大变更(v0.4.0):不再支持Zod 3,请升级至。
zod@4运行环境:Node.js 22+、Deno、Bun、Cloudflare Workers(实验性支持)
Core Concepts
核心概念
Agents: LLMs with instructions + tools
typescript
import { Agent } from '@openai/agents';
const agent = new Agent({ name: 'Assistant', tools: [myTool], model: 'gpt-5-mini' });Tools: Functions with Zod schemas
typescript
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
typescript
const triageAgent = Agent.create({ handoffs: [specialist1, specialist2] });Guardrails: Input/output validation
typescript
const agent = new Agent({ inputGuardrails: [detector], outputGuardrails: [filter] });Structured Outputs: Type-safe responses
typescript
const agent = new Agent({ outputType: z.object({ sentiment: z.enum(['positive', 'negative']) }) });Agent:带指令和工具的大语言模型(LLM)
typescript
import { Agent } from '@openai/agents';
const agent = new Agent({ name: 'Assistant', tools: [myTool], model: 'gpt-5-mini' });工具:基于Zod schema的函数
typescript
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`,
});Agent切换:多Agent委托
typescript
const triageAgent = Agent.create({ handoffs: [specialist1, specialist2] });防护机制:输入/输出验证
typescript
const agent = new Agent({ inputGuardrails: [detector], outputGuardrails: [filter] });结构化输出:类型安全的响应
typescript
const agent = new Agent({ outputType: z.object({ sentiment: z.enum(['positive', 'negative']) }) });Text Agents
文本Agent
Basic:
const result = await run(agent, 'What is 2+2?')Streaming:
typescript
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 result = await run(agent, 'What is 2+2?')流式传输:
typescript
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 || '');
}Multi-Agent Handoffs
多Agent切换
typescript
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 , sub-agents do NOT share parent conversation history (intentional design to simplify debugging).
agent.asTool()Workaround: Pass context via tool parameters:
typescript
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
typescript
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作为工具的上下文隔离:使用时,子Agent不会共享父级对话历史(此为有意设计,旨在简化调试)。
agent.asTool()解决方法:通过工具参数传递上下文:
typescript
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
Guardrails
防护机制
Input: Validate before processing
typescript
const guardrail: InputGuardrail = {
execute: async ({ input }) => ({ tripwireTriggered: detectHomework(input) })
};
const agent = new Agent({ inputGuardrails: [guardrail] });Output: Filter responses (PII detection, content safety)
输入防护:处理前验证输入
typescript
const guardrail: InputGuardrail = {
execute: async ({ input }) => ({ tripwireTriggered: detectHomework(input) })
};
const agent = new Agent({ inputGuardrails: [guardrail] });输出防护:过滤响应(PII检测、内容安全)
Human-in-the-Loop
人机协同
typescript
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 with , must explicitly check interruptions:
stream: truerequiresApprovaltypescript
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
typescript
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: truerequiresApprovaltypescript
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);
}Realtime Voice Agents
实时语音Agent
Create:
typescript
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:
typescript
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:
- Video streaming NOT supported: Despite camera examples, realtime video streaming is not natively supported. Model may not proactively speak based on video events. (Issue #694)
Templates:
templates/realtime-agents/realtime-agent-basic.tstemplates/realtime-agents/realtime-session-browser.tsxtemplates/realtime-agents/realtime-handoffs.ts
References:
- - WebRTC vs WebSocket
references/realtime-transports.md
创建:
typescript
import { RealtimeAgent } from '@openai/agents-realtime';
const voiceAgent = new RealtimeAgent({
voice: 'alloy', // alloy, echo, fable, onyx, nova, shimmer
model: 'gpt-5-realtime',
tools: [weatherTool],
});浏览器会话:
typescript
import { RealtimeSession } from '@openai/agents-realtime';
const session = new RealtimeSession(voiceAgent, { apiKey: sessionApiKey, transport: 'webrtc' });
await session.connect();重要提示:绝对不要将OPENAI_API_KEY发送到浏览器!请在服务器端生成临时会话令牌。
语音Agent切换:切换时,Agent的语音/模型必须保持一致(切换过程中无法更改)
限制:
- 不支持视频流式传输:尽管有摄像头示例,但原生不支持实时视频流式传输。模型可能不会根据视频事件主动发起对话。(Issue #694)
模板:
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):
typescript
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:
- No voice agents
- 30s CPU limit, 128MB memory
- Tracing requires manual setup - set or call
OTEL_SDK_DISABLED=true(Issue #16)startTracingExportLoop()
Next.js: → handler with
app/api/agent/route.tsPOSTrun(agent, message)Templates: ,
cloudflare-workers/nextjs/Cloudflare Workers(实验性支持):
typescript
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 });
}
};限制:
- 不支持语音Agent
- 30秒CPU限制,128MB内存
- 追踪需要手动设置 - 设置或调用
OTEL_SDK_DISABLED=true(Issue #16)startTracingExportLoop()
Next.js: → 包含的处理器
app/api/agent/route.tsrun(agent, message)POST模板:,
cloudflare-workers/nextjs/Error Handling (11+ Errors Prevented)
错误处理(可预防11+种错误)
1. Zod Schema Type Errors
1. Zod Schema类型错误
Error: Type errors with tool parameters.
Workaround: Define schemas inline.
typescript
// ❌ 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
错误:工具参数的类型错误。
解决方法:内联定义schema。
typescript
// ❌ Can cause type errors
parameters: mySchema
// ✅ Works reliably
parameters: z.object({ field: z.string() })说明:从v0.4.1开始,工具调用参数中的无效JSON会被优雅处理(此前会导致SyntaxError崩溃)。(PR #887)
来源:GitHub #188
2. MCP Tracing Errors
2. MCP追踪错误
Error: "No existing trace found" with MCP servers.
Workaround:
typescript
import { initializeTracing } from '@openai/agents/tracing';
await initializeTracing();Source: GitHub #580
错误:MCP服务器出现"No existing trace found"。
解决方法:
typescript
import { initializeTracing } from '@openai/agents/tracing';
await initializeTracing();来源:GitHub #580
3. MaxTurnsExceededError
3. MaxTurnsExceededError
Error: Agent loops infinitely.
Solution: Increase maxTurns or improve instructions:
typescript
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.`错误:Agent无限循环。
解决方案:增加maxTurns或优化指令:
typescript
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
4. ToolCallError
Error: Tool execution fails.
Solution: Retry with exponential backoff:
typescript
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;
}
}错误:工具执行失败。
解决方案:使用指数退避重试:
typescript
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
5. Schema不匹配
Error: Output doesn't match .
outputTypeSolution: Use stronger model or add validation instructions:
typescript
const agent = new Agent({
model: 'gpt-5', // More reliable than gpt-5-mini
instructions: 'CRITICAL: Return JSON matching schema exactly',
outputType: mySchema,
});错误:输出与不匹配。
outputType解决方案:使用更可靠的模型或添加验证指令:
typescript
const agent = new Agent({
model: 'gpt-5', // More reliable than gpt-5-mini
instructions: 'CRITICAL: Return JSON matching schema exactly',
outputType: mySchema,
});6. Reasoning Effort Defaults Changed (v0.4.0)
6. 推理默认值变更(v0.4.0)
Error: Unexpected reasoning behavior after upgrading to v0.4.0.
Why It Happens: Default reasoning effort for gpt-5.1/5.2 changed from to in v0.4.0.
"low""none"Prevention: Explicitly set reasoning effort if you need it.
typescript
// 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
错误:升级到v0.4.0后出现意外的推理行为。
原因:v0.4.0中,gpt-5.1/5.2的默认推理强度从改为。
"low""none"预防措施:如果需要推理功能,请显式设置推理强度。
typescript
// 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'
});来源:Release v0.4.0 | PR #876
7. Reasoning Content Leaks into JSON Output
7. 推理内容泄露到JSON输出
Error: field appears in structured output unexpectedly.
response_reasoningWhy It Happens: Model endpoint issue (not SDK bug) when using with reasoning models.
outputTypeWorkaround: Filter out from output.
response_reasoningtypescript
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.mdTemplate:
templates/shared/error-handling.ts错误:结构化输出中意外出现字段。
response_reasoning原因:使用带推理功能的模型和时的模型端点问题(非SDK bug)。
outputType解决方法:从输出中过滤掉。
response_reasoningtypescript
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.tsOrchestration Patterns
编排模式
LLM-Based: Agent decides routing autonomously (adaptive, higher tokens)
Code-Based: Explicit control flow with conditionals (predictable, lower cost)
Parallel: (concurrent execution)
Promise.all([run(agent1, text), run(agent2, text)])基于LLM:Agent自主决定路由(自适应,令牌消耗较高)
基于代码:通过条件语句实现显式控制流(可预测,成本较低)
并行模式:(并发执行)
Promise.all([run(agent1, text), run(agent2, text)])Debugging
调试
typescript
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:
- Simple OpenAI API calls (use skill instead)
openai-api - Non-OpenAI models exclusively
- Production voice at massive scale (consider LiveKit Agents)
typescript
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 API调用(请改用工具)
openai-api - 仅使用非OpenAI模型
- 大规模生产级语音应用(请考虑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-5-mini - Implement rate limiting
- Log token usage for cost monitoring
- Test handoff flows thoroughly
- Never expose API keys to browsers (use session tokens)
- 将设置为环境变量密钥
OPENAI_API_KEY - 为所有Agent调用实现错误处理
- 为安全关键型应用添加防护机制
- 启用追踪功能以方便调试
- 设置合理的以避免失控成本
maxTurns - 尽可能使用以提高成本效益
gpt-5-mini - 实现速率限制
- 记录令牌使用情况以监控成本
- 彻底测试Agent切换流程
- 绝对不要向浏览器暴露API密钥(使用会话令牌)
Token Efficiency
令牌效率
Estimated 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
预估节省:~60%
| 任务 | 不使用该SDK | 使用该SDK | 节省比例 |
|---|---|---|---|
| 多Agent设置 | ~12k令牌 | ~5k令牌 | 58% |
| 语音Agent | ~10k令牌 | ~4k令牌 | 60% |
| 错误调试 | ~8k令牌 | ~3k令牌 | 63% |
| 平均 | ~10k | ~4k | ~60% |
已预防错误:11种已记录问题 = 100%错误预防
Templates Index
模板索引
Text Agents (8):
- - 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 Agents (3):
9. - Voice setup
10. - React client
11. - Voice delegation
realtime-agent-basic.tsrealtime-session-browser.tsxrealtime-handoffs.tsFramework Integration (4):
12. - Cloudflare Workers
13. - Hono framework
14. - Next.js API
15. - Next.js voice
worker-text-agent.tsworker-agent-hono.tsapi-agent-route.tsapi-realtime-route.tsUtilities (2):
16. - Comprehensive errors
17. - Debugging
error-handling.tstracing-setup.ts文本Agent(8个):
- - 带工具的简单Agent
agent-basic.ts - - 多Agent分诊
agent-handoffs.ts - - Zod schema示例
agent-structured-output.ts - - 实时事件示例
agent-streaming.ts - - 输入验证示例
agent-guardrails-input.ts - - 输出过滤示例
agent-guardrails-output.ts - - 人机协同模式示例
agent-human-approval.ts - - 并发执行示例
agent-parallel.ts
实时Agent(3个):
9. - 语音Agent基础示例
10. - React客户端示例
11. - 语音Agent切换示例
realtime-agent-basic.tsrealtime-session-browser.tsxrealtime-handoffs.ts框架集成(4个):
12. - Cloudflare Workers示例
13. - Hono框架示例
14. - Next.js API示例
15. - Next.js语音示例
worker-text-agent.tsworker-agent-hono.tsapi-agent-route.tsapi-realtime-route.ts工具类(2个):
16. - 综合错误处理示例
17. - 调试追踪设置示例
error-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
- - 编排策略
agent-patterns.md - - 9种错误及解决方法
common-errors.md - - WebRTC vs WebSocket
realtime-transports.md - - Workers限制
cloudflare-integration.md - - 官方文档链接
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
Version: 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
- 文档:https://openai.github.io/openai-agents-js/
- GitHub:https://github.com/openai/openai-agents-js
- npm:https://www.npmjs.com/package/@openai/agents
- 问题反馈:https://github.com/openai/openai-agents-js/issues
版本:SDK v0.4.1
最后验证日期:2026-01-21
技能作者:Jeremy Dawes (Jezweb)
生产环境测试:已通过
变更内容:新增v0.4.0重大变更(Zod 4、推理默认值)、无效JSON处理(v0.4.1)、推理输出泄露、流式传输人机协同模式、Agent作为工具的上下文隔离、视频限制、Cloudflare追踪设置