24 讲路线 · 与 S06 配对
D06: Subagent Fork 深挖 · 子代理分支
本讲在 S06 主线之上,聚焦实现细节、边界条件与自测;导图与主线相同模块,便于对照。
建议:先读完 S06,再按下方顺序走读源码与练习。
🔬 深挖目标
子代理 = 隔离上下文 + 受限工具视图 + 结果回灌。深挖重点是:fork 时复制什么、不复制什么、合并时会不会重复计费或泄露秘密。
🧩 隔离清单
- 消息历史:通常截断为子任务描述 + 少量父上下文。
- 工具白名单:子代理可能无权 bash / 无权写仓库。
- 文件系统视图:cwd、忽略规则、沙箱路径是否继承?
🔀 合并策略
| 合并产物 | 父循环消费方式 | 风险 |
|---|---|---|
| 单条摘要消息 | 当作 tool_result | 细节丢失 → 父模型误判完成度 |
| 多条结构化块 | 拼进上下文 | 体积暴涨 → 触发 D05 |
| 仅状态 diff | 更新 AppState | 与 Git(D12)状态不一致 |
💰 成本与调试
每 fork 一轮完整 loop,token 与延迟近似翻倍;日志里应能区分 parent_turn_id / child_turn_id。
📖 走读顺序
- 搜索
subagent、fork、delegate等关键词,定位创建函数。 - 打印 fork 前后的 config diff(尤其 tools 与 permission)。
- 跟踪子代理异常退出时父层如何收尾(超时、部分结果)。
✏️ 自测 1 · 参考答案:子代理读到 .env 算不算泄露?
题干
若子代理读到 .env 而父未显式传入,这是泄露还是特性?怎么修?
结论
默认应视为策略缺陷或泄露风险:子上下文若与父共享同一工作目录与读文件工具,会「顺带」看到敏感文件,而用户未必理解「子任务也能读盘」。
- 修:子代理使用缩小的工具白名单(禁用 read 或仅允许路径前缀);或 fork 时不继承父的 secret 注入;对
.env*走更高权限级。 - 若业务上故意让子任务读配置,应在 UI/文档中显式标注,并审计日志记录访问路径。
✏️ 自测 2 · 参考答案:子成功、父应失败的验收测试
题干
设计「子任务成功但父任务应失败」的验收测试。
思路
父任务定义全局不变式(例如「不得修改 LICENSE」)。子任务只负责子树且成功完成;子返回后父在合并/校验阶段发现不变式被破坏 → 父状态 failed,并向用户展示子输出 + 父校验失败原因。
- 自动化可构造:子代理被授权写
src/,但子通过 symlink 或相对路径实际改到LICENSE(若未校验解析路径则父应 catch)。 - 断言:子进程 exit 0;父任务最终
failed,且日志含违规路径。