Shell 도구

Shell 도구 (Shell Tool)

에이전트가 임의 셸 명령을 동기적으로 실행하는 방법을 설명해요. 빌드, 의존성 설치, API 질의, 시스템 상호작용에 쓰는 강력한 도구예요.

출처: 문서

본문

shell 도구는 에이전트가 임의 셸 명령을 동기적으로 실행하게 해 줘요. 가장 강력한 도구 중 하나예요 — 에이전트가 빌드를 실행하고, 의존성을 설치하고, API를 질의하고, 시스템과 상호작용할 수 있게 하죠. 각 호출은 새롭고 격리된 셸 세션에서 실행돼요 — 호출 사이에 상태가 유지되지 않아요.

명령은 기본 30초 타임아웃이 있고, --yolo를 쓰지 않으면 사용자 확인을 요구해요. 서버, 감시자, 기타 장기 실행 명령에는 shell과 함께 background_jobs 도구셋을 추가하세요.

셸 인터프리터 감지

shell 도구는 해석된 셸 인터프리터(예: bash, zsh, powershell, pwsh, cmd)와 운영체제(Linux, macOS, Windows)를 설명에 자동 감지·이름 지정해요. 이렇게 하면 모델이 호스트 환경에 맞는 올바른 셸 문법을 쓰게 돼요.

예를 들어:

  • Linux + bash: "Executes the given shell command with bash on Linux."
  • Windows + PowerShell: "Executes the given shell command with powershell on Windows. Use Windows PowerShell 5.1 syntax: chain commands with ";" (not "&&"), and avoid POSIX commands/flags like "ls -la"."

이렇게 해서 모델이 Windows에서 POSIX 문법을 가정하거나 그 반대로 가정하며 턴을 낭비하는 것을 줄여요.

구성

toolsets:
  - type: shell

옵션

속성 타입 설명
env object 모든 셸 명령에 설정할 환경 변수
safer boolean 폐기되고 무시됨 — 셸 명령은 이제 항상 분류됨(아래 Command classification 참고). 기존 YAML이 여전히 파싱되도록 유지됨
sudo_askpass boolean sudo 비밀번호 프롬프트에 옵트인(아래 Sudo 지원 참고). 기본 false

커스텀 환경 변수

toolsets:
  - type: shell
    env:
      MY_VAR: "value"
      PATH: "${env.PATH}:/custom/bin"

명령 분류

모든 셸 명령은 승인 결정 전에 내장 분류 체계에 대해 분류돼요 — 옵트인이 필요 없어요:

  • 파괴적 매칭(rm -rf, docker volume rm, mkfs, dd if=… of=/dev/, …)은 blast_radius(low/medium/high)와 범주 태그와 함께 파괴적이라고 표시돼요. TUI 확인 대화상자는 blast radius를 색상 배지로 렌더링해요.
  • 알려진 안전한 읽기(ls, cat, git status, git diff, docker ps, docker logs, kubectl get, …)는 안전하다고 표시돼요.
  • 그 외 모든 것은 알 수 없음으로 표시돼요.

세션의 안전 모드가 각 라벨이 무슨 뜻인지 결정해요: strict는 모든 것에 묻고, balanced는 안전 명령을 자동 실행하고 파괴적/알 수 없음은 묻고, restricted는 안전 명령을 자동 실행하고 파괴적/알 수 없음을 묻지 않고 거부하며(무인 실행용 fail-closed), autonomous는 모든 것을 실행해요. 커스텀 권한 규칙이 항상 모드를 이겨요.

복합 셸(a && b, a; b, a | b)은 안전 허용 목록에 절대 매칭되지 않고, 어떤 파괴적 세그먼트든 물어보는 것으로 넘어가요. 전체 분류 체계는 pkg/safety/safety_patterns.json에 있어요.

examples/safety_modes.yaml에서 전체 예시를 확인하세요. 레거시 safer: true 도구셋 플래그는 폐기되고 무시돼요.

