Interpreters 为 agents 提供 programmable workspace,使其可以探索 data、协调 tool calls,并将 intermediate work 保持在 model context 之外。Agent 编写 code 来表达 intent,然后 in-memory runtime 执行该 code 并返回 relevant results。
如果说 sandboxes 是 code-first 地作用于 environment 的方式(例如 running commands、installing dependencies 和 editing files),那么 interpreters 就是 code-first 地作用于 agent loop 内部的方式:composing tools、preserving state,并决定哪些 information 应返回给 model。
Interpreters 处于 beta。APIs 和 lifecycle behavior 可能会在 releases 之间变化。
When to use an interpreter
大多数 agent work 会在 model reasoning 和 tool execution 之间交替。对于简单 actions 这很有效,但当 agent 需要 compose many steps、reason over structured data 或 manage intermediate state 时,这会变得笨拙。
Interpreter 为 agent 提供处理这些 work 的 runtime。Agent 不必让 model 一次选择一个下一步 tool call、等待 result,再决定下一个 call;它可以编写一个 small program,用来运行 control flow、调用 allowlisted tools、存储 variables,并向 model 返回 compact result。
当 agent 需要执行以下操作时,请使用 interpreters:
- 使用 code compose multiple tool calls,包括 loops、branching、retries 和 concurrency。
- 通过 code 协调 subagents:将 work 拆成 focused calls、存储其 results,并将这些 results 拼接成 final synthesis。
- 将 intermediate values 保留在 runtime state 中,而不是把每个 temporary result 都送回 model context。
- 确定性地 transform structured data,例如 sorting、grouping、parsing、validating、scoring 或 aggregating。
- 探索 large variable space,并只向 model 返回 selected evidence、summaries 或 outputs。
它通过在 QuickJS 中运行 code 实现,QuickJS 是为 embedded execution 设计的 lightweight JavaScript runtime。默认情况下,该 runtime 为 agent 提供一个 evaluate code 的位置,但不会暴露 host filesystem、network、shell、package 或 clock APIs。
QuickJS 是 interpreter code 的 execution boundary。显式 bridges,例如 programmatic tool calling,会决定 code 可以访问哪些 capabilities。
Choose the right execution path
| Need | Use |
|---|
| 一两个 simple external calls | Normal tool calling |
| 需要 loop、branch、retry 或 aggregate results 的 small program | Interpreter |
| 许多 selected tool calls 需要从 code 运行 | 带 programmatic tool calling 的 Interpreter |
| 跨 threads 使用的 reusable helpers | 带 interpreter skills 的 Interpreter |
| Shell commands、package installs、tests 或完整 OS filesystem access | Sandboxes |
Add an interpreter to an agent
安装 QuickJS middleware package,然后在创建 agent 时添加 middleware。
npm install deepagents @langchain/quickjs
import { createDeepAgent } from "deepagents";
import { createCodeInterpreterMiddleware } from "@langchain/quickjs";
const agent = createDeepAgent({
model: "openai:gpt-5.4",
middleware: [createCodeInterpreterMiddleware()],
});
Run code in the interpreter
Middleware 会向 agent 添加 eval tool。该 tool 在 persistent context 中运行 TypeScript、捕获 console.log,并返回最后一个 expression 的 result。
Agent 可以编写如下 code:
const rows = [
{ team: "alpha", score: 8 },
{ team: "beta", score: 13 },
{ team: "alpha", score: 21 },
];
const totals = rows.reduce((acc, row) => {
acc[row.team] = (acc[row.team] ?? 0) + row.score;
console.log(`${row.team} score: ${acc[row.team]}`)
return acc;
}, {});
totals;
Programmatic tool calling(PTC)会在 interpreter 内的 global tools namespace 下暴露 selected agent tools。Agent 不必让 model 发起一个 tool call、等待 result,再决定下一个 call;它可以编写 code,在 loops、branches、retries 或 parallel batches 中调用 tools。
当 intermediate tool results 只是下一步的 inputs 时,这很有用。Interpreter 可以先 process、filter 或 aggregate 这些 results,再将任何内容返回 model context,这能让 multi-tool/multi-step workflows 更节省 tokens。
PTC 在 Deep Agents 中是 model-agnostic 的。它由 middleware 实现,而不是 provider-specific code-execution 或 tool-calling API。
工作原理
- 你通过
ptc allowlist 选择 interpreter 可以调用哪些 tools。
- Middleware 将这些 tools 作为 async JavaScript functions 暴露在
tools 下。
- Agent 编写 interpreter code,并使用
await 调用这些 functions。
- Interpreter 运行 tool bridge、接收 tool result,并继续执行 code。
- Model 接收 final interpreter output,而不是每个 intermediate value。
每个 allowlisted tool 都会成为 async function。Tool names 会转换为 camel case,但 input object 仍遵循该 tool 的 schema。例如,名为 web_search 的 tool 会变成 tools.webSearch(...):
const result: string = await tools.webSearch({
query: "deepagents interpreters",
});
Useful patterns
| Pattern | What the interpreter can do |
|---|
| Batch processing | 循环处理许多 inputs,并为每个 input 调用 tool。 |
| Parallel work | 对 independent calls 使用 Promise.all。 |
| Conditional logic | 根据 earlier results 选择 next tool call。 |
| Early termination | 在满足 success condition 后停止调用 tools。 |
| Data filtering | 只向 model 返回 relevant rows、snippets、errors 或 summaries。 |
| Recursive orchestration | 反复调用 task,然后在 code 中合并 subagent results。 |
Enable PTC
使用 explicit allowlist 启用 PTC:
import { createDeepAgent } from "deepagents";
import { createCodeInterpreterMiddleware } from "@langchain/quickjs";
const agent = createDeepAgent({
model: "openai:gpt-5.4",
middleware: [createCodeInterpreterMiddleware({ ptc: ["task"] })],
});
启用 PTC 后,agent 可以从 interpreter code 调用 allowlisted tool。此 example 会并行启动多个 subagents,并在返回 model 前合并它们的 final reports:
const topics = ["retrieval", "memory", "evaluation"];
const reports = await Promise.all(
topics.map((topic) =>
tools.task({
description: `Research ${topic} in Deep Agents and return three concise findings.`,
subagent_type: "general-purpose",
}),
),
);
reports.join("\n\n");
因为这是 code,agent 也可以在本地处理 failures:
try {
const report = await tools.task({
description: "Check the migration notes and return breaking changes.",
subagent_type: "general-purpose",
});
console.log(report);
} catch (error) {
console.log(`Subagent failed: ${error.message}`);
}
PTC calls 目前通过 interpreter bridge 执行,不经过 normal tool calling path。因此,interrupt_on approval workflows 不会按每个 PTC-invoked tool call 强制执行。
Recursive language models
Recursive language models 使用 interpreter 作为 decomposition workspace。Model 将 large input 或 working set 保存在 runtime variables 中,编写 code 来 inspect 和 split 它,对较小 pieces 调用 subagents 或其他 model tools,然后在 code 中拼接返回的 results。
这会把 variable space 与 agent 的 context 分离。Variable space 是存储在 interpreter 中的信息,而 agent 的 context 是 model 在下一次 model call 中实际处理的内容。Model 可以决定哪些 snippets 成为 subagent tasks、哪些 results 需要再处理一轮,以及 final synthesis 应该向 main conversation 返回什么。
该 pattern 的背景请参阅 Recursive Language Models paper。
在 Deep Agents 中,recursive call 通常是通过 programmatic tool calling 暴露的 task tool。Interpreter 可以在许多 slices 上调用 subagents、合并 answers,并返回单个 synthesized result:
const candidates = notes
.filter((note) => note.includes("migration"))
.slice(0, 5);
const riskReports = await Promise.all(
candidates.map((note) =>
tools.task({
description: `Analyze this migration note for release risk. Return risks, affected users, and recommended follow-up:\n\n${note}`,
subagent_type: "general-purpose",
}),
),
);
const releaseSummary = riskReports
.map((report, index) => `## Candidate ${index + 1}\n${report}`)
.join("\n\n");
releaseSummary;
Interpreter skills
Interpreter skills 是向 interpreter 暴露 code modules 的 skills。配置 interpreter middleware 后,agent 可以从 code import 这些 modules,并将其用于 deterministic helper logic。
当 agent 需要 structured data workflows 的 reusable helpers 时,Interpreter skills 很有用,例如 sorting、grouping、scoring、parsing、validating 或 aggregating data。Setup details 请参阅 Interpreter skills。
Security and limits
Interpreters 使用 QuickJS 以 strict default isolation 运行 untrusted JavaScript。请将其视为 scoped interpreter runtime,而不是完整 production sandbox backend。
你通过 PTC 暴露的每个 tool 都是 interpreter code 可以使用的 outside capability。请将 PTC allowlist 视为 permission boundary:只暴露 agent 所需 tools,并避免桥接可访问 sensitive systems、spend money、mutate data 或调用 unrestricted networks 的 broad tools,除非这正是预期 behavior。
| Capability | Available by default | How to expose it |
|---|
| JavaScript execution | Yes | 添加 interpreter middleware |
Top-level await | Yes | 在 interpreter code 中使用 promises |
console.log capture | Yes | 使用 captureConsole: false 禁用 |
| Agent tools | No | 添加 PTC allowlist |
| Interpreter skill modules | No | 添加 module entry,并配置 skills_backend 或 skillsBackend |
| Filesystem access | No | 通过 PTC allowlist 添加 built-in filesystem tools |
| Network access | No | 通过 PTC 暴露 specific network tool |
| Wall-clock or datetime access | No | 如有需要,暴露 explicit time tool |
| Shell commands、package installs、tests、OS-level execution | No | 使用 sandbox backend |
Middleware options
createCodeInterpreterMiddleware 接受以下 options:
| Option | Default | Purpose |
|---|
ptc | omitted | PTC allowlist:tool names 或 StructuredToolInterface instances array。 |
memoryLimitBytes | 64 * 1024 * 1024 (64 MB) | QuickJS memory limit,以 bytes 为单位。 |
maxStackSizeBytes | 320 * 1024 | QuickJS stack size limit,以 bytes 为单位。 |
executionTimeoutMs | 5000 | Per-eval timeout,以 milliseconds 为单位。Negative values 会禁用 timeout。 |
systemPrompt | null | 覆盖 built-in interpreter system prompt。 |
skillsBackend | omitted | 用于 resolve interpreter skill modules 的 Backend。 |
maxPtcCalls | 256 | 每次 eval 的最大 tools.* calls 数。仅在 trusted environments 中使用 null。 |
maxResultChars | 4000 | 从 console output、result 和 error strings 保留的最大 characters。 |
toolName | "eval" | 暴露给 model 的 interpreter tool name。 |
captureConsole | true | 是否捕获 console.log、console.warn 和 console.error output。 |