docs/shell.mdXem bản gốc Bản dịch đầy đủ theo đúng cấu trúc tài liệu; code, liên kết và định danh kỹ thuật được giữ nguyên.
Vỏ
Shell cung cấp cho một agent khả năng chạy các lệnh shell, với sự cho phép/từ chối
kiểm soát, lọc môi trường và các quy trình nền được quản lý. Nó lộ ra
công cụ thực thi lệnh bắt nguồn từ một thư mục đang làm việc và dọn sạch mọi
quá trình nền tự động khi quá trình chạy agent kết thúc.
Mặc dù Pydantic AI Harness có trên các bản phát hành 0.x nhưng API có thể thay đổi giữa các bản phát hành nhỏ; khi đó, cảnh báo ngừng sử dụng và hướng dẫn di chuyển ghi chú phát hành sẽ cho bạn (hoặc người đại diện của bạn) biết chính xác cách nâng cấp. Xem chính sách phiên bản.
vấn đề
Các agent thường xuyên cần chạy một bản dựng, một bộ thử nghiệm, một kẻ nói dối hoặc một bản kiểm tra nhanh
grep. Kết nối việc xử lý quy trình con -- đầu ra phát trực tuyến, thời gian chờ, cắt bớt,
tiêu diệt các tiến trình chạy trốn và dọn dẹp các công việc nền ở cuối quá trình chạy --
là bản soạn sẵn khó sử dụng mà mọi agent đều phát minh lại.
Shell gộp hệ thống ống nước đó vào một khả năng:
danh sách cho phép/từ chối có thể định cấu hình, cắt bớt đầu ra được điều chỉnh để giữ phần đuôi hữu ích,
thư mục làm việc dính tùy chọn, kiểm soát môi trường có thể giữ máy chủ
bí mật từ các lệnh sinh ra và tự động dọn dẹp các tiến trình nền
khi quá trình chạy kết thúc.
Cách sử dụng
xây dựng Shell với một thư mục làm việc và chuyển nó tới một Agent thông qua
capabilities tham số:
from pydantic_ai import Agent
from pydantic_ai_harness import Shell
agent = Agent(
'anthropic:claude-sonnet-4-6',
capabilities=[Shell(cwd='./workspace', allowed_commands=['ls', 'cat', 'rg'])],
)
result = agent.run_sync('List the Python files and summarize the largest one.')
print(result.output)
Theo mặc định Shell chạy trong thư mục hiện tại với lệnh phá hủy tích hợp
danh sách từ chối đang hoạt động -- Shell() một mình cấu hình đang hoạt động (nếu được phép).
Công cụ
Shell đóng góp bốn công cụ cho agent:
| Công cụ | Mục đích |
|---|---|
run_command | Chạy lệnh một cách đồng bộ và trả về nhãn stdout/stderr cộng với mã thoát. Tôn vinh thời gian chờ cho mỗi cuộc gọi hoặc mặc định. |
start_command | Khởi chạy lệnh chạy dài (máy chủ, trình theo dõi) ở chế độ nền; trả về một ID. |
check_command | Báo cáo trạng thái và đầu ra tích lũy của lệnh nền. |
stop_command | Chấm dứt lệnh nền và trả về đầu ra cuối cùng của nó. |
run_command chấp nhận một tùy chọn timeout_seconds đối số ghi đè
default_timeout cho một cuộc gọi duy nhất. check_command và stop_command lấy
command_id chuỗi được trả về bởi start_command.
Đầu ra được dán nhãn với [stdout] / [stderr] dấu hiệu và một [exit code: N]
dòng trên lối ra khác không. Khi nó vượt quá max_output_chars đuôi được giữ lại
(phần đầu bị rơi), do đó có lỗi, dấu vết ngăn xếp và [stderr] phần --
mà tất cả đều ở cuối -- tồn tại khi bị cắt cụt. Trạng thái lệnh nền và
thoát siêu dữ liệu theo đầu ra đã ghi để chúng vẫn ở phần đuôi được giữ lại.
Điều khiển lệnh
Hai danh sách loại trừ lẫn nhau quyết định những tệp thực thi nào có thể chạy, cộng với các bộ lọc cho toán tử shell và các lệnh tương tác:
| Lĩnh vực | Hiệu ứng |
|---|---|
allowed_commands | Nếu không trống thì chỉ những tệp thực thi này mới có thể chạy (danh sách cho phép). |
denied_commands | Những tệp thực thi này luôn bị từ chối (danh sách từ chối). |
denied_operators | Toán tử Shell (ví dụ: >, >>, |) bị từ chối khi có mặt. |
allow_interactive | Nếu False (mặc định), các lệnh mong đợi TTY (vi, sudo, ssh, ...) bị chặn. |
allowed_commands và denied_commands loại trừ lẫn nhau -- đặt một, không phải
cả hai. Việc đặt các giá trị không trống cho cả hai sẽ làm tăng ValueError khi bộ công cụ
được xây dựng. denied_commands mặc định là danh sách các lệnh phá hoại
(rm, rmdir, mkfs, dd, format, shutdown, reboot, halt,
poweroff, init); chuyển một danh sách trống để vô hiệu hóa nó. Tên thực thi là
chiết xuất với shlex, vì vậy các đối số không bỏ qua việc kiểm tra.
trống rỗng allowed_commands bộ sưu tập không chọn chế độ danh sách cho phép. các
được cấu hình denied_commands duy trì hoạt động; khi bị bỏ qua, đây là phần tích hợp sẵn
danh sách từ chối. Vượt qua denied_commands=[] để tắt tính năng lọc tên lệnh.
Lệnh bị từ chối xuất hiện trong mô hình dưới dạng
ModelRetry, không phải là lỗi cứng:
quá trình chạy vẫn tiếp tục và mô hình có thể chọn một lệnh được phép thay thế. cũng vậy
mọi lỗi khác mà mô hình có thể xử lý: thư mục đang hoạt động và lệnh trước đó
bị xóa hoặc thay thế bằng một tập tin và một lệnh mà hệ điều hành từ chối thực hiện
spawn vì nó chứa byte NUL hoặc chứa ký tự của hệ điều hành
không thể mã hóa. Thất bại
mô hình không thể làm gì khi vẫn hủy bỏ quá trình chạy: một máy chủ không thể phân bổ
một quy trình, một đối số hoặc môi trường vượt quá kết hợp của nền tảng
giới hạn kích thước và ký tự không hợp lệ trong ứng dụng do ứng dụng cung cấp env.
!!! cảnh báo "Nỗ lực hết mình, không phải ranh giới an ninh"
allowed_commands là lan can ngăn ngừa tai nạn chứ không phải là ranh giới an ninh.
Quá trình xác thực chỉ kiểm tra token đầu tiên và các lệnh được đưa vào danh sách cho phép, chẳng hạn như
python, git, uvvà make có thể sinh ra các quá trình tùy ý. Một mô hình mà
muốn làm việc xung quanh danh sách cho phép có thể. Đối với công việc không đáng tin cậy, hãy chạy agent
bên trong sự cô lập ở cấp hệ điều hành, chẳng hạn như ModalSandbox hoặc một thùng chứa.
Kiểm soát môi trường
Theo mặc định, lệnh sinh ra sẽ kế thừa môi trường đầy đủ của quy trình agent. trong một hộp cát chứa khóa API LLM, token hoặc các bí mật khác, lệnh cho mô hình viết có thể đọc chúng. Hai trường kiểm soát những gì quy trình con nhìn thấy:
| Lĩnh vực | Hiệu ứng |
|---|---|
env | Môi trường rõ ràng thay thế tính kế thừa cho môi trường riêng của quy trình con. |
denied_env_patterns | Mô hình toàn cầu (fnmatch) cho các tên biến bị loại khỏi môi trường cơ sở. Gương denied_commands. |
env ngăn chặn các biến kế thừa xuất hiện trong chính tiến trình con
môi trường (bạn cung cấp PATH và bất cứ điều gì khác mà lệnh cần).
denied_env_patterns là một danh sách từ chối đối với môi trường được kế thừa -- nhẹ hơn đối với
cấu hình khi bạn chỉ cần bỏ một vài tên nhạy cảm đã biết. hai
soạn thảo: khi cả hai được đặt, các mẫu cũng lọc nội dung rõ ràng env. rời đi
cả hai đều không được đặt sẽ giữ nguyên mặc định kế thừa mọi thứ.
import os
from pydantic_ai_harness import LLM_API_KEY_ENV_PATTERNS, Shell
# Strip provider credentials from the inherited environment.
Shell(cwd='./repo', denied_env_patterns=LLM_API_KEY_ENV_PATTERNS)
# Or hand the subprocess a fixed environment, inheriting nothing.
Shell(cwd='./repo', env={'PATH': os.environ['PATH'], 'HOME': os.environ['HOME']})
LLM_API_KEY_ENV_PATTERNS bao gồm các tiền tố nhà cung cấp phổ biến (ANTHROPIC_*,
GATEWAY_*, GEMINI_*, GOOGLE_*, OPENAI_*, OPENROUTER_*) cộng
PYDANTIC_AI_GATEWAY_API_KEY. Nó chỉ nhắm mục tiêu thông tin xác thực LLM -- nó không
che giấu các bí mật máy chủ khác (a LOGFIRE_TOKEN, token GitHub, đám mây
thông tin đăng nhập) và tiền tố của nó rất thô, vì vậy GOOGLE_* cũng có dải
các loại không có thông tin xác thực như GOOGLE_APPLICATION_CREDENTIALS. Hãy đối xử với nó như một
điểm bắt đầu và thêm các mẫu của riêng bạn. Nó không phải là mặc định: tước
các biến môi trường sẽ âm thầm phá vỡ các agent dựa vào kế thừa
thông tin xác thực, vì vậy nó được chọn tham gia.
env được thực thi khi xuất hiện, không được áp dụng dưới dạng bộ lọc hậu định khi đang chạy
quy trình: quy trình con bắt đầu với chính xác môi trường được giải quyết (của bạn
env, trừ đi bất cứ thứ gì denied_env_patterns loại bỏ khỏi nó). Không có sự kiểm soát nào
một ranh giới an ninh. Một lệnh chạy dưới cùng một danh tính hệ điều hành vẫn có thể
đọc môi trường của tiến trình cha thông qua các giao diện hệ thống như Linux
Procfs, cũng như các tệp máy chủ khác. Sử dụng cách ly cấp hệ điều hành khi có lệnh
không đáng tin cậy. Mặt trái của nó là một mẫu đủ rộng để có thể lột bỏ PATH hoặc
HOMEhoặc một env bỏ qua chúng, có thể phá vỡ độ phân giải lệnh. Bên ngoài
các lệnh vẫn có thể chạy thông qua mặc định tích hợp của shell PATH trên một số hệ thống,
nhưng đừng dựa vào nó -- đặt PATH rõ ràng khi bạn thay thế môi trường.
Quá trình nền
start_command ghi stdout/stderr vào tệp tạm thời và trả về một ID ngắn. sử dụng
check_command(command_id) để thăm dò ý kiến và stop_command(command_id) chấm dứt
và thu thập đầu ra cuối cùng. Các tiến trình được khởi chạy trong phiên riêng của chúng
(start_new_session) để toàn bộ nhóm quy trình có thể được báo hiệu -- SIGTERM,
leo thang đến SIGKILL sau một thời gian ân hạn.
Khi kết thúc quá trình dọn dẹp bộ công cụ sẽ chấm dứt mọi nền vẫn đang chạy
xử lý và xóa các tập tin tạm thời của nó. runtime agent đi vào bộ công cụ thông qua một
AsyncExitStack, do đó quá trình dọn dẹp này sẽ diễn ra cho dù lần chạy thành công hay tăng lên -- một
agent quên gọi stop_command sẽ không rò rỉ quá trình.
from pydantic_ai import Agent
from pydantic_ai_harness import Shell
agent = Agent(
'anthropic:claude-sonnet-4-6',
capabilities=[Shell(cwd='./app', allowed_commands=['npm', 'curl'])],
)
result = agent.run_sync(
'Start the dev server with `npm run dev`, wait for it to boot, '
'then curl http://localhost:3000/health and report the status.'
)
print(result.output)
Thư mục làm việc
Theo mặc định mỗi lệnh chạy trong cwd và cd không có tác dụng lâu dài. Đặt
persist_cwd=True làm cd dính trên các cuộc gọi: mỗi lệnh được gói gọn
rằng sau khi nó chạy, thư mục làm việc cuối cùng của nó sẽ được ghi vào một thư mục tạm thời riêng tư
tập tin và thư mục đó được chuyển vào các cuộc gọi tiếp theo. Con đường chỉ có
được cập nhật khi lệnh thoát 0và bản ghi được ghi ngoài dải (không phải
thành thiết bị xuất chuẩn) để đầu ra lệnh không bao giờ có thể giả mạo thư mục được theo dõi.
from pydantic_ai import Agent
from pydantic_ai_harness import Shell
agent = Agent(
'anthropic:claude-sonnet-4-6',
capabilities=[Shell(cwd='.', persist_cwd=True, allowed_commands=['cd', 'ls', 'pwd'])],
)
Mỗi lần chạy sẽ có một phiên bản bộ công cụ mới, vì vậy thư mục được theo dõi và bất kỳ
các tiến trình nền được tách biệt giữa các lần chạy đồng thời và luôn bắt đầu lại
tại cấu hình cwd.
Cấu hình
Mỗi lĩnh vực của Shell với mặc định của nó:
from pydantic_ai_harness import Shell
Shell(
cwd='.', # str | Path -- working directory
allowed_commands=[], # allowlist (mutually exclusive with denied)
denied_commands=[...], # denylist (defaults to destructive commands)
denied_operators=[], # blocked shell operators
default_timeout=30.0, # seconds, per run_command
max_output_chars=50_000, # output cap returned to the model
persist_cwd=False, # make cd sticky across calls
allow_interactive=False, # allow TTY-style commands
env=None, # explicit env, replacing inheritance (None = inherit)
denied_env_patterns=[], # glob patterns stripped from the env
)
Thông số agent (YAML/JSON)
Shell hoạt động với Pydantic AI
thông số agent, vì vậy bạn có thể khai báo nó trong một
tập tin cấu hình thay vì Python:
# agent.yaml
model: anthropic:claude-sonnet-4-6
capabilities:
- Shell:
cwd: ./workspace
allowed_commands: ['ls', 'cat', 'rg', 'pytest']
from pydantic_ai import Agent
from pydantic_ai_harness import Shell
agent = Agent.from_file('agent.yaml', custom_capability_types=[Shell])
Vượt qua custom_capability_types để trình tải thông số kỹ thuật biết cách khởi tạo
Shell.
Đọc thêm
Tham chiếu API
::: pydantic_ai_harness.Shell