Bash 工具是一種 client tool(用戶端工具):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。此工具無需結構描述:您不需要提供 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 程序,並在其中執行每個命令。由於連接到運作中程序的管道永遠不會回報檔案結尾,工作階段會在每個命令之後印出一個唯一的哨兵行,以標記該命令輸出的結束位置:
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 時,重複執行並回傳的循環。關於完整的迴圈,請參閱處理用戶端工具的結果。
實作安全措施
新增驗證和限制。使用允許清單而非封鎖清單:封鎖清單會遺漏任何未預期的命令。此範例也會拒絕以獨立單字形式出現的 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此檢查是針對明顯錯誤的絆線,而非強制執行的邊界。它會拒絕本頁其他範例所使用的帶空格的串連(&&)、管道和重新導向。它無法攔截緊貼單字的運算子,例如 cat data.txt|grep x,因為分詞器會將 data.txt|grep 保留在同一個 token 內。請決定您的應用程式允許哪些命令和運算子。真正的控制在於隔離:在容器或虛擬機器內執行整個工作階段(請參閱安全性)。
當命令失敗或工作階段中斷時,告知 Claude 發生了什麼。將訊息作為 tool_result 內容回傳,並將 is_error 設為 true,以將該工具呼叫標記為失敗。請參閱使用 is_error 處理錯誤。
除了隔離之外,請新增以下控制措施:
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 連接到外部工具和 API。了解工具在何處執行、Claude 何時呼叫它們,以及哪個工具適合您的任務。
Was this page helpful?