实战:路径与工作流

OpenAI Agents SDK JS/TS 快速入门

更新 原创整合
标签
openai-agents-sdktypescripttutorialtools

适合谁

场景 是否适合 原因
Node.js 后端里加一个任务助手 适合 SDK 原生支持 JS/TS,容易接 Express、Hono、Next.js API Route
给已有 SaaS 加客服、报告、检索 Agent 适合 工具函数可以直接调用现有业务 API
要让 Agent 改代码、跑测试 谨慎 可以看 SandboxAgent,但要先做目录隔离和权限控制
只想日常写代码提效 不适合 直接用 Claude Code、Cursor、Copilot Agent 更快
需要极强流程确定性 不适合单独使用 应结合普通代码状态机,Agent 只负责不确定步骤

推荐路线:先做一个单 Agent + 一个工具的闭环,不要一上来做多 Agent。等你能稳定观测输入、工具调用、最终输出后,再考虑 handoffs、sessions 和 tracing。


环境要求

官方 README 标注支持 Node.js 22 或更高版本,也支持 Deno、Bun;Cloudflare Workers 属于实验支持,需要启用 nodejs_compat。本篇示例用 Node.js 22。

mkdir openai-agents-js-demo
cd openai-agents-js-demo
npm init -y
npm install @openai/agents zod

把项目切到 ESM:

npm pkg set type=module

配置 API Key:

export OPENAI_API_KEY="sk-..."

不要把 Key 写进代码或提交到仓库。生产环境应通过平台密钥管理注入环境变量。


版本更新注意

当前最新版为 v0.11.4(2026-05-12)。如果从 v0.10.x 或更早版本升级,注意以下变更:

v0.11.0(2026-05-08)— 包含破坏性变更

Sandbox 本地源物化边界收紧。 LocalFile.srcLocalDir.src 现在必须落在物化的 baseDir 内,除非你在 Manifest 里显式声明 extraPathGrants。如果你的沙箱代码从 baseDir 外部复制文件,升级后这些路径会被拦截。修复方式:

const manifest = new Manifest({
  // ...
  extraPathGrants: ['/data/external-assets', '/tmp/shared-cache'],
});

这是一个安全边界修复——防止沙箱内运行的代码静默访问未授权路径。不要绕过它,而是把实际需要的外部路径显式声明出来。

RealtimeAgent 默认模型切换为 gpt-realtime-2 如果你的代码没有显式指定模型,升级后 RealtimeAgent 会使用新模型。测试一下语音质量、延迟和 token 消耗是否仍然符合预期。

v0.11.1(2026-05-09)

  • 沙箱环境变量解析器在 Manifest 合并时不再丢失(之前合并多个 Manifest 可能覆盖 env 配置)
  • Blaxel 沙箱提供方行为对齐修复

v0.11.2(2026-05-11)— 大批量 Bug 修复

这版集中修复了生产环境稳定性问题,以下是影响较大的几项:

模块 修复内容
Sandbox 可配置的归档解压上限;结构化错误详情;Cloudflare 执行和清理错误可见
Tracing Span ID 防护;批量处理不再因导出器异常中断
Realtime 输出音频内容保留;空音频通道不再崩溃
Sessions Prisma 和 FileSession 记录损坏时的防护处理
AI SDK 并行工具调用时推理内容去重
其他 GitRepo 子路径别名保留和验证;回调式 handoff hooks 允许;推理项清理

v0.11.3 – v0.11.4(2026-05-11 ~ 05-12)

  • Tracing 关闭改为 best-effort,超时时主动中止导出,不再阻塞进程退出
  • 空 chat completions 工具输出不再发送
  • 未知 Realtime 工具不触发自动响应
  • Local approval 拒绝原因保留
  • Reasoning 身份在 OpenAI Conversations 持久化时保留

升级建议: 如果你用了 SandboxAgent 或 RealtimeAgent,务必升到 v0.11.4。Tracing 和 Session 的修复对生产稳定性直接有效。


第一个 Agent

创建 index.mjs

import { Agent, run } from '@openai/agents';

const agent = new Agent({
  name: 'ReleaseAssistant',
  instructions: 'You explain technical release notes as concrete engineering actions.',
});

const result = await run(
  agent,
  'Summarize how a backend team should evaluate a new SDK release.'
);

console.log(result.finalOutput);

运行:

node index.mjs

这个例子只有一个 Agent,没有工具。它适合验证三件事:包能正常加载、认证能通过、你能拿到 finalOutput。如果这一步不稳定,不要继续加工具或多 Agent。


加一个函数工具

真实 Agent 的价值来自工具。下面的例子模拟一个内部文档查询工具,让 Agent 先查资料再回答。

import { Agent, run, tool } from '@openai/agents';
import { z } from 'zod';

