跳转到内容

工具

工具让智能体能够采取行动——获取数据、调用外部 API、执行代码,甚至进行计算机操作。JavaScript/TypeScript SDK 支持六种类别:

  1. Hosted OpenAI tools——与模型一同在 OpenAI 服务器上运行。(Web 搜索、文件搜索、Code Interpreter、图像生成)
  2. 本地内置工具——在你的环境中运行。(计算机操作、shell、apply_patch)
  3. 函数工具(Function tools)——用 JSON schema 包装任意本地函数,使 LLM 可以调用。
  4. Agents as tools——将整个智能体暴露为可调用工具。
  5. MCP 服务器——附加一个 Model Context Protocol 服务器(本地或远程)。
  6. 实验性:Codex 工具——将 Codex SDK 包装为函数工具以运行具备工作区感知的任务。

本指南接下来先介绍每个工具类别,然后总结通用的工具选择与提示词编写建议。

当你使用 OpenAIResponsesModel 时,可以添加以下内置工具:

工具类型字符串目的
Web search'web_search'互联网搜索。
File / retrieval search'file_search'查询托管在 OpenAI 上的向量存储。
Code Interpreter'code_interpreter'在沙箱环境中运行代码。
Image generation'image_generation'基于文本生成图像。
Hosted tools
import {
Agent,
codeInterpreterTool,
fileSearchTool,
imageGenerationTool,
webSearchTool,
} from '@openai/agents';
const agent = new Agent({
name: 'Travel assistant',
tools: [
webSearchTool({ searchContextSize: 'medium' }),
fileSearchTool('VS_ID', { maxNumResults: 3 }),
codeInterpreterTool(),
imageGenerationTool({ size: '1024x1024' }),
],
});

SDK 提供了返回托管工具定义的辅助函数:

辅助函数说明
webSearchTool(options?)提供 JS 友好的选项,如 searchContextSizeuserLocation,以及 filters.allowedDomains
fileSearchTool(ids, options?)第一个参数接受一个或多个向量存储 ID,另有 maxNumResultsincludeSearchResultsrankingOptions 和过滤器等选项。
codeInterpreterTool(options?)当未提供 container 时,默认使用自动管理的容器。
imageGenerationTool(options?)支持图像生成配置,如 modelsizequalitybackgroundinputFidelityinputImageMaskmoderationoutputCompressionpartialImages 和输出格式。

这些辅助函数将 JavaScript/TypeScript 友好的选项名称映射到底层 OpenAI Responses API 工具负载。完整的工具 schema 与高级选项(如排序选项或语义过滤)请参考 OpenAI 官方文档。


本地内置工具在你自己的环境中运行,需要你提供实现:

  • 计算机操作——实现 Computer 接口并传给 computerTool()
  • Shell——提供本地 Shell 实现,或配置托管的容器环境。
  • Apply patch——实现 Editor 接口并传给 applyPatchTool()

计算机操作与 apply‑patch 工具在本地执行,由 OpenAI 托管。Shell 工具可根据 shellTool() 配置在本地或托管容器环境中运行。 工具调用仍由模型的响应请求,但你的应用控制这些调用如何执行。

Local built-in tools
import {
Agent,
applyPatchTool,
computerTool,
shellTool,
Computer,
Editor,
Shell,
} from '@openai/agents';
const computer: Computer = {
environment: 'browser',
dimensions: [1024, 768],
screenshot: async () => '',
click: async () => {},
doubleClick: async () => {},
scroll: async () => {},
type: async () => {},
wait: async () => {},
move: async () => {},
keypress: async () => {},
drag: async () => {},
};
const shell: Shell = {
run: async () => ({
output: [
{
stdout: '',
stderr: '',
outcome: { type: 'exit', exitCode: 0 },
},
],
}),
};
const editor: Editor = {
createFile: async () => ({ status: 'completed' }),
updateFile: async () => ({ status: 'completed' }),
deleteFile: async () => ({ status: 'completed' }),
};
const agent = new Agent({
name: 'Local tools agent',
tools: [
computerTool({ computer }),
shellTool({ shell, needsApproval: true }),
applyPatchTool({ editor, needsApproval: true }),
],
});
void agent;

