

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# インタラクティブシェル (ターミナル)
<a name="harness-command-shell"></a>

`InvokeAgentRuntimeCommandShell` オペレーションは、WebSocket 経由で実行中の AgentCore ハーネスセッション内で永続的なインタラクティブターミナルを開きます。API は、このハーネスセッションをランタイムセッション ID で識別します。ワンショットコマンドの実行とは異なり、インタラクティブシェルは、環境変数、作業ディレクトリ、コマンド履歴、および入力間での実行プロセスを維持します。

コマンド間でシェルの状態を保持する必要がある場合は、デバッグ、反復開発、または長時間実行されるプロセスにインタラクティブなシェルを使用します。

SigV4 および SigV4 の署名付きリクエストの場合、発信者にはハーネスに対する`bedrock-agentcore:InvokeAgentRuntimeCommandShell`アクセス許可が必要です。ベアラートークンリクエストは、代わりにハーネスインバウンドオーソライザーを満たす必要があります。

**重要**  
起動時に、AgentCore CLI コマンドと高レベルの AgentCore SDK シェルヘルパーはハーネスターゲットをサポートしていません。このページに示すように、`InvokeAgentRuntimeCommandShell`WebSocket API を介してハーネスシェルに直接接続します。

## 仕組み
<a name="harness-command-shell-how-it-works"></a>

 `InvokeAgentRuntimeCommandShell` は、ハーネスセッションを実行するmicroVM 内のインタラクティブなシェルプロセスへの WebSocket 接続を確立します。接続はバイナリフレームを使用して、ターミナルの入出力を両方向にストリーミングします。

ハーネスがデフォルト環境を使用している場合、シェルはマネージドハーネス環境で実行されます。ハーネスがカスタムコンテナを使用している場合、シェルはそのコンテナで実行されます。ハーネスインタラクティブターミナルは現在、Bash のみをサポートしています。

接続は以下をサポートします。


| 機能 | 説明 | 
| --- | --- | 
| 永続状態 | 環境変数、作業ディレクトリ、コマンド履歴、実行中のプロセスが同じシェル内に保持されます。 | 
| 再接続 | デタッチされたシェルに再接続`shellId`するには、同じランタイムセッション ID と を指定します。このサービスは、最大 256 KB のバッファされた出力を再生します。 | 
| 複数の同時シェル | 1 つのハーネスセッションで最大 10 のアクティブなシェルセッションを開きます。デタッチされたシェルはこの制限にはカウントされません。各シェルには独立したターミナルプロセスがあり、セッションファイルシステムを共有します。 | 

## 前提条件
<a name="harness-command-shell-prerequisites"></a>
+ `READY` 状態のハーネス
+ 選択した認証方法の承認: SigV4 `bedrock-agentcore:InvokeAgentRuntimeCommandShell` の IAM アクセス許可、またはハーネスインバウンドオーソライザーによって受け入れられるベアラートークン
+ バイナリフレームとリクエストヘッダーまたは署名付き URLs をサポートする WebSocket クライアント
+ カスタムコンテナの場合、Bash は にインストールされます`/bin/bash`。`sh` や などの他のシェル`dash`は現在サポートされていません。

