View a markdown version of this page

交互式外壳(终端) - Amazon Bedrock AgentCore

交互式外壳(终端)

InvokeAgentRuntimeCommandShell操作将在正在运行的 AgentCore Runtime 会话中打开一个持久的交互式终端会话 WebSocket。与一次性命令执行不同,shell 会话保持状态——环境变量、工作目录和命令历史记录跨越输入。这可以在应用程序中实现调试、环境检查和构建终端体验。

要拨打电话InvokeAgentRuntimeCommandShell,您需要bedrock-agentcore:InvokeAgentRuntimeCommandShell权限。

工作原理

InvokeAgentRuntimeCommandShell WebSocket 与在代理会话中运行的交互式 shell 进程建立连接。该连接使用二进制帧来双向传输终端输入和输出。

同一个代理,同一个会话

InvokeAgentRuntimeCommandShell在与InvokeAgentRuntime和相同的代理运行时上运行InvokeAgentRuntimeCommand。您无需创建单独的资源。您部署的代理在任何活动会话上都CreateAgentRuntime接受外壳连接。

注意

您可以通过传递session_id来定位特定的运行时会话。如果省略,则会为每个连接创建一个新会话。要使用重新连接,必须同时存储和重复使用session_idshellId

该连接支持:

功能 说明

持续状态

环境变量、工作目录和命令历史记录跨越同一个会话中的输入。

重新连接

提供相同的,session_id并在断开连接后重新shellId连接到同一 shell。该服务最多可重放 256 KB 的缓冲输出。

多个并发外壳

每个运行时最多 10 个活动的 shell 会话(终端)。新连接在满负荷时会被拒绝。

先决条件

  • bedrock-agentcore:InvokeAgentRuntimeCommandShell IAM 权限

  • AgentCore 运行时处于 READY 状态的有效运行时端点 ARN

注意

2026 年 6 月 5 日之后创建的代理会自动支持交互式外壳(终端)。如果您在此日期之前部署了代理,则必须重新部署代理以更新代理运行时。

使用 AgentCore CLI

有关安装和设置说明,请参阅使用 CLI 开始使用 AgentCore Runtime

CLI 提供了内置的终端体验agentcore exec

agentcore exec --it

要连接到特定的运行时,请执行以下操作:

agentcore exec --it --runtime <runtime-arn> --region us-west-2

按下Ctrl+]即可在不关闭外壳的情况下将其从外壳上分离。CLI 会打印一条重新连接命令:

agentcore exec --it \ --runtime <arn> \ --region <region> \ --session-id <uuid> \ --shell-id <id>

对于一次性命令,请省略--it

agentcore exec "ls -la /tmp"

对于机器可读的输出,请使用 JSON 模式:

agentcore exec --json "echo hello" # Output: {"success":true,"exitCode":0,"stdout":"hello\n","stderr":""}

有关其他 CLI 示例,请参阅中的AgentCore 示例 GitHub。

使用 AgentCore 软件开发工具包

安装 Python 开发工具包:

pip install bedrock-agentcore
SigV4 (default)
  1. 以下示例说明如何使用默认 AWS 凭据打开 shell 会话。

    import asyncio from bedrock_agentcore.runtime import AgentCoreRuntimeClient, ShellChannel async def main(): runtime_arn = "arn:aws:bedrock-agentcore:us-west-2:123456789012:runtime/my-agent" client = AgentCoreRuntimeClient(region="us-west-2") async with client.open_shell(runtime_arn) as shell: print(f"Connected. Shell ID: {shell.shell_id}") # Send a command await shell.send("echo Hello from AgentCore Shell\n") # Read output frames async for frame in shell: if frame.channel == ShellChannel.STDOUT: print(frame.text, end="") if "Hello from AgentCore Shell" in frame.text: break asyncio.run(main())
Pre-signed URL
  1. 以下示例说明如何使用预签名 URL 打开 shell 会话。

    import asyncio from bedrock_agentcore.runtime import AgentCoreRuntimeClient, PresignedAuth, ShellChannel async def main(): runtime_arn = "arn:aws:bedrock-agentcore:us-west-2:123456789012:runtime/my-agent" client = AgentCoreRuntimeClient(region="us-west-2") async with client.open_shell(runtime_arn, auth=PresignedAuth(expires=120)) as shell: await shell.send("whoami\n") async for frame in shell: if frame.channel == ShellChannel.STDOUT: print(frame.text, end="") break asyncio.run(main())
OAuth
  1. 以下示例说明如何使用 OAuth 持有者令牌打开 shell 会话。

    import asyncio from bedrock_agentcore.runtime import AgentCoreRuntimeClient, OAuthAuth, ShellChannel async def main(): runtime_arn = "arn:aws:bedrock-agentcore:us-west-2:123456789012:runtime/my-agent" bearer_token = "your_oauth_token_here" client = AgentCoreRuntimeClient(region="us-west-2") async with client.open_shell(runtime_arn, auth=OAuthAuth(bearer_token=bearer_token)) as shell: await shell.send("echo oauth-connected\n") async for frame in shell: if frame.channel == ShellChannel.STDOUT: print(frame.text, end="") if "oauth-connected" in frame.text: break asyncio.run(main())

