这是一个?
现有功能优化
详细描述
@RockChinQ 想讨论一下当前 Skill 激活、只读资源访问与 Box 沙盒执行之间的能力边界。
背景
当前 AgentRunner/Local Agent 使用 activate Tool Call 做 Skill 的渐进式披露:模型先看到 Skill 名称与描述,匹配后调用 activate 获取完整 SKILL.md。
但目前正常调用链把 Skill 能力整体绑定到了沙盒:
activate 与 register_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
- 将
activate 与 register_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 想请你重点看下:
- 是否认同
activate 的语义应当只是“加载指令”,本身不要求 sandbox entitlement/backend?
- references 的只读访问更适合独立 Host resource API,还是复用现有
read 并支持 skill:// URI?
- Phase 1 是否可以继续让 Box Runtime 作为 SkillStore,只先解除 backend/admission 耦合?
- 长期是否值得把 SkillRepository 从 Box 中抽离,以支持
box.enabled=false?
- 首次执行阶段,短期继续挂载全部 bound Skills,还是直接设计按 revision 懒 materialize?
该方案不扩大 Agent 权限:激活只向上下文注入已授权 Skill 的说明,不能凭激活获得未授权工具;无 sandbox 时 exec/write/edit 仍不进入本次 run 的 tool resources。
这是一个?
现有功能优化
详细描述
@RockChinQ 想讨论一下当前 Skill 激活、只读资源访问与 Box 沙盒执行之间的能力边界。
背景
当前 AgentRunner/Local Agent 使用
activateTool Call 做 Skill 的渐进式披露:模型先看到 Skill 名称与描述,匹配后调用activate获取完整SKILL.md。但目前正常调用链把 Skill 能力整体绑定到了沙盒:
activate与register_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.mdinstructions;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。安全边界包括:
也可以考虑复用统一的
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
activate与register_skill拆成不同 loader,或改为 per-tool capability gate;activate只要求 Skill catalog/read capability;register_skill和 native execution tools 继续要求 sandbox;invoke_tool()先按工具名分支,只在需要执行/写入的分支调用require_workspace_sandbox();activate确实被本次 run 授权时注入“call activate”提示;这一阶段应主要是 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.md,仅使用 instructions希望确认的设计点
@RockChinQ 想请你重点看下:
activate的语义应当只是“加载指令”,本身不要求 sandbox entitlement/backend?read并支持skill://URI?box.enabled=false?该方案不扩大 Agent 权限:激活只向上下文注入已授权 Skill 的说明,不能凭激活获得未授权工具;无 sandbox 时 exec/write/edit 仍不进入本次 run 的 tool resources。