Skip to content

[Feature]: Decouple Skill activation and read-only resources from Box sandbox execution #2410

Description

@huanghuoguoguo

这是一个?

现有功能优化

详细描述

@RockChinQ 想讨论一下当前 Skill 激活、只读资源访问与 Box 沙盒执行之间的能力边界。

背景

当前 AgentRunner/Local Agent 使用 activate Tool Call 做 Skill 的渐进式披露:模型先看到 Skill 名称与描述,匹配后调用 activate 获取完整 SKILL.md

但目前正常调用链把 Skill 能力整体绑定到了沙盒:

  • activateregister_skill 位于同一个 SkillToolLoader,统一要求 Docker/nsjail/E2B backend 可用;
  • ToolManager 会在 Workspace sandbox 不可用时隐藏整个 Skill tool surface;
  • SkillToolLoader.invoke_tool() 在区分 activate / register_skill 前就调用 require_workspace_sandbox()
  • SkillManager 当前只从 Box Runtime 加载,box.enabled=false 时缓存为空。

然而 _invoke_activate_skill() 本身只做可见性校验、登记激活状态、持久化 Skill 名称并返回缓存中的 instructions,没有执行命令或创建沙盒。SDK 侧 BoxSkillStore 的 list/get/list files/read file 也不依赖具体 sandbox backend。

这会导致纯提示词 Skill,以及只有 Markdown references/templates 的 Skill,也必须部署并授权沙盒才能使用。

不建议按“包里是否只有 SKILL.md”直接分类

  • 只有 SKILL.md 的 Skill 也可能要求后续执行 shell/Python;
  • 包含 references/、模板或静态 artifact 的 Skill 可能完全不需要代码执行;
  • 因此更适合按操作能力分层,而不是按包内文件数量分层。

建议语义:激活、资源读取、执行三层分离

1. 激活:不依赖沙盒

activate(skill_name) 仅返回:

  • SKILL.md instructions;
  • 不可变的 skill revision/digest;
  • 可选的资源清单(路径、MIME、大小,不直接加载内容);
  • 当前可用能力,如 resources_readable / execution_available

无沙盒时不应宣称 /workspace/.skills/<name> 已挂载,也不应向模型暴露 Runtime 的 package_root

2. references/artifacts:通过独立只读资源 API 按需读取

模型需要额外材料时调用类似:

  • list_skill_resources(skill_name)
  • read_skill_resource(skill_name, path, revision)

由 SkillStore 直接读取,不创建 sandbox session。安全边界包括:

  • 仅允许当前 run 已授权且已激活的 Skill;
  • Workspace / placement generation / resource policy 校验保持不变;
  • 路径规范化、禁止 symlink/path traversal;
  • 单文件、单次运行累计大小和可读 MIME 限制;
  • 二进制 artifact 返回受控资源引用,不把大段 base64 注入模型上下文;
  • 后续读取与执行固定到激活时的 revision/digest,避免 TOCTOU。

也可以考虑复用统一的 skill://<name>/<path> resource URI,但建议不要因为读取一份 Markdown reference 就启动容器。

3. 执行/修改:首次真正需要时才要求沙盒

只有以下操作要求 Box sandbox admission/backend:

  • exec 执行 Skill 的脚本或安装依赖;
  • write / edit 修改 Skill 或 Workspace;
  • 某个工具明确需要真实文件系统路径。

此时再把激活时固定的 Skill revision materialize/mount 到 sandbox。

建议分阶段落地

Phase 1:解除 sandbox backend 依赖,但仍由 Box Runtime 保存 Skill

  • activateregister_skill 拆成不同 loader,或改为 per-tool capability gate;
  • activate 只要求 Skill catalog/read capability;
  • register_skill 和 native execution tools 继续要求 sandbox;
  • invoke_tool() 先按工具名分支,只在需要执行/写入的分支调用 require_workspace_sandbox()
  • BoxService 的 Skill list/get/read-only methods 只做 Workspace fencing,不复用 managed-sandbox admission;
  • Local Agent 只在 activate 确实被本次 run 授权时注入“call activate”提示;
  • 首次真正执行时,可以暂时沿用当前“挂载全部 pipeline-bound Skills”的策略。

这一阶段应主要是 Core 改动。Box Runtime 已经能在没有可用 backend 时提供 SkillStore RPC。

Phase 2:支持 box.enabled=false 时激活和读取 Skill

将 Skill catalog/package storage 抽象为独立 SkillRepository,Box 只负责执行时消费指定 Skill revision。需要考虑现有 data/box/skills/tenants/... 数据迁移,以及 OSS 本地文件、远程 Box、Cloud object/shared storage 的实现差异。

Phase 3:按 Skill 懒 materialize

如果挂载全部 bound Skills 成为实际成本,再优化成按已激活 Skill revision 懒 materialize。Docker 不能向运行中的容器动态增加 bind mount;#2271 已经验证 mount set 变化需要重建 session。因此这里更适合将不可变 package snapshot 按需复制/materialize 到 Workspace,或显式重建 session,而不是“读取 reference 时动态加 mount”。

期望行为矩阵

Skill 类型/操作 无 sandbox 有 sandbox
只有 SKILL.md,仅使用 instructions 激活并完整使用 激活并完整使用
包含 Markdown references/templates 激活 + 按需只读 激活 + 按需只读
包含图片/PDF 等静态 artifact 返回受控资源引用 返回引用,必要时 materialize
包含 scripts/dependencies 可激活、可读说明;执行工具不可用 首次执行时 mount/materialize 并运行

希望确认的设计点

@RockChinQ 想请你重点看下:

  1. 是否认同 activate 的语义应当只是“加载指令”,本身不要求 sandbox entitlement/backend?
  2. references 的只读访问更适合独立 Host resource API,还是复用现有 read 并支持 skill:// URI?
  3. Phase 1 是否可以继续让 Box Runtime 作为 SkillStore,只先解除 backend/admission 耦合?
  4. 长期是否值得把 SkillRepository 从 Box 中抽离,以支持 box.enabled=false
  5. 首次执行阶段,短期继续挂载全部 bound Skills,还是直接设计按 revision 懒 materialize?

该方案不扩大 Agent 权限:激活只向上下文注入已授权 Skill 的说明,不能凭激活获得未授权工具;无 sandbox 时 exec/write/edit 仍不进入本次 run 的 tool resources。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

RoadmapIn roadmapeh: Improveenhance: 现有功能的改进 / improve current featuresm: Tools工具(ToolUse、内容函数)相关 / Function Calling or tools managementpd: Need designpending: 需要进一步设计的功能 / wait for us to design

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions