Skip to content

08|每个 Agent 自己的世界:作用域为什么不靠继承 ​

先别给子代理做一棵权限树 ​

第 07 章刚让工具按作用域解析。下一句联想几乎是本能的:父 Agent 有一份工具集,子 Agent 继承它,再自己加减,像进程权限,也像类继承。

这棵树在这个系统里是错的。

作用域被定成两层、扁平:一份贡献要么全局(每个 Agent 都看见),要么归恰好一个作用域所有。作用域内的登记不会向子代理传递。 子树的行为用"血缘(lineage)"数据表达,不用作用域的树状结构表达。血缘说得更绝:父会话标识、委托深度这些是带在身上的事实,从不影响可见性。

父 Agent 拥有子 Agent 的生命周期,但不会自动捐赠也不会限制子 Agent 的登记。这是一条明确的安全非目标:作用域组合的是受信任的同进程登记,它不是沙箱,不是权威边界,不保证孩子不能比父亲拥有更多能力。孩子的工具集比父亲更宽,是合法的。

这一章要拆的就是这句直觉:每个 Agent 自己的世界,不是从父亲那里抄来的世界。


1. 可见性和所有权必须是同一件事 ​

先给判断:一个登记从哪来,同时决定谁看得见它、跟谁一起死。拆开这两件事,泄漏是时间问题。

默认循环实现的落地方式是:司机用自己当钥匙铸一个作用域,再基于这个钥匙派生出这个 Agent 专属的上下文。钥匙按对象身份比较,不是按名字或编号——活着的 Agent 实例就是自己那层的钥匙。

经这个专属上下文做的登记,会同时决定了两件事:这份登记谁能看见,以及这份登记跟谁一起消失——一个事实驱动两件事。落到产品层面:经这个专属上下文挂的工具、提示词片段、变量、监听器,只对该 Agent 可见,该 Agent 销毁时全部撤走。

一个被拒绝的替代方案是:每次注册的时候单独传一个"这是哪个 Agent 的"参数。这样做的问题是,每个注册表都要重复实现一遍作用域管理逻辑,可见性的主人和清理的主人会漂成两个人。经专属上下文登记,两件事跟着同一个可逆效果走——第 02 章的效果登记机制已经这么设计了:一次登记动作绑在登记时所在的那个上下文上,这个上下文同时决定可见性和所有权。

有一个"组装窗口"是这层世界搭建的专属时段,不是开跑时段:作用域和 Agent 对象已经存在,但还没有对外发布,相关的启动事件还没触发,第一次提示词也还没组装。这个窗口跑完之后,才会正式提交并发布这个 Agent。在这个窗口里驱动一个还没发布的 Agent(比如让它主动发消息)是不受支持的行为。窗口内失败,整笔交易回滚,包括这层刚搭好的作用域。

拆除的顺序恰好相反:先停司机、排空在跑的工作、摘掉 Agent 和会话的注册,最后才销毁这层作用域。这个世界必须活到最后一份工作停干净为止。第 03 章的句柄释放动作,走的就是这条边界。

如果可见性和所有权分开会怎样?插件 A 往 Agent B 的视图里塞一个工具,自己先卸载了,工具还挂在 B 的提示词里,执行逻辑已经是野指针。或者 B 死了,工具还在全局表里,下一个同编号的 Agent 继承一份没人承认的能力。让一个上下文同时决定这两件事,这些分叉就都消失了。


2. 两层,不是一棵 Agent 树 ​

判断:一次操作看见的是"部署全局 + 这一个 Agent 自己的那层"。没有第三层叫"祖先 Agent"。

对大多数扩展作者,合同可以收成四条:

问题规则
给一个 Agent 挂行为?走这个 Agent 专属上下文上那套普通登记方式
一次操作看见什么?全局 + 这个 Agent 自己的层,具体合并规则归拥有方服务决定
哪些作用域监听器会触发?没打标记的全局监听器,加上专门为这个 Agent 登记的监听器
这层活多久?组装窗口在发布前完成;销毁要留到工作彻底静止之后

名字冲突用"遮蔽"解决,不用覆盖全局:最具体的赢。某个 Agent 自己作用域里的工具、提示词片段、变量,会替换同名的全局版本,但只在这一个作用域里生效。这是"每个人设一份配置、每个工具场景化变体"的机制,不是"子类重写父类"。

限制走的是另一条路:限制操作过滤的是全局工具集,多份限制之间求交集;某个 Agent 自己的本地登记,在这层过滤之后才合并进来。被过滤掉的全局工具,提示词里看不到,执行也会被拒绝,跟这个工具压根不存在没有区别。有一条专门的保护:如果从一个普通的全局上下文调用限制操作,会被直接拒绝——全局限制会遮住每一个 Agent,那通常是配置错误,不是有意的政策。

读取某个作用域自己的限制和闸门时,故意不去认祖先——只读这个作用域自己登记的那些,不准悄悄捡起"祖先"的。如果真的需要沿着某条链把配置合并起来(这是下一节要讲的另一种"父"关系),走的是另一套专门的合并逻辑:远的先铺一层,近的最后覆盖。自己的闸门和从共享构图里继承来的名字,不是同一件事。

