openai-agents

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

OpenAI 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@4
.
Runtimes: 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
agent.asTool()
, sub-agents do NOT share parent conversation history (intentional design to simplify debugging).
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.asTool()
时,子Agent不会共享父级对话历史(此为有意设计,旨在简化调试)。
解决方法:通过工具参数传递上下文:
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
stream: true
with
requiresApproval
, must explicitly check interruptions:
typescript
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);
}

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: true
requiresApproval
一起使用时,必须显式检查中断:
typescript
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.ts
  • templates/realtime-agents/realtime-session-browser.tsx
  • templates/realtime-agents/realtime-handoffs.ts
References:
  • references/realtime-transports.md
    - WebRTC vs WebSocket

创建
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.ts
  • templates/realtime-agents/realtime-session-browser.tsx
  • templates/realtime-agents/realtime-handoffs.ts
参考文档
  • references/realtime-transports.md
    - WebRTC vs WebSocket

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
    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/

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
    或调用
    startTracingExportLoop()
    (Issue #16)
Next.js
app/api/agent/route.ts
→ 包含
run(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
outputType
.
Solution: 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
"low"
to
"none"
in v0.4.0.
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'
});
错误:升级到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'
});

7. Reasoning Content Leaks into JSON Output

7. 推理内容泄露到JSON输出

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.
typescript
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

错误:结构化输出中意外出现
response_reasoning
字段。
原因:使用带推理功能的模型和
outputType
时的模型端点问题(非SDK bug)。
解决方法:从输出中过滤掉
response_reasoning
typescript
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

Orchestration Patterns

编排模式

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)

基于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
    openai-api
    skill instead)
  • 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
    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-5-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)

  • OPENAI_API_KEY
    设置为环境变量密钥
  • 为所有Agent调用实现错误处理
  • 为安全关键型应用添加防护机制
  • 启用追踪功能以方便调试
  • 设置合理的
    maxTurns
    以避免失控成本
  • 尽可能使用
    gpt-5-mini
    以提高成本效益
  • 实现速率限制
  • 记录令牌使用情况以监控成本
  • 彻底测试Agent切换流程
  • 绝对不要向浏览器暴露API密钥(使用会话令牌)

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

文本Agent(8个):
  1. agent-basic.ts
    - 带工具的简单Agent
  2. agent-handoffs.ts
    - 多Agent分诊
  3. agent-structured-output.ts
    - Zod schema示例
  4. agent-streaming.ts
    - 实时事件示例
  5. agent-guardrails-input.ts
    - 输入验证示例
  6. agent-guardrails-output.ts
    - 输出过滤示例
  7. agent-human-approval.ts
    - 人机协同模式示例
  8. agent-parallel.ts
    - 并发执行示例
实时Agent(3个): 9.
realtime-agent-basic.ts
- 语音Agent基础示例 10.
realtime-session-browser.tsx
- React客户端示例 11.
realtime-handoffs.ts
- 语音Agent切换示例
框架集成(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
- 调试追踪设置示例

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

  1. agent-patterns.md
    - 编排策略
  2. common-errors.md
    - 9种错误及解决方法
  3. realtime-transports.md
    - WebRTC vs WebSocket
  4. cloudflare-integration.md
    - Workers限制
  5. official-links.md
    - 官方文档链接

Official Resources

官方资源


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

版本:SDK v0.4.1 最后验证日期:2026-01-21 技能作者:Jeremy Dawes (Jezweb) 生产环境测试:已通过 变更内容:新增v0.4.0重大变更(Zod 4、推理默认值)、无效JSON处理(v0.4.1)、推理输出泄露、流式传输人机协同模式、Agent作为工具的上下文隔离、视频限制、Cloudflare追踪设置