工具
工具让智能体能够采取行动——获取数据、调用外部 API、执行代码,甚至进行计算机操作。JavaScript/TypeScript SDK 支持六种类别:
- Hosted OpenAI tools——与模型一同在 OpenAI 服务器上运行。(Web 搜索、文件搜索、Code Interpreter、图像生成)
- 本地内置工具——在你的环境中运行。(计算机操作、shell、apply_patch)
- 函数工具(Function tools)——用 JSON schema 包装任意本地函数,使 LLM 可以调用。
- Agents as tools——将整个智能体暴露为可调用工具。
- MCP 服务器——附加一个 Model Context Protocol 服务器(本地或远程)。
- 实验性:Codex 工具——将 Codex SDK 包装为函数工具以运行具备工作区感知的任务。
本指南接下来先介绍每个工具类别,然后总结通用的工具选择与提示词编写建议。
1. 托管工具(OpenAI Responses API)
Section titled “1. 托管工具(OpenAI Responses API)”当你使用 OpenAIResponsesModel 时,可以添加以下内置工具:
| 工具 | 类型字符串 | 目的 |
|---|---|---|
| Web search | 'web_search' | 互联网搜索。 |
| File / retrieval search | 'file_search' | 查询托管在 OpenAI 上的向量存储。 |
| Code Interpreter | 'code_interpreter' | 在沙箱环境中运行代码。 |
| Image generation | 'image_generation' | 基于文本生成图像。 |
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 友好的选项,如 searchContextSize、userLocation,以及 filters.allowedDomains。 |
fileSearchTool(ids, options?) | 第一个参数接受一个或多个向量存储 ID,另有 maxNumResults、includeSearchResults、rankingOptions 和过滤器等选项。 |
codeInterpreterTool(options?) | 当未提供 container 时,默认使用自动管理的容器。 |
imageGenerationTool(options?) | 支持图像生成配置,如 model、size、quality、background、inputFidelity、inputImageMask、moderation、outputCompression、partialImages 和输出格式。 |
这些辅助函数将 JavaScript/TypeScript 友好的选项名称映射到底层 OpenAI Responses API 工具负载。完整的工具 schema 与高级选项(如排序选项或语义过滤)请参考 OpenAI 官方文档。
2. 本地内置工具
Section titled “2. 本地内置工具”本地内置工具在你自己的环境中运行,需要你提供实现:
- 计算机操作——实现
Computer接口并传给computerTool()。 - Shell——提供本地
Shell实现,或配置托管的容器环境。 - Apply patch——实现
Editor接口并传给applyPatchTool()。
计算机操作与 apply‑patch 工具在本地执行,不由 OpenAI 托管。Shell 工具可根据 shellTool() 配置在本地或托管容器环境中运行。
工具调用仍由模型的响应请求,但你的应用控制这些调用如何执行。
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.ts 和 examples/tools/container-shell-inline-skill.ts。
3. 函数工具
Section titled “3. 函数工具”你可以使用 tool() 辅助函数将任意函数变成工具。
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 展示的清晰、可读的描述。 |
parameters | 是 | Zod schema 或原始 JSON schema 对象。使用 Zod parameters 会自动启用 strict 模式。 |
strict | 否 | 当为 true(默认)时,如果参数未通过校验,SDK 会返回模型错误。将其设为 false 可进行模糊匹配。 |
execute | 是 | (args, context, details) => string | unknown | Promise<...>——你的业务逻辑。非字符串输出会为模型进行序列化。context 为可选的 RunContext;details 包含 toolCall、resumeState、signal 等元数据。 |
errorFunction | 否 | 自定义处理器 (context, error) => string,将内部错误转化为用户可见的字符串。 |
timeoutMs | 否 | 每次调用的超时时间(毫秒)。必须大于 0 且不超过 2147483647。 |
timeoutBehavior | 否 | 超时模式:error_as_result(默认)向模型返回可见的超时消息,raise_exception 则抛出 ToolTimeoutError。 |
timeoutErrorFunction | 否 | 当 timeoutBehavior 为 error_as_result 时,用于自定义超时输出的处理器 (context, timeoutError) => string。 |
needsApproval | 否 | 在执行前需要人工批准。参见人机协作指南。 |
isEnabled | 否 | 按运行条件性地暴露工具;接受布尔值或谓词。 |
inputGuardrails | 否 | 在工具执行前运行的护栏;可拒绝或抛出。参见护栏。 |
outputGuardrails | 否 | 在工具执行后运行的护栏;可拒绝或抛出。参见护栏。 |
函数工具超时
Section titled “函数工具超时”使用 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 工具
Section titled “非严格 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; },});4. Agents as tools
Section titled “4. Agents as tools”有时你希望一个智能体在不完全交接对话的情况下“协助”另一个智能体。使用 agent.asTool():
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,并在函数执行期间用它来运行该智能体。如果你想提供任何 runConfig 或 runOptions 的属性,可以将它们传给 asTool() 方法来自定义 runner 的行为。
你还可以通过 asTool() 选项在智能体工具上设置 needsApproval 和 isEnabled,以集成到人机协作流程和条件性工具可用性中。
agent.asTool() 的高级结构化输入选项:
inputBuilder:将结构化的工具参数映射到嵌套智能体的输入负载。includeInputSchema:在嵌套运行中包含输入 JSON schema,以增强对 schema 的感知行为。resumeState:控制在恢复嵌套序列化RunState时的上下文协调策略:'merge'(默认)将实时的审批/上下文状态合并进序列化状态;'replace'则改用当前运行上下文;'preferSerialized'在不更改的情况下使用序列化上下文恢复。
来自智能体工具的流式事件
Section titled “来自智能体工具的流式事件”智能体工具可以将所有嵌套运行事件流回你的应用。根据你构建工具的方式选择合适的钩子样式:
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_event、run_item_stream_event、agent_updated_stream_event。 onStream是最简单的“兜底”方式,适合内联声明工具时使用(tools: [agent.asTool({ onStream })])。如果不需要按事件路由,请使用它。on(eventName, handler)允许你选择性订阅(或使用'*'),在需要更细粒度处理或在创建后附加监听器时更合适。- 如果你提供了
onStream或任一on(...)处理器,agent‑as‑tool 将自动以流式模式运行;否则保持非流式路径。 - 处理器并行调用,因此缓慢的
onStream回调不会阻塞on(...)处理器(反之亦然)。 - 当工具通过模型工具调用触发时会提供
toolCallId;直接invoke()调用或提供商差异可能会省略它。
5. MCP 服务器
Section titled “5. MCP 服务器”你可以通过 Model Context Protocol (MCP) 服务器暴露工具,并将其附加到智能体。
例如,你可以使用 MCPServerStdio 启动并连接到 stdio 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 集成 中的生命周期指导。
6. 实验性:Codex 工具
Section titled “6. 实验性:Codex 工具”@openai/agents-extensions/experimental/codex 提供了 codexTool(),这是一个函数工具,将模型的工具调用路由到 Codex SDK,从而使智能体可以自主运行面向工作区的任务(shell、文件编辑、MCP 工具)。该接口为实验性,可能会发生变化。
先安装依赖:
npm install @openai/agents-extensions @openai/codex-sdk快速开始:
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 }。 - 安全:将
sandboxMode与workingDirectory搭配使用;如果目录不是 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 搜索),便于你记录或追踪进度。 - 输出:工具结果包含
response、usage和threadId,且 Codex 的 token 用量会记录在RunContext中。 - 结构:
outputSchema可为描述符、JSON schema 对象或 Zod 对象。对于 JSON 对象 schema,additionalProperties必须为false。
运行上下文线程复用示例:
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;工具策略与最佳实践
Section titled “工具策略与最佳实践”工具使用行为
Section titled “工具使用行为”关于控制模型何时以及如何必须使用工具(modelSettings.toolChoice、toolUseBehavior 等),请参考智能体。
- 简短而明确的描述——说明工具做了什么、何时使用它。
- 校验输入——尽可能使用 Zod schema 进行严格的 JSON 校验。
- 避免在错误处理器中产生副作用——
errorFunction应返回有用的字符串,而不是抛出异常。 - 单一职责——小而可组合的工具能带来更好的模型推理。