完全なハーネスアクセス許可モデルの詳細については、「」を参照してください[発信者に必要な IAM アクセス許可](harness-security.md#harness-iam-permissions)。

## WebSocket API 経由で接続する
<a name="harness-command-shell-connect"></a>

次の 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 アップグレードリクエストで次の値を送信します。


| 値 | 必要 | 説明 | 
| --- | --- | --- | 
| Authentication | あり | 署名バージョン 4 (SigV4) でリクエストに署名するか、SigV4 の署名付き URL を使用するか、ハーネスインバウンドオーソライザーによって設定されたベアラートークンを `Authorization`ヘッダーに送信します。SigV4 サービス名は です`bedrock-agentcore`。 | 
|  `X-Amzn-Bedrock-AgentCore-Runtime-Session-Id` ヘッダーまたはクエリパラメータ | いいえ | 既存のハーネスセッションをターゲットにするか、指定された ID を持つハーネスセッションを作成します。値には 33 文字以上を含める必要があります。これを省略すると、サービスはランタイムセッション ID を作成し、レスポンスで返します。 | 
|  `Sec-WebSocket-Protocol`  | いいえ | SigV4 接続の場合、オプション`v1.command.agentcore.aws.dev`で コマンドシェルバイナリプロトコルを識別する を提供します。ベアラートークン接続は、代わりにこの表の後に説明されている認証サブプロトコルを使用します。 | 
|  `shellId` クエリパラメータ | いいえ | 既存のシェルに再接続します。シェルを作成したのと同じランタイムセッション ID で使用します。 | 

`Authorization` ヘッダーを設定できないブラウザクライアントの場合、base64url はベアラートークンをエンコードし、 `base64UrlBearerAuthorization.<encoded-token>` と `base64UrlBearerAuthorization` の両方を 経由で提供します`Sec-WebSocket-Protocol`。ベアラートークン接続`v1.command.agentcore.aws.dev`で も提供しないでください。

`101 Switching Protocols` レスポンスは、 および `X-Amzn-Bedrock-AgentCore-Shell-Id`ヘッダーでランタイムセッション ID `X-Amzn-Bedrock-AgentCore-Runtime-Session-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())
```

## バイナリフレームプロトコル
<a name="harness-command-shell-protocol"></a>

すべてのアプリケーションレベルのメッセージは、バイナリ WebSocket フレームです。最初のバイトはチャネルを識別し、残りのバイトはペイロードです。


| チャネル | Direction | ペイロード | 
| --- | --- | --- | 
|  `0x00` - STDIN | クライアントからサービスへ | Raw ターミナル入力。 | 
|  `0x01` - STDOUT | クライアントへのサービス | Raw PTY 出力。PTY は、このチャネルでコマンド stdout と stderr を組み合わせます。 | 
|  `0x02` - STDERR | クライアントへのサービス | サービスまたはプラットフォームの診断。コマンド stderr は `0x01` PTY 出力の一部です。 | 
|  `0x03` - ステータス | クライアントへのサービス | 接続メタデータまたはシェルの終了ステータスを含む UTF-8 JSON。 | 
|  `0x04` - サイズ変更 | クライアントからサービスへ | 形式の UTF-8 JSON`{"width":120,"height":40}`。各ディメンションは 1～1,000 である必要があります。 | 
|  `0x05` - ハートベアト | 両方向 | オプションのアプリケーションハートビート。サービスはペイロードをエコーします。WebSocket ping フレームもサポートされています。 | 
|  `0xFF` - 閉じる | 両方向 | シェルセッションを終了します。 | 

テキストフレームはプロトコルの一部ではありません。このサービスは、分離されたテキストフレームを無視し、5 つの連続したテキストフレーム`1003`の後にコードとの接続を閉じます。

最初の`STATUS`フレームは接続を確認し、次のようなメタデータを含めます。

```
{
  "kind": "Status",
  "apiVersion": "v1",
  "metadata": {
    "shellId": "my-shell",
    "reconnected": false
  },
  "status": "Success"
}
```

シェルがゼロ以外のステータスで終了すると、最終`STATUS`フレームに `ExitCode`の原因が含まれます`details.causes`。

## シェルへの再接続
<a name="harness-command-shell-reconnect"></a>

ランタイムセッション ID とシェル ID の両方を保存します。再接続するには、同じランタイムセッション ID ヘッダーを使用し、URL エンコードされたシェル ID をクエリパラメータとして追加します。

```
wss://bedrock-agentcore.<region>.amazonaws.com/runtimes/<url-encoded-harness-arn>/ws/shells?shellId=<shell-id>
```

接続がデタッチされている間、シェルプロセスは引き続き実行されます。再接続時に、サービスは最大 256 KB のバッファ出力を再生します。接続`STATUS`フレームは `metadata.reconnected`に設定`true`され、デタッチされたシェルが再生バッファが保持できるよりも多くの出力を生成`metadata.bytesDropped`したかどうかが含まれます。

同じシェル ID で別の接続を開くと、既存の接続が置き換えられます。置き換えられたクライアントはクローズコード を受け取ります`4000`。

## 一般的なユースケース
<a name="harness-command-shell-use-cases"></a>

インタラクティブデバッグ  
ハーネスエージェントと同じ環境で、インストールされているパッケージ、ファイル、プロセス、環境設定を検査します。

カスタム環境検証  
カスタムコンテナを持つハーネスの場合は、そのコンテナ内からインストールされた依存関係とファイルシステムのマウントを確認します。

コーディングエージェントのターミナルアクセス  
ファイルの作成、テストの実行、出力の検査、反復を行う必要があるエージェントをコーディングするための永続的な実行環境を提供します。

長時間実行中のプロセス  
プロセスを開始し、WebSocket からデタッチし、後で再接続して進行状況を確認したり、入力を提供したりできます。

## セキュリティに関する考慮事項
<a name="harness-command-shell-security"></a>

**重要**  
Harness シェルを開くことができるプリンシパルには、ハーネスセッションへのインタラクティブなコマンドアクセスがあります。信頼できるプリンシパルと特定のハーネス ARN `bedrock-agentcore:InvokeAgentRuntimeCommandShell`に制限します。 ARNs

シェルは、選択した環境またはマウントされたファイルシステムで、お客様が提供したデータ、ファイル、シークレットにアクセスできます。また、セッションが到達できるネットワーク送信先に接続することもできます。シェル環境は許可リストを使用し、AgentCore プラットフォームまたはワークロード認証情報を挿入しません。シェルはセッションの分離されたmicroVM 内にとどまり、別の顧客のワークロードにアクセスすることはできません。

AgentCore は、Amazon CloudWatch Logs のハーネスランタイムロググループにリクエスト ID と接続メタデータを送信します。サービスはターミナルの入力または出力を記録しません。

 AWS CloudTrail は、発信者 ID、タイムスタンプ、ソース IP アドレス、解決されたランタイムリソース、レスポンスステータスなどの `InvokeAgentRuntimeCommandShell` API コールを記録します。CloudTrail はターミナルの入力または出力を記録しません。

Harness セキュリティガイダンスの詳細については、「」を参照してください[セキュリティとアクセス制御について](harness-security.md)。

## エラー処理
<a name="harness-command-shell-errors"></a>

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)**   
サービスはターゲットセッションをプロビジョニングまたは破棄しています。短いエクスポネンシャルバックオフで再試行します。

