跳转到内容

工具

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

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

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

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

具体参数集与 OpenAI Responses API 一致——高级选项如 rankingOptions 或语义过滤请参考官方文档。


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

  • 计算机操作——实现 Computer 接口并传递给 computerTool()
  • Shell——实现 Shell 接口并传递给 shellTool()
  • 应用补丁——实现 Editor 接口并传递给 applyPatchTool()

这些工具在本地执行,由 OpenAI 托管。需要在运行时直接访问文件、终端或 GUI 自动化时使用。工具调用仍由 OpenAI 模型响应请求,但你的应用需在本地执行它们。

本地内置工具
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;

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

使用 Zod 参数的函数工具
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 参数会自动启用 strict 模式。
strict当为 true(默认)时,如果参数验证失败,SDK 会返回模型错误。设置为 false 可进行模糊匹配。
execute(args, context) => string | unknown | Promise<...>——你的业务逻辑。非字符串输出会被序列化给模型。可选的第二个参数为 RunContext
errorFunction自定义处理器 (context, error) => string,用于将内部错误转换为用户可见字符串。
needsApproval在执行前需要人工批准。参见人机协作
isEnabled按运行条件性暴露该工具;接受布尔值或谓词。
inputGuardrails在工具执行前运行的护栏;可以拒绝或抛出。参见护栏
outputGuardrails在工具执行后运行的护栏;可以拒绝或抛出。参见护栏

如果你需要模型去“猜测”无效或不完整的输入,你可以在使用原始 JSON Schema 时禁用严格模式:

非严格 JSON Schema 工具
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 时控制上下文协调策略。

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

智能体工具的流式传输
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 服务器:

本地 MCP 服务器
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

快速开始:

实验性 Codex 工具
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 中读取/存储最新的线程 ID,便于在你的应用状态中跨轮次复用。
  • 线程 ID 优先级:工具调用的 threadId(如果你的 schema 包含它)优先,然后是运行上下文中的线程 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 运行上下文线程复用
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 应返回有用的字符串,而不是抛出异常。
  • 单一职责——小而可组合的工具能带来更好的模型推理。