本地终端是一种工具,允许 Agent 在您或用户提供的机器上本地运行终端命令。它旨在与 Codex CLI and codex-mini-latest。命令在您自己的运行时中执行, 您可以完全控制实际运行的命令 ——API 仅返回指令,但不会在 OpenAI 基础设施上执行它们。
本地终端可通过 Responses API for use with codex-mini-latest。它不适用于其他模型,也无法通过 Chat Completies API 使用。
工作原理
本地终端工具使 Agent 能够在持续循环中运行,并访问终端。
它会发送终端命令,由您的代码在本地机器上执行,然后将输出返回给模型。此循环允许模型完成构建-测试-运行循环,无需用户额外干预。
作为代码的一部分,您需要实现一个循环来监听 local_shell_call 输出项并执行其中包含的命令。我们强烈建议对这些命令的执行进行沙盒化处理,以防止执行任何意外命令。
集成本地终端工具
以下是在应用程序中集成计算机使用工具所需的高层步骤:
-
向模型发送请求:包含
local_shell工具作为可用工具的一部分。 -
接收来自模型的响应:检查响应是否包含任何
local_shell_call项。此工具调用包含类似于exec并附带要执行的命令的操作。 -
执行请求的操作:在计算机或容器环境中通过代码执行相应的操作。
-
返回操作输出: 执行操作后,将命令输出以及状态码等元数据返回给模型。
-
重复: 使用更新后的状态作为
local_shell_call_output, 并重复此循环,直到模型停止请求操作或您决定停止为止。
示例工作流
以下是一个最小化的 (Python) 示例,展示了请求/响应循环。为简洁起见,省略了错误处理和安全检查——请勿在没有额外安全防护措施的情况下在生产环境中执行不受信任的命令.
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import os
import shlex
import subprocess
from openai import OpenAI
client = OpenAI()
# 1) Create the initial response request with the tool enabled
response = client.responses.create(
model="codex-mini-latest",
tools=[{"type": "local_shell"}],
input=[
{
"role": "user",
"content": [
{"type": "input_text", "text": "List files in the current directory"},
],
}
],
)
while True:
# 2) Look for a local_shell_call in the model's output items
shell_calls = []
for item in response.output:
item_type = getattr(item, "type", None)
if item_type == "local_shell_call":
shell_calls.append(item)
elif item_type == "tool_call" and getattr(item, "tool_name", None) == "local_shell":
shell_calls.append(item)
if not shell_calls:
# No more commands — the assistant is done.
break
call = shell_calls[0]
args = getattr(call, "action", None) or getattr(call, "arguments", None)
# 3) Execute the command locally (here we just trust the command!)
# The command is already split into argv tokens.
def _get(obj, key, default=None):
if isinstance(obj, dict):
return obj.get(key, default)
return getattr(obj, key, default)
timeout_ms = _get(args, "timeout_ms")
command = _get(args, "command")
if not command:
break
if isinstance(command, str):
command = shlex.split(command)
completed = subprocess.run(
command,
cwd=_get(args, "working_directory") or os.getcwd(),
env={**os.environ, **(_get(args, "env") or {})},
capture_output=True,
text=True,
timeout=(timeout_ms / 1000) if timeout_ms else None,
)
output_item = {
"type": "local_shell_call_output",
"call_id": getattr(call, "call_id", None),
"output": completed.stdout + completed.stderr,
}
# 4) Send the output back to the model to continue the conversation
response = client.responses.create(
model="codex-mini-latest",
tools=[{"type": "local_shell"}],
previous_response_id=response.id,
input=[output_item],
)
# Print the assistant's final answer
print(response.output_text)最佳实践
- 沙盒化或容器化 执行环境。考虑使用 Docker、firejail 或受限用户账户。
- 施加资源限制 (时间、内存、网络)。由
timeout_ms模型提供的仅是一个提示——您应该强制执行自己的限制。 - 过滤或审查 高风险命令(例如
rm,curl, 网络工具)。 - 记录每条命令及其输出 for auditability and debugging.
错误处理
如果命令在您这边失败(非零退出代码、超时等),您仍然可以发送一个 local_shell_call_output; 在其中包含错误信息 output field.
模型可以选择恢复或尝试执行其他命令。如果您发送格式不正确的数据(例如缺失 call_id),则 API 会返回标准的 400 验证错误。