shell 工具赋予模型在完整终端环境中工作的能力。我们支持用于本地执行的 shell,以及通过 Responses API 进行的托管执行。
shell 工具允许模型通过以下任一方式运行命令:
- 由 OpenAI 管理的托管 shell 容器。
- A local shell runtime 由您自行托管和执行的环境。
Shell 可通过 Responses API。它无法通过 Chat Completions API 使用。
运行任意 shell 命令可能存在危险。请始终在沙盒中执行,尽可能应用允许列表或拒绝列表,并记录工具活动以供审计。
托管 shell 快速入门
托管 shell 是一种原生且简化的选项,适用于需要更丰富、确定性处理的任务,从运行计算到处理多媒体。
使用 container_auto 当您希望 OpenAI 为请求配置和管理容器时。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
curl -L 'https://api.openai.com/v1/responses' \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-d '{
"model": "gpt-5.5",
"tools": [
{ "type": "shell", "environment": { "type": "container_auto" } }
],
"input": [
{
"type": "message",
"role": "user",
"content": [
{ "type": "input_text", "text": "Execute: ls -lah /mnt/data && python --version && node --version" }
]
}
],
"tool_choice": "auto"
}'托管运行环境详情
- 运行环境目前基于
Debian 12并可能随时间推移而改变。 - 默认工作目录为
/mnt/data. /mnt/data始终存在,并且是用户可下载构件的受支持路径。- 托管 shell 不支持交互式 TTY 会话。
- 托管 shell 命令不使用
sudo. - 您可以在工作流需要时在容器内运行服务。
当前预装的语言包括:
- Python
3.11 - Node.js
22.16 - Java
17.0 - PHP
8.2 - Ruby
3.1 - Go
1.23
跨请求复用容器
如果您需要用于迭代工作流的长期运行环境,请创建一个容器,然后在后续的 Responses API 调用中引用它。
1. 创建容器
1
2
3
4
5
6
7
8
curl -L 'https://api.openai.com/v1/containers' \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-d '{
"name": "analysis-container",
"memory_limit": "1g",
"expires_after": { "anchor": "last_active_at", "minutes": 20 }
}'2. 在 Responses 中引用该容器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
curl -L 'https://api.openai.com/v1/responses' \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-d '{
"model": "gpt-5.5",
"tools": [
{
"type": "shell",
"environment": {
"type": "container_reference",
"container_id": "cntr_08f3d96c87a585390069118b594f7481a088b16cda7d9415fe"
}
}
],
"input": "List files in the container and show disk usage."
}'附加技能
技能是可复用、版本化的捆绑包,您可以将其挂载到托管 shell 环境中。这将定义可用的技能,在执行 shell 时,模型会决定是否调用它们。
使用 技能指南 以获取上传和版本控制的详细信息。
1
2
3
4
5
6
7
8
9
10
curl -L 'https://api.openai.com/v1/containers' \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-d '{
"name": "skill-container",
"skills": [
{ "type": "skill_reference", "skill_id": "skill_4db6f1a2c9e73508b41f9da06e2c7b5f" },
{ "type": "skill_reference", "skill_id": "openai-spreadsheets", "version": "latest" }
]
}'网络访问
默认情况下,托管容器没有出站网络访问权限。
To enable it:
- 管理员必须在控制面板中配置您的组织允许列表。
- 您必须在请求中的容器环境上显式设置
network_policy结合网络允许列表的 Shell 工具
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
curl -L 'https://api.openai.com/v1/responses' \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-5.5",
"tool_choice": "required",
"tools": [
{
"type": "shell",
"environment": {
"type": "container_auto",
"network_policy": {
"type": "allowlist",
"allowed_domains": ["pypi.org", "files.pythonhosted.org", "github.com"]
}
}
}
],
"input": [
{
"role": "user",
"content": "In the container, pip install httpx beautifulsoup4, fetch release pages, and write /mnt/data/release_digest.md."
}
]
}'网络策略优先级 风险与安全 部分。
当存在多个控制措施时:
您的组织允许列表定义了完整的
- 请求级别的
allowed_domains. - 会进一步限制访问。
network_policy如果 - 包含超出您组织允许列表范围的域名,请求将会失败。
allowed_domains数据保留和容器生命周期
由托管 shell 和代码解释器使用的托管容器,可以在容器处于活动状态时向容器文件系统(由临时块存储提供支持)写入临时应用程序状态。当容器到期或被显式删除时,容器数据将被删除。
有关数据控制的更多详细信息,请参阅
下载构件 ZDR 和数据驻留.
托管 shell 可以生成可下载的文件。请使用与代码解释器相同的容器/文件 API 来检索写入在
下的构件 /mnt/data.
额外数据控制
如果您希望在托管生命周期内保持内容和文件是临时的,您可以在请求中内联文件,并在容器中挂载内联技能。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
INLINE_ZIP=$(base64 -i ./csv_insights.zip)
REPORT_CSV=$(base64 -i ./report.csv)
CONTAINER_ID=$(
curl -sL 'https://api.openai.com/v1/containers' \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-d '{
"name": "inline-skill-container",
"skills": [
{
"type": "inline",
"name": "csv-insights",
"description": "Summarize CSV files and produce a markdown report.",
"source": {
"type": "base64",
"media_type": "application/zip",
"data": "'"$INLINE_ZIP"'"
}
}
]
}' | jq -r '.id'
)
curl -L 'https://api.openai.com/v1/responses' \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-d '{
"model": "gpt-5.5",
"tools": [
{
"type": "shell",
"environment": {
"type": "container_reference",
"container_id": "'"$CONTAINER_ID"'"
}
}
],
"input": [
{
"role": "user",
"content": [
{
"type": "input_file",
"filename": "report.csv",
"file_data": "data:text/csv;base64,'"${REPORT_CSV}"'"
},
{
"type": "input_text",
"text": "Use the csv-insights skill to summarize report.csv."
}
]
}
]
}'对于后续请求,请传入相同的 container_id with container_reference。在容器处于活动状态期间,挂载的技能和现有容器文件仍然可用。
主动删除容器
您可以在工作完成后显式删除容器,而无需等待非活动状态超时。
curl -L -X DELETE 'https://api.openai.com/v1/containers/container_id' \
-H "Authorization: Bearer $OPENAI_API_KEY"域名密钥
使用 domain_secrets 当您的列表中的某个域名 allowed_domains 需要私有授权标头时,例如 Authorization: Bearer <token>.
每个密钥条目包含:
- 目标域名
- 密钥友好名称
- 密钥值
运行时:
- 模型和运行时会看到占位符名称(例如,
$API_KEY)而不是原始凭据。 - 授权转换 Sidecar 仅将原始密钥值应用于已批准的目标地址。
- 原始密钥值不会存储在 API 服务器上,也不会出现在模型可见的上下文中。
这允许助手调用受保护的服务,同时降低泄露风险。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
curl -L 'https://api.openai.com/v1/responses' \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-5.5",
"input": [
{
"role": "user",
"content": "Use curl to call https://httpbin.org/headers with header Authorization: Bearer $API_KEY. Tell me what you see in the final text response."
}
],
"tool_choice": "required",
"tools": [
{
"type": "shell",
"environment": {
"type": "container_auto",
"network_policy": {
"type": "allowlist",
"allowed_domains": ["httpbin.org"],
"domain_secrets": [
{
"domain": "httpbin.org",
"name": "API_KEY",
"value": "debug-secret-123"
}
]
}
}
}
]
}'多轮工作流
要在相同的托管环境中继续工作,请复用容器并传递 previous_response_id.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
curl -L 'https://api.openai.com/v1/responses' \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-d '{
"model": "gpt-5.5",
"previous_response_id": "resp_2a8e5c9174d63b0f18a4c572de9f64a1b3c76d508e12f9ab47",
"tools": [
{
"type": "shell",
"environment": {
"type": "container_reference",
"container_id": "cntr_f19c2b51e4a06793d82d54a7be0fc9154d3361ab28ce7f6041"
}
}
],
"input": "Read /mnt/data/top5.csv and report the top candidate."
}'响应中的 Shell 输出
托管 Shell 和本地 Shell 使用相同的输出项类型。Shell 运行由成对的输出项表示:
shell_call:模型请求的命令。shell_call_output:命令输出和退出结果。
1
2
3
4
5
6
7
8
9
10
{
"type": "shell_call",
"call_id": "call_9d14ac6f2b73485e91c0f4da6e1b27c8",
"action": {
"commands": ["ls -l"],
"timeout_ms": 120000,
"max_output_length": 4096
},
"status": "in_progress"
}本地 Shell 模式
您还可以通过执行 shell_call 操作并将结果 shell_call_output 发送回模型,在您自己的本地运行环境中运行 Shell 命令。
当您需要对执行环境、文件系统访问或现有内部工具进行完全控制时,请使用此模式。
1
2
3
4
5
6
7
8
9
curl -L 'https://api.openai.com/v1/responses' \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-d '{
"model": "gpt-5.5",
"instructions": "The local bash shell environment is on Mac.",
"input": "find me the largest pdf file in ~/Documents",
"tools": [{ "type": "shell", "environment": { "type": "local" } }]
}'当您收到 shell_call 输出项:
- 在您的运行时环境中执行请求的命令。
- 捕获
stdout,stderr,以及结果。 - 将结果返回为
shell_call_outputin the next request.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@dataclass
class CmdResult:
stdout: str
stderr: str
exit_code: int | None
timed_out: bool
class ShellExecutor:
def __init__(self, default_timeout: float = 60):
self.default_timeout = default_timeout
def run(self, cmd: str, timeout: float | None = None) -> CmdResult:
t = timeout or self.default_timeout
p = subprocess.Popen(
cmd,
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
)
try:
out, err = p.communicate(timeout=t)
return CmdResult(out, err, p.returncode, False)
except subprocess.TimeoutExpired:
p.kill()
out, err = p.communicate()
return CmdResult(out, err, p.returncode, True)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{
"type": "shell_call_output",
"call_id": "call_3ef1b8c79a4d6520f9e3ab7d41c68f25",
"max_output_length": 4096,
"output": [
{
"stdout": "...",
"stderr": "...",
"outcome": {
"type": "exit",
"exit_code": 0
}
},
{
"stdout": "...",
"stderr": "...",
"outcome": {
"type": "timeout"
}
}
]
}有关旧版迁移的详细信息,请参阅旧版 本地 Shell 指南.
配合 Agents SDK 使用本地 Shell
如果您正在使用 Apps SDK,你可以将自己的 shell 执行器实现传递给 shell 工具助手。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import {
Agent,
run,
withTrace,
Shell,
ShellAction,
ShellResult,
shellTool,
} from "@openai/agents";
class LocalShell implements Shell {
async run(action: ShellAction): Promise<ShellResult> {
return {
output: [
{
stdout: "Shell is not available. Needs to be implemented first.",
stderr: "",
outcome: {
type: "exit",
exitCode: 1,
},
},
],
maxOutputLength: action.maxOutputLength,
};
}
}
const shell = new LocalShell();
const agent = new Agent({
name: "Shell Assistant",
model: "gpt-5.5",
instructions:
"You can execute shell commands to inspect the repository. Keep responses concise and include command output when helpful.",
tools: [
shellTool({
shell,
needsApproval: true,
onApproval: async (_ctx, _approvalItem) => {
return { approve: true };
},
}),
],
});
await withTrace("shell-tool-example", async () => {
const result = await run(agent, "Show the Node.js version.");
console.log(`\nFinal response:\n${result.finalOutput}`);
});您可以在 SDK 代码库中找到可运行的示例。
Agents SDK 中 Shell 工具的 TypeScript 示例。
Agents SDK 中 Shell 工具的 Python 示例。
处理常见错误
- 如果命令超出了您的执行超时时间,请返回超时结果并包含已捕获的部分输出。
- If
max_output_length存在于shell_call,将其包含在shell_call_output. - 不要依赖交互式命令;Shell 工具的执行应当是非交互式的。
- 保留非零退出码的输出,以便模型能够推理恢复步骤。
风险与安全
在 Containers API 中启用网络访问是一项强大的功能,但也会带来重大的安全和数据治理风险。默认情况下,不启用网络访问。启用后,出站访问仍应严格限制在任务所需的受信任域名范围内。
启用网络的容器可以与第三方服务和包注册表进行交互。这会产生数据泄露、由提示注入驱动的工具滥用,以及意外越界访问等风险。当策略过于宽泛、静态或执行不一致时,这些风险会进一步增加。
了解网络获取内容带来的提示注入风险
任何通过网络获取的外部内容都可能包含旨在操纵模型行为的隐藏指令。请将不受信任的网络内容视为具有潜在敌意,并在执行可能修改数据或系统的操作时格外谨慎。
仅连接到受信任的目的地
仅允许您信任并积极维护的域名。对代理到其他服务的中介和聚合器保持谨慎,并在将它们添加到允许的域名列表之前审查其数据处理和保留做法。
在请求执行前后加入审查环节
检查 Shell 工具的命令和执行输出,这些内容会提供在 Responses API 响应中。捕获每个会话请求的主机和实际出站目的地。定期审查日志,以验证访问模式是否符合预期、检测偏差并识别可疑行为。
验证数据驻留和保留要求
OpenAI 数据控制 适用于 OpenAI 边界内。然而,通过网络连接传输到第三方服务的数据受其自身数据保留策略的约束。请确保外部端点满足您的驻留、保留和合规性要求。