继承了本不该看到的系统提示词的子智能体
规划代理(Planner agent)接收一个任务,将其分解,并生成一个研究员子代理(researcher subagent)来处理其中一个分支。编排框架会将父代理的完整上下文传播给子代理,因为这是最容易交付的默认设置。现在,研究员拥有了规划者的完整系统提示词(system prompt)——策略文本、内部工具名称、父代理被授权使用的凭证,以及暗示你计费流水线结构的 few-shot 示例。研究员的工作原本只是阅读三份文档。但这次调用的爆炸半径却是父代理的全部权限。
这并非假设。这是目前大多数投入生产的多代理框架的默认行为。最近的一项审计发现,93% 的代理项目使用未限制范围(unscoped)的 API 密钥;当一个代理调用另一个代理时,子代理要么继承父代理的全部凭证,要么接收自己独立的密钥——没有一个项目实现了针对委派访问的范围缩小、深度限制或级联撤销。框架将“共享父状态”视为一种便利,而将“缩小子代理范围”视为可选步骤。而这个可选步骤,恰恰是没人会去写的。
这种失效之所以悄无声息,是因为审计追踪(audit trail)崩溃了。当研究员子代理调用工具时,追踪到的身份是父代理的。编排框架在记录日志时会将委派链扁平化,因为父代理拥有该会话,而子代理被视为父代理推理步骤的一部分。当事后分析询问“哪个代理发起了这次数据库写入”时,答案是工作流 ID。实际的身份——即以更窄的角色规范运行的研究员——从未作为一个独立主体(principal)被持久化。该操作看起来像是来自被授权执行此操作的规划者。批准该操作的系统批准了错误的对象。
上下文传播是一种隐式的特权授予
第一个需要重构的认知是:向子代理传播上下文并不是一个 UX 决策。它是一种特权授予。系统提示词的内容并非死板的文本——它们是持有这些内容的代理的操作权限。它们包含了模型已经学会调用的工具名称,包含了演示如何构建特权调用的 few-shot 轨迹,还包含了策略文本。当子代理对任务进行推理时,这些策略文本也会变成子代理的策略文本。
当规划者的系统提示词中包含“你可以访问具有以下签名的 customer_refund 工具”时,继承该提示词的子代理现在已经知道该工具的存在、它的功能以及如何调用它。工具层的凭证检查可能仍会拒绝调用,但模型已经被告知了一个本不该被告知的暴露面。在随后的任何步骤中,一个足够坚定的提示词注入(prompt injection)现在可以通过名称引用该暴露面。注入不需要去寻找工具,父代理的系统提示词已经教会了它。
这就是为什么在编排方案中流行的“ 上下文偏移”(context drift)框架淡化了这一失效的严重性。风险不在于子代理基于不一致的上下文进行推理,而在于子代理基于授予其超出角色规范权限的上下文进行推理。偏移是一个质量问题,而继承权限是一个安全问题。
框架默认设置本末倒置
看看主流框架的配置层面。CrewAI 按顺序传递任务输出,并接受一个可选的 context 参数,其中包括先前任务的输出;编排层假设你希望链路共享,你必须显式地缩小范围。AutoGen 默认在 GroupChat 中跨代理共享内存中的对话历史。LangGraph 提供了检查点(checkpointing)和显式的状态控制,这更好一些,但显式状态仍然表现为“流经什么”而不是“允许子代理看到什么”。Google 的 ADK 在被调用方暴露了一个 include_contents 开关,用于控制从根代理流向子代理的上下文量——这是一个真实的初级原语,但其默认设置非常慷慨。
各个框架的模式都是一样的:简单的路径是“共享一切”,安全的路径则要求你进行枚举。默认设置塑造行为,而这里的默认设置将行为引向了泄露。
这种反转说起来简单,交付起来却很难:子代理应该接收一个缩小的指令集,而不是父代理的副本。子代理的系统提示词应该在移交时根据能力规范(capability specification)构建——即这个子代理扮演什么角色、这个角色需要什么工具、什么策略文本约束该角色——并重新组装,而不是克隆后修剪。克隆和修剪会留下残留,而从零构建则不留痕迹。
基于能力的移交是遏制模式
遏制这种失效的模式由三部分组成。首先,父代理声明子代理的能力——角色、子代理需要的输入、允许子代理调用的工具、允许子代理查询的数据范围。其次,编排层根据该能力声明构建子代理的系统提示词,而不是来自父代理的提示词。第三,凭证层为子代理签发一个完全限定于这些能力的令牌(token),时效仅限于子任务期间。当子代理遇到未被委派的工具时,不会回退到父代理的凭证。
第三部分是团队往往会跳过的,因为它最具侵入性。它要求凭证层支持按子任务签发令牌,而大多数内部凭证层并不支持。快捷方式——将父代理的持有者令牌(bearer token)交给子代理——正是造成上述审计追踪崩溃的原因。令牌中嵌入了父代理的身份,因此子代理发起的每一次调用都被读取为父代理的调用。
这就是零信任代理文献中的“委派胜过冒充”(delegation beats impersonation)框架。当子代理冒充父代理时,子代理持有父代理的权限,审计追踪会丢失子代理的身份。而当子代理持有被委派的、限定范围的凭证时,审计追踪会记录“父代理委派给了子代理,子代理发起了这次调用,调用在委派范围内”——事后分析就可以将该行为归于实际运行它的代理。