重新连接

一种常见的模式是在断开连接后重新连接到 shell,从而保留所有会话状态。shellId

import asyncio from bedrock_agentcore.runtime import AgentCoreRuntimeClient async def main(): client = AgentCoreRuntimeClient(region="us-west-2") runtime_arn = "arn:aws:bedrock-agentcore:us-west-2:123456789012:runtime/my-agent" session_id = "my-session-0000000000000000000000" shell_id = "my-shell" shell = await client.open_shell( runtime_arn, session_id=session_id, shell_id=shell_id, ).__aenter__() print(f"connected (reconnected={shell.reconnected})") await shell.send("export GREETING='hello'\n") await asyncio.sleep(1) async with client.open_shell( runtime_arn, session_id=session_id, shell_id=shell_id, ) as shell2: print(f"reconnected (reconnected={shell2.reconnected})") assert shell2.reconnected if __name__ == "__main__": asyncio.run(main())

Auto-reconnect

当连接中断时,SDK 也可以自动重新 WebSocket 连接。ReconnectConfig用于启用此功能:

import asyncio from bedrock_agentcore.runtime import AgentCoreRuntimeClient, ReconnectConfig, ShellChannel async def on_reconnect(reconnected: bool): print(f"Reconnected: {reconnected}") async def main(): runtime_arn = "arn:aws:bedrock-agentcore:us-west-2:123456789012:runtime/my-agent" shell_id = "my-persistent-shell" config = ReconnectConfig(max_retries=5, base_delay=0.5, on_reconnect=on_reconnect) client = AgentCoreRuntimeClient(region="us-west-2") async with client.open_shell(runtime_arn, shell_id=shell_id, reconnect_config=config) as shell: # If the connection drops, the SDK retries automatically await shell.send("long-running-command\n") async for frame in shell: if frame.channel == ShellChannel.STDOUT: print(frame.text, end="") asyncio.run(main())

有关其他 SDK 示例,请参阅中的AgentCore 示例 GitHub。

常见使用案例

交互式调试

打开 shell 以检查代理的运行时环境 — 检查已安装的软件包、读取日志文件、检查文件系统或测试命令,然后再将其添加到代理代码中。

python --version && pip list | head -20
环境检查

验证环境变量、网络连接、可用工具和文件系统状态。在诊断代理故障或验证部署配置时很有用。

env | grep AWS && curl -s http://169.254.169.254/latest/meta-data/
编码代理终端访问权限

AI 编码代理使用交互式 shell(终端)作为其执行环境。当编码代理需要运行代码、安装软件包或运行测试时,它会打开 AgentCore 运行时的 shell 会话并直接执行命令——就像开发人员使用终端一样。例如,Claude Code、Amazon Kiro 和 OpenAI Codex 都连接到一个 shell 会话,在那里他们可以在循环中迭代编写代码、运行代码、观察输出和修复错误。持久状态意味着代理可以运行一系列命令,而不会在步骤之间丢失上下文。

# A coding agent opens a shell and iterates on code async with client.open_shell(runtime_arn, shell_id="agent-workspace") as shell: await shell.send("cd /workspace && git clone https://github.com/user/repo.git\n") await shell.send("cd repo && pip install -r requirements.txt\n") await shell.send("python -m pytest tests/ -v\n") # Agent reads test output, fixes failures, re-runs — all in the same shell
Long-running 进程

启动寿命超过单个 HTTP 请求的进程。随着时间的推移,使用重新连接来检查进度或提供其他输入。

nohup python train.py > /tmp/train.log 2>&1 &

主要设计选择

持续的交互式会话

每个连接都映射到一个长寿命的 shell 进程。您无需重新建立连接即可发送多个命令,而较早的命令(导出的变量、cd更改)所累积的状态可供以后的命令使用。

二进制取景结束了 WebSocket

终端 I/O 以二进制 WebSocket 帧的形式进行流式传输。这支持原始终端控制序列、颜色、光标移动和全屏应用程序,无需编码开销。

与输出重播重新连接

当您使用相同的方式重新连接时shellId,该服务最多可重放 256 KB 的最近输出。这使您能够在不丢失上下文的情况下从网络中断中恢复。断开连接期间,shell 进程继续运行。

会话限制

当运行时已打开 10 个 shell 会话(终端)时,新的连接会被拒绝并显示错误。在打开新会话之前,必须先关闭现有会话。

安全注意事项

提示

有关所有 Runtime 安全建议的综合视图,请参阅 R AgentCore untime 安全最佳实践

重要

在责任 AWS 共担模式下,您对在运行 AgentCore 时会话中运行的命令负责。 AWS 在 microVM 级别提供安全的基础设施和隔离。您对所执行的命令、处理的数据以及您配置的访问控制负责。

外壳会话(终端)的安全边界是 microVM。每个 AgentCore 运行时会话都在具有自己的内核、内存和文件系统的隔离的 microVM 中运行。Shell 会话无法访问其他客户的工作负载或逃离虚拟机边界。但是,在您的虚拟机中,shell 命令可以完全访问容器文件系统以及您配置的任何凭据或机密。

