ag2-shell-tool

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Shell tools

Shell 工具

When to use

适用场景

Two distinct tools, both named "shell" — pick deliberately:
NeedUseWhy
Works with any model provider; full control over what runs and where
SandboxShellTool
Client-side
subprocess
(via
LocalEnvironment
). You own the sandbox.
Provider-managed sandbox (container, network policy) on OpenAI Responses
ShellTool
Server-side execution. No local subprocess.
SandboxShellTool
is the workhorse
. Reach for it unless you specifically need provider-managed isolation and you're on OpenAI Responses.
有两款名称均为"shell"的不同工具,请按需选择:
需求使用工具原因
支持所有模型提供商;完全控制运行内容和运行位置
SandboxShellTool
基于客户端
subprocess
(通过
LocalEnvironment
)。你拥有沙箱的控制权。
OpenAI Responses 提供的提供商托管沙箱(容器、网络策略)
ShellTool
服务器端执行。无需本地子进程。
SandboxShellTool
是主力工具
。除非你明确需要提供商托管的隔离环境且使用OpenAI Responses,否则优先选择它。

60-second recipe —
SandboxShellTool

60秒快速上手 —
SandboxShellTool

python
from ag2 import Agent
from ag2.config import AnthropicConfig
from ag2.tools import SandboxShellTool

agent = Agent(
    "coder",
    "You write and run Python code.",
    config=AnthropicConfig(model="claude-sonnet-4-6"),
    tools=[SandboxShellTool()],
)

reply = await agent.ask("Write a hello world script and run it.")
print(await reply.content())
SandboxShellTool
is provider-agnostic — swap
AnthropicConfig
for
OpenAIConfig(model="gpt-4.1")
,
GeminiConfig(model="gemini-2.5-pro")
, etc. Make sure you've installed the matching
ag2[<provider>]
extra and set the matching env var (see
ag2-quickstart
→ Prerequisites).
With no arguments,
SandboxShellTool
defaults to a
LocalEnvironment()
that creates a temporary working directory (prefixed
ag2_sandbox_
) and cleans it up when the process exits. Pass a
LocalEnvironment
with a path to use a specific directory:
python
from pathlib import Path
from ag2.tools import LocalEnvironment, SandboxShellTool

SandboxShellTool(LocalEnvironment("/tmp/my_project"))
SandboxShellTool(LocalEnvironment(Path("/tmp/my_project")))
When a path is given, the directory is created if it does not exist and is not deleted on exit. Inspect the resolved working directory via
tool.workdir
.
python
from ag2 import Agent
from ag2.config import AnthropicConfig
from ag2.tools import SandboxShellTool

agent = Agent(
    "coder",
    "You write and run Python code.",
    config=AnthropicConfig(model="claude-sonnet-4-6"),
    tools=[SandboxShellTool()],
)

reply = await agent.ask("Write a hello world script and run it.")
print(await reply.content())
SandboxShellTool
与提供商无关——你可以将
AnthropicConfig
替换为
OpenAIConfig(model="gpt-4.1")
GeminiConfig(model="gemini-2.5-pro")
等。请确保已安装对应的
ag2[<provider>]
扩展包,并设置好匹配的环境变量(详见
ag2-quickstart
→ 前提条件)。
若不传入参数,
SandboxShellTool
默认使用
LocalEnvironment()
,会创建一个临时工作目录(前缀为
ag2_sandbox_
),并在进程退出时自动清理。你可以传入指定路径的
LocalEnvironment
来使用特定目录:
python
from pathlib import Path
from ag2.tools import LocalEnvironment, SandboxShellTool

SandboxShellTool(LocalEnvironment("/tmp/my_project"))
SandboxShellTool(LocalEnvironment(Path("/tmp/my_project")))
当指定路径时,若目录不存在则会自动创建,且进程退出时不会被删除。你可以通过
tool.workdir
查看解析后的工作目录。

Sandboxing (
LocalEnvironment
+ tool-level filters)

沙箱机制(
LocalEnvironment
+ 工具级过滤)

