shell 工具使模型能够在完整的终端环境中工作。我们支持通过本地执行以及通过 Responses API 进行托管执行的 shell。
shell 工具允许模型通过以下方式运行命令:
- 由 OpenAI 管理的托管 shell 容器。
- 本地 shell 运行时,由您自行托管和执行。
Shell 可通过 Responses API 使用。它不可通过 Chat Completions API 使用。
运行任意 shell 命令可能存在危险。请务必沙箱化执行,尽可能应用允许列表或拒绝列表,并记录工具活动以进行审计。
托管 shell 快速入门
托管 shell 是一种原生且简化的选项,适用于需要更丰富、确定性处理的任务,从运行计算到处理多媒体。
当您希望 OpenAI 为请求提供并管理容器时,请使用 container_auto。
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."
}'附加技能 (Skills)
技能是可重用、带版本的包,您可以将其挂载到托管 shell 环境中。这定义了可用的技能,在 shell 执行时,模型会决定是否调用它们。
有关上传和版本控制的详细信息,请参阅 技能 (Skills) 指南。
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" }
]
}'网络访问
托管容器默认没有出站网络访问权限。
要启用它:
- 管理员必须在仪表板中配置您的组织允许列表。
- 您必须在请求的容器环境中显式设置
network_policy。
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 和 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>)时,请使用 domain_secrets。
每个密钥条目包括:
- 目标域
- 友好的密钥名称
- 密钥值
在运行时:
- 模型和运行时看到的是占位符名称(例如
$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."
}'Responses 中的 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_output的形式返回结果。
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
如果您正在使用 Agents 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 示例。
处理常见错误
- 如果命令超过了执行超时时间,请返回超时结果并包含部分已捕获的输出。
- 如果
max_output_length出现在shell_call中,请将其包含在shell_call_output中。 - 不要依赖交互式命令;shell 工具执行应该是无交互的。
- 保留非零退出输出,以便模型能够推断恢复步骤。
风险与安全
在容器 API 中启用网络访问是一项强大的功能,同时也会带来重大的安全和数据治理风险。默认情况下,网络访问未启用。启用后,出站访问应保持严格限制在任务所需的受信任域内。
启用网络的容器可以与第三方服务和包注册中心进行交互。这会带来包括数据泄露、提示注入驱动的工具滥用以及超出预期范围的意外访问等风险。当策略过于宽松、静态或执行不一致时,这些风险会增加。
理解网络获取内容带来的提示注入风险
任何通过网络获取的外部内容都可能包含旨在操纵模型行为的隐藏指令。应将不受信任的网络内容视为潜在的对抗性内容,并对可能修改数据或系统的操作保持额外谨慎。
仅连接到受信任的目标
仅允许您信任并主动维护的域。对于代理到其他服务的中间商和聚合器要保持谨慎,并在将它们添加到允许域列表之前,审查它们的数据处理和保留做法。
在请求执行前后建立审查机制
审查 Responses API 响应中提供的 shell 工具命令和执行输出。为每个会话捕获请求的主机和实际出站目标。定期审查日志,以验证访问模式是否符合预期,检测偏差并识别可疑行为。
验证数据驻留和保留要求
OpenAI 数据控制 在 OpenAI 范围内适用。但是,通过网络连接传输到第三方服务的数据受其各自数据保留政策的约束。请确保外部端点符合您的驻留、保留和合规性要求。