Code mode 代码模式
添加于: @mastra/core@1.38.0
Code mode 让 agent 在隔离的 sandbox 中运行多工具计算,并将结果作为单个更准确的响应返回。
模型不再一次一轮地调用工具,而是针对用户查询编写定制的函数。该函数将你现有的工具编排为 external_* 函数,并将其结果缩减或聚合为一个结构化答案。
createCodeMode() 返回此工具,默认 id 为 execute_typescript。id 可配置,因此一个 agent 可以同时拥有多个 code mode 工具,每个工具都限定于不同的工具集(参见跨多个代码工具限定工具范围)。
何时使用 code mode何时使用 code mode的直接链接
当 agent 需要涉及多个工具来回答用户查询或执行复杂计算时,使用 code mode:
- 更少的往返:多工具查询在一次工具调用中运行,而不是为每个工具决策重复 agent 循环。
- 更小的上下文:函数可以在将大型工具响应返回给 agent 之前进行缩减或聚合。
- 正确的数学计算:求和、平均值和其他算术运算以 JavaScript 运行,而不是作为 token 预测。
- 提前规划:过滤、聚合和分支在函数内部完成,而不是跨多个轮次。
工作原理工作原理的直接链接
没有 code mode 时,多工具查询可能会多次运行 agent 循环。模型选择一个工具并读取结果,然后按需重复该过程。
每一轮都会将完整的工具响应添加到 agent 的上下文窗口,这可能导致推理质量下降并增加 token 用量。
使用 code mode 时,你的工具继续在宿主上运行,具备完整的校验、request context 和 tracing。只有模型的编排代码在 sandbox 中运行。每次 external_* 调用都会桥接回宿主上的真实工具,函数可以在向 agent 返回一个响应之前缩减或聚合结果。
函数在 Workspace sandbox中运行。由于 code mode 运行模型编写的代码,你必须通过传入 sandbox 或使用提供 sandbox 的 workspace 来有意选择其执行边界。显式传入 new LocalSandbox() 可在宿主机器上执行。这会以宿主 node 进程的宿主权限运行函数,因此仅用于受信任的环境或本地开发。
自带执行边界的传输是例外:使用 IsolatedVmCodeModeTransport时,程序在进程内 V8 isolate 中运行,无需 sandbox(参见进程内隔离)。
快速开始快速开始的直接链接
createCodeMode() 返回工具以及生成的指令。未指定 id 时,工具使用名称 execute_typescript。将两者都添加到 agent:
import { Agent } from '@mastra/core/agent'
import { createCodeMode, createTool } from '@mastra/core/tools'
import { LocalSandbox } from '@mastra/core/workspace'
import { z } from 'zod'
const getTopProducts = createTool({
id: 'getTopProducts',
description: 'Get top selling products',
inputSchema: z.object({ limit: z.number() }),
outputSchema: z.object({
products: z.array(z.object({ id: z.string(), name: z.string(), totalSales: z.number() })),
}),
execute: async ({ limit }) => fetchTopProducts(limit),
})
const getProductRatings = createTool({
id: 'getProductRatings',
description: 'Get ratings for a product',
inputSchema: z.object({ productId: z.string() }),
outputSchema: z.object({ ratings: z.array(z.object({ score: z.number() })) }),
execute: async ({ productId }) => fetchRatings(productId),
})
const { tool, instructions } = createCodeMode({
tools: { getTopProducts, getProductRatings },
sandbox: new LocalSandbox(), // required; runs on the host — see "How it works"
})
const agent = new Agent({
id: 'shop-assistant',
name: 'shop-assistant',
instructions: ['You are a helpful shopping assistant.', instructions],
model: 'openai/gpt-5.6-sol',
tools: { execute_typescript: tool },
})
当被问到 "What are the top 5 products and the average rating for each?" 时,模型会发出一次 execute_typescript 调用,而不是许多单独的工具调用:
const top = await external_getTopProducts({ limit: 5 })
const ratings = await Promise.all(
top.products.map(p => external_getProductRatings({ productId: p.id })),
)
return top.products.map((product, i) => {
const scores = ratings[i].ratings.map(r => r.score)
const avg = scores.reduce((sum, s) => sum + s, 0) / scores.length
return {
name: product.name,
sales: product.totalSales,
averageRating: Math.round(avg * 100) / 100,
}
})
全部五次评分查询并行运行,平均值在 JavaScript 中计算,agent 收到一个结构化结果。
要让 createCodeMode() 良好工作,请记住以下提示:
- 保持工具专注,让每个工具做好一件事,并由模型在代码中组合它们。
- 当调用可以用
Promise.all并行化时,code mode 帮助最大。
关于配置选项、返回值、结果结构和指令检查,请访问 createCodeMode() 参考。
跨多个代码工具限定工具范围跨多个代码工具限定工具范围的直接链接
createCodeMode() 会捕获自己的允许列表。多次调用它可为 agent 提供多个代码工具,每个工具限定于不同的工具子集。每个实例只能调用传入其自身 createCodeMode() 调用的工具的 external_* 函数。各子集保持隔离。
为每个工具指定不同的 id,以免它们的 id 冲突,并将每个工具的指令添加到 agent:
const sales = createCodeMode({
id: 'sales_code',
tools: { listRecentOrders, getCustomer },
sandbox,
})
const inventory = createCodeMode({
id: 'inventory_code',
tools: { listProducts, getSupplier },
sandbox,
})
const agent = new Agent({
id: 'ops-assistant',
name: 'ops-assistant',
instructions: ['You are an ops assistant.', sales.instructions, inventory.instructions],
model: 'openai/gpt-5.6-sol',
tools: { sales_code: sales.tool, inventory_code: inventory.tool },
})
为 sales_code 生成的代码无法调用 inventory 工具,反之亦然。将其用于最小权限范围划定,并让每个工具的提示面保持精简。
远程 sandboxes远程 sandboxes的直接链接
默认情况下,code mode 使用的传输会将程序写入宿主文件系统并对其运行 node。这适用于共享宿主的 LocalSandbox,但不适用于在自有 micro-VM 中运行的远程 sandboxes(例如 E2B),因为宿主路径在那里不存在。
远程 sandboxes 需要将程序写入 sandbox 文件系统的传输。对于 E2B,将内置的 E2BCodeModeTransport 作为第二个参数传给 createCodeMode:
import { createCodeMode } from '@mastra/core/tools'
import { E2BSandbox, E2BCodeModeTransport } from '@mastra/e2b'
const { tool, instructions } = createCodeMode(
{ tools, sandbox: new E2BSandbox() },
new E2BCodeModeTransport(),
)
进程内隔离进程内隔离的直接链接
要在不启动进程或运行远程 sandbox 的情况下获得安全边界,请使用 @mastra/isolated-vm 中的 IsolatedVmCodeModeTransport。它在进程内 V8 isolate 中运行程序,因此不需要 sandbox:该 isolate 没有文件系统、网络或进程访问权限,其唯一能力是桥接回宿主工具的 external_* 函数。
import { createCodeMode } from '@mastra/core/tools'
import { IsolatedVmCodeModeTransport } from '@mastra/isolated-vm'
const { tool, instructions } = createCodeMode(
{ tools }, // no sandbox needed
new IsolatedVmCodeModeTransport({ memoryLimitMb: 128 }),
)
isolated-vm 是原生插件,在 Node.js 20 及更高版本上,宿主进程必须使用 --no-node-snapshot 标志启动。关于设置细节,请参阅 IsolatedVmCodeModeTransport 参考。
当宿主无法安装原生插件或设置 Node.js 标志时(这在无服务器平台上很常见),请改用 @mastra/quickjs 中的 QuickJsCodeModeTransport。它使用编译为 WebAssembly 的 QuickJS 运行时提供相同的进程内边界,代价是执行速度较慢:
import { createCodeMode } from '@mastra/core/tools'
import { QuickJsCodeModeTransport } from '@mastra/quickjs'
const { tool, instructions } = createCodeMode(
{ tools }, // no sandbox needed
new QuickJsCodeModeTransport({ memoryLimitMb: 128 }),
)
关于并排比较,请参阅选择传输。