{"schema_version":1,"id":"article:anthropic-managed-agents","kind":"article","slug":"anthropic-managed-agents","title":"从 Claude Code 技术架构，看 Anthropic 的 Managed Agents 设计哲学","author":"晨旭","url":"https://chenxu.xin/writing/anthropic-managed-agents","date":"2026-04-13","updated":"2026-04-13","description":"把 Claude Code 的本地单体架构和 Anthropic 的 Managed Agents 放在一起对读：为什么大脑、双手和会话必须解耦，以及「不要把服务器当宠物」在 Agent 架构上意味着什么。","position":null,"group":null,"series":"AI技术理解","tags":["agent","product-teardown","context-engineering"],"publication_status":"public","maturity":"evergreen","body_sha256":"9c664e11c6c6e90216f68320af1d6517de25e4f80207694826565e71489188bc","paragraph_rule":"src/lib/paragraphs.mjs@1","paragraphs":[{"id":"p1","kind":"paragraph","text":"Anthropic 官方工程团队发布了一篇技术博客《Scaling Managed Agents: Decoupling the brain from the hands》。","raw":"Anthropic 官方工程团队发布了一篇技术博客《Scaling Managed Agents: Decoupling the brain from the hands》。"},{"id":"p2","kind":"paragraph","text":"刚好最近在学习拆解 Claude Code 的底层技术架构，初读这篇博客时，脑子里冒出了不少问号：这个 Managed Agents 是一个新的协议吗？为什么原本用来包裹模型的 Harness 被剥离出来变成了大脑？","raw":"刚好最近在学习拆解 Claude Code 的底层技术架构，初读这篇博客时，脑子里冒出了不少问号：这个 Managed Agents 是一个新的协议吗？为什么原本用来包裹模型的 Harness 被剥离出来变成了大脑？"},{"id":"p3","kind":"paragraph","text":"带着这些疑问反复推敲，原来我的认知卡点在于：一直带着「本地单体应用」的思维，去看待「云端托管平台」的架构。","raw":"带着这些疑问反复推敲，原来我的认知卡点在于：一直带着「本地单体应用」的思维，去看待「云端托管平台」的架构。"},{"id":"p4","kind":"paragraph","text":"这篇文章就是我将 Claude Code 底层代码复现工程，与 Anthropic 这篇最新架构反思放在一起对读后，做的一次从本地单体应用到云端多智能体托管的架构演进梳理。","raw":"这篇文章就是我将 Claude Code 底层代码复现工程，与 Anthropic 这篇最新架构反思放在一起对读后，做的一次从本地单体应用到云端多智能体托管的架构演进梳理。"},{"id":"p5","kind":"heading","text":"一、Claude Code 的单体架构","raw":"## 一、Claude Code 的单体架构"},{"id":"p6","kind":"paragraph","text":"当我们打开终端界面，敲下一句「帮我写一个贪吃蛇游戏」后，背后会发生什么？可以大致拆解为三个核心组件。","raw":"当我们打开终端界面，敲下一句「帮我写一个贪吃蛇游戏」后，背后会发生什么？可以大致拆解为三个核心组件。"},{"id":"p7","kind":"heading","text":"1、核心状态机（The Harness / Query Loop）","raw":"### 1、核心状态机（The Harness / Query Loop）"},{"id":"p8","kind":"paragraph","text":"这是整个 Agent 最核心的部分，被具象化为一个名为 query_loop 的 while(True) 循环，它定义了 Agent 思考和行动的节奏：","raw":"这是整个 Agent 最核心的部分，被具象化为一个名为 [`query_loop`](/writing/claude-code-query-loop) 的 `while(True)` 循环，它定义了 Agent 思考和行动的节奏："},{"id":"p9","kind":"list","text":"- Phase 1（准备）：系统把你的要求、当前的文件目录、之前的对话等等，打包成一长串消息流（Transcript）。\n- Phase 2（调用与流式执行）：把这串文本发送给模型。如果模型决定调用工具（比如用 Bash 跑命令），系统可以不等模型把话全说完，立刻并发启动工具。\n- Phase 3（执行与拼装）：工具在你的本地电脑上真实地运行（比如创建了一个 game.py），然后系统把成功或失败的结果再次拼装回消息流中。\n- Phase 4（循环）：系统拿着带有工具执行结果的新消息流，再次去调用模型，直到模型说「任务完成」。","raw":"- **Phase 1（准备）**：系统把你的要求、当前的文件目录、之前的对话等等，打包成一长串消息流（Transcript）。\n- **Phase 2（调用与流式执行）**：把这串文本发送给模型。如果模型决定调用工具（比如用 Bash 跑命令），系统可以不等模型把话全说完，立刻并发启动工具。\n- **Phase 3（执行与拼装）**：工具在你的本地电脑上真实地运行（比如创建了一个 `game.py`），然后系统把成功或失败的结果再次拼装回消息流中。\n- **Phase 4（循环）**：系统拿着带有工具执行结果的新消息流，再次去调用模型，直到模型说「任务完成」。"},{"id":"p10","kind":"paragraph","text":"这个把模型包裹起来、给它提供上下文、并负责把模型的意图翻译成真实世界动作的脚手架代码，就是 Harness。","raw":"这个把模型包裹起来、给它提供上下文、并负责把模型的意图翻译成真实世界动作的脚手架代码，就是 Harness。"},{"id":"p11","kind":"heading","text":"2、双手（The Hands / Tools）","raw":"### 2、双手（The Hands / Tools）"},{"id":"p12","kind":"paragraph","text":"模型本身是没有实体的。这里的「手」就是那 20 多个预先写好的脚本（FileEditTool、BashTool、GlobTool 等）。当模型输出一段特定的 JSON 说 {\"tool\": \"bash\", \"command\": \"ls -la\"} 时，Harness 就会在当前的操作系统环境下拉起一个子进程去执行它。","raw":"模型本身是没有实体的。这里的「手」就是那 20 多个预先写好的脚本（`FileEditTool`、`BashTool`、`GlobTool` 等）。当模型输出一段特定的 JSON 说 `{\"tool\": \"bash\", \"command\": \"ls -la\"}` 时，Harness 就会在当前的操作系统环境下拉起一个子进程去执行它。"},{"id":"p13","kind":"heading","text":"3、记忆与上下文（The Session）","raw":"### 3、记忆与上下文（The Session）"},{"id":"p14","kind":"paragraph","text":"在这类 harness 中，运行时上下文高度依赖信息流（transcript），并通过 compact 与 memory 机制来缓解窗口限制。但它不等同于 Managed Agents 所强调的外置、耐久、可按需回放的 session log。","raw":"在这类 harness 中，运行时上下文高度依赖信息流（transcript），并通过 compact 与 memory 机制来缓解窗口限制。但它不等同于 Managed Agents 所强调的外置、耐久、可按需回放的 session log。"},{"id":"p15","kind":"paragraph","text":"简单总结一下：本地终端就是一个大容器，里面住着大脑（Harness + 模型接口）、双手（执行工具的环境）和记忆（不断被裁剪的上下文），它们紧紧抱在一起，共享着电脑的 CPU、内存和最高权限。","raw":"简单总结一下：本地终端就是一个大容器，里面住着大脑（Harness + 模型接口）、双手（执行工具的环境）和记忆（不断被裁剪的上下文），它们紧紧抱在一起，共享着电脑的 CPU、内存和最高权限。"},{"id":"p16","kind":"paragraph","text":"这在本地用起来的确很厉害，但如果要把这个模式搬到云端，卖给成千上万的企业呢？","raw":"这在本地用起来的确很厉害，但如果要把这个模式搬到云端，卖给成千上万的企业呢？"},{"id":"p17","kind":"heading","text":"二、单体 Agent 的困境：不要把服务器当宠物","raw":"## 二、单体 Agent 的困境：不要把服务器当宠物"},{"id":"p18","kind":"paragraph","text":"Anthropic 在博客中指出了这种紧耦合架构在面临大规模扩展时的三大痛点。","raw":"Anthropic 在博客中指出了这种紧耦合架构在面临大规模扩展时的三大痛点。"},{"id":"p19","kind":"heading","text":"痛点一：脆弱的宠物","raw":"### 痛点一：脆弱的宠物"},{"id":"p20","kind":"paragraph","text":"宠物是主人精心起名字且无法承受失去的个体，它要是病了，主人就会半夜爬起来去抢救；而牛是牧场里打着编号的家畜，死了一只，直接换下一只。","raw":"宠物是主人精心起名字且无法承受失去的个体，它要是病了，主人就会半夜爬起来去抢救；而牛是牧场里打着编号的家畜，死了一只，直接换下一只。"},{"id":"p21","kind":"paragraph","text":"在旧架构里，Agent 就变成了一只娇贵的宠物。因为大脑、手和会话日志都在同一个容器里，如果代码沙盒里跑了一个死循环导致内存溢出，整个容器崩溃了，那么 Harness 挂了大脑断线，Session 丢了刚才聊了几十轮的进度全都灰飞烟灭。工程师们只能被迫去抢救这些容器，而因为容器里有用户的私有代码，出于隐私安全，工程师甚至无法登进去 Debug。","raw":"在旧架构里，Agent 就变成了一只娇贵的宠物。因为大脑、手和会话日志都在同一个容器里，如果代码沙盒里跑了一个死循环导致内存溢出，整个容器崩溃了，那么 Harness 挂了大脑断线，Session 丢了刚才聊了几十轮的进度全都灰飞烟灭。工程师们只能被迫去抢救这些容器，而因为容器里有用户的私有代码，出于隐私安全，工程师甚至无法登进去 Debug。"},{"id":"p22","kind":"heading","text":"痛点二：上下文焦虑症","raw":"### 痛点二：上下文焦虑症"},{"id":"p23","kind":"paragraph","text":"随着模型变得越来越聪明，Harness 里的很多补丁代码会变得很可笑。","raw":"随着模型变得越来越聪明，Harness 里的很多补丁代码会变得很可笑。"},{"id":"p24","kind":"paragraph","text":"Anthropic 发现了一个有趣的现象：早期的 Claude 3.5 Sonnet 在做长周期任务时，如果感觉到 token 快到上限了，它会产生「上下文焦虑」，开始草草结案。为了解决这个问题，工程师在 Harness 里加了强制的上下文压缩。","raw":"Anthropic 发现了一个有趣的现象：早期的 Claude 3.5 Sonnet 在做长周期任务时，如果感觉到 token 快到上限了，它会产生「上下文焦虑」，开始草草结案。为了解决这个问题，工程师在 Harness 里加了强制的上下文压缩。"},{"id":"p25","kind":"paragraph","text":"但这是一种不可逆的破坏，它强行抹掉了前期的代码报错细节，等到模型后续需要复盘时线索已经断了。并且当模型升级到 Opus 4.5 时，模型本身已经没有焦虑症了，Harness 里那段强制压缩的代码，反而成了枷锁。","raw":"但这是一种不可逆的破坏，它强行抹掉了前期的代码报错细节，等到模型后续需要复盘时线索已经断了。并且当模型升级到 Opus 4.5 时，模型本身已经没有焦虑症了，Harness 里那段强制压缩的代码，反而成了枷锁。"},{"id":"p26","kind":"heading","text":"痛点三：可怕的安全边界","raw":"### 痛点三：可怕的安全边界"},{"id":"p27","kind":"paragraph","text":"在大脑和手不分家的架构里，模型生成的代码和系统的核心凭证（比如 GitHub Token）都在同一个盒子里。","raw":"在大脑和手不分家的架构里，模型生成的代码和系统的核心凭证（比如 GitHub Token）都在同一个盒子里。"},{"id":"p28","kind":"paragraph","text":"如果模型遭遇了用户的提示词注入攻击，它完全可以悄悄写一段代码，读取当前环境变量里的私钥，然后发送到黑客的服务器上。因为在这个容器里，模型的手能摸到一切。","raw":"如果模型遭遇了用户的提示词注入攻击，它完全可以悄悄写一段代码，读取当前环境变量里的私钥，然后发送到黑客的服务器上。因为在这个容器里，模型的手能摸到一切。"},{"id":"p29","kind":"heading","text":"三、Managed Agents：彻底的脑手分离","raw":"## 三、Managed Agents：彻底的脑手分离"},{"id":"p30","kind":"paragraph","text":"面对上述痛点，Anthropic 意识到修修补补是没用的，必须在架构层面进行肢解。这就是面向长周期复杂任务的云端托管方案：Managed Agents。","raw":"面对上述痛点，Anthropic 意识到修修补补是没用的，必须在架构层面进行肢解。这就是面向长周期复杂任务的云端托管方案：Managed Agents。"},{"id":"p31","kind":"paragraph","text":"它的核心哲学可以用一句话概括：定义永恒的接口，让大脑、双手和记忆彻底解耦。","raw":"它的核心哲学可以用一句话概括：**定义永恒的接口，让大脑、双手和记忆彻底解耦。**"},{"id":"p32","kind":"heading","text":"解耦一：大脑离开容器，双手变成「牛」","raw":"### 解耦一：大脑离开容器，双手变成「牛」"},{"id":"p33","kind":"paragraph","text":"在这个架构中，包含 query_loop 的大脑层被彻底从执行代码的容器中抽离了出来。","raw":"在这个架构中，包含 `query_loop` 的大脑层被彻底从执行代码的容器中抽离了出来。"},{"id":"p34","kind":"paragraph","text":"Harness 变成了无状态的调度器：它不再自己跑代码，当需要执行命令时，通过一个标准接口 execute(name, input) -> string 呼叫远端的沙盒。","raw":"Harness 变成了**无状态的调度器**：它不再自己跑代码，当需要执行命令时，通过一个标准接口 `execute(name, input) -> string` 呼叫远端的沙盒。"},{"id":"p35","kind":"paragraph","text":"沙盒则变成了牛：它只是一个用来干脏活累活的隔离环境。如果在编译代码时沙盒崩溃了，没关系——由于大脑在外面，大脑不会死，它只会收到一个报错「工具执行超时/失败」，然后冷静地决定调用 provision({resources}) 重新拉起一个新的沙盒继续干活。","raw":"沙盒则变成了**牛**：它只是一个用来干脏活累活的隔离环境。如果在编译代码时沙盒崩溃了，没关系——由于大脑在外面，大脑不会死，它只会收到一个报错「工具执行超时/失败」，然后冷静地决定调用 `provision({resources})` 重新拉起一个新的沙盒继续干活。"},{"id":"p36","kind":"paragraph","text":"这种「自杀与重生」的机制，呼应了 Agent = Model + Harness 中提到的理念：真正的鲁棒性，来自于系统的随时可抛弃。","raw":"这种「自杀与重生」的机制，呼应了 [Agent = Model + Harness](/writing/agent-model-plus-harness) 中提到的理念：真正的鲁棒性，来自于系统的随时可抛弃。"},{"id":"p37","kind":"heading","text":"解耦二：Session 独立于上下文窗口","raw":"### 解耦二：Session 独立于上下文窗口"},{"id":"p38","kind":"paragraph","text":"这是用来解决上下文焦虑症的。","raw":"这是用来解决上下文焦虑症的。"},{"id":"p39","kind":"paragraph","text":"在 Managed Agents 中，对话日志不再局限于随时会被挤爆的上下文窗口，Anthropic 引入了一个独立存在、只追加不修改的 Session 事件日志流。","raw":"在 Managed Agents 中，对话日志不再局限于随时会被挤爆的上下文窗口，Anthropic 引入了一个独立存在、只追加不修改的 Session 事件日志流。"},{"id":"p40","kind":"paragraph","text":"这就像给 Agent 外挂了一个行车记录仪：从第一条用户指令，到中间每一次工具调用的输入输出，全部被永久地、安全地记录在这个外部的 Session 数据库里。","raw":"这就像给 Agent 外挂了一个行车记录仪：从第一条用户指令，到中间每一次工具调用的输入输出，全部被永久地、安全地记录在这个外部的 Session 数据库里。"},{"id":"p41","kind":"paragraph","text":"当 Harness 发现上下文太长需要清理时，它可以放心地清理。因为只要模型需要，随时可以通过 getEvents() 接口，像查监控录像一样倒回前天下午 3 点 15 分，重新读取那一次特定的代码报错日志。","raw":"当 Harness 发现上下文太长需要清理时，它可以放心地清理。因为只要模型需要，随时可以通过 `getEvents()` 接口，像查监控录像一样倒回前天下午 3 点 15 分，重新读取那一次特定的代码报错日志。"},{"id":"p42","kind":"paragraph","text":"正如上下文不等于记忆所写：在这个架构下，短期的上下文窗口只负责当前的思考推理，而外置的 Session 才是 Agent 真正的长期记忆库。如果 Harness 崩溃重启了，它只需要调用 wake(sessionId)，就能从日志中完美恢复上一秒的状态。","raw":"正如[上下文不等于记忆](/writing/context-is-not-memory)所写：在这个架构下，短期的上下文窗口只负责当前的思考推理，而外置的 Session 才是 Agent 真正的长期记忆库。如果 Harness 崩溃重启了，它只需要调用 `wake(sessionId)`，就能从日志中完美恢复上一秒的状态。"},{"id":"p43","kind":"heading","text":"解耦三：安全边界的物理隔离","raw":"### 解耦三：安全边界的物理隔离"},{"id":"p44","kind":"paragraph","text":"因为脑手分离，鉴权问题迎刃而解。","raw":"因为脑手分离，鉴权问题迎刃而解。"},{"id":"p45","kind":"paragraph","text":"当 Agent 需要拉取 GitHub 仓库时，存放 Token 的保险库绝不会把 Token 告诉模型，也不会把它塞进跑代码的沙盒里。系统通过外部的 MCP 代理服务：代理服务拿着 Session ID 去金库验证权限，通过后由代理服务把代码拉下来，再挂载进沙盒。","raw":"当 Agent 需要拉取 GitHub 仓库时，存放 Token 的保险库绝不会把 Token 告诉模型，也不会把它塞进跑代码的沙盒里。系统通过外部的 MCP 代理服务：代理服务拿着 Session ID 去金库验证权限，通过后由代理服务把代码拉下来，再挂载进沙盒。"},{"id":"p46","kind":"paragraph","text":"Agent 永远都不会知道密码是什么，它只负责干活。即使它被注入了恶意指令，在四面环壁的沙盒里也偷不走任何东西。","raw":"Agent 永远都不会知道密码是什么，它只负责干活。即使它被注入了恶意指令，在四面环壁的沙盒里也偷不走任何东西。"},{"id":"p47","kind":"heading","text":"解耦四：多脑多手与极速启动","raw":"### 解耦四：多脑多手与极速启动"},{"id":"p48","kind":"paragraph","text":"当一切都被解耦为标准接口后，一个商业优势出现了：极致的性能体验。","raw":"当一切都被解耦为标准接口后，一个商业优势出现了：极致的性能体验。"},{"id":"p49","kind":"paragraph","text":"在旧架构下，用户说一句话，后台要花几十秒去启动一个包含完整环境的臃肿容器，导致首字返回时间极长。现在 Harness 是极其轻量的代码，立刻就能启动，只有当模型思考完毕、决定真的需要写代码时，后台才会去动态拉起一个沙盒。","raw":"在旧架构下，用户说一句话，后台要花几十秒去启动一个包含完整环境的臃肿容器，导致首字返回时间极长。现在 Harness 是极其轻量的代码，立刻就能启动，只有当模型思考完毕、决定真的需要写代码时，后台才会去动态拉起一个沙盒。"},{"id":"p50","kind":"paragraph","text":"更进一步，这种接口设计天然支持「多脑多手」：一个大脑可以同时操作多个不同的沙盒（比如一个跑前端代码，一个跑 Python 后端）；或者大脑遇到处理不了的专业问题，可以直接把手的控制权移交给另一个拥有专门 Prompt 的子大脑。","raw":"更进一步，这种接口设计天然支持「多脑多手」：一个大脑可以同时操作多个不同的沙盒（比如一个跑前端代码，一个跑 Python 后端）；或者大脑遇到处理不了的专业问题，可以直接把手的控制权移交给另一个拥有专门 Prompt 的子大脑。"},{"id":"p51","kind":"heading","text":"最后","raw":"## 最后"},{"id":"p52","kind":"paragraph","text":"从本地的一段 query_loop 循环，到云端的 Managed Agents 解耦架构，正如 Anthropic 博客中写道的：挑战其实是一个古老的问题——如何为「尚未被构想出来的程序」设计系统。","raw":"从本地的一段 `query_loop` 循环，到云端的 Managed Agents 解耦架构，正如 Anthropic 博客中写道的：挑战其实是一个古老的问题——如何为「尚未被构想出来的程序」设计系统。"},{"id":"p53","kind":"paragraph","text":"所以，Agent 不是一个更复杂的 Chatbot，它是一套全新的计算范式。","raw":"所以，Agent 不是一个更复杂的 Chatbot，它是一套全新的计算范式。"}],"authored_claims":[{"id":"pets-vs-cattle-for-agents","text":"在大脑、手和会话日志同处一个容器的架构里，Agent 是一只娇贵的宠物——沙盒里一个死循环就能让整个容器崩溃，几十轮的进度灰飞烟灭，而工程师因为容器里有用户私有代码甚至无法登进去 Debug。","stance":"judgment","confidence":"high","supersedes":null,"note":null,"formed_at":"2026-04-13"},{"id":"harness-patches-become-shackles","text":"早期 Claude 3.5 会在 token 接近上限时产生「上下文焦虑」草草结案，工程师为此在 Harness 里加了强制压缩；但压缩是不可逆的破坏，而当模型升级到 Opus 4.5 不再焦虑后，那段代码反而成了枷锁。","stance":"fact","confidence":"high","supersedes":null,"note":null,"formed_at":"2026-04-13"},{"id":"brain-hand-separation-fixes-security","text":"脑手分离让鉴权问题迎刃而解：凭证由外部 MCP 代理服务持有，代理验证权限后把代码拉下来挂载进沙盒。Agent 永远不知道密码是什么，即使被注入恶意指令，在四面环壁的沙盒里也偷不走东西。","stance":"fact","confidence":"high","supersedes":null,"note":null,"formed_at":"2026-04-13"},{"id":"session-log-is-the-real-memory","text":"外置的、只追加不修改的 Session 事件日志才是 Agent 真正的长期记忆库，上下文窗口只负责当前的思考推理。有了它，Harness 可以放心地清理上下文，也可以在崩溃后靠 wake(sessionId) 完美恢复。","stance":"judgment","confidence":"high","supersedes":null,"note":null,"formed_at":"2026-04-13"},{"id":"decoupling-enables-many-brains-many-hands","text":"一切被解耦为标准接口后，轻量的 Harness 可以立刻启动、只在真正需要写代码时才拉起沙盒，首字返回时间大幅缩短；同时天然支持一个大脑操作多个沙盒，或把控制权移交给专门的子大脑。","stance":"judgment","confidence":null,"supersedes":null,"note":null,"formed_at":"2026-04-13"}],"claim_ids":["pets-vs-cattle-for-agents","harness-patches-become-shackles","brain-hand-separation-fixes-security","session-log-is-the-real-memory","decoupling-enables-many-brains-many-hands"],"revision":"6fe0c84ede65530eea6ea5e55deb7268da511e70c23122f04c4f0b3b2e0f869f"}