Sudo 지원

기본적으로 셸 명령에는 제어 터미널이 없어서, 비밀번호가 필요한 sudo 명령은 타임아웃될 때까지 멈춰요(에이전트는 보통 포기하고 수동 지침을 인쇄하는 것으로 폴백해요).

sudo_askpass: true를 설정해 sudo 권한 상승 흐름을 활성화하세요:

toolsets:
  - type: shell
    sudo_askpass: true

활성화되면 sudo 명령이 호스트 UI를 통해 비밀번호 프롬프트를 띄워요(입력은 마스킹됨). 비밀번호는 표준 SUDO_ASKPASS 메커니즘을 통해 비공개 세션별 소켓으로 sudo에 전달돼요 — 커맨드라인, 로그, 에이전트 저장소에 절대 기록되지 않아요.

브리지 환경 변수(SUDO_ASKPASS, CAGENT_ASKPASS_SOCKET, CAGENT_ASKPASS_TOKEN)는 sudo를 호출하는 명령에만 추가되지만, 그런 명령 안에서는 sudo뿐 아니라 모든 자식 프로세스에 보여요. 그것들은 소켓 경로와 세션 토큰을 나르지, 비밀번호를 나르지 않아요. 소켓은 0700 디렉터리에 있어서 자기 사용자만 닿을 수 있어요.

참고 사항과 한계:

  • Unix 전용. 이 플래그는 Windows에서 효과가 없어요.
  • 대화형 UI 전용. 헤드리스/비대화형 실행에서는 프롬프트가 자동 거부되고 sudo는 예전처럼 실패해요.
  • POSIX 셸(sh, bash, zsh, ...)의 베어 sudo ... 호출만 처리돼요. 절대 경로(/usr/bin/sudo)로, env sudo로, 중첩 스크립트 안에서, 또는 비-POSIX 셸(예: fish)에서 호출된 sudo는 가로채지 않고 예전처럼 동작해요.
  • 캐싱은 sudo 자신의 몫이에요. 각 셸 도구 호출은 제어 터미널 없는 새 셸에서 실행되므로 sudo의 자격 증명 캐시가 별도 도구 호출 간에 지속되지 않아요: sudo를 쓰는 셸 명령마다 한 번 프롬프트가 떠요. 단일 명령 안에서 여러 sudo 호출(예: sudo a && sudo b)은 sudo 자신의 타임스탬프 구성에 따라 보통 한 프롬프트를 공유해요.
  • 프롬프트는 명령의 타임아웃 안에 답해야 해요. 입력을 기다릴 수 있는 sudo 명령에는 timeout 파라미터를 올리세요.
  • 프롬프트는 직렬화돼요: 단일 명령이 두 sudo 호출을 병렬로 실행하면(예: sudo a & sudo b) 두 번째는 첫 번째 프롬프트가 답변될 때까지 기다려요, 두 대화상자를 한 번에 열지 않아요.

사용 가능한 도구

shell 도구셋은 도구 하나를 노출해요:

도구 이름 설명
shell 명령을 동기적으로 실행하고 끝나면 결합 출력 반환

shell 파라미터

파라미터 타입 필수 설명
cmd string ✓ 실행할 셸 명령
cwd string ✗ 명령을 실행할 작업 디렉터리(기본: .)
timeout integer ✗ 호출별 실행 타임아웃(초, 기본: 30)

경고 안전 shell 도구는 에이전트에게 시스템 셸에 대한 전체 접근을 줘요. shell 도구를 쓰는 에이전트에는 무한 루프를 막도록 항상 max_iterations를 설정하세요. 개발 에이전트에서는 20–50 값이 전형적이에요. 추가 격리를 위해 Sandbox Mode를 사용하세요.

참고 도구 확인 기본적으로 Docker Agent는 셸 명령을 실행하기 전에 사용자 확인을 요구해요. --yolo로 모든 도구 호출을 자동 승인하세요.

더 알아보기 (Learn more)