对于托管的 shell 环境,使用以下任一方式配置 shellTool({ environment })

  • type: 'container_auto' 为本次运行创建托管容器(支持网络策略、内存限制和技能)。
  • type: 'container_reference' 通过 containerId 复用现有容器。

完整用法参见 examples/tools/container-shell-skill-ref.tsexamples/tools/container-shell-inline-skill.ts


你可以使用 tool() 辅助函数将任意函数变成工具。

Function tool with Zod parameters
import { tool } from '@openai/agents';
import { z } from 'zod';
const getWeatherTool = tool({
name: 'get_weather',
description: 'Get the weather for a given city',
parameters: z.object({ city: z.string() }),
async execute({ city }) {
return `The weather in ${city} is sunny.`;
},
});
字段必填描述
name默认为函数名(例如 get_weather)。
description为 LLM 展示的清晰、可读的描述。
parametersZod schema 或原始 JSON schema 对象。使用 Zod parameters 会自动启用 strict 模式。
strict当为 true(默认)时,如果参数未通过校验,SDK 会返回模型错误。将其设为 false 可进行模糊匹配。
execute(args, context, details) => string | unknown | Promise<...>——你的业务逻辑。非字符串输出会为模型进行序列化。context 为可选的 RunContextdetails 包含 toolCallresumeStatesignal 等元数据。
errorFunction自定义处理器 (context, error) => string,将内部错误转化为用户可见的字符串。
timeoutMs每次调用的超时时间(毫秒)。必须大于 0 且不超过 2147483647
timeoutBehavior超时模式:error_as_result(默认)向模型返回可见的超时消息,raise_exception 则抛出 ToolTimeoutError
timeoutErrorFunctiontimeoutBehaviorerror_as_result 时,用于自定义超时输出的处理器 (context, timeoutError) => string
needsApproval在执行前需要人工批准。参见人机协作指南
isEnabled按运行条件性地暴露工具;接受布尔值或谓词。
inputGuardrails在工具执行前运行的护栏;可拒绝或抛出。参见护栏
outputGuardrails在工具执行后运行的护栏;可拒绝或抛出。参见护栏

使用 timeoutMs 为每次函数工具调用设定上限。

  • timeoutBehavior: 'error_as_result'(默认)会向模型返回 Tool '<name>' timed out after <timeoutMs>ms.
  • timeoutBehavior: 'raise_exception' 会抛出 ToolTimeoutError,你可以作为运行异常的一部分进行捕获。
  • timeoutErrorFunction 允许在 error_as_result 模式下自定义超时文案。
  • 超时会中止 details.signal,因此长时间运行的工具在监听到取消时可以尽快停止。

如果你直接调用函数工具,请使用 invokeFunctionTool 来强制执行与正常智能体运行相同的超时行为。

如果你需要模型在参数无效或不完整时进行“猜测”,可以在使用原始 JSON schema 时禁用严格模式:

Non-strict JSON schema tools
import { tool } from '@openai/agents';
interface LooseToolInput {
text: string;
}
const looseTool = tool({
description: 'Echo input; be forgiving about typos',
strict: false,
parameters: {
type: 'object',
properties: { text: { type: 'string' } },
required: ['text'],
additionalProperties: true,
},
execute: async (input) => {
// because strict is false we need to do our own verification
if (typeof input !== 'object' || input === null || !('text' in input)) {
return 'Invalid input. Please try again';
}
return (input as LooseToolInput).text;
},
});

有时你希望一个智能体在不完全交接对话的情况下“协助”另一个智能体。使用 agent.asTool()

Agents as tools
import { Agent } from '@openai/agents';
const summarizer = new Agent({
name: 'Summarizer',
instructions: 'Generate a concise summary of the supplied text.',
});
const summarizerTool = summarizer.asTool({
toolName: 'summarize_text',
toolDescription: 'Generate a concise summary of the supplied text.',
});
const mainAgent = new Agent({
name: 'Research assistant',
tools: [summarizerTool],
});

