本文是 Agent SDK 中内置工具 Tools(工具)模块的参考。Tools 将 Sandbox(沙箱)的代码执行、命令运行、文件操作和网页操作封装为可调用的工具。您可以获取并选择所需工具,由业务代码直接执行,或交给 Agent 框架调用。本文先给出一段可直接运行的最短示例,随后说明工具集的获取与选择、各工具的用途和入参、框架适配、执行结果与错误处理。
工具决定了 Agent 能够执行哪些实际动作——抓取网页、运行代码、读写文件、执行命令等。SDK 已内置一组开箱即用的工具,您无需自行实现底层交互逻辑,即可让 Agent 具备访问网络、操作文件系统与执行代码的能力。
内置工具通过核心包 @iga-pages/agent 的 ./tools 子路径提供,入口为 getTools(sandbox):该方法从一个沙箱实例静态构建完整工具集并返回。所有工具均依赖传入的 Sandbox(沙箱)实例运行——工具的网络访问、文件操作与命令执行都发生在该沙箱环境内。关于沙箱的创建与配置,请参见沙箱 Sandbox。
getTools(sandbox) 从当前 Tools SDK 的静态注册表构建内置工具集。
在获取并使用工具之前,请确认您已完成以下准备:
@iga-pages/agent,并可通过子路径 @iga-pages/agent/tools 引入 getTools。安装步骤请参见安装与环境准备。getTools。下面这段代码是使用工具的最短闭环:取当前会话的沙箱,传给 getTools() 获取工具集,再调用单个工具的 execute() 执行一段代码并读取结果。
import { getConversationSandbox } from "@iga-pages/agent/sandbox"; import { getTools } from "@iga-pages/agent/tools"; export async function calculate(conversationId: string) { const sandbox = getConversationSandbox(conversationId); const tools = getTools(sandbox); const result = await tools.code_run.execute({ language: "python", code: "print(2 ** 20)", timeout: 30, }); if (result.status === "error") { console.error(result.error.code, result.error.message); return result; } console.log(result.data); return result; }
要点说明:
conversationId 为应用已校验归属的非空会话 ID,最多 256 UTF-8 字节。result.status 判断执行结果;成功数据已经过 Tools 转换,可直接从 result.data 读取。结果的完整说明见执行结果与错误处理。getTools(sandbox) 同步返回工具集,本身不执行操作,只接收一个沙箱实例参数。工具的框架格式由导入的子路径决定,而不是通过参数选项切换:@iga-pages/agent/tools 返回可移植工具集,各框架适配则从对应子路径导入同名的 getTools。各子路径与返回类型如下:
| 导入子路径 | 返回类型 |
|---|---|
@iga-pages/agent/tools | PortableTools(可移植的工具定义) |
@iga-pages/agent/tools/openai | OpenAISdkTools |
@iga-pages/agent/tools/openai-agents | OpenAIAgentsTools |
@iga-pages/agent/tools/claude | ClaudeAgentTools |
@iga-pages/agent/tools/langchain | LangChainTools(LangGraph 与 DeepAgents 共用) |
从 @iga-pages/agent/tools 导入时返回可移植工具集,单个工具包含 name、description、inputSchema 和 execute(input, options?);langchain 子路径的适配同时供 LangGraph 与 DeepAgents 使用,需要应用侧安装 @langchain/core。
获取到的工具集对象提供以下方法,用于按需筛选或转换工具:
| 方法 | 用途 |
|---|---|
all() | 返回全部内置工具(已按所选子路径适配)。 |
get(name) | 按名称取单个工具(未知名称抛错)。 |
files()、shell()、code()、browser() | 按能力域返回该组工具。 |
definitions(names?) | 返回可移植工具定义(可按名称筛选)。 |
能力域与工具的对应关系为:
shell 组为 shell_execfiles 组为 files_read、files_write、files_list、files_search、files_findcode 组为 code_runbrowser 组为 browser_fetch、browser_screenshot您也可以直接按工具名或分组取用:
const tools = getTools(sandbox); const selected = [tools.files_read, tools.files_list]; const fileTools = tools.files();
tools.files() 返回工具数组,tools.files_read.execute({ path }) 才读取文件。
选择工具决定提供哪些动作,具体资源访问权限仍由应用与沙箱控制。
将适配后的工具接入 OpenAI Agents、LangGraph、DeepAgents 或 Claude Agent SDK 等框架的做法见后文接入 Agent 框架;跨 SDK 模块的框架适配汇总另见框架适配。
以下示例使用未指定 framework 的通用工具集,execute(input) 返回 ToolResult;timeout 参数的单位为秒。
执行 Python 或 JavaScript,适合计算、数据处理和短程序。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
language | "python" | "javascript" | 是 | 执行语言。 |
code | string | 是 | 源代码。 |
timeout | number | 否 | 超时时间,单位为秒。 |
const result = await tools.code_run.execute({ language: "javascript", code: "console.log([1, 2, 3].reduce((sum, n) => sum + n, 0))", timeout: 30, });
成功数据包含 language、code,以及可选的 outputs、stdout、stderr、exitCode、traceback、sessionId。非零退出码和失败状态会转换为 status: "error"。JavaScript 模式不表示支持直接运行 TypeScript。
执行 Shell 命令,适合调用沙箱中的命令行程序。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
command | string | 是 | Shell 命令。 |
cwd | string | 否 | 工作目录。 |
timeout | number | 否 | 超时时间,单位为秒。 |
const result = await tools.shell_exec.execute({ command: "pwd && ls -la", cwd: "/tmp", timeout: 30, });
成功数据包含 sessionId、command,以及可选的 output、console 和 exitCode。
读取文件文本,可传入行范围参数。适合读取已知路径的文件内容。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
path | string | 是 | 文本文件路径。 |
startLine | number | 否 | 起始行参数,正整数。 |
endLine | number | 否 | 结束行参数,正整数。 |
const result = await tools.files_read.execute({ path: "/tmp/notes.txt", startLine: 1, endLine: 20, });
成功数据包含 content 和 file,正文位于 result.data.content。行范围由底层接口处理,Tools 不额外检查起止行的相对顺序。大文件可分段读取;files_read 只读取文本文件。
将文本写入沙箱文件,可覆盖已有内容或追加内容。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
path | string | 是 | 目标文件路径。 |
content | string | 是 | 要写入的文本,允许空字符串。 |
append | boolean | 否 | true 追加,false 覆盖。 |
const result = await tools.files_write.execute({ path: "/tmp/notes.txt", content: "Hello\n", append: false, });
成功数据包含 file 和可选的 bytesWritten,不返回完整文件内容。追加操作重复执行可能产生重复内容。沙箱文件不会通过 Tools 自动持久化,需要长期保存的产物应另行写入存储。
列出指定目录中的文件和子目录。目录结构未知时,可先列目录再读文件。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
path | string | 是 | 目录路径。 |
recursive | boolean | 否 | 是否递归列出子目录。 |
const result = await tools.files_list.execute({ path: "/tmp", recursive: false, });
成功数据包含 path、可选的 files 和计数字段。文件条目使用 isDirectory、modifiedTime 等 camelCase 字段。
按文本或正则表达式模式搜索文件内容。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
path | string | 是 | 搜索根路径。 |
pattern | string | 是 | 文本或正则表达式模式。 |
maxResults | number | 否 | 最大匹配数量,正整数。 |
const result = await tools.files_search.execute({ path: "/tmp", pattern: "ERROR", maxResults: 20, });
成功数据包含 path、pattern,以及可选的 matches、matchCount、filesSearched、filesMatched、truncated。匹配项使用 lineNumber、lineContent、contextBefore、contextAfter 等 camelCase 字段。正则语法和匹配行为由沙箱服务处理。
按 glob 模式定位文件。与 files_search 的区别是:它匹配文件名,不搜索文件内容。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
path | string | 是 | 搜索根路径。 |
glob | string | 是 | 文件名 glob 模式。 |
const result = await tools.files_find.execute({ path: "/tmp", glob: "**/*.txt", });
成功数据包含 path 和可选的 files。搜索子目录文件可使用 **/ 模式。
导航到指定 URL,再读取浏览器中的页面 HTML。适合访问需要浏览器渲染的已知网页,不提供搜索引擎查询能力。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
url | string | 是 | 要打开的绝对 URL。 |
const result = await tools.browser_fetch.execute({ url: "https://example.com", });
成功结果示意:
{ "status": "success", "data": { "url": "https://example.com/", "title": "Example Domain", "status": 200, "content": "<!DOCTYPE html>..." } }
content 为完整 HTML,不是纯正文或 Markdown。Tools 不设置统一的 HTML 长度上限。导航元信息由底层服务提供,url、title、status、loadTimeMs 等字段不保证每次全部出现。
导航或读取 HTML 返回业务失败时,即使底层 HTTP 请求成功,也会转换为 status: "error"。该工具会改变沙箱浏览器的当前页面。
对沙箱浏览器的当前页面截图。没有 url 参数,应先通过 browser_fetch 打开目标网页。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
fullPage | boolean | 否 | 是否截取整页。 |
const page = await tools.browser_fetch.execute({ url: "https://example.com" }); if (page.status === "success") { const screenshot = await tools.browser_screenshot.execute({ fullPage: true }); console.log(screenshot); }
不指定选项时,调用 tools.browser_screenshot.execute({})。
截图成功时,data 包含完整 Base64 图片、MIME 类型和 Base64 字符串长度:
type ScreenshotResult = { status: "success"; data: { base64Image: string; mimeType: "image/png" | "image/jpeg" | "image/webp" | "image/gif"; base64ImageLength: number; }; };
base64ImageLength 是 Base64 字符串长度,不是图片文件大小;结果不包含文件路径或下载地址,也不会根据模型是否支持视觉自动切换。
浏览器工具共享同一沙箱的当前页面。“导航 → 截图”等有先后依赖的操作应串行执行,避免其他导航改变截图目标。
前面的 execute() 是由业务代码直接执行工具。若希望由模型自主决定何时调用工具,需要先把工具适配成目标框架的格式,再交给框架驱动:导入的子路径决定工具格式,不改变操作所在的沙箱。
各框架从对应子路径导入 getTools,直接取得适配后的工具集。下面以 LangGraph 为例,演示工具视角下最关键的一步:从 @iga-pages/agent/tools/langchain 获取工具,再把所需工具传入框架入口。LangGraph 与 DeepAgents 共用该子路径。
import { ChatOpenAI } from "@langchain/openai"; import { createReactAgent } from "@langchain/langgraph/prebuilt"; import { getConversationSandbox } from "@iga-pages/agent/sandbox"; import { getTools } from "@iga-pages/agent/tools/langchain"; export async function runAgent(conversationId: string, modelName: string) { const sandbox = getConversationSandbox(conversationId); const tools = getTools(sandbox); const agent = createReactAgent({ llm: new ChatOpenAI({ model: modelName }), tools: [tools.code_run], }); const result = await agent.invoke({ messages: [{ role: "user", content: "使用工具计算 2 的 20 次方。" }], }); return result.messages.at(-1)?.content; }
OpenAI Agents SDK 从 @iga-pages/agent/tools/openai-agents 导入 getTools,再把所需工具传入 Agent。Claude Agent SDK 从 @iga-pages/agent/tools/claude 导入 getTools,调用 toMcpConfig() 选择工具,再用返回的配置创建进程内 MCP server 并交给 query()。
说明
以上仅演示本模块的适配出口如何接入框架。将 OpenAI Agents、LangGraph、DeepAgents、Claude Agent SDK 等框架从零搭建,并把 Store、Tools、Sandbox 等模块组合成一个完整应用的端到端示例,请参见框架适配。
通用工具的 execute() 返回以下结构:
import type { ToolError } from "@iga-pages/agent/tools"; type ToolResult<T = unknown> = | { readonly status: "success"; readonly data: T } | { readonly status: "error"; readonly error: ToolError };
通过 status 判断工具调用结果。请求失败、接口返回 success: false、文件操作错误,以及代码或命令的非零退出码、失败状态,都会转换为 status: "error"。成功时可直接读取 data。
| 工具 | 成功时 data 的内容 |
|---|---|
文件工具、shell_exec、code_run | 具体业务结果;如文件正文位于 result.data.content |
browser_fetch | 导航元信息和 content,其中 content 为完整 HTML |
browser_screenshot | { base64Image, mimeType, base64ImageLength },包含完整图片 |
const result = await tools.files_read.execute({ path: "/tmp/notes.txt" }); if (result.status === "success") { console.log(result.data.content); } else { console.error(result.error); }
成功结果的 data 会按敏感字段名脱敏。截图工具保留完整图片,其他结果中的图片 / Base64 字符串转换为长度信息。普通文本和 browser_fetch 的 HTML 不设统一长度上限。
| 执行入口 | 返回形式 |
|---|---|
execute() | ToolResult 对象;OpenAI Agents 的 invoke() 在截图成功时返回文本和图片数组,其余返回 ToolResult |
LangChain 工具的 invoke(),包括 LangGraph / DeepAgents 适配 | 普通结果返回序列化后的 ToolResult;截图成功时返回文本和图片数组。框架使用 ToolCall 调用时可封装为工具消息 |
Claude MCP 工具的 handler() | 普通结果返回 MCP 文本块;截图成功时返回文本和图片块;失败时带 isError: true |
工具执行失败时返回 status: "error",错误信息位于 error:
| 字段 | 说明 |
|---|---|
tool | 失败的工具名称。 |
code | 错误类型,例如 HTTP 429 对应 TooManyRequests;无对应 HTTP 错误状态时可能为 SandboxError,参数校验等本地错误可能为 UnknownError。 |
status | 可选,HTTP 状态码;网络请求失败时可能为 0。 |
message | 简短的错误说明,超过 1000 字符时用省略号结束。 |
issues | 可选,参数检查发现的所有问题,说明哪个参数有误以及原因。 |
例如,同时读取文件的请求过多时:
{ "status": "error", "error": { "tool": "files_read", "code": "TooManyRequests", "status": 429, "message": "Quota exceeded" } }
排查问题时,可以先看 message,参数检查失败时再查看 issues 中的详情。不同框架的返回方式见上一节。
如果执行工具时在创建沙箱或获取访问权限这一步出错,error 包含 tool、code、message 和可选的 status。例如,没有访问权限时可能返回 code: "Forbidden"、status: 403,具体原因查看 message。
通过结果中的 status 判断并记录错误:
const result = await tools.files_read.execute({ path: "/tmp/notes.txt" }); if (result.status === "error") { console.error(result.error); } else { console.log(result.data); }
获取沙箱、选择工具或加载框架依赖时,可能抛出异常。LangGraph / DeepAgents 的 invoke() 在参数有误或调用取消时也可能抛出异常,需用 try/catch 捕获。Tools 不会自行反复重试;重试写文件或执行命令前,请确认重复执行不会造成影响。
从 @iga-pages/agent/tools/claude 获取工具后,可调用 toMcpConfig(name?, { names?, alwaysLoad? }) 生成 Claude Agent SDK 所需的 MCP 配置。该方法返回 { name, tools, allowedTools };应用再用 createSdkMcpServer() 创建进程内 MCP server。