作用域也从来不是沙箱:它们是给受信任的同进程插件指路用的,不是权威边界。握着共享运行环境引用的插件跟 Agent 在同一个进程里,本来就可以直接调用得到相关的服务。部署方若真的需要"孩子不能比父亲多"这种强制约束,要另外做一套权威表示和执行检查,这些明确不在作用域机制要解决的问题范围内。

如果做成一棵 Agent 权限树会怎样?子代理的工具集变成父亲的函数,父亲一改人设,所有活着的孩子一起变。委托深度会变成继承深度。你再也说不清一次命令执行是孩子自己的,还是从爷爷那儿漏下来的。扁平两层让这个问题彻底消失:要么全局,要么就是这一个作用域。


3. 有一条"父链",但它是给共享构图用的,不是给父子会话用的 ​

判断:作用域这个底层原语确实有一种父链关系。产品把这种关系用在"一份构图被许多 Agent 共享",不用在"孩子继承父亲"。

这个底层原语本身有两种典型用法:循环给每个活着的 Agent 铸一层专属作用域;而某个"Agent 预设"的常驻挂载点,会作为一组 Agent 共同的父作用域。这个机制本身跟"Agent"这个概念无关,更底层的实现完全不需要认识"Agent"是什么。

预设包把这根链用到了点子上:每个预设自己的组装配置只挂一次,落在一个常驻的作用域上;点名要用这个预设的 Agent,通过"绑定作用域父级"这个动作把自己接到这份挂载上。于是构图里的插件实例、工具、提示词片段只存在一份;某个 Agent 能看见它们,是因为自己的钥匙认了这个父级,不是因为拷贝了一份登记。这个绑定关系会被记录下来,外面的人不能把一个已经绑定好构图的 Agent 随意搬到另一个预设上。

子代理要"继承"父亲的能力,走的正是这同一根钉子,不是走父亲那个 Agent 自己的钥匙:孩子加入的是父亲已经在跑的那一代常驻构图——同一批插件实例、同一批工具、同一批提示词,不是按预设编号重新挂载一次。这一点很关键:如果构图配置文件在父亲启动之后又被改过,重新挂载会让孩子拿到另一代配置,跟父亲历史上实际用过的那份对不上。

事件沿着这条链向上走,不向下:打了"祖先"标记的监听器能收到后代的事件,这让一份常驻构图能够观察所有加入它的 Agent。反过来,下面的标记收不到上面的事件——父亲 Agent 自己的监听器不会因为血缘关系就自动听到孩子的事件;除非孩子和父亲都加入了同一份预设构图,这份预设构图上的监听器才会同时听到两边。

所以系统里其实有两种"父",千万别混:

关系它是什么是否影响工具可见性
Agent → 它所属的预设常驻作用域显式绑定动作影响:孩子能看见那份共享构图
父会话 → 子会话血缘数据不影响:父会话标识只是日志和深度计数

第 04 章的待办队列、第 05 章的分叉前缀,带的都是第二种"父"。附录 C 里的委托、长期任务续跑机制,同样是第二种。第一种才是这一章的范围:一份构图,许多 Agent 共享。

如果用父亲 Agent 当作用域的父级会怎样?父亲本地挂的一份总结变量会漏进每一个孩子,父亲的限制规则会变成整棵委托树的强制法律。预设热更新会跟会话树缠在一起。把"共享构图"做成独立的常驻钥匙,让会话树继续作为纯数据存在,两棵树互不污染。


4. 登记选归属,操作选视图 ​

判断:经某个 Agent 专属上下文调用注册接口,决定的是新登记落在哪一层。一次读、一次执行、一次事件,要自己显式带上那个 Agent。

登记来源和操作主体是两件不同的事实:经专属上下文调用某个服务,不会把以后任何一次读操作都自动绑死在这个 Agent 上。工具查找和执行会收下它们服务的那个具体 Agent;提示词组装收下这次请求的装配上下文;事件派发收下事件所属的领域主体。共享的服务实例可以被多个 Agent 复用,每次操作的视图都是显式传入的。

所以"查找一个全局的工具"和"查找专属于某个 Agent 的同名工具"是两次不同的调用——前者拿到全局版本,后者才能拿到那个 Agent 本地的版本。第 07 章的执行前检查点用"事件所属的 Agent"来派发通知,也是同一规则:事件带着这次调用所属的那个 Agent,打了别的 Agent 标记的监听器听不见这次调用。注册表自己发生变化(比如又挂上一个新工具)这件事,属于"注册表本身的事件",故意不按 Agent 过滤——那是共享状态的变化,不是某一次具体操作。

还有一条冷水:只有认识作用域概念的接口才会真正隔离状态。注册表必须按登记所在的作用域去归档,事件必须经过专门的派发方法去投递。随便一个普通服务,仅仅因为你从某个 Agent 专属上下文里调用了它,并不会自动变成这个 Agent 私有的东西。专属上下文不是魔法命名空间。

在组装窗口里组合插件是合法的,因为那是登记动作。在组装窗口里让这个 Agent 主动发消息不合法,因为那是在驾驶一辆还没上牌的车。窗口的含义是:世界先完整搭好,再被别人看见。第 03 章的工厂交易、第 04 章的第一次 turn,都站在这道门的后面。


5. 结语:带走一句话 ​

一个 Agent 的世界是"全局 + 它自己那一层"——可见性和寿命是同一件事;父子关系是日志里的数据,不是一棵往下传工具的树。