Skip to content

使用声明式权限规则控制智能体可以读取或写入哪些文件和目录。将规则列表传给 permissions=,智能体的内置文件系统工具会遵循这些规则。

INFO

权限要求 deepagents>=0.5.2

INFO

权限要求 deepagents>=1.9.1

权限仅适用于内置文件系统工具(lsread_fileglobgrepwrite_fileedit_filedelete)。访问文件系统的自定义工具和 MCP 工具不在覆盖范围内。权限也不适用于 沙箱后端,它们通过 execute 工具支持任意命令执行。

权限仅适用于内置文件系统工具(lsread_fileglobgrepwrite_fileedit_file)。访问文件系统的自定义工具和 MCP 工具不在覆盖范围内。权限也不适用于 沙箱后端,它们通过 execute 工具支持任意命令执行。

TIP

当你需要在内置文件系统工具上使用基于路径的允许/拒绝规则时,请使用 permissions。当你需要自定义验证逻辑(限流、审计日志、内容检查)或需要控制自定义工具时,请使用 后端策略钩子

基本用法

将一列表 FilesystemPermission 规则传给 create_deep_agent。规则按声明顺序评估。第一条匹配的规则生效。如果没有规则匹配,则允许该操作。

python
from deepagents import FilesystemPermission, create_deep_agent

# 只读智能体:拒绝所有写入
agent = create_deep_agent(
    model=model,
    backend=backend,
    permissions=[
        FilesystemPermission(
            operations=["write"],
            paths=["/**"],
            mode="deny",
        ),
    ],
)

将一列表 FilesystemPermission 规则传给 createDeepAgent。规则按声明顺序评估。第一条匹配的规则生效。如果没有规则匹配,则允许该操作。

ts
const agent = createDeepAgent({
  model,
  backend,
  permissions: [
    {
      operations: ["write"],
      paths: ["/**"],
      mode: "deny",
    },
  ],
});
if (!agent) throw new Error("basic: agent not created");

规则结构

每个 FilesystemPermission 有三个字段:

字段类型描述
operationslist["read" | "write"]此规则适用的操作。"read" 涵盖 lsread_fileglobgrep"write" 涵盖 write_fileedit_filedelete
pathslist[str]用于匹配文件路径的 Glob 模式(例如 ["/workspace/**"])。支持用于递归匹配的 ** 和用于交替的 {a,b}
mode"allow" | "deny" | "interrupt"是允许、拒绝还是暂停等待人工批准匹配的操作。默认为 "allow"。请参阅 暂停等待人工批准

规则使用先匹配优先评估:第一条其 operationspaths 匹配当前调用的规则决定结果。如果没有规则匹配,则调用是允许的(宽松默认值)。

每个 FilesystemPermission 有三个字段:

字段类型描述
operations("read" | "write")[]此规则适用的操作。"read" 涵盖 lsread_fileglobgrep"write" 涵盖 write_fileedit_file
pathsstring[]用于匹配文件路径的 Glob 模式(例如 ["/workspace/**"])。支持用于递归匹配的 ** 和用于交替的 {a,b}
mode"allow" | "deny"是允许还是拒绝匹配的操作。默认为 "allow"

规则使用先匹配优先评估:第一条其 operationspaths 匹配当前调用的规则决定结果。如果没有规则匹配,则调用是允许的(宽松默认值)。

路径必须是绝对的(以 / 开头),并且不能包含 ..~。无效路径会在构建智能体时抛出异常。

暂停等待人工批准

INFO

"interrupt" 模式要求 deepagents>=0.6.8

mode="interrupt" 设置为暂停等待人工批准,而不是直接允许或拒绝匹配的操作。当智能体在匹配 interrupt 模式规则的路径上调用内置写入工具(write_fileedit_filedelete)时,create_deep_agent 会引发人在回路中断而不是运行该工具,审查者可以批准、编辑或拒绝该调用。

python
from deepagents import FilesystemPermission, create_deep_agent
from langgraph.checkpoint.memory import InMemorySaver

