Deep Agents 新功能:为 AI 代理添加解释器 Hunter Lovell 2026-05-21 34.0 KB 44.8K 114 ☆ 收藏 𝕏 文章列表 Deep Agents 推出了嵌入式解释器功能,允许 AI 在循环内编写和执行代码。它介于单次工具调用和完整沙箱之间,提供了受限的运行时环境。通过显式桥接外部能力,它能更安全、可预测地处理中间状态和复杂逻辑,提升代理的上下文管理能力。 Deep Agents代码解释器Agent系统架构运行时安全 86 强烈推荐 ▶ 文章极具时效性,深入探讨了为 AI Agent 引入嵌入式解释器的创新架构,通过丰富的代码示例和清晰的逻辑论证,提供了高价值且可落地的技术见解。 # Give your agents an interpreter **作者**: Hunter Lovell **日期**: 2026-05-20T18:26:40.000Z **来源**: [https://x.com/huntlovell/status/2057166131924988002](https://x.com/huntlovell/status/2057166131924988002) ---  TL;DR We’re adding interpreters to Deep Agents: small embedded runtimes where agents can write and execute code inside the agent loop. They give agents a middle ground between one-at-a-time tool calls and full sandboxes, so agents can express multi-step work, keep intermediate state out of model context, and execute code and actions in a more predictable way. ## What’s an interpreter? An interpreter is a small embedded runtime that an agent can write code against while it is working. Functionally, it feels like giving the agent a Python or Node REPL: it can define variables, inspect values, write helper functions, and reuse state across calls.  Many agents today already execute code by issuing commands to a host or sandbox environment. This is great when the task is environment-level work: running commands, installing dependencies, or operating over a filesystem. Interpreters are aimed at a different layer: the agent writes code that runs inside the agent loop to coordinate delegation, compose tool calls, transform structured data, and decide what information should come back to the model. ``` // agent writes code like this const rows = [ { team: "support", tickets: 18 }, { team: "infra", tickets: 7 }, { team: "sales", tickets: 11 }, ]; const total = rows.reduce((sum, row) => sum + row.tickets, 0); const busiest = rows.sort((a, b) => b.tickets - a.tickets)[0]; `${busiest.team} has the most tickets. ${total} tickets total.`; ``` This gives agents a new place to express behavior that doesn't fit cleanly into a sequence of tool calls. The agent gets a working space for multi-step logic, while the harness still controls what that working space can touch. The interpreter can hold temporary state and return only the part that matters. ## Where interpreters fit When you think of an agent, you usually think of attaching tools. In the simplest form of an agent, the agent uses those tools in a loop: the model calls one tool, inspects the observation, then decides what to do next. That one-step-at-a-time style is straightforward to debug and evaluate, and a lot of workflows do require a way to reason over immediate observations. Sandboxes build on top of that by giving the agent a bash tool that works against an environment to run commands, install dependencies, and work with files. But both ends have downsides: sandboxes can handle local procedure (since it can just write code to do so), but they can be harder to provision and scale; and purely serial tool loops can be awkward when those intermediate steps mostly feed the next step. Some agent work sits between those two extremes, which interpreters slot nicely into. They give the agent code-level composition over scoped capabilities without giving it a whole environment. The model can write a small program to express control flow over existing capabilities, while the harness decides which capabilities are available through the host.  ## More limited by design We call this an interpreter, not just a code runtime, because the interpreter is intentionally limited. By default it does not have the APIs you would expect from a normal programming environment: no filesystem, no network, no shell, no package installation, and no wall-time access. The agent starts with basic control flow and object manipulation: objects, arrays, maps, JSON, and the rest of the small language runtime. Those capabilities are exposed through explicit bridges to the host runtime. If the agent needs to call a tool, read from a scoped filesystem API, fetch a URL, or delegate to a subagent, the harness has to expose that capability deliberately. For instance, this script only works when we explicitly bridge the fetch, read_file and task tools directly to the interpreter: ``` // calls the `fetch` tool to make a network request const response = tools.fetch("https://docs.langchain.com"); // calls the `readFile` tool to fetch files from the agents filesystem const file = tools.readFile("SPEC.md"); // calls the `task` tool to spawn a subagent const subagentOutput = tools.task({ description: "Do you know the muffin man?" }); ``` The host runtime (the same one that runs the harness) contains all the actions an agent can take using the interpreter, and explicitly decides which ones the interpreter code can call. The interpreter is the agent’s programmable side of that boundary. By default, the interpreter starts with language features only, not generic host access like a sandbox gives you. Anything that touches the outside world has to cross an explicit bridge that you specify.  We do this for a few reasons: - Smaller action surface: With bash or a sandbox, the starting point is broad: the agent has something shaped like a computer, and you restrict what it can do from there. With an interpreter, the starting point is narrow: the agent has a language runtime, and capabilities are added back deliberately. That does not replace sandboxing when you require process or VM isolation, but it does mean the agent is not inheriting broad host access by default. - Predictability: A small, fixed runtime makes agent behavior easier to anticipate and evaluate. If the interpreter had broad host access or a rich library surface, the same goal could be achieved through many different strategies, which makes outputs less consistent and harder to test. By keeping the default environment minimal and forcing extra capabilities to cross explicit bridges, you make the agent’s action space narrower, the failure modes clearer, and the results more repeatable. You see the same architectural shape in systems from Figma, Shopify, AWS, and others: constrained code runs on one side, while the host exposes a controlled API boundary on the other. ## What interpreters unlock A few recent systems have converged on similar patterns: give the model a small, scoped runtime where it can write a bit of code to manage control flow and intermediate state. Cloudflare’s Code Mode, Anthropic’s Programmatic Tool Calling (PTC), and RLM-style workflows each point at that idea from different angles. In Deep Agents, an interpreter is how you get that pattern in a model-agnostic way. Here are a few places it’s already been useful: ## Interpreter state as a context surface Agent harnesses already organize context across a few surfaces: - Message history is the context immediately available to the model. It is expensive and attention-constrained: just because a model can accept a million tokens does not mean it will reason over every token equally well. (e.g. context rot) - A filesystem gives the agent somewhere to store durable artifacts, notes, intermediate files, and longer-lived working memory.It is durable and flexible, but it forces the agent to serialize working state into files and then reconstruct it later. Part of the job of the harness is to control the flow of context between the filesystem and the message history. Interpreter state gives the agent another option. Values can stay in the runtime as arrays, objects, maps, counters, queues, and helper functions. The model does not need to see every intermediate value as prompt text, but it can still ask the interpreter to inspect or reuse those values later.  This is similar to why a REPL feels different from running a one-off command. If you define a variable in a REPL, it is still there on the next command you submit. You do not have to turn it into stdout, write it to a file, or reconstruct it before doing the next thing. The same principle applies when an agent calls the interpreter multiple times, since it can just reuse the value from a previous call. That makes interpreters useful for agent-loop state. Message history is for what the model needs to reason over now, the filesystem is for durable artifacts and environment-level work, and interpreter state is for live working values that may be useful later but do not need to become model input yet. ## Programmatic tool calling Anthropic’s Programmatic Tool Calling (PTC) is another version of this pattern: tool calls happen from inside code the agent writes, rather than as a sequence of model-mediated actions. If the model calls a tool, receives the full result, reasons over it, and calls the next tool, every small step becomes another model round trip. If the agent can write code that calls tools directly, it can keep intermediate outputs in the runtime and return only the final result or selected evidence. In Deep Agents, PTC is implemented as middleware rather than as a model-provider behavior. The developer passes an allowlist, allowlisted tools appear under the global tools namespace, and each tool is exposed as an async function the interpreter can call with await. This means that you can enable PTC for any model (including open source ones). ``` 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"); ```  In some of our early testing, this style of tool calling used up to 35% fewer tokens on some tasks. (we evaluated this on a collected set of tasks from the OOLONG trec-coarse dataset)  ## Working over large datasets Take a document-heavy task: an agent needs to classify, extract, or synthesize information from 10,000 documents. With a standard tool-calling agent, the natural shape is a long sequence of model-mediated actions. The model searches, gets results back in context, decides what to inspect next, calls another tool, gets more results back, and repeats. For small tasks, that loop is sufficient. But at scale it starts to break down: - It is hard to verify that the agent actually followed the intended procedure. - Too much intermediate context gets routed back through the model. - It is easy to run into latency, context, or tool-call limits. - The response can degrade because the model is forced to manage too much working state through history. An interpreter-shaped version looks different. The model can write code that keeps document and search state in the runtime, iterates through batches programmatically, scores or filters candidates, and calls subagents only on selected slices. Instead of returning every intermediate result to the model, the interpreter returns a compact evidence set: the documents that matched, the fields that were extracted, the unresolved cases, or the few summaries worth reasoning over. The interpreter is not magically reasoning over all 10,000 documents. It gives the agent a better way to control the search space and decide what should enter model context. ``` const candidates = documents .map((doc) => ({ doc, score: scoreDocument(doc, query) })) .filter(({ score }) => score > 0.75) .sort((a, b) => b.score - a.score) .slice(0, 10); const reports = await Promise.all( candidates.map( ({ doc }) => tools.task({ description: `Extract evidence from ${doc.id} for: ${query}`, subagent_type: "general-purpose", }), ), ); reports.join("\n\n"); ``` ## Recursive Language Models Another related idea is Recursive Language Models (RLMs). RLMs treat long prompts as part of an external REPL environment, then let the model write code to inspect, decompose, and recursively call models over selected snippets. Deep Agents interpreters are not implementing RLMs at the model layer, but there is still a relevant connection at the harness level: code can hold working state outside the model context, select a slice of that state, and pass only that slice into the next model or subagent call. In Deep Agents, tools.task is the bridge for this. Interpreter code can select a slice of work, delegate that slice to a subagent, combine the result with existing runtime state, and return only the synthesized output to the main model. ## How it works in Deep Agents At the harness level, the interpreter is middleware between the agent loop and a small runtime. The middleware: - adds an eval tool to the agent - creates and maintains a QuickJS context - executes the agent’s TypeScript code - captures console.log output when configured - returns the final expression back into model context The eval tool is not “run arbitrary code on the host.” The code runs inside the interpreter context. If it needs to communicate with the outside world, it does so through bridges the host runtime exposes. Programmatic tool calling is one of those host bridges. The developer passes a ptc allowlist, allowlisted tools appear inside the interpreter under the tools namespace (e.g. tools.getWeather(...)), and each tool is exposed as an async function the interpreter can call with await. The host runtime still executes the real tool call. The rough flow looks like this: 1. the model writes code and calls eval 2. QuickJS evaluates the code inside the interpreter context 3. interpreter code optionally calls allowlisted tools 4. the host runtime executes the real tool calls 5. results cross back into the interpreter 6. the final expression crosses back into model context Repeated eval calls in a run can share the same live interpreter context, which is what lets values behave like REPL state. Snapshotting between conversation turns is also available, but it should be treated as a way to preserve serializable working data rather than live handles or host resources. Runtime controls live at this boundary too: - memory limits - per-eval timeouts - maximum programmatic tool calls - maximum result size - console capture - snapshotting between turns  ## How to use it in Deep Agents You can install the interpreter and add the middleware using create_deep_agent: ``` uv add "deepagents[quickjs]" ``` ``` from deepagents import create_deep_agent from langchain_quickjs import CodeInterpreterMiddleware agent = create_deep_agent( model="openai:gpt-5.5", middleware=[CodeInterpreterMiddleware()], ) ``` (and in TypeScript) ``` pnpm install deepagents @langchain/quickjs ``` ``` import { createDeepAgent } from "deepagents"; import { createCodeInterpreterMiddleware } from "@langchain/quickjs "; const agent = createDeepAgent({ model: "openai:gpt-5.5", middleware: [createCodeInterpreterMiddleware()], }); ``` To let interpreter code call agent tools, enable programmatic tool calling with an allowlist. Tools are not automatically exposed to interpreter code; you must choose which tools can cross the host-runtime bridge. ``` agent = create_deep_agent( model="openai:gpt-5.5", middleware=[CodeInterpreterMiddleware(ptc=["task"])], ) ``` ``` const agent = createDeepAgent({ model: "openai:gpt-5.5", middleware: [createCodeInterpreterMiddleware({ ptc: ["task"] })], }); ``` Once PTC is enabled, allowlisted tools appear under the global tools namespace. Each tool is an async function, and the model receives the final interpreter output rather than every intermediate tool result. Deep Agents is available in Python and TypeScript. See the docs for more information on interpreters, as well as the full set of middleware options and runtime controls. Special thanks to @sydneyrunkle, @hwchase17, and @veryboldbagel for their review on this writeup. ## 相关链接 - [Hunter Lovell](https://x.com/huntlovell) - [@huntlovell](https://x.com/huntlovell) - [16K](https://x.com/huntlovell/status/2057166131924988002/analytics) - [Code Mode](https://blog.cloudflare.com/code-mode/) - [Programmatic Tool Calling (PTC)](https://platform.claude.com/docs/en/agents-and-tools/tool-use/programmatic-tool-calling) - [RLM-style workflows](https://alexzhang13.github.io/blog/2025/rlm/) - [context rot](https://www.trychroma.com/research/context-rot) - [memory.It](https://memory.it/) - [Programmatic Tool Calling (PTC)](https://platform.claude.com/docs/en/agents-and-tools/tool-use/programmatic-tool-calling) - [OOLONG](https://huggingface.co/datasets/oolongbench/oolong-synth/viewer/default/validation) - [Recursive Language Models (RLMs)](https://alexzhang13.github.io/blog/2025/rlm/) - [Python](https://github.com/langchain-ai/deepagents) - [TypeScript](https://github.com/langchain-ai/deepagentsjs) - [interpreters](https://docs.langchain.com/oss/python/deepagents/interpreters) - [@sydneyrunkle](https://x.com/@sydneyrunkle) - [@hwchase17](https://x.com/@hwchase17) - [@veryboldbagel](https://x.com/@veryboldbagel) - [Upgrade to Premium](https://x.com/i/premium_sign_up) - [2:26 AM · May 21, 2026](https://x.com/huntlovell/status/2057166131924988002) - [16.2K Views](https://x.com/huntlovell/status/2057166131924988002/analytics) --- *导出时间: 2026/5/21 10:27:10* --- ## 中文翻译 # 给你的智能体一个解释器 **作者**: Hunter Lovell **日期**: 2026-05-20T18:26:40.000Z **来源**: [https://x.com/huntlovell/status/2057166131924988002](https://x.com/huntlovell/status/2057166131924988002) ---  **TL;DR** 我们正在为 Deep Agents 添加解释器:一种小型嵌入式运行时,智能体可以在智能体循环中编写并执行代码。它们为智能体提供了一种介于逐次工具调用和完整沙箱之间的中间方案,使智能体能够表达多步骤的工作、将中间状态保存在模型上下文之外,并以更可预测的方式执行代码和操作。 ## 什么是解释器? 解释器是一种小型嵌入式运行时,智能体在工作过程中可以针对它编写代码。从功能上看,这就像是给智能体提供了一个 Python 或 Node 的 REPL:它可以定义变量、检查值、编写辅助函数,并在多次调用之间复用状态。  如今许多智能体已经通过向宿主环境或沙箱环境发出命令来执行代码。当任务是环境层面的工作时,这种方式非常好:运行命令、安装依赖或操作文件系统。而解释器面向的是另一个层面:智能体编写在智能体循环内运行的代码,用来协调委派、组合工具调用、转换结构化数据,并决定哪些信息应该返回给模型。 ``` // agent writes code like this const rows = [ { team: "support", tickets: 18 }, { team: "infra", tickets: 7 }, { team: "sales", tickets: 11 }, ]; const total = rows.reduce((sum, row) => sum + row.tickets, 0); const busiest = rows.sort((a, b) => b.tickets - a.tickets)[0]; `${busiest.team} has the most tickets. ${total} tickets total.`; ``` 这为智能体提供了一个新的空间来表达那些无法干净地映射为一系列工具调用的行为。智能体获得了一个用于多步骤逻辑的工作空间,而宿主框架仍然控制着这个工作空间能够触及的范围。解释器可以保存临时状态,并只返回重要的部分。 ## 解释器适用的场景 当你想到智能体时,通常想到的是挂载工具。 在最简单的智能体形式中,智能体在循环中使用这些工具:模型调用一个工具,检查观察结果,然后决定下一步做什么。这种一步一步的方式易于调试和评估,而且很多工作流确实需要对即时观察结果进行推理。 沙箱则在此基础上更进一步,为智能体提供一个针对环境工作的 bash 工具,用于运行命令、安装依赖和处理文件。 但这两个极端都有缺点:沙箱可以处理本地过程(因为它可以直接编写代码来实现),但配置和扩展可能更困难;而当这些中间步骤主要是为下一步提供输入时,纯串行的工具循环会显得笨拙。 有些智能体工作恰好处于这两个极端之间,而解释器正好可以很好地填补这个位置。它们让智能体能够对受限的能力进行代码层面的组合,而不必给它一个完整的运行环境。模型可以编写一个小程序来表达对现有能力的控制流,同时由宿主框架决定哪些能力可以通过宿主获得。  ## 有意设计的限制 我们称之为解释器,而不仅仅是代码运行时,因为解释器是有意受限的。默认情况下,它不具备你通常在正常编程环境中期待的 API:没有文件系统、没有网络、没有 shell、没有包安装,也没有真实时间访问。智能体从基础的控制流和对象操作开始:对象、数组、映射、JSON 以及其他小型语言运行时功能。 这些能力是通过显式的桥接暴露给宿主运行时的。如果智能体需要调用工具、从受限的文件系统 API 读取内容、获取 URL 或委派给子智能体,宿主框架必须有意识地暴露该能力。例如,下面这个脚本只有在我们将 fetch、read_file 和 task 工具显式桥接到解释器时才能工作: ``` // calls the `fetch` tool to make a network request const response = tools.fetch("https://docs.langchain.com"); // calls the `readFile` tool to fetch files from the agents filesystem const file = tools.readFile("SPEC.md"); // calls the `task` tool to spawn a subagent const subagentOutput = tools.task({ description: "Do you know the muffin man?" }); ``` 宿主运行时(与运行宿主框架的是同一个运行时)包含智能体使用解释器可以执行的所有操作,并显式决定解释器代码可以调用哪些操作。解释器就是智能体在这一边界上的可编程一侧。 默认情况下,解释器只有语言功能,而不是像沙箱那样提供通用的宿主访问。任何触及外部世界的操作都必须经过你指定的显式桥接。  我们这样做有以下几个原因: - **更小的操作面**:使用 bash 或沙箱时,起点是宽泛的:智能体拥有一个类似于计算机的东西,然后你从那里开始限制它能做什么。而使用解释器时,起点是狭窄的:智能体拥有一个语言运行时,能力是有意添加回去的。当你需要进程或虚拟机级别的隔离时,这并不能取代沙箱,但它确实意味着智能体默认不会继承宽泛的宿主访问权限。 - **可预测性**:一个小而固定的运行时让智能体的行为更容易预测和评估。如果解释器拥有宽泛的宿主访问权限或丰富的库接口,同一个目标可以通过许多不同的策略来实现,这会导致输出的一致性更差、更难测试。通过保持默认环境的最小化并强制额外能力经过显式桥接,你可以让智能体的操作空间更窄、故障模式更清晰、结果更可复现。 你在 Figma、Shopify、AWS 等公司的系统中也能看到同样的架构形态:一侧运行受限的代码,另一侧由宿主暴露一个受控的 API 边界。 ## 解释器能带来什么 最近的一些系统已经收敛到相似的模式:给模型一个小型、范围受限的运行时,让它可以编写少量代码来管理控制流和中间状态。Cloudflare 的 Code Mode、Anthropic 的 Programmatic Tool Calling(PTC),以及 RLM 风格的工作流,都在从不同角度指向同一个想法。在 Deep Agents 中,解释器就是以一种与模型无关的方式实现这一模式的途径。以下是它已经发挥作用的几个场景: ## 解释器状态作为上下文载体 Agent 框架已经在多个层面上组织上下文: - 消息历史是模型立即可用的上下文。它昂贵且受注意力限制:模型能接受一百万个 token,并不意味着它对每个 token 的推理效果都一样好。(例如 context rot 现象) - 文件系统为 agent 提供了一个存放持久化产物、笔记、中间文件和更长生命周期工作记忆的地方。它持久且灵活,但迫使 agent 将工作状态序列化到文件中,之后再重新构建。 框架的一部分职责就是控制文件系统与消息历史之间的上下文流动。 解释器状态为 agent 提供了另一种选择。值可以以数组、对象、映射、计数器、队列和辅助函数的形式留在运行时中。模型不需要把每个中间值都作为提示文本看到,但它仍然可以让解释器在稍后检查或复用这些值。  这类似于 REPL 与运行一次性命令的区别。如果你在 REPL 中定义了一个变量,在你提交下一条命令时它仍然存在。你不必把它转成 stdout、写入文件,或在执行下一步之前重新构建它。当 agent 多次调用解释器时,同样的原理也适用,因为它可以直接复用上一次调用产生的值。 这使得解释器非常适合管理 agent 循环中的状态。消息历史用于模型当前需要推理的内容,文件系统用于持久化产物和环境层面的工作,而解释器状态用于以后可能有用但暂时不需要成为模型输入的实时工作值。 ## 程序化工具调用 Anthropic 的 Programmatic Tool Calling(PTC)是这一模式的另一种形式:工具调用发生在 agent 编写的代码内部,而不是作为一串由模型介导的动作。 如果模型调用一个工具、接收完整结果、对其进行推理,再调用下一个工具,那么每一个小步骤都会变成一次额外的模型往返。如果 agent 能编写直接调用工具的代码,它就可以把中间输出保留在运行时中,只返回最终结果或选定的证据。 在 Deep Agents 中,PTC 是作为中间件实现的,而不是模型提供商的行为。开发者传入一个允许列表,被允许的工具会出现在全局工具命名空间下,每个工具都暴露为解释器可以用 `await` 调用的异步函数。这意味着你可以为任何模型(包括开源模型)启用 PTC。 ``` 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"); ```  在我们的一些早期测试中,这种工具调用方式在某些任务上最多节省了 35% 的 token。(我们在从 OOLONG trec-coarse 数据集中收集的一组任务上对此进行了评估)  ## 处理大型数据集 设想一个文档密集的任务:agent 需要对 10,000 份文档进行分类、提取或综合信息。 对于标准的工具调用 agent,自然的形态是一长串由模型介导的动作。模型搜索、在上下文中接收结果、决定接下来检查什么、调用另一个工具、接收更多结果,如此往复。对于小任务,这个循环足够了。但在规模化场景下,它开始出现问题: - 很难验证 agent 是否真的遵循了预期的流程。 - 太多中间上下文被回传给模型。 - 很容易触及延迟、上下文或工具调用次数的限制。 - 响应质量可能下降,因为模型被迫通过历史记录管理过多的工作状态。 而解释器形态的版本则不同。模型可以编写代码,把文档和搜索状态保留在运行时中,以程序化方式遍历批次、对候选结果评分或过滤,并只对选定的切片调用子 agent。解释器不是把每个中间结果都返回给模型,而是返回一个紧凑的证据集合:匹配的文档、提取出的字段、未解决的案例,或少数值得推理的摘要。 解释器并不是在神奇地对全部 10,000 份文档进行推理。它为 agent 提供了一种更好的方式来控制搜索空间,并决定什么内容应该进入模型上下文。 ``` const candidates = documents .map((doc) => ({ doc, score: scoreDocument(doc, query) })) .filter(({ score }) => score > 0.75) .sort((a, b) => b.score - a.score) .slice(0, 10); const reports = await Promise.all( candidates.map( ({ doc }) => tools.task({ description: `Extract evidence from ${doc.id} for: ${query}`, subagent_type: "general-purpose", }), ), ); reports.join("\n\n"); ``` ## 递归语言模型(Recursive Language Models) 另一个相关的理念是递归语言模型(Recursive Language Models,RLMs)。RLMs 将长提示词视为外部 REPL 环境的一部分,然后让模型编写代码来检查、分解所选片段,并递归调用模型。 Deep Agents 解释器并没有在模型层实现 RLMs,但在 harness 层面仍然存在相关联系:代码可以将工作状态保存在模型上下文之外,选取该状态的一个切片,并只将那个切片传递给下一次模型或子代理调用。 在 Deep Agents 中,tools.task 就是实现这一点的桥梁。解释器代码可以选取一段工作切片,将其委托给子代理,将结果与现有运行时状态合并,并且只将综合后的输出返回给主模型。 ## Deep Agents 中的工作原理 在 harness 层面,解释器是代理循环与一个小型运行时之间的中间件。该中间件: - 为代理添加 eval 工具 - 创建并维护 QuickJS 上下文 - 执行代理的 TypeScript 代码 - 在配置后捕获 console.log 输出 - 将最终表达式返回到模型上下文中 eval 工具并不是“在宿主机上运行任意代码”。代码在解释器上下文中运行。如果它需要与外部世界通信,则通过宿主运行时暴露的桥梁来实现。 程序化工具调用(Programmatic tool calling)就是其中一种宿主桥梁。开发者传入一个 ptc 允许列表,被允许的工具就会以 tools 命名空间(如 tools.getWeather(...))的形式出现在解释器内,每个工具都以异步函数的形式暴露,解释器可以用 await 来调用它。真正的工具调用仍然由宿主运行时执行。 大致流程如下: 1. 模型编写代码并调用 eval 2. QuickJS 在解释器上下文中执行代码 3. 解释器代码可选择调用允许列表中的工具 4. 宿主运行时执行真正的工具调用 5. 结果传回解释器 6. 最终表达式传回模型上下文 一次运行中反复调用 eval 可以共享同一个活跃的解释器上下文,这正是让值表现得像 REPL 状态的原因。对话轮次之间也可以进行快照,但应将其视为保存可序列化工作数据的方式,而不是保存活跃句柄或宿主资源。 运行时控制也位于这一边界上: - 内存限制 - 每次 eval 的超时时间 - 程序化工具调用的最大次数 - 最大结果大小 - 控制台捕获 - 轮次间快照  ## 如何在 Deep Agents 中使用它 你可以安装解释器并使用 create_deep_agent 添加中间件: ``` uv add "deepagents[quickjs]" ``` ``` from deepagents import create_deep_agent from langchain_quickjs import CodeInterpreterMiddleware agent = create_deep_agent( model="openai:gpt-5.5", middleware=[CodeInterpreterMiddleware()], ) ``` (TypeScript 版本) ``` pnpm install deepagents @langchain/quickjs ``` ``` import { createDeepAgent } from "deepagents"; import { createCodeInterpreterMiddleware } from "@langchain/quickjs "; const agent = createDeepAgent({ model: "openai:gpt-5.5", middleware: [createCodeInterpreterMiddleware()], }); ``` 要让解释器代码调用代理工具,需通过允许列表启用程序化工具调用。工具不会自动暴露给解释器代码;你必须选择哪些工具可以通过宿主运行时桥梁。 ``` agent = create_deep_agent( model="openai:gpt-5.5", middleware=[CodeInterpreterMiddleware(ptc=["task"])], ) ``` ``` const agent = createDeepAgent({ model: "openai:gpt-5.5", middleware: [createCodeInterpreterMiddleware({ ptc: ["task"] })], }); ``` 启用 PTC 后,允许列表中的工具会出现在全局 tools 命名空间下。每个工具都是一个异步函数,模型接收到的是解释器的最终输出,而不是每个中间工具结果。 Deep Agents 提供 Python 和 TypeScript 版本。有关解释器以及完整的中间件选项和运行时控制的更多信息,请参阅文档。 特别感谢 @sydneyrunkle、@hwchase17 和 @veryboldbagel 对本文的审阅。 ## 相关链接 - [Hunter Lovell](https://x.com/huntlovell) - [@huntlovell](https://x.com/huntlovell) - [16K](https://x.com/huntlovell/status/2057166131924988002/analytics) - [Code Mode](https://blog.cloudflare.com/code-mode/) - [程序化工具调用(PTC)](https://platform.claude.com/docs/en/agents-and-tools/tool-use/programmatic-tool-calling) - [RLM 风格的工作流](https://alexzhang13.github.io/blog/2025/rlm/) - [上下文腐化](https://www.trychroma.com/research/context-rot) - [memory.It](https://memory.it/) - [程序化工具调用(PTC)](https://platform.claude.com/docs/en/agents-and-tools/tool-use/programmatic-tool-calling) - [OOLONG](https://huggingface.co/datasets/oolongbench/oolong-synth/viewer/default/validation) - [递归语言模型(RLMs)](https://alexzhang13.github.io/blog/2025/rlm/) - [Python](https://github.com/langchain-ai/deepagents) - [TypeScript](https://github.com/langchain-ai/deepagentsjs) - [解释器](https://docs.langchain.com/oss/python/deepagents/interpreters) - [@sydneyrunkle](https://x.com/@sydneyrunkle) - [@hwchase17](https://x.com/@hwchase17) - [@veryboldbagel](https://x.com/@veryboldbagel) - [升级到 Premium](https://x.com/i/premium_sign_up) - [2026年5月21日 凌晨2:26](https://x.com/huntlovell/status/2057166131924988002) - [16.2K 次浏览](https://x.com/huntlovell/status/2057166131924988002/analytics) --- *导出时间: 2026/5/21 10:27:10*
P Production Deep Agents 运行时指南:弹性执行、内存与多租户 本文探讨了将长运行周期的 Deep Agents 部署到生产环境所需的运行时基础设施。文章指出,除了 Agent 的 Harness(提示词、工具)外,更关键的是底层的 Runtime,它提供了弹性执行、持久化内存、多租户隔离、人在回路(HITL)和可观测性。文章详细介绍了如何通过检查点机制实现故障恢复与状态恢复,区分了短期与长期内存的存储策略,并阐述了在 Agent Server 中实现数据隔离与鉴权的多租户方案。 技术 › Harness Engineering LangChain 2026-05-06 LangChainAgentRuntime多租户系统架构持久化HITL生产环境Deep Agents
A AI 智能体的持续学习:模型、控制层与上下文 文章探讨了 AI 智能体的持续学习机制,将其分为三个层次:模型权重的更新、Harness 控制层的优化以及 Context 上下文层的记忆与配置。作者指出,虽然大多数讨论集中在模型层的微调(如 SFT)及其带来的灾难性遗忘问题上,但工程实践中 Harness 代码和 Context 技能(如 SOUL.md)的迭代往往更为灵活高效。文章最后以 LangSmith 和 Deep Agents 为例,强调了 Trace(追踪日志)在驱动所有层级进化中的核心作用。 技术 › Agent Harrison Chase 2026-04-05 Agent持续学习Harness EngineeringLangSmith模型微调系统架构Deep AgentsMemory
A Anthropic Claude Code 源码剖析:为什么它比别人好用 基于 Anthropic 泄露的 Claude Code 源码,深入剖析其技术架构。文章指出 Claude Code 实为以 LLM 为内核的“操作系统”,拥有极致的提示词工程、42 个独立工具的安全管控、AI 记忆检索系统、子蜂群 Agent 机制以及三层上下文压缩技术。其 51 万行代码中有 95% 专注于安全、权限和上下文管理等工程脚手架,而非单纯的模型调用。 技术 › Claude Code Yuker 2026-04-01 源码分析Agent提示词工程系统架构安全Anthropic上下文管理AI编程
用 用 DeepSeek Harness 手搓一个自己的 Agent 作者基于 DeepSeek Harness 从零搭建一个客服 Agent 的实战教程。文章梳理了客服 Agent 的四大核心能力:快速检索、记忆、人机协同与工具执行;并从交互模式接入、System Prompt 精简、Session 管理与持久化、工具与 Skill 的取舍、安全边界(接口鉴权与 Sandbox 只读)等方面逐步实现。作者强调通过收缩工具数量和精简 System Prompt 降低推理与 Token 开销,用 Skill 约束行为方式、用受控 Tool 约束能力边界,最后分享了利用 DSH 分步完成开发的流程与实用技巧。 技术 › Agent c cecilia 2026-10-19 DeepSeekAgent客服AgentSystem PromptSession管理Tool与Skill安全实战教程Harness Engineering
D DeepSeek 弹性计算(DSec):面向大规模智能体训练的多后端弹性沙箱基础设施 本文解读 DeepSeek-AI 与清华大学合著的 DSec 论文,这是支撑 DeepSeek V3.2 到 V4.1 智能体 RL 训练的生产级沙箱基础设施。文章分析了智能体训练负载的七大特性(突发创建、CPU 稀疏、有状态长寿命、高度异构等),介绍了其无状态控制面、分层代理数据面架构,以及可组合环境分层、高密度内存管理、QoS 感知 CPU 调度、按需镜像加载四大核心机制。还深入阐述了 agent loop 与训练解耦、暂停恢复协同、防 reward hacking 的安全对抗实践。作者认为这标志着智能体能力竞赛正在演变为基础设施竞赛。 技术 › Agent meng shao 2026-09-28 DeepSeek沙箱智能体训练强化学习基础设施系统架构容器microVM论文解读安全
T Thinking in Systems, Shipping in Loops 文章引用 DHH 的观点指出,手写代码对绝大多数程序员已不再经济,软件工程正演变为系统架构设计。通过 Artemis 和 SpaceXAI Grok 团队的案例,说明工程师如今通过设计验证循环(verification loops)让 AI 大规模正确地编写代码——如 Lauren Tan 每月发布 2000 个 PR。文章借鉴 Donella Meadows 的系统理论,提出优秀系统设计的三大特性:韧性(AI 通过测试、审查代理和生产可观测性自我校验)、自组织(循环学习将失败类型转化为新技能)和层级(将技能、工具与沙箱组合成可复用组件)。工程师的新职业是'驾驭智能'。 技术 › Agent Tomasz Tunguz 2026-09-25 AI编程Agent系统架构软件工程验证循环LLM敏捷开发自动化
H How we built LangChain's Paid Media Agent LangChain 分享了其付费媒体 Agent 的构建经验。该 Agent 运行在 Slack 中,每周整合广告平台数据与业务管道数据,自动生成分析报告并提出优化建议。核心设计理念是将 Agent 视为知识工作者:为其提供配备沙箱、软件、业务文档的工作空间;用代码处理计算和规则以保证一致性,用模型专注判断与建议;围绕完整工作流设计,包括提案、人工审批与验证环节。借助 Deep Agents 作为 Agent harness 和 LangSmith 沙箱,六个月内付费媒体贡献了 20% 的营销管道,CPL 下降 30%,报告工作流成本降低 40 倍、速度提升 13 倍。项目已开源。 技术 › Agent LangChain 2026-09-15 LangChainAgentDeep AgentsLangSmith付费媒体营销自动化沙箱上下文工程开源GTM
L LLM-as-Judge Architectures: Putting Evals Into Your Agent Runtime 文章探讨将 LLM-as-Judge 从离线评估工具迁移到 Agent 运行时架构中的趋势。传统确定性软件可通过类型检查、断言等方式验证结果,而 AI 应用输出往往需要判断性评估,LLM judge 能让应用自我完成这些判断。作者介绍了几种常见模式:使用另一个模型(包括专用小型评估模型以降低成本)、将大而模糊的判断拆解为多个小判断并用 DAG 结构组合、用成对比较代替打分以规避位置偏差、在 Agent 工作过程的关键节点(如检索、方案选择)设置检查点而非仅评估最终答案,以及使用多评委投票、辩论等机制提升可靠性。 技术 › LLM Josh Rosen 2026-09-09 LLM-as-JudgeAgent评估架构运行时EvalsPairwise比较多评委
L Latency Patterns for Faster Applications 本文探讨了AI与非AI应用中的延迟优化模式。作者指出延迟是指从用户操作到首个有用结果出现的时间,用户感知的是完整关键路径而非单个组件。文章将延迟优化归纳为四大类共19种模式:一是本地化,包括同置、复制、分区和缓存;二是减少工作量,包括算法优化、选择性数据处理、初始化复用、请求合并和运行时调优;三是并发执行,包括避免同步、独立并发、渐进式响应、并发预算和对冲请求;四是预测性优化,提前处理可预测的工作。这些模式既适用于传统应用,也适用于涉及LLM调用、MCP服务器和Agent协调的现代AI应用路径。 技术 › 后端 Bilgin Ibryam 2026-08-30 延迟优化性能工程系统架构LLM并发缓存Agent分布式系统后端开发
D DeepSeek Harness 从 0 到 1 全攻略|一文读懂 文章系统介绍了 DeepSeek Harness,强调它不是单纯的模型聊天界面,而是把模型、工具、会话、沙箱、工作流、调度和 UI 都插件化的 Agent 运行框架。内容涵盖安装启动、Web UI 与远程访问的安全风险、4 种 Agent 模式的权限取舍、Trajectory 执行轨迹带来的可调试性、多模型接入降低供应商锁定、'一切皆插件'的架构理念、会话分支用于并行验证假设,以及 Dynamic Workflow 和 Agent Teams 实现多 Agent 协作的任务拆分与汇总。作者认为其价值在于让 Agent 成为可配置、可观察、可复用的执行系统,但仍处 developer preview 阶段,需谨慎对待权限与数据安全。 技术 › Harness Engineering Martin 2026-08-29 DeepSeekAgentHarness插件化多Agent执行轨迹工作流Web UI安全多模型
说 说一句收到,我花了20341个token——Agent成本的过路费与省钱三刀 作者发现验证Agent成员是否存活时,一句简单的「收到」竟消耗两万个token,原因是每次对话都要重新装配成员的身份、记忆、技能清单等。文章剖析了Agent成本的三层「过路费」结构:身份装配、上下文搬运和格式开销,指出七成token花在空驶而非思考上。作者提出三刀止损法:利用前缀缓存把不变内容前置、健康探针直连绕过人格装配、协作转手只传摘要。实施后成本降了一半以上,但同时也暴露出便宜诱发滥用、缓存惩罚变动等新问题,并引出本地化部署的机会成本与主权优势思考。 技术 › Agent AI最严厉的父亲 2026-08-25 AgentToken成本缓存提示词工程成本优化LLM系统架构上下文管理本地部署降本增效
A AI 股票分析系统 — 技术方案仅供交流 本文介绍了基于 ChatGPT Codex 搭建的 AI 股票分析系统的技术方案,该系统定位为 AI 投资研究与信息处理系统,非自动交易或涨跌预测。文章详细阐述了系统的整体架构(6层)、技术选型(数据源、AI模型、调度、推送)、核心数据流、评分体系、配置说明、运行部署、安全边界及关键风险。作者强调工程上先单模型跑通更稳,评分不等于涨跌概率,并提供了与主线项目(Codex 式 Agent 桌面应用)的关联建议。 技术 › LLM Kelvin 2026-08-20 AI股票分析系统架构技术选型数据源DeepSeek自动化评分体系安全部署