Doramagic 项目包 · 项目说明书
openai-agents-js 项目
生成时间:2026-05-17 12:58:06 UTC
项目介绍
OpenAI Agents SDK(JavaScript/TypeScript 版本)是一个用于构建 AI Agent 的开发工具包,旨在帮助开发者快速构建、部署和管理智能代理应用。该 SDK 提供了完整的 Agent 生命周期管理、工具集成、流式输出、人类在环(Human-in-the-Loop)控制等功能。资料来源:[examples/basic/README.md:1...
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
OpenAI Agents SDK(JavaScript/TypeScript 版本)是一个用于构建 AI Agent 的开发工具包,旨在帮助开发者快速构建、部署和管理智能代理应用。该 SDK 提供了完整的 Agent 生命周期管理、工具集成、流式输出、人类在环(Human-in-the-Loop)控制等功能。资料来源:examples/basic/README.md:1
核心架构
OpenAI Agents SDK 采用模块化设计,由多个独立的功能包组成,每个包负责特定的功能领域。
包结构
| 包名 | 功能说明 |
|---|---|
@openai/agents-core | 核心包,提供 Agent、工具、运行器等基础功能 |
@openai/agents-extensions | 扩展包,提供 AI SDK UI 集成、沙箱环境等扩展功能 |
@openai/agents-realtime | 实时包,支持构建实时语音代理应用 |
@openai/agents-openai | OpenAI 特定实现,处理 OpenAI API 集成 |
资料来源:packages/agents-extensions/README.md:1
技术架构图
graph TD
A[开发者应用] --> B[@openai/agents]
B --> C[agents-core 核心包]
B --> D[agents-extensions 扩展包]
B --> E[agents-realtime 实时包]
C --> F[Agent 代理]
C --> G[Tools 工具集]
C --> H[Runner 运行器]
F --> I[Handoffs 交接]
F --> J[Guardrails 防护栏]
G --> K[FunctionTool]
G --> L[ComputerTool]
G --> M[ShellTool]
G --> N[FileSearchTool]
G --> O[WebSearchTool]核心概念
Agent(代理)
Agent 是 SDK 的核心组件,代表一个配置了指令、工具、防护栏和交接功能的 AI 代理实例。开发者通过创建 Agent 实例并定义其行为来实现各种智能应用场景。资料来源:packages/agents-core/src/agent.ts:1
import { Agent } from '@openai/agents';
const agent = new Agent({
name: 'Assistant',
instructions: 'Reply with a short answer.',
});
资料来源:examples/ai-sdk-ui/README.md:1
工具系统
SDK 提供了丰富的内置工具,支持开发者扩展 Agent 的能力边界。
| 工具类型 | 描述 | 使用场景 |
|---|---|---|
| FunctionTool | 函数工具,允许调用任意 JavaScript 函数 | 业务逻辑集成 |
| ComputerTool | 计算机工具,支持浏览器自动化操作 | 网页抓取、表单填写 |
| ShellTool | Shell 工具,在沙箱环境中执行命令 | 代码执行、系统操作 |
| FileSearchTool | 文件搜索工具,集成向量搜索能力 | 文档检索、知识库问答 |
| WebSearchTool | 网络搜索工具 | 实时信息查询 |
| CodeInterpreterTool | 代码解释器 | 代码执行、数据分析 |
资料来源:examples/tools/README.md:1-30
工具延迟加载机制
工具支持 deferLoading 属性,允许在 Responses API 中延迟加载顶层函数工具定义,直到工具搜索阶段才加载。资料来源:packages/agents-core/src/tool.ts:1
工具命名空间
多个相关工具可以组织在同一个命名空间下,便于管理和调用:
graph LR
A[Namespace: data] --> B[fileSearch]
A --> C[documentParser]
A --> D[textAnalyzer]
E[Namespace: compute] --> F[calculator]
E --> G[converter]主要功能特性
流式输出
SDK 支持多种流式输出模式,便于构建实时交互应用。
| 示例名称 | 功能说明 | 运行命令 |
|---|---|---|
| stream-text | 流式纯文本响应 | pnpm -F basic start:stream-text |
| stream-items | 流式事件包括工具调用 | pnpm -F basic start:stream-items |
| stream-ws | WebSocket 流式响应 | pnpm -F basic start:stream-ws |
| human-in-the-loop-stream | 人类审批流式版本 | pnpm examples:streamed:human-in-the-loop |
资料来源:examples/basic/README.md:1-20
生命周期管理
SDK 提供了完整的生命周期钩子,允许开发者在 Agent 运行的不同阶段注入自定义逻辑。
| 生命周期事件 | 触发时机 |
|---|---|
| onAgentStart | Agent 开始执行时 |
| onAgentEnd | Agent 完成执行时 |
| onToolStart | 工具开始调用时 |
| onToolEnd | 工具完成调用时 |
| onHandoff | 交接发生时 |
| onGuardrail | 防护栏检查时 |
资料来源:examples/basic/README.md:1
人类在环(Human-in-the-Loop)
支持在工具执行前进行人工审批,确保关键操作经过人工确认。
graph TD
A[Agent 调用工具] --> B{需要人工审批?}
B -->|是| C[暂停等待审批]
C --> D[用户批准/拒绝]
D -->|批准| E[继续执行]
D -->|拒绝| F[终止执行]
B -->|否| E资料来源:examples/agent-patterns/README.md:1
防护栏(Guardrails)
SDK 提供了输入和输出防护栏功能,用于过滤和验证用户输入与模型输出。
| 防护栏类型 | 功能 |
|---|---|
| InputGuardrail | 拒绝不需要的请求 |
| OutputGuardrail | 阻止不安全的输出 |
资料来源:examples/agent-patterns/README.md:1
交接(Handoffs)
Agent 之间支持交接功能,允许构建多代理协作系统。一个 Agent 可以将对话控制权转移给另一个 Agent。
const agentA = new Agent({ name: 'Agent A', handoffs: [agentB] });
const agentB = new Agent({ name: 'Agent B' });
资料来源:packages/agents-core/src/agent.ts:1
Agent 模式示例
基础模式
| 示例名称 | 功能描述 |
|---|---|
| hello-world | 基本 Agent 回复俳句 |
| chat | 交互式 CLI 聊天 |
| dynamic-system-prompt | 动态系统提示 |
资料来源:examples/basic/README.md:1-15
高级模式
| 示例名称 | 功能描述 |
|---|---|
| agents-as-tools | 将代理作为工具使用,实现翻译器编排 |
| agents-as-tools-structured | 使用 Agent.asTool() 实现结构化工具输入 |
| deterministic | 固定代理流程与质量检查 |
| forcing-tool-use | 要求特定工具使用后才输出最终结果 |
| llm-as-a-judge | 使用 LLM 评估故事大纲 |
资料来源:examples/agent-patterns/README.md:1-25
实时语音代理
agents-realtime 包专门用于构建实时语音代理应用,支持语音交互和代理交接功能。
import { RealtimeAgent } from '@openai/agents-realtime';
const voiceAgent = new RealtimeAgent({
name: 'Voice Assistant',
voice: 'alloy',
handoffs: [anotherAgent],
});
资料来源:packages/agents-realtime/src/realtimeAgent.ts:1-20
实时代理配置选项
| 配置项 | 类型 | 描述 |
|---|---|---|
| name | string | 实时代理名称 |
| voice | string | 使用的语音 |
| handoffs | RealtimeAgent[] | 可交接的代理列表 |
| instructions | string | 系统指令 |
模型配置
SDK 支持详细的模型配置选项,包括推理能力设置。
推理模型配置
| 配置项 | 可选值 | 描述 |
|---|---|---|
| effort | none, minimal, low, medium, high, xhigh | 推理工作量的约束 |
| summary | auto, concise, detailed | 推理摘要的详细程度 |
资料来源:packages/agents-core/src/model.ts:1-25
文本配置
| 配置项 | 可选值 | 描述 |
|---|---|---|
| verbosity | low, medium, high | 模型响应的详细程度约束 |
错误处理
SDK 提供了完善的错误处理机制,支持自定义错误处理器。
| 错误类型 | 说明 |
|---|---|
| MaxTurnsExceededError | 超出最大轮次限制 |
| ModelRefusalError | 模型拒绝执行 |
资料来源:packages/agents-core/src/runner/errorHandlers.ts:1-20
安装和使用
基础安装
npm install @openai/agents @openai/agents-extensions
资料来源:packages/agents-extensions/README.md:1
运行示例
项目使用 pnpm 作为包管理器,运行命令格式如下:
# 运行基础示例
pnpm -F basic start:<example-name>
# 运行代理模式示例
pnpm examples:<example-name>
# 运行工具示例
pnpm examples:tools-<tool-name>
资料来源:examples/basic/README.md:1, examples/tools/README.md:1
工具搜索与加载
客户端工具搜索执行器
SDK 支持自定义客户端工具搜索逻辑,通过实现 ClientToolSearchExecutor 接口来实现动态工具加载:
type ClientToolSearchExecutor<Context = UnknownContext> = (
args: ClientToolSearchExecutorArgs<Context>,
) => Tool<Context> | Tool<Context>[] | null | undefined;
资料来源:packages/agents-core/src/tool.ts:1
工具启用条件
工具可以配置动态启用条件,通过 ToolEnabledPredicate 类型定义:
type ToolEnabledPredicate<Context = UnknownContext> = (args: {
runContext: RunContext<Context>;
agent: Agent<any, any>;
}) => boolean | Promise<boolean>;
序列化支持
SDK 提供了工具序列化功能,支持在 Agent 运行前预先序列化和存储工具配置:
| 工具类型 | 序列化字段 |
|---|---|
| function | name, description, parameters, strict, deferLoading, namespace |
| computer | name, environment, dimensions |
| shell | name, environment |
| apply_patch | name |
资料来源:packages/agents-core/src/utils/serialize.ts:1-40
适用场景
| 场景类型 | 推荐使用方式 |
|---|---|
| 对话系统 | 使用基础 Agent + 工具集成 |
| 自动化流程 | 使用 Human-in-the-Loop + 防护栏 |
| 多代理协作 | 使用 Handoffs + 工具代理模式 |
| 实时语音交互 | 使用 RealtimeAgent |
| 代码执行与数据分析 | 使用 CodeInterpreterTool |
| 网页自动化 | 使用 ComputerTool + Playwright |
技术特点
- TypeScript 原生支持:完整的类型定义,良好的开发体验
- 模块化设计:按需引入,减小包体积
- 流式支持:多种流式输出模式
- 可扩展架构:支持自定义工具、执行器和处理器
- 安全防护:内置输入输出防护栏
- 生命周期钩子:完整的运行时代码注入能力
系统架构
OpenAI Agents SDK(openai-agents-js)是一个用于构建 AI Agent 应用的 TypeScript/JavaScript SDK,采用 monorepo 结构管理多个功能包。该 SDK 提供了创建 Agent、定义工具、处理错误、实现安全防护等核心能力,支持与 OpenAI 模型及多种扩展功能集成。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
OpenAI Agents SDK(openai-agents-js)是一个用于构建 AI Agent 应用的 TypeScript/JavaScript SDK,采用 monorepo 结构管理多个功能包。该 SDK 提供了创建 Agent、定义工具、处理错误、实现安全防护等核心能力,支持与 OpenAI 模型及多种扩展功能集成。
资料来源:pnpm-workspace.yaml
整体架构
graph TB
subgraph "主包层"
A["@openai/agents"]
A --> B["agents-core"]
A --> C["agents-openai"]
end
subgraph "核心层 packages/agents-core"
D["Agent 类"]
E["Tool 系统"]
F["Runner 执行器"]
G["Guardrails 防护"]
H["Handoffs 交接"]
I["Error Handlers"]
end
subgraph "扩展层"
J["agents-extensions<br/>扩展包"]
K["agents-realtime<br/>实时语音"]
end
subgraph "示例"
L["examples/basic<br/>基础示例"]
M["examples/agent-patterns<br/>模式示例"]
N["examples/tools<br/>工具集成"]
end
C --> D
C --> E
J --> B
K --> B包结构
| 包名 | 描述 | 依赖关系 |
|---|---|---|
@openai/agents | 主入口包,聚合所有功能 | agents-core, agents-openai |
@openai/agents-core | 核心功能实现 | 无外部依赖 |
@openai/agents-openai | OpenAI 模型适配器 | agents-core |
@openai/agents-extensions | 扩展功能(沙箱等) | agents-core |
@openai/agents-realtime | 实时语音 Agent | agents-core |
资料来源:packages/agents-extensions/README.md
核心组件
Agent 类
Agent 是 SDK 的核心类,泛型设计支持灵活的类型系统:
export class Agent<
TContext = UnknownContext,
TOutput extends AgentOutputType = TextOutput,
>
泛型参数:
| 参数 | 类型 | 说明 |
|---|---|---|
TContext | UnknownContext | Agent 执行的上下文对象,可跨工具、交接、防护传递状态 |
TOutput | AgentOutputType | 输出类型,默认为 TextOutput |
静态工厂方法 create:
static create<
TOutput extends AgentOutputType = TextOutput,
Handoffs extends readonly (Agent<any, any> | Handoff<any, any>)[] = [],
>(config: AgentConfigWithHandoffs...)
资料来源:packages/agents-core/src/agent.ts:1-50
Tool 系统
#### 工具类型体系
classDiagram
class Tool {
<<interface>>
type: 'function' | 'hosted_tool'
}
class FunctionTool {
name: string
description: string
parameters: JsonObjectSchema
strict: boolean
deferLoading?: boolean
invoke()
needsApproval?: boolean
}
class HostedTool {
name: string
providerData?: Record
}
Tool <|-- FunctionTool
Tool <|-- HostedTool#### FunctionTool 核心属性
| 属性 | 类型 | 说明 |
|---|---|---|
name | string | 工具名称 |
description | string | 工具描述,帮助模型理解何时使用 |
parameters | JsonObjectSchema | JSON Schema 参数定义 |
strict | boolean | 是否严格遵循 schema |
deferLoading | boolean | 延迟加载(Responses API 专用) |
invoke | Function | 工具执行函数 |
资料来源:packages/agents-core/src/tool.ts:1-80
#### 工具命名空间
工具支持通过 namespace 属性进行分组管理:
const namespaceName = typeof tool.namespace === 'string'
? tool.namespace.trim()
: '';
同一命名空间下的所有工具必须共享相同的 namespaceDescription。
资料来源:packages/agents-openai/src/openaiResponsesModel.ts:1-50
Handoffs 交接系统
Handoff 允许 Agent 之间进行交接,传递执行上下文:
export type RealtimeAgentConfiguration<TContext = UnknownContext> = {
name: string;
handoffs?: (RealtimeAgent<TContext> | Handoff<RealtimeContextData<TContext>, TextOutput>)[];
voice?: string;
};
资料来源:packages/agents-realtime/src/realtimeAgent.ts:1-30
Guardrails 防护系统
#### 输入防护(Input Guardrails)
在 Agent 处理输入前进行验证和过滤。
#### 输出防护(Output Guardrails)
在 Agent 生成最终输出后进行验证:
export type RunErrorHandlerResult<TAgent extends Agent<any, any>> = {
/**
* 返回的最终输出
*/
finalOutput: ResolvedAgentOutput<TAgent['outputType']>;
/**
* 是否将合成输出追加到历史记录
*/
includeInHistory?: boolean;
};
资料来源:packages/agents-core/src/runner/errorHandlers.ts:1-50
Error Handlers 错误处理
graph LR
A["RunError"] --> B["RunErrorHandlers"]
B --> C["MaxTurnsExceededError"]
B --> D["ModelRefusalError"]
B --> E["default handler"]
F["TryHandleRunErrorArgs"] --> G["buildRunData"]
G --> H["RunErrorData"]错误处理器类型:
export type RunErrorHandlers<
TContext,
TAgent extends Agent<any, any>,
> = Partial<Record<RunErrorKind, RunErrorHandler<TContext, TAgent>>> & {
default?: RunErrorHandler<TContext, TAgent>;
};
资料来源:packages/agents-core/src/runner/errorHandlers.ts:50-100
工具流处理
工具执行结果
stateDiagram-v2
[*] --> ToolCall
ToolCall --> ToolExecution
ToolExecution --> isFinalOutput: true
ToolExecution --> isInterrupted: true
isInterrupted --> RunToolApprovalItem
RunToolApprovalItem --> [*]
isFinalOutput --> [*]ToolsToFinalOutputResult 类型:
| 状态 | 字段 | 说明 |
|---|---|---|
| 非最终输出 | isFinalOutput: false | LLM 将再次运行并接收工具调用输出 |
| 等待审批 | isInterrupted: true | 需要人工审批,interruptions 包含审批项 |
| 最终输出 | isFinalOutput: true | 工具执行完成,返回最终结果 |
资料来源:packages/agents-core/src/agent.ts:150-200
序列化系统
工具支持序列化以支持跨进程传输:
export function serializeTool(tool: Tool<any>): SerializedTool {
if (tool.type === 'function') {
const namespace = getExplicitFunctionToolNamespace(tool);
return {
type: 'function',
name: tool.name,
description: tool.description,
parameters: tool.parameters as JsonObjectSchema<any>,
strict: tool.strict,
deferLoading: tool.deferLoading,
...(namespace ? { namespace } : {}),
};
}
}
支持序列化的工具类型:
| 工具类型 | 可序列化字段 |
|---|---|
function | name, description, parameters, strict, deferLoading, namespace |
computer | name, environment, dimensions |
shell | name, environment |
apply_patch | name |
资料来源:packages/agents-core/src/utils/serialize.ts:1-60
实时语音架构
RealtimeAgent 是专为实时语音场景设计的 Agent 类型:
export type RealtimeAgentConfiguration<TContext = UnknownContext> =
Partial<Omit<
AgentConfiguration<RealtimeContextData<TContext>, TextOutput>,
'model' | 'handoffs' | 'modelSettings' | 'outputType' |
'toolUseBehavior' | 'resetToolChoice' | 'outputGuardrails' | 'inputGuardrails'
>>;
不支持的配置项:
model:同一 RealtimeSession 内的所有 RealtimeAgent 使用相同模型modelSettings:不支持- 其他模型相关配置
资料来源:packages/agents-realtime/src/realtimeAgent.ts:1-50
执行流程
sequenceDiagram
participant U as User
participant R as Runner
participant A as Agent
participant T as Tool
participant M as Model
U->>R: Runner.run(agent, input)
R->>A: 创建 Agent 实例
A->>M: 发送初始请求
M-->>A: 返回响应
A->>T: 调用工具
T-->>A: 工具执行结果
A->>M: 发送工具结果
M-->>A: 返回最终输出
A-->>R: 返回结果
R-->>U: 完成执行扩展机制
Client Tool Search Executor
允许自定义工具搜索和加载逻辑:
export type ClientToolSearchExecutor<Context = UnknownContext> = (
args: ClientToolSearchExecutorArgs<Context>,
) => Tool<Context> | Tool<Context>[] | null | undefined;
export const CLIENT_TOOL_SEARCH_EXECUTOR = Symbol('clientToolSearchExecutor');
资料来源:packages/agents-core/src/tool.ts:150-200
命名空间隔离
工具执行时的路径操作通过 shellQuote 进行安全转义:
resolved_root=$(realpath -m -- "$root")
parent=$(dirname -- "$path")
base=$(basename -- "$path")
resolved_parent=$(realpath -m -- "$parent")
case "$resolved_parent" in "$resolved_root"|"$resolved_root"/*) ;;
*) printf "workspace escape: %s\\n" "$resolved_parent" >&2; exit 111 ;; esac
这确保了沙箱环境中的工作区隔离,防止目录遍历攻击。
资料来源:packages/agents-extensions/src/sandbox/daytona/sandbox.ts:1-50
总结
OpenAI Agents SDK 采用分层架构设计:
- 核心层(agents-core):提供 Agent、Tool、Guardrail、Handoff 等核心抽象
- 适配层(agents-openai):实现与 OpenAI 模型的集成
- 扩展层(agents-extensions、agents-realtime):提供沙箱、实时语音等高级功能
- 入口层(agents):统一导出所有功能
泛型设计贯穿整个系统,支持 TContext 跨组件传递状态,TOutput 定义输出类型约束,实现高度可扩展的 Agent 系统。
资料来源:pnpm-workspace.yaml
Agent 核心机制
Agent(智能体)是 OpenAI Agents SDK 的核心抽象单元,代表一个配置了指令、工具、护栏和交接逻辑的 AI 代理实例。Agent 继承自 AgentHooks 并实现 AgentConfiguration 接口,提供了一套完整的生命周期管理、工具调用、错误处理和状态追踪机制。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
Agent(智能体)是 OpenAI Agents SDK 的核心抽象单元,代表一个配置了指令、工具、护栏和交接逻辑的 AI 代理实例。Agent 继承自 AgentHooks 并实现 AgentConfiguration 接口,提供了一套完整的生命周期管理、工具调用、错误处理和状态追踪机制。
核心职责:
- 解析用户输入并生成模型响应
- 管理工具调用和工具输出处理
- 处理 Agent 之间的交接(handoff)
- 支持输入/输出护栏(Guardrails)
- 提供完整的运行生命周期钩子
资料来源:packages/agents-core/src/agent.ts:85-100
Agent 类架构
继承层次
graph TD
A[Agent<TContext, TOutput>] --> B[AgentHooks<TContext, TOutput>]
B --> C[实现 AgentConfiguration<TContext, TOutput>]Agent 类是一个泛型类,接受两个类型参数:
TContext:上下文类型,用于在工具函数、护栏、交接之间共享状态TOutput:输出类型,默认为TextOutput
资料来源:packages/agents-core/src/agent.ts:82-100
静态工厂方法
Agent 提供了静态方法用于创建实例,支持类型推断:
static create<
TOutput extends AgentOutputType = TextOutput,
Handoffs extends readonly (Agent<any, any> | Handoff<any, any>)[] = [],
>(
config: AgentConfigWithHandoffs<TOutput, Handoffs>
): Agent<UnknownContext, ...>
资料来源:packages/agents-core/src/agent.ts:95-110
核心配置项
AgentConfiguration 接口
| 配置项 | 类型 | 说明 | |
|---|---|---|---|
name | string | Agent 的唯一标识名称 | |
instructions | `string \ | function` | 系统提示或动态指令生成函数 |
model | Model | 使用的语言模型 | |
tools | Tool[] | 可用工具列表 | |
toolOptions | AgentToolOptions | 工具行为配置 | |
handoffs | Handoff[] | 可交接的 Agent 列表 | |
inputGuardrails | InputGuardrail[] | 输入护栏 | |
outputGuardrails | OutputGuardrail[] | 输出护栏 | |
outputType | AgentOutputType | 输出格式类型 |
资料来源:packages/agents-core/src/agent.ts:1-100
工具选项配置
AgentToolOptions 提供了细粒度的工具行为控制:
| 选项 | 类型 | 说明 | |
|---|---|---|---|
toolName | string | 工具名称,覆盖默认的 Agent 名称 | |
toolDescription | string | 工具描述,说明工具用途 | |
customOutputExtractor | function | 自定义输出提取函数 | |
needsApproval | `boolean \ | function` | 是否需要人工批准 |
parameters | TParameters | 参数 Schema 定义 | |
inputBuilder | AgentToolInputBuilder | 构建嵌套 Agent 输入的函数 | |
includeInputSchema | boolean | 是否包含完整 JSON Schema | |
runConfig | RunConfig | 内部 Runner 初始化配置 |
资料来源:packages/agents-core/src/agent.ts:20-65
工具系统
工具类型层次
graph TD
A[Tool<Context>] --> B[FunctionTool]
A --> C[HostedTool]
A --> D[AgentTool]
B --> E[type: 'function']
B --> F[name, description]
B --> G[parameters: JsonObjectSchema]
B --> H[strict: boolean]
B --> I[invoke: function]
B --> J[needsApproval?: boolean]
B --> K[deferLoading?: boolean]FunctionTool 定义
FunctionTool 是将普通函数暴露给 Agent 作为工具的核心类型:
type FunctionTool<
Context = UnknownContext,
TParameters extends ToolInputParameters = undefined,
Result = unknown,
> = {
type: 'function';
name: string;
description: string;
parameters: JsonObjectSchema<any>;
strict: boolean;
deferLoading?: boolean;
invoke: (
runContext: RunContext<Context>,
input: string,
details?: ToolCallDetails,
) => Promise<string | Result>;
needsApproval?: boolean | ToolApprovalFunction<Context>;
};
关键属性说明:
| 属性 | 必填 | 说明 |
|---|---|---|
type | 是 | 固定为 'function' |
name | 是 | 工具唯一名称 |
description | 是 | 帮助模型理解何时调用 |
parameters | 是 | JSON Schema 参数定义 |
strict | 是 | 是否严格遵循 Schema |
invoke | 是 | 实际执行逻辑 |
deferLoading | 否 | 延迟加载(用于 Responses API) |
needsApproval | 否 | 需要人工批准 |
资料来源:packages/agents-core/src/tool.ts:20-60
托管工具 (HostedTool)
托管工具用于包装 API 级别的工具调用:
type HostedTool = {
type: 'hosted_tool';
name: string;
providerData?: Record<string, any>;
};
资料来源:packages/agents-core/src/tool.ts:100-115
交接机制 (Handoff)
Handoff 概念
Handoff 允许一个 Agent 将控制权转移给另一个 Agent,同时可以传递上下文数据。
Handoff 类
export class Handoff<
TContext = UnknownContext,
TOutput extends AgentOutputType = TextOutput,
> {
public agentName: string;
public toolName: string;
public toolDescription: string;
public onHandoff?: OnHandoffCallback<TInputType>;
public inputSchema: JsonSchema;
public isEnabled: HandoffEnabledFunction<TContext>;
public agent: Agent<TContext, TOutput>;
}
资料来源:packages/agents-core/src/handoff.ts:40-75
Handoff 配置选项
| 选项 | 类型 | 说明 |
|---|---|---|
toolNameOverride | string | 自定义工具名称 |
toolDescriptionOverride | string | 自定义工具描述 |
onHandoff | OnHandoffCallback | 交接时执行的回调 |
inputType | ToolInputParameters | 交接输入的 Schema |
资料来源:packages/agents-core/src/handoff.ts:80-100
Handoff 回调签名
type OnHandoffCallback<TInputType extends ToolInputParameters> = (
context: RunContext<any>,
input?: ResolveParsedToolParameters<TInputType>,
) => Promise<void> | void;
资料来源:packages/agents-core/src/handoff.ts:55-60
错误处理系统
RunErrorHandler 类型
错误处理器用于捕获运行时的特定错误并生成最终输出:
type RunErrorHandler<
TContext,
TAgent extends Agent<any, any>,
> = (input: RunErrorHandlerInput<TContext, TAgent>) =>
| RunErrorHandlerResult<TAgent>
| void
| Promise<RunErrorHandlerResult<TAgent> | void>;
资料来源:packages/agents-core/src/runner/errorHandlers.ts:30-40
错误处理输入
type RunErrorHandlerInput<TContext, TAgent extends Agent<any, any>> = {
error: MaxTurnsExceededError | ModelRefusalError;
context: RunContext<TContext>;
runData: RunErrorData<TContext, TAgent>;
};
| 字段 | 类型 | 说明 | |
|---|---|---|---|
error | `MaxTurnsExceededError \ | ModelRefusalError` | 捕获的错误类型 |
context | RunContext<TContext> | 运行上下文 | |
runData | RunErrorData | 运行数据快照 |
资料来源:packages/agents-core/src/runner/errorHandlers.ts:10-25
错误处理结果
type RunErrorHandlerResult<TAgent extends Agent<any, any>> = {
finalOutput: ResolvedAgentOutput<TAgent['outputType']>;
includeInHistory?: boolean;
};
| 字段 | 类型 | 说明 |
|---|---|---|
finalOutput | 泛型 | 最终返回的输出 |
includeInHistory | boolean | 是否将输出追加到历史记录 |
资料来源:packages/agents-core/src/runner/errorHandlers.ts:25-35
错误处理器集合
type RunErrorHandlers<
TContext,
TAgent extends Agent<any, any>,
> = Partial<Record<RunErrorKind, RunErrorHandler<TContext, TAgent>>> & {
default?: RunErrorHandler<TContext, TAgent>;
};
支持按错误类型注册特定处理器,同时提供 default 作为兜底处理器。
工具使用行为
ToolUseBehaviorFlags
export type ToolUseBehaviorFlags = 'run_llm_again' | 'stop_on_first_tool';
| 值 | 行为 |
|---|---|
run_llm_again | LLM 在工具调用后再次运行 |
stop_on_first_tool | 遇到第一个工具调用就停止 |
资料来源:packages/agents-core/src/agent.ts:140-145
ToolsToFinalOutputResult 联合类型
type ToolsToFinalOutputResult =
| { isFinalOutput: false; isInterrupted: undefined }
| { isFinalOutput: false; isInterrupted: true; interruptions: RunToolApprovalItem[] }
| { isFinalOutput: true; ... }
表示工具调用结果的多种可能状态:
- 正常工具调用(非最终输出)
- 被中断等待批准
- 最终输出
实时 Agent
RealtimeAgent 是专用于语音交互场景的特殊 Agent 类型:
export type RealtimeAgentConfiguration<TContext = UnknownContext> = Partial<
Omit<
AgentConfiguration<RealtimeContextData<TContext>, TextOutput>,
| 'model'
| 'handoffs'
| 'modelSettings'
| 'outputType'
| 'toolUseBehavior'
| 'resetToolChoice'
| 'outputGuardrails'
| 'inputGuardrails'
>
> & {
name: string;
handoffs?: (RealtimeAgent<TContext> | Handoff<...>)[];
voice?: string;
};
不支持的配置项:
model:由 Session 统一管理modelSettings:由 Session 统一管理- 其他模型相关配置
资料来源:packages/agents-realtime/src/realtimeAgent.ts:1-40
工具搜索执行器
ClientToolSearchExecutor
用于自定义工具加载逻辑:
type ClientToolSearchExecutor<Context = UnknownContext> = (
args: ClientToolSearchExecutorArgs<Context>,
) => Tool<Context> | Tool<Context>[] | null | undefined;
执行参数:
| 参数 | 类型 | 说明 |
|---|---|---|
agent | Agent<Context, any> | 当前 Agent |
availableTools | Tool<Context>[] | 已加载工具 |
loadDefault | function | 加载默认工具的函数 |
runContext | RunContext<Context> | 运行上下文 |
toolCall | protocol.ToolSearchCallItem | 工具搜索调用项 |
资料来源:packages/agents-core/src/tool.ts:130-160
Agent 执行流程
sequenceDiagram
participant User as 用户输入
participant Runner as Runner
participant Agent as Agent
participant Model as 语言模型
participant Tools as 工具系统
User->>Runner: 启动运行
Runner->>Agent: 初始化 Agent
Agent->>Model: 发送指令和工具定义
Model->>Agent: 返回响应/工具调用
alt 工具调用
Agent->>Tools: 执行工具
Tools-->>Agent: 返回工具结果
Agent->>Model: 发送工具结果
Model->>Agent: 继续响应
end
alt Handoff
Agent->>Agent: 切换到目标 Agent
Note over Agent: 传递上下文
end
alt 错误处理
Agent->>Runner: 捕获错误
Runner->>Runner: 调用错误处理器
end
Agent-->>Runner: 返回最终输出
Runner-->>User: 返回结果类型层次总结
AgentOutputType
├── TextOutput
└── CustomOutput (泛型)
Tool<Context>
├── FunctionTool<Context, TParameters, Result>
├── HostedTool
└── AgentTool
AgentConfiguration<TContext, TOutput>
├── name: string
├── instructions: string | InstructionsFunction
├── model: Model
├── tools: Tool[]
├── handoffs: Handoff[]
├── inputGuardrails: InputGuardrail[]
├── outputGuardrails: OutputGuardrail[]
└── outputType: TOutput
最佳实践
1. 明确的 Agent 命名
使用描述性的名称便于调试和交接:
const agent = Agent.create({
name: 'research-assistant', // 使用 kebab-case
instructions: 'You are a helpful research assistant...',
});
2. 工具描述编写规范
工具描述应清晰说明用途和参数:
const searchTool = createTool({
name: 'web_search',
description: 'Search the web for information. Use for factual queries.',
parameters: { query: z.string() },
// ...
});
3. Handoff 回调使用场景
- 在交接时记录审计日志
- 清理或准备共享上下文
- 触发通知或监控事件
const handoff = new Handoff(agent, async (context, input) => {
context.logger.info(`Handoff to ${agent.name} at ${new Date()}`);
});
4. 错误处理器配置
为常见错误提供友好的兜底输出:
const errorHandlers: RunErrorHandlers = {
[RunErrorKind.MaxTurnsExceeded]: async ({ runData }) => ({
finalOutput: 'Reached maximum turns. Please try a more specific query.',
includeInHistory: true,
}),
default: async ({ error }) => ({
finalOutput: `An error occurred: ${error.message}`,
}),
};
相关文档
工具系统
OpenAI Agents SDK 的工具系统(Tool System)是框架的核心组成部分之一,它使 AI Agent 能够与外部系统交互、执行具体操作并获取实时信息。工具系统提供了标准化的接口定义、类型安全的工具配置、以及完整的工具生命周期管理机制。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
OpenAI Agents SDK 的工具系统(Tool System)是框架的核心组成部分之一,它使 AI Agent 能够与外部系统交互、执行具体操作并获取实时信息。工具系统提供了标准化的接口定义、类型安全的工具配置、以及完整的工具生命周期管理机制。
工具系统在整体架构中扮演以下关键角色:
- 能力扩展:通过工具为 Agent 提供 API 调用、文件操作、代码执行等能力
- 结构化输入输出:支持 JSON Schema 验证的工具参数和返回值
- 生命周期管理:提供工具启动、结束、错误处理等完整的生命周期钩子
- 运行时集成:与 Runner、Agent 等核心组件无缝集成
资料来源:packages/agents-core/src/tool.ts:1-50
工具类型体系
SDK 中定义了多种工具类型,每种类型针对不同的使用场景进行优化。
函数工具(FunctionTool)
函数工具是最常用的工具类型,用于将普通函数暴露给 AI Agent 调用。
export type FunctionTool<
Context = UnknownContext,
TParameters extends ToolInputParameters = undefined,
Result = unknown,
> = {
type: 'function';
name: string;
description: string;
parameters: JsonObjectSchema<any>;
strict: boolean;
deferLoading?: boolean;
invoke: (
runContext: RunContext<Context>,
input: string,
details?: ToolCallDetails,
) => Promise<string | Result>;
needsApproval?: boolean | ToolApprovalFunction<Context>;
};
资料来源:packages/agents-core/src/tool.ts:40-80
| 属性 | 类型 | 必填 | 说明 | |
|---|---|---|---|---|
type | 'function' | 是 | 工具类型标识 | |
name | string | 是 | 工具名称,用于 Agent 识别和调用 | |
description | string | 是 | 工具描述,帮助模型理解何时使用该工具 | |
parameters | JsonObjectSchema<any> | 是 | JSON Schema 描述工具参数 | |
strict | boolean | 是 | 是否严格遵循 Schema | |
deferLoading | boolean | 否 | 延迟加载标志,用于工具搜索场景 | |
invoke | Function | 是 | 工具实际执行逻辑 | |
needsApproval | `boolean \ | Function` | 否 | 是否需要人工审批 |
托管工具(HostedTool)
托管工具由 SDK 内置或第三方服务提供,代表外部能力。
export type HostedTool = {
type: 'hosted_tool';
name: string;
providerData?: Record<string, any>;
};
资料来源:packages/agents-core/src/tool.ts:100-110
| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
type | 'hosted_tool' | 是 | 工具类型标识 |
name | string | 是 | 工具唯一名称 |
providerData | Record<string, any> | 否 | 传递给工具的额外配置数据 |
客户端工具搜索执行器
客户端工具搜索执行器允许在运行时动态解析和加载工具。
export type ClientToolSearchExecutor<Context = UnknownContext> = (
args: ClientToolSearchExecutorArgs<Context>,
) =>
| Tool<Context>
| Tool<Context>[]
| null
| undefined
| Promise<ClientToolSearchExecutorResult<Context>>;
资料来源:packages/agents-core/src/tool.ts:130-145
工具创建与配置
基础工具创建
使用 functionTool 辅助函数创建标准工具:
import { functionTool } from '@openai/agents-core';
const calculator = functionTool({
name: 'calculator',
description: 'Perform mathematical calculations',
parameters: {
type: 'object',
properties: {
expression: { type: 'string', description: 'Math expression' }
},
required: ['expression']
},
strict: true,
execute: async (runContext, input) => {
// 实现计算逻辑
return result;
}
});
Agent 作为工具
Agent 可以被包装为工具供其他 Agent 调用,实现多 Agent 协作:
export type AgentToolOptions<
TContext,
TAgent extends Agent<TContext, any>,
TParameters extends AgentToolInputParameters,
> = {
toolName?: string;
toolDescription?: string;
customOutputExtractor?: (output: CompletedAgentToolInvocationRunResult<TContext, TAgent>) => string | Promise<string>;
needsApproval?: boolean | ToolApprovalFunction<TParameters>;
parameters?: TParameters;
inputBuilder?: AgentToolInputBuilder<TParameters>;
includeInputSchema?: boolean;
};
资料来源:packages/agents-core/src/agent.ts:1-50
| 配置项 | 类型 | 说明 | |
|---|---|---|---|
toolName | string | 工具名称,默认使用 Agent 名称 | |
toolDescription | string | 工具描述 | |
customOutputExtractor | Function | 自定义输出提取器 | |
needsApproval | `boolean \ | Function` | 是否需要人工审批 |
parameters | AgentToolInputParameters | 工具输入参数 Schema | |
inputBuilder | AgentToolInputBuilder | 嵌套 Agent 输入构建器 | |
includeInputSchema | boolean | 是否包含完整 JSON Schema |
工具启用条件
可以使用条件表达式动态控制工具是否可用:
type ToolEnabledPredicate<Context = UnknownContext> = (args: {
runContext: RunContext<Context>;
agent: Agent<any, any>;
}) => boolean | Promise<boolean>;
type ToolEnabledOption<Context = UnknownContext> =
| boolean
| ToolEnabledPredicate<Context>;
工具执行流程
graph TD
A[Agent 决策] --> B{工具调用请求}
B -->|FunctionTool| C[invoke 函数]
B -->|HostedTool| D[托管服务调用]
B -->|MCP Tool| E[MCP 协议通信]
C --> F[参数验证]
F --> G{验证通过?}
G -->|是| H[执行业务逻辑]
G -->|否| I[返回错误]
H --> J[结果序列化]
J --> K[返回给 Agent]
D --> K
E --> K
I --> K工具调用结果处理
SDK 定义了 ToolsToFinalOutputResult 类型来描述工具执行后的状态:
export type ToolsToFinalOutputResult =
| {
isFinalOutput: false;
isInterrupted: undefined;
}
| {
isFinalOutput: false;
isInterrupted: true;
interruptions: RunToolApprovalItem[];
}
| {
isFinalOutput: false;
// ... 其他状态
};
资料来源:packages/agents-core/src/agent.ts:80-110
错误处理机制
SDK 提供了完整的工具执行错误处理框架:
export type RunErrorHandler<TContext, TAgent extends Agent<any, any>> = (
input: RunErrorHandlerInput<TContext, TAgent>,
) =>
| RunErrorHandlerResult<TAgent>
| void
| Promise<RunErrorHandlerResult<TAgent> | void>;
export type RunErrorHandlers<
TContext,
TAgent extends Agent<any, any>,
> = Partial<Record<RunErrorKind, RunErrorHandler<TContext, TAgent>>> & {
default?: RunErrorHandler<TContext, TAgent>;
};
资料来源:packages/agents-core/src/runner/errorHandlers.ts:1-60
| 错误处理类型 | 说明 |
|---|---|
MaxTurnsExceededError | 最大轮次超限错误处理 |
ModelRefusalError | 模型拒绝执行错误处理 |
default | 通用错误默认处理 |
工具搜索与延迟加载
工具系统支持延迟加载机制,允许按需加载工具定义:
延迟加载函数工具
function isTopLevelDeferredFunctionTool(tool: Tool<any>): boolean {
return tool.type === 'function' && tool.deferLoading === true;
}
function getDeferredFunctionToolsByName(
tools: Tool<any>[],
): Map<string, FunctionTool<any>> {
return new Map(
tools
.filter(isTopLevelDeferredFunctionTool)
.map((tool) => [tool.name, tool] as const),
);
}
资料来源:packages/agents-core/src/runner/toolSearch.ts:1-30
延迟加载命名空间工具
SDK 支持命名空间分组管理延迟加载的工具:
function getDeferredNamespaceToolsByName(
tools: Tool<any>[],
): Map<string, DeferredNamespaceTools> {
const namespaces = new Map<string, DeferredNamespaceTools>();
for (const tool of tools) {
if (!isDeferredFunctionTool(tool)) {
continue;
}
const namespace = getExplicitFunctionToolNamespace(tool);
if (!namespace) {
continue;
}
// ... 命名空间处理逻辑
}
return namespaces;
}
资料来源:packages/agents-core/src/runner/toolSearch.ts:50-80
工具序列化
工具配置可以被序列化用于传输或持久化:
export function serializeTool(tool: Tool<any>): SerializedTool {
if (tool.type === 'function') {
const namespace = getExplicitFunctionToolNamespace(tool);
return {
type: 'function',
name: tool.name,
description: tool.description,
parameters: tool.parameters as JsonObjectSchema<any>,
strict: tool.strict,
deferLoading: tool.deferLoading,
...(namespace ? { namespace } : {}),
};
}
// ... 其他工具类型序列化
}
资料来源:packages/agents-core/src/utils/serialize.ts:1-50
工具使用示例
基础工具示例
import { Agent, functionTool } from '@openai/agents-core';
const fetchWeather = functionTool({
name: 'fetch_weather',
description: 'Get current weather for a location',
parameters: {
type: 'object',
properties: {
location: {
type: 'string',
description: 'City name'
}
},
required: ['location']
},
strict: true,
execute: async (runContext, input) => {
const { location } = JSON.parse(input);
// 调用天气 API
return JSON.stringify({ location, temperature: 22 });
}
});
Agent 作为工具
const translator = Agent.from({
name: 'translator',
instructions: 'Translate text to target language',
outputType: TextOutput
});
const mainAgent = Agent.from({
name: 'main',
instructions: 'You can use the translator tool to translate content',
tools: [
translator.asTool({
toolName: 'translate',
toolDescription: 'Translate text between languages',
parameters: translateParamsSchema
})
]
});
架构总览
graph TD
subgraph 核心层
A[Agent]
B[Runner]
C[Tool System]
end
subgraph 工具类型
D[FunctionTool]
E[HostedTool]
F[ComputerTool]
G[ShellTool]
H[MCPTool]
end
subgraph 工具生命周期
I[工具注册]
J[工具搜索]
K[工具执行]
L[结果处理]
end
C --> D
C --> E
C --> F
C --> G
C --> H
A --> C
B --> C
I --> J
J --> K
K --> L最佳实践
- 参数 Schema 定义:使用精确的 JSON Schema 定义工具参数,包含描述和类型约束
- 严格模式:启用
strict: true确保模型严格遵循参数规范 - 人工审批:对于敏感操作设置
needsApproval: true - 延迟加载:大量工具场景下使用
deferLoading优化初始化性能 - 命名空间管理:相关工具使用命名空间分组,便于管理和搜索
Handoffs 与 Agent 委托
Handoffs(交接)是 OpenAI Agents SDK 中实现多代理协作的核心机制。当一个 Agent 需要将对话控制权转移给另一个 Agent 时,Handoff 机制会完整地传递对话历史,使目标 Agent 能够无缝继续对话流程。资料来源:[packages/agents-core/src/agent.ts:1-100]()
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
Handoffs(交接)是 OpenAI Agents SDK 中实现多代理协作的核心机制。当一个 Agent 需要将对话控制权转移给另一个 Agent 时,Handoff 机制会完整地传递对话历史,使目标 Agent 能够无缝继续对话流程。资料来源:packages/agents-core/src/agent.ts:1-100
与 Handoff 不同的是 Agent 委托(Agent as Tool),它将一个 Agent 作为工具使用,目标 Agent 接收的是生成的输入而非完整对话历史,并且对话由原始 Agent 继续控制。资料来源:packages/agents-core/src/agent.ts:60-80
核心概念对比
| 特性 | Handoff | Agent as Tool |
|---|---|---|
| 对话历史传递 | 完整历史转移 | 不传递,需通过 inputBuilder 构建输入 |
| 控制权 | 完全转移给新 Agent | 原始 Agent 继续控制对话 |
| 使用场景 | 多角色切换、任务委派 | 工具化调用、嵌套推理 |
| 输入来源 | 历史消息 | 生成的参数 |
架构设计
graph TD
A[User Input] --> B[Primary Agent]
B --> C{Handoff Trigger?}
C -->|Yes| D[Handoff Tool Call]
D --> E[目标 Agent 接收完整历史]
C -->|No| F[继续当前 Agent]
E --> G[对话由目标 Agent 控制]
F --> H[执行工具或生成响应]
B --> I{asTool 调用?}
I -->|Yes| J[AgentTool Invocation]
J --> K[目标 Agent 作为工具执行]
K --> L[结果返回给原始 Agent]
L --> BHandoff 组件详解
Handoff 类
Handoff 类是交接机制的核心实现,封装了源 Agent 到目标 Agent 的转换逻辑。资料来源:packages/agents-core/src/handoff.ts:50-80
export class Handoff<
TContext = UnknownContext,
TOutput extends AgentOutputType = TextOutput,
> {
public agentName: string;
public onInvokeHandoff: (
context: RunContext<TContext>,
args: string,
) => Promise<Agent<TContext, TOutput>> | Agent<TContext, TOutput>;
public toolName: string;
public toolDescription: string;
public agent: Agent<TContext, TOutput>;
public isEnabled: HandoffEnabledFunction<TContext> = async () => true;
constructor(
agent: Agent<TContext, TOutput>,
onInvokeHandoff: (context: RunContext<TContext>, args: string) => Promise<Agent<TContext, TOutput>> | Agent<TContext, TOutput>,
) {
this.agentName = agent.name;
this.onInvokeHandoff = onInvokeHandoff;
this.toolName = defaultHandoffToolName(agent);
this.toolDescription = defaultHandoffToolDescription(agent);
this.agent = agent;
}
}
HandoffConfig 配置选项
| 配置项 | 类型 | 说明 |
|---|---|---|
toolNameOverride | string | 自定义 Handoff 工具名称 |
toolDescriptionOverride | string | 自定义 Handoff 工具描述 |
onHandoff | OnHandoffCallback<TInputType> | 交接触发时的回调函数 |
inputType | TInputType extends ToolInputParameters | 输入参数类型,支持 Zod Schema |
资料来源:packages/agents-core/src/handoff.ts:80-120
OnHandoffCallback 回调
export type OnHandoffCallback<TInputType extends ToolInputParameters> = (
context: RunContext<any>,
input?: ResolveParsedToolParameters<TInputType>,
) => Promise<void> | void;
回调函数在 Handoff 被触发时执行,可用于日志记录、数据收集或状态更新。资料来源:packages/agents-core/src/handoff.ts:70-75
HandoffEnabledFunction 条件启用
type HandoffEnabledFunction<TContext = UnknownContext> = (
context: RunContext<TContext>,
args?: string,
) => boolean | Promise<boolean>;
通过此函数可以实现基于上下文的条件性 Handoff,例如根据用户偏好或功能开关控制交接是否可用。资料来源:examples/handoffs/README.md
Agent 类的 Handoff 支持
handoffs 属性
export class Agent<
TContext = UnknownContext,
TOutput extends AgentOutputType = TextOutput,
> extends AgentHooks<TContext, TOutput>
implements AgentConfiguration<TContext, TOutput>
{
handoffs: (Agent<any, TOutput> | Handoff<any, TOutput>)[];
// ... 其他属性
}
Agent 的 handoffs 数组包含该 Agent 可以交接到的所有目标 Agent 或 Handoff 实例。资料来源:packages/agents-core/src/agent.ts:120-130
HandoffsOutputUnion 类型推导
type ExtractAgentOutput<T> = T extends Agent<any, infer O> ? O : never;
type ExtractHandoffOutput<T> = T extends Handoff<any, infer O> ? O : never;
export type HandoffsOutputUnion<
Handoffs extends readonly (Agent<any, any> | Handoff<any, any>)[],
> =
| ExtractAgentOutput<Handoffs[number]>
| ExtractHandoffOutput<Handoffs[number]>;
此类型工具自动从 Handoff 列表中提取输出类型的联合类型,确保类型安全。资料来源:packages/agents-core/src/agent.ts:160-175
Agent.create 静态工厂方法
static create<
TOutput extends AgentOutputType = TextOutput,
Handoffs extends readonly (Agent<any, any> | Handoff<any, any>)[] = [],
>(
config: AgentConfigWithHandoffs<TOutput, Handoffs>,
): Agent<UnknownContext, TOutput | HandoffsOutputUnion<Handoffs>> {
return new Agent<UnknownContext, TOutput | HandoffsOutputUnion<Handoffs>>({
...config,
handoffs: config.handoffs as any,
outputType: config.outputType,
handoffOutputTypeWarningEnabled: false,
});
}
Agent.create() 方法自动推断 Handoff 输出的联合类型,是创建带 Handoff 的 Agent 的推荐方式。资料来源:packages/agents-core/src/agent.ts:85-100
Agent as Tool(委托)
asTool 方法重载
export class Agent<...> {
asTool<TAgent extends Agent<TContext, TOutput> = Agent<TContext, TOutput>>(
this: TAgent,
options: AgentToolOptionsWithDefault<TContext, TAgent>,
): AgentTool<TContext, TAgent, typeof AgentAsToolInputSchema>;
asTool<
TAgent extends Agent<TContext, TOutput> = Agent<TContext, TOutput>,
TParameters extends AgentToolInputParameters = typeof AgentAsToolInputSchema,
>(
this: TAgent,
options: AgentToolOptionsWithParameters<TContext, TAgent, TParameters>,
): AgentTool<TContext, TAgent, TParameters>;
}
asTool() 方法将 Agent 转换为可被其他 Agent 调用的工具。与 Handoff 的关键区别在于:资料来源:packages/agents-core/src/agent.ts:60-90
- 对话历史不传递:新 Agent 接收的是生成的输入,而非完整对话历史
- 控制权不转移:对话由原始 Agent 继续控制
- 结果返回:被委托 Agent 的结果作为工具输出返回给调用者
AgentToolOptions 配置参数
| 参数 | 类型 | 说明 | |
|---|---|---|---|
toolName | string | 工具名称,默认为 Agent 名称 | |
toolDescription | string | 工具描述,说明工具用途 | |
customOutputExtractor | function | 自定义输出提取器 | |
needsApproval | `boolean \ | ToolApprovalFunction` | 调用前是否需要审批 |
parameters | TParameters | 输入参数 Schema | |
inputBuilder | AgentToolInputBuilder<TParameters> | 构建嵌套 Agent 输入 | |
includeInputSchema | boolean | 是否包含完整 JSON Schema |
资料来源:packages/agents-core/src/agent.ts:130-180
RealtimeAgent 中的 Handoff
export type RealtimeAgentConfiguration<TContext = UnknownContext> = Partial<
Omit<
AgentConfiguration<RealtimeContextData<TContext>, TextOutput>,
'model' | 'handoffs' | 'modelSettings' | 'outputType' | 'toolUseBehavior'
>
> & {
name: string;
handoffs?: (
| RealtimeAgent<TContext>
| Handoff<RealtimeContextData<TContext>, TextOutput>
)[];
voice?: string;
};
RealtimeAgent 支持 Handoff,但不支持 model、modelSettings 等配置,因为所有 RealtimeAgent 在同一个 RealtimeSession 中由相同模型处理。资料来源:packages/agents-core/src/realtimeAgent.ts:1-40
Handoff 解析与执行
modelOutputs.ts 中的解析逻辑
export function resolveToolCall(
toolCall: FunctionToolCall,
agent: Agent<any, any>,
tools: Tool<any>[],
handoffs: (Agent<any, any> | Handoff<any, any>)[],
priorItems: RunItem[],
): { type: 'handoff'; handoff: Handoff<any, any> } | { type: 'function'; tool: FunctionTool<any> } {
const resolvedToolName = resolveFunctionToolCallName(toolCall, functionMap) ?? toolCall.name;
if (functionTool && handoff && resolvedToolName.includes('.')) {
throw new ModelBehaviorError(
`Ambiguous dotted tool call ${resolvedToolName} in agent ${agent.name}: it matches both a namespaced function tool and a handoff.`
);
}
if (handoff) {
return { type: 'handoff', handoff };
}
// ...
}
系统会解析工具调用名称,如果同时匹配函数工具和 Handoff,会抛出歧义错误。资料来源:packages/agents-core/src/runner/modelOutputs.ts:1-60
handoffMap 和 functionMap 初始化
const handoffMap = new Map(handoffs.map((h) => [h.toolName, h]));
const functionMap = new Map(
tools
.filter((t): t is FunctionTool<TContext> => t.type === 'function')
.map((t) => [getFunctionToolQualifiedName(t) ?? t.name, t]),
);
通过 Map 数据结构实现 O(1) 时间复杂度的工具查找。资料来源:packages/agents-core/src/runner/modelOutputs.ts:80-100
使用示例
基础 Handoff 用法
import { Agent, Handoff } from '@openai/agents-core';
const spanishAgent = Agent.create({
name: 'Spanish Agent',
instructions: 'You only speak Spanish.',
handoffDescription: 'For Spanish language requests',
});
const triageAgent = Agent.create({
name: 'Triage Agent',
instructions: 'Route requests to the appropriate agent.',
handoffs: [spanishAgent],
});
带条件的 Handoff
const spanishHandoff = new Handoff(spanishAgent, {
inputType: z.object({ reason: z.string() }),
isEnabled: async (context) => {
const userPrefs = context.context.userPreferences;
return userPrefs.language === 'es';
},
onHandoff: async (context) => {
console.log(`Handoff to Spanish agent triggered`);
},
});
Agent as Tool 用法
const translatorAgent = Agent.create({
name: 'Translator',
instructions: 'Translate the following text to Spanish.',
});
const mainAgent = Agent.create({
name: 'Main Agent',
instructions: 'Use the translator when needed.',
tools: [translatorAgent.asTool({
toolName: 'translate_to_spanish',
toolDescription: 'Translate English text to Spanish',
})],
});
资料来源:examples/agent-patterns/README.md
生命周期事件
export type AgentHookEvents<TContext> = {
agent_handoff: [
context: RunContext<TContext>,
nextAgent: Agent<any, any>,
];
agent_tool_start: [
context: RunContext<TContext>,
tool: Tool<any>,
details: { toolCall: protocol.ToolCallItem },
];
agent_tool_end: [
context: RunContext<TContext>,
tool: Tool<any>,
result: string,
details: { toolCall: protocol.ToolCallItem },
];
};
agent_handoff 事件在 Handoff 发生时触发,可用于监控和日志记录。资料来源:packages/agents-core/src/lifecycle.ts:1-50
最佳实践
| 场景 | 推荐方案 |
|---|---|
| 多角色对话 | 使用 Handoff |
| 工具化调用 | 使用 asTool |
| 需要条件判断 | 实现 HandoffEnabledFunction |
| 状态同步 | 使用 OnHandoffCallback |
| 类型安全 | 使用 Agent.create() 工厂方法 |
| 避免歧义 | 不要让 Handoff 工具名与函数工具名冲突 |
总结
Handoffs 与 Agent 委托是实现多代理协作的两种互补机制:
- Handoff:适合角色切换、任务委派场景,完整传递对话历史,控制权完全转移
- Agent as Tool:适合工具化调用、子任务执行场景,通过参数传递输入,控制权保持在调用者
合理选择和组合这两种机制,可以构建出复杂而灵活的多代理系统架构。
Guardrails 安全防护
Guardrails(安全防护)是 openai-agents-js 框架中用于在 Agent 运行过程中对输入、输出和工具调用进行安全检查和质量控制的机制。Guardrails 允许开发者在 AI 模型生成响应之前(输入阶段)或之后(输出阶段)插入自定义验证逻辑,从而实现:
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
Guardrails(安全防护)是 openai-agents-js 框架中用于在 Agent 运行过程中对输入、输出和工具调用进行安全检查和质量控制的机制。Guardrails 允许开发者在 AI 模型生成响应之前(输入阶段)或之后(输出阶段)插入自定义验证逻辑,从而实现:
- 过滤有害或不安全的用户输入
- 阻止包含敏感信息的模型输出
- 验证工具调用的安全性
- 实现业务规则合规检查
资料来源:packages/agents-core/src/guardrail.ts:1-50
Guardrails 类型体系
框架支持两种主要的 Guardrail 类型,分别用于不同的检查阶段:
| Guardrail 类型 | 作用阶段 | 检查内容 | 命名空间 |
|---|---|---|---|
| InputGuardrail | 模型调用前 | 用户输入、对话历史 | inputGuardrails |
| OutputGuardrail | 模型调用后 | 模型生成的文本、结构化输出 | outputGuardrails |
| ToolOutputGuardrail | 工具执行后 | 工具返回的结果内容 | toolOutputGuardrails |
资料来源:packages/agents-core/src/guardrail.ts:10-60
输出防护(Output Guardrail)
核心接口定义
export interface OutputGuardrail<
TOutput extends AgentOutputType = TextOutput,
TContext = UnknownContext,
> {
name: string;
execute: OutputGuardrailFunction<TOutput, TContext>;
}
资料来源:packages/agents-core/src/guardrail.ts:30-40
OutputGuardrail 接口包含两个必需属性:
- name: 防护规则的唯一标识名称
- execute: 执行检查的异步函数
定义函数
开发者使用 defineOutputGuardrail 工厂函数创建 OutputGuardrail 实例:
export function defineOutputGuardrail<
TOutput extends AgentOutputType = TextOutput,
TContext = UnknownContext,
>({
name,
execute,
}: DefineOutputGuardrailArgs<TOutput, TContext>): OutputGuardrailDefinition<TOutput, TContext>
资料来源:packages/agents-core/src/guardrail.ts:70-85
元数据定义
export interface OutputGuardrailMetadata {
type: 'output';
name: string;
}
export interface OutputGuardrailDefinition<
TMeta = OutputGuardrailMetadata,
TOutput extends AgentOutputType = TextOutput,
TContext = UnknownContext,
> extends OutputGuardrailMetadata {
guardrailFunction: OutputGuardrailFunction<TOutput, TContext>;
run(args: OutputGuardrailFunctionArgs<TContext, TOutput>): Promise<GuardrailFunctionOutput>;
}
资料来源:packages/agents-core/src/guardrail.ts:42-55
工具输出防护(Tool Output Guardrail)
ToolOutputGuardrail 专门用于检查工具执行后的返回结果,防止工具泄露敏感信息或返回不符合预期的内容。
工具输出防护初始化
export type ToolOutputGuardrailInit<TContext> = {
name: string;
run: (
context: RunContext<TContext>,
result: ToolResult,
) => Promise<GuardrailFunctionOutput>;
};
资料来源:packages/agents-core/src/toolGuardrail.ts:1-20
工具输出防护工厂函数
export function defineToolOutputGuardrail<TContext>(
guardrail: ToolOutputGuardrailInit<TContext>
): ToolOutputGuardrailDefinition<TContext>
资料来源:packages/agents-core/src/toolGuardrail.ts:22-35
防护注册转换
guardrailsFromInit 函数负责将初始化配置转换为完整的防护定义:
export function guardrailsFromInit<TContext>(
guardrails: ToolOutputGuardrailInit<TContext>[]
): ToolOutputGuardrailDefinition<TContext>[] {
if (!guardrails) {
return [];
}
return guardrails.map((gr) =>
'type' in gr && gr.type === 'tool_output'
? (gr as ToolOutputGuardrailDefinition<TContext>)
: defineToolOutputGuardrail(gr as { name: string; run: any }),
);
}
资料来源:packages/agents-core/src/toolGuardrail.ts:38-52
错误处理与防护联动
框架将错误处理与 Guardrail 系统紧密集成,通过 RunErrorHandlers 类型支持对特定错误类型执行防护检查。
错误处理器类型
export type RunErrorHandler<TContext, TAgent extends Agent<any, any>> = (
input: RunErrorHandlerInput<TContext, TAgent>,
) => RunErrorHandlerResult<TAgent> | void | Promise<RunErrorHandlerResult<TAgent> | void>;
资料来源:packages/agents-core/src/runner/errorHandlers.ts:60-65
错误处理器结果
export type RunErrorHandlerResult<TAgent extends Agent<any, any>> = {
finalOutput: ResolvedAgentOutput<TAgent['outputType']>;
includeInHistory?: boolean;
};
资料来源:packages/agents-core/src/runner/errorHandlers.ts:48-55
错误处理注册表
export type RunErrorHandlers<TContext, TAgent extends Agent<any, any>> =
Partial<Record<RunErrorKind, RunErrorHandler<TContext, TAgent>>> & {
default?: RunErrorHandler<TContext, TAgent>;
};
资料来源:packages/agents-core/src/runner/errorHandlers.ts:67-73
Agent 配置中的 Guardrails
在创建 Agent 实例时,通过配置对象传入 Guardrails:
export class Agent<
TContext = UnknownContext,
TOutput extends AgentOutputType = TextOutput,
> extends AgentHooks<TContext, TOutput>
implements AgentConfiguration<TContext, TOutput>
资料来源:packages/agents-core/src/agent.ts:45-60
Agent 支持在配置中定义 inputGuardrails 和 outputGuardrails 数组,这些防护规则会在相应的生命周期阶段被自动调用。
架构流程图
graph TD
A[用户输入] --> B{Input Guardrails}
B -->|通过| C[Agent 推理]
B -->|拒绝| Z[返回错误]
C --> D[工具调用]
D --> E{Tool Output Guardrails}
E -->|通过| F[Agent 输出]
E -->|拒绝| Z
F --> G{Output Guardrails}
G -->|通过| H[返回结果]
G -->|拒绝| Z
style Z fill:#ff6b6b
style H fill:#51cf66使用示例
创建输出防护
import { defineOutputGuardrail } from '@openai/agents';
const contentFilter = defineOutputGuardrail({
name: 'content-filter',
execute: async ({ context, response }) => {
const flagged = await checkForHarmfulContent(response.content);
return {
decision: flagged ? 'flagged' : 'pass',
reason: flagged ? 'Content violates safety policy' : undefined,
};
},
});
创建工具输出防护
import { defineToolOutputGuardrail } from '@openai/agents';
const fileSystemGuard = defineToolOutputGuardrail({
name: 'file-system-filter',
run: async (context, result) => {
const sensitivePaths = ['/etc/passwd', '/root/.ssh'];
if (sensitivePaths.some(p => result.output.includes(p))) {
return { decision: 'flagged', reason: 'Access to sensitive path denied' };
}
return { decision: 'pass' };
},
});
防护决策类型
| 决策值 | 含义 | 后续动作 |
|---|---|---|
pass | 检查通过 | 继续执行 |
flagged | 检查发现问题 | 返回错误或拒绝输出 |
neutral | 无法判断 | 根据配置决定放行或拒绝 |
总结
Guardrails 安全防护系统为 openai-agents-js 提供了多层安全检查机制:
- 输入层防护 (
Input Guardrails): 在模型处理前过滤有害输入 - 工具层防护 (
Tool Output Guardrails): 验证工具返回内容的安全性 - 输出层防护 (
Output Guardrails): 检查最终响应的合规性
该系统采用声明式配置方式,通过统一的 defineXxxGuardrail 工厂函数创建防护实例,并支持异步执行和上下文感知检查,适配企业级应用的复杂安全需求。
沙箱 Agent
沙箱 Agent(Sandbox Agent)是 OpenAI Agents SDK 中的一种专用 Agent 类型,它继承自基础 Agent 类并在运行时环境中提供了安全的代码执行能力。沙箱 Agent 允许 AI Agent 在隔离的运行时环境中执行代码、访问文件系统并运行各种工具,同时保持安全边界以防止对主机系统的未授权访问。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
沙箱 Agent(Sandbox Agent)是 OpenAI Agents SDK 中的一种专用 Agent 类型,它继承自基础 Agent 类并在运行时环境中提供了安全的代码执行能力。沙箱 Agent 允许 AI Agent 在隔离的运行时环境中执行代码、访问文件系统并运行各种工具,同时保持安全边界以防止对主机系统的未授权访问。
沙箱 Agent 的核心职责包括:
- 在隔离环境中执行 Agent 生成的代码
- 管理文件系统的读写操作权限
- 提供可配置的运行时 Manifest 定义允许的操作范围
- 支持以指定用户身份运行以实现权限隔离
资料来源:agent.ts:1-50
架构设计
继承关系
沙箱 Agent 继承自标准的 Agent 类,并扩展了沙箱特定的功能。这种设计允许沙箱 Agent 复用 Agent 的所有核心功能,包括工具调用、handoffs、guardrails 和生命周期钩子。
graph TD
A[Agent<TContext, TOutput>] -->|extends| B[AgentHooks]
B --> C[Agent]
C -->|extends| D[SandboxAgent<TContext, TOutput>]
E[AgentConfiguration] -->|提供配置接口| C
F[SandboxAgentOptions] -->|扩展配置| E资料来源:agent.ts:50-80
核心组件
| 组件 | 类型 | 说明 | |
|---|---|---|---|
defaultManifest | `Manifest \ | undefined` | 默认的沙箱 Manifest,定义允许的操作范围 |
baseInstructions | SandboxBaseInstructions | 基础指令,传递给沙箱运行的代码 | |
capabilities | Capability[] | 沙箱能力数组,控制可用功能 | |
runAs | `string \ | SandboxUser` | 以特定用户身份运行的配置 |
runtimeManifest | Manifest | 运行时 Manifest,可动态更新 |
资料来源:agent.ts:35-45
SandboxAgent 类
类定义
export class SandboxAgent<
TContext = UnknownContext,
TOutput extends AgentOutputType = TextOutput,
> extends Agent<TContext, TOutput>
implements SandboxAgentOptions<TContext, TOutput>
{
// ... 实现代码
}
沙箱 Agent 是一个泛型类,接受两个类型参数:
TContext:运行上下文类型,默认为UnknownContextTOutput:输出类型,默认为TextOutput
资料来源:agent.ts:50-60
构造函数
构造函数接收 SandboxAgentOptions 配置对象,并对配置进行验证:
constructor(config: SandboxAgentOptions<TContext, TOutput>) {
super(config);
// 验证 baseInstructions 类型
if (
config.baseInstructions !== undefined &&
typeof config.baseInstructions !== 'string' &&
typeof config.baseInstructions !== 'function'
) {
throw new TypeError(
'SandboxAgent baseInstructions must be a string or function.',
);
}
// 初始化沙箱配置
this.defaultManifest = config.defaultManifest
? cloneManifest(config.defaultManifest)
: undefined;
this.baseInstructions = config.baseInstructions;
this.capabilities = config.capabilities ?? Capabilities.default();
this.runAs = normalizeRunAs(config.runAs);
this.runtimeManifest = this.defaultManifest ?? new Manifest();
}
关键验证规则:
baseInstructions必须为string类型或function类型,否则抛出TypeError
资料来源:agent.ts:55-85
clone 方法
沙箱 Agent 支持通过 clone 方法创建新的实例,允许部分覆盖配置:
override clone(
config: Partial<SandboxAgentOptions<TContext, TOutput>>,
): SandboxAgent<TContext, TOutput> {
return new SandboxAgent<TContext, TOutput>({
name: config.name ?? this.name,
instructions: config.instructions ?? this.instructions,
prompt: config.prompt ?? this.prompt,
handoffDescription: config.handoffDescription ?? this.handoffDescription,
handoffs: config.handoffs ?? this.handoffs,
model: config.model ?? this.model,
modelSettings: config.modelSettings ?? this.modelSettings,
tools: config.tools ?? this.tools,
mcpServers: config.mcpServers ?? this.mcpServers,
mcpConfig: config.mcpConfig ?? this.mcpConfig,
inputGuardrails: config.inputGuardrails ?? this.inputGuardrails,
// ... 其他配置项
});
}
该方法采用浅拷贝策略:对于非对象配置项使用 ?? 操作符合并,对于数组和对象配置项直接复用原实例引用。
资料来源:agent.ts:90-110
配置选项详解
SandboxAgentOptions
| 选项 | 类型 | 必填 | 默认值 | 说明 | |
|---|---|---|---|---|---|
name | string | 是 | - | Agent 名称 | |
instructions | `string \ | function` | 否 | - | 系统提示词 |
tools | Tool[] | 否 | [] | 可用工具列表 | |
model | `string \ | Model` | 否 | 默认模型 | 使用的 AI 模型 |
modelSettings | ModelSettings | 否 | - | 模型设置 | |
defaultManifest | Manifest | 否 | undefined | 默认 Manifest | |
baseInstructions | `string \ | function` | 否 | - | 基础执行指令 |
capabilities | Capability[] | 否 | Capabilities.default() | 沙箱能力列表 | |
runAs | `string \ | SandboxUser` | 否 | - | 运行用户身份 |
mcpServers | MCPServer[] | 否 | - | MCP 服务器配置 | |
mcpConfig | Record<string, any> | 否 | - | MCP 额外配置 |
资料来源:agent.ts:30-48
Manifest 配置
Manifest 定义了沙箱运行时允许的操作范围,包括文件路径白名单、允许的命令等。每个沙箱 Agent 维护两个 Manifest 实例:
defaultManifest:静态配置的默认 ManifestruntimeManifest:运行时动态更新的 Manifest
Manifest 克隆使用专用的 cloneManifest 函数确保不可变性。
资料来源:manifest.ts, agent.ts:75-80
Capabilities 能力系统
Capabilities 定义了沙箱可执行的具体功能。默认能力集通过 Capabilities.default() 获取,可通过覆盖 capabilities 选项进行定制。
沙箱与本地执行环境
本地沙箱执行
沙箱 Agent 支持本地执行模式,通过 local.ts 模块提供。执行时序如下:
sequenceDiagram
participant 用户
participant SandboxAgent
participant Manifest
participant 本地沙箱
participant 文件系统
用户->>SandboxAgent: 调用 run()
SandboxAgent->>Manifest: 验证 runtimeManifest
Manifest->>本地沙箱: 授权操作
本地沙箱->>文件系统: 读写文件
文件系统-->>本地沙箱: 操作结果
本地沙箱-->>Manifest: 执行完成
Manifest-->>SandboxAgent: 输出结果
SandboxAgent-->>用户: 返回最终结果资料来源:local.ts, agent.ts:1-100
文件系统安全
沙箱 Agent 通过以下机制确保文件系统安全:
- 路径解析验证:使用
realpath -m解析绝对路径,防止符号链接绕过 - 目录边界检查:确保操作不会超出
workspace root范围 - 文件名限制:禁止创建目录类型的目标文件
关键实现逻辑示例:
resolved_root=$(realpath -m -- "$root")
parent=$(dirname -- "$path")
resolved_parent=$(realpath -m -- "$parent")
# 验证路径在允许范围内
case "$resolved_parent" in
"$resolved_root"|"$resolved_root"/*) ;;
*) printf "workspace escape: %s\\n" "$resolved_parent" >&2; exit 111 ;;
esac
资料来源:sandbox.ts (agents-extensions), memory/prompts.ts
使用模式
基本用法
import { SandboxAgent } from '@openai/agents-core';
const sandboxAgent = new SandboxAgent({
name: 'code-executor',
instructions: '你是一个代码执行助手',
tools: [/* 工具列表 */],
baseInstructions: '在沙箱中执行代码时,请确保安全',
capabilities: Capabilities.default(),
});
带 Manifest 的配置
import { Manifest } from '@openai/agents-core';
const manifest = new Manifest({
root: '/workspace/project',
allowedPaths: ['/workspace/project/src'],
});
const agent = new SandboxAgent({
name: 'secure-coder',
instructions: '在受限环境中编写代码',
defaultManifest: manifest,
});
Agent as Tool 模式
沙箱 Agent 可以作为工具被其他 Agent 调用,通过 Agent.asTool() 方法暴露:
const executorTool = executorAgent.asTool({
toolName: 'code-executor',
toolDescription: '在沙箱中安全执行代码',
});
资料来源:agent.ts (Agent.asTool), examples/agent-patterns/README.md
与标准 Agent 的区别
| 特性 | 标准 Agent | 沙箱 Agent |
|---|---|---|
| 代码执行 | 依赖外部环境 | 内置沙箱隔离 |
| 权限控制 | 无内置机制 | Manifest + Capabilities |
| 用户身份 | 不支持 | runAs 选项 |
| 文件系统 | 无限制 | 路径白名单验证 |
| 适用场景 | 通用对话 | 安全代码执行 |
资料来源:agent.ts:1-120, agent.ts:agent-class
最佳实践
安全配置
- 最小权限原则:仅启用必要的 Capabilities
- Manifest 边界:设置狭窄的
workspace root和allowedPaths - 用户隔离:使用
runAs指定非特权用户运行
性能优化
- Manifest 缓存:避免重复创建相同的 Manifest 实例
- clone 复用:对于配置相似的 Agent,使用
clone方法而非重新创建 - 能力精简:移除未使用的工具以减少 Agent 初始化开销
错误处理
沙箱 Agent 的错误处理通过 RunErrorHandler 机制实现,支持的错误类型包括:
MaxTurnsExceededError:超出最大轮次限制ModelRefusalError:模型拒绝执行
const agent = new SandboxAgent({
name: 'robust-executor',
instructions: instructions,
errorHandlers: {
maxTurnsExceeded: async (input) => {
return {
finalOutput: generateTimeoutResponse(),
includeInHistory: true,
};
},
},
});
资料来源:errorHandlers.ts
总结
沙箱 Agent 是 OpenAI Agents SDK 中专为安全代码执行设计的 Agent 类型。通过继承标准 Agent 的全部功能并扩展沙箱特定能力,开发者可以在保持 Agent 框架一致性的同时,获得可靠的隔离执行环境。Manifest 系统和 Capabilities 机制共同提供了细粒度的权限控制,而 runAs 选项则支持以不同用户身份运行的场景。
资料来源:agent.ts:1-50
沙箱运行时与容器
沙箱运行时与容器是 OpenAI Agents SDK 中提供安全隔离执行环境的核心子系统。该系统允许 AI Agent 在受限的文件系统和 Shell 环境中执行操作,同时保持与主机环境的适当隔离。沙箱机制支持多种后端实现,包括本地 Unix 环境、Docker 容器以及第三方云沙箱服务。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
沙箱运行时与容器是 OpenAI Agents SDK 中提供安全隔离执行环境的核心子系统。该系统允许 AI Agent 在受限的文件系统和 Shell 环境中执行操作,同时保持与主机环境的适当隔离。沙箱机制支持多种后端实现,包括本地 Unix 环境、Docker 容器以及第三方云沙箱服务。
沙箱的核心职责包括:
- 进程隔离:在受限环境中执行 Shell 命令
- 文件系统安全:限制 Agent 对特定目录树的访问
- 资源控制:管理内存限制、网络策略等
- 路径翻译:透明处理工作区与主机之间的路径映射
- 生命周期管理:创建、暂停、恢复和销毁沙箱会话
核心架构
沙箱类型体系
SDK 支持三种主要的沙箱环境类型:
| 类型 | 标识符 | 适用场景 | 配置要求 |
|---|---|---|---|
| 本地沙箱 | local | 开发调试、直接进程执行 | 只需提供 Shell 实现 |
| 自动容器 | container_auto | 按需创建临时容器 | 需要 Docker 等容器运行时 |
| 容器引用 | container_reference | 复用已有容器 | 必须提供 containerId |
资料来源:packages/agents-core/src/tool.ts:1-50
沙箱环境配置接口
interface ShellToolEnvironment {
type: 'local' | 'container_auto' | 'container_reference';
fileIds?: string[];
memoryLimit?: string;
networkPolicy?: ShellToolContainerNetworkPolicy;
skills?: ShellToolContainerSkill[];
containerId?: string;
}
环境规范化函数 normalizeShellToolEnvironment 负责验证配置完整性:
export function normalizeShellToolEnvironment(
environment: ShellToolEnvironment | undefined,
): NormalizedShellToolEnvironment {
if (!environment || environment.type === 'local') {
return environment ?? { type: 'local' };
}
if (environment.type === 'container_auto') {
return {
type: 'container_auto',
fileIds: environment.fileIds,
memoryLimit: environment.memoryLimit,
networkPolicy: normalizeShellToolContainerNetworkPolicy(
environment.networkPolicy,
),
skills: environment.skills?.map(normalizeShellToolContainerSkill),
};
}
const containerId = environment.containerId;
if (!containerId) {
throw new UserError(
'shellTool with container_reference environment requires a containerId.',
);
}
return { type: 'container_reference', containerId };
}
资料来源:packages/agents-core/src/tool.ts
本地沙箱实现
UnixLocalSandbox 类
UnixLocalSandbox 是本地沙箱的核心实现类,负责在本地文件系统上创建隔离的 Shell 执行环境。
export class UnixLocalSandbox implements SandboxLike {
private shell: Shell;
private state: SandboxState;
private buildEnv(args: SandboxEnvironmentArgs): Record<string, string> {
return {
HOME: this.state.manifest.root,
PATH: process.env.PATH ?? '/usr/local/bin:/usr/bin:/bin',
LANG: 'en_US.UTF-8',
SHELL: args.shellPath,
TMPDIR: '/tmp',
...args.environment,
PWD: args.pwd,
};
}
}
资料来源:packages/agents-core/src/sandbox/sandboxes/unixLocal.ts
Shell 工具创建
本地沙箱通过 shellTool 工厂函数创建,其签名如下:
export function shellTool(options: LocalShellToolOptions): NormalizedLocalShellTool;
export function shellTool(options: HostedShellToolOptions): HostedShellTool;
export function shellTool(
options: LocalShellToolOptions | HostedShellToolOptions,
): NormalizedLocalShellTool | HostedShellTool
关键验证逻辑确保本地环境配置完整:
if (environment.type === 'local') {
const localShell = options.shell;
if (!localShell) {
throw new UserError(
'shellTool with local environment requires a shell implementation.',
);
}
// ... 创建本地 Shell 工具
}
资料来源:packages/agents-core/src/tool.ts
路径翻译机制
路径翻译是沙箱安全性的核心保障,确保 Agent 无法通过路径遍历访问受限目录。
命令输入路径翻译
系统提供两种路径翻译策略:
#### 绝对路径翻译
将绝对路径转换为工作区根目录的相对路径:
function translateRootManifestCommandInput(
command: string,
workspaceRootPath: string,
): string {
return command.replace(
/(^|[\s"'=<>])\/([^\s"'|&;<>(){}]*)/g,
(_match, prefix: string, pathSuffix: string) =>
`${prefix}${workspaceRootPath}/${pathSuffix}`,
);
}
#### Manifest 根目录翻译
将引用 Manifest 根目录的路径替换为工作区根目录:
function translateManifestRootCommandInput(
command: string,
manifestRoot: string,
workspaceRootPath: string,
): string {
const escapedManifestRoot = escapeRegExp(manifestRoot);
const pathPrefix = String.raw`(^|[\s"'=<>])`;
const pathSuffix = String.raw`(?=$|[\/\s"'|&;<>(){}])`;
return command.replace(
new RegExp(`${pathPrefix}${escapedManifestRoot}${pathSuffix}`, 'g'),
(_match, prefix: string) => `${prefix}${workspaceRootPath}`,
);
}
资料来源:packages/agents-core/src/sandbox/sandboxes/unixLocal.ts
命令输出路径翻译
输出路径翻译将工作区路径反向映射回 Manifest 根目录:
function translateRootManifestCommandOutput(
output: string,
workspaceRootPath: string,
): string {
return translateWorkspaceRootCommandOutput(output, '/', workspaceRootPath);
}
function translateManifestRootCommandOutput(
output: string,
manifestRoot: string,
workspaceRootPath: string,
): string {
return translateWorkspaceRootCommandOutput(
output,
manifestRoot,
workspaceRootPath,
);
}
工作流程图
graph TD
A[创建 ShellTool] --> B{environment.type}
B -->|local| C[使用 UnixLocalSandbox]
B -->|container_auto| D[创建新容器]
B -->|container_reference| E[连接已有容器]
C --> F[构建 Shell 环境变量]
D --> G[初始化容器]
E --> H[挂载容器]
F --> I[执行命令]
G --> I
H --> I
I --> J{路径翻译}
J --> K[输入翻译]
J --> L[输出翻译]
K --> M[安全检查]
L --> N[格式化输出]
M --> O[执行 Shell 命令]
O --> P[返回结果]SandboxAgent 核心组件
SandboxAgent 类定义
SandboxAgent 是专门用于沙箱环境的 Agent 基类:
export class SandboxAgent<
TContext,
TOutput extends AgentOutputTypes,
> extends Agent<TContext, TOutput> {
disabled?: boolean;
defaultManifest?: Manifest;
baseInstructions?: SandboxBaseInstructions<TContext, TOutput>;
capabilities: Capability[];
runAs?: string | SandboxUser;
runtimeManifest: Manifest;
constructor(config: SandboxAgentOptions<TContext, TOutput>) {
super(config);
// 验证 baseInstructions 类型
if (
config.baseInstructions !== undefined &&
typeof config.baseInstructions !== 'string' &&
typeof config.baseInstructions !== 'function'
) {
throw new TypeError(
'SandboxAgent baseInstructions must be a string or function.',
);
}
// 初始化 Manifest 和配置
this.defaultManifest = config.defaultManifest
? cloneManifest(config.defaultManifest)
: undefined;
this.baseInstructions = config.baseInstructions;
this.capabilities = config.capabilities ?? Capabilities.default();
this.runAs = normalizeRunAs(config.runAs);
this.runtimeManifest = this.defaultManifest ?? new Manifest();
}
}
资料来源:packages/agents-core/src/sandbox/agent.ts
克隆与配置
SandboxAgent 支持通过 clone 方法创建配置变体:
override clone(
config: Partial<SandboxAgentOptions<TContext, TOutput>>,
): SandboxAgent<TContext, TOutput> {
return new SandboxAgent<TContext, TOutput>({
name: config.name ?? this.name,
instructions: config.instructions ?? this.instructions,
prompt: config.prompt ?? this.prompt,
handoffDescription: config.handoffDescription ?? this.handoffDescription,
handoffs: config.handoffs ?? this.handoffs,
model: config.model ?? this.model,
modelSettings: config.modelSettings ?? this.modelSettings,
tools: config.tools ?? this.tools,
mcpServers: config.mcpServers ?? this.mcpServers,
mcpConfig: config.mcpConfig ?? this.mcpConfig,
inputGuardrails: config.inputGuardrails ?? this.inputGuardrails,
// ... 其他配置项
});
}
资料来源:packages/agents-core/src/sandbox/agent.ts
能力系统
能力检测
沙箱系统通过 requiredCapabilityTypes() 方法检测运行时所需能力:
override requiredCapabilityTypes(): Set<string> {
if (this.read === null) {
return new Set();
}
if (this.read.liveUpdate) {
return new Set(['filesystem', 'shell']);
}
return new Set(['shell']);
}
对于内存功能,当启用实时更新时需要文件系统和 Shell 两种能力,否则仅需 Shell 能力。
资料来源:packages/agents-core/src/sandbox/capabilities/memory.ts
Manifest 处理
processManifest 方法确保所需目录结构已创建:
override processManifest(manifest: Manifest): Manifest {
if (this.read?.liveUpdate || this.generate !== null) {
ensureDirectoryEntry(manifest, this.layout.memoriesDir);
}
if (this.generate !== null) {
ensureDirectoryEntry(manifest, this.layout.sessionsDir);
}
return manifest;
}
云沙箱扩展
Daytona 沙箱实现
Daytona 云沙箱提供了企业级的沙箱执行环境:
private async deleteEditorPath(path: string): Promise<void> {
const absolutePath = this.resolveEditorPath(path, { forWrite: true });
await this.runEditorFileCommand([
'set -eu',
`root=${shellQuote(this.state.manifest.root)}`,
`path=${shellQuote(absolutePath)}`,
'resolved_root=$(realpath -m -- "$root")',
'parent=$(dirname -- "$path")',
'base=$(basename -- "$path")',
'resolved_parent=$(realpath -m -- "$parent")',
'case "$resolved_parent" in "$resolved_root"|"$resolved_root"/*) ;; *) printf "workspace escape: %s\\n" "$resolved_parent" >&2; exit 111 ;; esac',
'target="$resolved_parent/$base"',
'if [ -d "$target" ]; then printf "directory target: %s\\n" "$target" >&2; exit 112; fi',
'tmp=$(mktemp "$resolved_parent/.openai-agents-write.XXXXXX")',
'cleanup() { rm -f -- "$tmp"; }',
'trap cleanup EXIT HUP INT TERM',
'base64 -d > "$tmp" <<\'OPENAI_AGENTS_CONTENT\'',
encoded,
'OPENAI_AGENTS_CONTENT',
'chmod 644 "$tmp"',
'mv -f -- "$tmp" "$target"',
'trap - EXIT',
].join('\n'));
}
资料来源:packages/agents-extensions/src/sandbox/daytona/sandbox.ts
安全防护机制
Daytona 实现包含多层安全检查:
| 错误码 | 含义 | 触发条件 |
|---|---|---|
111 | 工作区逃逸 | 目标路径不在允许的根目录树内 |
112 | 目录目标 | 写入操作目标是目录而非文件 |
沙箱运行时管理器
管理器职责
运行时管理器 (SandboxRuntimeManager) 负责协调沙箱的生命周期:
- 创建和初始化沙箱实例
- 管理多个并发沙箱会话
- 处理沙箱间的资源分配
- 提供统一的错误处理和恢复机制
会话管理
graph LR
A[创建 Manifest] --> B[初始化沙箱]
B --> C[执行任务]
C --> D{任务类型}
D -->|读取| E[文件系统操作]
D -->|执行| F[Shell 命令]
D -->|记忆| G[内存读写]
E --> H[清理资源]
F --> H
G --> H
H --> I[保存快照]
I --> J[会话结束]工具类型与沙箱集成
函数工具
函数工具是沙箱中使用最广泛的工具类型:
export type FunctionTool<
Context = UnknownContext,
TParameters extends ToolInputParameters = undefined,
Result = unknown,
> = {
type: 'function';
name: string;
description: string;
parameters: JsonObjectSchema<any>;
strict: boolean;
deferLoading?: boolean;
invoke: (
runContext: RunContext<Context>,
input: string,
details?: ToolCallDetails,
) => Promise<string | Result>;
needsApproval?: boolean | ToolApprovalFunction;
};
托管工具
托管工具通过客户端执行器扩展沙箱功能:
export type ClientToolSearchExecutor<Context = UnknownContext> = (
args: ClientToolSearchExecutorArgs<Context>,
) =>
| Tool<Context>
| Tool<Context>[]
| null
| undefined;
工具搜索执行器允许在运行时动态加载和执行工具,实现按需扩展。
资料来源:packages/agents-core/src/tool.ts
错误处理
错误处理器接口
沙箱系统定义了专门的错误处理接口:
export type RunErrorHandler<TContext, TAgent extends Agent<any, any>> = (
input: RunErrorHandlerInput<TContext, TAgent>,
) =>
| RunErrorHandlerResult<TAgent>
| void
| Promise<RunErrorHandlerResult<TAgent> | void>;
export type RunErrorHandlers<
TContext,
TAgent extends Agent<any, any>,
> = Partial<Record<RunErrorKind, RunErrorHandler<TContext, TAgent>>> & {
default?: RunErrorHandler<TContext, TAgent>;
};
运行错误数据结构
export type RunErrorData<TContext, TAgent extends Agent<any, any>> = {
input: unknown;
newItems: GenerationItem[];
history: TurnInput;
output: TurnInput;
rawResponses: Response[];
lastAgent?: TAgent;
state?: RunState<TContext, TAgent>;
};
export type RunErrorHandlerInput<TContext, TAgent extends Agent<any, any>> = {
error: MaxTurnsExceededError | ModelRefusalError;
context: RunContext<TContext>;
runData: RunErrorData<TContext, TAgent>;
};
资料来源:packages/agents-core/src/runner/errorHandlers.ts
使用示例
基本沙箱配置
import { shellTool, SandboxAgent } from '@openai/agents';
const sandboxTool = shellTool({
environment: {
type: 'local',
},
shell: {
async run(command, args) {
return { output: 'result' };
},
},
});
const agent = new SandboxAgent({
name: 'sandbox-agent',
instructions: '在沙箱中执行文件操作',
tools: [sandboxTool],
});
Docker 容器沙箱
import { shellTool } from '@openai/agents';
const containerTool = shellTool({
environment: {
type: 'container_auto',
memoryLimit: '2g',
networkPolicy: 'deny',
skills: ['javascript', 'bash'],
},
});
总结
沙箱运行时与容器系统为 OpenAI Agents SDK 提供了强大的安全隔离执行能力。通过清晰的分层架构,系统支持本地开发、临时容器和持久容器引用等多种运行模式。路径翻译、安全检查和能力检测等机制确保了沙箱环境的安全性和可靠性。
实时语音 Agent
实时语音 Agent(RealtimeAgent)是 OpenAI Agents SDK 中专门用于构建语音交互应用的组件。它基于 Agent 基类进行扩展,集成了实时语音通信能力,支持通过 WebRTC 或 WebSocket 传输层与 OpenAI Realtime API 进行双向音频交互。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
实时语音 Agent(RealtimeAgent)是 OpenAI Agents SDK 中专门用于构建语音交互应用的组件。它基于 Agent 基类进行扩展,集成了实时语音通信能力,支持通过 WebRTC 或 WebSocket 传输层与 OpenAI Realtime API 进行双向音频交互。
RealtimeAgent 的核心设计理念是简化语音应用的开发流程,使开发者无需关注底层传输细节,只需配置指令和工具即可快速构建语音助手、客服机器人等应用。
资料来源:packages/agents-realtime/src/realtimeAgent.ts:42-58
核心架构
类继承关系
RealtimeAgent 继承自 Agent 基类,泛型参数分别为上下文数据类型和输出类型:
export class RealtimeAgent<TContext = UnknownContext> extends Agent<
RealtimeContextData<TContext>,
TextOutput
>
| 基类属性 | RealtimeAgent 中的值 | 说明 |
|---|---|---|
| TContext | RealtimeContextData<TContext> | 实时会话上下文 |
| TOutput | TextOutput | 输出类型为纯文本 |
资料来源:packages/agents-realtime/src/realtimeAgent.ts:85-89
组件交互流程
graph TD
A[用户] -->|语音输入| B[RealtimeSession]
B -->|音频流| C[Transport Layer]
C -->|WebSocket/WebRTC| D[OpenAI Realtime API]
D -->|音频响应| C
C -->|音频流| B
B -->|语音输出| A
E[RealtimeAgent] -->|指令/工具| B
F[RealtimeContext] -->|上下文| BRealtimeAgent 配置
RealtimeAgentConfiguration 接口
RealtimeAgent 的配置通过 RealtimeAgentConfiguration 接口定义,相比标准 Agent 移除了部分不适用的配置项:
| 配置项 | 类型 | 必需 | 说明 |
|---|---|---|---|
| name | string | 是 | 实时语音 Agent 的名称 |
| instructions | string | 否 | 系统指令,定义 Agent 行为 |
| handoffs | RealtimeAgent[] 或 Handoff[] | 否 | 可转交给其他 Agent 的列表 |
| voice | string | 否 | 使用的语音名称 |
不支持的配置项(由 RealtimeSession 统一管理):
model:所有 RealtimeAgent 共享同一模型modelSettings:模型设置由会话级别统一配置outputType:不支持结构化输出toolUseBehavior:工具使用行为由会话统一管理
资料来源:packages/agents-realtime/src/realtimeAgent.ts:4-36
配置示例
const agent = new RealtimeAgent({
name: 'voice-assistant',
instructions: '你是一个乐于助人的语音助手,可以回答问题和协助完成任务。',
handoffs: [specializedAgent],
voice: 'alloy',
});
RealtimeSession 会话管理
会话初始化
RealtimeSession 是实时语音交互的核心管理器,负责:
- 管理传输层连接(WebRTC/WebSocket)
- 维护对话历史和上下文
- 处理 Agent 之间的转交(handoff)
- 应用输出 Guardrails
export class RealtimeSession<TBaseContext = UnknownContext> {
constructor(
public readonly initialAgent: RealtimeAgent<TBaseContext>,
public readonly options: Partial<RealtimeSessionOptions<TBaseContext>> = {},
) {
// 初始化传输层
if (options.transport === 'webrtc' || !options.transport) {
this.#transport = new OpenAIRealtimeWebRTC();
} else if (options.transport === 'websocket') {
this.#transport = new OpenAIRealtimeWebSocket();
} else {
this.#transport = options.transport;
}
}
}
资料来源:packages/agents-realtime/src/realtimeSession.ts:1-50
传输层架构
RealtimeSession 支持多种传输层实现:
| 传输类型 | 类 | 说明 |
|---|---|---|
| WebRTC | OpenAIRealtimeWebRTC | 适用于浏览器环境,支持媒体流 |
| WebSocket | OpenAIRealtimeWebSocket | 适用于 Node.js 环境或其他支持 WebSocket 的平台 |
| 自定义 | 自定义实现 | 实现 RealtimeTransport 接口 |
传输层选择逻辑:
if (
(typeof options.transport === 'undefined' && hasWebRTCSupport()) ||
options.transport === 'webrtc'
) {
this.#transport = new OpenAIRealtimeWebRTC();
} else if (
options.transport === 'websocket' ||
typeof options.transport === 'undefined'
) {
this.#transport = new OpenAIRealtimeWebSocket();
}
资料来源:packages/agents-realtime/src/realtimeSession.ts:30-44
会话上下文
RealtimeSession 创建一个包含历史记录的运行上下文:
this.#context = new RunContext<RealtimeContextData<TBaseContext>>({
...(options.context ?? {}),
history: this.#history,
} as RealtimeContextData<TBaseContext>);
会话配置
配置结构
会话配置(RealtimeSessionConfig)定义了与 OpenAI Realtime API 交互的各种参数:
| 配置类别 | 包含项 | 说明 |
|---|---|---|
| audio.input | format, noiseReduction, transcription, turnDetection | 输入音频配置 |
| audio.output | format, voice | 输出音频配置 |
| tools | 工具列表 | Agent 可调用的工具 |
| tool高层次 | 工具使用策略 | 工具调用行为控制 |
| turnDetection | 启用的检测类型 | 语音触发检测设置 |
废弃配置兼容
系统支持旧的配置格式向新格式的自动转换:
function isDeprecatedConfig(
config: Partial<RealtimeSessionConfig>,
): config is Partial<RealtimeSessionConfigDeprecated> {
return (
isDefined('modalities', config) ||
isDefined('inputAudioFormat', config) ||
isDefined('outputAudioFormat', config) ||
isDefined('inputAudioTranscription', config) ||
isDefined('turnDetection', config) ||
isDefined('inputAudioNoiseReduction', config) ||
isDefined('speed', config)
);
}
资料来源:packages/agents-realtime/src/clientMessages.ts:1-30
语音与转交(HandOff)
语音配置
RealtimeAgent 支持为每个 Agent 配置不同的语音:
export class RealtimeAgent<TContext = UnknownContext> {
/**
* The voice intended to be used by the agent.
* If another agent already spoke during the RealtimeSession,
* changing the voice during a handoff will fail.
*/
readonly voice?: string;
}
重要约束:如果在一个 RealtimeSession 中已有其他 Agent 发音,语音转交将失败。
资料来源:packages/agents-realtime/src/realtimeAgent.ts:90-96
Agent 转交
RealtimeAgent 支持将对话转交给其他专门的 Agent:
export type RealtimeAgentConfiguration<TContext = UnknownContext> = Partial<
Omit<AgentConfiguration<...>, ...>
> & {
/**
* Any other `RealtimeAgent` instances the agent is able to hand off to.
*/
handoffs?: (
| RealtimeAgent<TContext>
| Handoff<RealtimeContextData<TContext>, TextOutput>
)[];
};
转交时,目标 Agent 会被作为工具暴露给模型调用,实现多 Agent 协作。
事件与生命周期
运行钩子
RealtimeSession 继承自 LifecycleMixin,支持丰富的生命周期事件:
| 事件名 | 触发时机 | 参数 |
|---|---|---|
| agent_start | Agent 开始执行 | context, agent, turnInput |
| agent_end | Agent 完成执行 | context, agent, output |
| agent_handoff | Agent 转交给其他 Agent | context, fromAgent, toAgent |
| agent_tool_start | 工具开始调用 | context, agent, tool, details |
资料来源:packages/agents-core/src/lifecycle.ts:20-55
使用示例
基础语音助手
import { RealtimeAgent, RealtimeSession } from '@openai/agents-realtime';
const agent = new RealtimeAgent({
name: 'my-voice-assistant',
instructions: '你是一个友好的语音助手。',
voice: 'alloy',
});
const session = new RealtimeSession(agent, {
transport: 'websocket', // 或 'webrtc' 用于浏览器
});
await session.connect({ apiKey: process.env.OPENAI_API_KEY });
带工具的语音助手
const agent = new RealtimeAgent({
name: 'weather-assistant',
instructions: '你是一个天气助手,可以查询天气预报。',
handoffs: [],
});
// 在 RealtimeSession 层面配置工具
const session = new RealtimeSession(agent, {
tools: [weatherTool],
audio: {
input: { turnDetection: { type: 'server_vad' } },
output: { voice: 'nova' },
},
});
WebSocket 手动发送事件
// 手动发送客户端事件
session.transport.sendEvent({
type: 'response.create',
response: {
modalities: ['audio', 'text'],
},
});
// 取消正在进行的响应
session.transport.sendEvent({
type: 'response.cancel',
});
资料来源:packages/agents-realtime/src/openaiRealtimeWebsocket.ts:40-70
注意事项与限制
功能限制
- 不支持结构化输出:RealtimeAgent 只能输出纯文本
- 统一模型配置:同一会话中的所有 Agent 共享相同模型
- 语音转交限制:首次发音后无法更改语音
- 不支持输入 Guardrails:仅支持输出 Guardrails
传输层选择建议
| 环境 | 推荐传输 | 原因 |
|---|---|---|
| 浏览器 | WebRTC | 原生支持音视频流 |
| Node.js | WebSocket | 更稳定,依赖更少 |
| 移动端 | WebRTC | 低延迟音频传输 |
相关文件索引
| 文件路径 | 用途 |
|---|---|
packages/agents-realtime/src/realtimeAgent.ts | RealtimeAgent 类定义 |
packages/agents-realtime/src/realtimeSession.ts | RealtimeSession 会话管理 |
packages/agents-realtime/src/openaiRealtimeWebsocket.ts | WebSocket 传输实现 |
packages/agents-realtime/src/clientMessages.ts | 客户端消息处理与配置转换 |
packages/agents-core/src/agent.ts | Agent 基类定义 |
packages/agents-core/src/lifecycle.ts | 生命周期与事件系统 |
传输层与集成
传输层(Transport Layer)是 OpenAI Agents SDK 中处理实时会话通信的核心组件。它负责在客户端与 OpenAI Realtime API 之间建立、维护和管理双向通信连接。SDK 支持多种传输协议,包括 WebSocket 和 WebRTC,使得开发者能够灵活选择适合不同应用场景的通信方式。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
传输层(Transport Layer)是 OpenAI Agents SDK 中处理实时会话通信的核心组件。它负责在客户端与 OpenAI Realtime API 之间建立、维护和管理双向通信连接。SDK 支持多种传输协议,包括 WebSocket 和 WebRTC,使得开发者能够灵活选择适合不同应用场景的通信方式。
RealtimeSession 类是传输层的核心入口点,它封装了底层的传输实现,提供了统一的 API 接口。开发者可以根据网络环境、性能需求和功能特性选择合适的传输方式。
架构设计
传输层层次结构
┌─────────────────────────────────────────────┐
│ RealtimeSession │
│ (高级会话管理层,事件处理,用户交互) │
├─────────────────────────────────────────────┤
│ RealtimeTransport (接口) │
│ (统一抽象层,事件分发,消息序列化) │
├──────────────────┬──────────────────────────┤
│ OpenAIRealtime │ OpenAIRealtime │
│ WebSocket │ WebRTC │
│ │ │
│ (默认传输方式) │ (浏览器原生支持) │
├──────────────────┴──────────────────────────┤
│ OpenAI Realtime API │
│ (wss://api.openai.com/v1/realtime) │
└─────────────────────────────────────────────┘
传输类型枚举
| 传输类型 | 说明 | 使用场景 |
|---|---|---|
webrtc | WebRTC 传输协议 | 浏览器环境,NAT穿透需求 |
websocket | WebSocket 传输协议 | Node.js 环境,默认选项 |
custom | 自定义传输实现 | 第三方服务集成(Twilio、Cloudflare) |
传输选择机制
RealtimeSession 构造函数根据传入的 options.transport 参数和运行时环境自动选择合适的传输层实现。
graph TD
A[RealtimeSession 初始化] --> B{options.transport?}
B -->|undefined| C{hasWebRTCSupport?}
B -->|webrtc| D[使用 OpenAIRealtimeWebRTC]
B -->|websocket| E[使用 OpenAIRealtimeWebSocket]
B -->|自定义对象| F[使用 options.transport]
C -->|true| D
C -->|false| E
D --> G[建立连接]
E --> G
F --> G传输选择逻辑源码:
if (
(typeof options.transport === 'undefined' && hasWebRTCSupport()) ||
options.transport === 'webrtc'
) {
this.#transport = new OpenAIRealtimeWebRTC();
} else if (
options.transport === 'websocket' ||
typeof options.transport === 'undefined'
) {
this.#transport = new OpenAIRealtimeWebSocket();
} else {
this.#transport = options.transport;
}
资料来源:packages/agents-realtime/src/realtimeSession.ts:40-58
WebSocket 传输实现
核心功能
OpenAIRealtimeWebSocket 是默认的传输层实现,提供与 OpenAI Realtime API 的稳定连接。它处理消息的发送、接收、序列化和反序列化,并维护会话配置状态。
连接初始化流程
sequenceDiagram
participant Client as 客户端
participant WebSocket as OpenAIRealtimeWebSocket
participant API as OpenAI Realtime API
Client->>WebSocket: connect(options)
WebSocket->>WebSocket: 构建 URL (model, call_id)
WebSocket->>API: 建立 WebSocket 连接
API-->>WebSocket: 连接成功
WebSocket->>WebSocket: setupWebSocket()
WebSocket->>API: 发送 session.update 配置
API-->>WebSocket: session.created 事件
WebSocket-->>Client: 触发 connected 事件消息发送机制
sendEvent(event: RealtimeClientMessage): void {
this.#assertConnected();
if (event.type === 'response.create') {
this.#responseCreateSequencer.requestResponseCreate(event, {
manual: true,
});
return;
}
if (event.type === 'response.cancel') {
this.#responseCreateSequencer.beginCancelResponse();
}
this.#sendEventNow(event);
}
资料来源:packages/agents-realtime/src/openaiRealtimeWebsocket.ts:115-135
事件类型处理
| 事件类型 | 说明 | 处理逻辑 |
|---|---|---|
response.create | 创建新响应 | 请求响应创建,遵循序列器规则 |
response.cancel | 取消响应 | 开始取消流程 |
| 其他事件 | 通用消息 | 直接发送到服务器 |
会话配置管理
配置合并策略
传输层使用 _getMergedSessionConfig 方法合并默认配置与用户自定义配置:
_getMergedSessionConfig(
config: Partial<RealtimeSessionConfig>,
): RealtimeSessionPayload {
return this._getMergedSessionConfig(config);
}
资料来源:packages/agents-realtime/src/openaiRealtimeBase.ts:1-10
配置参数表格
| 参数类别 | 子参数 | 说明 | 默认值 |
|---|---|---|---|
audio.input | format | 输入音频格式 | pcm16 |
audio.input | noiseReduction | 噪音消除配置 | null |
audio.input | transcription | 输入转录设置 | undefined |
audio.input | turnDetection | 语音检测配置 | undefined |
audio.output | voice | 输出语音名称 | undefined |
audio.output | format | 输出音频格式 | pcm16 |
model | - | 使用的模型标识 | 必填 |
语音配置参数
const outputConfig =
audioOutput || typeof requestedOutputVoice !== 'undefined'
? {
format: normalizeAudioFormat(audioOutput?.format),
voice: requestedOutputVoice ?? undefined,
}
: undefined;
资料来源:packages/agents-realtime/src/clientMessages.ts:80-95
响应序列器
响应创建流程
响应序列器(Response Create Sequencer)管理响应的创建、排队和取消,确保多个响应请求按正确顺序处理。
graph LR
A[response.create 请求] --> B{是否手动触发?}
B -->|是| C[添加到序列]
B -->|否| D[自动处理]
C --> E{有进行中的响应?}
D --> E
E -->|是| F[等待当前响应完成]
E -->|否| G[立即执行]
F --> G响应取消机制
requestResponse(response?: Record<string, any>): void {
this.#assertConnected();
this.#responseCreateSequencer.requestResponseCreate(
{
type: 'response.create',
...(response ? { response } : {}),
},
{ manual: response !== undefined }
);
}
资料来源:packages/agents-realtime/src/openaiRealtimeWebsocket.ts:137-150
事件系统
会话事件类型
| 事件名称 | 触发时机 | 事件数据 |
|---|---|---|
guardrail_tripped | Guardrail 被触发 | OutputGuardrailTripwireTriggered |
history_updated | 历史记录更新 | 完整对话历史 |
history_added | 新项添加到历史 | 单个历史项 |
error | 发生错误 | RealtimeSessionError |
tool_approval_requested | 请求工具审批 | RealtimeToolApprovalRequest |
mcp_tool_call_completed | MCP 工具调用完成 | RealtimeMcpCallItem |
mcp_tools_changed | MCP 工具集变更 | 工具列表 |
资料来源:packages/agents-realtime/src/realtimeSessionEvents.ts:1-50
错误处理流程
graph TD
A[发生错误] --> B{错误类型}
B -->|MaxTurnsExceededError| C[调用 maxTurnsExceeded 处理器]
B -->|ModelRefusalError| D[调用 modelRefusal 处理器]
B -->|其他错误| E[调用 default 处理器]
C --> F{处理器返回结果?}
D --> F
E --> F
F -->|有结果| G[返回最终输出]
F -->|无结果| H[抛出错误]实时代理配置
RealtimeAgentConfiguration 接口
export type RealtimeAgentConfiguration<TContext = UnknownContext> = Partial<
Omit<
AgentConfiguration<RealtimeContextData<TContext>, TextOutput>,
| 'model'
| 'handoffs'
| 'modelSettings'
| 'outputType'
| 'toolUseBehavior'
| 'resetToolChoice'
| 'outputGuardrails'
| 'inputGuardrails'
| 'model'
>
> & {
name: string;
handoffs?: (RealtimeAgent<TContext> | Handoff<...>)[];
voice?: string;
};
资料来源:packages/agents-realtime/src/realtimeAgent.ts:1-30
配置限制说明
与标准 Agent 不同,RealtimeAgent 在 RealtimeSession 环境中运行时存在以下限制:
| 配置项 | 不支持原因 |
|---|---|
model | 所有 RealtimeAgent 共享同一模型 |
modelSettings | 模型设置由会话统一管理 |
toolUseBehavior | 工具行为由传输层控制 |
第三方传输集成
集成架构
┌──────────────────┐ ┌──────────────────┐
│ Twilio 集成 │ │ Cloudflare 集成 │
│ (agents-extensions) │ (agents-extensions) │
└────────┬─────────┘ └────────┬─────────┘
│ │
└───────────┬────────────┘
▼
┌───────────────────────┐
│ RealtimeTransport │
│ (统一接口) │
└───────────────────────┘
自定义传输实现
开发者可以通过实现 RealtimeTransport 接口来创建自定义传输层:
- 实现消息发送方法
- 实现连接管理方法
- 实现事件订阅机制
- 实现配置更新方法
// 自定义传输使用示例
const customTransport = new CustomRealtimeTransport();
const session = new RealtimeSession(agent, {
transport: customTransport
});
性能考虑
连接生命周期
graph LR
A[初始化] --> B[连接建立]
B --> C[会话配置]
C --> D[消息交换]
D --> E{保持连接?}
E -->|是| D
E -->|否| F[断开连接]
F --> G[清理资源]最佳实践
| 场景 | 推荐传输 | 原因 |
|---|---|---|
| 浏览器实时对话 | WebRTC | 更低的延迟,更好的 NAT 穿透 |
| Node.js 服务 | WebSocket | 稳定性更好 |
| 企业网络 | WebSocket | 防火墙友好 |
| 移动端应用 | WebRTC | 适应网络变化 |
总结
传输层与集成系统为 OpenAI Agents SDK 提供了灵活、高效的实时通信能力。通过抽象化的接口设计,开发者可以无缝切换不同的传输协议,同时支持 Twilio、Cloudflare 等第三方服务的深度集成。这种架构确保了 SDK 在各种运行环境下的适用性,同时保持了代码的简洁性和可维护性。
失败模式与踩坑日记
保留 Doramagic 在发现、验证和编译中沉淀的项目专属风险,不把社区讨论只当作装饰信息。
用户照着仓库名搜索包或照着包名找仓库时容易走错入口。
Upgrade or migration may change expected behavior: v0.10.0
Upgrade or migration may change expected behavior: v0.11.2
Upgrade or migration may change expected behavior: v0.9.0
Pitfall Log / 踩坑日志
项目:openai/openai-agents-js
摘要:发现 18 个潜在踩坑项,其中 0 个为 high/blocking;最高优先级:身份坑 - 仓库名和安装名不一致。
1. 身份坑 · 仓库名和安装名不一致
- 严重度:medium
- 证据强度:runtime_trace
- 发现:仓库名
openai-agents-js与安装入口@openai/agents不完全一致。 - 对用户的影响:用户照着仓库名搜索包或照着包名找仓库时容易走错入口。
- 建议检查:在 npm/PyPI/GitHub 上确认包名映射和官方 README 说明。
- 复现命令:
npm install @openai/agents - 防护动作:页面必须同时展示 repo 名和真实安装入口,避免用户搜索错包。
- 证据:identity.distribution | github_repo:993521808 | https://github.com/openai/openai-agents-js | repo=openai-agents-js; install=@openai/agents
2. 安装坑 · 失败模式:installation: v0.10.0
- 严重度:medium
- 证据强度:source_linked
- 发现:Developers should check this installation risk before relying on the project: v0.10.0
- 对用户的影响:Upgrade or migration may change expected behavior: v0.10.0
- 建议检查:Before packaging this project, run the relevant install/config/quickstart check for: v0.10.0. Context: Observed when using node, python
- 防护动作:State this as source-backed community evidence, not as Doramagic reproduction.
- 证据:failure_mode_cluster:github_release | fmev_0017083f7c144b8b8068b1aa812f1798 | https://github.com/openai/openai-agents-js/releases/tag/v0.10.0 | v0.10.0
3. 安装坑 · 失败模式:installation: v0.11.2
- 严重度:medium
- 证据强度:source_linked
- 发现:Developers should check this installation risk before relying on the project: v0.11.2
- 对用户的影响:Upgrade or migration may change expected behavior: v0.11.2
- 建议检查:Before packaging this project, run the relevant install/config/quickstart check for: v0.11.2. Context: Observed when using node, python
- 防护动作:State this as source-backed community evidence, not as Doramagic reproduction.
- 证据:failure_mode_cluster:github_release | fmev_cbb13be7191292a101a93f89e2c40ad3 | https://github.com/openai/openai-agents-js/releases/tag/v0.11.2 | v0.11.2
4. 配置坑 · 失败模式:configuration: v0.9.0
- 严重度:medium
- 证据强度:source_linked
- 发现:Developers should check this configuration risk before relying on the project: v0.9.0
- 对用户的影响:Upgrade or migration may change expected behavior: v0.9.0
- 建议检查:Before packaging this project, run the relevant install/config/quickstart check for: v0.9.0. Context: Observed when using docker
- 防护动作:State this as source-backed community evidence, not as Doramagic reproduction.
- 证据:failure_mode_cluster:github_release | fmev_742498adc1555b1770e9377463c11ff4 | https://github.com/openai/openai-agents-js/releases/tag/v0.9.0 | v0.9.0
5. 能力坑 · 能力判断依赖假设
- 严重度:medium
- 证据强度:source_linked
- 发现:README/documentation is current enough for a first validation pass.
- 对用户的影响:假设不成立时,用户拿不到承诺的能力。
- 建议检查:将假设转成下游验证清单。
- 防护动作:假设必须转成验证项;没有验证结果前不能写成事实。
- 证据:capability.assumptions | github_repo:993521808 | https://github.com/openai/openai-agents-js | README/documentation is current enough for a first validation pass.
6. 运行坑 · 失败模式:runtime: Large realtime audio buffers can crash during base64 encoding
- 严重度:medium
- 证据强度:source_linked
- 发现:Developers should check this runtime risk before relying on the project: Large realtime audio buffers can crash during base64 encoding
- 对用户的影响:Developers may hit a documented source-backed failure mode: Large realtime audio buffers can crash during base64 encoding
- 建议检查:Before packaging this project, run the relevant install/config/quickstart check for: Large realtime audio buffers can crash during base64 encoding. Context: Observed when using node
- 防护动作:State this as source-backed community evidence, not as Doramagic reproduction.
- 证据:failure_mode_cluster:github_issue | fmev_aaf4394591e72954462f8a949be29aee | https://github.com/openai/openai-agents-js/issues/1333 | Large realtime audio buffers can crash during base64 encoding, failure_mode_cluster:github_issue | fmev_dfcff51166e62ba4cc81679f3c9c2f18 | https://github.com/openai/openai-agents-js/issues/1333 | Large realtime audio buffers can crash during base64 encoding
7. 运行坑 · 失败模式:runtime: v0.11.4
- 严重度:medium
- 证据强度:source_linked
- 发现:Developers should check this runtime risk before relying on the project: v0.11.4
- 对用户的影响:Upgrade or migration may change expected behavior: v0.11.4
- 建议检查:Before packaging this project, run the relevant install/config/quickstart check for: v0.11.4. Context: Source discussion did not expose a precise runtime context.
- 防护动作:State this as source-backed community evidence, not as Doramagic reproduction.
- 证据:failure_mode_cluster:github_release | fmev_73a57d6e6bb4c1e93cea0e78313774b1 | https://github.com/openai/openai-agents-js/releases/tag/v0.11.4 | v0.11.4
8. 运行坑 · 来源证据:Large realtime audio buffers can crash during base64 encoding
- 严重度:medium
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个运行相关的待验证问题:Large realtime audio buffers can crash during base64 encoding
- 对用户的影响:可能阻塞安装或首次运行。
- 建议检查:来源问题仍为 open,Pack Agent 需要复核是否仍影响当前版本。
- 防护动作:不得脱离来源链接放大为确定性结论;需要标注适用版本和复核状态。
- 证据:community_evidence:github | cevd_1f01240eec894a519476aebd4a7590db | https://github.com/openai/openai-agents-js/issues/1333 | 来源讨论提到 node 相关条件,需在安装/试用前复核。
9. 维护坑 · 失败模式:migration: v0.9.1
- 严重度:medium
- 证据强度:source_linked
- 发现:Developers should check this migration risk before relying on the project: v0.9.1
- 对用户的影响:Upgrade or migration may change expected behavior: v0.9.1
- 建议检查:Before packaging this project, run the relevant install/config/quickstart check for: v0.9.1. Context: Observed during version upgrade or migration.
- 防护动作:State this as source-backed community evidence, not as Doramagic reproduction.
- 证据:failure_mode_cluster:github_release | fmev_e351743729d2a86ad6987f1baefae665 | https://github.com/openai/openai-agents-js/releases/tag/v0.9.1 | v0.9.1
10. 维护坑 · 维护活跃度未知
- 严重度:medium
- 证据强度:source_linked
- 发现:未记录 last_activity_observed。
- 对用户的影响:新项目、停更项目和活跃项目会被混在一起,推荐信任度下降。
- 建议检查:补 GitHub 最近 commit、release、issue/PR 响应信号。
- 防护动作:维护活跃度未知时,推荐强度不能标为高信任。
- 证据:evidence.maintainer_signals | github_repo:993521808 | https://github.com/openai/openai-agents-js | last_activity_observed missing
11. 安全/权限坑 · 下游验证发现风险项
- 严重度:medium
- 证据强度:source_linked
- 发现:no_demo
- 对用户的影响:下游已经要求复核,不能在页面中弱化。
- 建议检查:进入安全/权限治理复核队列。
- 防护动作:下游风险存在时必须保持 review/recommendation 降级。
- 证据:downstream_validation.risk_items | github_repo:993521808 | https://github.com/openai/openai-agents-js | no_demo; severity=medium
12. 安全/权限坑 · 存在评分风险
- 严重度:medium
- 证据强度:source_linked
- 发现:no_demo
- 对用户的影响:风险会影响是否适合普通用户安装。
- 建议检查:把风险写入边界卡,并确认是否需要人工复核。
- 防护动作:评分风险必须进入边界卡,不能只作为内部分数。
- 证据:risks.scoring_risks | github_repo:993521808 | https://github.com/openai/openai-agents-js | no_demo; severity=medium
13. 维护坑 · issue/PR 响应质量未知
- 严重度:low
- 证据强度:source_linked
- 发现:issue_or_pr_quality=unknown。
- 对用户的影响:用户无法判断遇到问题后是否有人维护。
- 建议检查:抽样最近 issue/PR,判断是否长期无人处理。
- 防护动作:issue/PR 响应未知时,必须提示维护风险。
- 证据:evidence.maintainer_signals | github_repo:993521808 | https://github.com/openai/openai-agents-js | issue_or_pr_quality=unknown
14. 维护坑 · 发布节奏不明确
- 严重度:low
- 证据强度:source_linked
- 发现:release_recency=unknown。
- 对用户的影响:安装命令和文档可能落后于代码,用户踩坑概率升高。
- 建议检查:确认最近 release/tag 和 README 安装命令是否一致。
- 防护动作:发布节奏未知或过期时,安装说明必须标注可能漂移。
- 证据:evidence.maintainer_signals | github_repo:993521808 | https://github.com/openai/openai-agents-js | release_recency=unknown
15. 维护坑 · 失败模式:maintenance: v0.10.1
- 严重度:low
- 证据强度:source_linked
- 发现:Developers should check this maintenance risk before relying on the project: v0.10.1
- 对用户的影响:Upgrade or migration may change expected behavior: v0.10.1
- 建议检查:Before packaging this project, run the relevant install/config/quickstart check for: v0.10.1. Context: Source discussion did not expose a precise runtime context.
- 防护动作:State this as source-backed community evidence, not as Doramagic reproduction.
- 证据:failure_mode_cluster:github_release | fmev_21fc49454e8260a68f620eef5031497f | https://github.com/openai/openai-agents-js/releases/tag/v0.10.1 | v0.10.1
16. 维护坑 · 失败模式:maintenance: v0.11.0
- 严重度:low
- 证据强度:source_linked
- 发现:Developers should check this maintenance risk before relying on the project: v0.11.0
- 对用户的影响:Upgrade or migration may change expected behavior: v0.11.0
- 建议检查:Before packaging this project, run the relevant install/config/quickstart check for: v0.11.0. Context: Observed when using node
- 防护动作:State this as source-backed community evidence, not as Doramagic reproduction.
- 证据:failure_mode_cluster:github_release | fmev_46b242251b25a22b32eeb2d3e132ab09 | https://github.com/openai/openai-agents-js/releases/tag/v0.11.0 | v0.11.0
17. 维护坑 · 失败模式:maintenance: v0.11.1
- 严重度:low
- 证据强度:source_linked
- 发现:Developers should check this maintenance risk before relying on the project: v0.11.1
- 对用户的影响:Upgrade or migration may change expected behavior: v0.11.1
- 建议检查:Before packaging this project, run the relevant install/config/quickstart check for: v0.11.1. Context: Source discussion did not expose a precise runtime context.
- 防护动作:State this as source-backed community evidence, not as Doramagic reproduction.
- 证据:failure_mode_cluster:github_release | fmev_4770e6d325b06442bfbac2c7a9228b8b | https://github.com/openai/openai-agents-js/releases/tag/v0.11.1 | v0.11.1
18. 维护坑 · 失败模式:maintenance: v0.11.3
- 严重度:low
- 证据强度:source_linked
- 发现:Developers should check this maintenance risk before relying on the project: v0.11.3
- 对用户的影响:Upgrade or migration may change expected behavior: v0.11.3
- 建议检查:Before packaging this project, run the relevant install/config/quickstart check for: v0.11.3. Context: Source discussion did not expose a precise runtime context.
- 防护动作:State this as source-backed community evidence, not as Doramagic reproduction.
- 证据:failure_mode_cluster:github_release | fmev_0b2d37ec4d2e0354b33ecb8cc520f142 | https://github.com/openai/openai-agents-js/releases/tag/v0.11.3 | v0.11.3
来源:Doramagic 发现、验证与编译记录