Skip to content

Latest commit

 

History

History
151 lines (96 loc) · 6.19 KB

File metadata and controls

151 lines (96 loc) · 6.19 KB

41. Agent 隔离:Worktree、Remote 与 CWD Override

所属分卷:卷五「Anthropic Agent 设计研究」

建议前读:11. 子代理与任务系统28. Direct Connect、Server 与 Upstream Proxy

建议后读:42. Agent Definition 加载与可用性

研究问题

agent 的 isolation 到底隔离了什么?是文件副本、运行目录、权限,还是整个会话身份?

一句话结论

Claude Code 的隔离不是一个单一开关,而是三层不同语义的组合:worktree 隔离工作副本,remote 隔离执行环境,cwd override 则只重定向本地文件与 shell 的默认工作目录。

这篇讲什么

这一章专门解释 AgentTool 里与隔离相关的执行路径:

  • isolation: "worktree"
  • isolation: "remote"
  • cwd

以及它们和 transcript、resume、cleanup 的关系。

如果你不看源码,只看这一章,应该记住什么

  • worktree 的目标是隔离文件修改,不是隔离上下文。
  • remote 的目标是把 agent 放进另一套远端运行环境,而且天然是 background 任务。
  • cwd override 不是 worktree 的弱版本,它不会复制仓库,只会重定向本地执行目录。

源码依据

Mermaid 图:隔离模式决策图

flowchart TD
    A["AgentTool input"] --> B{"isolation"}
    B -- none --> C{"cwd override?"}
    B -- worktree --> D["createAgentWorktree"]
    B -- remote --> E["teleportToRemote + registerRemoteAgentTask"]
    C -- 否 --> F["沿用父 cwd"]
    C -- 是 --> G["runWithCwdOverride"]
    D --> H["在隔离副本中执行"]
    H --> I{"是否有改动"}
    I -- 无改动 --> J["removeAgentWorktree"]
    I -- 有改动 --> K["保留 worktreePath/worktreeBranch"]
Loading

Anthropic 在这里想解决什么

多 agent 一旦进入真实工程工作流,就会立刻遇到冲突问题:

  • 两个 agent 同时写同一工作副本
  • agent 的临时修改污染主线程
  • 长任务需要更干净的执行环境

Anthropic 的回答不是“让 agent 小心一点”,而是把隔离作为一等执行参数。

worktree 隔离的真实语义

createAgentWorktree()hasWorktreeChanges() 体现了 worktree 路径的核心语义:

  • 给 agent 一个独立工作副本
  • 尽量复用主仓库的大目录与设置
  • 完成后根据是否发生修改决定清理还是保留

尤其值得注意的是“有改动就保留、无改动就清理”的策略。它说明 Anthropic 不是把 worktree 当临时目录,而是把它当成可交付工作结果的载体。

Hook-based worktree 和 Git-based worktree 的边界

src/utils/worktree.ts 不只支持 git worktree,还支持 hook-based worktree。文档上最值得记住的是:

  • git 路径下系统能检测是否有改动,并自动清理
  • hook-based 路径下系统更保守,往往倾向保留

这体现了一种 fail-closed 思路:检测不到可靠状态时,不主动删除用户可能需要的工作副本。

为什么 fork + worktree 还要注入 notice

fork child 如果跑在 worktree 里,buildWorktreeNotice() 会明确告诉它:

  • 上下文继承自父线程
  • 文件路径要映射到新的 worktree root
  • 编辑前要重新读文件

这说明 Anthropic 明确认定:上下文不是 live filesystem snapshot。即使给了 worktree,agent 也必须重新验证文件状态。

cwd override 解决的是另一类问题

cwd 的语义更简单也更窄:

  • 不复制 repo
  • 不创建隔离 worktree
  • 只是把本地执行的默认目录切换到某个绝对路径

在源码里它通过 runWithCwdOverride() 包裹执行。也就是说,cwd 更像一次局部执行重定向,而不是完整隔离策略。

remote isolation 为什么总是 background

remote 路径会走 teleportToRemote()registerRemoteAgentTask()。这条路径有几个很清晰的产品假设:

  • 远端执行天然不是同步 REPL 交互
  • 它应该表现为 task
  • 结果要通过 remote task notification 回来

因此 remote 不是“另一个本地模式”,而是一条明确的异步远端执行协议。

cleanup 策略暴露了怎样的不变量

cleanupWorktreeIfNeeded() 其实体现了一个很强的不变量:

  • 清理必须发生在通知之前
  • 通知里要能告诉调用者 worktree 是否被保留

这说明 Anthropic 把“后续如何继续处理该 agent 的产物”视为 agent 结果的一部分,而不是外围 housekeeping。

resume 为什么要恢复 worktreePath

resumeAgent.ts 会把 worktreePath 持久化在 metadata 里,并在恢复时检查该目录是否还存在。这说明:

  • 隔离不是一次性 spawn 配置
  • 它属于 agent 身份的一部分

如果 worktree 不存在,系统会回退到父 cwd,而不是直接崩溃。这体现了工程上更实用的恢复优先策略。

对 Anthropic agent 设计研究意味着什么

这一套设计说明 Anthropic 在谈“agent 隔离”时,并不是只关心 sandbox 安全。它更关心的是:

  • 多 agent 协作时的工作副本冲突
  • 长任务的结果可持续性
  • resume 时的环境连续性

也就是说,隔离在这里既是安全问题,也是软件工程协作问题。

这篇的工作结论

Claude Code 的 worktreeremotecwd 三条路径展示了非常工程化的 agent 隔离观:不是抽象地说“把 agent 隔离起来”,而是明确区分工作副本隔离、执行环境隔离和工作目录重定向三种不同机制。

延伸阅读