接続すると、次のクローズコードは接続が終了した理由を示します。


| コード | 意味 | クライアントアクション | 
| --- | --- | --- | 
|  `1000`  | シェルは正常に終了しました。 | 通常の終了として扱います。 | 
|  `1003`  | クライアントは、バイナリのみのプロトコルに 5 つの連続したテキストフレームを送信しました。 | バイナリフレームに切り替えます。同じ動作で自動的に再接続しないでください。 | 
|  `1006`  | ネットワーク障害またはサービスの中断により、接続はクローズフレームなしで終了しました。 | 保存されたシェル ID で再接続します。 | 
|  `1008`  | 接続時間が 1 時間経過した場合、フレームレートが 1 秒あたり 250 フレームを超えた場合、または書き込みバッファがオーバーフローした場合。 | 有効期限が切れるまで再接続します。レートまたはバッファ違反の場合は、再接続する前にバックオフします。 | 
|  `1009`  | フレームペイロードが 64 KB を超えました。 | ペイロードを 64 KB 未満のフレームに分割し、再接続します。 | 
|  `1011`  | 予期しないサーバー障害が発生しました。 | エクスポネンシャルバックオフを使用して再試行してください。 | 
|  `4000`  | 同じシェル ID で接続された別のクライアント。 | 自動的に再接続しないでください。別のクライアントがシェルにアタッチしたことをユーザーに通知します。 | 

## ベストプラクティス
<a name="harness-command-shell-best-practices"></a>
+ 論理ターミナルごとに一意のシェル ID を生成して保持します。
+ ランタイムセッション ID をシェル ID で保持します。再接続には両方の値が必要です。
+ 接続書き込みバッファがいっぱいにならないように、出力をすぐに読み取ります。
+ 大きな入力を 64 KB 未満のバイナリフレームに分割します。
+ シェルをより長く使用する必要がある場合は、1 時間の接続制限の前後に再接続します。
+ 不要になったシェルは明示的に終了します。デタッチされたシェルは、10-active-shell の制限にはカウントされません。このサービスは、最大 20 個のアクティブシェルエントリとデタッチシェルエントリを保持し、必要に応じて最も古いデタッチシェルを削除します。
+ 接続がコールドハーネスセッションを開始できる場合は、少なくとも 330 秒のアップグレードタイムアウトを使用します。アップグレード後の最初の`STATUS`フレームを待っている間に、別のタイムアウトを適用します。

## クォータと制限
<a name="harness-command-shell-limits"></a>


| 制限 | 値 | 説明 | 
| --- | --- | --- | 
| 最大フレームペイロード | 64 KB | フレームが大きいほど、クローズコード になります`1009`。 | 
| フレームレート | 250 フレーム/秒 | 制限を超えると、クローズコード になります`1008`。 | 
| 最大接続時間 | 1 時間 | 続行するには、同じランタイムセッション ID とシェル ID で再接続します。 | 
| ハーネスセッションあたりの同時アクティブシェル | 10 | 10 個のシェルがアクティブな場合、新しい接続は拒否されます。デタッチされたシェルはこの制限にはカウントされません。 | 
| 保持されたアクティブなシェルエントリとデタッチされたシェルエントリ | 20 | 制限に達すると、サービスは別のシェルを作成する前に、最も古いデタッチされたシェルを削除します。 | 
| 再接続バッファ | 256 KB | 再接続後に再生される最大出力。 | 

完全なサービス制限については、[「Amazon Bedrock AgentCore のクォ](bedrock-agentcore-limits.md)ータ」を参照してください。

## 関連トピック
<a name="_related_topics"></a>
+  [環境とファイルシステム](harness-environment.md) - デフォルトの環境またはカスタムコンテナを設定する
+  [セキュリティとアクセス制御について](harness-security.md) - ハーネスとその実行環境へのアクセスを制御する
+  [オブザーバビリティとコスト管理](harness-operations.md) - ハーネスのアクティビティとコストをモニタリングする
+  [AgentCore Runtime のインタラクティブシェル](runtime-get-started-command-shell.md) 