在底层,SDK 会:

  • 创建一个只有单个 input 参数的函数工具。
  • 在工具被调用时,用该输入运行子智能体。
  • 返回最后一条消息,或由 customOutputExtractor 提取的输出。

当你将智能体作为工具运行时,Agents SDK 会以默认设置创建一个 runner,并在函数执行期间用它来运行该智能体。如果你想提供任何 runConfigrunOptions 的属性,可以将它们传给 asTool() 方法来自定义 runner 的行为。

你还可以通过 asTool() 选项在智能体工具上设置 needsApprovalisEnabled,以集成到人机协作流程和条件性工具可用性中。

agent.asTool() 的高级结构化输入选项:

  • inputBuilder:将结构化的工具参数映射到嵌套智能体的输入负载。
  • includeInputSchema:在嵌套运行中包含输入 JSON schema,以增强对 schema 的感知行为。
  • resumeState:控制在恢复嵌套序列化 RunState 时的上下文协调策略:'merge'(默认)将实时的审批/上下文状态合并进序列化状态;'replace' 则改用当前运行上下文;'preferSerialized' 在不更改的情况下使用序列化上下文恢复。

智能体工具可以将所有嵌套运行事件流回你的应用。根据你构建工具的方式选择合适的钩子样式:

Streaming agent tools
import { Agent } from '@openai/agents';
const billingAgent = new Agent({
name: 'Billing Agent',
instructions: 'Answer billing questions and compute simple charges.',
});
const billingTool = billingAgent.asTool({
toolName: 'billing_agent',
toolDescription: 'Handles customer billing questions.',
// onStream: simplest catch-all when you define the tool inline.
onStream: (event) => {
console.log(`[onStream] ${event.event.type}`, event);
},
});
// on(eventName) lets you subscribe selectively (or use '*' for all).
billingTool.on('run_item_stream_event', (event) => {
console.log('[on run_item_stream_event]', event);
});
billingTool.on('raw_model_stream_event', (event) => {
console.log('[on raw_model_stream_event]', event);
});
const orchestrator = new Agent({
name: 'Support Orchestrator',
instructions: 'Delegate billing questions to the billing agent tool.',
tools: [billingTool],
});
  • 事件类型匹配 RunStreamEvent['type']raw_model_stream_eventrun_item_stream_eventagent_updated_stream_event
  • onStream 是最简单的“兜底”方式,适合内联声明工具时使用(tools: [agent.asTool({ onStream })])。如果不需要按事件路由,请使用它。
  • on(eventName, handler) 允许你选择性订阅(或使用 '*'),在需要更细粒度处理或在创建后附加监听器时更合适。
  • 如果你提供了 onStream 或任一 on(...) 处理器,agent‑as‑tool 将自动以流式模式运行;否则保持非流式路径。
  • 处理器并行调用,因此缓慢的 onStream 回调不会阻塞 on(...) 处理器(反之亦然)。
  • 当工具通过模型工具调用触发时会提供 toolCallId;直接 invoke() 调用或提供商差异可能会省略它。

你可以通过 Model Context Protocol (MCP) 服务器暴露工具,并将其附加到智能体。 例如,你可以使用 MCPServerStdio 启动并连接到 stdio MCP 服务器:

Local MCP server
import { Agent, MCPServerStdio } from '@openai/agents';
const server = new MCPServerStdio({
fullCommand: 'npx -y @modelcontextprotocol/server-filesystem ./sample_files',
});
await server.connect();
const agent = new Agent({
name: 'Assistant',
mcpServers: [server],
});

完整示例参见 filesystem-example.ts。此外,如果你在寻找有关 MCP 服务器工具集成的完整指南,请参考 MCP 集成 获取详情。 在管理多个服务器(或部分故障)时,使用 connectMcpServers 并遵循 MCP 集成 中的生命周期指导。


@openai/agents-extensions/experimental/codex 提供了 codexTool(),这是一个函数工具,将模型的工具调用路由到 Codex SDK,从而使智能体可以自主运行面向工作区的任务(shell、文件编辑、MCP 工具)。该接口为实验性,可能会发生变化。

先安装依赖:

Terminal window
npm install @openai/agents-extensions @openai/codex-sdk

快速开始:

Experimental Codex tool
import { Agent } from '@openai/agents';
import { codexTool } from '@openai/agents-extensions/experimental/codex';
export const codexAgent = new Agent({
name: 'Codex Agent',
instructions:
'Use the codex tool to inspect the workspace and answer the question. When skill names, which usually start with `$`, are mentioned, you must rely on the codex tool to use the skill and answer the question.',
tools: [
codexTool({
sandboxMode: 'workspace-write',
workingDirectory: '/path/to/repo',
defaultThreadOptions: {
model: 'gpt-5.2-codex',
networkAccessEnabled: true,
webSearchEnabled: false,
},
}),
],
});

需知事项:

  • 认证:提供 CODEX_API_KEY(优先)或 OPENAI_API_KEY,或传入 codexOptions.apiKey
  • 输入:严格的 schema——inputs 必须至少包含一个 { type: 'text', text }{ type: 'local_image', path }
  • 安全:将 sandboxModeworkingDirectory 搭配使用;如果目录不是 Git 仓库,请设置 skipGitRepoCheck
  • 线程:useRunContextThreadId: true 会在 runContext.context 中读取/存储最新的 thread id,便于在你的应用状态中跨轮次复用。
  • 线程 ID 优先级:工具调用的 threadId(若你的 schema 包含)优先,其次是运行上下文中的 thread id,最后是 codexTool({ threadId })
  • 运行上下文键:对于 name: 'codex' 默认为 codexThreadId;对于如 name: 'engineer' 的名称则为 codexThreadId_<suffix>(标准化后为 codex_engineer)。
  • 可变上下文要求:当启用 useRunContextThreadId 时,在 run(..., { context }) 传入可变对象或 Map
  • 命名:工具名会标准化到 codex 命名空间(engineer 变为 codex_engineer),且同一智能体中重复的 Codex 工具名会被拒绝。
  • 流式传输:onStream 映射 Codex 事件(推理、命令执行、MCP 工具调用、文件变更、Web 搜索),便于你记录或追踪进度。
  • 输出:工具结果包含 responseusagethreadId,且 Codex 的 token 用量会记录在 RunContext 中。
  • 结构:outputSchema 可为描述符、JSON schema 对象或 Zod 对象。对于 JSON 对象 schema,additionalProperties 必须为 false

运行上下文线程复用示例:

Codex run-context thread reuse
import { Agent, run } from '@openai/agents';
import { codexTool } from '@openai/agents-extensions/experimental/codex';
// Derived from codexTool({ name: 'engineer' }) when runContextThreadIdKey is omitted.
type ExampleContext = {
codexThreadId_engineer?: string;
};
const agent = new Agent<ExampleContext>({
name: 'Codex assistant',
instructions: 'Use the codex tool for workspace tasks.',
tools: [
codexTool({
// `name` is optional for a single Codex tool.
// We set it so the run-context key is tool-specific and to avoid collisions when adding more Codex tools.
name: 'engineer',
// Reuse the same Codex thread across runs that share this context object.
useRunContextThreadId: true,
sandboxMode: 'workspace-write',
workingDirectory: '/path/to/repo',
defaultThreadOptions: {
model: 'gpt-5.2-codex',
approvalPolicy: 'never',
},
}),
],
});
// The default key for useRunContextThreadId with name=engineer is codexThreadId_engineer.
const context: ExampleContext = {};
// First turn creates (or resumes) a Codex thread and stores the thread ID in context.
await run(agent, 'Inspect src/tool.ts and summarize it.', { context });
// Second turn reuses the same thread because it shares the same context object.
await run(agent, 'Now list refactoring opportunities.', { context });
const threadId = context.codexThreadId_engineer;
void threadId;

关于控制模型何时以及如何必须使用工具(modelSettings.toolChoicetoolUseBehavior 等),请参考智能体


  • 简短而明确的描述——说明工具做了什么、何时使用它。
  • 校验输入——尽可能使用 Zod schema 进行严格的 JSON 校验。
  • 避免在错误处理器中产生副作用——errorFunction 应返回有用的字符串,而不是抛出异常。
  • 单一职责——小而可组合的工具能带来更好的模型推理。