For anything beyond a throwaway demo, lock down what the agent can do. The environment (
LocalEnvironment
) decides where commands run and carries backend config (
path
,
timeout
,
max_output
,
env_vars
); the tool (
SandboxShellTool
) decides the agent-facing policy (
allowed
/
blocked
/
ignore
/
readonly
). Filtering is applied in this order on every call:
  1. allowed
    — if set, the command must match at least one prefix. In this restricted mode, shell operators (
    >
    ,
    >>
    ,
    |
    ,
    ;
    ,
    &&
    ,
    ||
    ,
    `
    ,
    $(
    ) are also rejected.
  2. blocked
    — if set, the command must not match any prefix. Best-effort only (head-command prefix match; chaining can bypass it).
  3. ignore
    — literal path tokens in the command are checked against gitignore-style patterns; matches return
    "Access denied: <path>"
    .
  4. Execute via the environment's
    subprocess
    .
python
from ag2.tools import LocalEnvironment, SandboxShellTool

sh = SandboxShellTool(
    LocalEnvironment(
        path="/tmp/my_project",
        timeout=30,
        max_output=50_000,
    ),
    allowed=["python", "uv run", "git"],
    blocked=["rm -rf", "curl", "wget"],
    ignore=["**/.env", "*.key", "secrets/**"],
)
除了一次性演示场景,都要限制Agent的操作权限。环境
LocalEnvironment
)决定命令的运行位置和后端配置(
path
timeout
max_output
env_vars
);工具
SandboxShellTool
)决定面向Agent的策略(
allowed
/
blocked
/
ignore
/
readonly
)。每次调用时会按以下顺序应用过滤规则:
  1. allowed
    — 若设置,命令必须匹配至少一个前缀。在此受限模式下,shell运算符(
    >
    >>
    |
    ;
    &&
    ||
    `
    $(
    )也会被拒绝。
  2. blocked
    — 若设置,命令不得匹配任何前缀。仅作尽力而为的限制(仅匹配头部命令前缀;命令链可能绕过该限制)。
  3. ignore
    — 命令中的字面路径会与gitignore风格的模式进行匹配;匹配到则返回
    "Access denied: <path>"
  4. 通过环境的
    subprocess
    执行命令。
python
from ag2.tools import LocalEnvironment, SandboxShellTool

sh = SandboxShellTool(
    LocalEnvironment(
        path="/tmp/my_project",
        timeout=30,
        max_output=50_000,
    ),
    allowed=["python", "uv run", "git"],
    blocked=["rm -rf", "curl", "wget"],
    ignore=["**/.env", "*.key", "secrets/**"],
)

Read-only mode

只读模式

For inspection-only access (
cat
,
head
,
tail
,
ls
,
grep
,
find
,
git log
,
git diff
,
git status
, …):
python
from ag2.tools import LocalEnvironment, SandboxShellTool

sh = SandboxShellTool(LocalEnvironment(path="/my/codebase"), readonly=True)
Pass an explicit
allowed=[...]
to override the built-in read-only allowlist.
仅用于查看操作(
cat
head
tail
ls
grep
find
git log
git diff
git status
等):
python
from ag2.tools import LocalEnvironment, SandboxShellTool

sh = SandboxShellTool(LocalEnvironment(path="/my/codebase"), readonly=True)
传入显式的
allowed=[...]
可以覆盖内置的只读允许列表。

Parameter reference

参数参考

LocalEnvironment
(the environment — where and how commands run):
ParameterDefaultDescription
path
None
Working dir.
None
→ temp dir (prefix
ag2_sandbox_
), deleted on exit
cleanup
None
None
→ auto (
True
when
path=None
,
False
otherwise). Deletes
path
on close
timeout
60
Per-command timeout in seconds (returns
"Command timed out after Ns"
with exit code 124)
max_output
100_000
Max characters returned (truncated output is suffixed
[truncated: …]
)
env_vars
None
Extra env vars merged into each command
SandboxShellTool
(the tool — agent-facing command policy):
ParameterDefaultDescription
environment
None
The backend.
None
LocalEnvironment()
(local subprocess, temp dir)
allowed
None
Whitelist of command prefixes.
None
→ all commands allowed
blocked
None
Blacklist of command prefixes (best-effort, not a security boundary)
ignore
None
Gitignore-style path patterns; matches block the command
readonly
False
When
True
and
allowed
unset, restricts to a built-in read-only list
LocalEnvironment
(环境——命令的运行位置和方式):
参数默认值描述
path
None
工作目录。
None
→ 临时目录(前缀
ag2_sandbox_
),进程退出时自动删除
cleanup
None
None
→ 自动模式(
path=None
时为
True
,否则为
False
)。关闭时删除
path
目录
timeout
60
单命令超时时间(秒),超时后返回
"Command timed out after Ns"
,退出码为124
max_output
100_000
返回内容的最大字符数(截断后的内容会添加后缀
[truncated: …]
env_vars
None
合并到每个命令中的额外环境变量
SandboxShellTool
(工具——面向Agent的命令策略):
参数默认值描述
environment
None
后端环境。
None
LocalEnvironment()
(本地子进程,临时目录)
allowed
None
命令前缀白名单。
None
→ 允许所有命令
blocked
None
命令前缀黑名单(仅作尽力而为的限制,不构成安全边界)
ignore
None
Gitignore风格的路径模式;匹配到则阻止命令执行
readonly
False
True
且未设置
allowed
时,限制为内置的只读命令列表

Stateful multi-turn workspaces

有状态多轮对话工作区

Files persist in
workdir
across
ask()
calls, so the agent can build on prior work:
python
from ag2.tools import LocalEnvironment, SandboxShellTool

sh = SandboxShellTool(LocalEnvironment(path="/tmp/counter_demo"))
agent = Agent("coder", "You manage files.", config=config, tools=[sh])

reply1 = await agent.ask("Create counter.txt with value 0")
reply2 = await reply1.ask("Increment the counter by 1")
reply3 = await reply2.ask("Read the counter and tell me the value")
文件会在
workdir
中跨
ask()
调用持久化,因此Agent可以基于之前的工作继续操作:
python
from ag2.tools import LocalEnvironment, SandboxShellTool

sh = SandboxShellTool(LocalEnvironment(path="/tmp/counter_demo"))
agent = Agent("coder", "You manage files.", config=config, tools=[sh])

reply1 = await agent.ask("Create counter.txt with value 0")
reply2 = await reply1.ask("Increment the counter by 1")
reply3 = await reply2.ask("Read the counter and tell me the value")

Provider-native
ShellTool
(OpenAI Responses only)

提供商原生
ShellTool
(仅OpenAI Responses可用)

ShellTool
is a provider-executed capability flag. Only the OpenAI Responses API runs shell server-side. Anthropic's
bash
tool is client-side and is rejected with
UnsupportedToolError
— use
SandboxShellTool
there. Gemini is also unsupported.
python
from ag2.config import OpenAIResponsesConfig
from ag2.tools import ShellTool

agent = Agent("devops", config=OpenAIResponsesConfig(model="gpt-4.1"), tools=[ShellTool()])
OpenAI lets you configure the execution environment:
python
from ag2.config import OpenAIResponsesConfig
from ag2.tools import ContainerAutoEnvironment, NetworkPolicy, ShellTool

agent = Agent(
    "devops",
    config=OpenAIResponsesConfig(model="gpt-4.1"),
    tools=[
        ShellTool(
            environment=ContainerAutoEnvironment(
                network_policy=NetworkPolicy(allowed_domains=["pypi.org"]),
            ),
        ),
    ],
)
Environment options (OpenAI-only):
EnvironmentDescription
ContainerAutoEnvironment
Provider-managed container with optional
NetworkPolicy
ContainerReferenceEnvironment
Reference an existing container by ID
ShellTool
是提供商执行的功能标识。仅OpenAI Responses API支持服务器端shell执行。Anthropic的
bash
工具是客户端实现,使用时会抛出
UnsupportedToolError
——请改用
SandboxShellTool
。Gemini同样不支持。
python
from ag2.config import OpenAIResponsesConfig
from ag2.tools import ShellTool

agent = Agent("devops", config=OpenAIResponsesConfig(model="gpt-4.1"), tools=[ShellTool()])
OpenAI允许你配置执行环境:
python
from ag2.config import OpenAIResponsesConfig
from ag2.tools import ContainerAutoEnvironment, NetworkPolicy, ShellTool

agent = Agent(
    "devops",
    config=OpenAIResponsesConfig(model="gpt-4.1"),
    tools=[
        ShellTool(
            environment=ContainerAutoEnvironment(
                network_policy=NetworkPolicy(allowed_domains=["pypi.org"]),
            ),
        ),
    ],
)
环境选项(仅OpenAI可用):
环境描述
ContainerAutoEnvironment
提供商托管的容器,可配置
NetworkPolicy
ContainerReferenceEnvironment
通过ID引用现有容器

SandboxShellTool
vs
ShellTool

SandboxShellTool
vs
ShellTool

SandboxShellTool
ShellTool
ExecutionClient-side
subprocess
Provider-side container
Provider supportAny providerOpenAI Responses only
Environment controlFull (
allowed
,
blocked
,
ignore
,
readonly
, …)
Limited (provider-dependent)
Local FS accessYes (you choose what's exposed)No
Network controlVia
blocked
/
allowed
patterns
OpenAI:
NetworkPolicy
Import
from ag2.tools import SandboxShellTool, LocalEnvironment
from ag2.tools import ShellTool
SandboxShellTool
ShellTool
执行方式客户端
subprocess
提供商端容器
提供商支持所有提供商仅OpenAI Responses
环境控制完全可控(
allowed
blocked
ignore
readonly
等)
有限控制(取决于提供商)
本地文件系统访问是(你选择暴露的内容)
网络控制通过
blocked
/
allowed
模式
OpenAI:
NetworkPolicy
导入方式
from ag2.tools import SandboxShellTool, LocalEnvironment
from ag2.tools import ShellTool

Going deeper

深入学习

  • website/docs/user-guide/tools/local_shell.mdx
    — full
    SandboxShellTool
    /
    LocalEnvironment
    reference, command-filtering semantics.
  • website/docs/user-guide/tools/builtin_tools.mdx#shell
    — provider-native
    ShellTool
    setup and environment configs.
  • For human-approval gating before each shell call, layer
    approval_required()
    middleware (see
    ag2-hitl
    ).
  • website/docs/user-guide/tools/local_shell.mdx
    SandboxShellTool
    /
    LocalEnvironment
    完整参考,命令过滤语义说明。
  • website/docs/user-guide/tools/builtin_tools.mdx#shell
    — 提供商原生
    ShellTool
    的设置和环境配置说明。
  • 若要在每次shell调用前需要人工审批,可添加
    approval_required()
    中间件(详见
    ag2-hitl
    )。

Common pitfalls

常见陷阱

  • Forgetting sandboxing in production
    SandboxShellTool()
    with no filters runs anything anywhere with a 60s timeout. Set
    allowed
    ,
    blocked
    , or
    readonly
    for any non-trivial use.
  • ignore
    only checks literal paths in the command string
    — variable substitution, command substitution (
    `cat secrets.key`
    ), and dynamic glob expansion are not inspected. Layer in
    blocked=["cat", "less"]
    if you also want to block readers.
  • blocked
    is best-effort, not a security boundary
    — it only matches the head command's prefix, so chaining (
    echo x; rm -rf ~
    ) bypasses
    blocked=["rm"]
    . Use
    allowed
    /
    readonly
    or an isolated container backend for real isolation.
  • Trying to use
    ShellTool
    on Anthropic or Gemini
    — unsupported, will raise
    UnsupportedToolError
    . Use
    SandboxShellTool
    instead.
  • Using a hardcoded path that another process is also touching — multiple agents sharing
    /tmp/my_project
    will race. Use
    tempfile.mkdtemp(prefix="...")
    for parallel runs.
  • Expecting
    ShellTool
    to access local files
    — it doesn't; it runs in the provider's container. Use
    SandboxShellTool
    for anything on your filesystem.
  • Trusting the LLM with shell access — even sandboxed, write
    prompt
    s that scope what's allowed and consider pairing with
    approval_required()
    for destructive operations.
  • 生产环境中忘记配置沙箱 — 未设置过滤规则的
    SandboxShellTool()
    会允许在任意位置执行任意命令,超时时间为60秒。对于非 trivial 的使用场景,务必设置
    allowed
    blocked
    readonly
  • ignore
    仅检查命令字符串中的字面路径
    — 变量替换、命令替换(
    `cat secrets.key`
    )和动态通配符扩展不会被检查。如果你还想阻止读取操作,可以添加
    blocked=["cat", "less"]
  • blocked
    仅作尽力而为的限制,不构成安全边界
    — 它仅匹配头部命令的前缀,因此命令链(
    echo x; rm -rf ~
    )可以绕过
    blocked=["rm"]
    。如需真正的隔离,请使用
    allowed
    /
    readonly
    或隔离容器后端。
  • 尝试在Anthropic或Gemini上使用
    ShellTool
    — 不支持,会抛出
    UnsupportedToolError
    。请改用
    SandboxShellTool
  • 使用其他进程也在访问的硬编码路径 — 多个Agent共享
    /tmp/my_project
    会导致竞争。并行运行时请使用
    tempfile.mkdtemp(prefix="...")
    创建临时目录。
  • 期望
    ShellTool
    访问本地文件
    — 它无法访问本地文件,因为它运行在提供商的容器中。如需访问本地文件系统,请使用
    SandboxShellTool
  • 信任LLM的shell访问权限 — 即使有沙箱保护,也要编写明确限定允许操作范围的
    prompt
    ,对于破坏性操作,可考虑搭配
    approval_required()
    中间件。