agent = create_deep_agent(
    model=model,
    permissions=[
        # 在向 /secrets 下写入任何内容前暂停等待批准。
        FilesystemPermission(
            operations=["write"],
            paths=["/secrets/**"],
            mode="interrupt",
        ),
    ],
    # 中断模式需要检查点器来暂停和恢复。
    checkpointer=InMemorySaver(),
)

Interrupt 模式规则会自动接入智能体的人在回路中间件,并与你传入的任何 interrupt_on 合并,因此你可以像处理工具调用中断一样处理和恢复它们。有关恢复流程,请参阅 人在回路

INFO

删除目录是全部或全无的:delete 会检查目标和每个后代路径的 write 权限,如果其中任何一个被拒绝,就拒绝整个操作,而不是移除树的一部分。

TIP

用字面量的前导段锚定 interrupt 模式(例如 /secrets/**/projects/*/secrets/**)。批量工具(lsglobgrep 以及对目录的 delete)会在其搜索子树可能与规则锚定前缀重叠时触发中断,因此像 /**/secrets 这样完全没有锚定的模式会保守地过度触发。

示例

隔离到工作区目录

只允许 /workspace/ 下的读写,并拒绝所有其他操作:

python
agent = create_deep_agent(
    model=model,
    backend=backend,
    permissions=[
        FilesystemPermission(
            operations=["read", "write"],
            paths=["/workspace/**"],
            mode="allow",
        ),
        FilesystemPermission(
            operations=["read", "write"],
            paths=["/**"],
            mode="deny",
        ),
    ],
)

保护特定文件

python
agent = create_deep_agent(
    model=model,
    backend=backend,
    permissions=[
        FilesystemPermission(
            operations=["read", "write"],
            paths=["/workspace/.env", "/workspace/examples/**"],
            mode="deny",
        ),
        FilesystemPermission(
            operations=["read", "write"],
            paths=["/workspace/**"],
            mode="allow",
        ),
        FilesystemPermission(
            operations=["read", "write"],
            paths=["/**"],
            mode="deny",
        ),
    ],
)

只读记忆

允许智能体读取记忆文件,但阻止其修改。这对于只应由应用代码更新的组织级策略或共享知识库很有用。有关更多上下文,请参阅 只读与可写记忆

python
from deepagents.backends import CompositeBackend, StateBackend, StoreBackend

agent = create_deep_agent(
    model=model,
    backend=CompositeBackend(
        default=StateBackend(),
        routes={
            "/memories/": StoreBackend(
                namespace=lambda rt: (rt.server_info.user.identity,),
            ),
            "/policies/": StoreBackend(
                namespace=lambda rt: (rt.context.org_id,),
            ),
        },
    ),
    permissions=[
        FilesystemPermission(
            operations=["write"],
            paths=["/memories/**", "/policies/**"],
            mode="deny",
        ),
    ],
)

拒绝所有访问

阻止所有读写。这是一个限制性基线,你可以在其上叠加更具体的允许规则:

python
agent = create_deep_agent(
    model=model,
    backend=backend,
    permissions=[
        FilesystemPermission(
            operations=["read", "write"],
            paths=["/**"],
            mode="deny",
        ),
    ],
)

规则排序

由于先匹配优先,规则顺序很重要。将更具体的规则放在更宽泛的规则之前:

python
# 正确:拒绝 .env,允许 workspace,拒绝其他一切
correct_permissions = [
    FilesystemPermission(
        operations=["read", "write"],
        paths=["/workspace/.env"],
        mode="deny",
    ),
    FilesystemPermission(
        operations=["read", "write"],
        paths=["/workspace/**"],
        mode="allow",
    ),
    FilesystemPermission(
        operations=["read", "write"],
        paths=["/**"],
        mode="deny",
    ),
]

# 错误:/workspace/** 会先匹配到 .env,因此 deny 永远不会触发
incorrect_permissions = [
    FilesystemPermission(
        operations=["read", "write"],
        paths=["/workspace/**"],
        mode="allow",
    ),
    FilesystemPermission(
        operations=["read", "write"],
        paths=["/workspace/.env"],
        mode="deny",  # 永远不会执行到
    ),
    FilesystemPermission(
        operations=["read", "write"],
        paths=["/**"],
        mode="deny",
    ),
]

隔离到工作区目录

只允许 /workspace/ 下的读写,并拒绝所有其他操作:

ts
const agent = createDeepAgent({
  model,
  backend,
  permissions: [
    {
      operations: ["read", "write"],
      paths: ["/workspace/**"],
      mode: "allow",
    },
    {
      operations: ["read", "write"],
      paths: ["/**"],
      mode: "deny",
    },
  ],
});
if (!agent) throw new Error("isolate-workspace: agent not created");

保护特定文件

ts
const agent = createDeepAgent({
  model,
  backend,
  permissions: [
    {
      operations: ["read", "write"],
      paths: ["/workspace/.env", "/workspace/examples/**"],
      mode: "deny",
    },
    {
      operations: ["read", "write"],
      paths: ["/workspace/**"],
      mode: "allow",
    },
    {
      operations: ["read", "write"],
      paths: ["/**"],
      mode: "deny",
    },
  ],
});
if (!agent) throw new Error("protect-files: agent not created");

只读记忆

允许智能体读取记忆文件,但阻止其修改。这对于只应由应用代码更新的组织级策略或共享知识库很有用。有关更多上下文,请参阅 只读与可写记忆

ts
const store = new InMemoryStore();
const agent = createDeepAgent({
  model,
  backend: new CompositeBackend(new StateBackend(), {
    "/memories/": new StoreBackend({
      namespace: (rt) => [rt.serverInfo.user.identity],
    }),
    "/policies/": new StoreBackend({
      namespace: (rt) => [rt.context.orgId],
    }),
  }),
  permissions: [
    {
      operations: ["write"],
      paths: ["/memories/**", "/policies/**"],
      mode: "deny",
    },
  ],
  store,
});
if (!agent) throw new Error("read-only-memory: agent not created");

拒绝所有访问

阻止所有读写。这是一个限制性基线,你可以在其上叠加更具体的允许规则:

ts
const agent = createDeepAgent({
  model,
  backend,
  permissions: [
    {
      operations: ["read", "write"],
      paths: ["/**"],
      mode: "deny",
    },
  ],
});
if (!agent) throw new Error("deny-all: agent not created");

规则排序

由于先匹配优先,规则顺序很重要。将更具体的规则放在更宽泛的规则之前:

ts
const correctPermissions: FilesystemPermission[] = [
  { operations: ["read", "write"], paths: ["/workspace/.env"], mode: "deny" },
  {
    operations: ["read", "write"],
    paths: ["/workspace/**"],
    mode: "allow",
  },
  { operations: ["read", "write"], paths: ["/**"], mode: "deny" },
];

const incorrectPermissions: FilesystemPermission[] = [
  {
    operations: ["read", "write"],
    paths: ["/workspace/**"],
    mode: "allow",
  },
  {
    operations: ["read", "write"],
    paths: ["/workspace/.env"],
    mode: "deny",
  },
  { operations: ["read", "write"], paths: ["/**"], mode: "deny" },
];

子智能体权限

子智能体 默认继承父智能体的权限。要给子智能体不同的权限,请在其 spec 中设置 permissions 字段。这会完全替换父级的规则。

python
agent = create_deep_agent(
    model=model,
    backend=backend,
    permissions=[
        FilesystemPermission(
            operations=["read", "write"],
            paths=["/workspace/**"],
            mode="allow",
        ),
        FilesystemPermission(
            operations=["read", "write"],
            paths=["/**"],
            mode="deny",
        ),
    ],
    subagents=[
        {
            "name": "auditor",
            "description": "Read-only code reviewer",
            "system_prompt": "Review the code for issues.",
            "permissions": [
                FilesystemPermission(
                    operations=["write"],
                    paths=["/**"],
                    mode="deny",
                ),
                FilesystemPermission(
                    operations=["read"],
                    paths=["/workspace/**"],
                    mode="allow",
                ),
                FilesystemPermission(
                    operations=["read"],
                    paths=["/**"],
                    mode="deny",
                ),
            ],
        }
    ],
)

子智能体 默认继承父智能体的权限。要给子智能体不同的权限,请在其 spec 中设置 permissions 字段。这会完全替换父级的规则。

ts
const agent = createDeepAgent({
  model,
  backend,
  permissions: [
    {
      operations: ["read", "write"],
      paths: ["/workspace/**"],
      mode: "allow",
    },
    { operations: ["read", "write"], paths: ["/**"], mode: "deny" },
  ],
  subagents: [
    {
      name: "auditor",
      description: "Read-only code reviewer",
      systemPrompt: "Review the code for issues.",
      permissions: [
        { operations: ["write"], paths: ["/**"], mode: "deny" },
        { operations: ["read"], paths: ["/workspace/**"], mode: "allow" },
        { operations: ["read"], paths: ["/**"], mode: "deny" },
      ],
    },
  ],
});
if (!agent) throw new Error("subagent: agent not created");

要显式授予子智能体无限制访问权限,请设置 permissions: []。空数组会用无限制的规则覆盖父级规则。省略 permissions 则继承自父级。

复合后端

当使用 CompositeBackend 并以沙箱作为默认值时,每个权限路径都必须限定在已知路由前缀下。沙箱支持任意命令执行,因此仅靠基于路径的限制无法阻止通过 shell 命令访问文件系统。将权限限定到特定路由的 后端 可以避免这种冲突。

python
from deepagents.backends import CompositeBackend

composite = CompositeBackend(
    default=sandbox,
    routes={"/memories/": memories_backend},
)

# 可行:权限限定在 /memories/ 路由下
agent = create_deep_agent(
    model=model,
    backend=composite,
    permissions=[
        FilesystemPermission(
            operations=["write"],
            paths=["/memories/**"],
            mode="deny",
        ),
    ],
)

包含任何路由之外路径的权限会抛出 NotImplementedError

python
# 抛出 NotImplementedError:/workspace/** 命中沙箱默认后端
try:
    create_deep_agent(
        model=model,
        backend=composite,
        permissions=[
            FilesystemPermission(
                operations=["write"],
                paths=["/workspace/**"],
                mode="deny",
            ),
        ],
    )
except NotImplementedError:
    pass

# 同样抛出:/** 同时覆盖两个路由和默认后端
try:
    create_deep_agent(
        model=model,
        backend=composite,
        permissions=[
            FilesystemPermission(
                operations=["read"],
                paths=["/**"],
                mode="deny",
            ),
        ],
    )
except NotImplementedError:
    pass

当使用 CompositeBackend 并以沙箱作为默认值时,每个权限路径都必须限定在已知路由前缀下。沙箱支持任意命令执行,因此仅靠基于路径的限制无法阻止通过 shell 命令访问文件系统。将权限限定到特定路由的 后端 可以避免这种冲突。

ts
const sandbox = new StateBackend();
const memoriesBackend = new StateBackend();
const composite = new CompositeBackend(sandbox, {
  "/memories/": memoriesBackend,
});
const agent = createDeepAgent({
  model,
  backend: composite,
  permissions: [
    { operations: ["write"], paths: ["/memories/**"], mode: "deny" },
  ],
});
if (!agent) throw new Error("composite-backend: agent not created");

包含任何路由之外路径的权限会在构造时抛出异常:

ts
const sandbox = new StateBackend();
const memoriesBackend = new StateBackend();
const composite = new CompositeBackend(sandbox, {
  "/memories/": memoriesBackend,
});

createDeepAgent({
  model,
  backend: composite,
  permissions: [
    { operations: ["write"], paths: ["/workspace/**"], mode: "deny" },
  ],
});

createDeepAgent({
  model,
  backend: composite,
  permissions: [{ operations: ["read"], paths: ["/**"], mode: "deny" }],
});