21.1 只会说话的 Agent 不值钱
6月前我做一个能"改代码并预览"的 Agent。光输出文本没用,它得真能跑命令、读文件、开浏览器。我一度想自己搭执行环境,看到 Makers 内置沙箱才松口气——这活它接了。
沙箱底层是腾讯云隔离实例,专门承载 Agent 的"副作用"。LLM 不再只能聊天,能真动手。
21.2 两层 API,同一个实例
平台把沙箱包成两层,都挂在 context 上:
| 视角 | 字段 | 给谁 | 粒度 |
|---|---|---|---|
| LLM 视角 | context.tools.* |
传给 LLM 当工具 | 原子化,便于放开范围 |
| 开发者视角 | context.sandbox.* |
你直接调 | 按模块:commands/files/browser/runCode |
| 标叔的结论 | 两层共用一实例 | 不用自己维护 | 一致才省心 |
context.tools 里的内置工具,底层就是调 context.sandbox.*,没有两套逻辑。
21.3 内置工具清单(节选)
工具按能力原子化,LLM 按名字语义匹配:
| 工具 | 干什么 |
|---|---|
commands |
执行一次性 shell 命令 |
files_read / files_write |
读 / 写文件 |
browser_fetch |
真实 Chromium 取渲染后页面 |
browser_screenshot |
截图,返回 base64 |
code_interpreter |
跑代码 |
web_search |
轻量网页搜索 |
给 LLM 全部工具很简单:
import { Agent } from "@openai/agents";
const agent = new Agent({
name: "Assistant",
instructions: "Use sandbox tools.",
tools: context.tools.all(), // 全部内置工具
model,
});
预期结果:Agent 能自己决定调哪个工具,跑命令、读文件、开浏览器。
别一股脑全放开。只给文件 + 浏览器,不开放 shell 和代码解释器,更安全:
typescript const safeTools = [...context.tools.files(), ...context.tools.browser()];
21.4 不同框架,同一套工具
context.tools 的输出格式由 edgeone.json 里的 framework 决定。Claude / OpenAI / LangGraph / CrewAI / DeepAgents 各自适配。
{ "agents": { "framework": "claude-agent-sdk" } }
预期结果:你不用自己写工具转换,平台按框架把沙箱工具包成原生形态。我第一次对接 LangGraph 时,光工具适配就耗了两天,换成 Makers 的 toLangChainTools,一行就完事。
| framework | 输出形态 | 标叔的结论 |
|---|---|---|
| claude-agent-sdk | MCP server bundle | 直接 createSdkMcpServer |
| openai-agents-sdk | function-tool | 无需 helper |
| langgraph | LangChain 工具 | toLangChainTools |
| crewai | CrewAI 工具 | toCrewAITools |
21.5 开发者也能直接用沙箱
不只 LLM,你的代码也能直接操作沙箱。比如沙箱里起个 vite,把预览地址返前端:
await context.sandbox.commands.run("nohup npx vite --port 5173 &", { timeout: 10 });
const previewUrl = context.sandbox.getHost(5173); // 暴露到外网
return Response.json({ previewUrl });
预期结果:Agent 改完代码,立刻把预览地址给用户,闭环体验。
沙箱实例按conversation_id一对话一实例。我第一次跑长任务没续命,沙箱到点被回收,进度全丢。后来才学会在快到期前
extendTimeout。长任务用它续命,结束用kill()释放。别让它空跑烧额度。
Agent 会想、会记、会动手了。但它万一乱来怎么办?下一章,把它的每一步看穿。