使用 CloudWatch 日志进行审计

AgentCore Runtime 会将请求编号和连接元数据发送到您的代理的 Amazon Log CloudWatch s 日志组。您可以使用这些日志来监控 shell 连接活动并维护审计跟踪。终端 I/O 内容 (stdin/stdout) 将流式传输到您的客户端,服务不会记录下来。

使用审计 CloudTrail

AWS CloudTrail 在您的账户中记录 InvokeAgentRuntimeCommandShell API 调用。每条记录都包含元数据,例如来电者身份、时间戳、源 IP 地址和响应状态。 CloudTrail 不记录请求或响应有效负载。 CloudTrail 用于审核谁打开了 shell 会话以及何时打开,然后使用请求 ID 与 CloudWatch 日志关联以获取连接详细信息。

对于敏感工作负载,可以考虑实施其他控制措施,例如:

  • 使用 IAM 策略限制哪些委托人可以调用 InvokeAgentRuntimeCommandShell

  • 配置 VPC 终端节点以保持网络内的流量

  • 设置 CloudWatch 日志指标筛选器和警报以检测意外的连接模式

  • 定期查看 CloudTrail 日志中是否有未经授权的访问尝试

错误处理

建立 shell 会话连接时,在 WebSocket 升级过程中可能会遇到以下错误:

ValidationException

在请求参数无效时发生。如果会话 ID 少于 33 个字符、目标区域未启用该功能或代理未处于 READY 状态,则可能会发生这种情况。

AccessDeniedException

当你没有必要的权限时发生。确保您的 IAM 策略包含bedrock-agentcore:InvokeAgentRuntimeCommandShell权限。

ResourceNotFoundException

在找不到指定的代理运行时时发生。验证运行时 ARN 是否正确。

RuntimeClientError (424)

发生在多种场景中:(1) 已达到最大并发 shell 会话(终端)(10 个已打开)— 关闭现有会话并重试。(2) 外壳 ID 格式无效 — 必须是 1-128 个字母数字字符、下划线或连字符。(3) 无法访问运行时间-退缩后重试。解析响应正文 JSON error 字段以区分原因。

ThrottlingException

当你超过 API 速率限制时发生。实现指数退避和重试逻辑。

ConflictException

另一个连接shellId同时声明了同样的内容。1 秒后重试。这是一个狭窄的竞争条件(不是持续状态),重试时会立即解决。

连接后,以下关闭代码指示连接终止的原因:

代码 含义 客户操作

1000

正常闭合 — 外壳干净地退出或优雅地断开连接

显示 “已断开连接”。正常终止。

1001

消失 — 服务器部署或关闭

Auto-reconnect 已存储shellId

1003

不支持的数据-在连续 5 个文本帧之后发送(仅限二进制协议)

不要自动重新连接。切换到二进制帧。

1006

异常闭合 — 未收到近帧时在本地合成(网络死亡,TCP RST)

Auto-reconnect 已存储shellId

1008

策略违规 — 连接 TTL 已过期(1 小时)、超过帧速率限制(250 frames/sec)或写入缓冲区溢出

Auto-reconnect TTL 到期(重新连接时为新 TTL)。对于速率限制:退出,然后重新连接。

1009

消息太大-帧有效载荷超过 64 KB

减小帧大小(区块到 <64 KB),然后重新连接。会话还活着。

1011

服务器错误-意外内部故障

使用退避功能重试。

4000

已替换 — 另一台与之连接的客户端 shellId

不要自动重新连接。显示 “从其他客户端连接的会话”。

最佳实践

使用时请遵循以下最佳实践InvokeAgentRuntimeCommandShell

  • 为每个逻辑会话使用唯一的shellId(例如 UUID)以启用重新连接。将其存储shellId在客户端。

  • ReconnectConfig在 SDK 中使用,无需手动重新连接逻辑即可自动处理瞬态网络中断。

  • 立即读取输出帧。如果客户端落后,服务器的写入缓冲区就会被填满,连接将因代码而关闭1008

  • 对于较大的输入(例如粘贴文件),请将内容拆分为每帧小于 64 KB 的块,以避免代码关闭。1009

  • 设置适当的连接超时。最长连接持续时间为 1 小时,使用相同的持续时间重新连接即可shellId继续连接。

  • 完成后明确关闭会话。分离的会话计入 10 个会话的限制。

限额和限制

限制 说明

最大帧有效载荷大小

64 KB

超过此限制的帧会导致代码关闭1009

帧率

250 frames/sec

超过此值会触发关闭代码1008

最大连接持续时间

1 小时

连接将使用代码关闭1008。使用相同的方法重新连接shellId以继续。

每个运行时的并发 shell 会话(终端)

10

如果已打开 10 个会话,则新连接将被拒绝。关闭现有会话并重试。

重新连接缓冲区

256 KB

重新连接到 shell 时重播的最大输出。

有关完整的服务限制,请参阅 Amazon Bedrock AgentCore 配额