기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.
대화형 셸(터미널)
InvokeAgentRuntimeCommandShell 작업은 WebSocket을 통해 실행 중인 AgentCore 하네스 세션 내에서 지속적인 대화형 터미널을 엽니다. API는 런타임 세션 ID로이 하네스 세션을 식별합니다. 원샷 명령 실행과 달리 대화형 셸은 입력 간에 환경 변수, 작업 디렉터리, 명령 기록 및 실행 프로세스를 유지합니다.
명령 간에 쉘 상태를 보존해야 하는 경우 디버깅, 반복 개발 또는 장기 실행 프로세스에 대화형 쉘을 사용합니다.
SigV4 및 SigV4 미리 서명된 요청의 경우 호출자는 하네스에 대한 bedrock-agentcore:InvokeAgentRuntimeCommandShell 권한이 필요합니다. 베어러 토큰 요청은 대신 하네스 인바운드 권한 부여자를 충족해야 합니다.
중요
시작 시 AgentCore CLI 명령과 상위 수준 AgentCore SDK 쉘 헬퍼는 하네스 대상을 지원하지 않습니다. 이 페이지에 표시된 대로 InvokeAgentRuntimeCommandShell WebSocket API를 통해 직접 하네스 쉘에 연결합니다.
작동 방식
InvokeAgentRuntimeCommandShell는 하네스 세션을 실행하는 microVM의 대화형 쉘 프로세스에 대한 WebSocket 연결을 설정합니다. 연결은 바이너리 프레임을 사용하여 터미널 입력 및 출력을 양방향으로 스트리밍합니다.
하네스가 기본 환경을 사용하는 경우 쉘은 관리형 하네스 환경에서 실행됩니다. 하네스가 사용자 지정 컨테이너를 사용하는 경우 쉘은 해당 컨테이너에서 실행됩니다. Harness 대화형 터미널은 현재 Bash만 지원합니다.
연결은 다음을 지원합니다.
| 기능 | 설명 |
|---|---|
|
영구 상태 |
환경 변수, 작업 디렉터리, 명령 기록 및 실행 중인 프로세스는 동일한 셸 내에 유지됩니다. |
|
재연결 |
동일한 런타임 세션 ID 및 |
|
여러 동시 쉘 |
하나의 하네스 세션에서 최대 10개의 활성 쉘 세션을 엽니다. 분리된 쉘은이 제한에 포함되지 않습니다. 각 쉘에는 독립적인 터미널 프로세스가 있으며 세션 파일 시스템을 공유합니다. |
사전 조건
-
READY상태의 하네스 -
선택한 인증 방법에 대한 권한 부여: SigV4에 대한
bedrock-agentcore:InvokeAgentRuntimeCommandShellIAM 권한 또는 하네스 인바운드 권한 부여자가 수락한 보유자 토큰 -
바이너리 프레임과 요청 헤더 또는 미리 서명된 URLs을 지원하는 WebSocket 클라이언트
-
사용자 지정 컨테이너의 경우 Bash는에 설치됩니다
/bin/bash.sh및를 포함한 다른 쉘dash은 현재 지원되지 않습니다.
전체 하네스 권한 모델에 대한 자세한 내용은 섹션을 참조하세요호출자에게 필요한 IAM 권한.
WebSocket API를 통해 연결
다음 URL에 대한 WebSocket 연결을 엽니다.
wss://bedrock-agentcore.<region>.amazonaws.com/runtimes/<url-encoded-harness-arn>/ws/shells
관리형 런타임의 ARN이 아닌 하네스 ARN을 사용합니다. 전체 하네스 ARN을 경로에 넣기 전에 URL 인코딩합니다. 하네스 ARN의 형식은 다음과 같습니다.
arn:aws:bedrock-agentcore:<region>:<accountId>:harness/<harnessId>
WebSocket 업그레이드 요청으로 다음 값을 전송합니다.
| 값 | 필수 | 설명 |
|---|---|---|
|
인증 |
예 |
서명 버전 4(SigV4)를 사용하여 요청에 서명하거나, SigV4 미리 서명된 URL을 사용하거나, |
|
|
아니요 |
기존 하네스 세션을 대상으로 하거나 제공된 ID로 세션을 생성합니다. 값은 33자 이상이어야 합니다. 이를 생략하면 서비스가 런타임 세션 ID를 생성하여 응답에 반환합니다. |
|
|
아니요 |
SigV4 연결의 경우 선택적으로 명령 쉘 바이너리 프로토콜을 식별 |
|
|
아니요 |
기존 쉘에 다시 연결합니다. 쉘을 생성한 것과 동일한 런타임 세션 ID로 사용합니다. |
Authorization 헤더를 설정할 수 없는 브라우저 클라이언트의 경우 base64url이 보유자 토큰을 인코딩하고를 통해 base64UrlBearerAuthorization.<encoded-token> 및 base64UrlBearerAuthorization 감시를 모두 제공합니다Sec-WebSocket-Protocol. 보유자 토큰 연결에 대해서도 v1.command.agentcore.aws.dev를 제공하지 마십시오.
101 Switching Protocols 응답은 X-Amzn-Bedrock-AgentCore-Runtime-Session-Id 및 X-Amzn-Bedrock-AgentCore-Shell-Id 헤더에서 런타임 세션 ID와 셸 ID를 반환합니다. WebSocket 업그레이드 응답 헤더를 읽을 수 없는 클라이언트는 첫 번째 STATUS 프레임에서 셸 ID를 읽을 수 있습니다. 프레임에는 런타임 세션 ID가 포함되어 있지 않으므로 이러한 클라이언트는 연결하기 전에 런타임 세션 ID를 생성하고 유지해야 합니다. 미리 서명된 URL을 생성할 때 URL에 서명하기 전에 런타임 세션 ID를 쿼리 파라미터로 포함합니다.
WebSocket 업그레이드 제한 시간은 서비스가를 반환할 때까지만 적용됩니다101 Switching Protocols. 업그레이드 후 쉘 및 사용자 지정 컨테이너 초기화를 계속할 수 있습니다. 쉘을 준비 상태로 처리하기 전에 초기 STATUS 프레임을 기다리고, 대기 중에 별도의 애플리케이션 제한 시간을 적용하고, 종료 코드를 쉘 초기화 또는 서버 장애1011로 처리합니다.
다음 Python 예제에서는 일반 WebSocket 클라이언트를 사용하며 업그레이드 요청에 서명하는 데botocore만 사용됩니다. AgentCore SDK 쉘 헬퍼는 사용하지 않습니다.
pip install "boto3>=1.34" "websockets>=15"
import asyncio import json import urllib.parse import uuid import botocore.session import websockets from botocore.auth import SigV4Auth from botocore.awsrequest import AWSRequest REGION = "us-west-2" HARNESS_ARN = ( "arn:aws:bedrock-agentcore:us-west-2:123456789012:" "harness/MyHarness-a1b2c3d4e5" ) SESSION_ID = str(uuid.uuid4()) # 36 characters SUBPROTOCOL = "v1.command.agentcore.aws.dev" def signed_headers(url): request = AWSRequest( method="GET", url=url, headers={ "X-Amzn-Bedrock-AgentCore-Runtime-Session-Id": SESSION_ID, }, ) credentials = botocore.session.Session().get_credentials() SigV4Auth(credentials, "bedrock-agentcore", REGION).add_auth(request) return dict(request.headers) async def main(): encoded_arn = urllib.parse.quote(HARNESS_ARN, safe="") host = f"bedrock-agentcore.{REGION}.amazonaws.com" path = f"/runtimes/{encoded_arn}/ws/shells" https_url = f"https://{host}{path}" websocket_url = f"wss://{host}{path}" async with websockets.connect( websocket_url, additional_headers=signed_headers(https_url), subprotocols=[SUBPROTOCOL], open_timeout=330, ) as websocket: shell_id = websocket.response.headers.get( "X-Amzn-Bedrock-AgentCore-Shell-Id" ) print(f"Connected to shell {shell_id}") # Channel 0x00 carries terminal input. await websocket.send(b"\x00echo 'Hello from my harness'\n") await websocket.send(b"\x00exit\n") async for frame in websocket: if isinstance(frame, str) or not frame: continue channel, payload = frame[0], frame[1:] if channel == 0x01: # PTY output (command stdout and stderr) print(payload.decode("utf-8", errors="replace"), end="") elif channel == 0x02: # Service or platform diagnostics print(payload.decode("utf-8", errors="replace"), end="") elif channel == 0x03: # STATUS status = json.loads(payload) shell_id = status.get("metadata", {}).get("shellId", shell_id) print(f"\nStatus: {status}") asyncio.run(main())
바이너리 프레임 프로토콜
모든 애플리케이션 수준 메시지는 바이너리 WebSocket 프레임입니다. 첫 번째 바이트는 채널을 식별하고 나머지 바이트는 페이로드입니다.
| 채널 | Direction | Payload |
|---|---|---|
|
|
클라이언트에서 서비스로 |
원시 터미널 입력입니다. |
|
|
클라이언트에 대한 서비스 |
원시 PTY 출력. PTY는이 채널에서 명령 stdout과 stderr를 결합합니다. |
|
|
클라이언트에 대한 서비스 |
서비스 또는 플랫폼 진단. 명령 stderr는 |
|
|
클라이언트에 대한 서비스 |
연결 메타데이터 또는 쉘 종료 상태가 포함된 UTF-8 JSON입니다. |
|
|
클라이언트에서 서비스로 |
형식의 UTF-8 JSON |
|
|
양방향 |
선택적 애플리케이션 하트비트입니다. 서비스는 페이로드를 에코합니다. WebSocket ping 프레임도 지원됩니다. |
|
|
양방향 |
쉘 세션을 종료합니다. |
텍스트 프레임은 프로토콜의 일부가 아닙니다. 서비스는 격리된 텍스트 프레임을 무시하고 5회 연속 텍스트 프레임 1003 후 코드와의 연결을 닫습니다.
첫 번째 STATUS 프레임은 연결을 확인하고 다음과 유사한 메타데이터를 포함합니다.
{ "kind": "Status", "apiVersion": "v1", "metadata": { "shellId": "my-shell", "reconnected": false }, "status": "Success" }
쉘이 0이 아닌 상태로 종료되면 최종 STATUS 프레임에는에 ExitCode 원인이 포함됩니다details.causes.
쉘에 다시 연결
런타임 세션 ID와 셸 ID를 모두 저장합니다. 다시 연결하려면 동일한 런타임 세션 ID 헤더를 사용하고 URL로 인코딩된 셸 ID를 쿼리 파라미터로 추가합니다.
wss://bedrock-agentcore.<region>.amazonaws.com/runtimes/<url-encoded-harness-arn>/ws/shells?shellId=<shell-id>
연결이 분리되는 동안 쉘 프로세스가 계속 실행됩니다. 재연결 시 서비스는 최대 256KB의 버퍼링된 출력을 재생합니다. 연결 STATUS 프레임은 metadata.reconnected로 설정true되며 분리된 쉘이 재생 버퍼가 유지할 수 있는 것보다 더 많은 출력을 생성metadata.bytesDropped했는지 여부를 포함합니다.
동일한 셸 ID로 다른 연결을 열면 기존 연결이 대체됩니다. 교체된 클라이언트는 종료 코드를 수신합니다4000.
일반 사용 사례
- 대화형 디버깅
-
하네스 에이전트와 동일한 환경에서 설치된 패키지, 파일, 프로세스 및 환경 구성을 검사합니다.
- 사용자 지정 환경 검증
-
사용자 지정 컨테이너가 있는 하네스의 경우 해당 컨테이너 내부에서 설치된 종속성과 파일 시스템 마운트를 확인합니다.
- 에이전트 터미널 액세스 코딩
-
파일을 생성하고, 테스트를 실행하고, 출력을 검사하고, 반복해야 하는 에이전트 코딩을 위한 영구 실행 환경을 제공합니다.
- 장기 실행 프로세스
-
프로세스를 시작하고 WebSocket에서 분리한 다음 나중에 다시 연결하여 진행 상황을 확인하거나 입력을 제공합니다.
보안 고려 사항
중요
Harness 쉘을 열 수 있는 보안 주체는 하네스 세션에 대한 대화형 명령 액세스 권한을 가집니다. 신뢰할 수 있는 보안 주체 및 특정 하네스 ARNbedrock-agentcore:InvokeAgentRuntimeCommandShell으로 제한합니다. ARNs
쉘은 선택한 환경 또는 탑재된 파일 시스템에서 고객이 제공한 데이터, 파일 및 보안 암호에 액세스할 수 있습니다. 세션이 도달할 수 있는 네트워크 대상에 연결할 수도 있습니다. 쉘 환경은 허용 목록을 사용하며 AgentCore 플랫폼 또는 워크로드 자격 증명을 주입하지 않습니다. 쉘은 세션의 격리된 microVM 내에 유지되며 다른 고객의 워크로드에 액세스할 수 없습니다.
AgentCore는 Amazon CloudWatch Logs의 하네스 런타임 로그 그룹에 요청 ID 및 연결 메타데이터를 전송합니다. 서비스는 터미널 입력 또는 출력을 로깅하지 않습니다.
AWS CloudTrail은 호출자 ID, 타임스탬프, 소스 IP 주소, 확인된 런타임 리소스 및 응답 상태를 포함한 InvokeAgentRuntimeCommandShell API 호출을 기록합니다. CloudTrail은 터미널 입력 또는 출력을 로깅하지 않습니다.
자세한 Harness 보안 지침은 섹션을 참조하세요보안 및 액세스 제어.
오류 처리
WebSocket 업그레이드는 다음 오류를 반환할 수 있습니다.
- ValidationException
-
요청 파라미터가 잘못되었습니다. 런타임 세션 ID에 33자 이상이 포함되어 있고, 셸 ID가 유효하며, 대상 리전에서 기능을 사용할 수 있는지 확인합니다. 요청 경로에서 URL로 인코딩된 하네스 ARN을 사용합니다. 관리형 런타임 ARN의 직접 사용은 거부됩니다.
- AccessDeniedException
-
호출자는 하네스에 대한
bedrock-agentcore:InvokeAgentRuntimeCommandShell권한이 없습니다. - ResourceNotFoundException
-
지정된 하네스가 존재하지 않습니다. URL에 URL로 인코딩된 하네스 ARN이 포함되어 있는지 확인합니다.
- ServiceQuotaExceededException(429)
-
최대 10개의 활성 쉘이 이미 열려 있습니다. 활성 쉘을 종료하거나 분리한 다음 다시 시도합니다.
- RuntimeClientError(424)
-
런타임에 도달할 수 없습니다.
- ThrottlingException
-
요청이 API 속도 제한을 초과했습니다. 지수 백오프를 사용하여 재시도하세요.
- RetryableConflictException(409)
-
서비스가 대상 세션을 프로비저닝하거나 해제하고 있습니다. 짧은 지수 백오프로 재시도합니다.
연결되면 다음 종료 코드는 연결이 종료된 이유를 나타냅니다.
| 코드 | 의미 | 클라이언트 작업 |
|---|---|---|
|
|
쉘이 완전히 종료되었습니다. |
일반 종료로 취급합니다. |
|
|
클라이언트는 이진 전용 프로토콜로 5개의 연속 텍스트 프레임을 전송했습니다. |
바이너리 프레임으로 전환합니다. 동일한 동작으로 자동으로 다시 연결하지 마세요. |
|
|
네트워크 장애 또는 서비스 중단으로 인해 연결 프레임이 닫히지 않고 연결이 종료되었습니다. |
저장된 셸 ID와 다시 연결합니다. |
|
|
1시간의 연결 기간이 만료되었거나, 프레임 속도가 초당 250프레임을 초과했거나, 쓰기 버퍼가 오버플로되었습니다. |
기간 만료를 위해 다시 연결합니다. 속도 또는 버퍼 위반의 경우 다시 연결하기 전에 다시 끕니다. |
|
|
프레임 페이로드가 64KB를 초과했습니다. |
페이로드를 64KB 미만의 프레임으로 분할한 다음 다시 연결합니다. |
|
|
예기치 않은 서버 장애가 발생했습니다. |
지수 백오프를 사용하여 재시도하세요. |
|
|
동일한 셸 ID로 연결된 다른 클라이언트입니다. |
자동으로 다시 연결하지 마세요. 다른 클라이언트가 쉘에 연결되었음을 사용자에게 알립니다. |
모범 사례
-
각 논리적 터미널에 대해 고유한 셸 ID를 생성하고 유지합니다.
-
런타임 세션 ID를 셸 ID로 유지합니다. 두 값 모두 재연결에 필요합니다.
-
연결 쓰기 버퍼가 채워지지 않도록 출력을 즉시 읽습니다.
-
큰 입력을 64KB 미만의 바이너리 프레임으로 분할합니다.
-
쉘을 더 오래 사용할 수 있어야 하는 경우 1시간 연결 제한 전후에 다시 연결합니다.
-
더 이상 필요하지 않은 경우 쉘을 명시적으로 종료합니다. 분리된 쉘은 10-active-shell 제한에 포함되지 않습니다. 서비스는 최대 20개의 활성 및 분리된 쉘 항목을 유지하고 필요한 경우 가장 오래된 분리된 쉘을 제거합니다.
-
연결이 콜드 하네스 세션을 시작할 수 있는 경우 최소 330초의 업그레이드 제한 시간을 사용합니다. 업그레이드 후 초기
STATUS프레임을 기다리는 동안 별도의 제한 시간을 적용합니다.
할당량 및 제한
| 한도 | 값 | 설명 |
|---|---|---|
|
최대 프레임 페이로드 |
64KB |
프레임이 클수록 종료 코드가 생성됩니다 |
|
프레임 속도 |
초당 250프레임 |
제한을 초과하면 종료 코드가 발생합니다 |
|
최대 연결 기간 |
1시간 |
계속하려면 동일한 런타임 세션 ID와 셸 ID로 다시 연결합니다. |
|
하네스 세션당 동시 활성 쉘 |
10 |
쉘 10개가 활성화되면 새 연결이 거부됩니다. 분리된 쉘은이 제한에 포함되지 않습니다. |
|
활성 및 분리된 쉘 항목 유지 |
20 |
한도에 도달하면 서비스는 다른 쉘을 생성하기 전에 가장 오래된 분리 쉘을 제거합니다. |
|
재연결 버퍼 |
256KB |
재연결 후 재생되는 최대 출력입니다. |
전체 서비스 제한은 Amazon Bedrock AgentCore 할당량을 참조하세요.
관련 주제
-
환경 및 파일 시스템 - 기본 환경 또는 사용자 지정 컨테이너 구성
-
보안 및 액세스 제어 - 하네스 및 실행 환경에 대한 액세스 제어
-
관찰성 및 비용 제어 - 하네스 활동 및 비용 모니터링