父 Agent spawn 子 Agent 时,有哪些边界问题需要考虑?OpenClaw 做了哪些限制和保护?
参考答案
父 Agent spawn(创建/派生)子 Agent,核心要防住 4 个东西:无限递归(A 生 B、B 生 C、C 又生 D…无穷无尽)、资源耗尽、权限泄露、上下文不隔离。
- 子 Agent 不断 spawn 新的子 Agent,嵌套层级失控,token 和内存直接爆掉。
- 同时跑太多子 Agent,LLM API 的并发额度和本地 CPU、内存全都扛不住。
- 子 Agent 如果继承了父 Agent 的全部权限,就可能操作不该碰的工具或数据。
- 父子 Agent 之间的对话历史如果不隔离,信息串了会导致不可预期的行为。
OpenClaw 针对这 4 个问题都有对应的保护机制:

扩展知识
为什么不能靠开发者自觉
Agent 系统和传统应用最大的区别在于,Agent 的行为不完全由代码决定,LLM 的输出有不确定性。
你写死了”只在必要时 spawn 子 Agent”,但模型觉得什么叫”必要”完全靠它自己推理。线上环境跑着跑着,模型突然决定”这个任务太复杂了,我再 spawn 一个帮手”,帮手又觉得自己搞不定再 spawn,几轮下来就炸了。
所以这些限制必须是框架层面硬性约束,不能靠 prompt 里写一句”不要无限 spawn”就完事。
Workspace 继承策略
resolveSpawnedWorkspaceInheritance() 控制子 Agent 是否继承父 Agent 的工作目录。两种模式各有适用场景:
继承模式适合父子 Agent 需要协作操作同一个项目的情况,比如父 Agent 负责拆任务,子 Agent 负责执行具体的文件修改,它们需要看到同一份代码。
隔离模式适合安全性要求高的场景,子 Agent 只能在自己的临时目录里操作,搞不了父 Agent 的文件。
沙箱策略
子 Agent 的 sandbox 参数支持两个值:
"inherit"继承父 Agent 的沙箱状态"require"强制在沙箱中运行。

生产环境建议一律用 "require",宁可牺牲一点灵活性也要保证安全。开发调试阶段可以用 "inherit" 方便测试。
深度检测的持久化
嵌套深度的检测不是靠运行时的递归计数器,而是通过 getSubagentDepthFromSessionStore() 从 session store 里读的。每次 spawn 的时候,当前嵌套深度会写到新 session 的元数据里。
这个设计的好处是即使 Gateway 进程重启了,深度信息也不会丢。如果用内存计数器,进程一重启计数器归零,限制就失效了。用持久化存储就不存在这个问题,重启后从 session store 读出来照样能正确拦截超限的 spawn。
Hook 拦截机制
OpenClaw 提供了两个和子 Agent 生命周期相关的 Hook:
1)subagent_spawning:在子 Agent 创建之前触发,插件可以在这里做额外校验。比如检查当前时间段的 API 额度是否充足、检查请求方是否有权限 spawn 特定类型的子 Agent。如果 Hook 返回拒绝,spawn 直接中止
2)subagent_ended:在子 Agent 结束时触发,可以做清理工作或发通知。比如统计子 Agent 的 token 消耗、记录执行日志、通知监控系统
清理策略
子 Agent 结束后,cleanup 参数决定怎么处理它的 session:
"delete" 直接删掉 session,释放存储空间,适合一次性任务。"keep" 保留 session 数据,方便后续调试和审计,能看到子 Agent 完整的对话历史和工具调用记录。
线上跑批量任务建议用 "delete" 避免存储膨胀,排查问题的时候临时切成 "keep" 留现场。
面试官追问
提问:如果父 Agent 自己被 kill 了,它 spawn 出来的子 Agent 怎么办?会变成孤儿进程吗?
回答:OpenClaw 的子 Agent 运行在独立 session 里,不依赖父 Agent 的进程。父 Agent 被 kill 后,子 Agent 还会继续跑直到自己完成或者超时。不会变成传统意义上的孤儿进程,因为 Gateway 始终持有所有活跃 session 的引用。但子 Agent 的结果没人接收了,所以最佳实践是父 Agent 结束时通过 Hook 主动取消还在跑的子 Agent。
提问:maxSpawnDepth 设成 0 和不设有什么区别?
回答:设成 0 表示当前 Agent 自身就不允许 spawn 任何子 Agent,调用 spawn 接口直接报错。不设的话走默认值 1,允许 spawn 一层子 Agent 但子 Agent 不能再 spawn。这两个是有区别的,0 是完全禁用,1 是允许一层。
提问:子 Agent 的工具权限能做到比 deny 更细粒度的控制吗?比如允许读文件但不允许写文件?
回答:可以。resolveSubagentToolPolicy() 支持到工具级别的 allow/deny 配置,而且工具插件自身也可以暴露参数级别的权限控制。比如文件操作工具可以拆成 file_read 和 file_write 两个独立工具,对子 Agent 只 allow file_read。更细的粒度需要工具插件自己在执行时做校验,框架层面控制的最小单位是工具。
提问:多个子 Agent 同时 spawn 出来,它们之间能互相通信吗?
回答:默认不能。每个子 Agent 的 session 是完全隔离的,看不到兄弟 Agent 的存在。如果需要协作,得通过父 Agent 中转,父 Agent 收到一个子 Agent 的结果后再传给另一个。也可以通过共享工具来间接通信,比如两个子 Agent 都能读写同一个数据库或文件,但这不是框架层面的通信机制,需要开发者自己保证并发安全。