📄 一句话概括
审批与沙箱在配置里是两个独立插件、两套独立配置:一个回答【这次要不要问人】,一个回答【能给多大范围】——寿命不同的东西不能放同一层。
📝 本节和前面几节的关系
4.5.1 讲了单调的档位表,这一节拆开档位里的那一对:为什么是两层,而不是一个总开关。
一、实测:两个插件,两套配置
@deepseek-ai/dsh-user-approval——配置项是policy,值是ask或never。@deepseek-ai/dsh-sandbox-policy——配置项是mode,值来自环境变量或补丁;另带一项workspaceRoot。
它们分别注册、分别配置、分别可替换——档位表只是把它们配对,不是把它们合并。
顺带注意 workspaceRoot: process.cwd() 这一项:沙箱的范围就是工作区——2.2 讲的边界,在这里变成了权限参数。
二、两件事的寿命不一样
- 审批是一次性的:这次点头,不代表下次也点头。它是【调用前】那一关。
- 沙箱是持续性的:整个执行期间都有效。它是【调用中】那一关。
寿命不同的东西放同一层,就会互相拖累:要么审批被当成长期授权,要么一次点头就把沙箱放开了。
4.4 的六道关之所以要分开,根子就在这里。
三、分开之后的三个好处
- 可解释:被拦下来时能说清是哪一层拦的——是【没批准】,还是【范围不允许】。
- 可替换:想换个审批方式(比如批量预批准),换 approval 那一件就行,沙箱不用动。
- 可审计:审批记录与执行范围记录是两本账,事后对得上。
四、这对写工具的人意味着什么
- 工具不应该自己判断要不要问人——那是审批层的事。
- 工具也不应该自己限制能改哪些文件——那是沙箱层的事。
- 工具只该做一件事:老老实实地调用,把意图说清楚。
一句话:工具管做事,规则管边界;两件事各有各的家。
五、动手 Demo:两件事,两个插件
把两个问题、两个插件、两种寿命摆在一起:
layers = [
("要不要问人", "user-approval", "一次性的"),
("能给多大范围", "sandbox-policy", "持续性的"),
]
for a, b, c in layers:
print(" %-14s %-16s %s" % (a, b, c))
print()
print(" 配对成三档(permission-presets):")
print(" read-only -> read-only / ask")
print(" workspace-write -> workspace-write / ask")
print(" danger-full-access -> danger-full-access / never")
实跑输出:
--------------------------------------------------------------------
两件事,两个插件
--------------------------------------------------------------------
沙箱与审批,在配置里是两个独立插件、两套独立配置:
问题 插件 回答什么
-------------------------------------------------------
要不要问人 user-approval 这一次要不要人点头
能给多大范围 sandbox-policy 手上这把刀能砍多远
-------------------------------------------------------
它们被 permission-presets 配对成三档(上一则 Demo 的表)。
为什么必须分开?两件事的寿命不一样:
审批 一次性的:这次点头,不代表下次点头
沙箱 持续性的:整个执行期间都有效
寿命不同的东西放同一层,就会互相拖累——
要么审批被当成长期授权,要么沙箱被一次点头反复放行。
配对 ≠ 合并:档位表把它们拉在一起,但两件的注册与配置是分开的。
寿命不同是分开的根本原因——一次性的事和持续性的事,判断时机都不一样。
workspaceRoot: process.cwd() 把 2.2 的工作区接进了权限系统:沙箱范围就是工作区范围。
30 秒实验
- 在配置树里分别找到 user-approval 与 sandbox-policy,读它们的 config。
- 说出被拦时的两种可能原因:分别属于哪一层?
- 想一想:如果给工具自己加一个【先问问我】的判断,会带来什么问题?
常见误区
- 错误:审批和沙箱是一件事,合起来做成一个开关更省事。——纠正:寿命不同(一次性 vs 持续性),合起来必然互相拖累。
- 错误:工具应该自己判断该不该问人。——纠正:那是审批层的职责;工具只管把意图说清楚。
- 错误:沙箱范围是系统随便定的。——纠正:实测它取的是
process.cwd()——沙箱范围就是工作区范围。
自测三问(点开对答案)
1. 审批与沙箱各回答什么问题? —— 审批回答【这次要不要问人】(一次性);沙箱回答【能给多大范围】(持续性)。 2. 为什么它们必须分在两层? —— **寿命不同**:一次性的事与持续性的事判断时机不同,放一层会互相拖累。 3. 分开之后带来哪三个好处? —— 可解释(知道是哪层拦的)、可替换(换一件不动另一件)、可审计(两本账对得上)。- ☐ 下一节(4.6 PTC 与 Pipeline:为什么不能绕开这条管线)
相关笔记
- 为什么 Guard 要【单调】 —— 档位表就是这两层的配对
- Workspace 是 Agent 的【现实世界】 —— workspaceRoot 把边界接进权限
- Creative:让 Runtime 本身也成为可操作对象 —— 能改自身时,这两层就更关键
- 🐳 DeepSeek Harness · 索引