const docs = {
  mcp: 'MCP connects models to external tools and resources through a standard protocol.',
  tracing: 'Tracing records agent runs, tool calls, and model usage for debugging.',
  guardrails: 'Guardrails validate inputs or outputs before the workflow proceeds.',
};

const searchDocs = tool({
  name: 'search_docs',
  description: 'Search the internal agent glossary by keyword.',
  parameters: z.object({
    keyword: z.string().describe('One lowercase keyword, such as mcp or tracing'),
  }),
  execute: async ({ keyword }) => {
    return docs[keyword.toLowerCase()] ?? 'No matching entry found.';
  },
});

const agent = new Agent({
  name: 'DocsAssistant',
  instructions: [
    'Answer in three short bullets.',
    'Use search_docs before explaining glossary terms.',
    'If the tool returns no match, say what is missing instead of guessing.',
  ].join('\n'),
  tools: [searchDocs],
});

const result = await run(agent, 'Explain tracing for an agent product team.');
console.log(result.finalOutput);

工具设计要保守:参数越窄,Agent 越容易稳定调用。不要把一个 execute_sql(query: string) 这种高权限工具直接暴露给模型;先封装成 get_user_order_summary(userId) 这类业务动作。


最小项目结构

小项目不需要复杂目录。先用这套结构:

openai-agents-js-demo/
  package.json
  src/
    agents/
      docs-agent.mjs
    tools/
      search-docs.mjs
    index.mjs

拆分规则很简单:

文件 放什么 不放什么
agents/*.mjs Agent 名称、instructions、工具组合 具体数据库查询逻辑
tools/*.mjs 参数 schema、业务 API 调用、错误返回 长篇提示词
index.mjs 运行入口、输入输出、日志 复杂业务规则

这样拆不是为了"架构优雅",而是方便后续测试:工具可以单测,Agent instructions 可以单独评审,入口只负责把它们串起来。


什么时候加多 Agent

不要因为 SDK 支持 handoffs 就马上拆多 Agent。满足下面任一条件再拆:

信号 拆法
同一个 Agent 的 instructions 超过 40 行 拆成 Router + Specialist
工具权限差异很大 高权限工具放到单独 Agent 后面
输出需要不同审查标准 生成 Agent 和 Review Agent 分开
任务需要长期运行或文件系统状态 研究 SandboxAgent,而不是普通 Agent 硬撑

最常见的第一种拆法是 Router 模式:入口 Agent 只判断任务类型,把问题交给"文档检索""数据分析""写作整理"等专门 Agent。不要让 Router 自己完成所有工作。


错误处理基线

上线前至少处理四类错误:

错误 典型现象 处理方式
缺少 API Key 启动后认证失败 进程启动时检查 OPENAI_API_KEY
工具参数不合法 工具没有执行或反复重试 用 Zod 收窄 schema,描述写具体
工具内部失败 返回异常堆栈给模型 捕获异常,返回结构化错误字符串
输出不可用 Agent 答非所问或格式漂移 缩短 instructions,加输出格式约束

工具内部不要直接抛业务细节给模型:

const safeTool = tool({
  name: 'get_order_status',
  description: 'Get order status by order ID.',
  parameters: z.object({ orderId: z.string().min(6) }),
  execute: async ({ orderId }) => {
    try {
      return await getOrderStatus(orderId);
    } catch {
      return 'ORDER_LOOKUP_FAILED: ask the user to verify the order ID.';
    }
  },
});

Agent 看到稳定的错误码,才有机会做合理降级。随机堆栈只会污染上下文。


生产化检查表

检查项 最小要求
输入边界 用户输入长度、文件大小、请求频率有限制
工具权限 每个工具只做一个业务动作,不暴露通用 Shell 或 SQL
沙箱路径 Sandbox Manifest 声明 extraPathGrants,不依赖 baseDir 外的隐式访问
日志 记录 run id、工具名、耗时、错误码,不记录敏感原文
回归样例 保存 10-20 个真实用户问题,每次改 instructions 后重跑
人工兜底 高风险操作必须有人确认或只生成草稿

JS/TS SDK 的优势是容易嵌进现有产品;风险也是太容易把现有产品的高权限 API 暴露给模型。先把工具边界做窄,再谈复杂编排。


和 Python 版怎么选

你当前团队 推荐
主应用是 Node.js / Next.js / Cloudflare Workers 先用 JS/TS SDK
数据、评估、机器学习脚本主要在 Python 先用 Python SDK
要接前端实时语音体验 看 JS/TS 的 Realtime Agents(注意 v0.11.0 后默认模型为 gpt-realtime-2
要做离线批处理、评估流水线 Python 生态更顺手

选择标准不是"哪个 SDK 更强",而是哪个能更快接入你已有的鉴权、日志、数据库和部署链路。Agent 框架本身只是运行时,真正的工程成本在工具边界和观测系统。