關於「zero data retention」(零資料保留),即 ZDR 如何適用於此功能,請參閱 API 與資料保留。
Bash 工具是一個用戶端工具:Claude 本身不會執行命令。當您在請求中包含此工具時,Claude 會以一個 tool_use 區塊回覆,指明要執行的命令。您的應用程式在其擁有的 bash 工作階段中執行該命令,並在 tool_result 區塊中回傳輸出。
您的應用程式在多次工具呼叫之間保持同一個 bash 程序存活,因此狀態會在命令之間持續存在。工作目錄、環境變數,以及命令建立的任何檔案,在下一個命令執行時仍然存在。
此工具目前的版本是 bash_20250124。關於模型支援、beta 標頭和較早的版本,請參閱工具版本。關於所有 Anthropic 提供的工具,請參閱工具參考。
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-opus-5",
max_tokens=1024,
tools=[{"type": "bash_20250124", "name": "bash"}],
messages=[
{"role": "user", "content": "List all Python files in the current directory."}
],
)
print(response)Claude 會以 stop_reason: "tool_use" 回應,並附上一個 tool_use 區塊,其中包含您的應用程式要執行的命令:
{
"id": "msg_01XAbCDeFgHiJkLmNoPQrStU",
"model": "claude-opus-5",
"stop_reason": "tool_use",
"role": "assistant",
"content": [
{
"type": "text",
"text": "I'll list all Python files in the current directory for you."
},
{
"type": "tool_use",
"id": "toolu_01A09q90qw90lq917835lq9",
"name": "bash",
"input": {
"command": "ls *.py"
}
}
]
}在您的 bash 工作階段中執行 input.command,並將輸出以 tool_result 的形式傳回。請參閱實作 bash 工具以了解完整的往返流程。
每次工具呼叫都是 Claude 與您的應用程式之間的一次往返:
command 的 tool_use 區塊。tool_result 區塊回傳給 Claude。Claude 也可以在一次回應中回傳多個 tool_use 區塊。請在同一個工作階段中依序執行它們,並在一則 user 訊息中回傳所有結果。請參閱平行工具使用。
API 是無狀態的。您的 shell 工作階段的任何資訊都不會在請求之間傳遞,因此由您的應用程式決定工作階段何時開始、存活多久,以及何時重新啟動。關於完整的請求與回應週期,請參閱處理工具呼叫。
Bash 工具定義有兩個必填欄位:type 和 name,且 name 必須是 bash。此工具是無結構描述(schema-less)的:您不需要提供 input_schema,因為結構描述已內建於 Claude 的模型中,無法修改。下表列出 Claude 呼叫此工具時設定的輸入欄位。
| 參數 | 必填 | 說明 |
|---|---|---|
command | 是* | 要執行的 bash 命令 |
restart | 否 | 設為 true 以重新啟動 bash 工作階段 |
*除非使用 restart,否則為必填
要處理 restart: true,請終止 shell 程序、啟動一個新的程序,並回傳一個確認重新啟動的 tool_result。重新啟動的工作階段是全新的:工作目錄、環境變數和任何執行中的程序都會消失。
bash_20250124 是此工具目前的版本,不需要 beta 標頭。從 Claude Sonnet 3.7(已停用)開始的每個模型都接受它,包括所有目前的 Claude 模型。
原始的 bash_20241022 版本是電腦使用(computer use)beta 的一部分,2024 年 10 月發布的 Claude Sonnet 3.5(已停用)是唯一接受它的模型。使用它的請求需要 anthropic-beta: computer-use-2024-10-22 標頭,且 SDK 僅在其 beta 命名空間中提供它。新的整合應使用 bash_20250124。
Claude 可以跨工具呼叫串連命令以完成多步驟任務:
User request:
"Install the requests library and create a simple Python script that
fetches a joke from an API, then run it."
Claude's tool uses:
1. Install package
{"command": "pip install requests"}
2. Create script
{"command": "cat > fetch_joke.py << 'EOF'\nimport requests\nresponse = requests.get('https://official-joke-api.appspot.com/random_joke')\njoke = response.json()\nprint(f\"Setup: {joke['setup']}\")\nprint(f\"Punchline: {joke['punchline']}\")\nEOF"}
3. Run script
{"command": "python fetch_joke.py"}工作階段在命令之間維持狀態,因此在步驟 2 中建立的檔案在步驟 3 中仍可使用。
Claude 決定要執行哪個命令。您的應用程式擁有其他一切:shell 程序、逾時設定和安全檢查。以下步驟展示一個最小化的實作。
建立持久的 bash 工作階段
啟動一個長期存活的 bash 程序,並在其中執行每個命令。由於連接到存活程序的管道永遠不會回報檔案結尾(end-of-file),工作階段會在每個命令之後印出一行唯一的哨兵(sentinel)行,以標記該命令輸出的結束位置:
import subprocess
import uuid
class BashSession:
"""A bash process that stays alive between commands so state persists."""
def __init__(self):
self.process = subprocess.Popen(
["/bin/bash"],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT, # interleave errors with output, in order
start_new_session=True, # own process group: a timeout can kill every child
text=True,
)
def execute_command(self, command):
"""Run a command in the session and return its output."""
sentinel = f"__CLAUDE_BASH_DONE_{uuid.uuid4().hex}__" # unique per call
self.process.stdin.write(f"{command}\necho {sentinel}\n")
self.process.stdin.flush()
output = []
for line in self.process.stdout:
if sentinel in line: # this command's output is complete
break
output.append(line)
return "".join(output)
def restart(self):
self.process.kill()
self.process.wait()
self.__init__()
bash_session = BashSession()
print(bash_session.execute_command("cd /tmp && pwd"))
print(bash_session.execute_command("pwd")) # still /tmp: the session kept its state工作階段會將 stderr 與 stdout 交錯輸出,因此錯誤訊息會出現在它們發生的位置。此範例省略了完整實作還需要的部分:當命令停滯時,需要一個逾時機制來終止 shell 及其啟動的所有程序,然後重新啟動工作階段。使用命令逾時最佳實務展示了一種新增此機制的方法。
處理 Claude 的工具呼叫
從 Claude 的回應中擷取並執行命令:
tool_results = []
for content in response.content:
if content.type == "tool_use" and content.name == "bash":
if content.input.get("restart"):
bash_session.restart()
result = "Bash session restarted"
else:
command = content.input.get("command")
result = bash_session.execute_command(command)
# 每個 tool_use 區塊對應一個 tool_result,全部在下一個使用者訊息中回傳
tool_results.append(
{"type": "tool_result", "tool_use_id": content.id, "content": result}
)將結果回傳給 Claude
在延續同一對話的 user 訊息中傳回 tool_result。Claude 要麼在同一個工作階段中請求另一個命令,要麼完成其回答:
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-opus-5",
max_tokens=1024,
tools=[{"type": "bash_20250124", "name": "bash"}],
messages=[
{"role": "user", "content": "List all Python files in the current directory."},
{
"role": "assistant",
"content": [
{
"type": "tool_use",
"id": "toolu_01A09q90qw90lq917835lq9",
"name": "bash",
"input": {"command": "ls *.py"},
}
],
},
{
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": "toolu_01A09q90qw90lq917835lq9",
"content": "analysis.py\nprocess_data.py\n",
}
],
},
],
)
print(response.content)當 stop_reason 為 tool_use 時,重複執行並回傳的循環。關於完整的迴圈,請參閱處理用戶端工具的結果。
實作安全措施
新增驗證和限制。使用允許清單(allowlist)而非封鎖清單(blocklist):封鎖清單會遺漏任何它未預料到的命令。此範例也會拒絕以獨立單詞形式出現的 shell 運算子:
import shlex
ALLOWED_COMMANDS = {"ls", "cat", "echo", "pwd", "grep", "find", "wc", "head", "tail"}
SHELL_OPERATORS = {"&&", "||", "|", ";", "&", ">", "<", ">>"}
def validate_command(command):
# 僅允許明確允許清單中的命令
try:
tokens = shlex.split(command)
except ValueError:
return False, "Could not parse command"
if not tokens:
return False, "Empty command"
executable = tokens[0]
if executable not in ALLOWED_COMMANDS:
return False, f"Command '{executable}' is not in the allowlist"
# 拒絕以獨立字詞形式寫出的 shell 運算子
for token in tokens[1:]:
if token in SHELL_OPERATORS or token.startswith(("$", "`")):
return False, f"Shell operator '{token}' is not allowed"
return True, None此檢查是針對明顯錯誤的警示機制(tripwire),而非強制執行的邊界。它會拒絕本頁其他範例所使用的以空格分隔的串連(&&)、管道和重新導向。它無法捕捉緊貼在單詞上的運算子,例如 cat data.txt|grep x,因為分詞器會將 data.txt|grep 保留在同一個 token 中。請決定您的應用程式允許哪些命令和運算子。真正的控制手段是隔離:在容器或虛擬機器中執行整個工作階段(請參閱安全性)。
當命令失敗或工作階段中斷時,請告知 Claude 發生了什麼事。將訊息作為 tool_result 的內容回傳,並將 is_error 設為 true,這會將該工具呼叫標記為失敗。請參閱使用 is_error 處理錯誤。
您的應用程式會執行 Claude 請求的任何命令。請在隔離的環境中執行工作階段,例如容器或虛擬機器,並以能完成工作的最低權限使用者身分執行。將每個命令都視為不受信任的輸入。
除了隔離之外,還請新增以下控制措施:
ulimit。bash 工具定義會在您的請求中增加以下輸入 token。這是在每個模型的工具使用系統提示之外額外增加的,後者在任何工具存在時都會適用。
| 模型 | 額外輸入 token |
|---|---|
| Claude Opus 5、Claude Opus 4.8 和 Claude Opus 4.7 | 325 個 token |
| Claude Opus 4.6、Claude Sonnet 4.6 及更早版本 | 244 個 token |
額外的 token 會被以下內容消耗:
請參閱工具使用定價以了解完整的定價詳情。
pytest && coverage reportnpm install && npm run buildgit status && git add . && git commit -m "message"關於在長時間執行的代理工作流程中使用 git 作為檢查點與復原機制的指引,請參閱狀態管理最佳實務。
wc -l *.csv && ls -lh *.csvfind . -name "*.py" | xargs grep "pattern"tar -czf backup.tar.gz ./datadf -h && free -mps aux | grep pythonexport PATH=$PATH:/new/path && echo $PATHvim、less、密碼提示,或任何在 stdin 上等待輸入的命令。tool_result 時,輸出才會到達 Claude。Bash 工具與文字編輯器工具搭配使用效果很好:Claude 使用一個工具編輯檔案,並使用另一個工具請求執行該檔案的命令。
如果您同時使用程式碼執行工具,Claude 可以存取兩個獨立的執行環境:您的本機 bash 工作階段和 Anthropic 的沙箱容器。兩者之間不共享狀態。請參閱將程式碼執行與其他執行工具搭配使用,以了解如何提示 Claude 區分不同環境的指引。
檢視和修改文字檔案,以除錯、修正和改進程式碼。
將 Claude 連接到外部工具和 API。了解工具在哪裡執行、Claude 何時呼叫它們,以及哪個工具適合您的任務。
Was this page helpful?